[net.sources] ucbxt -- UCB archive extraction program.

ka (01/17/83)

/*
 * ucbxt -- extract files in UCB archive format.
 *          Usage: ucbxt < archive
 *          Any netnews header on the input will be ignored.
 */

#include <stdio.h>

#define MAXSTR 200

struct utimbuf {
	long	actime;
	long	modtime;
};



main(argc, argv)
	char **argv;
	{
	getarch(stdin);
}



getarch(ar)
	FILE *ar;
	{
	char line[MAXSTR];
	char *p;
	char fname[MAXSTR];
	long mtime;
	int uid, gid;
	int fmode;
	long fsize;

	/* skip netnews header */
	do {
		if (fgets(line, MAXSTR, ar) == NULL)
			fatal("not an archive");
	} while (! equal(line, "!<arch>\n"));

	while (fgets(line, MAXSTR, ar) != NULL) {
		if (equal(line, "\n"))
			continue;	/* Don't ask me why */
		for (p = line ; *p != '`' ; p++)
			if (*p == '\0')
				fatal("Out of sync--file header expected");
		if (sscanf(line, "%s %ld %d %d %o %ld",
		    fname, &mtime, &uid, &gid, &fmode, &fsize) != 6)
			fatal("sscanf failed");
		makefile(fname, mtime, fmode, fsize, ar);
	}
}



makefile(fname, mtime, fmode, fsize, ar)
	char *fname;
	long mtime;
	int fmode;
	long fsize;
	FILE *ar;
	{
	FILE *fp;
	register i, c;
	struct utimbuf times;

	if ((fp = fopen(fname, "w")) == NULL)
		fatal("can't create file");
	for (i = 0 ; i < fsize ; i++) {
		if ((c = getc(ar)) == EOF)
			fatal("unexpected end of file");
		if (putc(c, fp) == EOF)
			fatal("write error");
	}
	fclose(fp);
	if (chmod(fname, fmode) < 0)
		fatal("can't chmod");
	time(&times.actime);
	times.modtime = mtime;
	if (utime(fname, &times) < 0)
		fatal("utime failed");
}



equal(s1, s2)
	char *s1, *s2;
	{
	while (*s1 == *s2) {
		if (*s1 == '\0')
			return 1;
		s1++, s2++;
	}
	return 0;
}



fatal(msg)
	char *msg;
	{
	printf("%s\n", msg);
	exit(1);
}