home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / PAX20.ZIP / PORT.C < prev    next >
C/C++ Source or Header  |  1990-11-12  |  9KB  |  404 lines

  1. /* $Source: /u/mark/src/pax/RCS/port.c,v $
  2.  *
  3.  * $Revision: 2.0.0.3 $
  4.  *
  5.  * port.c - These are routines not available in all environments.
  6.  *
  7.  * DESCRIPTION
  8.  *
  9.  *    The routines contained in this file are provided for portability to
  10.  *    other versions of UNIX or other operating systems.  Not all systems
  11.  *    have the same functions or the same semantics, these routines
  12.  *    attempt to bridge the gap as much as possible.
  13.  *
  14.  * AUTHOR
  15.  *
  16.  *    Mark H. Colburn, Open Systems Architects, Inc. (mark@@jhereg.mn.org)
  17.  *    John Gilmore (gnu@@hoptoad)
  18.  *
  19.  * COPYRIGHT
  20.  *
  21.  *    Copyright (c) 1989 Mark H. Colburn.  All rights reserved.
  22.  *
  23.  *    Redistribution and use in source and binary forms are permitted
  24.  *    provided that the above copyright notice and this paragraph are
  25.  *    duplicated in all such forms and that any documentation,
  26.  *    advertising materials, and other materials related to such
  27.  *    distribution and use acknowledge that the software was developed
  28.  *    by Mark H. Colburn.
  29.  *
  30.  *    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  31.  *    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  32.  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  33.  *
  34.  * $Log:    port.c,v $
  35.  * Revision 2.0.0.3  89/10/13  02:35:42  mark
  36.  * Beta Test Freeze
  37.  *
  38.  */
  39.  
  40. #ifndef lint
  41. static char        *ident = "$Id: port.c,v 2.0.0.3 89/10/13 02:35:42 mark Exp Locker: mark $";
  42. static char        *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  43. #endif /* ! lint */
  44.  
  45.  
  46. /* Headers */
  47.  
  48. #include "pax.h"
  49.  
  50.  
  51. #ifndef MKDIR
  52.  
  53. /* mkdir - make a directory
  54.  *
  55.  * DESCRIPTION
  56.  *
  57.  *     Mkdir will make a directory of the name "dpath" with a mode of
  58.  *    "dmode".  This is consistent with the BSD mkdir() function and the
  59.  *    P1003.1 definitions of MKDIR.
  60.  *
  61.  * PARAMETERS
  62.  *
  63.  *    dpath        - name of directory to create
  64.  *    dmode        - mode of the directory
  65.  *
  66.  * RETURNS
  67.  *
  68.  *    Returns 0 if the directory was successfully created, otherwise a
  69.  *    non-zero return value will be passed back to the calling function
  70.  *    and the value of errno should reflect the error.
  71.  */
  72.  
  73. #ifdef __STDC__
  74.  
  75. int
  76. mkdir(char *dpath, int dmode)
  77.  
  78. #else
  79.  
  80. int
  81. mkdir(dpath, dmode)
  82.     char               *dpath;    /* Directory to make */
  83.     int                 dmode;    /* mode to be used for new directory */
  84.  
  85. #endif
  86. {
  87.     int                 cpid;
  88.     int                 status;
  89.     Stat                statbuf;
  90.     extern int          errno;
  91.  
  92.     DBUG_ENTER("mkdir");
  93.     if (STAT(dpath, &statbuf) == 0) {
  94.     errno = EEXIST;        /* Stat worked, so it already exists */
  95.     DBUG_RETURN(-1);
  96.     }
  97.     /* If stat fails for a reason other than non-existence, return error */
  98.     if (errno != ENOENT)
  99.     DBUG_RETURN(-1);
  100.  
  101.     switch (cpid = vfork()) {
  102.  
  103.     case -1:            /* Error in fork() */
  104.     DBUG_RETURN(-1);    /* Errno is set already */
  105.  
  106.     case 0:            /* Child process */
  107.  
  108.     (void) umask(mask | (0777 & ~dmode));    /* Set for mkdir */
  109.     execl("/bin/mkdir", "mkdir", dpath, (char *) 0);
  110.     _exit(-1);        /* Can't exec /bin/mkdir */
  111.  
  112.     default:            /* Parent process */
  113.     while (cpid != wait(&status)) {
  114.         /* Wait for child to finish */
  115.     }
  116.     }
  117.  
  118.     if (TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0) {
  119.     errno = EIO;        /* We don't know why, but */
  120.     DBUG_RETURN(-1);    /* /bin/mkdir failed */
  121.     }
  122.     DBUG_RETURN(0);
  123. }
  124.  
  125. #endif /* !MKDIR */
  126.  
  127.  
  128. #ifndef RMDIR
  129.  
  130. /* rmdir - remove a directory
  131.  *
  132.  * DESCRIPTION
  133.  *
  134.  *    Rmdir will remove the directory specified by "dpath".  It is
  135.  *    consistent with the BSD and POSIX rmdir functions.
  136.  *
  137.  * PARAMETERS
  138.  *
  139.  *    dpath        - name of directory to remove
  140.  *
  141.  * RETURNS
  142.  *
  143.  *    Returns 0 if the directory was successfully deleted, otherwise a
  144.  *    non-zero return value will be passed back to the calling function
  145.  *    and the value of errno should reflect the error.
  146.  */
  147.  
  148. #ifdef __STDC__
  149.  
  150. int
  151. rmdir(char *dpath)
  152.  
  153. #else
  154.  
  155. int
  156. rmdir(dpath)
  157.     char               *dpath;    /* directory to remove */
  158.  
  159. #endif
  160. {
  161.     int                 cpid,
  162.                         status;
  163.     Stat                statbuf;
  164.     extern int          errno;
  165.  
  166.     DBUG_ENTER("rmdir");
  167.     /* check to see if it exists */
  168.     if (STAT(dpath, &statbuf) == -1) {
  169.     DBUG_RETURN(-1);
  170.     }
  171.     switch (cpid = vfork()) {
  172.  
  173.     case -1:            /* Error in fork() */
  174.     DBUG_RETURN(-1);    /* Errno is set already */
  175.  
  176.     case 0:            /* Child process */
  177.     execl("/bin/rmdir", "rmdir", dpath, (char *) 0);
  178.     _exit(-1);        /* Can't exec /bin/rmdir */
  179.  
  180.     default:            /* Parent process */
  181.     while (cpid != wait(&status)) {
  182.         /* Wait for child to finish */
  183.     }
  184.     }
  185.  
  186.     if (TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0) {
  187.     errno = EIO;        /* We don't know why, but */
  188.     DBUG_RETURN(-1);    /* /bin/rmdir failed */
  189.     }
  190.     DBUG_RETURN(0);
  191. }
  192.  
  193. #endif /* !RMDIR */
  194.  
  195.  
  196. #ifndef STRERROR
  197.  
  198. /* strerror - return pointer to appropriate system error message
  199.  *
  200.  * DESCRIPTION
  201.  *
  202.  *    Get an error message string which is appropriate for the setting
  203.  *    of the errno variable.
  204.  *
  205.  * RETURNS
  206.  *
  207.  *    Returns a pointer to a string which has an appropriate error
  208.  *    message for the present value of errno.  The error message
  209.  *    strings are taken from sys_errlist[] where appropriate.  If an
  210.  *    appropriate message is not available in sys_errlist, then a
  211.  *    pointer to the string "Unknown error (errno <errvalue>)" is
  212.  *    returned instead.
  213.  */
  214.  
  215. #ifdef __STDC__
  216.  
  217. char *
  218. strerror(void)
  219.  
  220. #else
  221.  
  222. char *
  223. strerror()
  224.  
  225. #endif
  226. {
  227.     static char         msg[40];/* used for "Unknown error" messages */
  228.  
  229.     DBUG_ENTER("strerror");
  230.     if (errno > 0 && errno < sys_nerr) {
  231.     DBUG_RETURN(sys_errlist[errno]);
  232.     }
  233.     sprintf(msg, "Unknown error (errno %d)", errno);
  234.     DBUG_RETURN(msg);
  235. }
  236.  
  237. #endif /* !STRERROR */
  238.  
  239.  
  240. #ifndef GETOPT
  241.  
  242. /*
  243.  * getopt - parse command line options
  244.  *
  245.  * DESCRIPTION
  246.  *
  247.  *    This is a slightly modified version of the AT&T Public Domain
  248.  *    getopt().  It is included for those systems that do not already
  249.  *    have getopt() available in their C libraries.
  250.  */
  251.  
  252. #define ERR(s, c)    if(opterr){\
  253.     extern int write();\
  254.     char errbuf[2];\
  255.     errbuf[0] = c; errbuf[1] = '\n';\
  256.     (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
  257.     (void) write(2, s, (unsigned)strlen(s));\
  258.     (void) write(2, errbuf, 2);}
  259.  
  260. int                 opterr = 1;
  261. int                 optind = 1;
  262. int                 optopt;
  263. char               *optarg;
  264.  
  265. #ifdef __STDC__
  266.  
  267. int
  268. getopt(int argc, char **argv, char *opts)
  269.  
  270. #else
  271.  
  272. int
  273. getopt(argc, argv, opts)
  274.     int                 argc;
  275.     char              **argv;
  276.     char               *opts;
  277.  
  278. #endif
  279. {
  280.     static int          sp = 1;
  281.     register int        c;
  282.     register char      *cp;
  283.  
  284.     DBUG_ENTER("getopt");
  285.     if (sp == 1)
  286.     if (optind >= argc ||
  287.         argv[optind][0] != '-' || argv[optind][1] == '\0')
  288.         DBUG_RETURN(EOF);
  289.     else if (strcmp(argv[optind], "--") == NULL) {
  290.         optind++;
  291.         DBUG_RETURN(EOF);
  292.     }
  293.     optopt = c = argv[optind][sp];
  294.     if (c == ':' || (cp = index(opts, c)) == NULL) {
  295.     ERR(": illegal option -- ", c);
  296.     if (argv[optind][++sp] == '\0') {
  297.         optind++;
  298.         sp = 1;
  299.     }
  300.     DBUG_RETURN('?');
  301.     }
  302.     if (*++cp == ':') {
  303.     if (argv[optind][sp + 1] != '\0')
  304.         optarg = &argv[optind++][sp + 1];
  305.     else if (++optind >= argc) {
  306.         ERR(": option requires an argument -- ", c);
  307.         sp = 1;
  308.         DBUG_RETURN('?');
  309.     } else
  310.         optarg = argv[optind++];
  311.     sp = 1;
  312.     } else {
  313.     if (argv[optind][++sp] == '\0') {
  314.         sp = 1;
  315.         optind++;
  316.     }
  317.     optarg = NULL;
  318.     }
  319.     DBUG_RETURN(c);
  320. }
  321.  
  322. #endif /* !GETOPT */
  323.  
  324.  
  325. #ifndef MEMCPY
  326.  
  327. /*
  328.  * memcpy - copy a block of memory from one place to another
  329.  *
  330.  * DESCRIPTION
  331.  *
  332.  *    This is an implementation of the System V/ANSI memcpy() function.
  333.  *    Although Berkeley has bcopy which could be used here, use of this
  334.  *    function does make the source more ANSI compliant.  This function
  335.  *    is only used if it is not in the C library.
  336.  */
  337.  
  338. #ifdef __STDC__
  339.  
  340. void
  341. memcpy(void *s1, void *s2, unsigned int n)
  342.  
  343. #else
  344.  
  345. char *
  346. memcpy(s1, s2, n)
  347.     char               *s1;    /* destination block */
  348.     char               *s2;    /* source block */
  349.     unsigned int        n;    /* number of bytes to copy */
  350.  
  351. #endif
  352. {
  353.     char               *p;
  354.  
  355.     DBUG_ENTER("memcpy");
  356.     p = s1;
  357.     while (n--) {
  358.     *(unsigned char) s1++ = *(unsigned char) s2++;
  359.     }
  360.     DBUG_RETURN(p);
  361. }
  362.  
  363. #endif /* !MEMCPY */
  364.  
  365.  
  366. #ifndef MEMSET
  367. /*
  368.  * memset - set a block of memory to a particular value
  369.  *
  370.  * DESCRIPTION
  371.  *
  372.  *    This is an implementation of the System V/ANSI memset function.
  373.  *    Although Berkeley has the bzero() function, which is often what
  374.  *    memset() is used for, the memset function is more general.  This
  375.  *    function is only used if it is not in the C library.
  376.  */
  377.  
  378. #ifdef __STDC__
  379.  
  380. void *
  381. memset(void *s1, int c, unsigned int n)
  382.  
  383. #else
  384.  
  385. char *
  386. memset(s1, c, n)
  387.     char               *s1;    /* pointer to buffer to fill */
  388.     int                 c;    /* character to fill buffer with */
  389.     unsigned int        n;    /* number of characters to fill */
  390.  
  391. #endif
  392. {
  393.     char               *p;
  394.  
  395.     DBUG_ENTER("memset");
  396.     p = s1;
  397.     while (n--) {
  398.     *(unsigned char) s1++ = (unsigned char) c;
  399.     }
  400.     DBUG_RETURN(p);
  401. }
  402.  
  403. #endif /* !MEMSET */
  404.