summaryrefslogtreecommitdiff
path: root/pith/osdep
diff options
context:
space:
mode:
authorEduardo Chappa <echappa@gmx.com>2013-02-03 00:59:38 -0700
committerEduardo Chappa <echappa@gmx.com>2013-02-03 00:59:38 -0700
commit094ca96844842928810f14844413109fc6cdd890 (patch)
treee60efbb980f38ba9308ccb4fb2b77b87bbc115f3 /pith/osdep
downloadalpine-094ca96844842928810f14844413109fc6cdd890.tar.xz
Initial Alpine Version
Diffstat (limited to 'pith/osdep')
-rw-r--r--pith/osdep/Makefile.am22
-rw-r--r--pith/osdep/Makefile.in558
-rw-r--r--pith/osdep/ReadMe13
-rw-r--r--pith/osdep/bldpath.c190
-rw-r--r--pith/osdep/bldpath.h29
-rw-r--r--pith/osdep/canaccess.c160
-rw-r--r--pith/osdep/canaccess.h51
-rw-r--r--pith/osdep/canonicl.c71
-rw-r--r--pith/osdep/canonicl.h26
-rw-r--r--pith/osdep/collate.c170
-rw-r--r--pith/osdep/collate.h32
-rw-r--r--pith/osdep/color.c93
-rw-r--r--pith/osdep/color.h98
-rw-r--r--pith/osdep/coredump.c31
-rw-r--r--pith/osdep/coredump.h26
-rw-r--r--pith/osdep/creatdir.c55
-rw-r--r--pith/osdep/creatdir.h26
-rw-r--r--pith/osdep/debugtime.c133
-rw-r--r--pith/osdep/debugtime.h31
-rw-r--r--pith/osdep/domnames.c145
-rw-r--r--pith/osdep/domnames.h26
-rw-r--r--pith/osdep/err_desc.c44
-rw-r--r--pith/osdep/err_desc.h26
-rw-r--r--pith/osdep/fgetpos.c50
-rw-r--r--pith/osdep/fgetpos.h27
-rw-r--r--pith/osdep/filesize.c123
-rw-r--r--pith/osdep/filesize.h31
-rw-r--r--pith/osdep/fnexpand.c96
-rw-r--r--pith/osdep/fnexpand.h26
-rw-r--r--pith/osdep/forkwait.h39
-rw-r--r--pith/osdep/hostname.c119
-rw-r--r--pith/osdep/hostname.h26
-rw-r--r--pith/osdep/lstcmpnt.c103
-rw-r--r--pith/osdep/lstcmpnt.h28
-rw-r--r--pith/osdep/makefile.wnt65
-rw-r--r--pith/osdep/mimedisp.c473
-rw-r--r--pith/osdep/mimedisp.h28
-rw-r--r--pith/osdep/pipe.c811
-rw-r--r--pith/osdep/pipe.h117
-rw-r--r--pith/osdep/pithosd.h43
-rw-r--r--pith/osdep/pw_stuff.c207
-rw-r--r--pith/osdep/pw_stuff.h29
-rw-r--r--pith/osdep/rename.c69
-rw-r--r--pith/osdep/rename.h26
-rw-r--r--pith/osdep/temp_nam.c345
-rw-r--r--pith/osdep/temp_nam.h28
-rw-r--r--pith/osdep/tempfile.c55
-rw-r--r--pith/osdep/tempfile.h28
-rw-r--r--pith/osdep/writ_dir.c54
-rw-r--r--pith/osdep/writ_dir.h27
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 */