home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / tcp / ftp / archie132.lha / archie-1.3.2 / src / support.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-10  |  20.9 KB  |  809 lines

  1. /*
  2.  * Copyright (c) 1989, 1990, 1991 by the University of Washington
  3.  *
  4.  * For copying and distribution information, please see the file
  5.  * <copyright.h>.
  6.  */
  7.  
  8. /*
  9.  * Miscellaneous routines pulled from ~beta/lib/pfs and ~beta/lib/filters
  10.  */
  11.  
  12. #include <copyright.h>
  13. #include <stdio.h>
  14.  
  15. #include <errno.h>
  16.  
  17. #ifdef VMS
  18. # ifdef WOLLONGONG
  19. #  include "twg$tcp:[netdist.include]netdb.h"
  20. # else /* not Wollongong */
  21. #  ifdef UCX
  22. #   include netdb
  23. #  else /* Multinet */
  24. #   include "multinet_root:[multinet.include]netdb.h"
  25. #  endif
  26. # endif
  27. # include <vms.h>
  28. #else /* not VMS */
  29. # include <sys/types.h>
  30. # include <pmachine.h>
  31. # ifdef NEED_STRING_H
  32. #  include <string.h>
  33. # else
  34. #  include <strings.h>
  35. # endif
  36. # ifndef CUTCP
  37. #  include <netdb.h>
  38. # endif
  39. /*# if !defined(MSDOS) || defined(OS2)
  40. #  include <sys/file.h>
  41. #  include <sys/param.h>
  42. # endif*/
  43. #endif /* VMS */
  44.  
  45. #include <pfs.h>
  46. #include <pprot.h>
  47. #include <perrno.h>
  48. #include <pcompat.h>
  49. #include <pauthent.h>
  50.  
  51. #include "regex.h"
  52.  
  53. int    pfs_enable = PMAP_ATSIGN;
  54.  
  55. #ifndef FALSE
  56. # define TRUE     1
  57. # define FALSE   0
  58. #endif
  59.  
  60. #define MAXPATHLEN 1024
  61.  
  62. /* 
  63.  * wcmatch - Match string s against template containing widlcards
  64.  *
  65.  *         WCMATCH takes a string and a template, and returns
  66.  *         true if the string matches the template, and 
  67.  *         FALSE otherwise.
  68.  *
  69.  *    ARGS:  s        - string to be tested
  70.  *           template - Template containing optional wildcards
  71.  *
  72.  * RETURNS:  TRUE (non-zero) on match.  FALSE (0) otherwise.
  73.  *
  74.  *    NOTE:  If template is NULL, will return TRUE.
  75.  *
  76.  */
  77. int
  78. wcmatch(s,template)
  79.     char    *s;
  80.     char    *template;
  81.     {
  82.     char    temp[200];
  83.     char    *p = temp;
  84.  
  85.     if(!template) return(TRUE);
  86.     *p++ = '^';
  87.  
  88.     while(*template) {
  89.         if(*template == '*') {*(p++)='.'; *(p++) = *(template++);}
  90.         else if(*template == '?') {*(p++)='.';template++;}
  91.         else if(*template == '.') {*(p++)='\\';*(p++)='.';template++;}
  92.         else if(*template == '[') {*(p++)='\\';*(p++)='[';template++;}
  93.         else if(*template == '$') {*(p++)='\\';*(p++)='$';template++;}
  94.         else if(*template == '^') {*(p++)='\\';*(p++)='^';template++;}
  95.         else if(*template == '\\') {*(p++)='\\';*(p++)='\\';template++;}
  96.         else *(p++) = *(template++);
  97.     }
  98.         
  99.     *p++ = '$';
  100.     *p++ = '\0';
  101.  
  102.     if(re_comp(temp)) return(FALSE);
  103.  
  104. #ifdef AUX
  105.     if (re_exec(s) == (char *)NULL)
  106.       return 0;
  107.     return 1;
  108. #else
  109.     return(re_exec(s));
  110. #endif
  111.     }
  112.  
  113. /*
  114.  * ul_insert - Insert a union link at the right location
  115.  *
  116.  *             UL_INSERT takes a directory and a union link to be added
  117.  *             to a the list of union links in the directory.  It then
  118.  *             inserts the union link in the right spot in the linked
  119.  *             list of union links associated with that directory.
  120.  *
  121.  *           If an identical link already exists, then the link which
  122.  *             would be evaluated earlier (closer to the front of the list)
  123.  *             wins and the other one is freed.  If this happens, an error
  124.  *             will also be returned.
  125.  *        
  126.  *    ARGS:    ul    - link to be inserted
  127.  *           vd    - directory to get link
  128.  *             p     - vl that this link will apper after
  129.  *                     NULL - This vl will go at end of list
  130.  *                     vd   - This vl will go at head of list
  131.  *
  132.  * RETURNS:    Success, or UL_INSERT_ALREADY_THERE or UL_INSERT_SUPERSEDING
  133.  */
  134. int
  135. ul_insert(ul,vd,p)
  136.     VLINK    ul;        /* Link to be inserted                   */
  137.     PVDIR    vd;        /* Directory to receive link             */
  138.     VLINK    p;        /* Union link to appear prior to new one */
  139.     {
  140.     VLINK    current;
  141.  
  142.     /* This is the first ul in the directory */
  143.     if(vd->ulinks == NULL) {
  144.         vd->ulinks = ul;
  145.         ul->previous = NULL;
  146.         ul->next = NULL;
  147.         return(PSUCCESS);
  148.     }
  149.  
  150.     /* This ul will go at the head of the list */
  151.     if(p == (VLINK) vd) {
  152.         ul->next = vd->ulinks;
  153.         ul->next->previous = ul;
  154.         vd->ulinks = ul;
  155.         ul->previous = NULL;
  156.     }
  157.     /* Otherwise, decide if it must be inserted at all  */
  158.     /* If an identical link appears before the position */
  159.     /* at which the new one is to be inserted, we can   */
  160.     /* return without inserting it                 */
  161.     else {
  162.         current = vd->ulinks;
  163.  
  164.         while(current) {
  165.         /* p == NULL means we insert after last link */
  166.         if(!p && (current->next == NULL))
  167.             p = current;
  168.  
  169.         if(vl_comp(current,ul) == 0) {
  170.             vlfree(ul);
  171.             return(UL_INSERT_ALREADY_THERE);
  172.         }
  173.  
  174.         if(current == p) break;
  175.         current = current->next;
  176.         }
  177.  
  178.         /* If current is null, p was not found */
  179.         if(current == NULL)
  180.         return(UL_INSERT_POS_NOTFOUND);
  181.  
  182.         /* Insert ul */
  183.         ul->next = p->next;
  184.         p->next = ul;
  185.         ul->previous = p;
  186.         if(ul->next) ul->next->previous = ul;
  187.     }
  188.  
  189.     /* Check for identical links after ul */
  190.     current = ul->next;
  191.  
  192.     while(current) {
  193.         if(vl_comp(current,ul) == 0) {
  194.         current->previous->next = current->next;
  195.         if(current->next)
  196.             current->next->previous = current->previous;
  197.         vlfree(current);
  198.         return(UL_INSERT_SUPERSEDING);
  199.         }
  200.         current = current->next;
  201.     }
  202.     
  203.     return(PSUCCESS);
  204.     }
  205.  
  206. /*
  207.  * vl_insert - Insert a directory link at the right location
  208.  *
  209.  *             VL_INSERT takes a directory and a link to be added to a 
  210.  *             directory and inserts it in the linked list of links for
  211.  *             that directory.  
  212.  *
  213.  *             If a link already exists with the same name, and if the
  214.  *             information associated with the new link matches that in
  215.  *             the existing link, an error is returned.  If the information
  216.  *             associated with the new link is different, but the magic numbers
  217.  *             match, then the new link will be added as a replica of the
  218.  *             existing link.  If the magic numbers do not match, the new
  219.  *             link will only be added to the list of "replicas" if the
  220.  *             allow_conflict flag has been set.
  221.  * 
  222.  *             If the link is not added, an error is returned and the link
  223.  *             is freed.  Ordering for the list of links is by the link name.  
  224.  *        
  225.  *             If vl is a union link, then VL_INSERT calls ul_insert with an
  226.  *           added argument indicating the link is to be included at the
  227.  *             end of the union link list.
  228.  * 
  229.  *    ARGS:    vl - Link to be inserted, vd - directory to get link
  230.  *             allow_conflict - insert links with conflicting names
  231.  *
  232.  * RETURNS:    Success, or VL_INSERT_ALREADY_THERE
  233.  */
  234. int
  235. vl_insert(vl,vd,allow_conflict)
  236.     VLINK    vl;        /* Link to be inserted               */
  237.     PVDIR    vd;        /* Directory to receive link         */
  238.     int        allow_conflict;    /* Allow duplicate names             */
  239.     {
  240.     VLINK    current;    /* To step through list             */
  241.     VLINK    crep;        /* To step through list of replicas  */
  242.     int    retval;        /* Temp for checking returned values */
  243.  
  244.     /* This can also be used to insert union links at end of list */
  245.     if(vl->linktype == 'U') return(ul_insert(vl,vd,NULL));
  246.  
  247.     /* If this is the first link in the directory */
  248.     if(vd->links == NULL) {
  249.         vd->links = vl;
  250.         vl->previous = NULL;
  251.         vl->next = NULL;
  252.         vd->lastlink = vl;
  253.         return(PSUCCESS);
  254.     }
  255.  
  256.     /* If no sorting is to be done, just insert at end of list */
  257.     if(allow_conflict == VLI_NOSORT) {
  258.         vd->lastlink->next = vl;
  259.         vl->previous = vd->lastlink;
  260.         vl->next = NULL;
  261.         vd->lastlink = vl;
  262.         return(PSUCCESS);
  263.     }
  264.  
  265.     /* If it is to be inserted at start of list */
  266.     if(vl_comp(vl,vd->links) < 0) {
  267.         vl->next = vd->links;
  268.         vl->previous = NULL;
  269.         vl->next->previous = vl;
  270.         vd->links = vl;
  271.         return(PSUCCESS);
  272.     }
  273.  
  274.     current = vd->links;
  275.  
  276.     /* Otherwise, we must find the right spot to insert it */
  277.     while((retval = vl_comp(vl,current)) > 0) {
  278.         if(!current->next) {
  279.         /* insert at end */
  280.         vl->previous = current;
  281.         vl->next = NULL;
  282.         current->next = vl;
  283.         vd->lastlink = vl;
  284.         return(PSUCCESS);
  285.         }
  286.         current = current->next;
  287.     }
  288.  
  289.     /* If we found an equivilant entry already in list */
  290.     if(!retval) {
  291.         if(vl_equal(vl,current)) {
  292.         vlfree(vl);
  293.         return(VL_INSERT_ALREADY_THERE);
  294.         }
  295.         if((allow_conflict == VLI_NOCONFLICT) &&
  296.            ((vl->f_magic_no != current->f_magic_no) ||
  297.         (vl->f_magic_no==0)))
  298.         return(VL_INSERT_CONFLICT);
  299.         /* Insert the link into the list of "replicas" */
  300.         /* If magic is 0, then create a pseudo magic number */
  301.         if(vl->f_magic_no == 0) vl->f_magic_no = -1;
  302.         crep = current->replicas;
  303.         if(!crep) {
  304.         current->replicas = vl;
  305.         vl->next = NULL;
  306.         vl->previous = NULL;
  307.         }
  308.         else {
  309.         while(crep->next) {
  310.             /* If magic was 0, then we need a unique magic number */
  311.             if((crep->f_magic_no < 0) && (vl->f_magic_no < 1))
  312.             (vl->f_magic_no)--;
  313.             crep = crep->next;
  314.         }
  315.         /* If magic was 0, then we need a unique magic number */
  316.         if((crep->f_magic_no < 0) && (vl->f_magic_no < 1))
  317.             (vl->f_magic_no)--;
  318.         crep->next = vl;
  319.         vl->previous = crep;
  320.         vl->next = NULL;
  321.         }
  322.         return(PSUCCESS);
  323.     }
  324.  
  325.     /* We found the spot where vl is to be inserted */
  326.     vl->next = current;
  327.     vl->previous = current->previous;
  328.     current->previous = vl;
  329.     vl->previous->next = vl;
  330.     return(PSUCCESS);
  331.     }
  332.  
  333. /*
  334.  * nlsindex - Find first instance of string 2 in string 1 following newline
  335.  *
  336.  *          NLSINDEX scans string 1 for the first instance of string
  337.  *          2 that immediately follows a newline.  If found, NLSINDEX
  338.  *          returns a pointer to the first character of that instance.
  339.  *          If no instance is found, NLSINDEX returns NULL (0).
  340.  *
  341.  *    NOTE:   This function is only useful for searching strings that
  342.  *            consist of multiple lines.  s1 is assumed to be preceeded
  343.  *           by a newline.  Thus, if s2 is at the start of s1, it will
  344.  *          be found.
  345.  *    ARGS:   s1 - string to be searched
  346.  *            s2 - string to be found
  347.  * RETURNS:   First instance of s2 in s1, or NULL (0) if not found
  348.  */
  349. char *
  350. nlsindex(s1,s2)
  351.     char    *s1;        /* String to be searched */
  352.     char    *s2;        /* String to be found    */
  353.     {
  354.     register int s2len = strlen(s2);
  355.     char    *curline = s1;    /* Pointer to start of current line */
  356.  
  357.     /* In case s2 appears at start of s1 */
  358.     if(strncmp(curline,s2,s2len) == 0)
  359.         return(curline);
  360.  
  361.     /* Check remaining lines of s1 */
  362.     while((curline = (char *) index(curline,'\n')) != NULL) {
  363.         curline++;
  364.         if(strncmp(curline,s2,s2len) == 0)
  365.         return(curline);
  366.     }
  367.  
  368.     /* We didn't find it */
  369.     return(NULL);
  370.     }
  371.  
  372. /*
  373.  * month_sname - Return a month name from it's number
  374.  *
  375.  *               MONTH_SNAME takes a number in the range 0
  376.  *               to 12 and returns a pointer to a string
  377.  *               representing the three letter abbreviation
  378.  *             for that month.  If the argument is out of 
  379.  *         range, MONTH_SNAME returns a pointer to "Unk".
  380.  *
  381.  *       ARGS:   n - Number of the month
  382.  *    RETURNS:   Abbreviation for selected month
  383.  */
  384. char *month_sname(n)
  385.     int n;        /* Month number */
  386. {
  387.     static char *name[] = { "Unk",
  388.         "Jan","Feb","Mar","Apr","May","Jun",
  389.         "Jul","Aug","Sep","Oct","Nov","Dec"
  390.     };
  391.     return((n < 1 || n > 12) ? name[0] : name[n]);
  392. }
  393.  
  394. /*
  395.  * sindex - Find first instance of string 2 in string 1 
  396.  *
  397.  *          SINDEX scans string 1 for the first instance of string
  398.  *          2.  If found, SINDEX returns a pointer to the first
  399.  *          character of that instance.  If no instance is found, 
  400.  *          SINDEX returns NULL (0).
  401.  *
  402.  *    ARGS:   s1 - string to be searched
  403.  *            s2 - string to be found
  404.  * RETURNS:   First instance of s2 in s1, or NULL (0) if not found
  405.  */
  406. char *
  407. sindex(s1,s2)
  408.     char    *s1;        /* String to be searched   */
  409.     char    *s2;        /* String to be found      */
  410.     {
  411.     register int s2len = strlen(s2);
  412.     char    *s = s1;    /* Temp pointer to string  */
  413.  
  414.     /* Check for first character of s2 */
  415.     while((s = (char *) index(s,*s2)) != NULL) {
  416.         if(strncmp(s,s2,s2len) == 0)
  417.         return(s);
  418.         s++;
  419.     }
  420.  
  421.     /* We didn't find it */
  422.     return(NULL);
  423.     }
  424.  
  425. int
  426. scan_error(erst)
  427.     char    *erst;
  428.     {
  429.     *p_err_string = '\0';
  430.  
  431.     if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0) 
  432.         return(DIRSRV_NOT_DIRECTORY);
  433.  
  434.     if(strncmp(erst,"UNIMPLEMENTED",13) == 0) {
  435.         perrno = DIRSRV_UNIMPLEMENTED;
  436.         sscanf(erst+13,"%*[^\n \t\r]%*[ \t]%[^\n]",p_err_string);
  437.         return(perrno);
  438.     }
  439.  
  440.     if(strncmp(erst,"WARNING ",8) == 0) {
  441.         erst += 8;
  442.         *p_warn_string = '\0';
  443.         sscanf(erst,"%*[^\n \t\r]%*[ \t]%[^\n]",p_warn_string);
  444.         /* Return values for warnings are negative */
  445.         if(strncmp(erst,"OUT-OF-DATE",11) == 0) {
  446.         pwarn = PWARN_OUT_OF_DATE;
  447.         return(PSUCCESS);
  448.         }
  449.         if(strncmp(erst,"MESSAGE",7) == 0) {
  450.         pwarn = PWARN_MSG_FROM_SERVER;
  451.         return(PSUCCESS);
  452.         }
  453.         pwarn = PWARNING;
  454.         sscanf(erst,"%[^\n]",p_warn_string);
  455.         return(PSUCCESS);
  456.     }
  457.     else if(strncmp(erst,"ERROR",5) == 0) {
  458.         if(*(erst+5)) sscanf(erst+6,"%[^\n]",p_err_string);
  459.         perrno = DIRSRV_ERROR;
  460.         return(perrno);
  461.     }
  462.     /* The rest start with "FAILURE" */
  463.     else if(strncmp(erst,"FAILURE",7) != 0) {
  464.         /* Unrecognized - Give warning, but return PSUCCESS */
  465.         if(pwarn == 0) {
  466.         *p_warn_string = '\0';
  467.         pwarn = PWARN_UNRECOGNIZED_RESP;
  468.         sscanf(erst,"%[^\n]",p_warn_string);
  469.         }
  470.         return(PSUCCESS);
  471.     }
  472.  
  473.     if(strncmp(erst,"FAILURE ",8) != 0) {
  474.         perrno = PFAILURE;
  475.         return(perrno);
  476.     }    
  477.     erst += 8;
  478.     
  479.     sscanf(erst,"%*[^\n \t\r]%*[ \t]%[^\n]",p_err_string);
  480.  
  481.     /* Still to add               */
  482.     /* DIRSRV_AUTHENT_REQ     242 */
  483.     /* DIRSRV_BAD_VERS        245 */
  484.  
  485.     if(strncmp(erst,"NOT-FOUND",9) == 0) 
  486.         perrno = DIRSRV_NOT_FOUND;
  487.     else if(strncmp(erst,"NOT-AUTHORIZED",13) == 0) 
  488.         perrno = DIRSRV_NOT_AUTHORIZED;
  489.     else if(strncmp(erst,"ALREADY-EXISTS",14) == 0) 
  490.         perrno = DIRSRV_ALREADY_EXISTS;
  491.     else if(strncmp(erst,"NAME-CONFLICT",13) == 0) 
  492.         perrno = DIRSRV_NAME_CONFLICT;
  493.     else if(strncmp(erst,"SERVER-FAILED",13) == 0) 
  494.         perrno = DIRSRV_SERVER_FAILED;
  495.      /* Use it whether it starts with FAILURE or not */
  496.     else if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0) 
  497.         perrno = DIRSRV_NOT_DIRECTORY;
  498.     else perrno = PFAILURE;
  499.  
  500.     return(perrno);
  501.     }
  502.  
  503. PATTRIB 
  504. parse_attribute(line)
  505.     char    *line;
  506.     {
  507.     char    l_precedence[MAX_DIR_LINESIZE];
  508.     char    l_name[MAX_DIR_LINESIZE];
  509.     char    l_type[MAX_DIR_LINESIZE];
  510.     char    l_value[MAX_DIR_LINESIZE];
  511.     PATTRIB    at;
  512.     int    tmp;
  513.  
  514.     tmp = sscanf(line,"OBJECT-INFO %s %s %[^\n]", l_name, l_type, l_value);
  515.     
  516.     if(tmp < 3) {
  517.         tmp = sscanf(line,"LINK-INFO %s %s %s %[^\n]", l_precedence,
  518.              l_name, l_type, l_value);
  519.         if(tmp < 4) {
  520.         perrno = DIRSRV_BAD_FORMAT;
  521.         return(NULL);
  522.         }
  523.     }
  524.  
  525.     at = atalloc();
  526.  
  527.     if(tmp == 4) {
  528.         if(strcmp(l_precedence,"CACHED") == 0) 
  529.         at->precedence = ATR_PREC_CACHED;
  530.         else if(strcmp(l_precedence,"LINK") == 0) 
  531.         at->precedence = ATR_PREC_LINK;
  532.         else if(strcmp(l_precedence,"REPLACEMENT") == 0) 
  533.         at->precedence = ATR_PREC_REPLACE;
  534.         else if(strcmp(l_precedence,"ADDITIONAL") == 0) 
  535.         at->precedence = ATR_PREC_ADD;
  536.     }
  537.  
  538.     at->aname = stcopy(l_name);
  539.     at->avtype = stcopy(l_type);
  540.     if(strcmp(l_type,"ASCII") == 0) 
  541.         at->value.ascii = stcopy(l_value);
  542.     else if(strcmp(l_type,"LINK") == 0) {
  543.         char        ftype[MAX_DIR_LINESIZE];
  544.         char        lname[MAX_DIR_LINESIZE];
  545.         char        htype[MAX_DIR_LINESIZE];
  546.         char        host[MAX_DIR_LINESIZE];
  547.         char        ntype[MAX_DIR_LINESIZE];
  548.         char        fname[MAX_DIR_LINESIZE];
  549.         VLINK        al;
  550.  
  551.         al = vlalloc();
  552.         at->value.link = al;
  553.  
  554.         tmp = sscanf(l_value,"%c %s %s %s %s %s %s %d %d",
  555.              &(al->linktype),
  556.              ftype,lname,htype,host,ntype,fname,
  557.              &(al->version),
  558.              &(al->f_magic_no));
  559.         if(tmp == 9) {
  560.         al->type = stcopyr(ftype,al->type);
  561.         al->name = stcopyr(unquote(lname),al->name);
  562.         al->hosttype = stcopyr(htype,al->hosttype);
  563.         al->host = stcopyr(host,al->host);
  564.         al->nametype = stcopyr(ntype,al->nametype);
  565.         al->filename = stcopyr(fname,al->filename);
  566.         }
  567.         else {
  568.         perrno = DIRSRV_BAD_FORMAT;
  569.         return(NULL);
  570.         }
  571.         
  572.     }
  573.  
  574.     return(at);
  575.     }
  576.  
  577. /*
  578.  * nxtline - Find the next line in the string
  579.  *
  580.  *          NXTLINE takes a string and returns a pointer to
  581.  *          the character immediately following the next newline.
  582.  *
  583.  *    ARGS:   s - string to be searched
  584.  *
  585.  * RETURNS:   Next line or NULL (0) on failure
  586.  */
  587. char *
  588. nxtline(s)
  589.     char    *s;        /* String to be searched */
  590.  {
  591.     s = (char *) index(s,'\n');
  592.     if(s) return(++s);
  593.     else return(NULL);
  594.     }
  595.  
  596.  
  597. /*
  598.  * unquote - unquote string if necessary
  599.  *
  600.  *          UNQUOTE takes a string and unquotes it if it has been quoted.
  601.  *
  602.  *    ARGS:   s - string to be unquoted
  603.  *            
  604.  * RETURNS:   The original string.  If the string has been quoted, then the
  605.  *            result appears in static storage, and must be copied if 
  606.  *            it is to last beyond the next call to quote.
  607.  *
  608.  */
  609. char *
  610. unquote(s)
  611.     char    *s;        /* String to be quoted */
  612.     {
  613.     static char    unquoted[200];
  614.     char        *c = unquoted;
  615.  
  616.     if(*s != '\'') return(s);
  617.  
  618.     s++;
  619.  
  620.     /* This should really treat a quote followed by other */
  621.     /* than a quote or a null as an error                 */
  622.     while(*s) {
  623.         if(*s == '\'') s++;
  624.         if(*s) *c++ = *s++;
  625.     }
  626.  
  627.     *c++ = '\0';
  628.  
  629.     return(unquoted);
  630.     }
  631.  
  632. #if defined(DEBUG) && defined(STRSPN)
  633. /* needed for -D option parsing */
  634. /*
  635.  * strspn - Count initial characters from chrs in s
  636.  *
  637.  *          STRSPN counts the occurances of chacters from chrs
  638.  *            in the string s preceeding the first occurance of
  639.  *            a character not in s.
  640.  *
  641.  *    ARGS:   s    - string to be checked
  642.  *            chrs - string of characters we are looking for
  643.  *
  644.  * RETURNS:   Count of initial characters from chrs in s
  645.  */
  646. strspn(s,chrs)
  647.     char    *s;    /* String to search                         */
  648.     char    *chrs; /* String of characters we are looking for  */
  649.     {
  650.     char    *cp;   /* Pointer to the current character in chrs */
  651.     int    count; /* Count of characters seen so far          */
  652.     
  653.     count = 0;
  654.  
  655.     while(*s) {
  656.         for(cp = chrs;*cp;cp++)
  657.         if(*cp == *s) {
  658.             s++;
  659.             count++;
  660.             goto done;
  661.         }
  662.         return(count);
  663.     done:
  664.         ;
  665.     }
  666.     return(count);
  667.     }
  668. #endif
  669.  
  670. #ifdef CUTCP
  671. char
  672. *inet_ntoa(struct in_addr in)
  673. {
  674.     static    char    buff[36];
  675.  
  676.     unsigned char    *c = (char *) &in.address;
  677.     sprintf(buff,"%d.%d.%d.%d",*c,*(c+1),*(c+2),*(c+3));
  678.     return(buff);
  679. }
  680.  
  681. long
  682. inet_addr(char *cp)
  683. {
  684.     long    value = 0;
  685.     unsigned    v1,v2,v3,v4;
  686.  
  687.     v1 = v2 = v3 = v4 = 0xff;
  688.     sscanf(cp,"%d.%d.%d.%d",&v1,&v2,&v3,&v4);
  689.     value = (v1 << 24) | (v2 << 16) | (v3 << 8) | v4;
  690.     return(value);
  691. }
  692.  
  693. struct    hostent
  694. *gethostbyname(char *name)
  695. {
  696.     struct machinfo    *mp;
  697.     int    mnum;
  698.     unsigned long    now;
  699.     static    struct hostent    ht;
  700.     extern int pfs_debug;
  701.  
  702.     mp = Shostlook(name);
  703.     if(!mp || (!mp->hostip[0])) {    /* DNS lookup */
  704. #ifdef DEBUG
  705.         if (pfs_debug)
  706.         fprintf(stderr, "Domain name lookup of %s\n", name);
  707. #endif
  708.         mnum = Sdomain(name);        /* start a DNS lookup */
  709.         now = time(NULL) + NS_TIMEOUT;
  710.         while(now > time(NULL)) {
  711.             int    i, class, dat;
  712.  
  713.             Stask();
  714.             i = Sgetevent(USERCLASS, &class, &dat);
  715.             if(i == DOMOK) {    /* domain lookup ok */
  716.                 mp = Slooknum(mnum);
  717. #ifdef DEBUG
  718.         if (pfs_debug)
  719.         fprintf(stderr, "Domain name lookup of %s Completed OK\n", name);
  720. #endif
  721.                 break;
  722.             }
  723.         }
  724.         if(!mp)    {    /* get here if timeout */
  725. #ifdef DEBUG
  726.         if (pfs_debug)
  727.         fprintf(stderr, "Domain name lookup of %s Failed\n", name);
  728. #endif
  729.             return(NULL);
  730.         }
  731.     }
  732.     ht.h_addr = *((unsigned long *) mp->hostip);
  733.     ht.h_length = 4;
  734.     ht.h_addrtype = AF_INET;
  735.     return(&ht);
  736.  
  737. }
  738. #endif /* CUTCP */
  739.  
  740. #ifdef GETENV
  741. /*
  742.  * Copyright (c) 1987 Regents of the University of California.
  743.  * All rights reserved.
  744.  *
  745.  * Redistribution and use in source and binary forms are permitted
  746.  * provided that: (1) source distributions retain this entire copyright
  747.  * notice and comment, and (2) distributions including binaries display
  748.  * the following acknowledgement:  ``This product includes software
  749.  * developed by the University of California, Berkeley and its contributors''
  750.  * in the documentation or other materials provided with the distribution
  751.  * and in all advertising materials mentioning features or use of this
  752.  * software. Neither the name of the University nor the names of its
  753.  * contributors may be used to endorse or promote products derived
  754.  * from this software without specific prior written permission.
  755.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  756.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  757.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  758.  */
  759.  
  760. #if defined(LIBC_SCCS) && !defined(lint)
  761. static char sccsid[] = "@(#)getenv.c    5.7 (Berkeley) 6/1/90";
  762. #endif /* LIBC_SCCS and not lint */
  763.  
  764. #include <stdlib.h>
  765. #include <stddef.h>
  766.  
  767. /*
  768.  * getenv --
  769.  *    Returns ptr to value associated with name, if any, else NULL.
  770.  */
  771. char *
  772. getenv(name)
  773.     char *name;
  774. {
  775.     int offset;
  776.     char *_findenv();
  777.  
  778.     return(_findenv(name, &offset));
  779. }
  780.  
  781. /*
  782.  * _findenv --
  783.  *    Returns pointer to value associated with name, if any, else NULL.
  784.  *    Sets offset to be the offset of the name/value combination in the
  785.  *    environmental array, for use by setenv(3) and unsetenv(3).
  786.  *    Explicitly removes '=' in argument name.
  787.  *
  788.  *    This routine *should* be a static; don't use it.
  789.  */
  790. char *
  791. _findenv(name, offset)
  792.     register char *name;
  793.     int *offset;
  794. {
  795.     extern char **environ;
  796.     register int len;
  797.     register char **P, *C;
  798.  
  799.     for (C = name, len = 0; *C && *C != '='; ++C, ++len);
  800.     for (P = environ; *P; ++P)
  801.         if (!strncmp(*P, name, len))
  802.             if (*(C = *P + len) == '=') {
  803.                 *offset = P - environ;
  804.                 return(++C);
  805.             }
  806.     return(NULL);
  807. }
  808. #endif
  809.