_setargv.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
  3. See the accompanying file LICENSE, version 1999-Oct-05 or later
  4. (the contents of which are also included in zip.h) for terms of use.
  5. If, for some reason, both of these files are missing, the Info-ZIP license
  6. also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
  7. */
  8. /*
  9. * __setargv.c - command argument expander
  10. *
  11. * Author : Jean-Michel Dubois
  12. * Date : 09/26/92
  13. *
  14. * Function: Expands the command line arguments by replacing any filename
  15. * including wilcards by the sorted list of matching files name.
  16. * Strings beginning by a dash are considered as options and left
  17. * unchanged.
  18. *
  19. * Syntax : void _setargv(int *argc, char ***argv);
  20. *
  21. * Returns : new argc. Caller's argc and argv are updated.
  22. * If a insufficient memory condition occurs, return 0 and errno
  23. * is set to ENOMEM.
  24. *
  25. * Example :
  26. * main(int argc, char **argv)
  27. * {
  28. * if (_setargv(&argc, &argv)) {
  29. * ...
  30. */
  31. #pragma library
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <malloc.h>
  36. #include <errno.h>
  37. #include <scr.h>
  38. #include <peek.h>
  39. /* Allocate argv array in 16 entries chunks */
  40. static int allocarg(int n, int l, char ***nargv, char *s)
  41. {
  42. if ((n+1) > l) { /* If array full */
  43. l += 16; /* increase size and reallocate */
  44. if (!(*nargv = (char **) realloc(*nargv,l * sizeof (void *)))) {
  45. errno = _errnum = ENOMEM; /* Not enough memory */
  46. return 0;
  47. }
  48. }
  49. (*nargv)[n] = strdup(s); /* Save argument */
  50. return l; /* Return new maxsize */
  51. }
  52. /* Comparison function for qsort */
  53. static int sortcmp(char **p, char **q)
  54. {
  55. return stricmp(*p,*q);
  56. }
  57. /* Main body of the function */
  58. int _setargv(int *argc, char ***argv)
  59. {
  60. register int nargc; /* New arguments counter */
  61. char **nargv; /* New arguments pointers */
  62. register int i, l, base;
  63. char *p, *q, *r;
  64. char path[FILENAME_MAX];
  65. _errnum = 0;
  66. nargc = 0; /* Initialise counter, size counter */
  67. l = *argc; /* and new argument vector to the */
  68. /* current argv array size */
  69. if ((nargv = (char **) calloc((size_t) *argc, sizeof (void *))) != NULL) {
  70. /* For each initial argument */
  71. for (i = 0; i < *argc; i++) {
  72. q = (*argv)[i];
  73. if (q[0] == '-' || ! testwild(q)) {
  74. /* if it begins with a dash or doesnt include
  75. * wildcard simply add it to the new array
  76. */
  77. if (! (l = allocarg(nargc, l, &nargv, q)))
  78. return 0; /* Not enough memory */
  79. nargc++;
  80. } else {
  81. /* else keep current counter for qsort */
  82. base = nargc;
  83. /* open directory with argument */
  84. diropen(q);
  85. while ((r = dirread()) != NULL) {
  86. /* reduce path to given one */
  87. if ((p = strrchr(q, '/')) != NULL) {
  88. strncpy(path, q, p-q+1);
  89. path[p-q+1] = '\0';
  90. } else
  91. path[0] = '\0';
  92. if ((p = strrchr(r, '/')) != NULL)
  93. strcat(path, p+1);
  94. else
  95. strcat(path, r);
  96. if (peekscr(&SCR->searchseq[1]) == 255
  97. && strchr(q, ':') == NULL) {
  98. *strchr(path, ':') = '\0';
  99. }
  100. /* and add each matching filename. */
  101. if (! (l = allocarg(nargc,l,&nargv,path)))
  102. return 0;/* Not enough memory */
  103. nargc++;
  104. }
  105. if (nargc == base) {
  106. /* if no match found include wild card name */
  107. if (! (l = allocarg(nargc, l, &nargv, q)))
  108. return 0; /* Not enough memory */
  109. nargc++;
  110. } else if ((nargc - base) > 1)
  111. /* If more than one file name matchs */
  112. /* sort arguments. */
  113. qsort(&(nargv[base]),(size_t)nargc-base,
  114. sizeof(void *),sortcmp);
  115. dirclose();
  116. }
  117. }
  118. /* Update caller's parameters */
  119. *argc = nargc;
  120. *argv = nargv;
  121. /* and sign on success */
  122. return nargc;
  123. }
  124. /* If it is not possible to allocate initial array, sign on error */
  125. _errnum = ENOMEM;
  126. return 0;
  127. }