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