123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- /*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
- (the contents of which are also included in zip.h) for terms of use.
- If, for some reason, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
- */
- /*
- * __setargv.c - command argument expander
- *
- * Author : Jean-Michel Dubois
- * Date : 09/26/92
- *
- * Function: Expands the command line arguments by replacing any filename
- * including wilcards by the sorted list of matching files name.
- * Strings beginning by a dash are considered as options and left
- * unchanged.
- *
- * Syntax : void _setargv(int *argc, char ***argv);
- *
- * Returns : new argc. Caller's argc and argv are updated.
- * If a insufficient memory condition occurs, return 0 and errno
- * is set to ENOMEM.
- *
- * Example :
- * main(int argc, char **argv)
- * {
- * if (_setargv(&argc, &argv)) {
- * ...
- */
- #pragma library
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <malloc.h>
- #include <errno.h>
- #include <scr.h>
- #include <peek.h>
- /* Allocate argv array in 16 entries chunks */
- static int allocarg(int n, int l, char ***nargv, char *s)
- {
- if ((n+1) > l) { /* If array full */
- l += 16; /* increase size and reallocate */
- if (!(*nargv = (char **) realloc(*nargv,l * sizeof (void *)))) {
- errno = _errnum = ENOMEM; /* Not enough memory */
- return 0;
- }
- }
- (*nargv)[n] = strdup(s); /* Save argument */
- return l; /* Return new maxsize */
- }
- /* Comparison function for qsort */
- static int sortcmp(char **p, char **q)
- {
- return stricmp(*p,*q);
- }
- /* Main body of the function */
- int _setargv(int *argc, char ***argv)
- {
- register int nargc; /* New arguments counter */
- char **nargv; /* New arguments pointers */
- register int i, l, base;
- char *p, *q, *r;
- char path[FILENAME_MAX];
- _errnum = 0;
- nargc = 0; /* Initialise counter, size counter */
- l = *argc; /* and new argument vector to the */
- /* current argv array size */
- if ((nargv = (char **) calloc((size_t) *argc, sizeof (void *))) != NULL) {
- /* For each initial argument */
- for (i = 0; i < *argc; i++) {
- q = (*argv)[i];
- if (q[0] == '-' || ! testwild(q)) {
- /* if it begins with a dash or doesnt include
- * wildcard simply add it to the new array
- */
- if (! (l = allocarg(nargc, l, &nargv, q)))
- return 0; /* Not enough memory */
- nargc++;
- } else {
- /* else keep current counter for qsort */
- base = nargc;
- /* open directory with argument */
- diropen(q);
- while ((r = dirread()) != NULL) {
- /* reduce path to given one */
- if ((p = strrchr(q, '/')) != NULL) {
- strncpy(path, q, p-q+1);
- path[p-q+1] = '\0';
- } else
- path[0] = '\0';
- if ((p = strrchr(r, '/')) != NULL)
- strcat(path, p+1);
- else
- strcat(path, r);
- if (peekscr(&SCR->searchseq[1]) == 255
- && strchr(q, ':') == NULL) {
- *strchr(path, ':') = '\0';
- }
- /* and add each matching filename. */
- if (! (l = allocarg(nargc,l,&nargv,path)))
- return 0;/* Not enough memory */
- nargc++;
- }
- if (nargc == base) {
- /* if no match found include wild card name */
- if (! (l = allocarg(nargc, l, &nargv, q)))
- return 0; /* Not enough memory */
- nargc++;
- } else if ((nargc - base) > 1)
- /* If more than one file name matchs */
- /* sort arguments. */
- qsort(&(nargv[base]),(size_t)nargc-base,
- sizeof(void *),sortcmp);
- dirclose();
- }
- }
- /* Update caller's parameters */
- *argc = nargc;
- *argv = nargv;
- /* and sign on success */
- return nargc;
- }
- /* If it is not possible to allocate initial array, sign on error */
- _errnum = ENOMEM;
- return 0;
- }
|