1/* 2 Copyright (c) 1990-2001 Info-ZIP. All rights reserved. 3 4 See the accompanying file LICENSE, version 2000-Apr-09 or later 5 (the contents of which are also included in unzip.h) for terms of use. 6 If, for some reason, all these files are missing, the Info-ZIP license 7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html 8*/ 9/* 10 * _setargv.c - derived from an command argument expander 11 * 12 * Author : Jean-Michel Dubois 13 * Date : 13-Dec-98 14 * 15 * Function: Looks for member names (fn.ft.mb) and add the libraries names 16 * (fn.ft) to the list of files to zip to force inclusion of 17 * libraries if necessary. 18 * Strings beginning by a dash are considered as options and left 19 * unchanged. 20 * 21 * Syntax : void _setargv(int *argc, char ***argv); 22 * 23 * Returns : new argc. Caller's argc and argv are updated. 24 * If a insufficient memory condition occurs, return 0 and errno 25 * is set to ENOMEM. 26 * 27 * Example : 28 * main(int argc, char **argv) 29 * { 30 * if (_setargv(&argc, &argv)) { 31 * ... 32 */ 33#pragma library 34 35#include <stdio.h> 36#include <stdlib.h> 37#include <string.h> 38#include <malloc.h> 39#include <errno.h> 40#include <scr.h> 41#include <peek.h> 42 43/* Allocate argv array in 16 entries chunks */ 44 45static int allocarg(int n, int asize, char ***nargv, char *s) 46{ 47 if ((n+1) > asize) { /* If array full */ 48 asize += 16; /* increase size and reallocate */ 49 if (!(*nargv = (char **) realloc(*nargv, asize * sizeof (void *)))) { 50 errno = _errnum = ENOMEM; /* Not enough memory */ 51 return 0; 52 } 53 } 54 (*nargv)[n] = strdup(s); /* Save argument */ 55 return asize; /* Return new maxsize */ 56} 57 58/* check if file is a member of a library */ 59 60static int ismember(char* path) 61{ 62 char* p; 63 64 if ((p = strrchr(path, '/')) == NULL) 65 p = path; 66 return ((p = strchr(p, '.')) && (p = strchr(p + 1, '.'))); 67} 68 69/* extract library name from a file name */ 70 71static char* libname(char* path) 72{ 73 char* p; 74 static char lib[256]; 75 char disk[3]; 76 77 strcpy(lib, path); 78 if (p = strrchr(lib, ':')) { 79 strncpy(disk, p, 2); 80 disk[2] = '\0'; 81 *p = '\0' ; 82 } else 83 disk[0] = '\0'; 84 85 if ((p = strrchr(lib, '/')) == NULL) 86 p = lib; 87 88 p = strchr(p, '.'); 89 p = strchr(p + 1, '.'); 90 *p = 0; 91 strcat(lib, disk); 92 return lib; 93} 94 95/* Main body of the function */ 96 97int _setargv(int *argc, char ***argv) 98{ 99 register int nargc; /* New arguments counter */ 100 char **nargv; /* New arguments pointers */ 101 register int i, j; 102 int asize; /* argv array size */ 103 char *arg; 104 char lib[256]; 105 106 _errnum = 0; 107 nargc = 0; /* Initialise counter, size counter */ 108 asize = *argc; /* and new argument vector to the */ 109 /* current argv array size */ 110 111 if ((nargv = (char **) calloc((size_t) *argc, sizeof (void *))) != NULL) { 112 /* For each initial argument */ 113 for (i = 0; i < *argc; i++) { 114 arg = (*argv)[i]; 115#ifdef DEBUG 116 fprintf(stderr, "checking arg: %s", arg); 117#endif 118 if (i == 0 || *arg == '-' || ! ismember(arg)) { 119 /* if it begins with a dash or doesn't include 120 * a library name simply add it to the new array */ 121 if (! (asize = allocarg(nargc, asize, &nargv, arg))) 122 return 0; /* Not enough memory */ 123 nargc++; 124 } else { 125 short insert; 126 strcpy(lib, libname(arg)); 127 /* add library name if necessary */ 128 for (j = 2, insert = 1; i < nargc; i++) { 129 if (ismember(nargv[i]) 130 && ! strcmp(lib, libname(nargv[i]))) { 131 insert = 0; 132 break; 133 } 134 } 135 if (insert) { 136#ifdef DEBUG 137 fprintf(stderr, "inserting lib %s ", lib); 138#endif 139 if (! (asize = allocarg(nargc, asize, &nargv, lib))) 140 return 0; /* Not enough memory */ 141 nargc++; 142 } 143 /* add file name */ 144#ifdef DEBUG 145 fprintf(stderr, "inserting file %s", arg); 146#endif 147 if (! (asize = allocarg(nargc, asize, &nargv, arg))) 148 return 0; /* Not enough memory */ 149 nargc++; 150 } 151#ifdef DEBUG 152 fprintf(stderr, "\n"); 153#endif 154 } 155 /* Update caller's parameters */ 156 *argc = nargc; 157 *argv = nargv; 158 /* and sign on success */ 159 return nargc; 160 } 161 162 /* If it is not possible to allocate initial array, sign on error */ 163 _errnum = ENOMEM; 164 return 0; 165} 166