File: _setargv.c

package info (click to toggle)
unzip 6.0-16%2Bdeb8u3
  • links: PTS
  • area: main
  • in suites: jessie
  • size: 8,768 kB
  • ctags: 10,194
  • sloc: ansic: 55,133; cpp: 4,084; makefile: 2,517; asm: 1,789; cs: 1,012; sh: 119
file content (165 lines) | stat: -rw-r--r-- 4,858 bytes parent folder | download | duplicates (15)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.

  See the accompanying file LICENSE, version 2000-Apr-09 or later
  (the contents of which are also included in unzip.h) for terms of use.
  If, for some reason, all these files are missing, the Info-ZIP license
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
*/
/*
 * _setargv.c - derived from an command argument expander
 *
 * Author  : Jean-Michel Dubois
 * Date    : 13-Dec-98
 *
 * Function: Looks for member names (fn.ft.mb) and add the libraries names
 *           (fn.ft) to the list of files to zip to force inclusion of
 *           libraries if necessary.
 *           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 asize, char ***nargv, char *s)
{
    if ((n+1) > asize) {    /* If array full */
        asize += 16;        /* increase size and reallocate */
        if (!(*nargv = (char **) realloc(*nargv, asize * sizeof (void *)))) {
            errno = _errnum = ENOMEM;    /* Not enough memory */
            return 0;
        }
    }
    (*nargv)[n] = strdup(s);    /* Save argument */
    return asize;               /* Return new maxsize */
}

/* check if file is a member of a library */

static int ismember(char* path)
{
    char* p;

    if ((p = strrchr(path, '/')) == NULL)
        p = path;
    return ((p = strchr(p, '.')) && (p = strchr(p + 1, '.')));
}

/* extract library name from a file name */

static char* libname(char* path)
{
    char* p;
    static char lib[256];
    char disk[3];

    strcpy(lib, path);
    if (p = strrchr(lib, ':')) {
        strncpy(disk, p, 2);
        disk[2] = '\0';
        *p = '\0' ;
    } else
        disk[0] = '\0';

    if ((p = strrchr(lib, '/')) == NULL)
        p = lib;

    p = strchr(p, '.');
    p = strchr(p + 1, '.');
    *p = 0;
    strcat(lib, disk);
    return lib;
}

/* 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, j;
    int asize;              /* argv array size */
    char *arg;
    char lib[256];

    _errnum = 0;
    nargc = 0;          /* Initialise counter, size counter */
    asize = *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++) {
            arg = (*argv)[i];
#ifdef DEBUG
            fprintf(stderr, "checking arg: %s", arg);
#endif
            if (i == 0 || *arg == '-' || ! ismember(arg)) {
                /* if it begins with a dash or doesn't include
                 * a library name simply add it to the new array */
                if (! (asize = allocarg(nargc, asize, &nargv, arg)))
                    return 0;   /* Not enough memory */
                nargc++;
            } else {
                short insert;
                strcpy(lib, libname(arg));
                /* add library name if necessary */
                for (j = 2, insert = 1; i < nargc; i++) {
                    if (ismember(nargv[i])
                     && ! strcmp(lib, libname(nargv[i]))) {
                        insert = 0;
                        break;
                    }
                }
                if (insert) {
#ifdef DEBUG
                    fprintf(stderr, "inserting lib %s ", lib);
#endif
                    if (! (asize = allocarg(nargc, asize, &nargv, lib)))
                        return 0;   /* Not enough memory */
                    nargc++;
                }
                /* add file name */
#ifdef DEBUG
                fprintf(stderr, "inserting file %s", arg);
#endif
                if (! (asize = allocarg(nargc, asize, &nargv, arg)))
                    return 0;   /* Not enough memory */
                nargc++;
            }
#ifdef DEBUG
            fprintf(stderr, "\n");
#endif
        }
        /* 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;
}