Annotation of coherent/d/bin/env.c, revision 1.1.1.1

1.1       root        1: static char _version[]="env version 1.0";
                      2: /*
                      3:  * env - execute a command in an environment
                      4:  *
                      5:  * usage: env [-] [VARIABLE=value ...] [command args]
                      6:  *
                      7:  * Executes "command" with "args", modifying the existing environment
                      8:  * by doing the requested assignments.  The "-" option means that the
                      9:  * environment should be _replaced_ with the list assignements, otherwise
                     10:  * the assignments are added to the environment.
                     11:  * If "command" is ommitted, the resulting environment is printed.
                     12:  */
                     13: 
                     14: #include <stdio.h>
                     15: #include <string.h>
                     16: #include <errno.h>
                     17: 
                     18: #define BIG_NUMBER 2048
                     19: #define TRUE (1==1)
                     20: #define FALSE (1==0)
                     21: #define VAR_SEPERATOR '='      /* Seperates an environment variable
                     22:                                   from its value.  */
                     23: 
                     24: void parse_args();
                     25: int arglen();
                     26: char **argcpy();
                     27: char **envncat();
                     28: int is_assignment();
                     29: 
                     30: /* Flags that tell us about our arguments */
                     31: int replace_env = FALSE;
                     32: int have_command = FALSE;
                     33: 
                     34: int assignment_count;  /* Number of assignments to add to environment.  */
                     35: char *first_assignment_argument = NULL;
                     36: 
                     37: int i; /* Generic index, used repeatedly */
                     38: 
                     39: char **new_argv;       /* Build new command line here.  */
                     40: char **new_envp;       /* Build the new environment here.  */
                     41: 
                     42: 
                     43: void
                     44: main(argc, argv, envp)
                     45:        int argc;
                     46:        char *argv[];
                     47:        char *envp[];
                     48: {
                     49: /* Parse arguments.  */
                     50:        parse_args(argc, argv);
                     51: 
                     52: /* Build the new environment.  */
                     53: 
                     54:        if (! replace_env) {
                     55:                /* Make enough space for the disjoint union of the two sets of
                     56:                 * environment assignments.  This is a guarenteed upper bound.
                     57:                 */
                     58:                new_envp = (char **) malloc( sizeof(char *)
                     59:                                             * (arglen(envp)
                     60:                                                + assignment_count + 1)
                     61:                                           );
                     62:                argcpy(new_envp, envp);
                     63:        } else {
                     64:                /* Otherwise, we only need enough space for the new
                     65:                 * environment.
                     66:                 */
                     67:                new_envp = (char **) malloc( sizeof(char *)
                     68:                                             * (assignment_count + 1)
                     69:                                           );
                     70:        } /* if (! replace_env) */
                     71: 
                     72: 
                     73:        envncat(new_envp, first_assignment_argument, assignment_count);
                     74: 
                     75: 
                     76: /* Do something--either a command or print the environment.  */
                     77:        if (have_command) {
                     78:                execvep(new_argv[0], new_argv, new_envp);
                     79:                perror(new_argv[0]);
                     80:                exit(1);
                     81:        } else {
                     82:                char **pntr;
                     83: 
                     84:                for (pntr = new_envp; *pntr != NULL; ++pntr){
                     85:                        printf("%s\n", *pntr);
                     86:                } /* for pntr in new_envp */
                     87: 
                     88:        } /* if have_command */
                     89: 
                     90:        exit(0);
                     91: }
                     92: 
                     93: 
                     94: void
                     95: parse_args(argc, argv)
                     96:        int argc;
                     97:        char *argv[];
                     98: {
                     99:        int current_arg;
                    100: 
                    101:        if (argc > 1) {
                    102:                current_arg = 1; /* Start looking at the first argument.  */
                    103: 
                    104:                /* - option -- Replace the existing environment.  */
                    105:                if (strcmp(argv[current_arg], "-") == 0) {
                    106:                        replace_env = TRUE;
                    107:                        ++current_arg;
                    108:                } /* if first argument is "-" */
                    109: 
                    110:                /* Count the number of arguments which are assignments.  */
                    111:                for (assignment_count = 0;
                    112:                     current_arg < argc;
                    113:                     current_arg++, assignment_count++) {
                    114: 
                    115:                        if (! is_assignment(argv[current_arg])) {
                    116:                                break;
                    117:                        }
                    118: 
                    119:                        if (first_assignment_argument == NULL) {
                    120:                                first_assignment_argument = &argv[current_arg];
                    121:                        }
                    122: 
                    123:                } /* for (Count the assignments on the command line.  ) */
                    124: 
                    125: 
                    126:                if ( current_arg < argc ) {
                    127:                        /* We broke out of the assignment couting loop
                    128:                         * early--this must be a command.
                    129:                         */
                    130:                        new_argv = &argv[current_arg];
                    131:                        have_command = TRUE;
                    132:                } /* if ( current_arg <= argc ) */
                    133: 
                    134:        } /* if there are any args */
                    135: 
                    136: } /* void parse_args() */
                    137: 
                    138: 
                    139: 
                    140: /* Count the number of arguments in an argument vector.
                    141:  * arg_vector MUST be NULL terminated!
                    142:  */
                    143: int
                    144: arglen(arg_vector)
                    145:        char **arg_vector;
                    146: {
                    147:        int count;
                    148:        
                    149:        for (count = 0; arg_vector[count] != NULL; ++count) {
                    150:        }
                    151: 
                    152:        return(count);
                    153: } /* arglen() */
                    154: 
                    155: 
                    156: /* Copy src argument vector to dest argument vector (pointer copy only).
                    157:  */
                    158: char **
                    159: argcpy(dest, src)
                    160:        char **dest, **src;
                    161: {
                    162:        while (*src != NULL) {
                    163:                *dest++ = *src++;
                    164:        } /* while (walk two pointers down envp and new_envp) */
                    165:        *dest = NULL;
                    166:        return (dest);
                    167: } /* char **argcpy() */
                    168: 
                    169: 
                    170: 
                    171: 
                    172: /* Merge one environment onto another, overwriting duplicate
                    173:  * variable names.  Compare at most n patterns.
                    174:  */
                    175: char **
                    176: envncat(dest, src, n)
                    177:        char **dest, **src;
                    178:        int n;
                    179: {
                    180:        char **dest_walker;
                    181:        char *sep_loc;  /* Seperator ("=") location in assignment */
                    182:        int i;
                    183:        int name_size;  /* Number of characters in a given variable name */
                    184: 
                    185:        for (i=0; *src != NULL && i < n; ++i, ++src) {
                    186: 
                    187:                /* Extract the variable name from the assignment *src.  */
                    188:                if ((sep_loc = strchr(*src, VAR_SEPERATOR)) == NULL) {
                    189:                        fprintf(stderr,
                    190:                                "Programming error:  %s is not an assignment\n",
                    191:                                *src);
                    192:                        exit(1);
                    193:                }
                    194:                name_size = sep_loc - *src;
                    195:                
                    196:                /* Look for variable part of *src in dest.
                    197:                 * Point at end if not found.
                    198:                 */
                    199:                for(dest_walker = dest; *dest_walker != NULL; ++dest_walker) {
                    200: 
                    201:                        /* NB: the + 1 is so the "=" is compared too.  */
                    202:                        if(strncmp(*dest_walker, *src, name_size + 1) == 0) {
                    203:                                /* We have found an exact match.  */
                    204:                                break;
                    205:                        } /* if *dest_walker and *src are same variable */
                    206: 
                    207:                } /* for Walk down dest environment */
                    208: 
                    209:                /* Checkpoint - *dest_walker either matches *src or is NULL.  */
                    210: 
                    211:                /* WARNING: possible memory leak--
                    212:                 *          *dest_walker is always clobbered.
                    213:                 *           Usually *dest_walker was copied from global
                    214:                 *           envp, so it isn't really lost memory.
                    215:                 */
                    216:                *dest_walker = *src;
                    217: 
                    218:        } /* for (i=0; *src != NULL && i < n; ++i, ++src) */
                    219: 
                    220:        return(dest);
                    221: } /* char ** envncat() */
                    222: 
                    223: int
                    224: is_assignment(s)
                    225:        char *s;
                    226: {
                    227:        if ( strchr(s, VAR_SEPERATOR) != NULL ) {
                    228:                return(TRUE);
                    229:        } else {
                    230:                return(FALSE);
                    231:        }
                    232: 
                    233: } /* int is_assignment() */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.