ref: a1b2fae9965606c705ee7a31772a5267650f3629
parent: c980d9a167cf89793266ae7dfdf60fd20836dfec
author: Quentin Rameau <quinq@fifth.space>
date: Thu Jan 10 10:08:44 EST 2019
[ar] Parse full pathname for file operands
--- a/src/cmd/ar.c
+++ b/src/cmd/ar.c
@@ -107,22 +107,24 @@
}
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 @@
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 @@
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 @@
{
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 @@
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;
}
--- a/src/cmd/posix.c
+++ b/src/cmd/posix.c
@@ -3,6 +3,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <string.h>
#include <unistd.h>
#include <utime.h>
@@ -12,6 +13,13 @@
totime(long long t)
{
return t;
+}
+
+char *
+canonical(char *path)
+{
+ char *name = strrchr(path, '/');
+ return (name && name[1]) ? name+1 : path;
}
int
--- a/src/cmd/sys.h
+++ b/src/cmd/sys.h
@@ -7,5 +7,6 @@
};
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);