diff options
author | Eduardo Chappa <echappa@gmx.com> | 2013-02-03 00:59:38 -0700 |
---|---|---|
committer | Eduardo Chappa <echappa@gmx.com> | 2013-02-03 00:59:38 -0700 |
commit | 094ca96844842928810f14844413109fc6cdd890 (patch) | |
tree | e60efbb980f38ba9308ccb4fb2b77b87bbc115f3 /pith/osdep | |
download | alpine-094ca96844842928810f14844413109fc6cdd890.tar.xz |
Initial Alpine Version
Diffstat (limited to 'pith/osdep')
50 files changed, 5129 insertions, 0 deletions
diff --git a/pith/osdep/Makefile.am b/pith/osdep/Makefile.am new file mode 100644 index 00000000..1d790f3c --- /dev/null +++ b/pith/osdep/Makefile.am @@ -0,0 +1,22 @@ +## Process this file with automake to produce Makefile.in +## Use aclocal -I m4; automake + +# ======================================================================== +# Copyright 2006 University of Washington +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# ======================================================================== + +noinst_LIBRARIES = libpithosd.a + +libpithosd_a_SOURCES = bldpath.c canaccess.c canonicl.c collate.c color.c coredump.c \ + creatdir.c debugtime.c domnames.c err_desc.c fgetpos.c filesize.c \ + fnexpand.c hostname.c lstcmpnt.c mimedisp.c pipe.c pw_stuff.c \ + rename.c tempfile.c temp_nam.c writ_dir.c + +AM_CPPFLAGS = -I@top_builddir@/include -I@top_srcdir@/include diff --git a/pith/osdep/Makefile.in b/pith/osdep/Makefile.in new file mode 100644 index 00000000..436101c8 --- /dev/null +++ b/pith/osdep/Makefile.in @@ -0,0 +1,558 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# ======================================================================== +# Copyright 2006 University of Washington +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# ======================================================================== + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = pith/osdep +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/VERSION \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libpithosd_a_AR = $(AR) $(ARFLAGS) +libpithosd_a_LIBADD = +am_libpithosd_a_OBJECTS = bldpath.$(OBJEXT) canaccess.$(OBJEXT) \ + canonicl.$(OBJEXT) collate.$(OBJEXT) color.$(OBJEXT) \ + coredump.$(OBJEXT) creatdir.$(OBJEXT) debugtime.$(OBJEXT) \ + domnames.$(OBJEXT) err_desc.$(OBJEXT) fgetpos.$(OBJEXT) \ + filesize.$(OBJEXT) fnexpand.$(OBJEXT) hostname.$(OBJEXT) \ + lstcmpnt.$(OBJEXT) mimedisp.$(OBJEXT) pipe.$(OBJEXT) \ + pw_stuff.$(OBJEXT) rename.$(OBJEXT) tempfile.$(OBJEXT) \ + temp_nam.$(OBJEXT) writ_dir.$(OBJEXT) +libpithosd_a_OBJECTS = $(am_libpithosd_a_OBJECTS) +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libpithosd_a_SOURCES) +DIST_SOURCES = $(libpithosd_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +C_CLIENT_CFLAGS = @C_CLIENT_CFLAGS@ +C_CLIENT_GCCOPTLEVEL = @C_CLIENT_GCCOPTLEVEL@ +C_CLIENT_LDFLAGS = @C_CLIENT_LDFLAGS@ +C_CLIENT_SPECIALS = @C_CLIENT_SPECIALS@ +C_CLIENT_TARGET = @C_CLIENT_TARGET@ +C_CLIENT_WITH_IPV6 = @C_CLIENT_WITH_IPV6@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +ISPELLPROG = @ISPELLPROG@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN = @LN@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NPA_PROG = @NPA_PROG@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSUB = @POSUB@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PWPROG = @PWPROG@ +RANLIB = @RANLIB@ +REGEX_BUILD = @REGEX_BUILD@ +RM = @RM@ +SED = @SED@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPELLPROG = @SPELLPROG@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WEB_BINDIR = @WEB_BINDIR@ +WEB_BUILD = @WEB_BUILD@ +WEB_PUBCOOKIE_BUILD = @WEB_PUBCOOKIE_BUILD@ +WEB_PUBCOOKIE_LIB = @WEB_PUBCOOKIE_LIB@ +WEB_PUBCOOKIE_LINK = @WEB_PUBCOOKIE_LINK@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +alpine_interactive_spellcheck = @alpine_interactive_spellcheck@ +alpine_simple_spellcheck = @alpine_simple_spellcheck@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libpithosd.a +libpithosd_a_SOURCES = bldpath.c canaccess.c canonicl.c collate.c color.c coredump.c \ + creatdir.c debugtime.c domnames.c err_desc.c fgetpos.c filesize.c \ + fnexpand.c hostname.c lstcmpnt.c mimedisp.c pipe.c pw_stuff.c \ + rename.c tempfile.c temp_nam.c writ_dir.c + +AM_CPPFLAGS = -I@top_builddir@/include -I@top_srcdir@/include +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign pith/osdep/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign pith/osdep/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libpithosd.a: $(libpithosd_a_OBJECTS) $(libpithosd_a_DEPENDENCIES) + -rm -f libpithosd.a + $(libpithosd_a_AR) libpithosd.a $(libpithosd_a_OBJECTS) $(libpithosd_a_LIBADD) + $(RANLIB) libpithosd.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bldpath.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canaccess.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canonicl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collate.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coredump.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/creatdir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debugtime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/domnames.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/err_desc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fgetpos.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filesize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnexpand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstcmpnt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mimedisp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pw_stuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rename.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/temp_nam.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tempfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writ_dir.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/pith/osdep/ReadMe b/pith/osdep/ReadMe new file mode 100644 index 00000000..30d9c876 --- /dev/null +++ b/pith/osdep/ReadMe @@ -0,0 +1,13 @@ + +README FOR DIRECTORY: pith/osdep/ + + Modules in this directory should provide OS-independent interfaces +for various OS-dependent methods of getting at resources or whatever. +They should compile on their own without pine, c-client or pico +dependencies. + +NOTES: + + "_WINDOWS" currently differentiates windows from unix code. + + "BUG:" comments mean there's something that needs to get worked on diff --git a/pith/osdep/bldpath.c b/pith/osdep/bldpath.c new file mode 100644 index 00000000..62d59e30 --- /dev/null +++ b/pith/osdep/bldpath.c @@ -0,0 +1,190 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: bldpath.c 934 2008-02-23 00:44:29Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> + +#if STDC_HEADERS +#include <ctype.h> +#endif + +#include "bldpath.h" + +/* + * Useful definitions + */ +#ifdef _WINDOWS +#define ROOTED(S) (*(S) == '\\' || (isalpha((unsigned char) (S)[0]) && (S)[1] == ':')) +#define HOMERELATIVE(S) (FALSE) +#else /* UNIX */ +#define ROOTED(S) (*(S) == '/') +#define HOMERELATIVE(S) (*(S) == '~') +#endif + + + + +/*---------------------------------------------------------------------- + Paste together two pieces of a file name path + + Args: pathbuf -- Put the result here + first_part -- of path name + second_part -- of path name + len -- Length of pathbuf + + Result: New path is in pathbuf. Note that + we don't have to check for /'s at end of first_part and beginning + of second_part since multiple slashes are ok. + +BUGS: This is a first stab at dealing with fs naming dependencies, and others +still exist. + ----*/ +void +build_path(char *pathbuf, char *first_part, char *second_part, size_t len) +{ + if(!(pathbuf && len > 0)) + return; + + pathbuf[0] = '\0'; + + if(!first_part || is_rooted_path(second_part)){ + if(second_part) + strncpy(pathbuf, second_part, len-1); + + pathbuf[len-1] = '\0'; + } + else{ +#ifdef _WINDOWS + int i; + char *orig_pathbuf = pathbuf; + + for(i = 0; i < len-2 && first_part[i]; i++) + *pathbuf++ = first_part[i]; + + if(second_part){ + if(i && first_part[i-1] == '\\'){ /* first part ended with \ */ + if(*second_part == '\\') /* and second starts with \ */ + second_part++; /* else just append second */ + } + else if(*second_part != '\\') /* no slash at all, so */ + *pathbuf++ = '\\'; /* insert one... */ + + while(pathbuf-orig_pathbuf < len-1 && *second_part) + *pathbuf++ = *second_part++; + } + + *pathbuf = '\0'; + +#else /* UNIX */ + + size_t fpl = 0; + + strncpy(pathbuf, first_part, len-2); + pathbuf[len-2] = '\0'; + if(second_part){ + if(*pathbuf && pathbuf[(fpl=strlen(pathbuf))-1] != '/'){ + pathbuf[fpl++] = '/'; + pathbuf[fpl] = '\0'; + } + + strncat(pathbuf, second_part, len-1-strlen(pathbuf)); + } + + pathbuf[len-1] = '\0'; + +#endif + } +} + + +/*---------------------------------------------------------------------- + Test to see if the given file path is absolute + + Args: file -- file path to test + + Result: TRUE if absolute, FALSE otw + + ----*/ +int +is_absolute_path(char *path) +{ + return(path && (ROOTED(path) || HOMERELATIVE(path))); +} + + +/* + * homedir_in_path - return pointer to point in path string where home dir + * reference starts + */ +int +is_rooted_path(char *path) +{ + return(path && ROOTED(path)); +} + + +/* + * homedir_in_path - return pointer to point in path string where home dir + * reference starts + */ +int +is_homedir_path(char *path) +{ + return(path && HOMERELATIVE(path)); +} + + +/* + * homedir_in_path - return pointer to point in path string where home dir + * reference starts + */ +char * +homedir_in_path(char *path) +{ +#ifdef _WINDOWS + return(NULL); +#else /* UNIX */ + char *p; + + return((p = strchr(path, '~')) ? p : NULL); +#endif +} + + +/* + * + */ +char * +filename_parent_ref(char *s) +{ +#ifdef _WINDOWS + return(strstr(s, "\\..\\")); +#else /* UNIX */ + return(strstr(s, "/../")); +#endif +} + + +int +filename_is_restricted(char *s) +{ +#ifdef _WINDOWS + return(filename_parent_ref(s) != NULL); +#else /* UNIX */ + return(strchr("./~", s[0]) != NULL || filename_parent_ref(s) != NULL); +#endif +} diff --git a/pith/osdep/bldpath.h b/pith/osdep/bldpath.h new file mode 100644 index 00000000..16ec8226 --- /dev/null +++ b/pith/osdep/bldpath.h @@ -0,0 +1,29 @@ +/* + * $Id: bldpath.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_BLDPATH_INCLUDED +#define PITH_OSDEP_BLDPATH_INCLUDED + + +void build_path(char *, char *, char *, size_t); +int is_absolute_path(char *); +int is_rooted_path(char *); +int is_homedir_path(char *); +char *homedir_in_path(char *); +char *filename_parent_ref(char *); +int filename_is_restricted(char *); + + +#endif /* PITH_OSDEP_BLDPATH_INCLUDED */ diff --git a/pith/osdep/canaccess.c b/pith/osdep/canaccess.c new file mode 100644 index 00000000..4d79c407 --- /dev/null +++ b/pith/osdep/canaccess.c @@ -0,0 +1,160 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: canaccess.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2007 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include "bldpath.h" +#include "fnexpand.h" +#include "../charconv/utf8.h" +#include "../charconv/filesys.h" +#include "canaccess.h" + + +/* + * Useful definitions + */ +#ifdef _WINDOWS + +#define ACCESS_IN_CWD(F,M) (can_access((F), (M))) +#define PATH_SEP ';' +#define FILE_SEP '\\' + +#else /* UNIX */ + +#define ACCESS_IN_CWD(F,M) (-1) +#define PATH_SEP ':' +#define FILE_SEP '/' + +#endif /* UNIX */ + + + +/* + * Check if we can access a file in a given way + * + * Args: file -- The file to check + * mode -- The mode ala the access() system call, see ACCESS_EXISTS + * and friends in alpine.h. + * + * Result: returns 0 if the user can access the file according to the mode, + * -1 if he can't (and errno is set). + * + * + */ +int +can_access(char *file, int mode) +{ +#ifdef _WINDOWS + struct stat buf; + + /* + * NOTE: The WinNT access call returns that every directory is readable and + * writable. We actually want to know if the write is going to fail, so we + * try it. We don't read directories in Windows so we skip implementing that. + */ + if(mode & WRITE_ACCESS && file && !our_stat(file, &buf) && (buf.st_mode & S_IFMT) == S_IFDIR){ + char *testname; + int fd; + size_t l = 0; + + /* + * We'd like to just call temp_nam here, since it creates a file + * and does what we want. However, temp_nam calls us! + */ + if((testname = malloc(MAXPATH * sizeof(char)))){ + strncpy(testname, file, MAXPATH-1); + testname[MAXPATH-1] = '\0'; + if(testname[0] && testname[(l=strlen(testname))-1] != '\\' && + l+1 < MAXPATH){ + l++; + strncat(testname, "\\", MAXPATH-strlen(testname)-1); + testname[MAXPATH-1] = '\0'; + } + + if(l+8 < MAXPATH && + strncat(testname, "caXXXXXX", MAXPATH-strlen(testname)-1) && mktemp(testname)){ + if((fd = our_open(testname, O_CREAT|O_EXCL|O_WRONLY|O_BINARY, 0600)) >= 0){ + (void)close(fd); + our_unlink(testname); + free(testname); + /* success, drop through to access call */ + } + else{ + free(testname); + /* can't write in the directory */ + return(-1); + } + } + else{ + free(testname); + return(-1); + } + } + } + if(mode & EXECUTE_ACCESS) /* Windows access has no execute mode */ + mode &= ~EXECUTE_ACCESS; /* and crashes because of it */ +#endif /* WINDOWS */ + + return(our_access(file, mode)); +} + + +/*---------------------------------------------------------------------- + Check if we can access a file in a given way in the given path + + Args: path -- The path to look for "file" in + file -- The file to check + mode -- The mode ala the access() system call, see ACCESS_EXISTS + and friends in alpine.h. + + Result: returns 0 if the user can access the file according to the mode, + -1 if he can't (and errno is set). + ----*/ +int +can_access_in_path(char *path, char *file, int mode) +{ + char tmp[MAXPATH]; + int rv = -1; + + if(!path || !*path || is_rooted_path(file)){ + rv = can_access(file, mode); + } + else if(is_homedir_path(file)){ + strncpy(tmp, file, sizeof(tmp)); + tmp[sizeof(tmp)-1] = '\0'; + rv = fnexpand(tmp, sizeof(tmp)) ? can_access(tmp, mode) : -1; + } + else if((rv = ACCESS_IN_CWD(file,mode)) < 0){ + char path_copy[MAXPATH + 1], *p, *t; + + if(strlen(path) < MAXPATH){ + strncpy(path_copy, path, sizeof(path_copy)); + path_copy[sizeof(path_copy)-1] = '\0'; + + for(p = path_copy; p && *p; p = t){ + if((t = strchr(p, PATH_SEP)) != NULL) + *t++ = '\0'; + + snprintf(tmp, sizeof(tmp), "%s%c%s", p, FILE_SEP, file); + if((rv = can_access(tmp, mode)) == 0) + break; + } + } + } + + return(rv); +} diff --git a/pith/osdep/canaccess.h b/pith/osdep/canaccess.h new file mode 100644 index 00000000..13ff7cf1 --- /dev/null +++ b/pith/osdep/canaccess.h @@ -0,0 +1,51 @@ +/* + * $Id: canaccess.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_CANACCESS_INCLUDED +#define PITH_OSDEP_CANACCESS_INCLUDED + + +#define EXECUTE_ACCESS 0x01 /* These five are */ +#define WRITE_ACCESS 0x02 /* for the calls */ +#define READ_ACCESS 0x04 /* to access() */ +#define ACCESS_EXISTS 0x00 /* <etc> */ +#define EDIT_ACCESS (WRITE_ACCESS + READ_ACCESS) + +/* + * These flags are used in calls to so_get. + * They're OR'd together with the ACCESS flags above but + * are otherwise unrelated. + */ +#define OWNER_ONLY 0x08 /* open with mode 0600 */ +/* + * If the storage object being written to needs to be converted to + * the character set of the user's locale, then use this flag. For + * example, when exporting to a file. Do not use this if the data + * will eventually go to the display because the data is expected + * to remain as UTF-8 until it gets to Writechar where it will be + * converted. + */ +#define WRITE_TO_LOCALE 0x10 /* convert to locale-specific charset */ +#define READ_FROM_LOCALE 0x20 /* convert from locale-specific charset */ + + +/* + * Exported Prototypes + */ +int can_access(char *, int); +int can_access_in_path(char *, char *, int); + + +#endif /* PITH_OSDEP_CANACCESS_INCLUDED */ diff --git a/pith/osdep/canonicl.c b/pith/osdep/canonicl.c new file mode 100644 index 00000000..09791148 --- /dev/null +++ b/pith/osdep/canonicl.c @@ -0,0 +1,71 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: canonicl.c 764 2007-10-23 23:44:49Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include "../../c-client/mail.h" +extern unsigned char *lcase(unsigned char *); + +#ifdef _WINDOWS +/* wingdi.h uses ERROR (!) and we aren't using the c-client ERROR so... */ +#undef ERROR +#endif + +#include <system.h> + +#include "canonicl.h" + + +/*---------------------------------------------------------------------- + Return canonical form of host name ala c-client (UNIX version). + + Args: host -- The host name + + Result: Canonical form, or input argument (worst case) + + You can call it twice without worrying about copying + the results, but not more than twice. + ----*/ +char * +canonical_name(char *host) +{ + struct hostent *hent; + char tmp[MAILTMPLEN]; + static int whichbuf = 0; + static char buf[2][NETMAXHOST+1]; + char *b; + + whichbuf = (whichbuf + 1) % 2; + b = buf[whichbuf]; + + /* domain literal is easy */ + if (host[0] == '[' && host[(strlen (host))-1] == ']') + strncpy(b, host, NETMAXHOST); + else{ + strncpy(tmp, host, sizeof(tmp)-1); + tmp[sizeof(tmp)-1] = '\0'; + + hent = gethostbyname((char *) lcase((unsigned char *) tmp)); + if(hent && hent->h_name) + strncpy(b, hent->h_name, NETMAXHOST); + else + strncpy(b, host, NETMAXHOST); + } + + b[NETMAXHOST] = '\0'; + return(b); +} + + diff --git a/pith/osdep/canonicl.h b/pith/osdep/canonicl.h new file mode 100644 index 00000000..97c05b93 --- /dev/null +++ b/pith/osdep/canonicl.h @@ -0,0 +1,26 @@ +/* + * $Id: canonicl.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_CANONICL_INCLUDED +#define PITH_OSDEP_CANONICL_INCLUDED + + +/* + * Exported Prototypes + */ +char *canonical_name(char *); + + +#endif /* PITH_OSDEP_CANONICL_INCLUDED */ diff --git a/pith/osdep/collate.c b/pith/osdep/collate.c new file mode 100644 index 00000000..9a60379c --- /dev/null +++ b/pith/osdep/collate.c @@ -0,0 +1,170 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: collate.c 766 2007-10-23 23:59:00Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> + +#include "collate.h" + + +/* + * global hook + */ +int (*pcollator)(); + + +void +set_collation(int collation, int ctype) +{ + extern int collator(); /* set to strcoll if available in system.h */ + + pcollator = strucmp; + +#ifdef LC_COLLATE + if(collation){ + char *status = NULL; + + /* + * This may not have the desired effect, if collator is not + * defined to be strcoll in os.h and strcmp and friends + * don't know about locales. If your system does have strcoll + * but we haven't defined collator to be strcoll in os.h, let us know. + */ + status = setlocale(LC_COLLATE, ""); + + /* + * If there is an error or if the locale is the "C" locale, then we + * don't want to use strcoll because in the default "C" locale strcoll + * uses strcmp ordering and we want strucmp ordering. + * + * The problem with this is that setlocale returns a string which is + * not equal to "C" on some systems even when the locale is "C", so we + * can't really tell on those systems. On some systems like that, we + * may end up with a strcmp-style collation instead of a strucmp-style. + * We recommend that the users of those systems explicitly set + * LC_COLLATE in their environment. + */ + if(status && !(status[0] == 'C' && status[1] == '\0')) + pcollator = collator; + } +#endif +#ifdef LC_CTYPE + if(ctype){ + (void)setlocale(LC_CTYPE, ""); + } +#endif + +#ifdef LC_TIME + setlocale(LC_TIME, ""); +#endif +} + + +/* + * sstrcasecmp - compare two pointers to strings case independently + */ +int +sstrcasecmp(const qsort_t *s1, const qsort_t *s2) +{ + return((*pcollator)(*(char **)s1, *(char **)s2)); +} + + +#ifndef _WINDOWS + +/*-------------------------------------------------- + A case insensitive strcmp() + + Args: o, r -- The two strings to compare + + Result: integer indicating which is greater + ---*/ +int +strucmp(register char *o, register char *r) +{ + if(o == NULL){ + if(r == NULL) + return 0; + else + return -1; + } + else if(r == NULL) + return 1; + + while(*o && *r + && ((isupper((unsigned char)(*o)) + ? (unsigned char)tolower((unsigned char)(*o)) + : (unsigned char)(*o)) + == (isupper((unsigned char)(*r)) + ? (unsigned char)tolower((unsigned char)(*r)) + : (unsigned char)(*r)))){ + o++; + r++; + } + + return((isupper((unsigned char)(*o)) + ? tolower((unsigned char)(*o)) + : (int)(unsigned char)(*o)) + - (isupper((unsigned char)(*r)) + ? tolower((unsigned char)(*r)) + : (int)(unsigned char)(*r))); +} + +/*---------------------------------------------------------------------- + A case insensitive strncmp() + + Args: o, r -- The two strings to compare + n -- length to stop comparing strings at + + Result: integer indicating which is greater + + ----*/ +int +struncmp(register char *o, register char *r, register int n) +{ + if(n < 1) + return 0; + + if(o == NULL){ + if(r == NULL) + return 0; + else + return -1; + } + else if(r == NULL) + return 1; + + n--; + while(n && *o && *r + && ((isupper((unsigned char)(*o)) + ? (unsigned char)tolower((unsigned char)(*o)) + : (unsigned char)(*o)) + == (isupper((unsigned char)(*r)) + ? (unsigned char)tolower((unsigned char)(*r)) + : (unsigned char)(*r)))){ + o++; + r++; + n--; + } + + return((isupper((unsigned char)(*o)) + ? tolower((unsigned char)(*o)) + : (int)(unsigned char)(*o)) + - (isupper((unsigned char)(*r)) + ? tolower((unsigned char)(*r)) + : (int)(unsigned char)(*r))); +} +#endif diff --git a/pith/osdep/collate.h b/pith/osdep/collate.h new file mode 100644 index 00000000..80aaab90 --- /dev/null +++ b/pith/osdep/collate.h @@ -0,0 +1,32 @@ +/* + * $Id: collate.h 925 2008-02-06 02:03:01Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_COLLATE_INCLUDED +#define PITH_OSDEP_COLLATE_INCLUDED + + +/* + * Exported Prototypes + */ +void set_collation(int, int); +int strucmp(char *, char *); +int struncmp(char *, char *, int); +int sstrcasecmp(const qsort_t *, const qsort_t *); + +extern int (*pcollator)(); + + +#endif /* PITH_OSDEP_COLLATE_INCLUDED */ diff --git a/pith/osdep/color.c b/pith/osdep/color.c new file mode 100644 index 00000000..faf3c675 --- /dev/null +++ b/pith/osdep/color.c @@ -0,0 +1,93 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: color.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + + /* + * + * These routines themselves aren't necessarily OS-specific, they + * are all called from within pico, pine and webpine. + * + * They used to be in pico source (osdep/unix, mswin.c), but considering + * webpine uses color as well and it should *not* have to be linked + * against libpico and considering pico uses these routines but should + * not have to link against libpith (and in turn c-client) we put them + * in pith/osdep which should only have to link against system libraries + * and thus be include freely in all of pine, pico and webpine. + */ + + +#include <system.h> +#include "./color.h" + + + +/* + * new_color_pair - allocate a new color pair structure assigning + * given foreground and background color strings + */ +COLOR_PAIR * +new_color_pair(char *fg, char *bg) +{ + COLOR_PAIR *ret; + + if((ret = (COLOR_PAIR *) malloc(sizeof(*ret))) != NULL){ + memset(ret, 0, sizeof(*ret)); + if(fg){ + strncpy(ret->fg, fg, MAXCOLORLEN); + ret->fg[MAXCOLORLEN] = '\0'; + } + + if(bg){ + strncpy(ret->bg, bg, MAXCOLORLEN); + ret->bg[MAXCOLORLEN] = '\0'; + } + } + + return(ret); +} + + +/* + * free_color_pair - release resources associated with given + * color pair structure + */ +void +free_color_pair(COLOR_PAIR **cp) +{ + if(cp && *cp){ + free(*cp); + *cp = NULL; + } +} + + +/* + * Just like pico_set_color except it doesn't set the color, it just + * returns the value. Assumes def of PSC_NONE, since otherwise we always + * succeed and don't need to call this. + */ +int +pico_is_good_colorpair(COLOR_PAIR *cp) +{ + return(cp && pico_is_good_color(cp->fg) && pico_is_good_color(cp->bg)); +} + + +COLOR_PAIR * +pico_set_colorp(COLOR_PAIR *col, int flags) +{ + return(pico_set_colors(col ? col->fg : NULL, col ? col->bg : NULL, flags)); +} diff --git a/pith/osdep/color.h b/pith/osdep/color.h new file mode 100644 index 00000000..32c86242 --- /dev/null +++ b/pith/osdep/color.h @@ -0,0 +1,98 @@ +/* + * $Id: color.h 1012 2008-03-26 00:44:22Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_COLOR_INCLUDED +#define PITH_OSDEP_COLOR_INCLUDED + + +#define RGBLEN 11 +#define MAXCOLORLEN 11 /* longest string a color can be */ + +typedef struct COLOR_PAIR { + char fg[MAXCOLORLEN+1]; + char bg[MAXCOLORLEN+1]; +} COLOR_PAIR; + +#define COL_BLACK 0 +#define COL_RED 1 +#define COL_GREEN 2 +#define COL_YELLOW 3 +#define COL_BLUE 4 +#define COL_MAGENTA 5 +#define COL_CYAN 6 +#define COL_WHITE 7 + +#define DEFAULT_NORM_FORE_RGB "000,000,000" +#define DEFAULT_NORM_BACK_RGB "255,255,255" + +/* flags for pico_set_color() */ +#define PSC_NONE 0x0 +#define PSC_NORM 0x1 +#define PSC_REV 0x2 +#define PSC_RET 0x4 /* return an allocated copy of previous color */ + + +/* + * MATCH_NORM_COLOR means that the color that is set to this value + * will actually use the corresponding fg or bg color from the + * so called Normal Color. A MATCH_NONE_COLOR means that the + * corresponding fg or bg color will just be left alone, so that + * it will stay the same as it was. This is useful when you want + * to change the foreground color but let the background match + * whatever it was before, for example in colored index lines. + * + * Note: these need to be RGBLEN in length because they are sometimes + * used in places where an RGB value is expected. + */ +#define MATCH_NORM_COLOR "norm_padded" +#define MATCH_NONE_COLOR "none_padded" + +#define MATCH_TRAN_COLOR "transparent" + + +/* exported prototypes */ +COLOR_PAIR *new_color_pair(char *, char *); +void free_color_pair(COLOR_PAIR **cp); +int pico_is_good_colorpair(COLOR_PAIR *); +COLOR_PAIR *pico_set_colorp(COLOR_PAIR *, int); + + +/* required prototypes (os/app dependent ) */ +int pico_usingcolor(void); +int pico_hascolor(void); +char *colorx(int); +char *color_to_asciirgb(char *); +int pico_is_good_color(char *); +COLOR_PAIR *pico_set_colors(char *, char *, int); +int pico_set_fg_color(char *); +int pico_set_bg_color(char *); +void pico_nfcolor(char *); +void pico_nbcolor(char *); +void pico_rfcolor(char *); +void pico_rbcolor(char *); +COLOR_PAIR *pico_get_cur_color(void); +COLOR_PAIR *pico_get_rev_color(void); +void pico_set_normal_color(void); +void pico_set_color_options(unsigned); +unsigned pico_get_color_options(void); +int pico_trans_is_on(void); +char *pico_get_last_fg_color(void); +char *pico_get_last_bg_color(void); +char *color_to_canonical_name(char *); +int pico_count_in_color_table(void); + + +#endif /* PITH_OSDEP_COLOR_INCLUDED */ diff --git a/pith/osdep/coredump.c b/pith/osdep/coredump.c new file mode 100644 index 00000000..52ad27d7 --- /dev/null +++ b/pith/osdep/coredump.c @@ -0,0 +1,31 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: coredump.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include "coredump.h" + + +/*---------------------------------------------------------------------- + Abort with a core dump + ----*/ +void +coredump(void) +{ + abort(); +} + + diff --git a/pith/osdep/coredump.h b/pith/osdep/coredump.h new file mode 100644 index 00000000..05c95a62 --- /dev/null +++ b/pith/osdep/coredump.h @@ -0,0 +1,26 @@ +/* + * $Id: coredump.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_COREDUMP_INCLUDED +#define PITH_OSDEP_COREDUMP_INCLUDED + + +/* + * Exported Prototypes + */ +void coredump(void); + + +#endif /* PITH_OSDEP_COREDUMP_INCLUDED */ diff --git a/pith/osdep/creatdir.c b/pith/osdep/creatdir.c new file mode 100644 index 00000000..bc15da21 --- /dev/null +++ b/pith/osdep/creatdir.c @@ -0,0 +1,55 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: creatdir.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2007 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include "../charconv/utf8.h" +#include "../charconv/filesys.h" +#include "creatdir.h" + + +#ifdef S_IRWXU +#define MAILDIR_MODE S_IRWXU +#else +#define MAILDIR_MODE 0700 +#endif + + + +/*---------------------------------------------------------------------- + Create the mail subdirectory. + + Args: dir -- Name of the directory to create + + Result: Directory is created. Returns 0 on success, else -1 on error + and errno is valid. + ----*/ +int +create_mail_dir(char *dir) +{ + if(our_mkdir(dir, MAILDIR_MODE) < 0) + return(-1); + +#ifndef _WINDOWS + our_chmod(dir, MAILDIR_MODE); + + /* Some systems need this, on others we don't care if it fails */ + our_chown(dir, getuid(), getgid()); +#endif /* !_WINDOWS */ + + return(0); +} diff --git a/pith/osdep/creatdir.h b/pith/osdep/creatdir.h new file mode 100644 index 00000000..496d1f6c --- /dev/null +++ b/pith/osdep/creatdir.h @@ -0,0 +1,26 @@ +/* + * $Id: creatdir.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_CREATDIR_INCLUDED +#define PITH_OSDEP_CREATDIR_INCLUDED + + +/* + * Exported Prototypes + */ +int create_mail_dir(char *); + + +#endif /* PITH_OSDEP_CREATDIR_INCLUDED */ diff --git a/pith/osdep/debugtime.c b/pith/osdep/debugtime.c new file mode 100644 index 00000000..a1ee3b2a --- /dev/null +++ b/pith/osdep/debugtime.c @@ -0,0 +1,133 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: debugtime.c 770 2007-10-24 00:23:09Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <stdio.h> + +#include <system.h> +#include "debugtime.h" + +#ifdef DEBUG + +/* + * Returns a pointer to static string for a timestamp. + * + * If timestamp is set .subseconds are added if available. + * If include_date is set the date is appended. + */ +char * +debug_time(int include_date, int include_subseconds) +{ + time_t t; + struct tm *tm_now; +#if HAVE_GETTIMEOFDAY + struct timeval tp; + struct timezone tzp; +#else + struct _timeb timebuffer; +#endif + static char timestring[23]; + char subsecond[8]; + char datestr[7]; + + timestring[0] = '\0'; + +#if HAVE_GETTIMEOFDAY + if(gettimeofday(&tp, &tzp) == 0){ + t = (time_t)tp.tv_sec; + if(include_date){ + tm_now = localtime(&t); + snprintf(datestr, sizeof(datestr), " %d/%d", tm_now->tm_mon+1, tm_now->tm_mday); + } + else + datestr[0] = '\0'; + + if(include_subseconds) + snprintf(subsecond, sizeof(subsecond), ".%06ld", tp.tv_usec); + else + subsecond[0] = '\0'; + + snprintf(timestring, sizeof(timestring), "%.8s%.7s%.6s", ctime(&t)+11, subsecond, datestr); + } +#else /* !HAVE_GETTIMEOFDAY */ + /* Should be _WINDOWS */ + t = time((time_t *)0); + if(include_date){ + tm_now = localtime(&t); + snprintf(datestr, sizeof(datestr), " %d/%d", tm_now->tm_mon+1, tm_now->tm_mday); + } + else + datestr[0] = '\0'; + + if(include_subseconds){ + _ftime(&timebuffer); + snprintf(subsecond, sizeof(subsecond), ".%03ld", timebuffer.millitm); + } + else + subsecond[0] = '\0'; + + snprintf(timestring, sizeof(timestring), "%.8s%.7s%.6s", ctime(&t)+11, subsecond, datestr); +#endif /* HAVE_GETTIMEOFDAY */ + + return(timestring); +} +#endif /* DEBUG */ + + +/* + * Fills in the passed in structure with the current time. + * + * Returns 0 if ok + * -1 if can't do it + */ +int +get_time(TIMEVAL_S *our_time_val) +{ +#if HAVE_GETTIMEOFDAY + struct timeval tp; + struct timezone tzp; + + if(gettimeofday(&tp, &tzp) == 0){ + our_time_val->sec = tp.tv_sec; + our_time_val->usec = tp.tv_usec; + return 0; + } +#else /* !HAVE_GETTIMEOFDAY */ +#ifdef _WINDOWS + struct _timeb timebuffer; + + _ftime(&timebuffer); + our_time_val->sec = (long)timebuffer.time; + our_time_val->usec = 1000L * (long)timebuffer.millitm; + return 0; +#endif +#endif + + return -1; +} + + +/* + * Returns the difference between the two values, in microseconds. + * Value returned is first - second. + */ +long +time_diff(TIMEVAL_S *first, TIMEVAL_S *second) +{ + return(1000000L*(first->sec - second->sec) + (first->usec - second->usec)); +} + + diff --git a/pith/osdep/debugtime.h b/pith/osdep/debugtime.h new file mode 100644 index 00000000..6a3eda1e --- /dev/null +++ b/pith/osdep/debugtime.h @@ -0,0 +1,31 @@ +/* + * $Id: debugtime.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_DEBUGTIME_INCLUDED +#define PITH_OSDEP_DEBUGTIME_INCLUDED + +#include "../adjtime.h" + +/* + * Exported Prototypes + */ +#ifdef DEBUG +char *debug_time(int, int); +#endif +int get_time(TIMEVAL_S *); +long time_diff(TIMEVAL_S *, TIMEVAL_S *); + + +#endif /* PITH_OSDEP_DEBUGTIME_INCLUDED */ diff --git a/pith/osdep/domnames.c b/pith/osdep/domnames.c new file mode 100644 index 00000000..47a95278 --- /dev/null +++ b/pith/osdep/domnames.c @@ -0,0 +1,145 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: domnames.c 1176 2008-09-29 21:16:42Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2008 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include <general.h> + +#include "domnames.h" + + +/*---------------------------------------------------------------------- + Get the current host and domain names + + Args: hostname -- buffer to return the hostname in + hsize -- size of buffer above + domainname -- buffer to return domain name in + dsize -- size of buffer above + + Result: The system host and domain names are returned. If the full host + name is akbar.cac.washington.edu then the domainname is + cac.washington.edu. + +On Internet connected hosts this look up uses /etc/hosts and DNS to +figure all this out. On other less well connected machines some other +file may be read. If there is no notion of a domain name the domain +name may be left blank. On a PC where there really isn't a host name +this should return blank strings. The .pinerc will take care of +configuring the domain names. That is, this should only return the +native system's idea of what the names are if the system has such +a concept. + ----*/ +void +getdomainnames(char *hostname, int hsize, char *domainname, int dsize) +{ +#if HAVE_NETDB_H + char *dn, hname[MAX_ADDRESS+1]; + struct hostent *he; + char **alias; + char *maybe = NULL; + + if(gethostname(hname, MAX_ADDRESS)) + hname[0] = 0xff; + + /* sanity check of hostname string */ + for(dn = hname; (*dn > 0x20) && (*dn < 0x7f); ++dn) + ; + + if(*dn){ /* if invalid string returned, return "unknown" */ + strncpy(domainname, "unknown", dsize-1); + domainname[dsize-1] = '\0'; + strncpy(hostname, "unknown", hsize-1); + hostname[hsize-1] = '\0'; + return; + } + + he = gethostbyname(hname); + hostname[0] = '\0'; + + if(he == NULL){ + strncpy(hostname, hname, hsize-1); + hostname[hsize-1] = '\0'; + } + else{ + /* + * If no dot in hostname it may be the case that there + * is an alias which is really the fully-qualified + * hostname. This could happen if the administrator has + * (incorrectly) put the unqualified name first in the + * hosts file, for example. The problem with looking for + * an alias with a dot is that now we're guessing, since + * the aliases aren't supposed to be the official hostname. + * We'll compromise and only use an alias if the primary + * name has no dot and exactly one of the aliases has a + * dot. + */ + strncpy(hostname, he->h_name, hsize-1); + hostname[hsize-1] = '\0'; + if(strchr(hostname, '.') == NULL){ /* no dot in hostname */ + for(alias = he->h_aliases; *alias; alias++){ + if(strchr(*alias, '.') != NULL){ /* found one */ + if(maybe){ /* oops, this is the second one */ + maybe = NULL; + break; + } + else + maybe = *alias; + } + } + + if(maybe){ + strncpy(hostname, maybe, hsize-1); + hostname[hsize-1] = '\0'; + } + } + } + + hostname[hsize-1] = '\0'; + + if((dn = strchr(hostname, '.')) != NULL) + strncpy(domainname, dn+1, dsize-1); + else + strncpy(domainname, hostname, dsize-1); + + domainname[dsize-1] = '\0'; +#else /* !HAVE_NETDB_H */ + /* should only be _WINDOWS */ + +#ifdef _WINDOWS + char *p; + extern char *mylocalhost(void); + + hostname[0] = domainname[0] = '\0'; + if(p = mylocalhost()) + snprintf(hostname, hsize, "%s", p); + + snprintf(domainname, dsize, "%s", + (hostname[0] && hostname[0] != '[' && (p = strchr(hostname,'.'))) + ? p+1 : hostname); +#else /* !_WINDOWS */ + + char *p, hname[MAX_ADDRESS+1]; + + hostname[0] = domainname[0] = '\0'; + if(gethostname(hname, MAX_ADDRESS) == 0) + snprintf(hostname, hsize, "%s", hname); + + snprintf(domainname, dsize, "%s", + (hostname[0] && hostname[0] != '[' && (p = strchr(hostname,'.'))) + ? p+1 : hostname); +#endif /* !_WINDOWS */ +#endif /* !HAVE_NETDB_H */ +} diff --git a/pith/osdep/domnames.h b/pith/osdep/domnames.h new file mode 100644 index 00000000..303561a7 --- /dev/null +++ b/pith/osdep/domnames.h @@ -0,0 +1,26 @@ +/* + * $Id: domnames.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_DOMNAMES_INCLUDED +#define PITH_OSDEP_DOMNAMES_INCLUDED + + +/* + * Exported Prototypes + */ +void getdomainnames(char *, int, char *, int); + + +#endif /* PITH_OSDEP_DOMNAMES_INCLUDED */ diff --git a/pith/osdep/err_desc.c b/pith/osdep/err_desc.c new file mode 100644 index 00000000..645953e9 --- /dev/null +++ b/pith/osdep/err_desc.c @@ -0,0 +1,44 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: err_desc.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include "err_desc.h" + + +/*---------------------------------------------------------------------- + Return string describing the error + + Args: errnumber -- The system error number (errno) + + Result: long string describing the error is returned + ----*/ +char * +error_description(int errnumber) +{ + static char buffer[50+1]; + + buffer[0] = '\0'; + + if(errnumber >= 0) + snprintf(buffer, sizeof(buffer), "%s", strerror(errnumber)); + else + snprintf(buffer, sizeof(buffer), "Unknown error #%d", errnumber); + + return ( (char *) buffer); +} + + diff --git a/pith/osdep/err_desc.h b/pith/osdep/err_desc.h new file mode 100644 index 00000000..9fff814e --- /dev/null +++ b/pith/osdep/err_desc.h @@ -0,0 +1,26 @@ +/* + * $Id: err_desc.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_ERR_DESC_INCLUDED +#define PITH_OSDEP_ERR_DESC_INCLUDED + + +/* + * Exported Prototypes + */ +char *error_description(int); + + +#endif /* PITH_OSDEP_ERR_DESC_INCLUDED */ diff --git a/pith/osdep/fgetpos.c b/pith/osdep/fgetpos.c new file mode 100644 index 00000000..94dcc6c0 --- /dev/null +++ b/pith/osdep/fgetpos.c @@ -0,0 +1,50 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: fgetpos.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <stdio.h> +#include "fgetpos.h" + + +/*---------------------------------------------------------------------- + This is just a call to the ANSI C fgetpos function. + ----*/ +int +fget_pos(FILE *stream, fpos_t *ptr) +{ +#ifdef IS_NON_ANSI + *ptr = (fpos_t)ftell(stream); + return (*ptr == -1L ? -1 : 0); +#else /* ANSI */ + return(fgetpos(stream, ptr)); +#endif /* ANSI */ +} + + +/*---------------------------------------------------------------------- + This is just a call to the ANSI C fsetpos function. + ----*/ +int +fset_pos(FILE *stream, fpos_t *ptr) +{ +#ifdef IS_NON_ANSI + return fseek(stream, *ptr, 0); +#else /* ANSI */ + return(fsetpos(stream, ptr)); +#endif /* ANSI */ +} + + diff --git a/pith/osdep/fgetpos.h b/pith/osdep/fgetpos.h new file mode 100644 index 00000000..32fb7f33 --- /dev/null +++ b/pith/osdep/fgetpos.h @@ -0,0 +1,27 @@ +/* + * $Id: fgetpos.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_FGETPOS_INCLUDED +#define PITH_OSDEP_FGETPOS_INCLUDED + + +/* + * Exported Prototypes + */ +int fget_pos(FILE *, fpos_t *); +int fset_pos(FILE *, fpos_t *); + + +#endif /* PITH_OSDEP_FGETPOS_INCLUDED */ diff --git a/pith/osdep/filesize.c b/pith/osdep/filesize.c new file mode 100644 index 00000000..e96479e9 --- /dev/null +++ b/pith/osdep/filesize.c @@ -0,0 +1,123 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: filesize.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include "../charconv/utf8.h" +#include "../charconv/filesys.h" +#include "filesize.h" + + +/*---------------------------------------------------------------------- + Return the number of bytes in given file + + Args: file -- file name + + Result: the number of bytes in the file is returned or + -1 on error, in which case errno is valid + ----*/ +long +name_file_size(char *file) +{ + struct stat buffer; + + if(our_stat(file, &buffer) != 0) + return(-1L); + + return((long)buffer.st_size); +} + + +/*---------------------------------------------------------------------- + Return the number of bytes in given file + + Args: fp -- FILE * for open file + + Result: the number of bytes in the file is returned or + -1 on error, in which case errno is valid + ----*/ +long +fp_file_size(FILE *fp) +{ + struct stat buffer; + + if(fstat(fileno(fp), &buffer) != 0) + return(-1L); + + return((long)buffer.st_size); +} + + +/*---------------------------------------------------------------------- + Return the modification time of given file + + Args: file -- file name + + Result: the time of last modification (mtime) of the file is returned or + -1 on error, in which case errno is valid + ----*/ +time_t +name_file_mtime(char *file) +{ + struct stat buffer; + + if(our_stat(file, &buffer) != 0) + return((time_t)(-1)); + + return(buffer.st_mtime); +} + + +/*---------------------------------------------------------------------- + Return the modification time of given file + + Args: fp -- FILE * for open file + + Result: the time of last modification (mtime) of the file is returned or + -1 on error, in which case errno is valid + ----*/ +time_t +fp_file_mtime(FILE *fp) +{ + struct stat buffer; + + if(fstat(fileno(fp), &buffer) != 0) + return((time_t)(-1)); + + return(buffer.st_mtime); +} + + +/*---------------------------------------------------------------------- + Copy the mode, owner, and group of sourcefile to targetfile. + + Args: targetfile -- + sourcefile -- + + We don't bother keeping track of success or failure because we don't care. + ----*/ +void +file_attrib_copy(char *targetfile, char *sourcefile) +{ + struct stat buffer; + + if(our_stat(sourcefile, &buffer) == 0){ + our_chmod(targetfile, buffer.st_mode); +#if HAVE_CHOWN + our_chown(targetfile, buffer.st_uid, buffer.st_gid); +#endif + } +} diff --git a/pith/osdep/filesize.h b/pith/osdep/filesize.h new file mode 100644 index 00000000..a80297dc --- /dev/null +++ b/pith/osdep/filesize.h @@ -0,0 +1,31 @@ +/* + * $Id: filesize.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_FILESIZE_INCLUDED +#define PITH_OSDEP_FILESIZE_INCLUDED + + +/* + * Exported Prototypes + */ +long name_file_size(char *); +long fp_file_size(FILE *); +time_t name_file_mtime(char *); +time_t fp_file_mtime(FILE *); +void file_attrib_copy(char *, char *); + + + +#endif /* PITH_OSDEP_FILESIZE_INCLUDED */ diff --git a/pith/osdep/fnexpand.c b/pith/osdep/fnexpand.c new file mode 100644 index 00000000..1856c231 --- /dev/null +++ b/pith/osdep/fnexpand.c @@ -0,0 +1,96 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: fnexpand.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> + +#include "../charconv/filesys.h" + +#include "fnexpand.h" + + + + +/*---------------------------------------------------------------------- + Expand the ~ in a file ala the csh (as home directory) + + Args: buf -- The filename to expand (nothing happens unless begins with ~) + len -- The length of the buffer passed in (expansion is in place) + + Result: Expanded string is returned using same storage as passed in. + If expansion fails, NULL is returned + ----*/ +char * +fnexpand(char *buf, int len) +{ +#ifdef _WINDOWS + /* We used to use ps_global->home_dir, now we have to build it */ + if(*buf == '~' && *(buf+1) == '\\'){ + char temp_path[_MAX_PATH], home_buf[_MAX_PATH], *temp_home_str; + + if(getenv("HOME") != NULL) + temp_home_str = getenv("HOME"); + else{ + /* should eventually strip this out of get_user_info */ + char *p, *q; + + if((p = (char *) getenv("HOMEDRIVE")) + && (q = (char *) getenv("HOMEPATH"))) + snprintf(home_buf, sizeof(home_buf), "%s%s", p, q); + else + snprintf(home_buf, sizeof(home_buf), "%c:\\", '@' + _getdrive()); + + temp_home_str = home_buf; + } + snprintf(temp_path, sizeof(temp_path), "%s", buf+1); + snprintf(buf, sizeof(buf), "%s%s", temp_path, fname_to_utf8(temp_home_str)); + } + return(buf); +#else /* UNIX */ + struct passwd *pw; + register char *x,*y; + char name[20], *tbuf; + + if(*buf == '~') { + for(x = buf+1, y = name; + *x != '/' && *x != '\0' && y < name + sizeof(name)-1; + *y++ = *x++) + ; + + *y = '\0'; + if(x == buf + 1) + pw = getpwuid(getuid()); + else + pw = getpwnam(name); + + if(pw == NULL) + return((char *)NULL); + if(strlen(pw->pw_dir) + strlen(buf) > len) { + return((char *)NULL); + } + + if((tbuf = (char *) malloc((len+1)*sizeof(char))) != NULL){ + snprintf(tbuf, len, "%s%s", pw->pw_dir, x); + snprintf(buf, len, "%s", tbuf); + free((void *)tbuf); + } + } + + return(len ? buf : (char *)NULL); +#endif /* UNIX */ +} + + diff --git a/pith/osdep/fnexpand.h b/pith/osdep/fnexpand.h new file mode 100644 index 00000000..df2dd899 --- /dev/null +++ b/pith/osdep/fnexpand.h @@ -0,0 +1,26 @@ +/* + * $Id: fnexpand.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_FNEXPAND_INCLUDED +#define PITH_OSDEP_FNEXPAND_INCLUDED + + +/* + * Exported Prototypes + */ +char *fnexpand(char *, int); + + +#endif /* PITH_OSDEP_FNEXPAND_INCLUDED */ diff --git a/pith/osdep/forkwait.h b/pith/osdep/forkwait.h new file mode 100644 index 00000000..e1aafa84 --- /dev/null +++ b/pith/osdep/forkwait.h @@ -0,0 +1,39 @@ +/* + * $Id: forkwait.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_FORKWAIT_INCLUDED +#define PITH_OSDEP_FORKWAIT_INCLUDED + + +#if HAVE_UNION_WAIT +#define WAITSTATUS_T union wait +#else +#define WAITSTATUS_T int +#endif + +#ifndef WEXITSTATUS +#define WEXITSTATUS(X) (((X) >> 8) & 0xff) /* high bits tell exit value */ +#endif +#ifndef WIFEXITED +#define WIFEXITED(X) (!((X) & 0xff)) /* low bits tell how it died */ +#endif + +#if !HAVE_WORKING_VFORK +#define vfork fork +#endif + + +#endif /* PITH_OSDEP_FORKWAIT_INCLUDED */ + diff --git a/pith/osdep/hostname.c b/pith/osdep/hostname.c new file mode 100644 index 00000000..6ba445d3 --- /dev/null +++ b/pith/osdep/hostname.c @@ -0,0 +1,119 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: hostname.c 1176 2008-09-29 21:16:42Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2008 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> + +#if HAVE_GETHOSTNAME + +#elif HAVE_UNAME + +#include <sys/utsname.h> + +#elif defined(SYSTEMID) + +#elif defined(XENIX) + +#endif + +#include "hostname.h" + + + +/*---------------------------------------------------------------------- + Call system gethostname + + Args: hostname -- buffer to return host name in + size -- Size of buffer hostname is to be returned in + + Result: returns 0 if the hostname is correctly set, + -1 if not (and errno is set). + ----*/ +int +hostname(char *hostname, int size) +{ +#if HAVE_GETHOSTNAME + + if (gethostname(hostname, size)) + return -1; + + /* sanity check of hostname string */ + for (*dn = hname; (*dn > 0x20) && (*dn < 0x7f); ++dn) + ; + + if (*dn) /* non-ascii in hostname */ + strncpy(hostname, "unknown", size-1); + + hostname[size - 1] = '\0'; + return 0; + +#elif HAVE_UNAME + + /** This routine compliments of Scott McGregor at the HP + Corporate Computing Center **/ + + int uname(struct utsname *); + struct utsname name; + + (void)uname(&name); + (void)strncpy(hostname,name.nodename,size-1); + + hostname[size - 1] = '\0'; + return 0; + +#elif defined(SYSTEMID) + char buf[32]; + FILE *fp; + char *p; + + if ((fp = our_fopen("/etc/systemid", "rb")) != 0) { + fgets(buf, sizeof(buf) - 1, fp); + fclose(fp); + if ((p = strindex(buf, '\n')) != NULL) + *p = '\0'; + (void) strncpy(hostname, buf, size - 1); + hostname[size - 1] = '\0'; + return 0; + } + +#elif defined(XENIX) + +#ifdef DOUNAME + /** This routine compliments of Scott McGregor at the HP + Corporate Computing Center **/ + + int uname(); + struct utsname name; + + (void) uname(&name); + (void) strncpy(hostname,name.nodename,size-1); +#else + (void) strncpy(hostname, HOSTNAME, size-1); +#endif /* DOUNAME */ + + hostname[size - 1] = '\0'; + return 0; +#else + /* We shouldn't get here except for the windows + * case, which currently doesn't use this (as + * it appears nothing else does as well) + */ + return -1; + +#endif +} + + diff --git a/pith/osdep/hostname.h b/pith/osdep/hostname.h new file mode 100644 index 00000000..65303ce4 --- /dev/null +++ b/pith/osdep/hostname.h @@ -0,0 +1,26 @@ +/* + * $Id: hostname.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_HOSTNAME_INCLUDED +#define PITH_OSDEP_HOSTNAME_INCLUDED + + +/* + * Exported Prototypes + */ +int hostname(char *, int); + + +#endif /* PITH_OSDEP_HOSTNAME_INCLUDED */ diff --git a/pith/osdep/lstcmpnt.c b/pith/osdep/lstcmpnt.c new file mode 100644 index 00000000..2a920939 --- /dev/null +++ b/pith/osdep/lstcmpnt.c @@ -0,0 +1,103 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: lstcmpnt.c 1074 2008-06-04 00:08:43Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include <general.h> + +#include <string.h> +#include "../../pith/charconv/filesys.h" +#include "canaccess.h" +#include "lstcmpnt.h" + + +#ifdef _WINDOWS + +#define FILE_SEP '\\' + +#else /* UNIX */ + +#define FILE_SEP '/' + +#endif /* UNIX */ + + + +/*---------------------------------------------------------------------- + Return pointer to last component of pathname. + + Args: filename -- The pathname. + + Result: Returned pointer points to last component in the input argument. + ----*/ +char * +last_cmpnt(char *filename) +{ + char *p = NULL, *q = filename; + + if(filename == NULL) + return(filename); + + while((q = strchr(q, FILE_SEP)) != NULL) + if(*++q) + p = q; + +#ifdef _WINDOWS + + if(!p && isalpha((unsigned char) *filename) && *(filename+1) == ':' && *(filename+2)) + p = filename + 2; + +#endif + + return(p); +} + + +/* + * Like our_mkdir but it makes subdirs as well as the final dir + */ +int +our_mkpath(char *path, mode_t mode) +{ + char save, *q = path; + +#ifdef _WINDOWS + if(isalpha((unsigned char) q[0]) && q[1] == ':' && q[2]) + q = path + 3; +#endif + + if(q == path && q[0] == FILE_SEP) + q = path + 1; + + while((q = strchr(q, FILE_SEP)) != NULL){ + save = *q; + *q = '\0'; + if(can_access(path, ACCESS_EXISTS) != 0) + if(our_mkdir(path, mode) != 0){ + *q = save; + return -1; + } + + *q = save; + q++; + } + + if(can_access(path, ACCESS_EXISTS) != 0 && our_mkdir(path, mode) != 0) + return -1; + + return 0; +} diff --git a/pith/osdep/lstcmpnt.h b/pith/osdep/lstcmpnt.h new file mode 100644 index 00000000..f2d9ec59 --- /dev/null +++ b/pith/osdep/lstcmpnt.h @@ -0,0 +1,28 @@ +/* + * $Id: lstcmpnt.h 1074 2008-06-04 00:08:43Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_LSTCMPNT_INCLUDED +#define PITH_OSDEP_LSTCMPNT_INCLUDED + + +/* + * Exported Prototypes + */ +char *last_cmpnt(char *); +int our_mkpath(char *, mode_t); + + +#endif /* PITH_OSDEP_LSTCMPNT_INCLUDED */ diff --git a/pith/osdep/makefile.wnt b/pith/osdep/makefile.wnt new file mode 100644 index 00000000..5b0cc0c8 --- /dev/null +++ b/pith/osdep/makefile.wnt @@ -0,0 +1,65 @@ +# $Id: makefile.wnt 14098 2005-10-03 18:54:13Z jpf@u.washington.edu $ +# +# ======================================================================== +# Copyright 2006 University of Washington +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# ======================================================================== + +# +# +# Makefile for WIN NT version of the libpith.lib +# +# +CC=cl +RM=del +CP=copy +RC=rc + +#includes symbol info for debugging +CDEBUG= #-Zi -Od +LDEBUG= /DEBUG /DEBUGTYPE:CV + +STDCFLAGS= -I..\..\include -I..\..\regex -nologo -MT -DWIN32 -DDOS -D_WINDOWS -DJOB_CONTROL -DMSC_MALLOC + +CFLAGS= $(CDEBUG) $(STDCFLAGS) $(NET) $(EXTRACFLAGS) + +LFLAGS= $(LDEBUG) $(EXTRALDFLAGS) + +RCFLAGS = + +LIBER=lib +LIBARGS=/nologo /verbose + +HFILES= ../../include/system.h ../../include/general.h \ + bldpath.h canaccess.h canonicl.h collate.h color.h coredump.h \ + creatdir.h debugtime.h domnames.h err_desc.h fgetpos.h filesize.h \ + fnexpand.h forkwait.h hostname.h lstcmpnt.h mimedisp.h pipe.h \ + pithosd.h pw_stuff.h rename.h tempfile.h temp_nam.h \ + writ_dir.h + +OFILES= bldpath.obj canaccess.obj canonicl.obj collate.obj color.obj coredump.obj \ + creatdir.obj debugtime.obj domnames.obj err_desc.obj fgetpos.obj filesize.obj \ + fnexpand.obj hostname.obj lstcmpnt.obj mimedisp.obj pipe.obj \ + pw_stuff.obj rename.obj tempfile.obj temp_nam.obj \ + writ_dir.obj + +all: libpithosd.lib + +.c.obj: + $(CC) -c $(CFLAGS) "$(MAKEDIR)"\$*.c + +$(OFILES): $(HFILES) + +libpithosd.lib: $(OFILES) + $(RM) libpithosd.lib || rem + $(LIBER) /out:libpithosd.lib $(OFILES) + +clean: + $(RM) *.lib + $(RM) *.obj diff --git a/pith/osdep/mimedisp.c b/pith/osdep/mimedisp.c new file mode 100644 index 00000000..69ff3337 --- /dev/null +++ b/pith/osdep/mimedisp.c @@ -0,0 +1,473 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: mimedisp.c 942 2008-03-04 18:21:33Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include <general.h> + +#include "../../c-client/fs.h" + +#ifdef _WINDOWS +#include "../../pico/osdep/mswin.h" +#endif + +#include "mimedisp.h" +#include "../charconv/utf8.h" +#ifdef OSX_TARGET +#include <Security/AuthSession.h> +#endif + + +/* + * Internal prototypes + */ +#ifdef _WINDOWS +int mswin_reg_viewer(LPTSTR mime_type, LPTSTR mime_ext, + char *cmd, int clen, int chk); +int mswin_reg_mime_type(LPTSTR file_ext, LPTSTR mime_type, size_t mime_type_len); +int mswin_reg_mime_ext(LPTSTR mime_type, LPTSTR file_ext, size_t file_ext_len); + +#endif /* WINDOWS */ + +#if OSX_TARGET + +int osx_build_mime_type_cmd(char *, char *, int, int *); +int osx_build_mime_ext_cmd(char *, char *, int, int *); + +#endif /* OSX_TARGET */ + + + +/* + * Determine if there is an OS-specific mechanism for accessing + * MIME and extension data. In the general *nix case this is all + * done through mailcap and mime.types files. + * + * Returns: 0 if there is no support (most *nix cases) + * 1 if there is support (Mac OS X, Windows) + */ +int +mime_os_specific_access(void) +{ +#ifdef _WINDOWS + return 1; +#elif OSX_TARGET +# ifdef AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER + { + /* + * if we don't have the WidowSession then we should avoid using + * frameworks unless they call themselves daemon-safe + */ + SecuritySessionId session_id; + SessionAttributeBits session_bits; + + if((SessionGetInfo(callerSecuritySession, &session_id, &session_bits) + == errSessionSuccess) + && session_bits & sessionHasGraphicAccess) + return 1; + else + return 0; + } +# else + return 0; +# endif +#else + return 0; +#endif +} + + +/* + * Return the command based on either the mimetype or the file + * extension. Mime-type always takes precedence. + * + * mime_type - mime-type of the file we're looking at + * mime_ext - file extension given us by the mime data + * cmd - buffer to copy the resulting command into + * chk - whether or not we should check the file extension + * + * Returns: 1 on success, 0 on failure + */ +int +mime_get_os_mimetype_command(char *mime_type, char *mime_ext, char *cmd, + int clen, int chk, int *sp_hndlp) +{ +#ifdef _WINDOWS + int ret; + LPTSTR mime_type_lpt, mime_ext_lpt; + + mime_type_lpt = utf8_to_lptstr(mime_type); + mime_ext_lpt = utf8_to_lptstr(mime_ext); + + ret = mswin_reg_viewer(mime_type_lpt, mime_ext_lpt, cmd, clen, chk); + + if(mime_type_lpt) + fs_give((void **) &mime_type_lpt); + + if(mime_ext_lpt) + fs_give((void **) &mime_ext_lpt); + + return ret; + +#elif OSX_TARGET + + /* + * if we wanted to be more like PC-Pine, we'd try checking + * the mime-type of mime_ext and seeing if that matches + * with our mime-type, which is safe for opening + */ + if(!mime_os_specific_access()) + return(0); + + /* don't want to use Mail or something for a part alpine is good at */ + if(!strucmp(mime_type, "message/rfc822")) + return(0); + + return(osx_build_mime_type_cmd(mime_type, cmd, clen, sp_hndlp) + || (chk && mime_ext && *mime_ext && + osx_build_mime_ext_cmd(mime_ext, cmd, clen, sp_hndlp))); +#else + return 0; +#endif +} + + +/* + * Given a file extension, return the mime-type if there is one + * + * Returns: 1 on success, 0 on failure + */ +int +mime_get_os_mimetype_from_ext(char *file_ext, char *mime_type, int mime_type_len) +{ +#ifdef _WINDOWS + int ret; + LPTSTR x, file_ext_lpt, mime_type_lpt; + + file_ext_lpt = utf8_to_lptstr(file_ext); + + if(file_ext_lpt){ + if(mime_type){ + mime_type_lpt = (LPTSTR) fs_get(mime_type_len * sizeof(TCHAR)); + mime_type_lpt[0] = '\0'; + } + else + mime_type_lpt = NULL; + } + + ret = mswin_reg_mime_type(file_ext_lpt, mime_type_lpt, (size_t) mime_type_len); + + /* convert answer back to UTF-8 */ + if(ret && mime_type_lpt && mime_type){ + char *u; + + u = lptstr_to_utf8(mime_type_lpt); + if(u){ + strncpy(mime_type, u, mime_type_len); + mime_type[mime_type_len-1] = '\0'; + fs_give((void **) &u); + } + } + + if(file_ext_lpt) + fs_give((void **) &file_ext_lpt); + + if(mime_type_lpt) + fs_give((void **) &mime_type_lpt); + + return ret; + +#elif OSX_TARGET + + if(!mime_os_specific_access()) + return(0); +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER + CFStringRef mime_ref = NULL, type_id_ref = NULL, ext_ref = NULL; + char buf[1024]; + + if(!file_ext || !*file_ext) + return 0; + + /* This for if we built on OS X >= 10.3 but run on < 10.3 */ + if(&UTTypeCreatePreferredIdentifierForTag == NULL) + return 0; + if((ext_ref = CFStringCreateWithCString(NULL, *file_ext == '.' ? + file_ext + 1 : file_ext, + kCFStringEncodingASCII)) == NULL) + return 0; + if((type_id_ref + = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, + ext_ref, NULL)) == NULL) + return 0; + + if((mime_ref = UTTypeCopyPreferredTagWithClass(type_id_ref, + kUTTagClassMIMEType)) == NULL) + return 0; + if(CFStringGetCString(mime_ref, mime_type, + (CFIndex)mime_type_len - 1, + kCFStringEncodingASCII) == false) + return 0; + + mime_type[mime_type_len - 1] = '\0'; + + return 1; +#else + return 0; +#endif /* AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER */ + +#else + return 0; +#endif /* OSX_TARGET */ +} + + +/* + * Given a mime-type, return the file extension if there is one + * + * Returns: 1 on success, 0 on failure + */ +int +mime_get_os_ext_from_mimetype(char *mime_type, char *file_ext, int file_ext_len) +{ +#ifdef _WINDOWS + int ret; + LPTSTR x, mime_type_lpt, file_ext_lpt; + + mime_type_lpt = utf8_to_lptstr(mime_type); + + if(mime_type_lpt){ + if(file_ext){ + file_ext_lpt = (LPTSTR) fs_get(file_ext_len * sizeof(TCHAR)); + file_ext_lpt[0] = '\0'; + } + else + file_ext_lpt = NULL; + } + + ret = mswin_reg_mime_ext(mime_type_lpt, file_ext_lpt, (size_t) file_ext_len); + + /* convert answer back to UTF-8 */ + if(ret && file_ext_lpt && file_ext){ + char *u; + + u = lptstr_to_utf8(file_ext_lpt); + if(u){ + strncpy(file_ext, u, file_ext_len); + file_ext[file_ext_len-1] = '\0'; + fs_give((void **) &u); + } + } + + if(mime_type_lpt) + fs_give((void **) &mime_type_lpt); + + if(file_ext_lpt) + fs_give((void **) &file_ext_lpt); + + return ret; + +#elif OSX_TARGET + + if(!mime_os_specific_access()) + return(0); +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER + CFStringRef mime_ref = NULL, type_id_ref = NULL, ext_ref = NULL; + + if(!mime_type || !*mime_type) + return 0; + /* This for if we built on OS X >= 10.3 but run on < 10.3 */ + if(&UTTypeCreatePreferredIdentifierForTag == NULL) + return 0; + if((mime_ref = CFStringCreateWithCString(NULL, mime_type, + kCFStringEncodingASCII)) == NULL) + return 0; + if((type_id_ref + = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, + mime_ref, NULL)) == NULL) + return 0; + + if((ext_ref = UTTypeCopyPreferredTagWithClass(type_id_ref, + kUTTagClassFilenameExtension)) == NULL) + return 0; + if((CFStringGetCString(ext_ref, file_ext, (CFIndex)file_ext_len - 1, + kCFStringEncodingASCII)) == false) + return 0; + + file_ext[file_ext_len - 1] = '\0'; + + return 1; +#else + return 0; +#endif /* AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER */ + +#else + return 0; +#endif /* OSX_TARGET */ +} + + + +#ifdef _WINDOWS + +/* + * mswin_reg_viewer - + */ +int +mswin_reg_viewer(LPTSTR mime_type, LPTSTR mime_ext, char *cmd, int clen, int chk) +{ + TCHAR tmp[256]; + LPTSTR ext; + + tmp[0] = '\0'; + + /* + * Everything's based on the file extension. + * So, sniff at registry's mapping for the given MIME type/subtype + * and sniff at clues on how to launch it, or + * extension mapping and then + * look for clues that some app will handle it. + * + */ + return(((mswin_reg_mime_ext(mime_type, ext = tmp, sizeof(tmp)/sizeof(TCHAR)) + || ((ext = mime_ext) && *mime_ext + && ((mswin_reg_mime_type(mime_ext, tmp, sizeof(tmp)/sizeof(TCHAR)) + && mime_type && !_tcsicmp(mime_type, tmp)) + || mime_type && !_tcsicmp(mime_type, TEXT("application/octet-stream"))))) + && MSWRShellCanOpen(ext, cmd, clen, 0) == TRUE) + || (chk && MSWRShellCanOpen(ext, cmd, clen, 1) == TRUE)); +} + + +/* + * given a file name extension, fill in the provided buf with its + * corresponding MIME type + */ +int +mswin_reg_mime_type(LPTSTR file_ext, LPTSTR mime_type, size_t mime_type_len) +{ + TCHAR buf[64]; + DWORD len = mime_type_len; + + if(file_ext[0] != '.'){ + *buf = '.'; + _tcsncpy(buf + 1, file_ext, sizeof(buf)/sizeof(TCHAR)-1); + buf[sizeof(buf)/sizeof(TCHAR)-1] = '\0'; + file_ext = buf; + } + + return(MSWRPeek(HKEY_CLASSES_ROOT, file_ext, TEXT("content type"), + mime_type, &len) == TRUE); +} + + +/* + * given a mime_type, fill in the provided buf with its + * corresponding file name extension + */ +int +mswin_reg_mime_ext(LPTSTR mime_type, LPTSTR file_ext, size_t file_ext_len) +{ + TCHAR keybuf[128]; + DWORD len = file_ext_len; + + if(mime_type && _tcslen(mime_type) < 50){ + _sntprintf(keybuf, sizeof(keybuf), TEXT("MIME\\Database\\Content Type\\%s"), mime_type); + return(MSWRPeek(HKEY_CLASSES_ROOT, keybuf, + TEXT("extension"), file_ext, &len) == TRUE); + } + + return FALSE; +} +#endif /* _WINDOWS */ + + + +#if OSX_TARGET +/* returns: 1 if success, 0 if failure */ +int +osx_build_mime_type_cmd(mime_type, cmd, cmdlen, sp_hndlp) + char *mime_type, *cmd; + int cmdlen, *sp_hndlp; +{ + int rv = 0; + + if(!mime_os_specific_access()) + return(0); +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER + CFStringRef str_ref = NULL, ret_str_ref = NULL; + CFURLRef url_ref = NULL; + + if(&LSCopyApplicationForMIMEType == NULL) + return 0; + if((str_ref = CFStringCreateWithCString(NULL, mime_type, + kCFStringEncodingASCII)) == NULL) + return 0; + if(LSCopyApplicationForMIMEType(str_ref, kLSRolesAll, &url_ref) + != kLSApplicationNotFoundErr){ + if((ret_str_ref = CFURLGetString(url_ref)) == NULL) + return 0; + if(CFStringGetCString(ret_str_ref, cmd, (CFIndex)cmdlen, + kCFStringEncodingASCII) == false) + return 0; + if(sp_hndlp) + *sp_hndlp = 1; + rv = 1; + if(url_ref) + CFRelease(url_ref); + } +#endif /* AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER */ + return rv; +} + + +/* returns: 1 if success, 0 if failure */ +int +osx_build_mime_ext_cmd(mime_ext, cmd, cmdlen, sp_hndlp) + char *mime_ext, *cmd; + int cmdlen, *sp_hndlp; +{ + int rv = 0; + + if(!mime_os_specific_access()) + return 0; + +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER + CFStringRef str_ref = NULL, ret_str_ref = NULL; + CFURLRef url_ref = NULL; + + if((str_ref = CFStringCreateWithCString(NULL, (*mime_ext) == '.' + ? mime_ext+1 : mime_ext, + kCFStringEncodingASCII)) == NULL) + return 0; + if(LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, + str_ref, kLSRolesAll, NULL, &url_ref) + != kLSApplicationNotFoundErr){ + if((ret_str_ref = CFURLGetString(url_ref)) == NULL) + return 0; + if(CFStringGetCString(ret_str_ref, cmd, (CFIndex)cmdlen, + kCFStringEncodingASCII) == false) + return 0; + if(sp_hndlp) + *sp_hndlp = 1; + rv = 1; + if(url_ref) + CFRelease(url_ref); + } +#endif + return rv; +} +#endif /* OSX_TARGET */ diff --git a/pith/osdep/mimedisp.h b/pith/osdep/mimedisp.h new file mode 100644 index 00000000..36ddb7b1 --- /dev/null +++ b/pith/osdep/mimedisp.h @@ -0,0 +1,28 @@ +/* + * $Id: mimedisp.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_MIMEDISP_INCLUDED +#define PITH_OSDEP_MIMEDISP_INCLUDED + + +/* + * Exported Prototypes + */ +int mime_os_specific_access(void); +int mime_get_os_mimetype_command(char *, char *, char *, int, int, int *); +int mime_get_os_mimetype_from_ext(char *, char *, int); +int mime_get_os_ext_from_mimetype(char *, char *, int); + +#endif /* PITH_OSDEP_MIMEDISP_INCLUDED */ diff --git a/pith/osdep/pipe.c b/pith/osdep/pipe.c new file mode 100644 index 00000000..2183f529 --- /dev/null +++ b/pith/osdep/pipe.c @@ -0,0 +1,811 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: pipe.c 1204 2009-02-02 19:54:23Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> + +#include "err_desc.h" + +#include "canaccess.h" +#include "temp_nam.h" +#include "forkwait.h" +#include "pipe.h" +#include "../charconv/utf8.h" +#include "../charconv/filesys.h" +#include "../debug.h" + +#ifdef _WINDOWS +#include "../../pico/osdep/mswin.h" +#endif + + + +/*====================================================================== + pipe + + Initiate I/O to and from a process. These functions used to be + similar to popen and pclose, but both an incoming stream and an + output file are provided. + + ====*/ + + + +/* + * Global's to helpsignal handler tell us child's status has changed... + */ +static pid_t child_pid; + + +/* + * Internal Protos + */ +void zot_pipe(PIPE_S **); +#ifdef _WINDOWS +int pipe_mswin_exec_wrapper(char *, PIPE_S *, unsigned, + void (*)(PIPE_S *, int, void *), + void (*)(char *)); +#else /* UNIX */ +char *pipe_error_msg(char *, char *, char *); +RETSIGTYPE pipe_alarm(int); +#endif /* UNIX */ + + + + +/*---------------------------------------------------------------------- + Spawn a child process and optionally connect read/write pipes to it + + Args: command -- string to hand the shell + outfile -- address of pointer containing file to receive output + errfile -- address of pointer containing file to receive error output + mode -- mode for type of shell, signal protection etc... + Returns: pointer to alloc'd PIPE_S on success, NULL otherwise + + The outfile is either NULL, a pointer to a NULL value, or a pointer + to the requested name for the output file. In the pointer-to-NULL case + the caller doesn't care about the name, but wants to see the pipe's + results so we make one up. It's up to the caller to make sure the + free storage containing the name is cleaned up. + + Mode bits serve several purposes. + PIPE_WRITE tells us we need to open a pipe to write the child's + stdin. + PIPE_READ tells us we need to open a pipe to read from the child's + stdout/stderr. *NOTE* Having neither of the above set means + we're not setting up any pipes, just forking the child and exec'ing + the command. Also, this takes precedence over any named outfile. + PIPE_STDERR means we're to tie the childs stderr to the same place + stdout is going. *NOTE* This only makes sense then if PIPE_READ + or an outfile is provided. Also, this takes precedence over any + named errfile. + PIPE_RESET means we reset the terminal mode to what it was before + we started pine and then exec the command. In PC-Pine, _RESET + was a shortcut for just executing a command. We'll try to pay + attention to the above flags to make sure we do the right thing. + PIPE_PROT means to protect the child from the usual nasty signals + that might cause premature death. Otherwise, the default signals are + set so the child can deal with the nasty signals in its own way. + NOT USED UNDER WINDOWS + PIPE_NOSHELL means we're to exec the command without the aid of + a system shell. *NOTE* This negates the affect of PIPE_USER. + NOT USED UNDER WINDOWS + PIPE_USER means we're to try executing the command in the user's + shell. Right now we only look in the environment, but that may get + more sophisticated later. + NOT USED UNDER WINDOWS + PIPE_RUNNOW was added for WINDOWS for the case pipe is called to run + a shell program (like for url viewing). This is the only option + where we don't wait for child termination, and is only obeyed if + PIPE_WRITE and PIPE_READ aren't set + ----*/ +PIPE_S * +open_system_pipe(char *command, char **outfile, char **errfile, int mode, + int timeout, void (*pipecb_f)(PIPE_S *, int, void *), + void (*piperr_f)(char *)) +{ + PIPE_S *syspipe = NULL; +#ifdef _WINDOWS + int exit_code = 0; + char cmdbuf[1024]; + unsigned flags = 0; +#else + char shellpath[MAXPATH+1], *shell; + int p[2], oparentd = -1, ochildd = -1, iparentd = -1, ichildd = -1; +#endif + +#ifdef _WINDOWS + if(mode & PIPE_STDERR) + flags |= MSWIN_EAW_CAPT_STDERR; + /* + * It'll be a lot more difficult to support READing and WRITing. + * This was never supported, and there don't look to be any cases + * that set both of these flags anymore for win32. + * + * errfile could probably be supported pretty easily + */ + + if(errfile){ + if(piperr_f) + (*piperr_f)("Pipe arg not yet supported: Error File"); + + return(NULL); + } + + + if((mode & PIPE_RUNNOW) + && !(mode & (PIPE_WRITE | PIPE_READ | PIPE_STDERR))){ + if(mswin_shell_exec(command, NULL) == 0 + && (syspipe = (PIPE_S *) malloc(sizeof(PIPE_S))) != NULL){ + memset(syspipe, 0, sizeof(PIPE_S)); + return(syspipe); + } + + return(NULL); + } + + strncpy(cmdbuf, command, sizeof(cmdbuf)); + cmdbuf[sizeof(cmdbuf)-1] = '\0'; + + if((syspipe = (PIPE_S *) malloc(sizeof(PIPE_S))) == NULL) + return(NULL); + + memset(syspipe, 0, sizeof(PIPE_S)); + syspipe->mode = mode; + if(!outfile){ + syspipe->deloutfile = 1; + if(mode & PIPE_READ){ + syspipe->outfile = temp_nam(NULL, "po"); + our_unlink(syspipe->outfile); + } + } + else{ + if(!*outfile) /* asked for, but not named? */ + *outfile = temp_nam(NULL, "po"); + + our_unlink(*outfile); + syspipe->outfile = (char *) malloc((strlen(*outfile)+1)*sizeof(char)); + snprintf(syspipe->outfile, strlen(*outfile)+1, "%s", *outfile); + } + + if(mode & PIPE_WRITE){ + /* + * Create tmp file to write, spawn child in close_pipe + * after tmp file's written... + */ + syspipe->infile = temp_nam(NULL, "pw"); + syspipe->out.f = our_fopen(syspipe->infile, "wb"); + syspipe->command = (char *) malloc((strlen(cmdbuf)+1)*sizeof(char)); + snprintf(syspipe->command, strlen(cmdbuf)+1, "%s", cmdbuf); + dprint((1, "pipe write: %s", cmdbuf)); + } + else if(mode & PIPE_READ){ + /* + * Create a tmp file for command result, exec the command + * here into temp file, and return file pointer to it... + */ + syspipe->command = (char *) malloc((strlen(cmdbuf)+1)*sizeof(char)); + snprintf(syspipe->command, strlen(cmdbuf)+1, "%s", cmdbuf); + dprint((1, "pipe read: %s", cmdbuf)); + if(pipe_mswin_exec_wrapper("pipe command", syspipe, + flags, pipecb_f, piperr_f)){ + if(syspipe->outfile){ + free((void *) syspipe->outfile); + syspipe->outfile = NULL; + } + + zot_pipe(&syspipe); + } + else{ + syspipe->in.f = our_fopen(syspipe->outfile, "rb"); + syspipe->exit_code = exit_code; + } + } + else{ + /* we just run the command taking outfile into account */ + syspipe->command = (char *) malloc((strlen(cmdbuf)+1)*sizeof(char)); + snprintf(syspipe->command, strlen(cmdbuf)+1, "%s", cmdbuf); + if(pipe_mswin_exec_wrapper("pipe command", syspipe, + flags, pipecb_f, piperr_f)){ + if(syspipe->outfile){ + free((void *) syspipe->outfile); + syspipe->outfile = NULL; + } + + zot_pipe(&syspipe); + } + else + syspipe->exit_code = exit_code; + } + +#else /* !_WINDOWS */ + + if((syspipe = (PIPE_S *) malloc(sizeof(PIPE_S))) == NULL) + return(NULL); + + memset(syspipe, 0, sizeof(PIPE_S)); + + syspipe->mode = mode; + + /* + * If we're not using the shell's command parsing smarts, build + * argv by hand... + */ + if(mode & PIPE_NOSHELL){ + char **ap, *p; + size_t n; + + /* parse the arguments into argv */ + for(p = command; *p && isspace((unsigned char)(*p)); p++) + ; /* swallow leading ws */ + + if(*p){ + int l = strlen(p); + + if((syspipe->args = (char *) malloc((l + 1) * sizeof(char))) != NULL){ + strncpy(syspipe->args, p, l); + syspipe->args[l] = '\0'; + } + else{ + if(piperr_f) + (*piperr_f)(pipe_error_msg("<null>", "execute", + "Can't allocate command string")); + zot_pipe(&syspipe); + return(NULL); + } + } + else{ + if(piperr_f) + (*piperr_f)(pipe_error_msg("<null>", "execute", + "No command name found")); + zot_pipe(&syspipe); + return(NULL); + } + + for(p = syspipe->args, n = 2; *p; p++) /* count the args */ + if(isspace((unsigned char)(*p)) + && *(p+1) && !isspace((unsigned char)(*(p+1)))) + n++; + + if ((syspipe->argv = ap = (char **)malloc(n * sizeof(char *))) == NULL){ + zot_pipe(&syspipe); + return(NULL); + } + + memset(syspipe->argv, 0, n * sizeof(char *)); + + for(p = syspipe->args; *p; ){ /* collect args */ + while(*p && isspace((unsigned char)(*p))) + *p++ = '\0'; + + *ap++ = (*p) ? p : NULL; + while(*p && !isspace((unsigned char)(*p))) + p++; + } + + /* make sure argv[0] exists in $PATH */ + if(can_access_in_path(getenv("PATH"), syspipe->argv[0], + EXECUTE_ACCESS) < 0){ + if(piperr_f) + (*piperr_f)(pipe_error_msg(syspipe->argv[0], "access", + error_description(errno))); + zot_pipe(&syspipe); + return(NULL); + } + } + + /* fill in any output filenames */ + if(!(mode & PIPE_READ)){ + if(outfile && !*outfile) + *outfile = temp_nam(NULL, "pine_p"); /* asked for, but not named? */ + + if(errfile && !*errfile) + *errfile = temp_nam(NULL, "pine_p"); /* ditto */ + } + + /* create pipes */ + if(mode & (PIPE_WRITE | PIPE_READ)){ + if(mode & PIPE_WRITE){ + pipe(p); /* alloc pipe to write child */ + oparentd = p[STDOUT_FILENO]; + ichildd = p[STDIN_FILENO]; + } + + if(mode & PIPE_READ){ + pipe(p); /* alloc pipe to read child */ + iparentd = p[STDIN_FILENO]; + ochildd = p[STDOUT_FILENO]; + } + } + + if(pipecb_f) /* let caller prep display */ + (*pipecb_f)(syspipe, OSB_PRE_OPEN, NULL); + + + if((syspipe->pid = vfork()) == 0){ + /* reset child's handlers in requested fashion... */ + (void)signal(SIGINT, (mode & PIPE_PROT) ? SIG_IGN : SIG_DFL); + (void)signal(SIGQUIT, (mode & PIPE_PROT) ? SIG_IGN : SIG_DFL); + (void)signal(SIGHUP, (mode & PIPE_PROT) ? SIG_IGN : SIG_DFL); +#ifdef SIGCHLD + (void) signal(SIGCHLD, SIG_DFL); +#endif + + /* if parent isn't reading, and we have a filename to write */ + if(!(mode & PIPE_READ) && outfile){ /* connect output to file */ + int output = our_creat(*outfile, 0600); + dup2(output, STDOUT_FILENO); + if(mode & PIPE_STDERR) + dup2(output, STDERR_FILENO); + else if(errfile) + dup2(our_creat(*errfile, 0600), STDERR_FILENO); + } + + if(mode & PIPE_WRITE){ /* connect process input */ + close(oparentd); + dup2(ichildd, STDIN_FILENO); /* tie stdin to pipe */ + close(ichildd); + } + + if(mode & PIPE_READ){ /* connect process output */ + close(iparentd); + dup2(ochildd, STDOUT_FILENO); /* tie std{out,err} to pipe */ + if(mode & PIPE_STDERR) + dup2(ochildd, STDERR_FILENO); + else if(errfile) + dup2(our_creat(*errfile, 0600), STDERR_FILENO); + + close(ochildd); + } + + if(mode & PIPE_NOSHELL){ + execvp(syspipe->argv[0], syspipe->argv); + } + else{ + if(mode & PIPE_USER){ + char *env, *sh; + if((env = getenv("SHELL")) && (sh = strrchr(env, '/'))){ + shell = sh + 1; + strncpy(shellpath, env, sizeof(shellpath)-1); + shellpath[sizeof(shellpath)-1] = '\0'; + } + else{ + shell = "csh"; + strncpy(shellpath, "/bin/csh", sizeof(shellpath)-1); + shellpath[sizeof(shellpath)-1] = '\0'; + } + } + else{ + shell = "sh"; + strncpy(shellpath, "/bin/sh", sizeof(shellpath)-1); + shellpath[sizeof(shellpath)-1] = '\0'; + } + + execl(shellpath, shell, command ? "-c" : (char *)NULL, fname_to_locale(command), (char *)NULL); + } + + fprintf(stderr, "Can't exec %s\nReason: %s", + command, error_description(errno)); + _exit(-1); + } + + if((child_pid = syspipe->pid) > 0){ + syspipe->isig = signal(SIGINT, SIG_IGN); /* Reset handlers to make */ + syspipe->qsig = signal(SIGQUIT, SIG_IGN); /* sure we don't come to */ + syspipe->hsig = signal(SIGHUP, SIG_IGN); /* a premature end... */ + if((syspipe->timeout = timeout) != 0){ + syspipe->alrm = signal(SIGALRM, pipe_alarm); + syspipe->old_timeo = alarm(timeout); + } + + if(mode & PIPE_WRITE){ + close(ichildd); + if(mode & PIPE_DESC) + syspipe->out.d = oparentd; + else + syspipe->out.f = fdopen(oparentd, "w"); + } + + if(mode & PIPE_READ){ + close(ochildd); + if(mode & PIPE_DESC) + syspipe->in.d = iparentd; + else + syspipe->in.f = fdopen(iparentd, "r"); + } + } + else{ + if(mode & (PIPE_WRITE | PIPE_READ)){ + if(mode & PIPE_WRITE){ + close(oparentd); + close(ichildd); + } + + if(mode & PIPE_READ){ + close(iparentd); + close(ochildd); + } + } + + if(pipecb_f) /* let caller fixup display */ + (*pipecb_f)(syspipe, OSB_POST_OPEN, NULL); + + if(outfile && *outfile){ + our_unlink(*outfile); + free((void *) *outfile); + *outfile = NULL; + } + + if(errfile && *errfile){ + our_unlink(*errfile); + free((void *) *errfile); + *errfile = NULL; + } + + if(piperr_f) + (*piperr_f)(pipe_error_msg(command, "fork", + error_description(errno))); + zot_pipe(&syspipe); + } + +#endif /* UNIX */ + + return(syspipe); +} + + + +#ifndef _WINDOWS +/*---------------------------------------------------------------------- + Return appropriate error message + + Args: cmd -- command we were trying to exec + op -- operation leading up to the exec + res -- result of that operation + + ----*/ +char * +pipe_error_msg(char *cmd, char *op, char *res) +{ + static char ebuf[512]; + + snprintf(ebuf, 256, "Pipe can't %.256s \"%.32sb\": %.223s", + op ? op : "?", cmd ? cmd : "?", res ? res : "?"); + + return(ebuf); +} +#endif /* !_WINDOWS */ + + +/*---------------------------------------------------------------------- + Free resources associated with the given pipe struct + + Args: syspipe -- address of pointer to struct to clean up + + ----*/ +void +zot_pipe(PIPE_S **syspipe) +{ + if((*syspipe)->args){ + free((void *) (*syspipe)->args); + (*syspipe)->args = NULL; + } + + if((*syspipe)->argv){ + free((void *) (*syspipe)->argv); + (*syspipe)->argv = NULL; + } + + if((*syspipe)->tmp){ + free((void *) (*syspipe)->tmp); + (*syspipe)->tmp = NULL; + } + +#ifdef _WINDOWS + + if((*syspipe)->outfile){ + free((void *) (*syspipe)->outfile); + (*syspipe)->outfile = NULL; + } + + if((*syspipe)->command){ + free((void *) (*syspipe)->command); + (*syspipe)->command = NULL; + } + +#endif /* _WINDOWS */ + + free((void *) *syspipe); + *syspipe = NULL; +} + + + +/* + * Returns: 0 if all went well, -1 otherwise + */ +int +pipe_close_write(PIPE_S *syspipe) +{ + int rv = 0; + + if(!syspipe || !syspipe->out.f) + return -1; + +#ifdef _WINDOWS + + { + unsigned flags = 0; + + if(syspipe->mode & PIPE_STDERR) + flags |= MSWIN_EAW_CAPT_STDERR; + + rv = fclose(syspipe->out.f); + syspipe->out.f = NULL; + if(syspipe->mode & PIPE_WRITE){ + /* + * PIPE_WRITE should always be set if we're trying to close + * the write end. + * PIPE_WRITE can't start process till now, all the others + * will have already run + */ + if(pipe_mswin_exec_wrapper("pipe command", syspipe, + flags, NULL, NULL)) + /* some horrible error just occurred */ + rv = -1; + else + syspipe->in.f = our_fopen(syspipe->outfile, "rb"); + } + else + rv = -1; + } + +#else /* UNIX */ + + rv = fclose(syspipe->out.f) ? -1 : 0; + syspipe->out.f = NULL; + +#endif + return(rv); +} + + + +/*---------------------------------------------------------------------- + Close pipe previously allocated and wait for child's death + + Args: syspipe -- address of pointer to struct returned by open_system_pipe + exitval -- return exit status here. + + Returns: + Two modes of return values for backcompat. + If exitval == NULL + returns exit status of child or -1 if invalid syspipe + If exitval != NULL + returns -1 if invalid syspipe or 0 if ok. In that case, exitval + of child is returned in exitval + ----*/ +int +close_system_pipe(PIPE_S **syspipe, int *exitval, void (*pipecb_f) (PIPE_S *, int, void *)) +{ +#ifdef _WINDOWS + int rv = 0; + unsigned flags = 0; + + if(!(syspipe && *syspipe)) + return(-1); + + if((*syspipe)->mode & PIPE_STDERR) + flags |= MSWIN_EAW_CAPT_STDERR; + + if(((*syspipe)->mode & PIPE_WRITE) && (*syspipe)->out.f){ + fclose((*syspipe)->out.f); + /* + * PIPE_WRITE can't start process till now, all the others + * will have already run + */ + if(pipe_mswin_exec_wrapper("pipe command", (*syspipe), + flags, pipecb_f, NULL)) + /* some horrible error just occurred */ + rv = -1; + } + else if((*syspipe)->mode & PIPE_READ) + if((*syspipe)->in.f) + fclose((*syspipe)->in.f); + + if(exitval){ + *exitval = (*syspipe)->exit_code; + dprint((5, "Closed pipe: exitval=%d\n", *exitval)); + } + + if((*syspipe)->infile) + our_unlink((*syspipe)->infile); + + if((*syspipe)->outfile && (*syspipe)->deloutfile) + our_unlink((*syspipe)->outfile); + + if(rv != -1 && !exitval) + rv = (*syspipe)->exit_code; + + zot_pipe(syspipe); + +#ifdef DEBUG + if(!exitval){ + dprint((5, "Closed pipe: rv=%d\n", rv)); + } +#endif /* DEBUG */ + + return(rv); + +#else /* UNIX */ + int status; + + if(!(syspipe && *syspipe)) + return -1; + + if(((*syspipe)->mode) & PIPE_WRITE){ + if(((*syspipe)->mode) & PIPE_DESC){ + if((*syspipe)->out.d >= 0) + close((*syspipe)->out.d); + } + else if((*syspipe)->out.f) + fclose((*syspipe)->out.f); + } + + if(((*syspipe)->mode) & PIPE_READ){ + if(((*syspipe)->mode) & PIPE_DESC){ + if((*syspipe)->in.d >= 0) + close((*syspipe)->in.d); + } + else if((*syspipe)->in.f) + fclose((*syspipe)->in.f); + } + + if(pipecb_f) + (*pipecb_f)(*syspipe, OSB_PRE_CLOSE, NULL); + + /* wait on the child */ + (void) process_reap((*syspipe)->pid, &status, PR_NONE); + + /* restore original handlers... */ + (void) signal(SIGINT, (*syspipe)->isig); + (void) signal(SIGHUP, (*syspipe)->hsig); + (void) signal(SIGQUIT, (*syspipe)->qsig); + + if((*syspipe)->timeout){ + (void)signal(SIGALRM, (*syspipe)->alrm); + alarm((*syspipe)->old_timeo); + child_pid = 0; + } + + if(pipecb_f) + (*pipecb_f)(*syspipe, OSB_POST_CLOSE, NULL); + + zot_pipe(syspipe); + + if(exitval){ + *exitval = status; + return 0; + } + else{ + return(status); + } +#endif /* UNIX */ +} + + +/* + * process_reap - manage child demise and return exit status + * + * Args: pid -- id of process to reap + * esp -- pointer to exist status + * flags -- special reaping considerations + * + * Returns: + * < 0 -- if there's a problem + * 0 -- if no child to reap + * > 0 -- process id of the child + */ +pid_t +process_reap(pid_t pid, int *esp, int flags) +{ +#ifdef _WINDOWS + + return 0; + +#else /* UNIX */ + WAITSTATUS_T wstatus; + pid_t rv; + int wflags; + +#if HAVE_WAITPID + + wflags = 0; + +#ifdef WNOHANG + if(flags & PR_NOHANG) + wflags |= WNOHANG; +#endif + + while (((rv = waitpid(pid, &wstatus, wflags)) < 0) && (errno != ECHILD)); + +#elif HAVE_WAIT4 + + wflags = 0; + +#ifdef WNOHANG + if(flags & PR_NOHANG) + wflags |= WNOHANG; +#endif + + while (((rv = wait4(pid,&wstatus,wflags,NULL)) < 0) && (errno != ECHILD)); + +#elif HAVE_WAIT + + while (((rv = wait(&wstatus)) != pid) && ((rv > 0) || (errno != ECHILD))); + +#else + + /* BUG: BAIL */ + +#endif + + if(rv > 0) + *esp = (WIFEXITED(wstatus)) ? (int) WEXITSTATUS(wstatus) : -1; + + return(rv); +#endif /* UNIX */ +} + + +#ifndef _WINDOWS +RETSIGTYPE +pipe_alarm(int sig) +{ + if(child_pid) + kill(child_pid, SIGINT); +} +#endif /* !_WINDOWS */ + + +#ifdef _WINDOWS +/* + * Wrapper around mswin_exec_and_wait() + */ +int +pipe_mswin_exec_wrapper(char *whatsit, + PIPE_S *syspipe, unsigned flags, + void (*pipecb_f)(PIPE_S *, int, void *), + void (*piperr_f)(char *)) +{ + int rv; + + flags |= MSWIN_EAW_CTRL_C_CANCELS; + + if(pipecb_f) + (*pipecb_f)(syspipe, OSB_PRE_OPEN, NULL); + + rv = mswin_exec_and_wait(whatsit, syspipe->command, + syspipe->infile, syspipe->outfile, + &syspipe->exit_code, flags); + + if(pipecb_f) + (*pipecb_f)(syspipe, OSB_POST_OPEN, (void *)rv); + + return rv; +} +#endif diff --git a/pith/osdep/pipe.h b/pith/osdep/pipe.h new file mode 100644 index 00000000..589fc839 --- /dev/null +++ b/pith/osdep/pipe.h @@ -0,0 +1,117 @@ +/* + * $Id: pipe.h 769 2007-10-24 00:15:40Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_PIPE_INCLUDED +#define PITH_OSDEP_PIPE_INCLUDED + +/* Standard I/O File Descriptor Definitions */ +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + + +/* + * Flags for the pipe command routines... + */ +#define PIPE_WRITE 0x0001 /* set up pipe for reading */ +#define PIPE_READ 0x0002 /* set up pipe for reading */ +#define PIPE_NOSHELL 0x0004 /* don't exec in shell */ +#define PIPE_USER 0x0008 /* user mode */ +#define PIPE_STDERR 0x0010 /* stderr to child output */ +#define PIPE_PROT 0x0020 /* protected mode */ +#define PIPE_RESET 0x0040 /* reset terminal mode */ +#define PIPE_DESC 0x0080 /* no stdio desc wrapping */ +#define PIPE_SILENT 0x0100 /* no screen clear, etc */ +#define PIPE_RUNNOW 0x0200 /* don't wait for child (PC-Pine) */ +#define PIPE_RAW 0x0400 /* don't convert to locale */ +#define PIPE_NONEWMAIL 0x0800 /* don't call new_mail */ + +#ifdef _WINDOWS +/* + * Flags for mswin_exec_and_wait + */ +#define MSWIN_EAW_CAPT_STDERR 0x0001 +#define MSWIN_EAW_CTRL_C_CANCELS 0x0002 +#endif + + +/* + * Reaper flags + */ +#define PR_NONE 0x0000 +#ifdef WNOHANG +#define PR_NOHANG 0x0001 +#endif + +/* + * open_system_pipe callback so caller can insert code, typically interface + * stuff right before/after the fork and before/after wait + */ +#define OSB_PRE_OPEN 0x0001 +#define OSB_POST_OPEN 0x0002 +#define OSB_PRE_CLOSE 0x0004 +#define OSB_POST_CLOSE 0x0008 + +/* + * stucture required for the pipe commands... + */ +typedef struct pipe_s { + pid_t pid; /* child's process id */ + int mode, /* mode flags used to open */ + timeout, /* wait this long for child */ + old_timeo; /* previous active alarm */ + RETSIGTYPE (*hsig)(int), /* previously installed... */ + (*isig)(int), /* handlers */ + (*qsig)(int), + (*alrm)(int), + (*chld)(int); + union { + FILE *f; + int d; + } in; /* input data handle */ + union { + FILE *f; + int d; + } out; /* output data handle */ + char **argv, /* any necessary args */ + *args, + *tmp; /* pointer to stuff */ +#ifdef _WINDOWS + char *infile; /* file containing pipe's stdin */ + char *outfile; /* file containing pipe's stdout */ + char *command; /* command to execute */ + int exit_code; /* proc rv if run right away */ + int deloutfile; /* need to rm outfile at close */ +#endif +} PIPE_S; + + +/* + * Exported Prototypes + */ +PIPE_S *open_system_pipe(char *, char **, char **, int, int, + void (*)(PIPE_S *, int, void *), void (*)(char *)); +int close_system_pipe(PIPE_S **, int *, void (*)(PIPE_S *, int, void *)); +int pipe_close_write(PIPE_S *); +pid_t process_reap(pid_t, int *, int); + + +#endif /* PITH_OSDEP_PIPE_INCLUDED */ diff --git a/pith/osdep/pithosd.h b/pith/osdep/pithosd.h new file mode 100644 index 00000000..adf71e8d --- /dev/null +++ b/pith/osdep/pithosd.h @@ -0,0 +1,43 @@ +/* + * $Id: pithosd.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_PITHOSD_INCLUDED +#define PITH_PITHOSD_INCLUDED + +#include "bldpath.h" +#include "canaccess.h" +#include "canonicl.h" +#include "collate.h" +#include "color.h" +#include "coredump.h" +#include "creatdir.h" +#include "debugtime.h" +#include "domnames.h" +#include "err_desc.h" +#include "fgetpos.h" +#include "filesize.h" +#include "fnexpand.h" +#include "hostname.h" +#include "lstcmpnt.h" +#include "mimedisp.h" +#include "pipe.h" +#include "pw_stuff.h" +#include "rename.h" +#include "tempfile.h" +#include "temp_nam.h" +#include "writ_dir.h" + + +#endif /* PITH_PITHOSD_INCLUDED */ diff --git a/pith/osdep/pw_stuff.c b/pith/osdep/pw_stuff.c new file mode 100644 index 00000000..f8f779c5 --- /dev/null +++ b/pith/osdep/pw_stuff.c @@ -0,0 +1,207 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: pw_stuff.c 763 2007-10-23 23:37:34Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include <general.h> + +#include "../charconv/utf8.h" +#include "../charconv/filesys.h" +#include "pw_stuff.h" + +/* + * internal prototypes + */ +#ifndef _WINDOWS + +static char *gcos_name(char *, char *); + + +/*---------------------------------------------------------------------- + Pull the name out of the gcos field if we have that sort of /etc/passwd + + Args: gcos_field -- The long name or GCOS field to be parsed + logname -- Replaces occurances of & with logname string + + Result: returns pointer to buffer with name + ----*/ +static char * +gcos_name(char *gcos_field, char *logname) +{ + static char fullname[MAX_FULLNAME+1]; + register char *fncp, *gcoscp, *lncp, *end; + + /* + * Full name is all chars up to first ',' (or whole gcos, if no ','). + * Replace any & with Logname. + */ + + for(fncp = fullname, gcoscp= gcos_field, end = fullname + MAX_FULLNAME; + (*gcoscp != ',' && *gcoscp != '\0' && fncp < end); + gcoscp++){ + + if(*gcoscp == '&'){ + for(lncp = logname; *lncp && fncp < end; fncp++, lncp++) + *fncp = (lncp == logname) ? toupper((unsigned char) (*lncp)) + : (*lncp); + }else + *fncp++ = *gcoscp; + } + + *fncp = '\0'; + return(fullname); +} + +#endif /* !_WINDOWS */ + + + +/*---------------------------------------------------------------------- + Fill in homedir, login, and fullname for the logged in user. + These are all pointers to static storage so need to be copied + in the caller. + + Args: ui -- struct pointer to pass back answers + + Result: fills in the fields + ----*/ +void +get_user_info(struct user_info *ui) +{ +#ifndef _WINDOWS + struct passwd *unix_pwd; + + unix_pwd = getpwuid(getuid()); + if(unix_pwd == NULL) { + ui->homedir = (char *) malloc(sizeof(char)); + ui->homedir[0] = '\0'; + ui->login = (char *) malloc(sizeof(char)); + ui->login[0] = '\0'; + ui->fullname = (char *) malloc(sizeof(char)); + ui->fullname[0] = '\0'; + }else { + char *s; + size_t len; + + len = strlen(fname_to_utf8(unix_pwd->pw_dir)); + ui->homedir = (char *) malloc((len+1) * sizeof(char)); + snprintf(ui->homedir, len+1, "%s", fname_to_utf8(unix_pwd->pw_dir)); + + len = strlen(fname_to_utf8(unix_pwd->pw_name)); + ui->login = (char *) malloc((len+1) * sizeof(char)); + snprintf(ui->login, len+1, "%s", fname_to_utf8(unix_pwd->pw_name)); + + if((s = gcos_name(unix_pwd->pw_gecos, unix_pwd->pw_name)) != NULL){ + len = strlen(fname_to_utf8(s)); + ui->fullname = (char *) malloc((len+1) * sizeof(char)); + snprintf(ui->fullname, len+1, "%s", fname_to_utf8(s)); + } + } + +#else /* _WINDOWS */ + char buf[_MAX_PATH], *p, *q; + TCHAR lptstr_buf[_MAX_PATH]; + int len = _MAX_PATH; + + if(GetUserName(lptstr_buf, &len)) + ui->login = lptstr_to_utf8(lptstr_buf); + else + ui->login = our_getenv("USERNAME"); + + if((p = our_getenv("HOMEDRIVE")) + && (q = our_getenv("HOMEPATH"))) + snprintf(buf, sizeof(buf), "%s%s", p, q); + else + snprintf(buf, sizeof(buf), "%c:\\", '@' + _getdrive()); + + if(p) + free((void *)p); + + if(q) + free((void *)q); + + ui->homedir = (char *) malloc((strlen(buf)+1) * sizeof(char)); + if(ui->homedir){ + strncpy(ui->homedir, buf, strlen(buf)); + ui->homedir[strlen(buf)] = '\0'; + } + + ui->fullname = (char *) malloc(sizeof(char)); + if(ui->fullname) + ui->fullname[0] = '\0'; +#endif /* _WINDOWS */ +} + + +/*---------------------------------------------------------------------- + Look up a userid on the local system and return rfc822 address + + Args: name -- possible login name on local system + + Result: returns NULL or pointer to alloc'd string rfc822 address. + ----*/ +char * +local_name_lookup(char *name) +{ +#ifndef _WINDOWS + struct passwd *pw = getpwnam(name); + + if(pw == NULL){ + char *p; + + for(p = name; *p; p++) + if(isupper((unsigned char)*p)) + break; + + /* try changing it to all lower case */ + if(p && *p){ + char lcase[256]; + size_t l; + + snprintf(lcase, sizeof(lcase), "%s", name); + + l = strlen(name); + for(p = lcase; *p; p++) + if(isupper((unsigned char)*p)) + *p = tolower((unsigned char)*p); + + pw = getpwnam(lcase); + + if(pw){ + strncpy(name, lcase, l+1); + name[l] = '\0'; + } + } + } + + if(pw != NULL){ + char *gn, *s = NULL; + size_t l; + + if((gn = gcos_name(pw->pw_gecos, name)) != NULL + && (s = (char *) malloc(l = ((strlen(gn) + 1) * sizeof(char)))) != NULL) + snprintf(s, l, "%s", gn); + + return(s); + } + else + return((char *) NULL); +#else /* _WINDOWS */ + return(NULL); +#endif /* _WINDOWS */ +} + + diff --git a/pith/osdep/pw_stuff.h b/pith/osdep/pw_stuff.h new file mode 100644 index 00000000..7a1191b7 --- /dev/null +++ b/pith/osdep/pw_stuff.h @@ -0,0 +1,29 @@ +/* + * $Id: pw_stuff.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_PW_STUFF_INCLUDED +#define PITH_OSDEP_PW_STUFF_INCLUDED + +#include "../user.h" + + +/* + * Exported Prototypes + */ +void get_user_info(USER_S *); +char *local_name_lookup(char *); + + +#endif /* PITH_OSDEP_PW_STUFF_INCLUDED */ diff --git a/pith/osdep/rename.c b/pith/osdep/rename.c new file mode 100644 index 00000000..8ca993b4 --- /dev/null +++ b/pith/osdep/rename.c @@ -0,0 +1,69 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: rename.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include "err_desc.h" +#include "../charconv/utf8.h" +#include "../charconv/filesys.h" +#include "rename.h" + + +/*---------------------------------------------------------------------- + Rename a file + + Args: tmpfname -- Old name of file + fname -- New name of file + + Result: File is renamed. Returns 0 on success, else -1 on error + and errno is valid. + ----*/ +int +rename_file(char *tmpfname, char *fname) +{ +#if HAVE_RENAME + return(our_rename(tmpfname, fname)); +#else +# if defined(_WINDOWS) + int ret; + + /* + * DOS rename doesn't unlink destination for us... + */ + if((ret = our_unlink(fname)) && (errno == EPERM)){ + ret = -5; + } + else{ + ret = our_rename(tmpfname, fname); + if(ret) + ret = -1; + } + + return(ret); +# else + int status; + + our_unlink(fname); + if ((status = link(tmpfname, fname)) != 0) + return(status); + + our_unlink(tmpfname); + return(0); +# endif +#endif +} + + diff --git a/pith/osdep/rename.h b/pith/osdep/rename.h new file mode 100644 index 00000000..e8472495 --- /dev/null +++ b/pith/osdep/rename.h @@ -0,0 +1,26 @@ +/* + * $Id: rename.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_RENAME_INCLUDED +#define PITH_OSDEP_RENAME_INCLUDED + + +/* + * Exported Prototypes + */ +int rename_file(char *, char *); + + +#endif /* PITH_OSDEP_RENAME_INCLUDED */ diff --git a/pith/osdep/temp_nam.c b/pith/osdep/temp_nam.c new file mode 100644 index 00000000..03136ea6 --- /dev/null +++ b/pith/osdep/temp_nam.c @@ -0,0 +1,345 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: temp_nam.c 1012 2008-03-26 00:44:22Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> + +#if HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#include "canaccess.h" +#include "temp_nam.h" +#include "../charconv/utf8.h" +#include "../charconv/filesys.h" + + +#ifdef _WINDOWS + +#include <process.h> + +#define ACCESSIBLE (WRITE_ACCESS) +#define PATH_SEP "\\" + +#else /* UNIX */ + +#define ACCESSIBLE (WRITE_ACCESS|EXECUTE_ACCESS) +#define PATH_SEP "/" + +#endif /* UNIX */ + + +/* + * Internal Prototypes + */ +char *was_nonexistent_tmp_name(char *, size_t, char *); + + + +/* + * This routine is derived from BSD4.3 code, + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + */ +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)mktemp.c 5.7 (Berkeley) 6/27/88"; +#endif /* LIBC_SCCS and not lint */ + +char * +was_nonexistent_tmp_name(char *as, size_t aslen, char *ext) +{ + register char *start, *trv; + struct stat sbuf; + unsigned pid; + static unsigned n = 0; + int i; + int fd, tries = 0; + int f; + static unsigned long r = 0; + + if(r == 0L) + r = (unsigned)getpid() + time((time_t *)0); + + for(i = 5; i > 0; i--) + r = 1664525 * r + 1013904223; + + pid = ((unsigned)getpid() * 100) + n++; + + pid += (r % 50000L); + + /* extra X's get set to 0's */ + for(trv = as; *trv; ++trv) + ; + + /* + * We should probably make the name random instead of having it + * be the pid. + */ + while(*--trv == 'X'){ + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* add the extension, enough room guaranteed by caller */ + if(ext && *ext){ + strncat(as, ".", aslen-strlen(as)-1); + as[aslen-1] = '\0'; + strncat(as, ext, aslen-strlen(as)-1); + as[aslen-1] = '\0'; + } + + /* + * Check for write permission on target directory; if you have + * six X's and you can't write the directory, this will run for + * a *very* long time. + */ + for(start = ++trv; trv > as && *trv != PATH_SEP[0]; --trv) + ; + + if(*trv == PATH_SEP[0]){ +#ifdef _WINDOWS + char treplace; + + if((trv - as == 2) && isalpha(as[0]) && as[1] == ':') + trv++; + treplace = *trv; + *trv = '\0'; + if(our_stat(as==trv ? PATH_SEP : as, &sbuf) || !(sbuf.st_mode & S_IFDIR)) + return((char *)NULL); + + *trv = treplace; + +#else /* UNIX */ + + *trv = '\0'; + + if(our_stat(as==trv ? PATH_SEP : as, &sbuf) || !(sbuf.st_mode & S_IFDIR)) + return((char *)NULL); + + *trv = PATH_SEP[0]; + +#endif + } + else if (our_stat(".", &sbuf) == -1) + return((char *)NULL); + + for(;;){ + /* + * Check with lstat to be sure we don't have + * a symlink. If lstat fails and no such file, then we + * have a winner. Otherwise, lstat shouldn't fail. + * If lstat succeeds, then skip it because it exists. + */ +#ifndef _WINDOWS + if(our_lstat(as, &sbuf)){ /* lstat failed */ + if(errno == ENOENT){ /* no such file, success */ +#endif /* !_WINDOWS */ + /* + * Create the file so that the + * evil ones don't have a chance to put something there + * that they can read or write before we create it + * ourselves. + */ + f = O_CREAT|O_EXCL|O_WRONLY|O_BINARY; + + if((fd=our_open(as, f, 0600)) >= 0 && close(fd) == 0) + return(as); + else if(++tries > 3) /* open failed unexpectedly */ + return((char *)NULL); +#ifndef _WINDOWS + } + else /* failed for unknown reason */ + return((char *)NULL); + } +#endif /* !_WINDOWS */ + + for(trv = start;;){ + if(!*trv) + return((char *)NULL); + + /* + * Change the digits from the initial values into + * lower case letters and try again. + */ + if(*trv == 'z') + *trv++ = 'a'; + else{ + if(isdigit((unsigned char)*trv)) + *trv = 'a'; + else + ++*trv; + + break; + } + } + } + /*NOTREACHED*/ +} + + +/* + * This routine is derived from BSD4.3 code, + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + */ +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)tmpnam.c 4.5 (Berkeley) 6/27/88"; +#endif /* LIBC_SCCS and not lint */ +/*---------------------------------------------------------------------- + Return a unique file name in a given directory. This is not quite + the same as the usual tempnam() function, though it is similar. + We want it to use the TMPDIR/TMP/TEMP environment variable only if dir + is NULL, instead of using it regardless if it is set. + We also want it to be safer than tempnam(). + If we return a filename, we are saying that the file did not exist + at the time this function was called (and it wasn't a symlink pointing + to a file that didn't exist, either). + If dir is NULL this is a temp file in a public directory. In that + case we create the file with permission 0600 before returning. + + Args: dir -- The directory to create the name in + prefix -- Prefix of the name + + Result: Malloc'd string equal to new name is returned. It must be free'd + by the caller. Returns the string on success and NULL on failure. + ----*/ +char * +temp_nam(char *dir, char *prefix) +{ + return(temp_nam_ext(dir, prefix, NULL)); +} + + +/*---------------------------------------------------------------------- + + Like temp_nam but create a unique name with an extension. + + Result: Malloc'd string equal to new name is returned. It must be free'd + by the caller. Returns the string on success and NULL on failure. + ----*/ +char * +temp_nam_ext(char *dir, char *prefix, char *ext) +{ + struct stat buf; + size_t l, ll; + char *f, *name; + + if(ext == NULL) + ext = ""; + + if(!(name = (char *)malloc(MAXPATH * sizeof(char)))) + return((char *)NULL); + + if(!dir && (f = getenv("TMPDIR")) && !our_stat(f, &buf) && + (buf.st_mode&S_IFMT) == S_IFDIR && + !can_access(f, ACCESSIBLE)){ + strncpy(name, f, MAXPATH-1); + name[MAXPATH-1] = '\0'; + goto done; + } + + if(!dir && (f = getenv("TMP")) && !our_stat(f, &buf) && + (buf.st_mode&S_IFMT) == S_IFDIR && + !can_access(f, ACCESSIBLE)){ + strncpy(name, f, MAXPATH-1); + name[MAXPATH-1] = '\0'; + goto done; + } + + if(!dir && (f = getenv("TEMP")) && !our_stat(f, &buf) && + (buf.st_mode&S_IFMT) == S_IFDIR && + !can_access(f, ACCESSIBLE)){ + strncpy(name, f, MAXPATH-1); + name[MAXPATH-1] = '\0'; + goto done; + } + + if(dir){ + strncpy(name, dir, MAXPATH-1); + name[MAXPATH-1] = '\0'; + +#ifdef _WINDOWS + if(!*dir || (isalpha(*dir) && *(dir+1) == ':' && !*(dir+2))){ + strncat(name, PATH_SEP, MAXPATH-strlen(name)-1); + name[MAXPATH-1] = '\0'; + } +#endif + + if(!our_stat(name, &buf) + && (buf.st_mode&S_IFMT) == S_IFDIR + && !can_access(name, ACCESSIBLE)){ + strncpy(name, dir, MAXPATH-1); + name[MAXPATH-1] = '\0'; + goto done; + } + } + +#ifndef P_tmpdir +#ifdef _WINDOWS +#define P_tmpdir "\\tmp" +#else /* UNIX */ +#define P_tmpdir "/usr/tmp" +#endif /* UNIX */ +#endif + + if(!our_stat(P_tmpdir, &buf) && + (buf.st_mode&S_IFMT) == S_IFDIR && + !can_access(P_tmpdir, ACCESSIBLE)){ + strncpy(name, P_tmpdir, MAXPATH-1); + name[MAXPATH-1] = '\0'; + goto done; + } + +#ifndef _WINDOWS + if(!our_stat("/tmp", &buf) && + (buf.st_mode&S_IFMT) == S_IFDIR && + !can_access("/tmp", ACCESSIBLE)){ + strncpy(name, "/tmp", MAXPATH-1); + name[MAXPATH-1] = '\0'; + goto done; + } +#endif + + free((void *)name); + return((char *)NULL); + +done: + f = NULL; + if(name[0] && *((f = &name[l=strlen(name)]) - 1) != PATH_SEP[0] && l+1 < MAXPATH){ + *f++ = PATH_SEP[0]; + *f = '\0'; + l++; + } + + if(prefix && (ll = strlen(prefix)) && l+ll < MAXPATH){ + strncpy(f, prefix, MAXPATH-(f-name)); + name[MAXPATH-1] = '\0'; + f += ll; + l += ll; + } + + if(l+5+(ext[0] ? strlen(ext)+1 : 0) < MAXPATH){ + strncpy(f, "XXXXX", MAXPATH-(f-name)); + name[MAXPATH-1] = '\0'; + } + else{ + free((void *)name); + return((char *)NULL); + } + + return(was_nonexistent_tmp_name(name, MAXPATH, ext)); +} diff --git a/pith/osdep/temp_nam.h b/pith/osdep/temp_nam.h new file mode 100644 index 00000000..fef56f33 --- /dev/null +++ b/pith/osdep/temp_nam.h @@ -0,0 +1,28 @@ +/* + * $Id: temp_nam.h 770 2007-10-24 00:23:09Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006-2007 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_TEMP_NAM_INCLUDED +#define PITH_OSDEP_TEMP_NAM_INCLUDED + + +/* + * Exported Prototypes + */ +char *temp_nam(char *, char *); +char *temp_nam_ext(char *, char *, char *); + + +#endif /* PITH_OSDEP_TEMP_NAM_INCLUDED */ diff --git a/pith/osdep/tempfile.c b/pith/osdep/tempfile.c new file mode 100644 index 00000000..4aa83e26 --- /dev/null +++ b/pith/osdep/tempfile.c @@ -0,0 +1,55 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: tempfile.c 1074 2008-06-04 00:08:43Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006-2008 University of Washington + * Copyright 2013 Eduardo Chappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> + +#if HAVE_TMPFILE +#else +#include "temp_nam.h" +#endif + +#include "../charconv/filesys.h" + +#include "tempfile.h" + + +/*---------------------------------------------------------------------- + Create a temporary file, the name of which we don't care about +and that goes away when it is closed. Just like ANSI C tmpfile. + ----*/ +FILE * +create_tmpfile(void) +{ +#if HAVE_TMPFILE + return(tmpfile()); +#else + char *file_name; + FILE *stream = NULL; + + file_name = temp_nam(NULL, "pine-tmp"); + if(file_name){ + stream = our_fopen(file_name, "w+b"); + our_unlink(file_name); + fs_give((void **) &file_name); + } + + return(stream); +#endif +} + + diff --git a/pith/osdep/tempfile.h b/pith/osdep/tempfile.h new file mode 100644 index 00000000..22573f85 --- /dev/null +++ b/pith/osdep/tempfile.h @@ -0,0 +1,28 @@ +/* + * $Id: tempfile.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_TEMPFILE_INCLUDED +#define PITH_OSDEP_TEMPFILE_INCLUDED + + + +/* + * Exported Prototypes + */ +FILE *create_tmpfile(void); + + + +#endif /* PITH_OSDEP_TEMPFILE_INCLUDED */ diff --git a/pith/osdep/writ_dir.c b/pith/osdep/writ_dir.c new file mode 100644 index 00000000..955839c1 --- /dev/null +++ b/pith/osdep/writ_dir.c @@ -0,0 +1,54 @@ +#if !defined(lint) && !defined(DOS) +static char rcsid[] = "$Id: writ_dir.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $"; +#endif + +/* + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#include <system.h> +#include "../charconv/utf8.h" +#include "../charconv/filesys.h" +#include "canaccess.h" +#include "writ_dir.h" + + +/*---------------------------------------------------------------------- + Check to see if a directory exists and is writable by us + + Args: dir -- directory name + + Result: returns 0 if it exists and is writable + 1 if it is a directory, but is not writable + 2 if it is not a directory + 3 it doesn't exist. + ----*/ +int +is_writable_dir(char *dir) +{ + struct stat sb; + + if(our_stat(dir, &sb) < 0) + /*--- It doesn't exist ---*/ + return(3); + + if(!(sb.st_mode & S_IFDIR)) + /*---- it's not a directory ---*/ + return(2); + + if(can_access(dir, 07)) + return(1); + else + return(0); +} + + diff --git a/pith/osdep/writ_dir.h b/pith/osdep/writ_dir.h new file mode 100644 index 00000000..c3ed238e --- /dev/null +++ b/pith/osdep/writ_dir.h @@ -0,0 +1,27 @@ +/* + * $Id: writ_dir.h 761 2007-10-23 22:35:18Z hubert@u.washington.edu $ + * + * ======================================================================== + * Copyright 2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * ======================================================================== + */ + +#ifndef PITH_OSDEP_WRIT_DIR_INCLUDED +#define PITH_OSDEP_WRIT_DIR_INCLUDED + + + +/* + * Exported Prototypes + */ +int is_writable_dir(char *); + + +#endif /* PITH_OSDEP_WRIT_DIR_INCLUDED */ |