shithub: scc

Download patch

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);