scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit 59402b0a9be9b9ead0fa86bc90b24701cae4e87b
parent 7b38f863668cb3b479957580516dac0b413851a7
Author: Quentin Rameau <quinq@fifth.space>
Date:   Thu, 10 Jan 2019 15:08:44 +0100

[ar] Parse full pathname for file operands

Diffstat:
Msrc/cmd/ar.c | 55++++++++++++++++++++++++++++++-------------------------
Msrc/cmd/posix.c | 8++++++++
Msrc/cmd/sys.h | 1+
3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/src/cmd/ar.c b/src/cmd/ar.c @@ -107,22 +107,24 @@ openar(void) } static void -archive(char *fname, FILE *to, char letter) +archive(char *pname, FILE *to, char letter) { int c; size_t n; FILE *from; - char mtime[13]; + char mtime[13], *fname; struct fprop prop; + fname = canonical(pname); + if (vflag) printf("%c - %s\n", letter, fname); if (strlen(fname) > 16) fprintf(stderr, "ar:%s: too long name\n", fname); - if ((from = fopen(fname, "rb")) == NULL) - error("opening member '%s':%s\n", fname, errstr()); - if (getstat(fname, &prop) < 0) - error("error getting '%s' attributes", fname); + if ((from = fopen(pname, "rb")) == NULL) + error("opening member '%s':%s\n", pname, errstr()); + if (getstat(pname, &prop) < 0) + error("error getting '%s' attributes", pname); strftime(mtime, sizeof(mtime), "%s", gmtime(&prop.time)); fprintf(to, "%-16.16s%-12s%-6u%-6u%-8lo%-10llu`\n", @@ -137,7 +139,7 @@ archive(char *fname, FILE *to, char letter) if (n & 1) putc('\n', to); if (ferror(from)) - error("reading input '%s':%s", fname, errstr()); + error("reading input '%s':%s", pname, errstr()); fclose(from); } @@ -196,25 +198,28 @@ perms(struct member *m) return buf; } -static int +static char * inlist(char *fname, int argc, char *argv[]) { - for (; argc-- > 0; ++argv) { - if (*argv && !strcmp(*argv, fname)) { + char *p; + + for ( ; argc-- > 0; ++argv) { + if (*argv && !strcmp(canonical(*argv), fname)) { + p = *argv; *argv = NULL; - return 1; + return p; } } - return 0; + return NULL; } static int -older(struct member *m) +older(struct member *m, char *pname) { struct fprop prop; - if (getstat(m->fname, &prop) < 0) - error("error getting '%s' attributes", m->fname); + if (getstat(pname, &prop) < 0) + error("error getting '%s' attributes", pname); return prop.time > m->date; } @@ -252,10 +257,11 @@ update(struct member *m, int argc, char *argv[]) { int where; FILE *fp = tmps[BEFORE].fp; + char *pname; - if (inlist(m->fname, argc, argv)) { - if (uflag && older(m)) - archive(m->fname, tmps[m->cur].fp, 'r'); + if (pname = inlist(m->fname, argc, argv)) { + if (uflag && older(m, pname)) + archive(pname, tmps[m->cur].fp, 'r'); return; } else if (posname && !strcmp(posname, m->fname)) { where = (bflag) ? AFTER : BEFORE; @@ -354,16 +360,15 @@ static char * getfname(struct ar_hdr *hdr) { static char fname[SARNAM+1]; - size_t i; + char *p; memcpy(fname, hdr->ar_name, SARNAM); - fname[SARNAM] = '\0'; - for (i = SARNAM-1; i >= 0; --i) { - if (fname[i] != ' ' && fname[i] != '/') - break; - fname[i] = '\0'; - } + if (p = strchr(fname, ' ')) + *p = '\0'; + else + fname[SARNAM] = '\0'; + return fname; } diff --git a/src/cmd/posix.c b/src/cmd/posix.c @@ -3,6 +3,7 @@ static char sccsid[] = "@(#) ./ar/posix/driver.c"; #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> +#include <string.h> #include <unistd.h> #include <utime.h> @@ -14,6 +15,13 @@ totime(long long t) return t; } +char * +canonical(char *path) +{ + char *name = strrchr(path, '/'); + return (name && name[1]) ? name+1 : path; +} + int getstat(char *fname, struct fprop *prop) { diff --git a/src/cmd/sys.h b/src/cmd/sys.h @@ -7,5 +7,6 @@ struct fprop { }; extern time_t totime(long long t); +extern char *canonical(char *path); extern int getstat(char *fname, struct fprop *prop); extern int setstat(char *fname, struct fprop *prop);