/* * rl.c -- rl */ #include #include #include #include #include enum { RLENTSIZE = 4 + NNAME + 4, }; char symname[]="__.SYMDEF"; /* table of contents file name */ char *libname; /* current archive */ char firstname[NNAME]; /* first file in archive */ char *errs; /* exit status */ char verbose; int nextern; /* number of 'T' & 'D' symbols */ int symsize; /* size of __.SYMDEF archive member */ int readrl(Biobuf *bp); void writerl(void), setoffsets(Sym *, int), fexec(char *, char *, ...); void main(int argc, char *argv[]) { int i; Biobuf *bin; argv0 = argv[0]; ARGBEGIN { case 'v': verbose = 1; break; } ARGEND for(i=0; itype == 'T' || s->type == 'D') { s->value = offset-symsize; nextern++; } j++; } offset += size; } return 1; } void writerl(void) { Biobuf b; Sym *s; long new, off; int fd, i; fd = create(symname, 1, 0664); if(fd < 0){ fprint(2, "%s: cannot create %s\n", argv0, symname); return; } Binit(&b, fd, OWRITE); new = nextern * RLENTSIZE + SAR_HDR; for(i=0; s = objsym(i); i++) { if(s->type != 'T' && s->type != 'D') continue; off = s->value + new; if(verbose) print("%10s %d %ld\n", s->name, s->type == 'D', off); Bputc(&b, off); Bputc(&b, off>>8); Bputc(&b, off>>16); Bputc(&b, off>>24); if (Bwrite(&b, s->name, NNAME) != NNAME) { fprint(2, "%s: short write to %s\n", argv0, symname); errs = "errors"; } if(s->type == 'T') Bputc(&b, 0); else Bputc(&b, 1); /* padding */ Bputc(&b, 0); Bputc(&b, 0); Bputc(&b, 0); } Bclose(&b); close(fd); if(strcmp(firstname, symname) != 0) if(symsize == 0) fexec("/bin/ar", "ar", "rb", firstname, libname, symname, 0); else{ fexec("/bin/ar", "ar", "mb", firstname, libname, symname, 0); fexec("/bin/ar", "ar", "r", libname, symname, 0); } else fexec("/bin/ar", "ar", "r", libname, symname, 0); remove(symname); } void fexec(char *av0, char *av, ...) { int pid; Waitmsg w; switch(pid = fork()){ case -1: fprint(2, "%s: can't fork\n", argv0); exits("fork"); case 0: exec(av0, &av); fprint(2, "%s: can't exec\n", argv0); exits("exec"); } while(wait(&w) != -1 && atoi(w.pid) != pid) ; }