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