home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 4 / CDPD_IV.bin / networking / tcpip / amitcp-support / ncftp-1.5.6 / src / rcs / util.c,v < prev    next >
Encoding:
Text File  |  1994-06-29  |  17.0 KB  |  901 lines

  1. head    5.2;
  2. access;
  3. symbols
  4.     ORIGINAL:5.1;
  5. locks; strict;
  6. comment    @ * @;
  7.  
  8.  
  9. 5.2
  10. date    93.10.10.20.03.06;    author alph;    state Exp;
  11. branches;
  12. next    5.1;
  13.  
  14. 5.1
  15. date    93.05.23.09.38.13;    author alph;    state Exp;
  16. branches;
  17. next    ;
  18.  
  19.  
  20. desc
  21. @Original version
  22. @
  23.  
  24.  
  25. 5.2
  26. log
  27. @amigados changes
  28. @
  29. text
  30. @/* Util.c */
  31.  
  32. /*  $RCSfile: util.c,v $
  33.  *  $Revision: 1.1 $
  34.  *  $Date: 1993/10/02 10:34:34 $
  35.  */
  36.  
  37. #include "sys.h"
  38.  
  39. #include <string.h>
  40. #include <errno.h>
  41. #include <ctype.h>
  42. #include <sys/time.h>
  43. #include <time.h>
  44. #include <pwd.h>
  45.  
  46. #ifndef NO_VARARGS
  47. #    include <stdarg.h>
  48. #endif
  49.  
  50. #ifndef NO_UNISTDH
  51. #    include <unistd.h>
  52. #endif
  53.  
  54. #ifdef READLINE
  55. #    include <readline/readline.h>
  56. #endif /* READLINE */
  57.  
  58. #ifdef GETLINE
  59. #    include <getline.h>
  60. #endif
  61.  
  62. #include "util.h"
  63. #include "cmds.h"
  64. #include "main.h"
  65. #include "ftp.h"
  66. #include "ftprc.h"
  67. #include "defaults.h"
  68. #include "copyright.h"
  69.  
  70. /* Util.c globals */
  71. int                    Opterr = 1;            /* if error message should be printed */
  72. int                    Optind = 1;            /* index into parent argv vector */
  73. int                    Optopt;                /* character checked for validity */
  74. char                *Optarg;            /* argument associated with option */
  75. char                *Optplace = EMSG;    /* saved position in an arg */
  76.  
  77. /* Util.c externs */
  78. extern int            toatty, fromatty;
  79. extern int            verbose;
  80. extern string        prompt2;
  81. extern char            *line, *margv[];
  82. extern int            margc;
  83. extern int            debug, mprompt, activemcmd;
  84. extern string        progname;
  85. extern struct cmd    cmdtab[];
  86. extern struct userinfo uinfo;
  87.  
  88. #ifndef NO_VARARGS
  89. void dbprintf(char *fmt, ...)
  90. {
  91.     va_list ap;
  92.  
  93.     if (debug) {
  94.         (void) fprintf(DB_STREAM, "#DB# ");
  95.         va_start(ap, fmt);
  96.         (void) vfprintf(DB_STREAM, fmt, ap);
  97.         va_end(ap);
  98.         (void) fflush(DB_STREAM);
  99.     }
  100. }    /* dbprintf */
  101. #endif
  102.  
  103.  
  104.  
  105.  
  106. /*
  107.  * Concatenate src on the end of dst.  The resulting string will have at most
  108.  * n-1 characters, not counting the NUL terminator which is always appended
  109.  * unlike strncat.  The other big difference is that strncpy uses n as the
  110.  * max number of characters _appended_, while this routine uses n to limit
  111.  * the overall length of dst.
  112.  */
  113. char *_Strncat(char *dst, char *src, register size_t n)
  114. {
  115.     register size_t i;
  116.     register char *d, *s;
  117.  
  118.     if (n != 0 && ((i = strlen(dst)) < (n - 1))) {
  119.         d = dst + i;
  120.         s = src;
  121.         /* If they specified a maximum of n characters, use n - 1 chars to
  122.          * hold the copy, and the last character in the array as a NUL.
  123.          * This is the difference between the regular strncpy routine.
  124.          * strncpy doesn't guarantee that your new string will have a
  125.          * NUL terminator, but this routine does.
  126.          */
  127.         for (++i; i<n; i++) {
  128.             if ((*d++ = *s++) == 0) {
  129.                 /* Pad with zeros. */
  130.                 for (; i<n; i++)
  131.                     *d++ = 0;
  132.                 return dst;
  133.             }
  134.         }
  135.         /* If we get here, then we have a full string, with n - 1 characters,
  136.          * so now we NUL terminate it and go home.
  137.          */
  138.         *d = 0;
  139.     }
  140.     return (dst);
  141. }    /* _Strncat */
  142.  
  143.  
  144. /*
  145.  * Copy src to dst, truncating or null-padding to always copy n-1 bytes.
  146.  * Return dst.
  147.  */
  148. char *_Strncpy(char *dst, char *src, register size_t n)
  149. {
  150.     register char *d;
  151.     register char *s;
  152.     register size_t i;
  153.  
  154.     d = dst;
  155.     *d = 0;
  156.     if (n != 0) {
  157.         s = src;
  158.         /* If they specified a maximum of n characters, use n - 1 chars to
  159.          * hold the copy, and the last character in the array as a NUL.
  160.          * This is the difference between the regular strncpy routine.
  161.          * strncpy doesn't guarantee that your new string will have a
  162.          * NUL terminator, but this routine does.
  163.          */
  164.         for (i=1; i<n; i++) {
  165.             if ((*d++ = *s++) == 0) {
  166.                 /* Pad with zeros. */
  167.                 for (; i<n; i++)
  168.                     *d++ = 0;
  169.                 return dst;
  170.             }
  171.         }
  172.         /* If we get here, then we have a full string, with n - 1 characters,
  173.          * so now we NUL terminate it and go home.
  174.          */
  175.         *d = 0;
  176.     }
  177.     return (dst);
  178. }    /* _Strncpy */
  179.  
  180.  
  181.  
  182.  
  183. char *Strpcpy(char *dst, char *src)
  184. {
  185.     while (*dst++ = *src++)
  186.         ;
  187.     return (--dst);    /* return current value of dst, NOT original value! */
  188. }    /* Strpcpy */
  189.  
  190.  
  191.  
  192. /*
  193.  * malloc's a copy of oldstr.
  194.  */
  195. char *NewString(char *oldstr)
  196. {
  197.     size_t howLong;
  198.     char *newstr;
  199.  
  200.     howLong = strlen(oldstr);
  201.     if ((newstr = malloc(howLong + 1)) != NULL)
  202.         (void) strcpy(newstr, oldstr);
  203.     return newstr;
  204. }    /* NewString */
  205.  
  206.  
  207.  
  208.  
  209.  
  210. void Getopt_Reset(void)
  211. {
  212.     Optind = 1;
  213.     Optplace = "";
  214. }    /* Getopt_Reset */
  215.  
  216. static char *NextOption(char *ostr)
  217. {
  218.     if ((Optopt = (int) *Optplace++) == (int) ':')
  219.         return 0;
  220.     return index(ostr, Optopt);
  221. }
  222.  
  223. int Getopt(int nargc, char **nargv, char *ostr)
  224. {
  225.     register char *oli;                   /* Option letter list index */
  226.  
  227.     if (!*Optplace) {                       /* update scanning pointer */
  228.         if (Optind >= nargc || *(Optplace = nargv[Optind]) != '-')
  229.             return (EOF);
  230.         if (Optplace[1] && *++Optplace == '-') {    /* found "--" */
  231.             ++Optind;
  232.             return (EOF);
  233.         }
  234.     }                                   /* Option letter okay? */
  235.     oli = NextOption(ostr);
  236.     if (oli == NULL) {
  237.         if (!*Optplace)
  238.             ++Optind;
  239.         if (Opterr) {
  240.             (void) fprintf(stderr, "%s%s%c\n", *nargv, ": illegal option -- ", Optopt);
  241.             return(BADCH);
  242.         }
  243.     }
  244.     if (*++oli != ':') {               /* don't need argument */
  245.         Optarg = NULL;
  246.         if (!*Optplace)
  247.             ++Optind;
  248.     } else {                           /* need an argument */
  249.         if (*Optplace)                       /* no white space */
  250.             Optarg = Optplace;
  251.         else if (nargc <= ++Optind) {  /* no arg */
  252.             Optplace = EMSG;
  253.             if (Opterr) {
  254.                 (void) fprintf(stderr, "%s%s%c\n", *nargv, ": option requires an argument -- ", Optopt);
  255.                 return(BADCH);
  256.             }
  257.         } else                           /* white space */
  258.             Optarg = nargv[Optind];
  259.         Optplace = EMSG;
  260.         ++Optind;
  261.     }
  262.     return (Optopt);                   /* dump back Option letter */
  263. }                                       /* Getopt */
  264.  
  265.  
  266.  
  267.  
  268. /*
  269.  * Converts an ls date, in either the "Feb  4  1992" or "Jan 16 13:42"
  270.  * format to a time_t.
  271.  */
  272. unsigned long UnLSDate(char *dstr)
  273. {
  274. #ifdef NO_MKTIME
  275.     return (0);
  276. #else
  277.     char *cp = dstr;
  278.     int long mon, day, year, hr, min;
  279.     time_t now;
  280.     struct tm ut, *t;
  281.  
  282.     switch (*cp++) {
  283.         case 'A':
  284.             mon = (*cp == 'u') ? 7 : 3;
  285.             break;
  286.         case 'D':
  287.             mon = 11;
  288.             break;
  289.         case 'F':
  290.             mon = 1;
  291.             break;
  292.         default:                       /* shut up un-init warning */
  293.         case 'J':
  294.             if (*cp++ == 'u')
  295.                 mon = (*cp == 'l') ? 6 : 5;
  296.             else
  297.                 mon = 0;
  298.             break;
  299.         case 'M':
  300.             mon = (*++cp == 'r') ? 2 : 4;
  301.             break;
  302.         case 'N':
  303.             mon = 10;
  304.             break;
  305.         case 'O':
  306.             mon = 9;
  307.             break;
  308.         case 'S':
  309.             mon = 8;
  310.     }
  311.     cp = dstr + 4;
  312.     day = 0;
  313.     if (*cp != ' ')
  314.         day = 10 * (*cp - '0');
  315.     cp++;
  316.     day += *cp++ - '0';
  317.     min = 0;
  318.     
  319.     (void) time(&now);
  320.     t = localtime(&now);
  321.  
  322.     if (*++cp != ' ') {
  323.         /* It's a time, XX:YY, not a year. */
  324.         cp[2] = ' ';
  325.         (void) sscanf(cp, "%ld %ld", &hr, &min);
  326.         cp[2] = ':';
  327.         year = t->tm_year;
  328.         if (mon > t->tm_mon)
  329.             --year;
  330.     } else {
  331.         hr = min = 0;
  332.         (void) sscanf(cp, "%ld", &year);
  333.         year -= 1900;
  334.     }
  335.     ut.tm_sec = 1;
  336.     ut.tm_min = min;
  337.     ut.tm_hour = hr;
  338.     ut.tm_mday = day;
  339.     ut.tm_mon = mon;
  340.     ut.tm_year = year;
  341.     ut.tm_isdst = t->tm_isdst;
  342.     ut.tm_wday = ut.tm_yday = 0;
  343.     return ((unsigned long) mktime(&ut));
  344. #endif    /* NO_MKTIME */
  345. }    /* UnLSDate */
  346.  
  347.  
  348.  
  349.  
  350. void Perror(
  351. #ifdef DB_ERRS
  352.             char *fromProc
  353.             ,
  354. #ifdef __LINE__
  355.             int lineNum,
  356. #endif
  357. #endif
  358.             char *msg
  359.             )
  360. {
  361.     extern int errno;
  362.  
  363.     if (NOT_VQUIET) {
  364. #ifdef sun
  365.     /*
  366.      * There is a problem in the SunOS headers when compiling with an ANSI
  367.      * compiler.  The problem is that there are macros in the form of
  368.      * #define MAC(x) 'x', and this will always be the character x instead
  369.      * of whatever parameter was passed to MAC.  If we get these errors, it
  370.      * usually means that you are trying to compile with gcc when you haven't
  371.      * run the 'fixincludes' script that fixes these macros.  We will ignore
  372.      * the error, but it means that the echo() function won't work correctly,
  373.      * and you will see your password echo.
  374.      */
  375.         if (errno == ENOTTY)
  376.             return;
  377. #endif
  378.         (void) fprintf(stderr, "NcFTP");
  379. #ifdef DB_ERRS
  380.         if (fromProc != NULL)
  381.             (void) fprintf(stderr, "/%s", fromProc);
  382. #ifdef __LINE__
  383.         (void) fprintf(stderr, "/%d", lineNum);
  384. #endif
  385. #endif
  386.         (void) fprintf(stderr, ": ");
  387.         if (msg != NULL)
  388.             (void) fprintf(stderr, "%s (%d): ", msg, errno);
  389.         perror(NULL);
  390.     }
  391. }    /* Perror */
  392.  
  393.  
  394.  
  395.  
  396. size_t RemoveTrailingNewline(char *cp, int *stripped)
  397. {
  398.     size_t len;
  399.     int nBytesStripped = 0;
  400.  
  401.     if (cp != NULL) {
  402.         cp += (len = strlen(cp)) - 1;
  403.         if (*cp == '\n') {
  404.             *cp-- = 0;    /* get rid of the newline. */
  405.             nBytesStripped++;
  406.         }
  407.         if (*cp == '\r') { /* no returns either, please. */
  408.             *cp = 0;
  409.             nBytesStripped++;
  410.         }
  411.         if (stripped != NULL)
  412.             *stripped = nBytesStripped;
  413.         return len;
  414.     }
  415.     return (size_t)0;
  416. }    /* RemoveTrailingNewline */
  417.  
  418.  
  419.  
  420. #ifdef GETLINE
  421. extern size_t epromptlen;
  422.  
  423. /*
  424.  * The Getline library doesn't detect the ANSI escape sequences, so the
  425.  * library would think that a string is longer than actually appears on
  426.  * screen.  This function lets Getline work properly.  This function is
  427.  * intended to fix that problem for the main command prompt only.  If any
  428.  * other prompts want to use ANSI escapes, a (costly) function would have
  429.  * to scan the prompt for all escape sequences.
  430.  */
  431. /*ARGSUSED*/
  432. static size_t MainPromptLen(char *pr)
  433. {
  434.     return (int)epromptlen;
  435. }
  436. #endif
  437.  
  438. char *Gets(char *promptstr, char *sline, size_t size)
  439. {
  440.     char *cp, ch;
  441.     string plines;
  442. #ifdef GETLINE
  443.     int ismainprompt = (promptstr == prompt2);
  444. #endif
  445.  
  446.     if (!fromatty || !toatty) {
  447.         /* Don't worry about a cmdline/history editor if you redirected a
  448.          * file at me.
  449.          */
  450.         if (!toatty && fromatty) {
  451.             /* It's okay to print a prompt if we are redirecting stdout,
  452.              * as long as stdin is still a tty.  Otherwise, don't print
  453.              * a prompt at all if stdin is redirected.
  454.              */
  455. #ifdef CURSES
  456.             tcap_put(promptstr);
  457. #else
  458.             (void) fputs(promptstr, stdout);
  459. #endif
  460.         }
  461.         cp = fgets(sline, (int)size, stdin);
  462.         (void) RemoveTrailingNewline(cp, NULL);
  463.         return cp;
  464.     }
  465.  
  466.     /*
  467.      * The prompt string may actually be several lines if the user put a
  468.      * newline in it with the @@N option.  In this case we only want to print
  469.      * the very last line, so the command-line editors won't screw up.  So
  470.      * now we print all the lines except the last line.
  471.      */
  472.     cp = rindex(promptstr, '\n');
  473.     if (cp != NULL) {
  474.         ch = *++cp;
  475.         *cp = 0;
  476.         (void) Strncpy(plines, promptstr);
  477.         *cp = ch;
  478.         promptstr = cp;
  479. #ifdef CURSES
  480.         tcap_put(plines);
  481. #else
  482.         (void) fputs(plines, stdout);
  483. #endif
  484.     }
  485.  
  486. #ifdef READLINE
  487.     if ((cp = readline(promptstr)) != NULL) {
  488.         (void) _Strncpy(sline, cp, size);
  489.         free(cp);
  490.         (void) RemoveTrailingNewline(cp = sline, NULL);
  491.         if (*cp != 0)    /* Don't add blank lines to history buffer. */
  492.             add_history(cp);
  493.     }
  494. #else    /* READLINE */
  495.  
  496. #ifdef GETLINE
  497.     if (toatty) {
  498.         if (ismainprompt)
  499.             gl_strwidth(MainPromptLen);
  500.         if ((cp = getline(promptstr)) != NULL) {
  501.             (void) _Strncpy(sline, cp, size);
  502.             if (*cp != 0) {        /* Don't add blank lines to history buffer. */
  503.                 gl_histadd(cp);
  504.                 cp = sline;
  505.             }
  506.         }
  507.         /* Hope your strlen is declared as returning a size_t. */
  508.         gl_strwidth(strlen);
  509.     } else {
  510. #ifdef CURSES
  511.         tcap_put(promptstr);
  512. #else
  513.         (void) fputs(promptstr, stdout);
  514. #endif
  515.         cp = fgets(sline, (int) (size - 1), stdin);
  516.     }
  517.     (void) RemoveTrailingNewline(cp, NULL);
  518. #else /* !GETLINE */
  519.  
  520. #ifdef CURSES
  521.     tcap_put(promptstr);
  522. #else
  523.     (void) fputs(promptstr, stdout);
  524. #endif
  525.  
  526.     cp = fgets(sline, (int) (size - 1), stdin);
  527.     (void) RemoveTrailingNewline(cp, NULL);
  528. #endif /* !GETLINE */
  529. #endif /* !READLINE */
  530.     return cp;
  531. }    /* Gets */
  532.  
  533.  
  534.  
  535.  
  536. char **re_makeargv(char *promptstr, int *argc)
  537. {
  538.     size_t sz;
  539.  
  540.     (void) strcat(line, " ");
  541.     sz = strlen(line);
  542.     (void) Gets(promptstr, &line[sz], (size_t) (CMDLINELEN - sz)) ;
  543.     (void) makeargv();
  544.     *argc = margc;
  545.     return (margv);
  546. }    /* re_makeargv */
  547.  
  548.  
  549.  
  550.  
  551. char *get_cwd(char *buf, int size)
  552. {
  553. #if defined(SYSV) || defined(USE_GETCWD)
  554. #    if defined(NO_UNISTDH) && !defined(HAS_GETCWD_PROTO)
  555. #        ifdef GETCWDSIZET
  556.             extern char *getcwd(char *, size_t);
  557. #        else
  558.             extern char *getcwd(char *, int);
  559. #        endif
  560. #    endif
  561.     return (getcwd(buf, size - 1));
  562. #else
  563.     extern char *getwd(char *);
  564.     return (getwd(buf));
  565. #endif
  566. }   /* get_cwd */
  567.  
  568.  
  569.  
  570. int tmp_name(char *str)
  571. {
  572. #ifdef TMP_NAME
  573.     (void) strcpy(str, "/tmp/ncftpXXXXXX");
  574. #else
  575.     (void) strcpy(str, TMP_NAME);
  576. #endif
  577. #ifdef USE_TMPNAM
  578.     return (!tmpnam(str));
  579. #else
  580.     return (!mktemp(str));
  581. #endif
  582. }    /* tmp_name */
  583.  
  584.  
  585.  
  586.  
  587. char *onoff(int boolf)
  588. {
  589.     return (boolf ? "on" : "off");
  590. }   /* onoff */
  591.  
  592.  
  593.  
  594.  
  595. int StrToBool(char *s)
  596. {
  597.     int c;
  598.     int result;
  599.  
  600.     c = tolower(*s);
  601.     result = 0;
  602.     switch (c) {
  603.         case 'f':           /* false */
  604.         case 'n':            /* no */
  605.             break;
  606.         case 'o':           /* test for "off" and "on" */
  607.             c = tolower(s[1]);
  608.             if (c == 'f')
  609.                 break;
  610.             /* fall through */
  611.         case 't':           /* true */
  612.         case 'y':            /* yes */
  613.             result = 1;
  614.             break;
  615.         default:            /* 1, 0, -1, other number? */
  616.             if (atoi(s) != 0)
  617.                 result = 1;
  618.     }
  619.     return result;
  620. }   /* StrToBool */
  621.  
  622.  
  623.  
  624.  
  625. int confirm(char *cmd, char *file)
  626. {
  627.     str32 str, pr;
  628.  
  629.     if (!fromatty || (activemcmd && !mprompt))
  630.         return 1;
  631.     (void) sprintf(pr, "%s %s? ", cmd, file);
  632.     (void) Gets(pr, str, sizeof(str));
  633.     return (*str != 'n' && *str != 'N');
  634. }    /* confirm */
  635.  
  636.  
  637.  
  638. void fatal(char *msg)
  639. {
  640.     (void) fprintf(stderr, "%s: %s\n", progname, msg);
  641.     close_up_shop();
  642.     exit(1);
  643. }    /* fatal */
  644.  
  645.  
  646.  
  647.  
  648. int UserLoggedIn(void)
  649. {
  650. #ifndef amigados
  651.     static int inited = 0;
  652.     static int parent_pid, stderr_was_tty;
  653.  
  654.     if (!inited) {
  655.         stderr_was_tty = isatty(2);
  656.         parent_pid = getppid();
  657.         inited++;
  658.     }
  659.     if ((stderr_was_tty && !isatty(2)) || (getppid() != parent_pid))
  660.         return 0;
  661.     return 1;
  662. #else
  663.     return 1; /* no parent no die */
  664. #endif
  665. }    /* UserLoggedIn */
  666.  
  667.  
  668.  
  669.  
  670. struct cmd *getcmd(char *name)
  671. {
  672.     struct cmd *c, *found;
  673.     int nmatches;
  674.     size_t len;
  675.     char *p;
  676.  
  677.     found = (struct cmd *)0;
  678.     if (name != NULL) {
  679.         len = strlen(name);
  680.         nmatches = 0;
  681.         for (c = cmdtab; (p = c->c_name) != NULL; c++) {
  682.             if (strcmp(name, p) == 0) {
  683.                 /* Exact match. */
  684.                 found = c;
  685.                 goto xx;
  686.             }
  687.             if (c->c_handler == unimpl)
  688.                 continue;
  689.             if (strncmp(name, p, len) == 0) {
  690.                 if (++nmatches > 1) {
  691.                     found = ((struct cmd *) -1);    
  692.                     goto xx;
  693.                 }                
  694.                 found = c;
  695.             } else if (found != NULL)
  696.                 break;
  697.         }
  698.     }
  699. xx:
  700.     return (found);
  701. }    /* getcmd */
  702.  
  703.  
  704.  
  705.  
  706. void cmd_help(struct cmd *c)
  707. {
  708.     (void) printf("%s: %s.\n",
  709.         c->c_name,
  710.         c->c_help
  711.     );
  712. }    /* cmd_help */
  713.  
  714.  
  715.  
  716.  
  717. void cmd_usage(struct cmd *c)
  718. {
  719.     if (c->c_usage != NULL)
  720.         (void) printf("Usage: %s%s\n",
  721.             c->c_name,
  722.             c->c_usage
  723.         );
  724. }    /* cmd_usage */
  725.  
  726.  
  727.  
  728.  
  729. char *GetHomeDir(char *home)
  730. {
  731. #ifdef HOME_DIR
  732.     return (strcpy(home, HOME_DIR));
  733. #else
  734.     struct passwd *pw;
  735.     pw = getpwuid(getuid());
  736.     return (strcpy(home, pw->pw_dir));
  737. #endif
  738. }    /* GetHomeDir */
  739.  
  740.  
  741.  
  742.  
  743. /*
  744.  * A simple function that translates most pathnames with ~, ~user, or
  745.  * environment variables as the first item.  It won't do paths with env vars
  746.  * or ~s in the middle of the path, but those are extremely rare.
  747.  */
  748. char *LocalPath(char *path)
  749. {
  750.     longstring orig;
  751. #ifndef NO_PWSTUFF
  752.     struct passwd *pw;
  753. #endif
  754.     char *firstent = NULL;
  755.     char *cp, *dp, *rest;
  756.  
  757.     (void) Strncpy(orig, path);
  758.     if (((cp = index(orig, '/')) != NULL) && (cp != orig)) {
  759.         *cp = 0;
  760.         rest = cp + 1;
  761.         if (orig[0] == '~') {
  762.             if (orig[1] == 0) {
  763.                 firstent = uinfo.homedir;
  764.             } else {
  765. #ifndef NO_PWSTUFF
  766.                 pw = getpwnam(orig + 1);
  767.                 if (pw != NULL)
  768.                     firstent = pw->pw_dir;
  769. #endif
  770.             }
  771.         } else if (orig[0] == '$') {
  772.             cp = orig + 1;
  773.             dp = orig + strlen(orig) - 1;
  774.             if ((*cp == '(' && *dp == ')') || (*cp == '{' && *dp == '}')) {
  775.                 cp++;
  776.                 *dp = 0;
  777.             }
  778.             firstent = getenv(cp);
  779.         }
  780.         if (firstent != NULL)
  781.             (void) sprintf(path, "%s/%s", firstent, rest);
  782.     }
  783.     return (path);
  784. }    /* LocalPath */
  785.  
  786.  
  787.  
  788. /*
  789.  * A special case, where invisible dot-files that would normally appear in
  790.  * your home directory will appear instead as visible files in your $DOTDIR
  791.  * directory if you have one.
  792.  */
  793.  
  794. #define LCMP(b) (strncmp(path, (b), (o = sizeof(b) - 1)) == 0)
  795.  
  796. char *LocalDotPath(char *path)
  797. {
  798.     size_t o;
  799.     longstring s, s2, h;
  800.     char *cp = getenv("DOTDIR");
  801.  
  802.     if (cp == NULL) {
  803.         goto aa;
  804.     } else {
  805.         if (*cp != '/' && *cp != '~') {
  806.             /* then maybe they mean relative to $HOME. */
  807.             (void) sprintf(s2, "%s/%s", GetHomeDir(h), cp);
  808.             cp = s2;
  809.         }
  810.         if (LCMP("~/.") ||
  811.             LCMP("$HOME/.") ||
  812.             LCMP("$home/.") ||
  813.             LCMP("$(HOME)/.") ||
  814.             LCMP("${HOME}/.")
  815.         ) {
  816.             (void) Strncpy(s, path);
  817.             (void) sprintf(path, "%s/%s", cp, s + o);
  818.             cp = path;
  819.         } else {
  820. aa:            cp = LocalPath(path);
  821.         }
  822.     }
  823.     return cp;
  824. }    /* LocalDotPath */
  825.  
  826. #ifdef NO_STRSTR
  827.  
  828. /*
  829.  *  The Elm Mail System  -  $Revision: 1.1 $   $State: Exp $
  830.  *
  831.  *            Copyright (c) 1988-1992 USENET Community Trust
  832.  *            Copyright (c) 1986,1987 Dave Taylor
  833.  */
  834.  
  835. char *strstr(s1, s2)
  836. char *s1, *s2;
  837. {
  838.     int len;
  839.     char *ptr;
  840.     char *tmpptr;
  841.  
  842.     ptr = NULL;
  843.     len = strlen(s2);
  844.  
  845.     if ( len <= strlen(s1)) {
  846.         tmpptr = s1;
  847.         while ((ptr = index(tmpptr, (int)*s2)) != NULL) {
  848.             if (strncmp(ptr, s2, len) == 0) {
  849.                 break;
  850.             }
  851.             tmpptr = ptr+1;
  852.         }
  853.     }
  854.     return (ptr);
  855. }
  856.  
  857. #endif
  858.  
  859.  
  860. #ifdef NO_RENAME
  861. int rename(oldname, newname)
  862. const char *oldname, *newname;
  863. {
  864.     return (link(oldname, newname) == 0 ? unlink(oldname) : -1);
  865. }
  866. #endif /*NO_RENAME*/
  867.  
  868.  
  869. /* eof Util.c */
  870. @
  871.  
  872.  
  873. 5.1
  874. log
  875. @checked in with -k by alph at 1993/10/10 19:59:56
  876. @
  877. text
  878. @d4 2
  879. a5 2
  880.  *  $Revision: 14020.13 $
  881.  *  $Date: 93/05/23 09:38:13 $
  882. d524 2
  883. a525 2
  884. #ifdef SYSV
  885. #    ifdef NO_UNISTDH
  886. d543 1
  887. d545 6
  888. d552 1
  889. d621 1
  890. d633 3
  891. d702 3
  892. d708 1
  893. d722 1
  894. d724 1
  895. d736 1
  896. d740 1
  897. d800 1
  898. a800 1
  899.  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
  900. @
  901.