support.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:26k
源码类别:

代理服务器

开发平台:

Unix_Linux

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