shithub: scc

Download patch

ref: 95e151ee065ec25ae3bab2b8a74a8529e72f5ee8
parent: 7ce12b649649aa1f31cb4fb5007284a4128f29a6
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Feb 12 03:25:07 EST 2018

[ar] Add openar() and archive()

These are the basic functions to create an archieve with -q.

--- a/ar/main.c
+++ b/ar/main.c
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
 #include <stat.h>
 
@@ -13,12 +14,18 @@
 
 char *argv0;
 
-int dflag, rflag, qflag, tflag, pflag, mflag, bflag,
-    iflag, xflag, vflag, cflag, lflag, uflag, aflag;
-    
-char *posname;
+static int bflag, iflag, vflag, cflag, lflag, uflag, aflag;
+static int done;
+static char *afile, *posname;
 
 static void
+cleanup(void)
+{
+	if (!done)
+		remove(afile);
+}
+
+static void
 usage(void)
 {
 	fputs("ar [-drqtpmx][posname] [-vuaibcl] [posname] afile name ...\n", stderr);
@@ -25,40 +32,136 @@
 	exit(1);
 }
 
+FILE *
+openar(char *afile)
+{
+	FILE *fp;
+	char magic[SARMAG+1];
+	struct stat st;
+
+	if ((fp = fopen(afile,"rb")) == NULL) {
+		if (!cflag)
+			fprintf(stderr, "ar: creating %s\n", afile);
+		if ((fopen(afile, "w+b")) == NULL)
+			goto file_error;
+		fputs(ARMAG, fp);
+		fflush(fp);
+	} else {
+		if (fgets(magic, sizeof(magic), fp) == NULL)
+			goto file_error;
+		if (!strcmp(magic, ARMAG)) {
+			fprintf(stderr,
+			        "ar:%s:invalid magic number '%s'\n",
+			        afile,
+			        magic);
+			exit(1);
+		}
+	}
+	if (ferror(fp))
+		goto file_error;
+	return fp;
+
+file_error:
+	perror("ar:opening archive");
+	exit(1);
+}
+
+static void
+archieve(char *fname, FILE *to)
+{
+	int c;
+	size_t n;
+	FILE *from;
+	char mtime[13];
+	struct stat st;
+
+	if (strlen(fname) > 16)
+		fprintf(stderr, "ar:%s: too long name\n", fname);
+	if (stat(fname, &st) < 0) {
+		fprintf(stderr, "ar:error getting '%s' attributes\n", fname);
+		exit(1);
+	}
+	if ((from = fopen(fname, "rb")) == NULL) {
+		fprintf(stderr,
+		        "ar:opening member '%s':%s\n",
+		        fname,
+		        strerror(errno));
+		exit(1);
+	}
+	strftime(mtime, sizeof(mtime), "%s", gmtime(&st.st_mtime));
+	fprintf(to,
+	        "%-16.16s%-12s%-6u%-6u%-8o%-10llu`\n",
+	        fname,
+	        mtime,
+	        st.st_uid,
+	        st.st_gid,
+	        st.st_mode,
+	        st.st_size);
+	for (n = 0; (c = getc(from)) != EOF; n++)
+		putc(c, to);
+	if (n & 1)
+		putc('\n', to);
+	if (ferror(from)) {
+		fprintf(stderr,
+		        "ar:reading input '%s':%s\n",
+		        fname, strerror(errno));
+		exit(1);
+	}
+	fclose(from);
+}
+
+static void
+append(FILE *fp, char *list[])
+{
+	char *fname;
+
+	if (fseek(fp, 0, SEEK_END) == EOF) {
+		perror("ar:seeking archive");
+		exit(1);
+	}
+	while ((fname = *list++) != NULL) {
+		if (vflag)
+			printf("a - %s\n", fname);
+		archieve(fname, fp);
+	}
+}
+
 int
 main(int argc, char *argv[])
 {
-	int key = 0, pos = 0;
+	int key, nkey = 0, pos = 0;
+	FILE *fp;
 
+	atexit(cleanup);
 	ARGBEGIN {
 	case 'd':
-		dflag = 1;
-		key++;
+		nkey++;
+		key = 'd';
 		break;
 	case 'r':
-		rflag = 1;
-		key++;
+		key = 'r';
 		break;
 	case 'q':
-		qflag = 1;
-		key++;
+		nkey++;
+		key = 'q';
 		break;
 	case 't':
-		tflag = 1;
-		key++;
+		nkey++;
+		key = 't';
 		break;
 	case 'p':
-		pflag = 1;
-		key++;
+		nkey++;
+		key = 'p';
 		break;
 	case 'm':
-		mflag = 1;
-		key++;
+		nkey++;
+		key = 'm';
 		break;
 	case 'x':
-		xflag = 1;
-		key++;
+		nkey++;
+		key = 'x';
 		break;
+
 	case 'a':
 		aflag = 1;
 		pos++;
@@ -90,8 +193,34 @@
 		usage();
 	} ARGEND
 
-	if (key == 0 || key > 1 || pos > 1)
+	if (nkey == 0 || nkey > 1 || pos > 1 || argc == 0)
 		usage();
+	afile = *argv++;
+	fp = openar(afile);
 
+	switch (key) {
+	case 'q':
+		append(fp, argv);
+		break;
+	case 'd':
+	case 'r':
+	case 't':
+	case 'p':
+	case 'm':
+	case 'x':
+		/* TODO */
+		;
+	}
+
+	if (ferror(fp)) {
+		perror("ar:error reading archive");
+		exit(1);
+	}
+
+
+	/* TODO: check status of stdout */
+	done = 1;
+
 	return 0;
+
 }