Deleted Added
full compact
2c2
< * Copyright (c) 2002-2003 Luigi Rizzo
---
> * Copyright (c) 2002-2003,2010 Luigi Rizzo
20c20
< * $FreeBSD: head/sbin/ipfw/main.c 190633 2009-04-01 20:23:47Z piso $
---
> * $FreeBSD: head/sbin/ipfw/main.c 204591 2010-03-02 17:40:48Z luigi $
83,95d82
< * Free a the (locally allocated) copy of command line arguments.
< */
< static void
< free_args(int ac, char **av)
< {
< int i;
<
< for (i=0; i < ac; i++)
< free(av[i]);
< free(av);
< }
<
< /*
98a86,92
> * First thing we do is process parameters creating an argv[] array
> * which includes the program name and a NULL entry at the end.
> * If we are called with a single string, we split it on whitespace.
> * Also, arguments with a trailing ',' are joined to the next one.
> * The pointers (av[]) and data are in a a single chunk of memory.
> * av[0] points to the original program name, all other entries
> * point into the allocated chunk.
103c97
< int ch, ac, save_ac;
---
> int ch, ac;
107a102,103
> int av_size; /* compute the av size */
> char *av_p; /* used to build the av list */
115,118c111,113
< * If we are called with a single string, try to split it into
< * arguments for subsequent parsing.
< * But first, remove spaces after a ',', by copying the string
< * in-place.
---
> * If we are called with one argument, try to split it into
> * words for subsequent parsing. Spaces after a ',' are
> * removed by copying the string in-place.
153,154c148,152
< * Allocate the argument list, including one entry for
< * the program name because getopt expects it.
---
> * Allocate the argument list structure as a single block
> * of memory, containing pointers and the argument
> * strings. We include one entry for the program name
> * because getopt expects it, and a NULL at the end
> * to simplify further parsing.
156c154,156
< av = safe_calloc(ac + 1, sizeof(char *));
---
> ac++; /* add 1 for the program name */
> av_size = (ac+1) * sizeof(char *) + l + 1;
> av = safe_calloc(av_size, 1);
159c159,160
< * Second, copy arguments from arg[] to av[]. For each one,
---
> * Init the argument pointer to the end of the array
> * and copy arguments from arg[] to av[]. For each one,
162c163,164
< for (ac = 1, i = j = 0; i < l; i++)
---
> av_p = (char *)&av[ac+1];
> for (ac = 1, i = j = 0; i < l; i++) {
166,167c168,171
< av[ac] = safe_calloc(i-j+1, 1);
< bcopy(arg+j, av[ac], i-j);
---
> bcopy(arg+j, av_p, i-j);
> av[ac] = av_p;
> av_p += i-j; /* the lenght of the string */
> *av_p++ = '\0';
170a175
> }
175c180
< int first, i, l;
---
> int first, i, l=0;
177c182,200
< av = safe_calloc(oldac, sizeof(char *));
---
> /*
> * Allocate the argument list structure as a single block
> * of memory, containing both pointers and the argument
> * strings. We include some space for the program name
> * because getopt expects it.
> * We add an extra pointer to the end of the array,
> * to make simpler further parsing.
> */
> for (i=0; i<oldac; i++)
> l += strlen(oldav[i]);
>
> av_size = (oldac+1) * sizeof(char *) + l + oldac;
> av = safe_calloc(av_size, 1);
>
> /*
> * Init the argument pointer to the end of the array
> * and copy arguments from arg[] to av[]
> */
> av_p = (char *)&av[oldac+1];
185c208
< av[ac] = safe_calloc(l+1, 1);
---
> av[ac] = av_p;
187,188c210,211
< strcat(av[ac]+l, oldav[first]);
< l += strlen(oldav[first]);
---
> strcat(av_p, oldav[first]);
> av_p += strlen(oldav[first]);
189a213
> *av_p++ = '\0';
197c221,227
< av[0] = strdup(oldav[0]); /* copy progname from the caller */
---
> /*
> * set the progname pointer to the original string
> * and terminate the array with null
> */
> av[0] = oldav[0];
> av[ac] = NULL;
>
201a232,260
> #ifdef EMULATE_SYSCTL /* sysctl emulation */
> if ( ac >= 2 && !strcmp(av[1], "sysctl")) {
> char *s;
> int i;
>
> if (ac != 3) {
> printf( "sysctl emulation usage:\n"
> " ipfw sysctl name[=value]\n"
> " ipfw sysctl -a\n");
> return 0;
> }
> s = index(av[2], '=');
> if (s == NULL) {
> s = !strcmp(av[2], "-a") ? NULL : av[2];
> sysctlbyname(s, NULL, NULL, NULL, 0);
> } else { /* ipfw sysctl x.y.z=value */
> /* assume an INT value, will extend later */
> if (s[1] == '\0') {
> printf("ipfw sysctl: missing value\n\n");
> return 0;
> }
> *s = '\0';
> i = strtol(s+1, NULL, 0);
> sysctlbyname(av[2], NULL, NULL, &i, sizeof(int));
> }
> return 0;
> }
> #endif
>
203d261
< save_ac = ac;
235c293
< free_args(save_ac, save_av);
---
> free(save_av);
276c334
< free_args(save_ac, save_av);
---
> free(save_av);
306a365,368
> else if (_substrcmp(*av, "flowset") == 0)
> co.do_pipe = 2;
> else if (_substrcmp(*av, "sched") == 0)
> co.do_pipe = 3;
338c400
< ipfw_add(ac, av);
---
> ipfw_add(av);
346c408
< ipfw_sets_handler(ac, av);
---
> ipfw_sets_handler(av);
350c412
< ipfw_sysctl_handler(ac, av, 1);
---
> ipfw_sysctl_handler(av, 1);
352c414
< ipfw_sysctl_handler(ac, av, 0);
---
> ipfw_sysctl_handler(av, 0);
359c421
< ipfw_delete(ac, av);
---
> ipfw_delete(av);
376c438
< free_args(save_ac, save_av);
---
> free(save_av);