home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / UUPC11XT.ZIP / RN / UTIL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-21  |  15.5 KB  |  691 lines

  1. /* $Header: E:\SRC\UUPC\RN\RCS/UTIL.C 1.1 1992/11/21 06:14:58 ahd Exp $
  2.  *
  3.  * $Log: UTIL.C $
  4.  * Revision 1.1  1992/11/21  06:14:58  ahd
  5.  * Initial
  6.  *
  7.  *
  8.  *    Rev 1.0   18 Nov 1990  0:22:08
  9.  * Initial revision.
  10.  * Revision 4.3.2.6  90/04/23  00:24:42  sob
  11.  * A bit of clean up.
  12.  *
  13.  * Revision 4.3.2.5  90/03/17  21:34:21  sob
  14.  * Reworked VOIDSIG into SIGRET.
  15.  *
  16.  * Revision 4.3.2.4  89/12/14  23:58:54  sob
  17.  * Fixed small bug reported by fletcher@cs.utexas.edu in getwd().
  18.  *
  19.  * Revision 4.3.2.3  89/11/08  04:47:11  sob
  20.  * Added VOIDSIG handling for SunOS 4.X
  21.  *
  22.  * Revision 4.3.2.2  89/11/07  23:19:35  sob
  23.  * Bug fixes for SIGSTP problems
  24.  *
  25.  * Revision 4.3.2.1  89/11/06  01:03:21  sob
  26.  * Added RRN support from NNTP 1.5
  27.  *
  28.  * Revision 4.3.1.2  85/05/15  14:44:27  lwall
  29.  * Last arg of execl changed from 0 to Nullch [(char*)0].
  30.  *
  31.  * Revision 4.3.1.1  85/05/10  11:41:30  lwall
  32.  * Branch for patches.
  33.  *
  34.  * Revision 4.3  85/05/01  11:51:44  lwall
  35.  * Baseline for release with 4.3bsd.
  36.  *
  37.  */
  38.  
  39. #include <string.h>
  40.  
  41. #include "EXTERN.h"
  42. #include "common.h"
  43. #include "final.h"
  44. #include "ndir.h"
  45. #include "INTERN.h"
  46. #include "util.h"
  47.  
  48. #ifdef   msdos
  49. #include <process.h>
  50. #endif                       /* msdos */
  51.  
  52. void
  53.   util_init()
  54. {
  55.    ;
  56. }
  57.  
  58. #ifdef   unix
  59. /* fork and exec a shell command */
  60.  
  61. int
  62.   doshell(shl, s)
  63.    char *s, *shl;
  64. {
  65.    int status, pid, w;
  66.    char *shell;
  67.  
  68. #ifdef SIGTSTP
  69.    sigset(SIGTSTP, SIG_DFL);
  70.    sigset(SIGTTOU, SIG_DFL);
  71.    sigset(SIGTTIN, SIG_DFL);
  72. #endif
  73.  
  74.    if (shl != Nullch)
  75.       shell = shl;
  76.    else if ((shell = getenv("SHELL")) == Nullch || !*shell)
  77.       shell = PREFSHELL;
  78.    if ((pid = vfork()) == 0)
  79.    {
  80.  
  81. #ifdef SERVER
  82.       int i;
  83.  
  84.       /* This is necessary to keep bourne shell from puking */
  85.  
  86.       for (i = 3; i < 10; ++i)
  87.          close(i);
  88. #endif                       /* SERVER */
  89.  
  90.       if (*s)
  91.          execl(shell, shell, "-c", s, Nullch);
  92.       else
  93.          execl(shell, shell, Nullch, Nullch, Nullch);
  94.       _exit(127);
  95.    }
  96.    signal(SIGINT, SIG_IGN);
  97.  
  98. #ifdef   SIGQUIT
  99.    signal(SIGQUIT, SIG_IGN);
  100. #endif                       /* SIGQUIT */
  101.  
  102.    waiting = TRUE;
  103.    while ((w = wait(&status)) != pid && w != -1)
  104.       ;
  105.    if (w == -1)
  106.       status = -1;
  107.    waiting = FALSE;
  108.    sigset(SIGINT, int_catcher); /* always catch
  109.                                  * interrupts */
  110.  
  111. #ifdef   SIGQUIT
  112.    signal(SIGQUIT, SIG_DFL);
  113. #endif                       /* SIGQUIT */
  114.  
  115. #ifdef SIGTSTP
  116.    sigset(SIGTSTP, stop_catcher);
  117.    sigset(SIGTTOU, stop_catcher);
  118.    sigset(SIGTTIN, stop_catcher);
  119. #endif
  120.  
  121.    return status;
  122. }
  123.  
  124. #endif                       /* unix */
  125.  
  126. #ifdef   msdos
  127. /* fork and exec a shell command */
  128.  
  129. int
  130.   doshell(shl, cmd_str)
  131.    char *shl;
  132.    char *cmd_str;
  133. {
  134.    int status;
  135.    char *shell;
  136.    char *z;
  137.    char *zxz;
  138.    char *zz[11];
  139.    int i;
  140.  
  141.    if (shl != Nullch)
  142.       shell = shl;
  143.    else if ((shell = getenv("SHELL")) == Nullch || !*shell)
  144.       shell = PREFSHELL;
  145.  
  146.    if (*cmd_str)
  147.    {
  148.       i = 0;
  149.       z = cmd_str;
  150.       zz[0] = z;
  151.       zxz = strchr(z, ' ');
  152.       while ((z != zxz) && (*zxz != '\\'))
  153.          zxz--;
  154.       if (*zxz == '\\')
  155.          zxz++;
  156.       while ((*z != '\0') && (i < 9))
  157.       {
  158.          z = strchr(z, ' ');
  159.          if (z == NULL)
  160.             break;
  161.          if (*z == ' ')
  162.          {
  163.             *z = '\0';
  164.             z++;
  165.          }
  166.          zz[++i] = z;
  167.       }
  168.       zz[++i] = Nullch;
  169.  
  170.       /* status = spawnlp(P_WAIT, shell, shell, "/c", cmd_str, Nullch); */
  171.       status = spawnlp(P_WAIT, zz[0], zxz, zz[1], zz[2], zz[3], zz[4], zz[5], zz[6], zz[7], zz[8], zz[9], Nullch);
  172.  
  173.    }
  174.    else
  175.    {
  176.       status = spawnlp(P_WAIT, shell, shell, Nullch, Nullch, Nullch);
  177.    }
  178.  
  179.    return status;
  180. }
  181.  
  182. #endif                       /* msdos */
  183.  
  184. static char nomem[] = "rn: out of memory!\n";
  185.  
  186. /* paranoid version of malloc */
  187.  
  188. char *
  189.   safemalloc(size)
  190.    MEM_SIZE size;
  191. {
  192.    char *ptr;
  193.    char *malloc();
  194.  
  195.    ptr = malloc(size ? size : 1);       /* malloc(0) is NASTY on
  196.                                          * our system */
  197.    if (ptr != Nullch)
  198.       return ptr;
  199.    else
  200.    {
  201.       fputs(nomem, stdout) FLUSH;
  202.       sig_catcher(0);
  203.    }
  204.    /* NOTREACHED */
  205. }
  206.  
  207. /* paranoid version of realloc */
  208.  
  209. char *
  210.   saferealloc(where, size)
  211.    char *where;
  212.    MEM_SIZE size;
  213. {
  214.    char *ptr;
  215.    char *realloc();
  216.  
  217.    ptr = realloc(where, size ? size : 1);       /* realloc(0) is NASTY
  218.                                                  * on our system */
  219.    if (ptr != Nullch)
  220.       return ptr;
  221.    else
  222.    {
  223.       fputs(nomem, stdout) FLUSH;
  224.       sig_catcher(0);
  225.    }
  226.    /* NOTREACHED */
  227. }
  228.  
  229. /* safe version of string copy */
  230.  
  231. char *
  232.   safecpy(to, from, len)
  233.    char *to;
  234.    register char *from;
  235.    register int len;
  236. {
  237.    register char *dest = to;
  238.  
  239.    if (from != Nullch)
  240.       for (len--; len && (*dest++ = *from++); len--);
  241.    *dest = '\0';
  242.    return to;
  243. }
  244.  
  245. /* safe version of string concatenate, with \n deletion and space padding */
  246.  
  247. char *
  248.   safecat(to, from, len)
  249.    char *to;
  250.    register char *from;
  251.    register int len;
  252. {
  253.    register char *dest = to;
  254.  
  255.    len--;                    /* leave room for null */
  256.    if (*dest)
  257.    {
  258.       while (len && *dest++)
  259.          len--;
  260.       if (len)
  261.       {
  262.          len--;
  263.          *(dest - 1) = ' ';
  264.       }
  265.    }
  266.    if (from != Nullch)
  267.       while (len && (*dest++ = *from++))
  268.          len--;
  269.    if (len)
  270.       dest--;
  271.    if (*(dest - 1) == '\n')
  272.       dest--;
  273.    *dest = '\0';
  274.    return to;
  275. }
  276.  
  277. /* copy a string up to some (non-backslashed) delimiter, if any */
  278.  
  279. char *
  280.   cpytill(to, from, delim)
  281.    register char *to, *from;
  282.    register int delim;
  283. {
  284.    for (; *from; from++, to++)
  285.    {
  286.       if (*from == '\\' && from[1] == delim)
  287.          from++;
  288.       else if (*from == delim)
  289.          break;
  290.       *to = *from;
  291.    }
  292.    *to = '\0';
  293.    return from;
  294. }
  295.  
  296. /* return ptr to little string in big string, NULL if not found */
  297.  
  298. char *
  299.   instr(big, little)
  300.    char *big, *little;
  301.  
  302. {
  303.    register char *t, *s, *x;
  304.  
  305.    for (t = big; *t; t++)
  306.    {
  307.       for (x = t, s = little; *s; x++, s++)
  308.       {
  309.          if (!*x)
  310.             return Nullch;
  311.          if (*s != *x)
  312.             break;
  313.       }
  314.       if (!*s)
  315.          return t;
  316.    }
  317.    return Nullch;
  318. }
  319.  
  320. /* effective access */
  321.  
  322. #ifdef SETUIDGID
  323. int
  324.   eaccess(filename, mod)
  325.    char *filename;
  326.    int mod;
  327. {
  328.    int protection, euid;
  329.  
  330.    mod &= 7;                 /* remove extraneous
  331.                               * garbage */
  332.    if (stat(filename, &filestat) < 0)
  333.       return -1;
  334.    euid = geteuid();
  335.    if (euid == ROOTID)
  336.       return 0;
  337.    protection = 7 & (filestat.st_mode >>
  338.                      (filestat.st_uid == euid ? 6 :
  339.                       (filestat.st_gid == getegid() ? 3 : 0)
  340.                       ));
  341.    if ((mod & protection) == mod)
  342.       return 0;
  343.    errno = EACCES;
  344.    return -1;
  345. }
  346.  
  347. #endif
  348.  
  349. /*
  350.  * Get working directory
  351.  */
  352.  
  353. #ifdef GETCWD
  354. char *
  355.   getwd(np)
  356.    char *np;
  357. {
  358.    char *name;
  359.    extern char *getcwd();
  360.  
  361.    name = getcwd(np, 1024);
  362.    return (name);
  363. }
  364.  
  365. #else
  366.  
  367. #ifndef GETWD
  368. char *
  369.   getwd(np)                  /* shorter but slower */
  370.    char *np;
  371. {
  372.    FILE *popen();
  373.    FILE *pipefp = popen("/bin/pwd", "r");
  374.  
  375.    if (pipefp == Nullfp)
  376.    {
  377.       printf("Can't run /bin/pwd\n") FLUSH;
  378.       finalize(1);
  379.    }
  380.    fgets(np, 512, pipefp);
  381.    np[strlen(np) - 1] = '\0';/* wipe out newline */
  382.    pclose(pipefp);
  383.    return np;
  384. }
  385.  
  386. #endif
  387.  
  388. #endif
  389.  
  390. /* just like fgets but will make bigger buffer as necessary */
  391.  
  392. char *
  393.   get_a_line(original_buffer, buffer_length, fp)
  394.    char *original_buffer;
  395.    register int buffer_length;
  396.    FILE *fp;
  397. {
  398.    register int bufix = 0;
  399.    register int nextch;
  400.    register char *some_buffer_or_other = original_buffer;
  401.  
  402.    do
  403.    {
  404.       if (bufix >= buffer_length)
  405.       {
  406.          buffer_length *= 2;
  407.          if (some_buffer_or_other == original_buffer)
  408.          {
  409.             /* currently static? */
  410.             some_buffer_or_other = safemalloc((MEM_SIZE) buffer_length + 1);
  411.             strncpy(some_buffer_or_other, original_buffer, buffer_length / 2);
  412.             /* so we must copy it */
  413.          }
  414.          else
  415.          {                   /* just grow in place,
  416.                               * if possible */
  417.             some_buffer_or_other = saferealloc(some_buffer_or_other,
  418.                                                (MEM_SIZE) buffer_length + 1);
  419.          }
  420.       }
  421.       if ((nextch = getc(fp)) == EOF)
  422.          return Nullch;
  423.       some_buffer_or_other[bufix++] = (char) nextch;
  424.    } while (nextch && nextch != '\n');
  425.    some_buffer_or_other[bufix] = '\0';
  426.    len_last_line_got = bufix;
  427.    return some_buffer_or_other;
  428. }
  429.  
  430. /* copy a string to a safe spot */
  431.  
  432. char *
  433.   savestr(str)
  434.    char *str;
  435. {
  436.    register char *newaddr = safemalloc((MEM_SIZE) (strlen(str) + 1));
  437.  
  438.    strcpy(newaddr, str);
  439.    return newaddr;
  440. }
  441.  
  442. int
  443.   makedir(dirname, nametype)
  444.    register char *dirname;
  445.    int nametype;
  446. {
  447.  
  448. #ifdef MAKEDIR
  449.    register char *end;
  450.    register char *s;
  451.    char tmpbuf[1024];
  452.    register char *tbptr = tmpbuf + 5;
  453.  
  454.    for (end = dirname; *end; end++);    /* find the end */
  455.    if (nametype == MD_FILE)
  456.    {                         /* not to create last
  457.                               * component? */
  458.       for (--end; end != dirname && *end != '/'; --end);
  459.       if (*end != '/')
  460.          return 0;           /* nothing to make */
  461.       *end = '\0';           /* isolate file name */
  462.    }
  463.    strcpy(tmpbuf, "mkdir");
  464.  
  465.    s = end;
  466.    for (;;)
  467.    {
  468.       if (stat(dirname, &filestat) >= 0)
  469.       {
  470.          /* does this much exist? */
  471.          *s = '/';           /* mark this as existing */
  472.          break;
  473.       }
  474.       s = rindex(dirname, '/'); /* shorten name */
  475.       if (!s)                /* relative path! */
  476.          break;              /* hope they know what
  477.                               * they are doing */
  478.       *s = '\0';             /* mark as not existing */
  479.    }
  480.  
  481.    for (s = dirname; s <= end; s++)
  482.    {                         /* this is grody but
  483.                               * efficient */
  484.       if (!*s)
  485.       {                      /* something to make? */
  486.          sprintf(tbptr, " %s", dirname);
  487.          tbptr += strlen(tbptr);        /* make it, sort of */
  488.          *s = '/';           /* mark it made */
  489.       }
  490.    }
  491.    if (nametype == MD_DIR)   /* don't need final
  492.                               * slash unless */
  493.       *end = '\0';           /* a filename follows
  494.                               * the dir name */
  495.  
  496.    return (tbptr == tmpbuf + 5 ? 0 : doshell(sh, tmpbuf));
  497.    /* exercise our faith */
  498. #endif                       /* MAKEDIR */
  499.  
  500. #ifdef   DIRMAKER
  501.    sprintf(cmd_buf, "%s %s %d", filexp(DIRMAKER), dirname, nametype);
  502.    return doshell(sh, cmd_buf);
  503. #endif                       /* DIRMAKER */
  504.  
  505. #ifdef   MKDIR
  506.    register char *end;
  507.    register char *s;
  508.  
  509.    for (end = dirname; *end; end++);    /* find the end */
  510.    if (nametype == MD_FILE)
  511.    {                         /* not to create last
  512.                               * component? */
  513.       for (--end; end != dirname && *end != '/'; --end);
  514.       if (*end != '/')
  515.          return 0;           /* nothing to make */
  516.       *end = '\0';           /* isolate file name */
  517.    }
  518.  
  519.    s = end;
  520.    for (;;)
  521.    {
  522.       if (stat(dirname, &filestat) >= 0)
  523.       {
  524.          /* does this much exist? */
  525.          *s = '/';           /* mark this as existing */
  526.          break;
  527.       }
  528.       s = rindex(dirname, '/'); /* shorten name */
  529.       if (!s)                /* relative path! */
  530.          break;              /* hope they know what
  531.                               * they are doing */
  532.       *s = '\0';             /* mark as not existing */
  533.    }
  534.  
  535.    for (s = dirname; s <= end; s++)
  536.    {                         /* this is grody but
  537.                               * efficient */
  538.       if (!*s)
  539.       {                      /* something to make? */
  540.          if (mkdir(dirname))
  541.             return -1;
  542.          *s = '/';           /* mark it made */
  543.       }
  544.    }
  545.    if (nametype == MD_DIR)   /* don't need final
  546.                               * slash unless */
  547.       *end = '\0';           /* a filename follows
  548.                               * the dir name */
  549.  
  550.    return 0;
  551. #endif                       /* MKDIR */
  552. }
  553.  
  554. #ifdef SETENV
  555. static bool firstsetenv = TRUE;
  556. extern char **environ;
  557.  
  558. void
  559.   setenv(nam, val)
  560.    char *nam, *val;
  561. {
  562.    register int i = envix(nam); /* where does it go? */
  563.  
  564.    if (!environ[i])
  565.    {                         /* does not exist yet */
  566.       if (firstsetenv)
  567.       {                      /* need we copy
  568.                               * environment? */
  569.          int j;
  570.  
  571. #ifndef lint
  572.          char **tmpenv = (char **)      /* point our wand at
  573.                                          * memory */
  574.          safemalloc((MEM_SIZE) (i + 2) * sizeof (char *));
  575.  
  576. #else
  577.          char **tmpenv = Null(char **);
  578.  
  579. #endif                       /* lint */
  580.  
  581.          firstsetenv = FALSE;
  582.          for (j = 0; j < i; j++)        /* copy environment */
  583.             tmpenv[j] = environ[j];
  584.          environ = tmpenv;   /* tell exec where it is
  585.                               * now */
  586.       }
  587.  
  588. #ifndef lint
  589.       else
  590.          environ = (char **) saferealloc((char *) environ,
  591.                                          (MEM_SIZE) (i + 2) * sizeof (char *));
  592.       /* just expand it a bit */
  593. #endif                       /* lint */
  594.  
  595.       environ[i + 1] = Nullch;  /* make sure it's null
  596.                                  * terminated */
  597.    }
  598.    environ[i] = safemalloc((MEM_SIZE) strlen(nam) + strlen(val) + 2);
  599.    /* this may or may not be in */
  600.    /* the old environ structure */
  601.    sprintf(environ[i], "%s=%s", nam, val);      /* all that work just
  602.                                                  * for this */
  603. }
  604.  
  605. int
  606.   envix(nam)
  607.    char *nam;
  608. {
  609.    register int i, len = strlen(nam);
  610.  
  611.    for (i = 0; environ[i]; i++)
  612.    {
  613.       if (strnEQ(environ[i], nam, len) && environ[i][len] == '=')
  614.          break;              /* strnEQ must come
  615.                               * first to avoid */
  616.    }                         /* potential SEGV's */
  617.    return i;
  618. }
  619.  
  620. #endif
  621.  
  622. void
  623.   notincl(feature)
  624.    char *feature;
  625. {
  626.    printf("\nNo room for feature \"%s\" on this machine.\n", feature) FLUSH;
  627. }
  628.  
  629. char *
  630.   getval(nam, def)
  631.    char *nam, *def;
  632. {
  633.    char *val;
  634.  
  635.    if ((val = getenv(nam)) == Nullch || !*val)
  636.       val = def;
  637.    return val;
  638. }
  639.  
  640. /* grow a static string to at least a certain length */
  641.  
  642. void
  643.   growstr(strptr, curlen, newlen)
  644.    char **strptr;
  645.    int *curlen;
  646.    int newlen;
  647. {
  648.    if (newlen > *curlen)
  649.    {                         /* need more room? */
  650.       if (*curlen)
  651.          *strptr = saferealloc(*strptr, (MEM_SIZE) newlen);
  652.       else
  653.          *strptr = safemalloc((MEM_SIZE) newlen);
  654.       *curlen = newlen;
  655.    }
  656. }
  657.  
  658. void
  659.   setdef(buffer, dflt)
  660.    char *buffer, *dflt;
  661. {
  662.  
  663. #ifdef STRICTCR
  664.    if (*buffer == ' ')
  665. #else
  666.    if (*buffer == ' ' || *buffer == '\n')
  667. #endif
  668.  
  669.    {
  670.       if (*dflt == '^' && isupper(dflt[1]))
  671.          *buffer = Ctl(dflt[1]);
  672.       else
  673.          *buffer = *dflt;
  674.    }
  675. }
  676.  
  677. #ifdef   msdos
  678. /* If there's a return in the string, turn it into a newline and */
  679. /* terminate the string at that point. */
  680. stripcr(s)
  681.    char *s;
  682. {
  683.    if (s = index(s, '\r'))
  684.    {
  685.       *s++ = '\n';
  686.       *s = '\0';
  687.    }
  688. }
  689.  
  690. #endif                       /* msdos */
  691.