socsvn commit: r268756 - soc2014/zkorchev/freebsd_head/bin/ls
zkorchev at FreeBSD.org
zkorchev at FreeBSD.org
Wed May 28 10:02:29 UTC 2014
Author: zkorchev
Date: Wed May 28 10:02:26 2014
New Revision: 268756
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=268756
Log:
first modified version of ls
Added:
soc2014/zkorchev/freebsd_head/bin/ls/sol.c
soc2014/zkorchev/freebsd_head/bin/ls/sol.h
Modified:
soc2014/zkorchev/freebsd_head/bin/ls/Makefile
soc2014/zkorchev/freebsd_head/bin/ls/extern.h
soc2014/zkorchev/freebsd_head/bin/ls/ls.c
soc2014/zkorchev/freebsd_head/bin/ls/ls.h
soc2014/zkorchev/freebsd_head/bin/ls/print.c
soc2014/zkorchev/freebsd_head/bin/ls/util.c
Modified: soc2014/zkorchev/freebsd_head/bin/ls/Makefile
==============================================================================
--- soc2014/zkorchev/freebsd_head/bin/ls/Makefile Wed May 28 09:06:36 2014 (r268755)
+++ soc2014/zkorchev/freebsd_head/bin/ls/Makefile Wed May 28 10:02:26 2014 (r268756)
@@ -4,9 +4,10 @@
.include <src.opts.mk>
PROG= ls
-SRCS= cmp.c ls.c print.c util.c
+SRCS= cmp.c ls.c print.c util.c sol.c
DPADD= ${LIBUTIL}
-LDADD= -lutil
+LDADD= -L/usr/local/lib -lutil -lyajl
+CFLAGS+= -DSOL_ON -I/usr/local/include -Wno-format-invalid-specifier
.if !defined(RELEASE_CRUNCH) && \
${MK_LS_COLORS} != no
Modified: soc2014/zkorchev/freebsd_head/bin/ls/extern.h
==============================================================================
--- soc2014/zkorchev/freebsd_head/bin/ls/extern.h Wed May 28 09:06:36 2014 (r268755)
+++ soc2014/zkorchev/freebsd_head/bin/ls/extern.h Wed May 28 10:02:26 2014 (r268756)
@@ -48,6 +48,10 @@
int printname(const char *);
void printscol(const DISPLAY *);
void printstream(const DISPLAY *);
+#if defined(SOL_ON)
+void printsollong(const DISPLAY *dp);
+void printsolshort(const DISPLAY *dp);
+#endif
void usage(void);
int prn_normal(const char *);
size_t len_octal(const char *, int);
Modified: soc2014/zkorchev/freebsd_head/bin/ls/ls.c
==============================================================================
--- soc2014/zkorchev/freebsd_head/bin/ls/ls.c Wed May 28 09:06:36 2014 (r268755)
+++ soc2014/zkorchev/freebsd_head/bin/ls/ls.c Wed May 28 10:02:26 2014 (r268756)
@@ -69,6 +69,7 @@
#include "ls.h"
#include "extern.h"
+#include "sol.h"
/*
* Upward approximation of the maximum number of characters needed to
@@ -99,6 +100,10 @@
static void (*printfcn)(const DISPLAY *);
static int (*sortfcn)(const FTSENT *, const FTSENT *);
+#if defined(SOL_ON)
+struct sol_stream sol_stream;
+#endif
+
long blocksize; /* block size units */
int termwidth = 80; /* default terminal width */
@@ -113,12 +118,15 @@
static int f_listdir; /* list actual directory, not contents */
static int f_listdot; /* list files beginning with . */
int f_longform; /* long listing format */
+#if defined(SOL_ON)
+ int f_solformat; /* structured output format */
+#endif
static int f_noautodot; /* do not automatically enable -A for root */
static int f_nofollow; /* don't follow symbolic link arguments */
int f_nonprint; /* show unprintables as ? */
static int f_nosort; /* don't sort output */
int f_notabs; /* don't use tab-separated multi-col output */
-static int f_numericonly; /* don't convert uid/gid to name */
+ int f_numericonly; /* don't convert uid/gid to name */
int f_octal; /* show unprintables as \xxx */
int f_octal_escape; /* like f_octal but use C escapes if possible */
static int f_recursive; /* ls subdirectories also */
@@ -186,7 +194,11 @@
if (getenv("LS_SAMESORT"))
f_samesort = 1;
while ((ch = getopt(argc, argv,
+#if defined(SOL_ON)
+ "1ABCD:FGHILOPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
+#else
"1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
+#endif
switch (ch) {
/*
* The -1, -C, -x and -l options all override each other so
@@ -210,6 +222,11 @@
f_longform = 0;
f_singlecol = 0;
break;
+#if defined(SOL_ON)
+ case 'O':
+ f_solformat = 1;
+ break;
+#endif
/* The -c, -u, and -U options override each other. */
case 'c':
f_statustime = 1;
@@ -361,6 +378,9 @@
if (!f_listdot && getuid() == (uid_t)0 && !f_noautodot)
f_listdot = 1;
+ // TODO zaro:
+ // make SOL_ON and COLORLS mutually exclusive
+
/* Enabling of colours is conditional on the environment. */
if (getenv("CLICOLOR") &&
(isatty(STDOUT_FILENO) || getenv("CLICOLOR_FORCE")))
@@ -465,19 +485,41 @@
}
/* Select a print function. */
- if (f_singlecol)
- printfcn = printscol;
- else if (f_longform)
- printfcn = printlong;
- else if (f_stream)
- printfcn = printstream;
+#if defined(SOL_ON)
+ if (f_solformat)
+ {
+ // TODO zaro compact and formatted output support, etc.
+ if (f_longform)
+ printfcn = printsollong;
+ else
+ printfcn = printsolshort;
+ }
else
- printfcn = printcol;
+#endif
+ {
+ if (f_singlecol)
+ printfcn = printscol;
+ else if (f_longform)
+ printfcn = printlong;
+ else if (f_stream)
+ printfcn = printstream;
+ else
+ printfcn = printcol;
+ }
+
+#if defined(SOL_ON)
+ if (f_solformat) sol_init(&sol_stream, SOL_JSON);
+#endif
if (argc)
traverse(argc, argv, fts_options);
else
traverse(1, dotav, fts_options);
+
+#if defined(SOL_ON)
+ if (f_solformat) sol_term(&sol_stream);
+#endif
+
exit(rval);
}
@@ -537,6 +579,7 @@
* a separator. If multiple arguments, precede each
* directory with its name.
*/
+#if !defined(SOL_ON)
if (output) {
putchar('\n');
(void)printname(p->fts_path);
@@ -546,6 +589,10 @@
puts(":");
output = 1;
}
+#else
+ (void)argc; // TODO remove this
+ // TODO zaro what to do on multiple directory listing?
+#endif
chp = fts_children(ftsp, ch_options);
display(p, chp, options);
@@ -588,6 +635,8 @@
char ngroup[STRBUF_SIZEOF(uid_t) + 1];
char nuser[STRBUF_SIZEOF(gid_t) + 1];
+ // TODO zaro: don't calculate widths when using SOL
+
needstats = f_inode || f_longform || f_size;
flen = 0;
btotal = 0;
Modified: soc2014/zkorchev/freebsd_head/bin/ls/ls.h
==============================================================================
--- soc2014/zkorchev/freebsd_head/bin/ls/ls.h Wed May 28 09:06:36 2014 (r268755)
+++ soc2014/zkorchev/freebsd_head/bin/ls/ls.h Wed May 28 10:02:26 2014 (r268756)
@@ -46,6 +46,9 @@
extern int f_label; /* show MAC label */
extern int f_inode; /* print inode */
extern int f_longform; /* long listing format */
+#if defined(SOL_ON)
+extern int f_solformat; /* structured output format */
+#endif
extern int f_octal; /* print unprintables in octal */
extern int f_octal_escape; /* like f_octal but use C escapes if possible */
extern int f_nonprint; /* show unprintables as ? */
@@ -58,11 +61,16 @@
extern int f_thousands; /* show file sizes with thousands separators */
extern char *f_timeformat; /* user-specified time format */
extern int f_notabs; /* don't use tab-separated multi-col output */
+extern int f_numericonly; /* don't convert uid/gid to name */
extern int f_type; /* add type character for non-regular files */
#ifdef COLORLS
extern int f_color; /* add type in color for non-regular files */
#endif
+#if defined(SOL_ON)
+extern struct sol_stream sol_stream;
+#endif
+
typedef struct {
FTSENT *list;
u_long btotal;
Modified: soc2014/zkorchev/freebsd_head/bin/ls/print.c
==============================================================================
--- soc2014/zkorchev/freebsd_head/bin/ls/print.c Wed May 28 09:06:36 2014 (r268755)
+++ soc2014/zkorchev/freebsd_head/bin/ls/print.c Wed May 28 10:02:26 2014 (r268756)
@@ -61,6 +61,7 @@
#include "ls.h"
#include "extern.h"
+#include "sol.h"
static int printaname(const FTSENT *, u_long, u_long);
static void printdev(size_t, dev_t);
@@ -354,7 +355,6 @@
static void
printdev(size_t width, dev_t dev)
{
-
(void)printf("%#*jx ", (u_int)width, (uintmax_t)dev);
}
@@ -365,6 +365,7 @@
static time_t now = 0;
const char *format;
static int d_first = -1;
+ size_t len;
if (d_first < 0)
d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
@@ -383,18 +384,37 @@
else
/* mmm dd yyyy || dd mmm yyyy */
format = d_first ? "%e %b %Y" : "%b %e %Y";
- strftime(longstring, sizeof(longstring), format, localtime(&ftime));
- fputs(longstring, stdout);
- fputc(' ', stdout);
+ len = strftime(longstring, sizeof(longstring), format, localtime(&ftime));
+
+#if defined(SOL_ON)
+ if (f_solformat)
+ {
+ sol_map_key(&sol_stream, "time", 4);
+ sol_map_string(&sol_stream, longstring, len);
+ }
+ else
+#endif
+ {
+ fputs(longstring, stdout);
+ fputc(' ', stdout);
+ }
}
static int
printtype(u_int mode)
{
+ char type;
if (f_slash) {
if ((mode & S_IFMT) == S_IFDIR) {
- (void)putchar('/');
+#if defined(SOL_ON)
+ if (f_solformat) {
+ sol_map_key(&sol_stream, "type", 4);
+ sol_map_string(&sol_stream, "/", 1);
+ }
+ else
+#endif
+ (void)putchar('/');
return (1);
}
return (0);
@@ -402,28 +422,37 @@
switch (mode & S_IFMT) {
case S_IFDIR:
- (void)putchar('/');
- return (1);
+ type = '/';
+ break;
case S_IFIFO:
- (void)putchar('|');
- return (1);
+ type = '|';
+ break;
case S_IFLNK:
- (void)putchar('@');
- return (1);
+ type = '@';
+ break;
case S_IFSOCK:
- (void)putchar('=');
- return (1);
+ type = '=';
+ break;
case S_IFWHT:
- (void)putchar('%');
- return (1);
- default:
+ type = '%';
break;
+ default:
+ if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
+ type = '*';
+ break;
+ }
+ return (0);
}
- if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
- (void)putchar('*');
- return (1);
+
+#if defined(SOL_ON)
+ if (f_solformat) {
+ sol_map_key(&sol_stream, "type", 4);
+ sol_map_string(&sol_stream, &type, 1);
}
- return (0);
+ else
+#endif
+ (void)putchar(type);
+ return (1);
}
#ifdef COLORLS
@@ -587,15 +616,25 @@
(void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
return;
}
- path[lnklen] = '\0';
- (void)printf(" -> ");
- (void)printname(path);
+
+#if defined(SOL_ON)
+ if (f_solformat)
+ {
+ sol_map_key(&sol_stream, "link", 4);
+ sol_map_string(&sol_stream, path, lnklen);
+ }
+ else
+#endif
+ {
+ path[lnklen] = '\0';
+ (void)printf(" -> ");
+ (void)printname(path);
+ }
}
static void
printsize(size_t width, off_t bytes)
{
-
if (f_humanval) {
/*
* Reserve one space before the size and allocate room for
@@ -684,3 +723,137 @@
buf[10] = '+';
acl_free(facl);
}
+
+#if defined(SOL_ON)
+void
+printsollong(const DISPLAY *dp)
+{
+ struct stat *sp;
+ FTSENT *p;
+ NAMES *np;
+ char buf[20];
+
+ /*if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
+ (f_longform || f_size)) {
+ (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
+ }*/
+
+ sol_array_start(&sol_stream);
+
+ for (p = dp->list; p; p = p->fts_link) {
+ if (IS_NOPRINT(p))
+ continue;
+
+ sol_map_start(&sol_stream);
+
+ sp = p->fts_statp;
+ if (f_inode) {
+ sol_map_key(&sol_stream, "inode", 5);
+ sol_map_integer(&sol_stream, sp->st_ino);
+ }
+ if (f_size) {
+ sol_map_key(&sol_stream, "bsize", 5);
+ sol_map_integer(&sol_stream, howmany(sp->st_blocks, blocksize));
+ }
+ strmode(sp->st_mode, buf);
+ aclmode(buf, p);
+ np = p->fts_pointer;
+
+ sol_map_key(&sol_stream, "mode", 4);
+ sol_map_string(&sol_stream, buf, strlen(buf));
+
+ sol_map_key(&sol_stream, "nlink", 5);
+ sol_map_integer(&sol_stream, sp->st_nlink);
+
+ if (f_numericonly) {
+ sol_map_key(&sol_stream, "uid", 3);
+ sol_map_integer(&sol_stream, sp->st_uid);
+ sol_map_key(&sol_stream, "gid", 3);
+ sol_map_integer(&sol_stream, sp->st_gid);
+ }
+ else {
+ sol_map_key(&sol_stream, "user", 4);
+ sol_map_string(&sol_stream, np->user, strlen(np->user));
+ sol_map_key(&sol_stream, "group", 5);
+ sol_map_string(&sol_stream, np->group, strlen(np->group));
+ }
+
+ if (f_flags) {
+ sol_map_key(&sol_stream, "flags", 5);
+ sol_map_string(&sol_stream, np->flags, strlen(np->flags));
+ }
+ if (f_label) {
+ sol_map_key(&sol_stream, "label", 5);
+ sol_map_string(&sol_stream, np->label, strlen(np->label));
+ }
+
+ if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) {
+ sol_map_key(&sol_stream, "dev", 3);
+ sol_map_integer(&sol_stream, sp->st_rdev); // TODO hex?
+ }
+ else {
+ if (f_humanval) {
+ /*
+ * Reserve one space before the size and allocate room for
+ * the trailing '\0'.
+ */
+ char buffer[HUMANVALSTR_LEN - 1 + 1];
+ size_t len = humanize_number(buffer, sizeof(buffer), (int64_t)sp->st_size,
+ "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
+
+ sol_map_key(&sol_stream, "hsize", 5);
+ sol_map_string(&sol_stream, buffer, len);
+ } else if (f_thousands) { /* with commas */
+ /*
+ * Reserve 4 bytes for each byte of the size.
+ */
+ char buffer[sizeof(sp->st_size) * 4 + 1];
+ /* This format assignment needed to work round gcc bug. */
+ const char *format = "%j'd ";
+ size_t len = snprintf(buffer, sizeof(buffer), format, sp->st_size);
+
+ sol_map_key(&sol_stream, "csize", 5);
+ sol_map_string(&sol_stream, buffer, len);
+ } else {
+ sol_map_key(&sol_stream, "size", 4);
+ sol_map_integer(&sol_stream, sp->st_size);
+ }
+ }
+
+ if (f_accesstime)
+ printtime(sp->st_atime);
+ else if (f_birthtime)
+ printtime(sp->st_birthtime);
+ else if (f_statustime)
+ printtime(sp->st_ctime);
+ else
+ printtime(sp->st_mtime);
+
+ sol_map_key(&sol_stream, "name", 4);
+ sol_map_string(&sol_stream, p->fts_name, p->fts_namelen);
+
+ if (f_type)
+ (void)printtype(sp->st_mode);
+ if (S_ISLNK(sp->st_mode))
+ printlink(p);
+
+ sol_map_end(&sol_stream);
+ }
+
+ sol_array_end(&sol_stream);
+}
+
+void
+printsolshort(const DISPLAY *dp)
+{
+ FTSENT *p;
+
+ sol_array_start(&sol_stream);
+ for (p = dp->list; p; p = p->fts_link) {
+ if (IS_NOPRINT(p))
+ continue;
+ sol_string(&sol_stream, p->fts_name, p->fts_namelen);
+ }
+ sol_array_end(&sol_stream);
+}
+#endif
Added: soc2014/zkorchev/freebsd_head/bin/ls/sol.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2014/zkorchev/freebsd_head/bin/ls/sol.c Wed May 28 10:02:26 2014 (r268756)
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 2014
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+
+#include "sol.h"
+
+//static struct sol_stream sol;
+
+// TODO error checks
+
+int sol_init(struct sol_stream *restrict stream, enum sol_format format)
+{
+ stream->f = format;
+ stream->ctx.g = yajl_gen_alloc(0);
+
+ //sol.f = format;
+ //sol.ctx.g = yajl_gen_alloc(0);
+
+ return 0;
+}
+
+void sol_term(struct sol_stream *restrict stream)
+{
+ const char *buffer;
+ size_t length;
+
+ switch (stream->f)
+ {
+ case SOL_JSON:
+ yajl_gen_get_buf(stream->ctx.g, (const unsigned char **)&buffer, &length);
+ write(1, buffer, length);
+ write(1, "\n", 1); // TODO change this
+ yajl_gen_clear(stream->ctx.g);
+ break;
+ }
+
+ yajl_gen_free(stream->ctx.g);
+
+ /*switch (sol.f)
+ {
+ case SOL_JSON:
+ yajl_gen_get_buf(sol.ctx.g, (const unsigned char **)&buffer, &length);
+ write(1, buffer, length);
+ write(1, "\n", 1); // TODO change this
+ yajl_gen_clear(sol.ctx.g);
+ break;
+ }
+
+ yajl_gen_free(sol.ctx.g);*/
+}
+
+int sol_array_start(struct sol_stream *restrict stream)
+{
+ yajl_gen_array_open(stream->ctx.g);
+
+ return 0;
+}
+
+int sol_array_end(struct sol_stream *restrict stream)
+{
+ yajl_gen_array_close(stream->ctx.g);
+
+ return 0;
+}
+
+int sol_string(struct sol_stream *restrict stream, const char *data, size_t length)
+{
+ // TODO ?handle special characters
+ yajl_gen_string(stream->ctx.g, (const unsigned char *)data, length);
+
+ return 0;
+}
+
+int sol_map_start(struct sol_stream *restrict stream)
+{
+ yajl_gen_map_open(stream->ctx.g);
+
+ return 0;
+}
+
+int sol_map_end(struct sol_stream *restrict stream)
+{
+ yajl_gen_map_close(stream->ctx.g);
+
+ return 0;
+}
+
+int sol_map_key(struct sol_stream *restrict stream, const char *key, size_t length)
+{
+ // TODO error if value is expected
+
+ // TODO ?handle special characters
+ yajl_gen_string(stream->ctx.g, (const unsigned char *)key, length);
+
+ return 0;
+}
+
+int sol_map_string(struct sol_stream *restrict stream, const char *value, size_t length)
+{
+ // TODO error if key is expected?
+
+ // TODO ?handle special characters
+ yajl_gen_string(stream->ctx.g, (const unsigned char *)value, length);
+
+ return 0;
+}
+
+int sol_map_integer(struct sol_stream *restrict stream, long long value)
+{
+ // TODO error if key is expected?
+
+ // TODO ?handle special characters
+ yajl_gen_integer(stream->ctx.g, value);
+
+ return 0;
+}
Added: soc2014/zkorchev/freebsd_head/bin/ls/sol.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2014/zkorchev/freebsd_head/bin/ls/sol.h Wed May 28 10:02:26 2014 (r268756)
@@ -0,0 +1,30 @@
+#include <yajl/yajl_gen.h> // libyajl
+
+enum sol_format
+{
+ SOL_JSON = 1,
+};
+
+struct sol_stream
+{
+ enum sol_format f;
+ union
+ {
+ yajl_gen g;
+ } ctx;
+};
+
+int sol_init(struct sol_stream *restrict stream, enum sol_format format);
+void sol_term(struct sol_stream *restrict stream);
+
+int sol_array_start(struct sol_stream *restrict stream);
+int sol_array_end(struct sol_stream *restrict stream);
+
+int sol_string(struct sol_stream *restrict stream, const char *data, size_t length);
+
+int sol_map_start(struct sol_stream *restrict stream);
+int sol_map_end(struct sol_stream *restrict stream);
+
+int sol_map_key(struct sol_stream *restrict stream, const char *key, size_t length);
+int sol_map_string(struct sol_stream *restrict stream, const char *value, size_t length);
+int sol_map_integer(struct sol_stream *restrict stream, long long value);
Modified: soc2014/zkorchev/freebsd_head/bin/ls/util.c
==============================================================================
--- soc2014/zkorchev/freebsd_head/bin/ls/util.c Wed May 28 09:06:36 2014 (r268755)
+++ soc2014/zkorchev/freebsd_head/bin/ls/util.c Wed May 28 10:02:26 2014 (r268756)
@@ -224,11 +224,14 @@
usage(void)
{
(void)fprintf(stderr,
-#ifdef COLORLS
- "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
-#else
- "usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
+ "usage: ls [-ABCF"
+#if defined(COLORLS)
+ "G"
#endif
- " [file ...]\n");
+ "HIL"
+#if defined(SOL_ON)
+ "O"
+#endif
+ "PRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format] [file ...]\n");
exit(1);
}
More information about the svn-soc-all
mailing list