diff --git a/util/arch/archiver.c b/util/arch/archiver.c index 2be5fd3ad..73ea4e606 100644 --- a/util/arch/archiver.c +++ b/util/arch/archiver.c @@ -2,91 +2,96 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -/* ar - archiver Author: Michiel Huisjes */ +/* ar - archiver Author: Michiel Huisjes */ /* Made into arch/aal by Ceriel Jacobs */ -static char RcsId[] = "$Id$"; + /* * Usage: [arch|aal] [qdprtx][vlcu] archive [file] ... - * v: verbose - * x: extract - * q: append - * r: replace (append when not in archive) - * d: delete - * t: print contents of archive - * p: print named files - * l: temporaries in current directory instead of /tmp - * c: don't give "create" message - * u: replace only if dated later than member in archive -#ifdef DISTRIBUTION - * D: make distribution: use distr_time, uid=2, gid=2, mode=0644 -#endif + * possible key + * d: delete + * p: print named files + * q: append + * r: replace (append when not in archive) + * t: print contents of archive + * x: extract + * possible args + * c: don't give "create" message + * u: replace only if dated later than member in archive + * v: verbose + #ifdef DISTRIBUTION + * D: make distribution: use distr_time, uid=2, gid=2, mode=0644 + #endif */ #include +#include #include #include #include #include #include -#include -#include +#include "print.h" +#include "system.h" +#include "object.h" +#include "arch.h" +#include "ranlib.h" + +/* UNIX specific */ +#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) +#ifndef unix +#define unix +#endif +#endif + +#ifdef unix #include +#else +#define getuid() 0 +#define getgid() 0 +#endif + #ifdef AAL -#include -#define MAGIC_NUMBER AALMAG -long offset; +#include "out.h" +#define MAGIC_NUMBER AALMAG +long offset; struct ranlib *tab; -unsigned int tnum = 0; -char *tstrtab; -unsigned int tssiz = 0; +unsigned int tnum = 0; +char *tstrtab; +unsigned int tssiz = 0; unsigned int tabsz, strtabsz; #else -#define MAGIC_NUMBER ARMAG +#define MAGIC_NUMBER ARMAG #endif -#define odd(nr) (nr & 01) -#define even(nr) (odd(nr) ? nr + 1 : nr) +#define odd(nr) (nr & 01) +#define even(nr) (odd(nr) ? nr + 1 : nr) typedef char BOOL; -#define FALSE 0 -#define TRUE 1 +#define FALSE 0 +#define TRUE 1 -#define READ 0 -#define APPEND 2 -#define CREATE 1 +#define READ 0 +#define APPEND 2 +#define CREATE 1 -#define MEMBER struct ar_hdr +#define MEMBER struct ar_hdr -#define NIL_PTR ((char *) 0) -#define NIL_MEM ((MEMBER *) 0) -#define NIL_LONG ((long *) 0) +#define NIL_PTR ((char *) 0) +#define NIL_MEM ((MEMBER *) 0) +#define NIL_LONG ((long *) 0) -#define IO_SIZE (10 * 1024) +#define IO_SIZE (10 * 1024) -#define equal(str1, str2) (!strncmp((str1), (str2), 14)) -#ifndef S_ISDIR -#define S_ISDIR(m) (m & S_IFDIR) /* is a directory */ -#endif - -/* Use Posix names if old-fashioned names are not defined. */ - -#ifndef S_IREAD -#define S_IREAD S_IRUSR -#endif -#ifndef S_IWRITE -#define S_IWRITE S_IWUSR -#endif -#ifndef S_IEXEC -#define S_IEXEC S_IXUSR -#endif +#define equal(str1, str2) (!strncmp((str1), (str2), AR_NAME_MAX)) BOOL verbose; BOOL app_fl; BOOL ex_fl; BOOL show_fl; +/* print files found in archive. */ BOOL pr_fl; BOOL u_fl; BOOL rep_fl; @@ -95,536 +100,658 @@ BOOL nocr_fl; BOOL local_fl; #ifdef DISTRIBUTION BOOL distr_fl; -long distr_time; +time_t distr_time; #endif -int ar_fd; +#ifndef S_ISUID +#define S_ISUID 0 +#endif +#ifndef S_ISGID +#define S_ISGID 0 +#endif + +#define MODE_COUNT 11 char io_buffer[IO_SIZE]; char *progname; -char temp_buf[32]; +char temp_buf[L_tmpnam]; char *temp_arch = &temp_buf[0]; -extern char *ctime(); -void do_object(int f, long size); -void write_symdef(); -void add(); +void do_object(FILE* f, long size); +void do_names(struct outhead *headp); +void enter_name(struct outname *namep); +void write_symdef(FILE *ar); -usage() +void error(BOOL quit, char *str1, char *str2); +FILE* open_archive(char *name, int mode); +void +catch(int param); +MEMBER *get_member(FILE*); +void get(int argc, char *argv[]); +void add(char *name, FILE* ar, FILE* dst, char *mess); +void extract(FILE* ar, MEMBER *member); +void copy_member(MEMBER *member, FILE* from, FILE* to, BOOL extracting); +char *get_mode(int mode); +void wr_fatal(void); +void rd_fatal(void); +void mwrite(FILE* f, void* address, size_t bytes); +void show(char *s, char *name); + +/* Conversion utilities. */ +static mode_t ar2mode(short mode); +static short mode2ar(mode_t mode); + +/** Maps an AR mode to the current system mode. */ +struct modemap { - error(TRUE, "usage: %s [qdprtxl][vlc] archive [file] ...\n", - progname - ); + short ar_mode; + mode_t mode; +}; + +/** Mapping table to map an AR mode to a system mode. */ +static const struct modemap armodes[MODE_COUNT] = +{ +{ AR_IRUSR, S_IRUSR }, +{ AR_IWUSR, S_IWUSR }, +{ AR_IXUSR, S_IXUSR }, + +{ AR_IRGRP, S_IRGRP }, +{ AR_IWGRP, S_IWGRP }, +{ AR_IXGRP, S_IXGRP }, + +{ AR_IROTH, S_IROTH }, +{ AR_IWOTH, S_IWOTH }, +{ AR_IXOTH, S_IXOTH }, + +{ AR_ISUID, S_ISUID }, +{ AR_ISGID, S_ISGID } }; + +/** Convert an "ar" mode to a system specific + * mode. + */ +static mode_t ar2mode(short mode) +{ + int i; + mode_t result = 0; + for (i = 0; i < MODE_COUNT; i++) + { + if (mode & armodes[i].ar_mode) + { + result = result | armodes[i].mode; + } + } + return result; +} + +/** Convert a system specified mode to + * an ar compatible mode. + */ +static short mode2ar(mode_t mode) +{ + int i; + short result = 0; + for (i = 0; i < MODE_COUNT; i++) + { + if (mode & armodes[i].mode) + { + result = result | armodes[i].ar_mode; + } + } + return result; +} + +static void usage(void) +{ + error(TRUE, "usage: %s [qdprtxl][vc] archive [file] ...\n", progname); } /*VARARGS2*/ -error(quit, str1, str2, str3, str4) -BOOL quit; -char *str1, *str2, *str3, *str4; +void error(BOOL quit, char *str1, char *str2) { char errbuf[256]; - sprint(errbuf, str1, str2, str3, str4); - write(2, errbuf, strlen(errbuf)); - if (quit) { - unlink(temp_arch); - _exit(1); - } -} - -char *basename(path) -char *path; -{ - register char *ptr = path; - register char *last = NIL_PTR; - - while (*ptr != '\0') { - if (*ptr == '/') - last = ptr; - ptr++; - } - if (last == NIL_PTR) - return path; - if (*(last + 1) == '\0') { - *last = '\0'; - return basename(path); - } - return last + 1; -} - -extern unsigned int rd_unsigned2(); - -open_archive(name, mode) -register char *name; -register int mode; -{ - unsigned short magic = 0; - int fd; - - if (mode == CREATE) { - if ((fd = creat(name, 0666)) < 0) - error(TRUE, "cannot creat %s\n", name); - magic = MAGIC_NUMBER; - wr_int2(fd, magic); - return fd; - } - - if ((fd = open(name, mode)) < 0) { - if (mode == APPEND) { - close(open_archive(name, CREATE)); - if (!nocr_fl) error(FALSE, "%s: creating %s\n", progname, name); - return open_archive(name, APPEND); + sprint(errbuf, str1, str2); + fwrite(errbuf, strlen(errbuf), 1, stderr); + if (quit) + { + remove(temp_arch); + exit(1); } - error(TRUE, "cannot open %s\n", name); - } - lseek(fd, 0L, 0); - magic = rd_unsigned2(fd); - if (magic != AALMAG && magic != ARMAG) - error(TRUE, "%s is not in ar format\n", name); +} - return fd; +/** Opens the specified archive. */ +FILE* open_archive(char *name, int mode) +{ + unsigned short magic = 0; + FILE* file = NULL; + + if (mode == CREATE) + { + file = fopen(name, "wb+"); + if (file == NULL) + error(TRUE, "cannot create %s\n", name); + magic = MAGIC_NUMBER; + wr_int2(file, magic); + return file; + } + + file = fopen(name, "rb"); + if (file == NULL) + { + /* mode APPEND and files does not exist. */ + if (mode == APPEND) + { + fclose(open_archive(name, CREATE)); + if (!nocr_fl) + error(FALSE, "creating %s\n", name); + return open_archive(name, APPEND); + } + error(TRUE, "cannot open %s\n", name); + } + else + /* file already exists, simply open it for appending */ + { + if (mode == APPEND) + { + fclose(file); + file = fopen(name, "a+b"); + } + } + fseek(file, 0, SEEK_SET); + magic = rd_unsigned2(file); + if (magic != AALMAG && magic != ARMAG) + error(TRUE, "%s is not in ar format\n", name); + + return file; } void -catch() +catch(int param) { - unlink(temp_arch); - _exit (2); + remove(temp_arch); + exit(2); } -main(argc, argv) -int argc; -char *argv[]; +int main(int argc, char *argv[]) { - register char *ptr; - int needs_arg = 0; + register char *ptr; + int needs_arg = 0; - progname = argv[0]; + progname = argv[0]; - if (argc < 3) - usage(); + if (argc < 3) + usage(); - for (ptr = argv[1]; *ptr; ptr++) { - switch (*ptr) { - case 't' : + for (ptr = argv[1]; *ptr; ptr++) + { + switch (*ptr) + { + case 't': show_fl = TRUE; break; - case 'v' : + case 'v': verbose = TRUE; break; - case 'x' : + case 'x': ex_fl = TRUE; break; - case 'q' : + case 'q': needs_arg = 1; app_fl = TRUE; break; - case 'c' : + case 'c': nocr_fl = TRUE; break; case 'u': u_fl = TRUE; break; - case 'p' : + case 'p': needs_arg = 1; pr_fl = TRUE; break; - case 'd' : + case 'd': needs_arg = 1; del_fl = TRUE; break; - case 'r' : + case 'r': needs_arg = 1; rep_fl = TRUE; break; - case 'l' : - local_fl = TRUE; - break; #ifdef DISTRIBUTION - case 'D' : + case 'D' : distr_fl = TRUE; break; #endif - default : + default: usage(); + } } - } - if (needs_arg && argc <= 3) - usage(); + if (needs_arg && argc <= 3) + usage(); #ifdef DISTRIBUTION - if (distr_fl) { - static struct stat statbuf; + if (distr_fl) + { + static struct stat statbuf; - stat(progname, &statbuf); - distr_time = statbuf.st_mtime; - } + stat(progname, &statbuf); + distr_time = statbuf.st_mtime; + } #endif - if (local_fl) strcpy(temp_arch, "ar.XXXXXX"); - else strcpy(temp_arch, "/tmp/ar.XXXXXX"); + if (sys_tmpnam(temp_arch) == NULL) + { + error(TRUE, "Cannot create a temporary filename\n", NULL); + } - if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1) - usage(); + if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1) + usage(); - if (u_fl && ! rep_fl) - usage(); + if (u_fl && !rep_fl) + usage(); - if (rep_fl || del_fl + if (rep_fl || del_fl #ifdef AAL - || app_fl + || app_fl #endif - ) { - close(mkstemp(temp_arch)); - } + ) + { + /*fclose(mkstemp(temp_arch));*/ + } #ifdef AAL - tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib)); - tstrtab = malloc(4096); - if (!tab || !tstrtab) error(TRUE,"Out of core\n"); - tabsz = 512; - strtabsz = 4096; + tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib)); + tstrtab = malloc(4096); + if (!tab || !tstrtab) + error(TRUE, "Out of core\n", NULL); + tabsz = 512; + strtabsz = 4096; #endif - signal(SIGINT, catch); - get(argc, argv); + signal(SIGINT, + catch); + get(argc, argv); - return 0; + return 0; } -MEMBER * -get_member() +/* Read next member of in the archive file "f". */ +MEMBER *get_member(FILE *f) { - static MEMBER member; + static MEMBER member; -again: - if (rd_arhdr(ar_fd, &member) == 0) + again: + if (rd_arhdr(f, &member) == 0) return NIL_MEM; - if (member.ar_size < 0) { - error(TRUE, "archive has member with negative size\n"); - } - if (equal(SYMDEF, member.ar_name)) { - lseek(ar_fd, member.ar_size, 1); - goto again; - } - return &member; + if (member.ar_size < 0) + { + error(TRUE, "archive has member with negative size\n",NULL); + } + if (equal(SYMDEF, member.ar_name)) + { + fseek(f, member.ar_size, SEEK_CUR); + goto again; + } + return &member; } -char *get_mode(); - -get(argc, argv) -int argc; -register char *argv[]; +void get(int argc, char *argv[]) { - register MEMBER *member; - int i = 0; - int temp_fd, read_chars; + register MEMBER *member; + FILE *ar_f; + int i = 0; + char buffer[FILENAME_MAX]; + size_t read_chars; + FILE* temp_fd; - ar_fd = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND); - if (rep_fl || del_fl + ar_f = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND); + if (rep_fl || del_fl #ifdef AAL - || app_fl + || app_fl #endif - ) + ) temp_fd = open_archive(temp_arch, CREATE); - while ((member = get_member()) != NIL_MEM) { - if (argc > 3) { - for (i = 3; i < argc; i++) { - if (equal(basename(argv[i]), member->ar_name)) + while ((member = get_member(ar_f)) != NIL_MEM) + { + if (argc > 3) + { + for (i = 3; i < argc; i++) + { + sys_basename(argv[i],buffer); + if (equal(buffer, member->ar_name)) break; - } - if (i == argc || app_fl) { - if (rep_fl || del_fl -#ifdef AAL - || app_fl -#endif - ) { -#ifdef AAL - if (i != argc) { - print("%s: already in archive\n", argv[i]); - argv[i] = ""; - } -#endif - wr_arhdr(temp_fd, member); - copy_member(member, ar_fd, temp_fd, 0); } - else { + if (i == argc || app_fl) + { + if (rep_fl || del_fl +#ifdef AAL + || app_fl +#endif + ) + { +#ifdef AAL + if (i != argc) + { + print("%s: already in archive\n", argv[i]); + argv[i] = ""; + } +#endif + wr_arhdr(temp_fd, member); + copy_member(member, ar_f, temp_fd, FALSE); + } + else + { #ifndef AAL - if (app_fl && i != argc) { - print("%s: already in archive\n", argv[i]); - argv[i] = ""; - } + if (app_fl && i != argc) + { + print("%s: already in archive\n", argv[i]); + argv[i] = ""; + } #endif - lseek(ar_fd, even(member->ar_size),1); + fseek(ar_f, even(member->ar_size),SEEK_CUR); + } + continue; } - continue; } - } - if (ex_fl || pr_fl) - extract(member); - else { - if (rep_fl) - add(argv[i], temp_fd, "r - %s\n"); - else if (show_fl) { - char buf[sizeof(member->ar_name) + 2]; - register char *p = buf, *q = member->ar_name; + if (ex_fl || pr_fl) + extract(ar_f,member); + else + { + if (rep_fl) + add(argv[i], ar_f, temp_fd, "r - %s\n"); + else if (show_fl) + { + char buf[sizeof(member->ar_name) + 2]; + register char *p = buf, *q = member->ar_name; - while (q <= &member->ar_name[sizeof(member->ar_name)-1] && *q) { - *p++ = *q++; + while (q <= &member->ar_name[sizeof(member->ar_name)-1] && *q) + { + *p++ = *q++; + } + *p++ = '\n'; + *p = '\0'; + if (verbose) + { + char *mode = get_mode(member->ar_mode); + char *date = ctime(&(member->ar_date)); + + *(date + 16) = '\0'; + *(date + 24) = '\0'; + + print("%s%3u/%u%7ld %s %s %s", + mode, + (unsigned) (member->ar_uid & 0377), + (unsigned) (member->ar_gid & 0377), + member->ar_size, + date+4, + date+20, + buf); + } + else print(buf); } - *p++ = '\n'; - *p = '\0'; - if (verbose) { - char *mode = get_mode(member->ar_mode); - char *date = ctime(&(member->ar_date)); - - *(date + 16) = '\0'; - *(date + 24) = '\0'; - - print("%s%3u/%u%7ld %s %s %s", - mode, - (unsigned) (member->ar_uid & 0377), - (unsigned) (member->ar_gid & 0377), - member->ar_size, - date+4, - date+20, - buf); + else if (del_fl) + { + show("d - %s\n", member->ar_name); } - else print(buf); + fseek(ar_f, even(member->ar_size), SEEK_CUR); } - else if (del_fl) - show("d - %s\n", member->ar_name); - lseek(ar_fd, even(member->ar_size), 1); + argv[i] = ""; } - argv[i] = ""; - } - if (argc > 3) { - for (i = 3; i < argc; i++) - if (argv[i][0] != '\0') { + if (argc > 3) + { + for (i = 3; i < argc; i++) + if (argv[i][0] != '\0') + { #ifndef AAL if (app_fl) - add(argv[i], ar_fd, "a - %s\n"); + add(argv[i], ar_f, "a - %s\n"); else #endif if (rep_fl #ifdef AAL - || app_fl + || app_fl #endif ) - add(argv[i], temp_fd, "a - %s\n"); - else { + add(argv[i], ar_f, temp_fd, "a - %s\n"); + else + { print("%s: not found\n", argv[i]); } } - } + } - if (rep_fl || del_fl + if (rep_fl || del_fl #ifdef AAL - || app_fl + || app_fl #endif - ) { - signal(SIGINT, SIG_IGN); - close(ar_fd); - close(temp_fd); - ar_fd = open_archive(argv[2], CREATE); - temp_fd = open_archive(temp_arch, APPEND); + ) + { + signal(SIGINT, SIG_IGN); + fclose(ar_f); + fclose(temp_fd); + ar_f = open_archive(argv[2], CREATE); + temp_fd = open_archive(temp_arch, APPEND); #ifdef AAL - write_symdef(); + write_symdef(ar_f); #endif - while ((read_chars = read(temp_fd, io_buffer, IO_SIZE)) > 0) - mwrite(ar_fd, io_buffer, read_chars); - close(temp_fd); - unlink(temp_arch); - } - close(ar_fd); + while ((read_chars = fread(io_buffer, 1, IO_SIZE, temp_fd)) > 0) + mwrite(ar_f, io_buffer, read_chars); + fclose(temp_fd); + remove(temp_arch); + } + fclose(ar_f); } -void -add(name, fd, mess) -char *name; -int fd; -char *mess; +/** Add an entry into the archive. + * + * @param[in] name path specification of the file to add. + * @param[in] ar Original ar file for update. + * @param[in] dst Archive name that will have its file added. + * + */ +void add(char *name, FILE* ar, FILE* dst, char *mess) { - static MEMBER member; - register int read_chars; - struct stat status; - int src_fd; + static MEMBER member; + size_t read_chars; + struct stat status; + char buffer[FILENAME_MAX]; + FILE* src_fd = NULL; - if (stat(name, &status) < 0) { - error(FALSE, "cannot find %s\n", name); - return; - } - else if (S_ISDIR(status.st_mode)) { - error(FALSE, "%s is a directory (ignored)\n", name); - return; - } - else if (u_fl && status.st_mtime <= member.ar_date) { - wr_arhdr(fd, member); - copy_member(member, ar_fd, fd, 0); - return; - } - else if ((src_fd = open(name, 0)) < 0) { - error(FALSE, "cannot open %s\n", name); - return; - } + if (stat(name, &status) < 0) + { + error(FALSE, "cannot find %s\n", name); + return; + } + else if (S_ISDIR(status.st_mode)) + { + error(FALSE, "%s is a directory (ignored)\n", name); + return; + } + else if (u_fl && status.st_mtime <= member.ar_date) + { + wr_arhdr(dst, &member); + copy_member(&member, ar, dst, FALSE); + return; + } + else if ((src_fd = fopen(name, "rb")) == NULL) + { + error(FALSE, "cannot open %s\n", name); + return; + } - strncpy (member.ar_name, basename (name), sizeof(member.ar_name)); - member.ar_uid = status.st_uid; - member.ar_gid = status.st_gid; - member.ar_mode = status.st_mode; - member.ar_date = status.st_mtime; - member.ar_size = status.st_size; + sys_basename(name, buffer); + strncpy (member.ar_name, buffer, sizeof(member.ar_name)); + member.ar_uid = status.st_uid; + member.ar_gid = status.st_gid; + member.ar_mode = mode2ar(status.st_mode); + member.ar_date = status.st_mtime; + member.ar_size = status.st_size; #ifdef DISTRIBUTION - if (distr_fl) { - member.ar_uid = 2; - member.ar_gid = 2; - member.ar_mode = 0644; - member.ar_date = distr_time; - } + if (distr_fl) + { + member.ar_uid = 2; + member.ar_gid = 2; + member.ar_mode = AR_IUSR | AR_IWUSR | AR_IRGRP | AR_IROTH; + member.ar_date = distr_time; + } #endif - wr_arhdr(fd, &member); + wr_arhdr(dst, &member); #ifdef AAL - do_object(src_fd, member.ar_size); - lseek(src_fd, 0L, 0); - offset += AR_TOTAL + even(member.ar_size); + do_object(src_fd, member.ar_size); + fseek(src_fd, 0L, SEEK_SET); + offset += AR_TOTAL + even(member.ar_size); #endif - while (status.st_size > 0) { - int x = IO_SIZE; + while (status.st_size > 0) + { + size_t x = IO_SIZE; - read_chars = x; - if (status.st_size < x) { - x = status.st_size; read_chars = x; - status.st_size = 0; - x = even(x); + if (status.st_size < x) + { + x = status.st_size; + read_chars = x; + status.st_size = 0; + x = even(x); + } + else status.st_size -= x; + if (fread(io_buffer, 1, read_chars, src_fd) != read_chars) + { + error(FALSE,"%s seems to shrink\n", name); + break; + } + mwrite(dst, io_buffer, x); } - else status.st_size -= x; - if (read(src_fd, io_buffer, read_chars) != read_chars) { - error(FALSE,"%s seems to shrink\n", name); - break; - } - mwrite(fd, io_buffer, x); - } - if (verbose) - show(mess, member.ar_name); - close(src_fd); + if (verbose) + show(mess, member.ar_name); + fclose(src_fd); } -extract(member) -register MEMBER *member; +/** Extract an archive entry pointed to by member to + * either standard output or to a file. + * + */ +void extract(FILE* ar, MEMBER *member) { - int fd = 1; - char buf[sizeof(member->ar_name) + 1]; + FILE* file = stdout; + char buf[sizeof(member->ar_name) + 1]; - strncpy(buf, member->ar_name, sizeof(member->ar_name)); - buf[sizeof(member->ar_name)] = 0; - if (pr_fl == FALSE && (fd = creat(buf, 0666)) < 0) { - error(FALSE, "cannot create %s\n", buf); - fd = -1; - } + strncpy(buf, member->ar_name, sizeof(member->ar_name)); + buf[sizeof(member->ar_name)] = 0; + if (pr_fl == FALSE) + { + file = fopen(buf, "wb"); + if (file == NULL) + { + error(FALSE, "cannot create %s\n", buf); + file = NULL; + } + }; - if (verbose) { - if (pr_fl == FALSE) show("x - %s\n", buf); - else show("\n<%s>\n\n", buf); - } + if (verbose) + { + if (pr_fl == FALSE) + show("x - %s\n", buf); + else + show("\n<%s>\n\n", buf); + } - copy_member(member, ar_fd, fd, 1); + copy_member(member, ar, file, TRUE); - if (fd >= 0 && fd != 1) - close(fd); - if (pr_fl == FALSE) chmod(buf, member->ar_mode); + if (file != NULL) + fclose(file); + if (pr_fl == FALSE) + chmod(buf, ar2mode(member->ar_mode)); } -copy_member(member, from, to, extracting) -register MEMBER *member; -int from, to; +void copy_member(MEMBER *member, FILE* from, FILE* to, BOOL extracting) { - register int rest; - long mem_size = member->ar_size; - BOOL is_odd = odd(mem_size) ? TRUE : FALSE; + size_t rest; + long mem_size = member->ar_size; + BOOL is_odd = odd(mem_size) ? TRUE : FALSE; #ifdef AAL - if (! extracting) { - long pos = lseek(from, 0L, 1); + if (!extracting) + { + long pos = ftell(from); - do_object(from, mem_size); - offset += AR_TOTAL + even(mem_size); - lseek(from, pos, 0); - } -#endif - do { - rest = mem_size > (long) IO_SIZE ? IO_SIZE : (int) mem_size; - if (read(from, io_buffer, rest) != rest) { - char buf[sizeof(member->ar_name) + 1]; - - strncpy(buf, member->ar_name, sizeof(member->ar_name)); - buf[sizeof(member->ar_name)] = 0; - error(TRUE, "read error on %s\n", buf); + do_object(from, mem_size); + offset += AR_TOTAL + even(mem_size); + fseek(from, pos, SEEK_SET); } - if (to >= 0) mwrite(to, io_buffer, rest); - mem_size -= (long) rest; - } while (mem_size > 0L); +#endif + do + { + rest = mem_size > (size_t) IO_SIZE ? IO_SIZE : (size_t) mem_size; + if (fread(io_buffer, 1, rest, from) != rest) + { + char buf[sizeof(member->ar_name) + 1]; - if (is_odd) { - lseek(from, 1L, 1); - if (to >= 0 && ! extracting) - lseek(to, 1L, 1); - } + strncpy(buf, member->ar_name, sizeof(member->ar_name)); + buf[sizeof(member->ar_name)] = 0; + error(TRUE, "read error on %s\n", buf); + } + if (to != NULL) + mwrite(to, io_buffer, rest); + mem_size -= (long) rest; + } while (mem_size > 0L); + + if (is_odd) + { + fseek(from, 1L, SEEK_CUR); + if ((to != NULL) && (extracting == FALSE)) + fseek(to, 1L, SEEK_CUR); + } } -char * -get_mode(mode) -register int mode; +char *get_mode(int mode) { - static char mode_buf[11]; - register int tmp = mode; - int i; + static char mode_buf[11]; + register int tmp = mode; + int i; - mode_buf[9] = ' '; - for (i = 0; i < 3; i++) { - mode_buf[i * 3] = (tmp & S_IREAD) ? 'r' : '-'; - mode_buf[i * 3 + 1] = (tmp & S_IWRITE) ? 'w' : '-'; - mode_buf[i * 3 + 2] = (tmp & S_IEXEC) ? 'x' : '-'; - tmp <<= 3; - } - if (mode & S_ISUID) - mode_buf[2] = 's'; - if (mode & S_ISGID) - mode_buf[5] = 's'; - return mode_buf; + mode_buf[9] = ' '; + for (i = 0; i < 3; i++) + { + mode_buf[i * 3] = (tmp & AR_IRUSR) ? 'r' : '-'; + mode_buf[i * 3 + 1] = (tmp & AR_IWUSR) ? 'w' : '-'; + mode_buf[i * 3 + 2] = (tmp & AR_IXUSR) ? 'x' : '-'; + tmp <<= 3; + } + if (mode & AR_ISUID) + mode_buf[2] = 's'; + if (mode & AR_ISGID) + mode_buf[5] = 's'; + return mode_buf; } -wr_fatal() +void wr_fatal(void) { - error(TRUE, "write error\n"); + error(TRUE, "write error\n", NULL); } -rd_fatal() +void rd_fatal(void) { - error(TRUE, "read error\n"); + error(TRUE, "read error\n", NULL); } -mwrite(fd, address, bytes) -int fd; -register char *address; -register int bytes; +void mwrite(FILE* f, void* address, size_t bytes) { - if (write(fd, address, bytes) != bytes) - error(TRUE, "write error\n"); + if (fwrite(address, 1, bytes, f) != bytes) + error(TRUE, "write error\n", NULL); } -show(s, name) -char *s, *name; +void show(char *s, char *name) { - MEMBER x; - char buf[sizeof(x.ar_name)+1]; - register char *p = buf, *q = name; + MEMBER x; + char buf[sizeof(x.ar_name) + 1]; + register char *p = buf, *q = name; - while (q <= &name[sizeof(x.ar_name)-1] && *q) *p++ = *q++; - *p++ = '\0'; - print(s, buf); + while (q <= &name[sizeof(x.ar_name) - 1] && *q) + *p++ = *q++; + *p++ = '\0'; + print(s, buf); } #ifdef AAL @@ -634,76 +761,80 @@ char *s, *name; * then 4 bytes giving the size of the string table, followed by the string * table itself. */ -void -write_symdef() +void write_symdef(FILE *ar) { - register struct ranlib *ran; - register int i; - register long delta; - MEMBER arbuf; + register struct ranlib *ran; + register int i; + register long delta; + time_t time_value; + MEMBER arbuf; - if (! tnum) return; + if (!tnum) + return; if (odd(tssiz)) tstrtab[tssiz++] = '\0'; for (i = 0; i < sizeof(arbuf.ar_name); i++) arbuf.ar_name[i] = '\0'; strcpy(arbuf.ar_name, SYMDEF); - arbuf.ar_size = 4 + 2 * 4 * (long)tnum + 4 + (long)tssiz; - time(&arbuf.ar_date); + arbuf.ar_size = 4 + 2 * 4 * (long) tnum + 4 + (long) tssiz; + time(&time_value); + arbuf.ar_date = (long) time_value; arbuf.ar_uid = getuid(); arbuf.ar_gid = getgid(); - arbuf.ar_mode = 0444; + arbuf.ar_mode = AR_IRUSR | AR_IRGRP | AR_IROTH; #ifdef DISTRIBUTION - if (distr_fl) { + if (distr_fl) + { arbuf.ar_uid = 2; arbuf.ar_gid = 2; arbuf.ar_date = distr_time; } #endif - wr_arhdr(ar_fd,&arbuf); - wr_long(ar_fd, (long) tnum); + wr_arhdr(ar, &arbuf); + wr_long(ar, (long) tnum); /* * Account for the space occupied by the magic number * and the ranlib table. */ delta = 2 + AR_TOTAL + arbuf.ar_size; - for (ran = tab; ran < &tab[tnum]; ran++) { + for (ran = tab; ran < &tab[tnum]; ran++) + { ran->ran_pos += delta; } - wr_ranlib(ar_fd, tab, (long) tnum); - wr_long(ar_fd, (long) tssiz); - wr_bytes(ar_fd, tstrtab, (long) tssiz); + wr_ranlib(ar, tab, (long) tnum); + wr_long(ar, (long) tssiz); + wr_bytes(ar, tstrtab, (long) tssiz); } /* * Return whether the bytes in `buf' form a good object header. * The header is put in `headp'. */ -int -is_outhead(headp) - register struct outhead *headp; +int is_outhead(struct outhead *headp) { - return !BADMAGIC(*headp) && headp->oh_nname != 0; } -void do_object(int f, long size) +void do_object(FILE* f, long size) { - struct outhead headbuf; + struct outhead headbuf; - if (size < SZ_HEAD) { + if (size < SZ_HEAD) + { /* It can't be an object file. */ return; } /* * Read a header to see if it is an object file. */ - if (! rd_fdopen(f)) { + if (!rd_fdopen(f)) + { rd_fatal(); } rd_ohead(&headbuf); - if (!is_outhead(&headbuf)) { + if (!is_outhead(&headbuf)) + { return; } do_names(&headbuf); @@ -714,30 +845,32 @@ void do_object(int f, long size) * name table and read and write the names one by one. Update the ranlib table * accordingly. */ -do_names(headp) - struct outhead *headp; +void do_names(struct outhead *headp) { - register char *strings; - register int nnames = headp->oh_nname; + register char *strings = NULL; + register int nnames = headp->oh_nname; #define NNAMES 100 - struct outname namebuf[NNAMES]; + struct outname namebuf[NNAMES]; long xxx = OFF_CHAR(*headp); - if ( headp->oh_nchar != (unsigned int)headp->oh_nchar || - (strings = malloc((unsigned int)headp->oh_nchar)) == (char *)0 - ) { - error(TRUE, "string table too big\n"); + if ( (headp->oh_nchar != (unsigned int) headp->oh_nchar) + || ((strings = malloc((unsigned int) headp->oh_nchar))) == NULL) + { + error(TRUE, "string table too big\n", NULL); } rd_string(strings, headp->oh_nchar); - while (nnames) { + while (nnames) + { int i = nnames >= NNAMES ? NNAMES : nnames; register struct outname *p = namebuf; nnames -= i; rd_name(namebuf, i); - while (i--) { + while (i--) + { long off = p->on_foff - xxx; - if (p->on_foff == (long)0) { + if (p->on_foff == (long) 0) + { p++; continue; /* An unrecognizable name. */ } @@ -750,9 +883,7 @@ do_names(headp) * However, this problem also exists on the Unix * ranlib archives. */ - if ( (p->on_type & S_EXT) && - (p->on_type & S_TYP) != S_UND - ) + if ((p->on_type & S_EXT) && (p->on_type & S_TYP) != S_UND) enter_name(p); p++; } @@ -760,26 +891,31 @@ do_names(headp) free(strings); } -enter_name(namep) - struct outname *namep; +void enter_name(struct outname *namep) { - register char *cp; + register char *cp; - if (tnum >= tabsz) { - tab = (struct ranlib *) - realloc((char *) tab, (tabsz += 512) * sizeof(struct ranlib)); - if (! tab) error(TRUE, "Out of core\n"); + if (tnum >= tabsz) + { + tab = (struct ranlib *) realloc((char *) tab, + (tabsz += 512) * sizeof(struct ranlib)); + if (!tab) + error(TRUE, "Out of core\n", NULL); } tab[tnum].ran_off = tssiz; tab[tnum].ran_pos = offset; - for (cp = namep->on_mptr;; cp++) { - if (tssiz >= strtabsz) { + for (cp = namep->on_mptr;; cp++) + { + if (tssiz >= strtabsz) + { tstrtab = realloc(tstrtab, (strtabsz += 4096)); - if (! tstrtab) error(TRUE, "string table overflow\n"); + if (!tstrtab) + error(TRUE, "string table overflow\n", NULL); } - tstrtab[tssiz++] = *cp; - if (!*cp) break; + tstrtab[tssiz++] = *cp; + if (!*cp) + break; } tnum++; }