home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE0.TAR / support.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-27  |  15.9 KB  |  610 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. #include <strings.h>
  15. #include <errno.h>
  16. #include <netdb.h>
  17.  
  18. #ifdef AUX
  19. #include <sys/types.h>
  20. #endif
  21. #include <sys/file.h>
  22. #include <sys/param.h>
  23.  
  24. #include <pfs.h>
  25. #include <pprot.h>
  26. #include <perrno.h>
  27. #include <pcompat.h>
  28. #include <pauthent.h>
  29. #include <pmachine.h>
  30.  
  31. int    pfs_enable = PMAP_ATSIGN;
  32. char    p_err_string[P_ERR_STRING_SZ];
  33.  
  34. #ifndef FALSE
  35. #define TRUE     1
  36. #define FALSE   0
  37. #endif
  38.  
  39. #ifdef NOREGEX
  40. #include REGEX_FILE
  41. #endif
  42.  
  43. /* 
  44.  * wcmatch - Match string s against template containing widlcards
  45.  *
  46.  *         WCMATCH takes a string and a template, and returns
  47.  *         true if the string matches the template, and 
  48.  *         FALSE otherwise.
  49.  *
  50.  *    ARGS:  s        - string to be tested
  51.  *           template - Template containing optional wildcards
  52.  *
  53.  * RETURNS:  TRUE (non-zero) on match.  FALSE (0) otherwise.
  54.  *
  55.  *    NOTE:  If template is NULL, will return TRUE.
  56.  *
  57.  */
  58. wcmatch(s,template)
  59.     char    *s;
  60.     char    *template;
  61.     {
  62.     char    temp[200];
  63.     char    *p = temp;
  64.  
  65.     if(!template) return(TRUE);
  66.     *p++ = '^';
  67.  
  68.     while(*template) {
  69.         if(*template == '*') {*(p++)='.'; *(p++) = *(template++);}
  70.         else if(*template == '?') {*(p++)='.';template++;}
  71.         else if(*template == '.') {*(p++)='\\';*(p++)='.';template++;}
  72.         else if(*template == '[') {*(p++)='\\';*(p++)='[';template++;}
  73.         else if(*template == '$') {*(p++)='\\';*(p++)='$';template++;}
  74.         else if(*template == '^') {*(p++)='\\';*(p++)='^';template++;}
  75.         else if(*template == '\\') {*(p++)='\\';*(p++)='\\';template++;}
  76.         else *(p++) = *(template++);
  77.     }
  78.         
  79.     *p++ = '$';
  80.     *p++ = '\0';
  81.  
  82.     if(re_comp(temp)) return(FALSE);
  83.  
  84.     return(re_exec(s));
  85.     }
  86.  
  87. /*
  88.  * ul_insert - Insert a union link at the right location
  89.  *
  90.  *             UL_INSERT takes a directory and a union link to be added
  91.  *             to a the list of union links in the directory.  It then
  92.  *             inserts the union link in the right spot in the linked
  93.  *             list of union links associated with that directory.
  94.  *
  95.  *           If an identical link already exists, then the link which
  96.  *             would be evaluated earlier (closer to the front of the list)
  97.  *             wins and the other one is freed.  If this happens, an error
  98.  *             will also be returned.
  99.  *        
  100.  *    ARGS:    ul    - link to be inserted
  101.  *           vd    - directory to get link
  102.  *             p     - vl that this link will apper after
  103.  *                     NULL - This vl will go at end of list
  104.  *                     vd   - This vl will go at head of list
  105.  *
  106.  * RETURNS:    Success, or UL_INSERT_ALREADY_THERE or UL_INSERT_SUPERSEDING
  107.  */
  108. ul_insert(ul,vd,p)
  109.     VLINK    ul;        /* Link to be inserted                   */
  110.     VDIR    vd;        /* Directory to receive link             */
  111.     VLINK    p;        /* Union link to appear prior to new one */
  112.     {
  113.     VLINK    current;
  114.  
  115.     /* This is the first ul in the directory */
  116.     if(vd->ulinks == NULL) {
  117.         vd->ulinks = ul;
  118.         ul->previous = NULL;
  119.         ul->next = NULL;
  120.         return(PSUCCESS);
  121.     }
  122.  
  123.     /* This ul will go at the head of the list */
  124.     if(p == (VLINK) vd) {
  125.         ul->next = vd->ulinks;
  126.         ul->next->previous = ul;
  127.         vd->ulinks = ul;
  128.         ul->previous = NULL;
  129.     }
  130.     /* Otherwise, decide if it must be inserted at all  */
  131.     /* If an identical link appears before the position */
  132.     /* at which the new one is to be inserted, we can   */
  133.     /* return without inserting it                 */
  134.     else {
  135.         current = vd->ulinks;
  136.  
  137.         while(current) {
  138.         /* p == NULL means we insert after last link */
  139.         if(!p && (current->next == NULL))
  140.             p = current;
  141.  
  142.         if(vl_comp(current,ul) == 0) {
  143.             vlfree(ul);
  144.             return(UL_INSERT_ALREADY_THERE);
  145.         }
  146.  
  147.         if(current == p) break;
  148.         current = current->next;
  149.         }
  150.  
  151.         /* If current is null, p was not found */
  152.         if(current == NULL)
  153.         return(UL_INSERT_POS_NOTFOUND);
  154.  
  155.         /* Insert ul */
  156.         ul->next = p->next;
  157.         p->next = ul;
  158.         ul->previous = p;
  159.         if(ul->next) ul->next->previous = ul;
  160.     }
  161.  
  162.     /* Check for identical links after ul */
  163.     current = ul->next;
  164.  
  165.     while(current) {
  166.         if(vl_comp(current,ul) == 0) {
  167.         current->previous->next = current->next;
  168.         if(current->next)
  169.             current->next->previous = current->previous;
  170.         vlfree(current);
  171.         return(UL_INSERT_SUPERSEDING);
  172.         }
  173.         current = current->next;
  174.     }
  175.     
  176.     return(PSUCCESS);
  177.     }
  178.  
  179. /*
  180.  * vl_insert - Insert a directory link at the right location
  181.  *
  182.  *             VL_INSERT takes a directory and a link to be added to a 
  183.  *             directory and inserts it in the linked list of links for
  184.  *             that directory.  
  185.  *
  186.  *             If a link already exists with the same name, and if the
  187.  *             information associated with the new link matches that in
  188.  *             the existing link, an error is returned.  If the information
  189.  *             associated with the new link is different, but the magic numbers
  190.  *             match, then the new link will be added as a replica of the
  191.  *             existing link.  If the magic numbers do not match, the new
  192.  *             link will only be added to the list of "replicas" if the
  193.  *             allow_conflict flag has been set.
  194.  * 
  195.  *             If the link is not added, an error is returned and the link
  196.  *             is freed.  Ordering for the list of links is by the link name.  
  197.  *        
  198.  *             If vl is a union link, then VL_INSERT calls ul_insert with an
  199.  *           added argument indicating the link is to be included at the
  200.  *             end of the union link list.
  201.  * 
  202.  *    ARGS:    vl - Link to be inserted, vd - directory to get link
  203.  *             allow_conflict - insert links with conflicting names
  204.  *
  205.  * RETURNS:    Success, or VL_INSERT_ALREADY_THERE
  206.  */
  207. vl_insert(vl,vd,allow_conflict)
  208.     VLINK    vl;        /* Link to be inserted               */
  209.     VDIR    vd;        /* Directory to receive link         */
  210.     int        allow_conflict;    /* Allow duplicate names             */
  211.     {
  212.     VLINK    current;    /* To step through list             */
  213.     VLINK    crep;        /* To step through list of replicas  */
  214.     int    retval;        /* Temp for checking returned values */
  215.  
  216.     /* This can also be used to insert union links at end of list */
  217.     if(vl->linktype == 'U') return(ul_insert(vl,vd,NULL));
  218.  
  219.     /* If this is the first link in the directory */
  220.     if(vd->links == NULL) {
  221.         vd->links = vl;
  222.         vl->previous = NULL;
  223.         vl->next = NULL;
  224.         vd->lastlink = vl;
  225.         return(PSUCCESS);
  226.     }
  227.  
  228.     /* If no sorting is to be done, just insert at end of list */
  229.     if(allow_conflict == VLI_NOSORT) {
  230.         vd->lastlink->next = vl;
  231.         vl->previous = vd->lastlink;
  232.         vl->next = NULL;
  233.         vd->lastlink = vl;
  234.         return(PSUCCESS);
  235.     }
  236.  
  237.     /* If it is to be inserted at start of list */
  238.     if(vl_comp(vl,vd->links) < 0) {
  239.         vl->next = vd->links;
  240.         vl->previous = NULL;
  241.         vl->next->previous = vl;
  242.         vd->links = vl;
  243.         return(PSUCCESS);
  244.     }
  245.  
  246.     current = vd->links;
  247.  
  248.     /* Otherwise, we must find the right spot to insert it */
  249.     while((retval = vl_comp(vl,current)) > 0) {
  250.         if(!current->next) {
  251.         /* insert at end */
  252.         vl->previous = current;
  253.         vl->next = NULL;
  254.         current->next = vl;
  255.         vd->lastlink = vl;
  256.         return(PSUCCESS);
  257.         }
  258.         current = current->next;
  259.     }
  260.  
  261.     /* If we found an equivilant entry already in list */
  262.     if(!retval) {
  263.         if(vl_equal(vl,current)) {
  264.         vlfree(vl);
  265.         return(VL_INSERT_ALREADY_THERE);
  266.         }
  267.         if((allow_conflict == VLI_NOCONFLICT) &&
  268.            ((vl->f_magic_no != current->f_magic_no) ||
  269.         (vl->f_magic_no==0)))
  270.         return(VL_INSERT_CONFLICT);
  271.         /* Insert the link into the list of "replicas" */
  272.         /* If magic is 0, then create a pseudo magic number */
  273.         if(vl->f_magic_no == 0) vl->f_magic_no = -1;
  274.         crep = current->replicas;
  275.         if(!crep) {
  276.         current->replicas = vl;
  277.         vl->next = NULL;
  278.         vl->previous = NULL;
  279.         }
  280.         else {
  281.         while(crep->next) {
  282.             /* If magic was 0, then we need a unique magic number */
  283.             if((crep->f_magic_no < 0) && (vl->f_magic_no < 1))
  284.             (vl->f_magic_no)--;
  285.             crep = crep->next;
  286.         }
  287.         /* If magic was 0, then we need a unique magic number */
  288.         if((crep->f_magic_no < 0) && (vl->f_magic_no < 1))
  289.             (vl->f_magic_no)--;
  290.         crep->next = vl;
  291.         vl->previous = crep;
  292.         vl->next = NULL;
  293.         }
  294.         return(PSUCCESS);
  295.     }
  296.  
  297.     /* We found the spot where vl is to be inserted */
  298.     vl->next = current;
  299.     vl->previous = current->previous;
  300.     current->previous = vl;
  301.     vl->previous->next = vl;
  302.     return(PSUCCESS);
  303.     }
  304.  
  305. /*
  306.  * nlsindex - Find first instance of string 2 in string 1 following newline
  307.  *
  308.  *          NLSINDEX scans string 1 for the first instance of string
  309.  *          2 that immediately follows a newline.  If found, NLSINDEX
  310.  *          returns a pointer to the first character of that instance.
  311.  *          If no instance is found, NLSINDEX returns NULL (0).
  312.  *
  313.  *    NOTE:   This function is only useful for searching strings that
  314.  *            consist of multiple lines.  s1 is assumed to be preceeded
  315.  *           by a newline.  Thus, if s2 is at the start of s1, it will
  316.  *          be found.
  317.  *    ARGS:   s1 - string to be searched
  318.  *            s2 - string to be found
  319.  * RETURNS:   First instance of s2 in s1, or NULL (0) if not found
  320.  */
  321. char *
  322. nlsindex(s1,s2)
  323.     char    *s1;        /* String to be searched */
  324.     char    *s2;        /* String to be found    */
  325.     {
  326.     register int s2len = strlen(s2);
  327.     char    *curline = s1;    /* Pointer to start of current line */
  328.  
  329.     /* In case s2 appears at start of s1 */
  330.     if(strncmp(curline,s2,s2len) == 0)
  331.         return(curline);
  332.  
  333.     /* Check remaining lines of s1 */
  334.     while((curline = index(curline,'\n')) != NULL) {
  335.         curline++;
  336.         if(strncmp(curline,s2,s2len) == 0)
  337.         return(curline);
  338.     }
  339.  
  340.     /* We didn't find it */
  341.     return(NULL);
  342.     }
  343.  
  344. /*
  345.  * month_sname - Return a month name from it's number
  346.  *
  347.  *               MONTH_SNAME takes a number in the range 0
  348.  *               to 12 and returns a pointer to a string
  349.  *               representing the three letter abbreviation
  350.  *             for that month.  If the argument is out of 
  351.  *         range, MONTH_SNAME returns a pointer to "Unk".
  352.  *
  353.  *       ARGS:   n - Number of the month
  354.  *    RETURNS:   Abbreviation for selected month
  355.  */
  356. char *month_sname(n)
  357.     int n;        /* Month number */
  358. {
  359.     static char *name[] = { "Unk",
  360.         "Jan","Feb","Mar","Apr","May","Jun",
  361.         "Jul","Aug","Sep","Oct","Nov","Dec"
  362.     };
  363.     return((n < 1 || n > 12) ? name[0] : name[n]);
  364. }
  365.  
  366. /*
  367.  * sindex - Find first instance of string 2 in string 1 
  368.  *
  369.  *          SINDEX scans string 1 for the first instance of string
  370.  *          2.  If found, SINDEX returns a pointer to the first
  371.  *          character of that instance.  If no instance is found, 
  372.  *          SINDEX returns NULL (0).
  373.  *
  374.  *    ARGS:   s1 - string to be searched
  375.  *            s2 - string to be found
  376.  * RETURNS:   First instance of s2 in s1, or NULL (0) if not found
  377.  */
  378. char *
  379. sindex(s1,s2)
  380.     char    *s1;        /* String to be searched   */
  381.     char    *s2;        /* String to be found      */
  382.     {
  383.     register int s2len = strlen(s2);
  384.     char    *s = s1;    /* Temp pointer to string  */
  385.  
  386.     /* Check for first character of s2 */
  387.     while((s = index(s,*s2)) != NULL) {
  388.         if(strncmp(s,s2,s2len) == 0)
  389.         return(s);
  390.         s++;
  391.     }
  392.  
  393.     /* We didn't find it */
  394.     return(NULL);
  395.     }
  396.  
  397. scan_error(erst)
  398.     char    *erst;
  399.     {
  400.     *p_err_string = '\0';
  401.  
  402.     if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0) 
  403.         return(DIRSRV_NOT_DIRECTORY);
  404.  
  405.     /* The rest start with "FAILURE" */
  406.  
  407.     if(strncmp(erst,"FAILURE",7) != 0) 
  408.         return(DIRSRV_BAD_FORMAT);
  409.  
  410.     if(strncmp(erst,"FAILURE ",8) != 0) 
  411.         return(PFAILURE);
  412.  
  413.     erst += 8;
  414.  
  415.     sscanf(erst, "%*s %[^\n]", p_err_string);
  416.     
  417.     /* Still to add               */
  418.     /* DIRSRV_AUTHENT_REQ     242 */
  419.     /* DIRSRV_BAD_VERS        245 */
  420.  
  421.     if(strncmp(erst,"NOT-FOUND",9) == 0) 
  422.         return(DIRSRV_NOT_FOUND);
  423.  
  424.     if(strncmp(erst,"NOT-AUTHORIZED",13) == 0) 
  425.         return(DIRSRV_NOT_AUTHORIZED);
  426.  
  427.     if(strncmp(erst,"ALREADY-EXISTS",14) == 0) 
  428.         return(DIRSRV_ALREADY_EXISTS);
  429.  
  430.     if(strncmp(erst,"NAME-CONFLICT",13) == 0) 
  431.         return(DIRSRV_NAME_CONFLICT);
  432.  
  433.     if(strncmp(erst,"SERVER-FAILED",13) == 0) 
  434.         return(DIRSRV_SERVER_FAILED);
  435.  
  436.  
  437.     /* Use it whether it starts with FAILURE or not */
  438.     if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0) 
  439.         return(DIRSRV_NOT_DIRECTORY);
  440.  
  441.     return(PFAILURE);
  442.     }
  443.  
  444. PATTRIB 
  445. parse_attribute(line)
  446.     char    *line;
  447.     {
  448.     char    l_precedence[MAX_DIR_LINESIZE];
  449.     char    l_name[MAX_DIR_LINESIZE];
  450.     char    l_type[MAX_DIR_LINESIZE];
  451.     char    l_value[MAX_DIR_LINESIZE];
  452.     PATTRIB    at;
  453.     int    tmp;
  454.  
  455.     tmp = sscanf(line,"OBJECT-INFO %s %s %[^\n]", l_name, l_type, l_value);
  456.     
  457.     if(tmp < 3) {
  458.         tmp = sscanf(line,"LINK-INFO %s %s %s %[^\n]", l_precedence,
  459.              l_name, l_type, l_value);
  460.         if(tmp < 4) {
  461.         perrno = DIRSRV_BAD_FORMAT;
  462.         return(NULL);
  463.         }
  464.     }
  465.  
  466.     at = atalloc();
  467.  
  468.     if(tmp == 4) {
  469.         if(strcmp(l_precedence,"CACHED") == 0) 
  470.         at->precedence = ATR_PREC_CACHED;
  471.         else if(strcmp(l_precedence,"LINK") == 0) 
  472.         at->precedence = ATR_PREC_LINK;
  473.         else if(strcmp(l_precedence,"REPLACEMENT") == 0) 
  474.         at->precedence = ATR_PREC_REPLACE;
  475.         else if(strcmp(l_precedence,"ADDITIONAL") == 0) 
  476.         at->precedence = ATR_PREC_ADD;
  477.     }
  478.  
  479.     at->aname = stcopy(l_name);
  480.     at->avtype = stcopy(l_type);
  481.     if(strcmp(l_type,"ASCII") == 0) 
  482.         at->value.ascii = stcopy(l_value);
  483.     else if(strcmp(l_type,"LINK") == 0) {
  484.         char        ftype[MAX_DIR_LINESIZE];
  485.         char        lname[MAX_DIR_LINESIZE];
  486.         char        htype[MAX_DIR_LINESIZE];
  487.         char        host[MAX_DIR_LINESIZE];
  488.         char        ntype[MAX_DIR_LINESIZE];
  489.         char        fname[MAX_DIR_LINESIZE];
  490.         VLINK        al;
  491.  
  492.         al = vlalloc();
  493.         at->value.link = al;
  494.  
  495.         tmp = sscanf(l_value,"%c %s %s %s %s %s %s %d %d",
  496.              &(al->linktype),
  497.              ftype,lname,htype,host,ntype,fname,
  498.              &(al->version),
  499.              &(al->f_magic_no));
  500.         if(tmp == 9) {
  501.         al->type = stcopyr(ftype,al->type);
  502.         al->name = stcopyr(unquote(lname),al->name);
  503.         al->hosttype = stcopyr(htype,al->hosttype);
  504.         al->host = stcopyr(host,al->host);
  505.         al->nametype = stcopyr(ntype,al->nametype);
  506.         al->filename = stcopyr(fname,al->filename);
  507.         }
  508.         else {
  509.         perrno = DIRSRV_BAD_FORMAT;
  510.         return(NULL);
  511.         }
  512.         
  513.     }
  514.  
  515.     return(at);
  516.     }
  517.  
  518. /*
  519.  * nxtline - Find the next line in the string
  520.  *
  521.  *          NXTLINE takes a string and returns a pointer to
  522.  *          the character immediately following the next newline.
  523.  *
  524.  *    ARGS:   s - string to be searched
  525.  *
  526.  * RETURNS:   Next line or NULL (0) on failure
  527.  */
  528. char *
  529. nxtline(s)
  530.     char    *s;        /* String to be searched */
  531.  {
  532.     s = index(s,'\n');
  533.     if(s) return(++s);
  534.     else return(NULL);
  535.     }
  536.  
  537.  
  538. /*
  539.  * unquote - unquote string if necessary
  540.  *
  541.  *          UNQUOTE takes a string and unquotes it if it has been quoted.
  542.  *
  543.  *    ARGS:   s - string to be unquoted
  544.  *            
  545.  * RETURNS:   The original string.  If the string has been quoted, then the
  546.  *            result appears in static storage, and must be copied if 
  547.  *            it is to last beyond the next call to quote.
  548.  *
  549.  */
  550. char *
  551. unquote(s)
  552.     char    *s;        /* String to be quoted */
  553.     {
  554.     static char    unquoted[200];
  555.     char        *c = unquoted;
  556.  
  557.     if(*s != '\'') return(s);
  558.  
  559.     s++;
  560.  
  561.     /* This should really treat a quote followed by other */
  562.     /* than a quote or a null as an error                 */
  563.     while(*s) {
  564.         if(*s == '\'') s++;
  565.         if(*s) *c++ = *s++;
  566.     }
  567.  
  568.     *c++ = '\0';
  569.  
  570.     return(unquoted);
  571.     }
  572.  
  573. #if defined(DEBUG) && defined(STRSPN)
  574. /* needed for -D option parsing */
  575. /*
  576.  * strspn - Count initial characters from chrs in s
  577.  *
  578.  *          STRSPN counts the occurances of chacters from chrs
  579.  *            in the string s preceeding the first occurance of
  580.  *            a character not in s.
  581.  *
  582.  *    ARGS:   s    - string to be checked
  583.  *            chrs - string of characters we are looking for
  584.  *
  585.  * RETURNS:   Count of initial characters from chrs in s
  586.  */
  587. strspn(s,chrs)
  588.     char    *s;    /* String to search                         */
  589.     char    *chrs; /* String of characters we are looking for  */
  590.     {
  591.     char    *cp;   /* Pointer to the current character in chrs */
  592.     int    count; /* Count of characters seen so far          */
  593.     
  594.     count = 0;
  595.  
  596.     while(*s) {
  597.         for(cp = chrs;*cp;cp++)
  598.         if(*cp == *s) {
  599.             s++;
  600.             count++;
  601.             goto done;
  602.         }
  603.         return(count);
  604.     done:
  605.         ;
  606.     }
  607.     return(count);
  608.     }
  609. #endif
  610.