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;
+
}