home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip51.zip / envargs.c < prev    next >
C/C++ Source or Header  |  1993-12-09  |  6KB  |  216 lines

  1. /*----------------------------------------------------------------*
  2.  | envargs - add default options from environment to command line
  3.  |---------------------------------------------------------------- 
  4.  | Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
  5.  | This program is in the public domain.
  6.  |---------------------------------------------------------------- 
  7.  | Minor program notes:
  8.  |  1. Yes, the indirection is a tad complex
  9.  |  2. Parenthesis were added where not needed in some cases
  10.  |     to make the action of the code less obscure.
  11.  |  3. Set tabsize to four to make this pretty
  12.  |---------------------------------------------------------------- 
  13.  | UnZip notes 24 May 92 ("v1.4"):
  14.  |  1. #include "unzip.h" for prototypes
  15.  |  2. changed ch to type char
  16.  |  3. added an ifdef to avoid Borland warnings
  17.  |
  18.  | UnZip notes 4 Dec 93 ("v1.5"):
  19.  |  1. included Rich Wales' mksargs() routine (for MS-DOS, maybe
  20.  |     OS/2? NT?)
  21.  *----------------------------------------------------------------*/
  22.  
  23.  
  24. #include "unzip.h"
  25.  
  26. static int count_args __((char *));
  27. static void mem_err __((void));
  28.  
  29. #if (defined(SCCS) && !defined(lint))  /* causes warnings:  annoying */
  30.    static char *SCCSid = "@(#)envargs.c    1.3 23 Oct 1991";
  31. #endif
  32.  
  33.  
  34.  
  35. void envargs(Pargc, Pargv, envstr)
  36.     int *Pargc;
  37.     char ***Pargv, *envstr;
  38. {
  39.     char *getenv();
  40.     char *envptr;       /* value returned by getenv */
  41.     char *bufptr;       /* copy of env info */
  42.     int argc = 0;       /* internal arg count */
  43.     char ch;            /* spare temp value */
  44.     char **argv;        /* internal arg vector */
  45.     char **argvect;     /* copy of vector address */
  46.  
  47.     /* see if anything in the environment */
  48.     envptr = getenv(envstr);
  49.     if (envptr == (char *)NULL || *envptr == 0)
  50.         return;
  51.  
  52.     /* count the args so we can allocate room for them */
  53.     argc = count_args(envptr);
  54.     bufptr = (char *)malloc(1+strlen(envptr));
  55.     if (bufptr == (char *)NULL)
  56.         mem_err();
  57.     strcpy(bufptr, envptr);
  58.  
  59.     /* allocate a vector large enough for all args */
  60.     argv = (char **)malloc((argc+*Pargc+1)*sizeof(char *));
  61.     if (argv == (char **)NULL)
  62.         mem_err();
  63.     argvect = argv;
  64.  
  65.     /* copy the program name first, that's always true */
  66.     *(argv++) = *((*Pargv)++);
  67.  
  68.     /* copy the environment args next, may be changed */
  69.     do {
  70.         *(argv++) = bufptr;
  71.         /* skip the arg and any trailing blanks */
  72.         while (((ch = *bufptr) != '\0') && ch != ' ')
  73.             ++bufptr;
  74.         if (ch == ' ')
  75.             *(bufptr++) = '\0';
  76.         while (((ch = *bufptr) != '\0') && ch == ' ')
  77.             ++bufptr;
  78.     } while (ch);
  79.  
  80.     /* now save old argc and copy in the old args */
  81.     argc += *Pargc;
  82.     while (--(*Pargc))
  83.         *(argv++) = *((*Pargv)++);
  84.  
  85.     /* finally, add a NULL after the last arg, like UNIX */
  86.     *argv = (char *)NULL;
  87.  
  88.     /* save the values and return */
  89.     *Pargv = argvect;
  90.     *Pargc = argc;
  91. }
  92.  
  93.  
  94.  
  95. static int count_args(s)
  96.     char *s;
  97. {
  98.     int count = 0;
  99.     char ch;
  100.  
  101.     do {
  102.         /* count and skip args */
  103.         ++count;
  104.         while (((ch = *s) != '\0') && ch != ' ')
  105.             ++s;
  106.         while (((ch = *s) != '\0') && ch == ' ')
  107.             ++s;
  108.     } while (ch);
  109.  
  110.     return count;
  111. }
  112.  
  113.  
  114.  
  115. static void mem_err()
  116. {
  117.     perror("Can't get memory for arguments");
  118.     exit(2);
  119. }
  120.  
  121.  
  122.  
  123. #ifdef TEST
  124.  
  125. main(argc, argv)
  126.     int argc;
  127.     char **argv;
  128. {
  129.     int i;
  130.  
  131.     printf("Orig argv: %p\n", argv);
  132.     dump_args(argc, argv);
  133.     envargs(&argc, &argv, "ENVTEST");
  134.     printf(" New argv: %p\n", argv);
  135.     dump_args(argc, argv);
  136. }
  137.  
  138.  
  139.  
  140. dump_args(argc, argv)
  141.     int argc;
  142.     char *argv[];
  143. {
  144.     int i;
  145.  
  146.     printf("\nDump %d args:\n", argc);
  147.     for (i = 0; i < argc; ++i)
  148.         printf("%3d %s\n", i, argv[i]);
  149. }
  150.  
  151. #endif /* TEST */
  152.  
  153.  
  154.  
  155. #ifdef MSDOS   /* DOS_OS2?  DOS_NT_OS2? */
  156.  
  157. /*
  158.  * void mksargs(int *argcp, char ***argvp)
  159.  *
  160.  *    Substitutes the extended command line argument list produced by
  161.  *    the MKS Korn Shell in place of the command line info from DOS.
  162.  *
  163.  *    The MKS shell gets around DOS's 128-byte limit on the length of
  164.  *    a command line by passing the "real" command line in the envi-
  165.  *    ronment.  The "real" arguments are flagged by prepending a tilde
  166.  *    (~) to each one.
  167.  *
  168.  *    This "mksargs" routine creates a new argument list by scanning
  169.  *    the environment from the beginning, looking for strings begin-
  170.  *    ning with a tilde character.  The new list replaces the original
  171.  *    "argv" (pointed to by "argvp"), and the number of arguments
  172.  *    in the new list replaces the original "argc" (pointed to by
  173.  *    "argcp").
  174.  *
  175.  *    Rich Wales
  176.  */
  177. void mksargs(argcp, argvp)
  178.     int *argcp;
  179.     char ***argvp;
  180. {
  181. #ifndef MSC /* declared differently in MSC 7.0 headers, at least */
  182.     extern char **environ;          /* environment */
  183. #endif
  184.     char        **envp;             /* pointer into environment */
  185.     char        **newargv;          /* new argument list */
  186.     char        **argp;             /* pointer into new arg list */
  187.     int         newargc;            /* new argument count */
  188.  
  189.     /* sanity check */
  190.     if (environ == NULL || argcp == NULL || argvp == NULL || *argvp == NULL)
  191.         return;
  192.  
  193.     /* find out how many environment arguments there are */
  194.     for (envp = environ, newargc = 0; *envp != NULL && (*envp)[0] == '~';
  195.          envp++, newargc++)
  196.         ;
  197.     if (newargc == 0)
  198.         return;     /* no environment arguments */
  199.  
  200.     /* set up new argument list */
  201.     newargv = (char **) malloc(sizeof(char **) * (newargc+1));
  202.     if (newargv == NULL)
  203.         return;     /* malloc failed */
  204.  
  205.     for (argp = newargv, envp = environ; *envp != NULL && (*envp)[0] == '~';
  206.          *argp++ = &(*envp++)[1])
  207.         ;
  208.     *argp = NULL;   /* null-terminate the list */
  209.  
  210.     /* substitute new argument list in place of old one */
  211.     *argcp = newargc;
  212.     *argvp = newargv;
  213. }
  214.  
  215. #endif /* MSDOS */
  216.