This is support.c in view mode; [Download] [Up]
/* * Copyright (c) 1989, 1990, 1991 by the University of Washington * * For copying and distribution information, please see the file * <copyright.h>. * * gf xarchie v2.0 - Sync with archie v1.4.1. */ /* * Miscellaneous routines pulled from ~beta/lib/pfs and ~beta/lib/filters */ #include <copyright.h> #include <stdio.h> #include <errno.h> #ifdef VMS # ifdef WOLLONGONG # include "twg$tcp:[netdist.include]netdb.h" # else /* not Wollongong */ # ifdef UCX # include <netdb.h> # else /* Multinet */ # include "multinet_root:[multinet.include]netdb.h" # endif # endif # include <vms.h> #else /* not VMS */ # include <sys/types.h> # include <pmachine.h> # ifdef NEED_STRING_H # include <string.h> # else # include <strings.h> # endif # ifndef CUTCP # include <netdb.h> # endif # if !defined(MSDOS) || defined(OS2) # include <sys/file.h> # include <sys/param.h> # endif #endif /* VMS */ #include <pfs.h> #include <pprot.h> #include <perrno.h> #include <pcompat.h> #include <pauthent.h> #include "regex.h" int pfs_enable = PMAP_ATSIGN; #ifndef FALSE # define TRUE 1 # define FALSE 0 #endif /* * wcmatch - Match string s against template containing widlcards * * WCMATCH takes a string and a template, and returns * true if the string matches the template, and * FALSE otherwise. * * ARGS: s - string to be tested * template - Template containing optional wildcards * * RETURNS: TRUE (non-zero) on match. FALSE (0) otherwise. * * NOTE: If template is NULL, will return TRUE. * */ int wcmatch(s,template) char *s; char *template; { char temp[200]; char *p = temp; if(!template) return(TRUE); *p++ = '^'; while(*template) { if(*template == '*') {*(p++)='.'; *(p++) = *(template++);} else if(*template == '?') {*(p++)='.';template++;} else if(*template == '.') {*(p++)='\\';*(p++)='.';template++;} else if(*template == '[') {*(p++)='\\';*(p++)='[';template++;} else if(*template == '$') {*(p++)='\\';*(p++)='$';template++;} else if(*template == '^') {*(p++)='\\';*(p++)='^';template++;} else if(*template == '\\') {*(p++)='\\';*(p++)='\\';template++;} else *(p++) = *(template++); } *p++ = '$'; *p++ = '\0'; if(re_comp(temp)) return(FALSE); #ifdef AUX if (re_exec(s) == (char *)NULL) return 0; return 1; #else return(re_exec(s)); #endif } /* * ul_insert - Insert a union link at the right location * * UL_INSERT takes a directory and a union link to be added * to a the list of union links in the directory. It then * inserts the union link in the right spot in the linked * list of union links associated with that directory. * * If an identical link already exists, then the link which * would be evaluated earlier (closer to the front of the list) * wins and the other one is freed. If this happens, an error * will also be returned. * * ARGS: ul - link to be inserted * vd - directory to get link * p - vl that this link will apper after * NULL - This vl will go at end of list * vd - This vl will go at head of list * * RETURNS: Success, or UL_INSERT_ALREADY_THERE or UL_INSERT_SUPERSEDING */ int ul_insert(ul,vd,p) VLINK ul; /* Link to be inserted */ PVDIR vd; /* Directory to receive link */ VLINK p; /* Union link to appear prior to new one */ { VLINK current; /* This is the first ul in the directory */ if(vd->ulinks == NULL) { vd->ulinks = ul; ul->previous = NULL; ul->next = NULL; return(PSUCCESS); } /* This ul will go at the head of the list */ if(p == (VLINK) vd) { ul->next = vd->ulinks; ul->next->previous = ul; vd->ulinks = ul; ul->previous = NULL; } /* Otherwise, decide if it must be inserted at all */ /* If an identical link appears before the position */ /* at which the new one is to be inserted, we can */ /* return without inserting it */ else { current = vd->ulinks; while(current) { /* p == NULL means we insert after last link */ if(!p && (current->next == NULL)) p = current; if(vl_comp(current,ul) == 0) { vlfree(ul); return(UL_INSERT_ALREADY_THERE); } if(current == p) break; current = current->next; } /* If current is null, p was not found */ if(current == NULL) return(UL_INSERT_POS_NOTFOUND); /* Insert ul */ ul->next = p->next; p->next = ul; ul->previous = p; if(ul->next) ul->next->previous = ul; } /* Check for identical links after ul */ current = ul->next; while(current) { if(vl_comp(current,ul) == 0) { current->previous->next = current->next; if(current->next) current->next->previous = current->previous; vlfree(current); return(UL_INSERT_SUPERSEDING); } current = current->next; } return(PSUCCESS); } /* * vl_insert - Insert a directory link at the right location * * VL_INSERT takes a directory and a link to be added to a * directory and inserts it in the linked list of links for * that directory. * * If a link already exists with the same name, and if the * information associated with the new link matches that in * the existing link, an error is returned. If the information * associated with the new link is different, but the magic numbers * match, then the new link will be added as a replica of the * existing link. If the magic numbers do not match, the new * link will only be added to the list of "replicas" if the * allow_conflict flag has been set. * * If the link is not added, an error is returned and the link * is freed. Ordering for the list of links is by the link name. * * If vl is a union link, then VL_INSERT calls ul_insert with an * added argument indicating the link is to be included at the * end of the union link list. * * ARGS: vl - Link to be inserted, vd - directory to get link * allow_conflict - insert links with conflicting names * * RETURNS: Success, or VL_INSERT_ALREADY_THERE */ int vl_insert(vl,vd,allow_conflict) VLINK vl; /* Link to be inserted */ PVDIR vd; /* Directory to receive link */ int allow_conflict; /* Allow duplicate names */ { VLINK current; /* To step through list */ VLINK crep; /* To step through list of replicas */ int retval; /* Temp for checking returned values */ /* This can also be used to insert union links at end of list */ if(vl->linktype == 'U') return(ul_insert(vl,vd,NULL)); /* If this is the first link in the directory */ if(vd->links == NULL) { vd->links = vl; vl->previous = NULL; vl->next = NULL; vd->lastlink = vl; return(PSUCCESS); } /* If no sorting is to be done, just insert at end of list */ if(allow_conflict == VLI_NOSORT) { vd->lastlink->next = vl; vl->previous = vd->lastlink; vl->next = NULL; vd->lastlink = vl; return(PSUCCESS); } /* If it is to be inserted at start of list */ if(vl_comp(vl,vd->links) < 0) { vl->next = vd->links; vl->previous = NULL; vl->next->previous = vl; vd->links = vl; return(PSUCCESS); } current = vd->links; /* Otherwise, we must find the right spot to insert it */ while((retval = vl_comp(vl,current)) > 0) { if(!current->next) { /* insert at end */ vl->previous = current; vl->next = NULL; current->next = vl; vd->lastlink = vl; return(PSUCCESS); } current = current->next; } /* If we found an equivilant entry already in list */ if(!retval) { if(vl_equal(vl,current)) { vlfree(vl); return(VL_INSERT_ALREADY_THERE); } if((allow_conflict == VLI_NOCONFLICT) && ((vl->f_magic_no != current->f_magic_no) || (vl->f_magic_no==0))) return(VL_INSERT_CONFLICT); /* Insert the link into the list of "replicas" */ /* If magic is 0, then create a pseudo magic number */ if(vl->f_magic_no == 0) vl->f_magic_no = -1; crep = current->replicas; if(!crep) { current->replicas = vl; vl->next = NULL; vl->previous = NULL; } else { while(crep->next) { /* If magic was 0, then we need a unique magic number */ if((crep->f_magic_no < 0) && (vl->f_magic_no < 1)) (vl->f_magic_no)--; crep = crep->next; } /* If magic was 0, then we need a unique magic number */ if((crep->f_magic_no < 0) && (vl->f_magic_no < 1)) (vl->f_magic_no)--; crep->next = vl; vl->previous = crep; vl->next = NULL; } return(PSUCCESS); } /* We found the spot where vl is to be inserted */ vl->next = current; vl->previous = current->previous; current->previous = vl; vl->previous->next = vl; return(PSUCCESS); } /* * nlsindex - Find first instance of string 2 in string 1 following newline * * NLSINDEX scans string 1 for the first instance of string * 2 that immediately follows a newline. If found, NLSINDEX * returns a pointer to the first character of that instance. * If no instance is found, NLSINDEX returns NULL (0). * * NOTE: This function is only useful for searching strings that * consist of multiple lines. s1 is assumed to be preceeded * by a newline. Thus, if s2 is at the start of s1, it will * be found. * ARGS: s1 - string to be searched * s2 - string to be found * RETURNS: First instance of s2 in s1, or NULL (0) if not found */ char * nlsindex(s1,s2) char *s1; /* String to be searched */ char *s2; /* String to be found */ { register int s2len = strlen(s2); char *curline = s1; /* Pointer to start of current line */ /* In case s2 appears at start of s1 */ if(strncmp(curline,s2,s2len) == 0) return(curline); /* Check remaining lines of s1 */ while((curline = (char *) index(curline,'\n')) != NULL) { curline++; if(strncmp(curline,s2,s2len) == 0) return(curline); } /* We didn't find it */ return(NULL); } /* * month_sname - Return a month name from it's number * * MONTH_SNAME takes a number in the range 0 * to 12 and returns a pointer to a string * representing the three letter abbreviation * for that month. If the argument is out of * range, MONTH_SNAME returns a pointer to "Unk". * * ARGS: n - Number of the month * RETURNS: Abbreviation for selected month */ char *month_sname(n) int n; /* Month number */ { static char *name[] = { "Unk", "Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec" }; return((n < 1 || n > 12) ? name[0] : name[n]); } /* * sindex - Find first instance of string 2 in string 1 * * SINDEX scans string 1 for the first instance of string * 2. If found, SINDEX returns a pointer to the first * character of that instance. If no instance is found, * SINDEX returns NULL (0). * * ARGS: s1 - string to be searched * s2 - string to be found * RETURNS: First instance of s2 in s1, or NULL (0) if not found */ char * sindex(s1,s2) char *s1; /* String to be searched */ char *s2; /* String to be found */ { register int s2len = strlen(s2); char *s = s1; /* Temp pointer to string */ /* Check for first character of s2 */ while((s = (char *) index(s,*s2)) != NULL) { if(strncmp(s,s2,s2len) == 0) return(s); s++; } /* We didn't find it */ return(NULL); } int scan_error(erst) char *erst; { *p_err_string = '\0'; if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0) return(DIRSRV_NOT_DIRECTORY); if(strncmp(erst,"UNIMPLEMENTED",13) == 0) { perrno = DIRSRV_UNIMPLEMENTED; sscanf(erst+13,"%*[^\n \t\r]%*[ \t]%[^\n]",p_err_string); return(perrno); } if(strncmp(erst,"WARNING ",8) == 0) { erst += 8; *p_warn_string = '\0'; sscanf(erst,"%*[^\n \t\r]%*[ \t]%[^\n]",p_warn_string); /* Return values for warnings are negative */ if(strncmp(erst,"OUT-OF-DATE",11) == 0) { pwarn = PWARN_OUT_OF_DATE; return(PSUCCESS); } if(strncmp(erst,"MESSAGE",7) == 0) { pwarn = PWARN_MSG_FROM_SERVER; return(PSUCCESS); } pwarn = PWARNING; sscanf(erst,"%[^\n]",p_warn_string); return(PSUCCESS); } else if(strncmp(erst,"ERROR",5) == 0) { if(*(erst+5)) sscanf(erst+6,"%[^\n]",p_err_string); perrno = DIRSRV_ERROR; return(perrno); } /* The rest start with "FAILURE" */ else if(strncmp(erst,"FAILURE",7) != 0) { /* Unrecognized - Give warning, but return PSUCCESS */ if(pwarn == 0) { *p_warn_string = '\0'; pwarn = PWARN_UNRECOGNIZED_RESP; sscanf(erst,"%[^\n]",p_warn_string); } return(PSUCCESS); } if(strncmp(erst,"FAILURE ",8) != 0) { perrno = PFAILURE; return(perrno); } erst += 8; sscanf(erst,"%*[^\n \t\r]%*[ \t]%[^\n]",p_err_string); /* Still to add */ /* DIRSRV_AUTHENT_REQ 242 */ /* DIRSRV_BAD_VERS 245 */ if(strncmp(erst,"NOT-FOUND",9) == 0) perrno = DIRSRV_NOT_FOUND; else if(strncmp(erst,"NOT-AUTHORIZED",13) == 0) perrno = DIRSRV_NOT_AUTHORIZED; else if(strncmp(erst,"ALREADY-EXISTS",14) == 0) perrno = DIRSRV_ALREADY_EXISTS; else if(strncmp(erst,"NAME-CONFLICT",13) == 0) perrno = DIRSRV_NAME_CONFLICT; else if(strncmp(erst,"SERVER-FAILED",13) == 0) perrno = DIRSRV_SERVER_FAILED; /* Use it whether it starts with FAILURE or not */ else if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0) perrno = DIRSRV_NOT_DIRECTORY; else perrno = PFAILURE; return(perrno); } PATTRIB parse_attribute(line) char *line; { char l_precedence[MAX_DIR_LINESIZE]; char l_name[MAX_DIR_LINESIZE]; char l_type[MAX_DIR_LINESIZE]; char l_value[MAX_DIR_LINESIZE]; PATTRIB at; int tmp; tmp = sscanf(line,"OBJECT-INFO %s %s %[^\n]", l_name, l_type, l_value); if(tmp < 3) { tmp = sscanf(line,"LINK-INFO %s %s %s %[^\n]", l_precedence, l_name, l_type, l_value); if(tmp < 4) { perrno = DIRSRV_BAD_FORMAT; return(NULL); } } at = atalloc(); if(tmp == 4) { if(strcmp(l_precedence,"CACHED") == 0) at->precedence = ATR_PREC_CACHED; else if(strcmp(l_precedence,"LINK") == 0) at->precedence = ATR_PREC_LINK; else if(strcmp(l_precedence,"REPLACEMENT") == 0) at->precedence = ATR_PREC_REPLACE; else if(strcmp(l_precedence,"ADDITIONAL") == 0) at->precedence = ATR_PREC_ADD; } at->aname = stcopy(l_name); at->avtype = stcopy(l_type); if(strcmp(l_type,"ASCII") == 0) at->value.ascii = stcopy(l_value); else if(strcmp(l_type,"LINK") == 0) { char ftype[MAX_DIR_LINESIZE]; char lname[MAX_DIR_LINESIZE]; char htype[MAX_DIR_LINESIZE]; char host[MAX_DIR_LINESIZE]; char ntype[MAX_DIR_LINESIZE]; char fname[MAX_DIR_LINESIZE]; VLINK al; al = vlalloc(); at->value.link = al; tmp = sscanf(l_value,"%c %s %s %s %s %s %s %d %d", &(al->linktype), ftype,lname,htype,host,ntype,fname, &(al->version), &(al->f_magic_no)); if(tmp == 9) { al->type = stcopyr(ftype,al->type); al->name = stcopyr(unquote(lname),al->name); al->hosttype = stcopyr(htype,al->hosttype); al->host = stcopyr(host,al->host); al->nametype = stcopyr(ntype,al->nametype); al->filename = stcopyr(fname,al->filename); } else { perrno = DIRSRV_BAD_FORMAT; return(NULL); } } return(at); } /* * nxtline - Find the next line in the string * * NXTLINE takes a string and returns a pointer to * the character immediately following the next newline. * * ARGS: s - string to be searched * * RETURNS: Next line or NULL (0) on failure */ char * nxtline(s) char *s; /* String to be searched */ { s = (char *) index(s,'\n'); if(s) return(++s); else return(NULL); } /* * unquote - unquote string if necessary * * UNQUOTE takes a string and unquotes it if it has been quoted. * * ARGS: s - string to be unquoted * * RETURNS: The original string. If the string has been quoted, then the * result appears in static storage, and must be copied if * it is to last beyond the next call to quote. * */ char * unquote(s) char *s; /* String to be quoted */ { static char unquoted[200]; char *c = unquoted; if(*s != '\'') return(s); s++; /* This should really treat a quote followed by other */ /* than a quote or a null as an error */ while(*s) { if(*s == '\'') s++; if(*s) *c++ = *s++; } *c++ = '\0'; return(unquoted); } #if defined(DEBUG) && defined(STRSPN) /* needed for -D option parsing */ /* * strspn - Count initial characters from chrs in s * * STRSPN counts the occurances of chacters from chrs * in the string s preceeding the first occurance of * a character not in s. * * ARGS: s - string to be checked * chrs - string of characters we are looking for * * RETURNS: Count of initial characters from chrs in s */ strspn(s,chrs) char *s; /* String to search */ char *chrs; /* String of characters we are looking for */ { char *cp; /* Pointer to the current character in chrs */ int count; /* Count of characters seen so far */ count = 0; while(*s) { for(cp = chrs;*cp;cp++) if(*cp == *s) { s++; count++; goto done; } return(count); done: ; } return(count); } #endif #ifdef CUTCP char *inet_ntoa(struct in_addr in) { static char buff[36]; unsigned char *c = (char *) &in.address; sprintf(buff,"%d.%d.%d.%d",*c,*(c+1),*(c+2),*(c+3)); return(buff); } long inet_addr(char *cp) { long value = 0; unsigned v1,v2,v3,v4; v1 = v2 = v3 = v4 = 0xff; sscanf(cp,"%d.%d.%d.%d",&v1,&v2,&v3,&v4); value = (v1 << 24) | (v2 << 16) | (v3 << 8) | v4; return(value); } struct hostent *gethostbyname(char *name) { struct machinfo *mp; int mnum; unsigned long now; static struct hostent ht; extern int pfs_debug; mp = Shostlook(name); if(!mp || (!mp->hostip[0])) { /* DNS lookup */ #ifdef DEBUG if (pfs_debug) fprintf(stderr, "Domain name lookup of %s\n", name); #endif mnum = Sdomain(name); /* start a DNS lookup */ now = time(NULL) + NS_TIMEOUT; while(now > time(NULL)) { int i, class, dat; Stask(); i = Sgetevent(USERCLASS, &class, &dat); if(i == DOMOK) { /* domain lookup ok */ mp = Slooknum(mnum); #ifdef DEBUG if (pfs_debug) fprintf(stderr, "Domain name lookup of %s Completed OK\n", name); #endif break; } } if(!mp) { /* get here if timeout */ #ifdef DEBUG if (pfs_debug) fprintf(stderr, "Domain name lookup of %s Failed\n", name); #endif return(NULL); } } ht.h_addr = *((unsigned long *) mp->hostip); ht.h_length = 4; ht.h_addrtype = AF_INET; return(&ht); } #endif /* CUTCP */ #ifdef GETENV /* * Copyright (c) 1987 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that: (1) source distributions retain this entire copyright * notice and comment, and (2) distributions including binaries display * the following acknowledgement: ``This product includes software * developed by the University of California, Berkeley and its contributors'' * in the documentation or other materials provided with the distribution * and in all advertising materials mentioning features or use of this * software. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)getenv.c 5.7 (Berkeley) 6/1/90"; #endif /* LIBC_SCCS and not lint */ #include <stdlib.h> #include <stddef.h> /* * getenv -- * Returns ptr to value associated with name, if any, else NULL. */ char * getenv(name) char *name; { int offset; char *_findenv(); return(_findenv(name, &offset)); } /* * _findenv -- * Returns pointer to value associated with name, if any, else NULL. * Sets offset to be the offset of the name/value combination in the * environmental array, for use by setenv(3) and unsetenv(3). * Explicitly removes '=' in argument name. * * This routine *should* be a static; don't use it. */ char * _findenv(name, offset) register char *name; int *offset; { extern char **environ; register int len; register char **P, *C; for (C = name, len = 0; *C && *C != '='; ++C, ++len); for (P = environ; *P; ++P) if (!strncmp(*P, name, len)) if (*(C = *P + len) == '=') { *offset = P - environ; return(++C); } return(NULL); } #endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.