home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: OtherApp / OtherApp.zip / wincam.zip / winc_src.zip / mergeenv.c < prev    next >
C/C++ Source or Header  |  1997-02-28  |  4KB  |  154 lines

  1.  
  2. /*
  3.  * merge a file with the environment
  4.  */
  5.  
  6. /*
  7.  * Copyright (C) 1996, Paul G. Fox
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify it
  10.  * under the terms of the GNU General Public License as published by the
  11.  * Free Software Foundation; either version 2 of the License, or (at your
  12.  * option) any later version.
  13.  * 
  14.  * This program is distributed in the hope that it will be useful, but
  15.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * General Public License for more details.
  18.  * 
  19.  * You should have received a copy of the GNU General Public License along
  20.  * with this program; if not, write to the Free Software Foundation, Inc.,
  21.  * 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  *
  23.  */
  24.  
  25. /*
  26.  * read the specified file, parse out environment-like variables (i.e.
  27.  * things that look like FOO=BAR, or MyVerySpecialVariable=frewfrew)
  28.  * and put them in the environment.  if "replace" is true, replace
  29.  * existing variables, otherwise skip them.  variables cannot be removed
  30.  * from the environment -- only added or replaced, possibly being set to null.
  31.  *
  32.  *  - lines whose first non-whitespace character is '#' are skipped.
  33.  *  - end-of-line comments are not supported.
  34.  *  - whitespace surrounding the '=' sign itself is removed, as is
  35.  *    whitespace at the end of the line.  thus no values can ever
  36.  *    begin or end in whitespace.
  37.  *  - no other modifications are made to the value part.
  38.  *  - no quoting mechanisms are supported.
  39.  *  - line continuations are not supported.
  40.  */ 
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <unistd.h>
  44. #include <ctype.h>
  45. #include <string.h>
  46.  
  47. /*
  48.  * wrap putenv in something that allocates the necessary memory
  49.  * for us.
  50.  */
  51. int
  52. safeputenv(char *name, char *value)
  53. {
  54.     char *cp;
  55.     cp = malloc(strlen(name) + strlen(value) + 2);
  56.     if (!cp)
  57.     return -1;
  58.  
  59.     sprintf(cp, "%s=%s", name, value);
  60.     if (putenv(cp) == -1) {
  61.     free(cp);
  62.     return -1;
  63.     }
  64.     return 0;
  65. }
  66.  
  67. int
  68. mergeenv( char *filename, int replace)
  69. {
  70.     FILE *fp;
  71.     int c, nlen;
  72.     int lineno = 0;
  73.     char *cp, *np, *vp;
  74.     char line[160];
  75.  
  76.     fp = fopen(filename, "r");
  77.     if (!fp)
  78.     return 0;
  79.  
  80.     while (fgets(line, sizeof(line), fp) != NULL) {
  81.     lineno++;
  82.     cp = strchr(line, '\n');
  83.     if (!cp) { /* didn't get a whole line */
  84.         /* skip the _rest_ of that line */
  85.         while ((c = fgetc(fp)) != '\n' && c != EOF)
  86.         ;
  87.         continue;
  88.     }
  89.     *cp = '\0'; /* nuke the newline */
  90.  
  91.     cp = line;
  92.     while (isspace(*cp)) cp++;  /* eat leading whitespace */
  93.  
  94.     /* nothing of interest on line? */
  95.     if (!*cp || *cp == '#')
  96.         continue;
  97.  
  98.     np = cp;    /* name starts here */
  99.  
  100.     while (isalnum(*cp) || *cp == '_') cp++; /* the name part */
  101.  
  102.     /* name part is this long */
  103.     nlen = cp - np;
  104.  
  105.     while (isspace(*cp)) cp++;  /* eat whitespace */
  106.  
  107.     if (nlen == 0 || *cp++ != '=') { /* syntax error */
  108.         fclose(fp);
  109.         return lineno;
  110.     }
  111.     np[nlen] = '\0'; /* terminate the name part */
  112.  
  113.     /* we're not supposed to replace existing, and it exists */
  114.     if (!replace && getenv(np))
  115.         continue;
  116.  
  117.     while (isspace(*cp)) cp++;  /* eat whitespace */
  118.  
  119.     vp = cp;    /* value starts here */
  120.  
  121.     cp = strchr(vp, '\0'); /* find end of line */
  122.     while(isspace(*--cp))    /* shrink to non-whitespace */
  123.         *cp = '\0';
  124.  
  125.     if (safeputenv(np, vp) == -1) {
  126.         fclose(fp);
  127.         return -1;
  128.     }
  129.     }
  130.  
  131.     fclose(fp);
  132.     return 0;
  133. }
  134.  
  135. #if TESTING
  136.  
  137. #include <unistd.h>
  138.  
  139. int
  140. main()
  141. {
  142.     int r;
  143.     r = mergeenv("foo",1);
  144.     if (r == 0)
  145.     execl("/bin/sh", "sh", 0);
  146.     if (r == -1) {
  147.     fprintf(stderr, "error reading file\n");
  148.     exit(1);
  149.     }
  150.     fprintf(stderr, "syntax error at line %d\n", r);
  151.     return 1;
  152. }
  153. #endif
  154.