[hackers] [PATCH] Implement -p for xargs(1)
This patch implements prompting for user input before executing commands. Input is read from /dev/tty as per posix 2013 spec. --- README | 2 +- xargs.1 | 6 +- xargs.c | 28 +--- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/README b/README index 68a921c..e8b16b0 100644 --- a/README +++ b/README @@ -99,7 +99,7 @@ The following tools are implemented: #*|o wc . =*|x which . =*|x whoami . -=*|o xargs (-p) +=*|o xargs . =*|x yes . The complement of sbase is ubase[1] which is Linux-specific and diff --git a/xargs.1 b/xargs.1 index 47cc194..1015756 100644 --- a/xargs.1 +++ b/xargs.1 @@ -6,7 +6,7 @@ .Nd construct argument lists and execute command .Sh SYNOPSIS .Nm -.Op Fl rtx +.Op Fl prtx .Op Fl E Ar eofstr .Op Fl n Ar num .Op Fl s Ar num @@ -36,6 +36,10 @@ newlines, may be escaped by a backslash. Use at most .Ar num arguments per command line. +.It Fl p +Prompt before running each command. Run the command only if the response +starts with 'y' or 'Y'. Implies +.Fl t . .It Fl r Do not run the command if there are no arguments. Normally the command is executed at least once even if there are no arguments. diff --git a/xargs.c b/xargs.c index 0d5dd53..5b3d214 100644 --- a/xargs.c +++ b/xargs.c @@ -26,7 +26,7 @@ static size_t argbsz; static size_t argbpos; static size_t maxargs = 0; static intnerrors = 0; -static intrflag = 0, nflag = 0, tflag = 0, xflag = 0; +static intnflag = 0, pflag = 0, rflag = 0, tflag = 0, xflag = 0; static char *argb; static char *cmd[NARGS]; static char *eofstr; @@ -162,15 +162,34 @@ spawn(void) int savederrno; int first = 1; char **p; + FILE *tty; + int ch, savedch; - if (tflag) { + if (pflag || tflag) { for (p = cmd; *p; p++) { if (!first) fputc(' ', stderr); fputs(*p, stderr); first = 0; } + } + + if (!pflag && tflag) fputc('\n', stderr); + + if (pflag) { + fputs(" ?...", stderr); + + tty = fopen("/dev/tty", "r"); + if (!tty) + return; + ch = savedch = fgetc(tty); + while (ch != EOF && ch != '\n') + ch = getc(tty); + fclose(tty); + + if (savedch != 'y' && savedch != 'Y') + return; } switch (fork()) { @@ -188,7 +207,7 @@ spawn(void) static void usage(void) { - eprintf("usage: %s [-rtx] [-E eofstr] [-n num] [-s num] " + eprintf("usage: %s [-prtx] [-E eofstr] [-n num] [-s num] " "[cmd [arg ...]]\n", argv0); } @@ -210,6 +229,9 @@ main(int argc, char *argv[]) nflag = 1; maxargs = estrtonum(EARGF(usage()), 1, MIN(SIZE_MAX, LLONG_MAX)); break; + case 'p': + pflag = 1; + break; case 'r': rflag = 1; break; -- 2.1.4
Re: [hackers] [sbase][PATCH] Add -d, -f and -i flags to sort(1)
Here's the patch with updated manpage and usage(). --- sort.1 | 8 +++- sort.c | 63 ++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/sort.1 b/sort.1 index 8fd5ee9..52c73dc 100644 --- a/sort.1 +++ b/sort.1 @@ -6,7 +6,7 @@ .Nd sort lines .Sh SYNOPSIS .Nm -.Op Fl Cbcmnru +.Op Fl Cbcdfimnru .Op Fl o Ar outfile .Op Fl t Ar delim .Op Fl k Ar key ... @@ -35,6 +35,12 @@ The same as .Fl C except that when disorder is detected, a message is written to stderr indicating the location of the disorder. +.It Fl d +Skip non-whitespace and non-alphanumeric characters. +.It Fl f +Ignore letter case when sorting. +.It FL i +Skip non-printable characters. .It Fl k Ar key Specify a key definition of the form .Sm off diff --git a/sort.c b/sort.c index 0761d0f..4870f79 100644 --- a/sort.c +++ b/sort.c @@ -23,6 +23,9 @@ enum { MOD_STARTB = 1 << 1, MOD_ENDB = 1 << 2, MOD_R = 1 << 3, + MOD_D = 1 << 4, + MOD_F = 1 << 5, + MOD_I = 1 << 6, }; static TAILQ_HEAD(kdhead, keydef) kdhead = TAILQ_HEAD_INITIALIZER(kdhead); @@ -116,6 +119,44 @@ columns(char *line, const struct keydef *kd, char **col, size_t *colsiz) } static int +skipmodcmp(const char *s1, const char *s2, int flags) +{ + Rune r1, r2; + + do { + s1 += chartorune(&r1, s1); + s2 += chartorune(&r2, s2); + + if (flags & MOD_D && flags & MOD_I) { + while (*s1 && ((!isblankrune(r1) && !isalnumrune(r1)) || + (!isprintrune(r1 + s1 += chartorune(&r1, s1); + while (*s2 && ((!isblankrune(r2) && !isalnumrune(r2)) || + (!isprintrune(r2 + s2 += chartorune(&r2, s2); + } + else if (flags & MOD_D) { + while (*s1 && !isblankrune(r1) && !isalnumrune(r1)) + s1 += chartorune(&r1, s1); + while (*s2 && !isblankrune(r2) && !isalnumrune(r2)) + s2 += chartorune(&r2, s2); + } + else if (flags & MOD_I) { + while (*s1 && !isprintrune(r1)) + s1 += chartorune(&r1, s1); + while (*s2 && !isprintrune(r2)) + s2 += chartorune(&r2, s2); + } + if (flags & MOD_F) { + r1 = toupperrune(r1); + r2 = toupperrune(r2); + } + } while (r1 && r1 == r2); + + return r1 - r2; +} + +static int linecmp(const char **a, const char **b) { int res = 0; @@ -135,6 +176,8 @@ linecmp(const char **a, const char **b) x = strtold(col1, NULL); y = strtold(col2, NULL); res = (x < y) ? -1 : (x > y); + } else if (kd->flags & (MOD_D | MOD_F | MOD_I)) { + res = skipmodcmp(col1, col2, kd->flags); } else { res = strcmp(col1, col2); } @@ -178,6 +221,15 @@ parse_flags(char **s, int *flags, int bflag) case 'b': *flags |= bflag; break; + case 'd': + *flags |= MOD_D; + break; + case 'f': + *flags |= MOD_F; + break; + case 'i': + *flags |= MOD_I; + break; case 'n': *flags |= MOD_N; break; @@ -240,7 +292,7 @@ addkeydef(char *kdstr, int flags) static void usage(void) { - enprintf(2, "usage: %s [-Cbcmnru] [-o outfile] [-t delim] " + enprintf(2, "usage: %s [-Cbcdfimnru] [-o outfile] [-t delim] " "[-k def]... [file ...]\n", argv0); } @@ -263,6 +315,15 @@ main(int argc, char *argv[]) case 'c': cflag = 1; break; + case 'd': + global_flags |= MOD_D; + break; + case 'f': + global_flags |= MOD_F; + break; + case 'i': + global_flags |= MOD_I; + break; case 'k': addkeydef(EARGF(usage()), global_flags); break; -- 2.1.4
Re: [hackers] [sbase] tar: don't change modes for hardlinks on extraction || Eivind Uggedal
On Mon, Feb 15, 2016 at 12:08:16PM -0600, Brad Barden wrote: > > tar: don't change modes for hardlinks on extraction > > > > Changing timestamps, modes and ownership of hardlinks > > makes no sense. > > See also my earlier email on this subject (Dec 6). I'm glad it's fixed. Yes I totally missed that patch at the time.
Re: [hackers] [sbase] tar: don't change modes for hardlinks on extraction || Eivind Uggedal
> tar: don't change modes for hardlinks on extraction > > Changing timestamps, modes and ownership of hardlinks > makes no sense. See also my earlier email on this subject (Dec 6). I'm glad it's fixed.
Re: [hackers][vis][PATCH] Handle quote matching in its own function
On Mon, Feb 15, 2016 at 05:50:12PM +0100, Marc André Tanner wrote: > On Mon, Feb 15, 2016 at 04:01:48PM +0100, Silvan Jegen wrote: > > [...] > > What would be more interesting is to add a way to define motions and > text objects in Lua. Integration with the LPeg based lexers should > then be relatively easy ... That would mean that you would call out to lua each time you want to use one of these motions/objects, if I understand correctly. Writing a grammar for matching these things in LPeg should be possible. Do you think it would be worth implementing these motions/text objects in LPeg? The main advantage I can see with this approach is that you could create robust grammars for these motions/objects using LPeg instead of doing some ad-hoc parsing like I did in this patch. Cheers, Silvan
Re: [hackers][vis][PATCH] Handle quote matching in its own function
On Mon, Feb 15, 2016 at 04:01:48PM +0100, Silvan Jegen wrote: > Unlike other paired characters neither of the quote types allow for the > search for the closing occurrence to be optimised because there is no > directionality implied. This means theoretically we always have to start > from the beginning of a file to check whether all the quotes until the > occurrence of the one in question have been properly closed before we > can say which one is the closing occurrence of the quote. > > This is the justification for introducing this new function that > duplicates some code. Instead of searching from the beginning of a > file we start our search for the corresponding quote character at > an arbitrarily chosen offset of 500 bytes before the occurrence in > question. > --- > Consider this to be a bug report for a pet peeve of mine. When you > position the cursor at line 797 of vis.c in vis on the quote after > __DATE__ the quote highlighting will be wrong. The text motion for > "select inner quote" is wrong as well but I think it makes more sense > there to select the text between the quotes instead of selecting nothing > only because the quotes are not actually corresponding to each other. > > This patch fixes the highlighting case but it may be overkill for such > marginal issue. Yes it is. The highlighting feature is just a convenience which should work most of the time. As you noted making this work correctly for all cases would need integration with a lexer. Simply counting a couple of quotes like it is currently done will only work for the common case. Things which are not handled correctly include: - escaped quotes as in "some \"string\"" - quotes can also appear on their own, an example from your patch (case '"':). For single quotes this is frequently the case with english comments. What would be more interesting is to add a way to define motions and text objects in Lua. Integration with the LPeg based lexers should then be relatively easy ... -- Marc André Tanner >< http://www.brain-dump.org/ >< GPG key: 10C93617
[hackers][vis][PATCH] Handle quote matching in its own function
Unlike other paired characters neither of the quote types allow for the search for the closing occurrence to be optimised because there is no directionality implied. This means theoretically we always have to start from the beginning of a file to check whether all the quotes until the occurrence of the one in question have been properly closed before we can say which one is the closing occurrence of the quote. This is the justification for introducing this new function that duplicates some code. Instead of searching from the beginning of a file we start our search for the corresponding quote character at an arbitrarily chosen offset of 500 bytes before the occurrence in question. --- Consider this to be a bug report for a pet peeve of mine. When you position the cursor at line 797 of vis.c in vis on the quote after __DATE__ the quote highlighting will be wrong. The text motion for "select inner quote" is wrong as well but I think it makes more sense there to select the text between the quotes instead of selecting nothing only because the quotes are not actually corresponding to each other. This patch fixes the highlighting case but it may be overkill for such marginal issue. text-motions.c | 36 +++- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/text-motions.c b/text-motions.c index 298d4ac..20218fd 100644 --- a/text-motions.c +++ b/text-motions.c @@ -607,6 +607,28 @@ size_t text_bracket_match(Text *txt, size_t pos) { return text_bracket_match_symbol(txt, pos, NULL); } +size_t text_bracket_match_quote(Text *txt, size_t pos, char q) { + size_t lastqpos = pos; + size_t prevpos = pos > 500 ? pos - 500 : 0; + char c; + bool closed = true; + + Iterator it = text_iterator_get(txt, prevpos); + text_iterator_byte_get(&it, &c); + do { + if (it.pos == pos && !closed) + return lastqpos; + if (c == q && it.pos != pos) { + if (it.pos > pos) + return it.pos; + lastqpos = it.pos; + closed = !closed; + } + } while (text_iterator_byte_next(&it, &c)); + + return pos; /* no match found */ +} + size_t text_bracket_match_symbol(Text *txt, size_t pos, const char *symbols) { int direction, count = 1; char search, current, c; @@ -627,19 +649,7 @@ size_t text_bracket_match_symbol(Text *txt, size_t pos, const char *symbols) { case '>': search = '<'; direction = -1; break; case '"': case '`': - case '\'': { - char special[] = " \n)}]>.,:;"; - search = current; - direction = 1; - if (text_iterator_byte_next(&it, &c)) { - /* if a single or double quote is followed by -* a special character, search backwards */ - if (memchr(special, c, sizeof(special))) - direction = -1; - text_iterator_byte_prev(&it, NULL); - } - break; - } + case '\'': return text_bracket_match_quote(txt, pos, current); default: return pos; } -- 2.7.1
[hackers] [sbase] tar: make remove(3) non-fatal when extracting || Eivind Uggedal
commit ae528208910cdfa1d71ad82de9f65b8c32b23397 Author: Eivind Uggedal AuthorDate: Mon Feb 15 14:00:00 2016 + Commit: sin CommitDate: Mon Feb 15 14:27:10 2016 + tar: make remove(3) non-fatal when extracting Handles special cases like: . diff --git a/tar.c b/tar.c index 10b2024..71719b0 100644 --- a/tar.c +++ b/tar.c @@ -259,7 +259,7 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ]) if (!mflag && ((mtime = strtol(h->mtime, &p, 8)) < 0 || *p != '\0')) eprintf("strtol %s: invalid number\n", h->mtime); if (remove(fname) < 0 && errno != ENOENT) - eprintf("remove %s:", fname); + weprintf("remove %s:", fname); tmp = estrdup(fname); mkdirp(dirname(tmp));
[hackers] [PATCH] [slock] Revert "No need for usage()"
This reverts most of commit a6dc051e3744ce5b14c54d2d246d3e8258207e76 and fixes some related stuff: - keep spelling fixes from original commit - make -h and -v also work when followed by more arguments - any unknown flag prints usage - fix output of -v to display "slock: version 1.3" instead of "slock: slock-1.3" --- slock.1 | 16 +--- slock.c | 17 +++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/slock.1 b/slock.1 index 467194d..0ef3e15 100644 --- a/slock.1 +++ b/slock.1 @@ -3,17 +3,27 @@ slock \- simple X screen locker .SH SYNOPSIS .B slock -.RB [ -.IR cmd -] +.RB [ \-v +| +.IR cmd ] .SH DESCRIPTION .B slock is an X screen locker. If provided, .IR cmd is executed after the screen has been locked. +.SH OPTIONS +.TP +.B \-v +prints version information to stdout, then exits. .SH EXAMPLES $ slock /usr/sbin/s2ram .SH CUSTOMIZATION .B slock can be customized by creating a custom config.h and (re)compiling the source code. This keeps it fast, secure and simple. +.SH AUTHORS +See the LICENSE file for the authors. +.SH LICENSE +See the LICENSE file for the terms of redistribution. +.SH BUGS +Please report them. diff --git a/slock.c b/slock.c index 2aa395e..c9cdee2 100644 --- a/slock.c +++ b/slock.c @@ -273,15 +273,28 @@ lockscreen(Display *dpy, int screen) return NULL; } +static void +usage(void) +{ + fprintf(stderr, "usage: slock [-v|POST_LOCK_CMD]\n"); + exit(1); +} + int -main(int argc, char **argv) -{ +main(int argc, char **argv) { #ifndef HAVE_BSD_AUTH const char *pws; #endif Display *dpy; int screen; + if ((argc >= 2) && !strcmp("-v", argv[1])) + die("version %s, © 2006-2016 slock engineers\n", VERSION); + + /* treat first argument starting with a '-' as option */ + if ((argc >= 2) && argv[1][0] == '-') + usage(); + #ifdef __linux__ dontkillme(); #endif -- 2.4.10
[hackers] [PATCH] [slock] revert using argv0 and minor fixup
- use hardcoded "slock" instead of argv[0] - add "slock: " to fprintf calls, where it was missing - revert `argc--, argv++` shifting --- slock.c | 15 ++- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/slock.c b/slock.c index a0ffed0..2aa395e 100644 --- a/slock.c +++ b/slock.c @@ -46,15 +46,14 @@ static Bool failure = False; static Bool rr; static int rrevbase; static int rrerrbase; -static char *argv0; static void die(const char *errstr, ...) { va_list ap; + fputs("slock: ", stderr); va_start(ap, errstr); - fprintf(stderr, "%s: ", argv0); vfprintf(stderr, errstr, ap); va_end(ap); exit(1); @@ -256,7 +255,7 @@ lockscreen(Display *dpy, int screen) usleep(1000); } if (!len) { - fprintf(stderr, "unable to grab mouse pointer for screen %d\n", screen); + fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", screen); } else { for (len = 1000; len; len--) { if (XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) { @@ -266,7 +265,7 @@ lockscreen(Display *dpy, int screen) } usleep(1000); } - fprintf(stderr, "unable to grab keyboard for screen %d\n", screen); + fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", screen); } /* grabbing one of the inputs failed */ running = 0; @@ -283,8 +282,6 @@ main(int argc, char **argv) Display *dpy; int screen; - argv0 = argv[0], argc--, argv++; - #ifdef __linux__ dontkillme(); #endif @@ -317,11 +314,11 @@ main(int argc, char **argv) return 1; } - if (argc >= 1 && fork() == 0) { + if (argc >= 2 && fork() == 0) { if (dpy) close(ConnectionNumber(dpy)); - execvp(argv[0], argv); - die("execvp %s failed: %s\n", argv[0], strerror(errno)); + execvp(argv[1], argv+1); + die("execvp %s failed: %s\n", argv[1], strerror(errno)); } /* Everything is now blank. Now wait for the correct password. */ -- 2.4.10
Re: [hackers] [slock] No need for usage() || FRIGN
On 14 February 2016 at 02:00, wrote: > commit a6dc051e3744ce5b14c54d2d246d3e8258207e76 > Author: FRIGN > AuthorDate: Sun Feb 14 01:48:48 2016 +0100 > Commit: FRIGN > CommitDate: Sun Feb 14 02:00:14 2016 +0100 > > No need for usage() > > There are 2 arguments why -v and -h are broken: > > 1) if you are running off git, -v will show the last stable >release, effectively making this option useless. >people running stable versions leave open an attack surface >this way in case there are vulnerabilities found. >99% of the people are also using package managers to keep >their software up to date, instead of running $TOOL -v to >check how old it is. > 2) -h is a sad excuse for not just looking at the manual page >(man 1 slock). Given we accept a post_lock_command, we can't >be as liberal and just intercept certain flags. > > I changed the manpage to reflect this change. I agree with 20h here, I heavily dislike removing -v and -h. It is good style to have those options in, at least in the past the suckless tools reliably listed their usage and version using this approach. The point here is, that very basic tools shouldn't have a man page, if the usage is rather simple. usage() is also to prefer as a quick way to check the right argument sequence at an occasion if you know the command line tool in theory. It's quicker than reading a man page. Also, in very limited embedded environments, you might end up without man pages at hand, and at least on such hosts it is very good to have a quick usage() reference to check for. Same applies for the version. Removing this information reduces the code for no good reason imho. BR, Anselm
Re: [hackers] [slock] Use argv0 instead of passing "slock:" to die every time || FRIGN
On 14 February 2016 at 02:14, wrote: > commit b02c4d452a7942d4be3c69e6f98dafd35a2e4e78 > Author: FRIGN > AuthorDate: Sun Feb 14 02:13:54 2016 +0100 > Commit: FRIGN > CommitDate: Sun Feb 14 02:13:54 2016 +0100 > > Use argv0 instead of passing "slock:" to die every time > > diff --git a/slock.c b/slock.c > index 4531f95..a0ffed0 100644 > --- a/slock.c > +++ b/slock.c > @@ -46,6 +46,7 @@ static Bool failure = False; > static Bool rr; > static int rrevbase; > static int rrerrbase; > +static char *argv0; > > static void > die(const char *errstr, ...) > @@ -53,6 +54,7 @@ die(const char *errstr, ...) > va_list ap; > > va_start(ap, errstr); > + fprintf(stderr, "%s: ", argv0); I don't like this approach. Code should always output the original name of the program, not the name of the process. When someone renames slock into foo, then I cannot assert anymore what it really is all about, if I query ./foo -v or ./foo -h I'm for reverting to the original approach here -- btw. same for all other suckless tools. BR, Anselm
Re: [hackers] [slock] No need for usage() || FRIGN
On Mon, Feb 15, 2016 at 11:51:00AM +0100, FRIGN wrote: > On Mon, 15 Feb 2016 11:47:30 +0100 > Markus Teich wrote: > > Hey Markus, > > > then we would have to assume users don't have *any* binary starting with a > > `-` > > that they might want to run after locking, but I can still live with that. > > that was actually my consideration. Given -h is documented nowhere, it might > be surprising for users, especially for people starting slock with dmenu > (where it just silently "fails" by printing the usage). you will notice that slock didn't start immediately, not to mention that if it failed once it will continue to fail because of a misconfiguration.
Re: [hackers] [slock] No need for usage() || FRIGN
On Mon, Feb 15, 2016 at 11:47:30AM +0100, Markus Teich wrote: > Dimitris Papastamos wrote: > > On Mon, Feb 15, 2016 at 11:35:11AM +0100, FRIGN wrote: > > > My considerations here were that it was quite arbitrary not to document > > > -h, > > > given we "allow" a command to be passed to slock as second + further > > > arguments. However, I respect your stances on this and will revert it, > > > but > > > also document -h in the manpage. > > > > The right way to do this is to consider -h an invalid option. For invalid > > options always print usage. > > Heyho, > > then we would have to assume users don't have *any* binary starting with a `-` > that they might want to run after locking, but I can still live with that. for this unlikely scenario, they can use an absolute path or a relative one starting with ./
Re: [hackers] [slock] No need for usage() || FRIGN
On Mon, 15 Feb 2016 11:47:30 +0100 Markus Teich wrote: Hey Markus, > then we would have to assume users don't have *any* binary starting with a `-` > that they might want to run after locking, but I can still live with that. that was actually my consideration. Given -h is documented nowhere, it might be surprising for users, especially for people starting slock with dmenu (where it just silently "fails" by printing the usage). Cheers FRIGN -- FRIGN
Re: [hackers] [slock] No need for usage() || FRIGN
Dimitris Papastamos wrote: > On Mon, Feb 15, 2016 at 11:35:11AM +0100, FRIGN wrote: > > My considerations here were that it was quite arbitrary not to document -h, > > given we "allow" a command to be passed to slock as second + further > > arguments. However, I respect your stances on this and will revert it, but > > also document -h in the manpage. > > The right way to do this is to consider -h an invalid option. For invalid > options always print usage. Heyho, then we would have to assume users don't have *any* binary starting with a `-` that they might want to run after locking, but I can still live with that. --Markus
Re: [hackers] [slock] Use argv0 instead of passing "slock:" to die every time || FRIGN
On Mon, Feb 15, 2016 at 11:37:15AM +0100, FRIGN wrote: > On Mon, 15 Feb 2016 10:34:15 + > Dimitris Papastamos wrote: > > Hey Dimitris, > > > Yes this pattern is used in sbase. There is no point however > > replicating it to other projects. > > so how would you approach this? If slock was only a main()-function, > one could've thought to just pass argv[0] to each call of die. > But it is not. > > Would your approach be to just set argv0 as argv[0] and carry on > without modifying argc, argv? > I was surprised this idiomatic one-liner has received such opposition. The code was fine as it was.
Re: [hackers] [slock] Use argv0 instead of passing "slock:" to die every time || FRIGN
FRIGN wrote: > we came up with this in sbase/ubase as an idiomatic way to set argv0 > for tools that don't use arg.h. > We need argv0 here because I moved the prepending of the argv[0] into > die(), and thus we need to store the argv0 in a global variable. Heyho frign, sure, but I asked why you would *shift* argc and argv right at the start of main. If someone reads just the fork exec part and assumes argv[0] is `slock`, this is confusing and forcing the reader to search for the place where argv is changed. --Markus
Re: [hackers] [slock] No need for usage() || FRIGN
On Mon, Feb 15, 2016 at 11:35:11AM +0100, FRIGN wrote: > On Mon, 15 Feb 2016 11:15:50 +0100 > Markus Teich wrote: > > Hey Markus, > > > I have to agree with Christoph here. People running off git can just use > > the rev > > id they are using. I don't get what you mean with the attack surface > > sentence. > > it was a rather weak argument by me, but still a possibility. Say somebody is > running > an older version of slock, an "attacker" could probe it out. > However, after further consideration, this could also be done by examining the > behaviour of the problem while locked to identify an older version. Nevermind > then. > > > I think we can ignore the possibility of someone wanting to call his custom > > `-h` > > or `-v` binary when the screen is locked and revert the commit. > > My considerations here were that it was quite arbitrary not to document -h, > given > we "allow" a command to be passed to slock as second + further arguments. > However, I respect your stances on this and will revert it, but also document > -h > in the manpage. The right way to do this is to consider -h an invalid option. For invalid options always print usage.
Re: [hackers] [slock] Use argv0 instead of passing "slock:" to die every time || FRIGN
On Mon, 15 Feb 2016 10:34:15 + Dimitris Papastamos wrote: Hey Dimitris, > Yes this pattern is used in sbase. There is no point however > replicating it to other projects. so how would you approach this? If slock was only a main()-function, one could've thought to just pass argv[0] to each call of die. But it is not. Would your approach be to just set argv0 as argv[0] and carry on without modifying argc, argv? I was surprised this idiomatic one-liner has received such opposition. Cheers FRIGN -- FRIGN
Re: [hackers] [slock] No need for usage() || FRIGN
On Mon, 15 Feb 2016 11:15:50 +0100 Markus Teich wrote: Hey Markus, > I have to agree with Christoph here. People running off git can just use the > rev > id they are using. I don't get what you mean with the attack surface sentence. it was a rather weak argument by me, but still a possibility. Say somebody is running an older version of slock, an "attacker" could probe it out. However, after further consideration, this could also be done by examining the behaviour of the problem while locked to identify an older version. Nevermind then. > I think we can ignore the possibility of someone wanting to call his custom > `-h` > or `-v` binary when the screen is locked and revert the commit. My considerations here were that it was quite arbitrary not to document -h, given we "allow" a command to be passed to slock as second + further arguments. However, I respect your stances on this and will revert it, but also document -h in the manpage. Cheers FRIGN -- FRIGN
Re: [hackers] [slock] Use argv0 instead of passing "slock:" to die every time || FRIGN
On Mon, Feb 15, 2016 at 11:30:59AM +0100, FRIGN wrote: > On Mon, 15 Feb 2016 11:22:08 +0100 > Markus Teich wrote: > > Hey Markus, > > > why this `argc--, argv++` shenanigans? I think it's more confusing rather > > than > > helping. > > we came up with this in sbase/ubase as an idiomatic way to set argv0 > for tools that don't use arg.h. > We need argv0 here because I moved the prepending of the argv[0] into > die(), and thus we need to store the argv0 in a global variable. Yes this pattern is used in sbase. There is no point however replicating it to other projects.
Re: [hackers] [slock] Use argv0 instead of passing "slock:" to die every time || FRIGN
On Mon, 15 Feb 2016 11:22:08 +0100 Markus Teich wrote: Hey Markus, > why this `argc--, argv++` shenanigans? I think it's more confusing rather than > helping. we came up with this in sbase/ubase as an idiomatic way to set argv0 for tools that don't use arg.h. We need argv0 here because I moved the prepending of the argv[0] into die(), and thus we need to store the argv0 in a global variable. Cheers FRIGN -- FRIGN
[hackers] [sbase] tar: support -f - for stdin/out || Eivind Uggedal
commit e13f571d119cdd6fedef3f748a264bb143cecc70 Author: Eivind Uggedal AuthorDate: Mon Feb 15 09:48:32 2016 + Commit: sin CommitDate: Mon Feb 15 10:20:12 2016 + tar: support -f - for stdin/out diff --git a/tar.1 b/tar.1 index 8394fdb..7cc34b4 100644 --- a/tar.1 +++ b/tar.1 @@ -32,7 +32,8 @@ before beginning. .It Fl f Ar file Set .Ar file -as input | output archive instead of stdin | stdout. +as input | output archive instead of stdin | stdout. If '-', +stdin | stdout is used. .It Fl m Do not preserve modification time. .It Fl t diff --git a/tar.c b/tar.c index b4ba2d6..10b2024 100644 --- a/tar.c +++ b/tar.c @@ -550,7 +550,7 @@ main(int argc, char *argv[]) switch (mode) { case 'c': tarfd = 1; - if (file) { + if (file && *file != '-') { tarfd = open(file, O_WRONLY | O_TRUNC | O_CREAT, 0644); if (tarfd < 0) eprintf("open %s:", file); @@ -571,7 +571,7 @@ main(int argc, char *argv[]) case 't': case 'x': tarfd = 0; - if (file) { + if (file && *file != '-') { tarfd = open(file, O_RDONLY); if (tarfd < 0) eprintf("open %s:", file);
Re: [hackers] [slock] Use argv0 instead of passing "slock:" to die every time || FRIGN
g...@suckless.org wrote: > + argv0 = argv[0], argc--, argv++; > - if (argc >= 2 && fork() == 0) { > + if (argc >= 1 && fork() == 0) { > if (dpy) > close(ConnectionNumber(dpy)); > - execvp(argv[1], argv+1); > - die("slock: execvp %s failed: %s\n", argv[1], strerror(errno)); > + execvp(argv[0], argv); > + die("execvp %s failed: %s\n", argv[0], strerror(errno)); Heyho frign, why this `argc--, argv++` shenanigans? I think it's more confusing rather than helping. --Markus
Re: [hackers] [slock] No need for usage() || FRIGN
Christoph Lohmann wrote: > On Sun, 14 Feb 2016 10:46:52 +0100 g...@suckless.org wrote: > > 1) if you are running off git, -v will show the last stable > >release, effectively making this option useless. > >people running stable versions leave open an attack surface > >this way in case there are vulnerabilities found. > >99% of the people are also using package managers to keep > >their software up to date, instead of running $TOOL -v to > >check how old it is. > > 2) -h is a sad excuse for not just looking at the manual page > >(man 1 slock). Given we accept a post_lock_command, we can't > >be as liberal and just intercept certain flags. > > This is suckless software, which should be useful even without a manpage or a > package manager. Heyho, I have to agree with Christoph here. People running off git can just use the rev id they are using. I don't get what you mean with the attack surface sentence. I think we can ignore the possibility of someone wanting to call his custom `-h` or `-v` binary when the screen is locked and revert the commit. --Markus
[hackers] [sbase] ls: only display directory headers when more than one directory is specified || tty0
commit b107489bf2cda579ca53551206270b9eee80c059 Author: tty0 AuthorDate: Mon Feb 15 09:56:11 2016 + Commit: sin CommitDate: Mon Feb 15 09:59:09 2016 + ls: only display directory headers when more than one directory is specified diff --git a/ls.c b/ls.c index 3611a87..b132a3c 100644 --- a/ls.c +++ b/ls.c @@ -52,6 +52,7 @@ static int Uflag = 0; static int uflag = 0; static int first = 1; static char sort = 0; +static size_t ds = 0; static void ls(const char *, const struct entry *, int); @@ -269,7 +270,7 @@ lsdir(const char *path, const struct entry *dir) if (!Uflag) qsort(ents, n, sizeof(*ents), entcmp); - if (path[0] || dir->name[0] != '.') + if (ds > 1 && (path[0] || dir->name[0] != '.')) printf("%s:\n", dir->name); for (i = 0; i < n; i++) output(&ents[i]); @@ -360,7 +361,7 @@ int main(int argc, char *argv[]) { struct entry ent, *dents, *fents; - size_t i, ds, fs; + size_t i, fs; ARGBEGIN { case '1':
[hackers] [sbase] Makefile: add sbase-box-uninstall rule || Mattias Andrée
commit d9c85a2d79cd0cc9e1c338a28bedbcfa39182ac6 Author: Mattias Andrée AuthorDate: Mon Feb 15 09:47:16 2016 + Commit: sin CommitDate: Mon Feb 15 09:49:54 2016 + Makefile: add sbase-box-uninstall rule Signed-off-by: Mattias Andrée diff --git a/Makefile b/Makefile index 19501a4..57be12a 100644 --- a/Makefile +++ b/Makefile @@ -250,9 +250,12 @@ sbase-box-install: sbase-box cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN) mv -f $(DESTDIR)$(MANPREFIX)/man1/xinstall.1 $(DESTDIR)$(MANPREFIX)/man1/install.1 +sbase-box-uninstall: uninstall + cd $(DESTDIR)$(PREFIX)/bin && rm -f sbase-box + clean: rm -f $(BIN) $(OBJ) $(LIB) sbase-box sbase-$(VERSION).tar.gz rm -f confstr_l.h limits_l.h sysconf_l.h pathconf_l.h .PHONY: - all install uninstall dist sbase-box sbase-box-install clean + all install uninstall dist sbase-box sbase-box-install sbase-box-uninstall clean
[hackers] [sbase] Fix uninstall target || sin
commit 6ca2a046f8f680131046fc152031a899db4182d2 Author: sin AuthorDate: Mon Feb 15 09:44:27 2016 + Commit: sin CommitDate: Mon Feb 15 09:44:27 2016 + Fix uninstall target The installed tool is called install not xinstall. diff --git a/Makefile b/Makefile index 9f473dd..19501a4 100644 --- a/Makefile +++ b/Makefile @@ -206,7 +206,7 @@ install: all mv -f $(DESTDIR)$(MANPREFIX)/man1/xinstall.1 $(DESTDIR)$(MANPREFIX)/man1/install.1 uninstall: - cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) [ xinstall + cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) [ install cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN) dist: clean
[hackers] [sbase] Add Eivind Uggedal to LICENSE || sin
commit 835020b4bf3279c9bfccd45202699f37508b062f Author: sin AuthorDate: Mon Feb 15 09:42:30 2016 + Commit: sin CommitDate: Mon Feb 15 09:42:59 2016 + Add Eivind Uggedal to LICENSE diff --git a/LICENSE b/LICENSE index 2a26979..1ff215b 100644 --- a/LICENSE +++ b/LICENSE @@ -60,3 +60,4 @@ Authors/contributors include: © 2015 Dionysis Grigoropoulos © 2015 Wolfgang Corcoran-Mathe © 2016 Mattias Andrée +© 2016 Eivind Uggedal
[hackers] [sbase] install: bsd make compatibility || Eivind Uggedal
commit 2f128ab050b39ced864fa24c6afc0eb6e6225f55 Author: Eivind Uggedal AuthorDate: Mon Feb 15 09:44:35 2016 +0100 Commit: sin CommitDate: Mon Feb 15 09:41:58 2016 + install: bsd make compatibility diff --git a/Makefile b/Makefile index b17d19f..9f473dd 100644 --- a/Makefile +++ b/Makefile @@ -103,7 +103,6 @@ BIN =\ getconf\ grep\ head\ - install.out\ join\ hostname\ kill\ @@ -162,13 +161,14 @@ BIN =\ which\ whoami\ xargs\ + xinstall\ yes LIBUTFOBJ = $(LIBUTFSRC:.c=.o) LIBUTILOBJ = $(LIBUTILSRC:.c=.o) OBJ = $(BIN:=.o) $(LIBUTFOBJ) $(LIBUTILOBJ) -SRC = $(foreach F,$(BIN:.out=),$(F:=.c)) -MAN = $(foreach F,$(BIN:.out=),$(F:=.1)) +SRC = $(BIN:=.c) +MAN = $(BIN:=.1) all: $(BIN) @@ -179,9 +179,6 @@ $(OBJ): $(HDR) config.mk .o: $(CC) $(LDFLAGS) -o $@ $< $(LIB) -install.out: install.o - $(CC) $(LDFLAGS) -o $@ $^ $(LIB) - .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< @@ -201,14 +198,15 @@ confstr_l.h limits_l.h sysconf_l.h pathconf_l.h: getconf.sh install: all mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin - mv -f $(DESTDIR)$(PREFIX)/bin/install.out $(DESTDIR)$(PREFIX)/bin/install - cd $(DESTDIR)$(PREFIX)/bin && ln -f test [ && chmod 755 $(BIN:.out=) + cd $(DESTDIR)$(PREFIX)/bin && ln -f test [ && chmod 755 $(BIN) + mv -f $(DESTDIR)$(PREFIX)/bin/xinstall $(DESTDIR)$(PREFIX)/bin/install mkdir -p $(DESTDIR)$(MANPREFIX)/man1 for m in $(MAN); do sed "s/^\.Os sbase/.Os sbase $(VERSION)/g" < "$$m" > $(DESTDIR)$(MANPREFIX)/man1/"$$m"; done cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN) + mv -f $(DESTDIR)$(MANPREFIX)/man1/xinstall.1 $(DESTDIR)$(MANPREFIX)/man1/install.1 uninstall: - cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN:.out=) [ + cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) [ xinstall cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN) dist: clean @@ -231,6 +229,7 @@ sbase-box: $(LIB) $(SRC) for f in $(SRC); do echo "int $${f%.c}_main(int, char **);"; done >> build/$@.c echo 'int main(int argc, char *argv[]) { char *s = basename(argv[0]);' >> build/$@.c echo 'if(!strcmp(s,"sbase-box")) { argc--; argv++; s = basename(argv[0]); } if(0) ;' >> build/$@.c + echo "else if (!strcmp(s, \"install\")) return xinstall_main(argc, argv);" >> build/$@.c echo "else if (!strcmp(s, \"[\")) return test_main(argc, argv);" >> build/$@.c for f in $(SRC); do echo "else if(!strcmp(s, \"$${f%.c}\")) return $${f%.c}_main(argc, argv);"; done >> build/$@.c echo 'else { fputs("[ ", stdout);' >> build/$@.c @@ -243,11 +242,13 @@ sbase-box-install: sbase-box mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f sbase-box $(DESTDIR)$(PREFIX)/bin chmod 755 $(DESTDIR)$(PREFIX)/bin/sbase-box - for f in $(BIN:.out=); do ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/"$$f"; done + for f in $(BIN); do ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/"$$f"; done ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/[ + mv -f $(DESTDIR)$(PREFIX)/bin/xinstall $(DESTDIR)$(PREFIX)/bin/install mkdir -p $(DESTDIR)$(MANPREFIX)/man1 for m in $(MAN); do sed "s/^\.Os sbase/.Os sbase $(VERSION)/g" < "$$m" > $(DESTDIR)$(MANPREFIX)/man1/"$$m"; done cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN) + mv -f $(DESTDIR)$(MANPREFIX)/man1/xinstall.1 $(DESTDIR)$(MANPREFIX)/man1/install.1 clean: rm -f $(BIN) $(OBJ) $(LIB) sbase-box sbase-$(VERSION).tar.gz diff --git a/install.1 b/install.1 deleted file mode 100644 index 99eff81..000 --- a/install.1 +++ /dev/null @@ -1,88 +0,0 @@ -.Dd 2016-02-12 -.Dt INSTALL 1 -.Os sbase -.Sh NAME -.Nm install -.Nd copy files and set attributes -.Sh SYNOPSIS -.Nm -.Op Fl g Ar group -.Op Fl o Ar owner -.Op Fl m Ar mode -.Po -.Fl d Ar dir ... -| -.Op Fl sD -.Po -.Fl t Ar dest -.Ar source ... -| -.Ar source ... -.Ar dest -.Pc -.Pc -.Sh DESCRIPTION -.Nm -copies -.Ar source -to -.Ar dest . -If more than one -.Ar source -is given -.Ar dest -has to be a directory. -.Nm -can also change the attributes of the copies. -.Sh OPTIONS -.Bl -tag -width Ds -.It Fl d -Create the directories -.Ar dir . -.It Fl D -Create missing parent directories to -.Ar dest . -If -.Fl t -is used, the -.Ar dest -itself is also created if missing. -.It Fl g Ar group -Change the installed files' group to -.Ar group . -This may be a group name or a group identifier. -.It Fl m Ar mode -Change the file modes. Both numerical and symbolic -values are supported. See -.Xr chmod 1 -for the syntex. -Default mode 0755. If a file has the mode 0644 and -is copied with -.It Fl o Ar owner -Change the instal
[hackers] [sbase] tar: don't change modes for hardlinks on extraction || Eivind Uggedal
commit 3c2f8b0cfa592bbe31ee4270cf275acfd261cd71 Author: Eivind Uggedal AuthorDate: Mon Feb 15 08:03:17 2016 + Commit: sin CommitDate: Mon Feb 15 09:41:58 2016 + tar: don't change modes for hardlinks on extraction Changing timestamps, modes and ownership of hardlinks makes no sense. diff --git a/tar.c b/tar.c index 10b2e30..b4ba2d6 100644 --- a/tar.c +++ b/tar.c @@ -325,6 +325,9 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ]) close(fd); } + if (h->type == HARDLINK) + return 0; + times[0].tv_sec = times[1].tv_sec = mtime; times[0].tv_nsec = times[1].tv_nsec = 0; if (!mflag && utimensat(AT_FDCWD, fname, times, AT_SYMLINK_NOFOLLOW) < 0)
[hackers] [sbase] New command with corresponding man page. Includes the flags: || Mattias Andrée
commit db952ed18cbd0ea2cee89be43277db186b20f356 Author: Mattias Andrée AuthorDate: Fri Feb 12 14:33:09 2016 +0100 Commit: sin CommitDate: Mon Feb 15 09:41:58 2016 + New command with corresponding man page. Includes the flags: -s strip binary -d create directory -D create missing directories -t DIR target directory -m MODE permission bits -o USER set owner -g GROUP set group Installed files are copied, and default mode is 755. Signed-off-by: Mattias Andrée diff --git a/Makefile b/Makefile index 0ae7671..b17d19f 100644 --- a/Makefile +++ b/Makefile @@ -103,6 +103,7 @@ BIN =\ getconf\ grep\ head\ + install.out\ join\ hostname\ kill\ @@ -166,8 +167,8 @@ BIN =\ LIBUTFOBJ = $(LIBUTFSRC:.c=.o) LIBUTILOBJ = $(LIBUTILSRC:.c=.o) OBJ = $(BIN:=.o) $(LIBUTFOBJ) $(LIBUTILOBJ) -SRC = $(BIN:=.c) -MAN = $(BIN:=.1) +SRC = $(foreach F,$(BIN:.out=),$(F:=.c)) +MAN = $(foreach F,$(BIN:.out=),$(F:=.1)) all: $(BIN) @@ -178,6 +179,9 @@ $(OBJ): $(HDR) config.mk .o: $(CC) $(LDFLAGS) -o $@ $< $(LIB) +install.out: install.o + $(CC) $(LDFLAGS) -o $@ $^ $(LIB) + .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< @@ -197,13 +201,14 @@ confstr_l.h limits_l.h sysconf_l.h pathconf_l.h: getconf.sh install: all mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin - cd $(DESTDIR)$(PREFIX)/bin && ln -f test [ && chmod 755 $(BIN) + mv -f $(DESTDIR)$(PREFIX)/bin/install.out $(DESTDIR)$(PREFIX)/bin/install + cd $(DESTDIR)$(PREFIX)/bin && ln -f test [ && chmod 755 $(BIN:.out=) mkdir -p $(DESTDIR)$(MANPREFIX)/man1 for m in $(MAN); do sed "s/^\.Os sbase/.Os sbase $(VERSION)/g" < "$$m" > $(DESTDIR)$(MANPREFIX)/man1/"$$m"; done cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN) uninstall: - cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) [ + cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN:.out=) [ cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN) dist: clean @@ -238,7 +243,7 @@ sbase-box-install: sbase-box mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f sbase-box $(DESTDIR)$(PREFIX)/bin chmod 755 $(DESTDIR)$(PREFIX)/bin/sbase-box - for f in $(BIN); do ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/"$$f"; done + for f in $(BIN:.out=); do ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/"$$f"; done ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/[ mkdir -p $(DESTDIR)$(MANPREFIX)/man1 for m in $(MAN); do sed "s/^\.Os sbase/.Os sbase $(VERSION)/g" < "$$m" > $(DESTDIR)$(MANPREFIX)/man1/"$$m"; done diff --git a/README b/README index b3005dd..68a921c 100644 --- a/README +++ b/README @@ -42,6 +42,7 @@ The following tools are implemented: =*|o grep. =*|o head. =*|x hostname. +=*|x install . =* o join. =*|o kill. =*|o link. diff --git a/TODO b/TODO index a5559d1..fc0730d 100644 --- a/TODO +++ b/TODO @@ -8,7 +8,6 @@ awk bc diff ed manpage -install patch stty diff --git a/install.1 b/install.1 new file mode 100644 index 000..99eff81 --- /dev/null +++ b/install.1 @@ -0,0 +1,88 @@ +.Dd 2016-02-12 +.Dt INSTALL 1 +.Os sbase +.Sh NAME +.Nm install +.Nd copy files and set attributes +.Sh SYNOPSIS +.Nm +.Op Fl g Ar group +.Op Fl o Ar owner +.Op Fl m Ar mode +.Po +.Fl d Ar dir ... +| +.Op Fl sD +.Po +.Fl t Ar dest +.Ar source ... +| +.Ar source ... +.Ar dest +.Pc +.Pc +.Sh DESCRIPTION +.Nm +copies +.Ar source +to +.Ar dest . +If more than one +.Ar source +is given +.Ar dest +has to be a directory. +.Nm +can also change the attributes of the copies. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl d +Create the directories +.Ar dir . +.It Fl D +Create missing parent directories to +.Ar dest . +If +.Fl t +is used, the +.Ar dest +itself is also created if missing. +.It Fl g Ar group +Change the installed files' group to +.Ar group . +This may be a group name or a group identifier. +.It Fl m Ar mode +Change the file modes. Both numerical and symbolic +values are supported. See +.Xr chmod 1 +for the syntex. +Default mode 0755. If a file has the mode 0644 and +is copied with +.It Fl o Ar owner +Change the installed files' owner to +.Ar owner . +This may be a user name or a user identifier. +.It Fl s +Remove unnecessary symbols using +.Xr strip 1 . +Failure to strip a file does not imply failure to install the file. +.It Fl t Ar dest +Copy files into the directory +.Ar dest . +.Nm install , +the copy's mode will be 0755 unless +.Fl m +is used to select another mode. When the symbolic +notation is used, the base mode is . +.Sh SEE ALSO +.Xr chmod 1 , +.Xr chown 1 , +.Xr cp 1 , +.Xr mkdir 1 , +.Xr strip 1 +.Sh STANDARDS +The +.Nm +utility is not standardized. This implementation is a subset +of the GNU implementation and a subset with extensions to +the FreeBSD implementation. diff --git a/install.c b/install.c new file mode 100644 index 00
Re: [hackers] [sbase][PATCH] Add -d, -f and -i flags to sort(1)
On Fri, Feb 12, 2016 at 06:06:18PM +0200, Pekka Jylhä-Ollila wrote: > Hey, here's a patch that adds support to the -d, -f and -i flags to sort. > The added code uses libutf for string comparisons when the flags are used. > > --- > sort.c | 61 + > 1 file changed, 61 insertions(+) Thanks, the patch looks good. Can you update usage() and the manpage as well?