Page MenuHomeFreeBSD

D21434.id61349.diff
No OneTemporary

D21434.id61349.diff

Index: sbin/ping6/Makefile
===================================================================
--- sbin/ping6/Makefile
+++ sbin/ping6/Makefile
@@ -4,6 +4,7 @@
PACKAGE=runtime
PROG= ping6
+SRCS= ping6.c options.c
MAN= ping6.8
CFLAGS+=-DIPSEC -DKAME_SCOPEID
Index: sbin/ping6/options.h
===================================================================
--- /dev/null
+++ sbin/ping6/options.h
@@ -0,0 +1,70 @@
+#ifndef OPTIONS_H
+#define OPTIONS_H 1
+
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netipsec/ipsec.h>
+
+#include <stdbool.h>
+
+#define F_FLOOD 0x0001
+#define F_INTERVAL 0x0002
+#define F_PINGFILLED 0x0008
+#define F_QUIET 0x0010
+#define F_RROUTE 0x0020
+#define F_SO_DEBUG 0x0040
+#define F_VERBOSE 0x0100
+#ifdef IPSEC
+#ifdef IPSEC_POLICY_IPSEC
+#define F_POLICY 0x0400
+#else
+#define F_AUTHHDR 0x0200
+#define F_ENCRYPT 0x0400
+#endif /*IPSEC_POLICY_IPSEC*/
+#endif /*IPSEC*/
+#define F_NODEADDR 0x0800
+#define F_FQDN 0x1000
+#define F_INTERFACE 0x2000
+#define F_SRCADDR 0x4000
+#define F_HOSTNAME 0x10000
+#define F_FQDNOLD 0x20000
+#define F_NIGROUP 0x40000
+#define F_SUPTYPES 0x80000
+#define F_NOMINMTU 0x100000
+#define F_ONCE 0x200000
+#define F_AUDIBLE 0x400000
+#define F_MISSED 0x800000
+#define F_DONTFRAG 0x1000000
+#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
+#define F_WAITTIME 0x2000000
+
+struct option {
+ char *arg;
+ unsigned int count;
+};
+
+/* Options that are counted or have an argument. */
+struct options_processed {
+ struct option addrtype;
+ struct option gateway;
+ struct option hoplimit;
+ struct option interface;
+ struct option interval;
+ struct option ipsec_policy;
+ struct option nigroup;
+ struct option packet_count;
+ struct option packet_size;
+ struct option pattern;
+ struct option preload;
+ struct option sock_buff_size;
+ struct option source_address;
+ struct option timeout;
+ struct option use_min_mtu;
+ struct option wait_time;
+};
+
+bool options_parse(int argc, char *argv[],
+ struct options_processed *const opts, u_int *const flags);
+
+#endif
Index: sbin/ping6/options.c
===================================================================
--- /dev/null
+++ sbin/ping6/options.c
@@ -0,0 +1,164 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+#include <unistd.h>
+
+#include "options.h"
+
+#ifndef IPSEC
+#define ADDOPTS
+#else
+#ifdef IPSEC_POLICY_IPSEC
+#define ADDOPTS "P:"
+#else
+#define ADDOPTS "ZE"
+#endif /*IPSEC_POLICY_IPSEC*/
+#endif
+
+bool
+options_parse(int argc, char *argv[],
+ struct options_processed *const opts, u_int *const flags)
+{
+ int ch;
+
+ memset(opts, 0, sizeof(*opts));
+
+ while ((ch = getopt(argc, argv,
+ "k:b:c:DdfHe:m:I:i:l:unNop:qaAS:s:OvyYW:t:" ADDOPTS)) != -1) {
+ struct option *current_option = NULL;
+
+ switch (ch) {
+ case 'k':
+ *flags &= ~F_NOUSERDATA;
+ *flags |= F_NODEADDR;
+ current_option = &opts->addrtype;
+ break;
+ case 'b':
+#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
+ current_option = &opts->sock_buff_size;
+ break;
+#else
+ errx(1, "-b option ignored: SO_SNDBUF/SO_RCVBUF socket"
+ "options not supported");
+ /*NOTREACHED*/
+#endif
+ case 'c':
+ current_option = &opts->packet_count;
+ break;
+ case 'D':
+ *flags |= F_DONTFRAG;
+ break;
+ case 'd':
+ *flags |= F_SO_DEBUG;
+ break;
+ case 'f':
+ *flags |= F_FLOOD;
+ break;
+ case 'e':
+ current_option = &opts->gateway;
+ break;
+ case 'H':
+ *flags |= F_HOSTNAME;
+ break;
+ case 'm':
+ current_option = &opts->hoplimit;
+ break;
+ case 'I':
+ *flags |= F_INTERFACE;
+ current_option = &opts->interface;
+ break;
+ case 'i':
+ *flags |= F_INTERVAL;
+ current_option = &opts->interval;
+ break;
+ case 'l':
+ current_option = &opts->preload;
+ break;
+ case 'u':
+#ifdef IPV6_USE_MIN_MTU
+ current_option = &opts->use_min_mtu;
+ break;
+#else
+ errx(1, "-u is not supported on this platform");
+ /*NOTREACHED*/
+#endif
+ case 'n':
+ *flags &= ~F_HOSTNAME;
+ break;
+ case 'N':
+ *flags |= F_NIGROUP;
+ current_option = &opts->nigroup;
+ break;
+ case 'o':
+ *flags |= F_ONCE;
+ break;
+ case 'p':
+ *flags |= F_PINGFILLED;
+ current_option = &opts->pattern;
+ break;
+ case 'q':
+ *flags |= F_QUIET;
+ break;
+ case 'a':
+ *flags |= F_AUDIBLE;
+ break;
+ case 'A':
+ *flags |= F_MISSED;
+ break;
+ case 'S':
+ *flags |= F_SRCADDR;
+ current_option = &opts->source_address;
+ break;
+ case 's':
+ current_option = &opts->packet_size;
+ break;
+ case 'O':
+ *flags &= ~F_NOUSERDATA;
+ *flags |= F_SUPTYPES;
+ break;
+ case 'v':
+ *flags |= F_VERBOSE;
+ break;
+ case 'y':
+ *flags &= ~F_NOUSERDATA;
+ *flags |= F_FQDN;
+ break;
+ case 'Y':
+ *flags &= ~F_NOUSERDATA;
+ *flags |= F_FQDNOLD;
+ break;
+ case 'W':
+ *flags |= F_WAITTIME;
+ current_option = &opts->wait_time;
+ break;
+ case 't':
+ current_option = &opts->timeout;
+ break;
+#ifdef IPSEC
+#ifdef IPSEC_POLICY_IPSEC
+ case 'P':
+ *flags |= F_POLICY;
+ current_option = &opts->ipsec_policy;
+ break;
+#else
+ case 'Z':
+ *flags |= F_AUTHHDR;
+ break;
+ case 'E':
+ *flags |= F_ENCRYPT;
+ break;
+#endif /*IPSEC_POLICY_IPSEC*/
+#endif /*IPSEC*/
+ default:
+ return (false);
+ }
+
+ if (current_option != NULL) {
+ current_option->arg = optarg;
+ (current_option->count)++;
+ }
+ }
+
+ return (true);
+}
Index: sbin/ping6/ping6.c
===================================================================
--- sbin/ping6/ping6.c
+++ sbin/ping6/ping6.c
@@ -142,6 +142,8 @@
#include <md5.h>
+#include "options.h"
+
struct tv32 {
u_int32_t tv32_sec;
u_int32_t tv32_nsec;
@@ -168,36 +170,6 @@
#define CLR(bit) (A(bit) &= (~B(bit)))
#define TST(bit) (A(bit) & B(bit))
-#define F_FLOOD 0x0001
-#define F_INTERVAL 0x0002
-#define F_PINGFILLED 0x0008
-#define F_QUIET 0x0010
-#define F_RROUTE 0x0020
-#define F_SO_DEBUG 0x0040
-#define F_VERBOSE 0x0100
-#ifdef IPSEC
-#ifdef IPSEC_POLICY_IPSEC
-#define F_POLICY 0x0400
-#else
-#define F_AUTHHDR 0x0200
-#define F_ENCRYPT 0x0400
-#endif /*IPSEC_POLICY_IPSEC*/
-#endif /*IPSEC*/
-#define F_NODEADDR 0x0800
-#define F_FQDN 0x1000
-#define F_INTERFACE 0x2000
-#define F_SRCADDR 0x4000
-#define F_HOSTNAME 0x10000
-#define F_FQDNOLD 0x20000
-#define F_NIGROUP 0x40000
-#define F_SUPTYPES 0x80000
-#define F_NOMINMTU 0x100000
-#define F_ONCE 0x200000
-#define F_AUDIBLE 0x400000
-#define F_MISSED 0x800000
-#define F_DONTFRAG 0x1000000
-#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
-#define F_WAITTIME 0x2000000
static u_int options;
#define IN6LEN sizeof(struct in6_addr)
@@ -299,8 +271,9 @@
struct sockaddr_in6 from, *sin6;
struct addrinfo hints, *res;
struct sigaction si_sa;
+ struct options_processed opts;
int cc, i;
- int almost_done, ch, hold, packlen, preload, optval, error;
+ int almost_done, hold, packlen, preload, optval, error;
int nig_oldmcprefix = -1;
u_char *datap;
char *e, *target, *ifname = NULL, *gateway = NULL;
@@ -341,268 +314,186 @@
alarmtimeout = preload = 0;
datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
capdns = capdns_setup();
-#ifndef IPSEC
-#define ADDOPTS
-#else
-#ifdef IPSEC_POLICY_IPSEC
-#define ADDOPTS "P:"
-#else
-#define ADDOPTS "ZE"
-#endif /*IPSEC_POLICY_IPSEC*/
-#endif
- while ((ch = getopt(argc, argv,
- "k:b:c:DdfHe:m:I:i:l:unNop:qaAS:s:OvyYW:t:" ADDOPTS)) != -1) {
-#undef ADDOPTS
- switch (ch) {
- case 'k':
- {
- char *cp;
-
- options &= ~F_NOUSERDATA;
- options |= F_NODEADDR;
- for (cp = optarg; *cp != '\0'; cp++) {
- switch (*cp) {
- case 'a':
- naflags |= NI_NODEADDR_FLAG_ALL;
- break;
- case 'c':
- case 'C':
- naflags |= NI_NODEADDR_FLAG_COMPAT;
- break;
- case 'l':
- case 'L':
- naflags |= NI_NODEADDR_FLAG_LINKLOCAL;
- break;
- case 's':
- case 'S':
- naflags |= NI_NODEADDR_FLAG_SITELOCAL;
- break;
- case 'g':
- case 'G':
- naflags |= NI_NODEADDR_FLAG_GLOBAL;
- break;
- case 'A': /* experimental. not in the spec */
+
+ if (!options_parse(argc, argv, &opts, &options))
+ usage();
+ /* NOTREACHED */
+
+ if ((options & F_NODEADDR) != 0) {
+ char *cp;
+
+ for (cp = opts.addrtype.arg; *cp != '\0'; cp++) {
+ switch (*cp) {
+ case 'a':
+ naflags |= NI_NODEADDR_FLAG_ALL;
+ break;
+ case 'c':
+ case 'C':
+ naflags |= NI_NODEADDR_FLAG_COMPAT;
+ break;
+ case 'l':
+ case 'L':
+ naflags |= NI_NODEADDR_FLAG_LINKLOCAL;
+ break;
+ case 's':
+ case 'S':
+ naflags |= NI_NODEADDR_FLAG_SITELOCAL;
+ break;
+ case 'g':
+ case 'G':
+ naflags |= NI_NODEADDR_FLAG_GLOBAL;
+ break;
+ case 'A': /* experimental. not in the spec */
#ifdef NI_NODEADDR_FLAG_ANYCAST
- naflags |= NI_NODEADDR_FLAG_ANYCAST;
- break;
+ naflags |= NI_NODEADDR_FLAG_ANYCAST;
+ break;
#else
- errx(1,
-"-a A is not supported on the platform");
- /*NOTREACHED*/
+ errx(1,
+ "-a A is not supported on the platform");
+ /*NOTREACHED*/
#endif
- default:
- usage();
- /*NOTREACHED*/
- }
+ default:
+ usage();
+ /*NOTREACHED*/
}
- break;
}
- case 'b':
-#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
- errno = 0;
- e = NULL;
- lsockbufsize = strtoul(optarg, &e, 10);
- sockbufsize = (int)lsockbufsize;
- if (errno || !*optarg || *e ||
- lsockbufsize > INT_MAX)
- errx(1, "invalid socket buffer size");
-#else
+ }
+ if (opts.sock_buff_size.count != 0) {
+ errno = 0;
+ e = NULL;
+ lsockbufsize = strtoul(opts.sock_buff_size.arg, &e, 10);
+ sockbufsize = (int)lsockbufsize;
+ if (errno || !*opts.sock_buff_size.arg || *e ||
+ lsockbufsize > INT_MAX)
+ errx(1, "invalid socket buffer size");
+ }
+ if (opts.packet_count.count != 0) {
+ npackets = strtol(opts.packet_count.arg, &e, 10);
+ if (npackets <= 0 || *opts.packet_count.arg == '\0' ||
+ *e != '\0')
errx(1,
-"-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported");
-#endif
- break;
- case 'c':
- npackets = strtol(optarg, &e, 10);
- if (npackets <= 0 || *optarg == '\0' || *e != '\0')
- errx(1,
- "illegal number of packets -- %s", optarg);
- break;
- case 'D':
- options |= F_DONTFRAG;
- break;
- case 'd':
- options |= F_SO_DEBUG;
- break;
- case 'f':
- if (getuid()) {
- errno = EPERM;
- errx(1, "Must be superuser to flood ping");
- }
- options |= F_FLOOD;
- setbuf(stdout, (char *)NULL);
- break;
- case 'e':
- gateway = optarg;
- break;
- case 'H':
- options |= F_HOSTNAME;
- break;
- case 'm': /* hoplimit */
- hoplimit = strtol(optarg, &e, 10);
- if (*optarg == '\0' || *e != '\0')
- errx(1, "illegal hoplimit %s", optarg);
- if (255 < hoplimit || hoplimit < -1)
- errx(1,
- "illegal hoplimit -- %s", optarg);
- break;
- case 'I':
- ifname = optarg;
- options |= F_INTERFACE;
+ "illegal number of packets -- %s",
+ opts.packet_count.arg);
+ }
+ if ((options & F_FLOOD) != 0) {
+ if (getuid()) {
+ errno = EPERM;
+ errx(1, "Must be superuser to flood ping");
+ }
+ setbuf(stdout, (char *)NULL);
+ }
+ if (opts.gateway.count != 0)
+ gateway = opts.gateway.arg;
+ if (opts.hoplimit.count != 0) {
+ hoplimit = strtol(opts.hoplimit.arg, &e, 10);
+ if (*opts.hoplimit.arg == '\0' || *e != '\0')
+ errx(1, "illegal hoplimit %s", opts.hoplimit.arg);
+ if (255 < hoplimit || hoplimit < -1)
+ errx(1,
+ "illegal hoplimit -- %s", opts.hoplimit.arg);
+ }
+ if ((options & F_INTERFACE) != 0) {
+ ifname = opts.interface.arg;
#ifndef USE_SIN6_SCOPE_ID
- usepktinfo++;
+ usepktinfo += opts.interface.count;
#endif
- break;
- case 'i': /* wait between sending packets */
- t = strtod(optarg, &e);
- if (*optarg == '\0' || *e != '\0')
- errx(1, "illegal timing interval %s", optarg);
- if (t < 1 && getuid()) {
- errx(1, "%s: only root may use interval < 1s",
- strerror(EPERM));
- }
- intvl.tv_sec = (time_t)t;
- intvl.tv_nsec =
- (long)((t - intvl.tv_sec) * 1000000000);
- if (intvl.tv_sec < 0)
- errx(1, "illegal timing interval %s", optarg);
- /* less than 1/hz does not make sense */
- if (intvl.tv_sec == 0 && intvl.tv_nsec < 1000) {
- warnx("too small interval, raised to .000001");
- intvl.tv_nsec = 1000;
- }
- options |= F_INTERVAL;
- break;
- case 'l':
- if (getuid()) {
- errno = EPERM;
- errx(1, "Must be superuser to preload");
- }
- preload = strtol(optarg, &e, 10);
- if (preload < 0 || *optarg == '\0' || *e != '\0')
- errx(1, "illegal preload value -- %s", optarg);
- break;
- case 'u':
-#ifdef IPV6_USE_MIN_MTU
- mflag++;
- break;
-#else
- errx(1, "-%c is not supported on this platform", ch);
- /*NOTREACHED*/
-#endif
- case 'n':
- options &= ~F_HOSTNAME;
- break;
- case 'N':
- options |= F_NIGROUP;
- nig_oldmcprefix++;
- break;
- case 'o':
- options |= F_ONCE;
- break;
- case 'p': /* fill buffer with user pattern */
- options |= F_PINGFILLED;
- fill((char *)datap, optarg);
- break;
- case 'q':
- options |= F_QUIET;
- break;
- case 'a':
- options |= F_AUDIBLE;
- break;
- case 'A':
- options |= F_MISSED;
- break;
- case 'S':
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */
- hints.ai_family = AF_INET6;
- hints.ai_socktype = SOCK_RAW;
- hints.ai_protocol = IPPROTO_ICMPV6;
+ }
+ if ((options & F_INTERVAL) != 0) {
+ t = strtod(opts.interval.arg, &e);
+ if (*opts.interval.arg == '\0' || *e != '\0')
+ errx(1, "illegal timing interval %s", opts.interval.arg);
+ if (t < 1 && getuid()) {
+ errx(1, "%s: only root may use interval < 1s",
+ strerror(EPERM));
+ }
+ intvl.tv_sec = (time_t)t;
+ intvl.tv_nsec =
+ (long)((t - intvl.tv_sec) * 1000000000);
+ if (intvl.tv_sec < 0)
+ errx(1, "illegal timing interval %s", opts.interval.arg);
+ /* less than 1/hz does not make sense */
+ if (intvl.tv_sec == 0 && intvl.tv_nsec < 1000) {
+ warnx("too small interval, raised to .000001");
+ intvl.tv_nsec = 1000;
+ }
+ }
+ if (opts.preload.count != 0) {
+ if (getuid()) {
+ errno = EPERM;
+ errx(1, "Must be superuser to preload");
+ }
+ preload = strtol(opts.preload.arg, &e, 10);
+ if (preload < 0 || *opts.preload.arg == '\0' || *e != '\0')
+ errx(1, "illegal preload value -- %s",
+ opts.preload.arg);
+ }
+ mflag += opts.use_min_mtu.count;
+ nig_oldmcprefix += opts.nigroup.count;
+ if ((options & F_PINGFILLED) != 0)
+ fill((char *)datap, opts.pattern.arg);
+ if ((options & F_SRCADDR) != 0) {
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_RAW;
+ hints.ai_protocol = IPPROTO_ICMPV6;
- error = cap_getaddrinfo(capdns, optarg, NULL, &hints, &res);
- if (error) {
- errx(1, "invalid source address: %s",
- gai_strerror(error));
- }
- /*
- * res->ai_family must be AF_INET6 and res->ai_addrlen
- * must be sizeof(src).
- */
- memcpy(&src, res->ai_addr, res->ai_addrlen);
- srclen = res->ai_addrlen;
- freeaddrinfo(res);
- options |= F_SRCADDR;
- break;
- case 's': /* size of packet to send */
- datalen = strtol(optarg, &e, 10);
- if (datalen <= 0 || *optarg == '\0' || *e != '\0')
- errx(1, "illegal datalen value -- %s", optarg);
- if (datalen > MAXDATALEN) {
- errx(1,
- "datalen value too large, maximum is %d",
- MAXDATALEN);
- }
- break;
- case 'O':
- options &= ~F_NOUSERDATA;
- options |= F_SUPTYPES;
- break;
- case 'v':
- options |= F_VERBOSE;
- break;
- case 'y':
- options &= ~F_NOUSERDATA;
- options |= F_FQDN;
- break;
- case 'Y':
- options &= ~F_NOUSERDATA;
- options |= F_FQDNOLD;
- break;
- case 'W':
- t = strtod(optarg, &e);
- if (*e || e == optarg || t > (double)INT_MAX)
- err(EX_USAGE, "invalid timing interval: `%s'",
- optarg);
- options |= F_WAITTIME;
- waittime = (int)t;
- break;
- case 't':
- alarmtimeout = strtoul(optarg, &e, 0);
- if ((alarmtimeout < 1) || (alarmtimeout == ULONG_MAX))
- errx(EX_USAGE, "invalid timeout: `%s'",
- optarg);
- if (alarmtimeout > MAXALARM)
- errx(EX_USAGE, "invalid timeout: `%s' > %d",
- optarg, MAXALARM);
- alarm((int)alarmtimeout);
- break;
+ error = cap_getaddrinfo(capdns, opts.source_address.arg, NULL,
+ &hints, &res);
+ if (error) {
+ errx(1, "invalid source address: %s",
+ gai_strerror(error));
+ }
+ /*
+ * res->ai_family must be AF_INET6 and res->ai_addrlen
+ * must be sizeof(src).
+ */
+ memcpy(&src, res->ai_addr, res->ai_addrlen);
+ srclen = res->ai_addrlen;
+ freeaddrinfo(res);
+ }
+ if (opts.packet_size.count != 0) {
+ datalen = strtol(opts.packet_size.arg, &e, 10);
+ if (datalen <= 0 || *opts.packet_size.arg == '\0' || *e != '\0')
+ errx(1, "illegal datalen value -- %s",
+ opts.packet_size.arg);
+ if (datalen > MAXDATALEN) {
+ errx(1,
+ "datalen value too large, maximum is %d",
+ MAXDATALEN);
+ }
+ }
+ if ((options & F_WAITTIME) != 0) {
+ t = strtod(opts.wait_time.arg, &e);
+ if (*e || e == opts.wait_time.arg || t > (double)INT_MAX)
+ err(EX_USAGE, "invalid timing interval: `%s'",
+ opts.wait_time.arg);
+ waittime = (int)t;
+ }
+ if (opts.timeout.count != 0) {
+ alarmtimeout = strtoul(opts.timeout.arg, &e, 0);
+ if ((alarmtimeout < 1) || (alarmtimeout == ULONG_MAX))
+ errx(EX_USAGE, "invalid timeout: `%s'",
+ opts.timeout.arg);
+ if (alarmtimeout > MAXALARM)
+ errx(EX_USAGE, "invalid timeout: `%s' > %d",
+ opts.timeout.arg, MAXALARM);
+ alarm((int)alarmtimeout);
+ }
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
- case 'P':
- options |= F_POLICY;
- if (!strncmp("in", optarg, 2)) {
- if ((policy_in = strdup(optarg)) == NULL)
- errx(1, "strdup");
- } else if (!strncmp("out", optarg, 3)) {
- if ((policy_out = strdup(optarg)) == NULL)
- errx(1, "strdup");
- } else
- errx(1, "invalid security policy");
- break;
-#else
- case 'Z':
- options |= F_AUTHHDR;
- break;
- case 'E':
- options |= F_ENCRYPT;
- break;
+ if ((options & F_POLICY) != 0) {
+ if (!strncmp("in", opts.ipsec_policy.arg, 2)) {
+ if ((policy_in = strdup(opts.ipsec_policy.arg)) == NULL)
+ errx(1, "strdup");
+ } else if (!strncmp("out", opts.ipsec_policy.arg, 3)) {
+ if ((policy_out = strdup(opts.ipsec_policy.arg)) == NULL)
+ errx(1, "strdup");
+ } else
+ errx(1, "invalid security policy");
+ }
#endif /*IPSEC_POLICY_IPSEC*/
#endif /*IPSEC*/
- default:
- usage();
- /*NOTREACHED*/
- }
- }
argc -= optind;
argv += optind;

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 20, 4:59 AM (16 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29999918
Default Alt Text
D21434.id61349.diff (18 KB)

Event Timeline