home *** CD-ROM | disk | FTP | other *** search
- /* cfar.c */
- /* Import .o and .a (a.out format) files into a cff archive */
- /* Version 2 now incorporates FILE mode, absorbing 'cfin' and 'cfdel' */
- /* Copyright 1993, 1995 Norman D. Culver, All Rights Reserved */
-
- /* compile: gcc -o -O2 -DSKELETON cfar.c */
-
- typedef unsigned long size_t;
-
- #include "oxbow.h"
-
- extern void (*BUGPRINTF)(char *fmt, ...);
-
- extern long atol(const char *);
- extern int strlen(const char *);
- extern void *strcpy(char *, const char *);
- extern int _strcpy(char *, char *);
- extern void memclr(char *, long);
- extern int strlwr(char *);
- extern void *strrchr(const char *, char);
- extern void *strstr(const char *, const char *);
- static void setup_origin(unsigned long, int);
- extern void oxlink_close_libs(void);
-
- /* Program version */
- static Item prgversion = (Item)2;
- /* Archive version */
- static Item arversion;
-
- /* Maximum library types */
- #define MAXLIBTYPE 16
-
- typedef struct {
- unsigned long sn;
- unsigned long libnum : 12; /* capacity for 4096 libraries per libtype */
- unsigned long libtype : 4; /* capacity for 16 library types */
- unsigned long unused : 12;
- unsigned long tag : 4;
- } SymItem;
-
- typedef struct {
- unsigned long filetime;
- unsigned long sn : 28;
- unsigned long tag : 4;
- } OrgItem;
-
- /* Action bitmap */
- static int act;
- #define arADD (1)
- #define arREPLACE (2)
- #define arDELETE (4)
- #define arEXTRACT (8)
- #define arCHECK (16)
- #define arUPDATE (32)
-
- static int verbose; /* if 1, verbose mode */
- static long libtype; /* 0 = modules, 1 = classes */
- static long oldlibtype = -1;
- static long libnum; /* library number into which files are stored */
- static long oldlibnum = -1;
- static int map; /* if 1, print archive map */
- static int map_bitmaps; /* if 1, and map, print bitmaps */
- static int map_entries; /* if 1, and map, print entries */
- static int freshen; /* if 1, freshen entries */
- static int shrink; /* if 1, shrink archive */
- static int issymbol; /* if 1, file names are really symbol names */
- static int batfile; /* if 1, print a batchfile to remake archive */
- static void *archive; /* handle of the open archive */
- static void *msyms; /* handle of the master symbol table */
- static void *fipaths; /* handle of the internal filemode path table */
- static void *ipaths; /* handle of the internal path table */
- static void *qipaths;
- static void *origins; /* handle of the origin path table */
- static void *qorigins;
- static void *lib; /* handle of the current internal library */
- static void *plib; /* handle of the library parent directory */
- static char curlib[1024]; /* internal path to the current library */
- static int curliblen;
- static char curobj[1024]; /* internal path to the current file */
- static int curobjlen;
- static char *cur_orgpath; /* current origin path as given by cfpathtrn */
- static int cur_orgtype; /* current origin type as given by cfpathtrn */
- static OrgItem cur_org; /* current origin time and serial num */
- static char ltypes[MAXLIBTYPE];
- static char lnums[4096];
- static int delete;
- static int replace;
- static int add;
-
- static unsigned long
- new_sn(char *name)
- {
- Item sn;
- int namlen = strlen(name);
- if(cffind(archive, name, namlen, &sn) >= FOUND)
- {
- ++sn.a0;
- cfreinsert(archive, name, namlen, &sn);
- return sn.a0;
- }
- return 0;
- }
-
- /* ++++++++++++++++++++++++++++ DLLMODE ++++++++++++++++++++++++++++++++ */
- static int dllmode;
-
- static void
- proc_dllmode(char *dllpath)
- {
- char buf[256];
- char symbol[256];
- char dllname[256];
- char dlldef[256];
- int ordinal, argcnt, symlen, match, deflen;
- int filesize, filesize1;
- long dupnum;
- SymItem symval, saveval;
- char *filename;
- cfFILE *df;
- CFSTAT sbuf;
- void *xx, *xx1, *yy;
- int dlltype, dll_sn;
- char *cp;
-
- filename = strrchr(dllpath, '/');
- if(filename)
- ++filename;
- else filename = dllpath;
-
- deflen = _strcpy(dlldef, filename);
- if(strstr(dlldef, ".w32"))
- dlltype = 1<<4;
- else if(strstr(dlldef, ".os2"))
- dlltype = 2<<4;
- else if(strstr(dlldef, ".lnx"))
- dlltype = 3<<4;
- else if(strstr(dlldef, ".w16"))
- dlltype = 4<<4;
- else if(strstr(dlldef, ".os1"))
- dlltype = 5<<4;
- else
- dlltype = 0;
-
- strcpy(curlib, "ltype3");
- plib = cfsubopen(archive, curlib, F_RDWR|F_CREAT, NULL);
- xx = cfsubopen(plib, dlldef, F_RDONLY, NULL);
- if(!xx && delete)
- {
- cfprintf("cfar: %s does not exist\n", filename);
- return;
- }
- if(xx && !(replace || delete))
- {
- cfclose(xx);
- cfprintf("cfar: %s exists and replace not enabled\n", dlldef);
- return;
- }
- if(add || replace)
- {
- if(!(xx1 = cfopen(dllpath, F_RDONLY, NULL)))
- {
- cfclose(xx);
- cfprintf("cfar: cannot open %s\n", dllpath);
- return;
- }
- cfstat(xx1, &sbuf);
- setup_origin(sbuf.st_mtime, 1);
- }
- symbol[0] = '_'; /* add leading underscore to symbols */
- if(xx && (replace || delete))
- {/* DELETE ALL OF THE OLD SYMBOLS */
- saveval.sn = 0;
-
- /* get an in-memory uncompressed copy */
- yy = cfsubopen(MEMTEMP, "", F_TEMPFILE, NULL);
- filesize = cfunzip(yy,0,xx,0);
- cfclose(xx);
-
- /* convert the memory file to a stream FILE */
- cfseek(yy, 0, S_SET);
- df = cffdopen(yy, "rt");
- while(cffgets(buf, sizeof(buf)-1, df))
- {
- if( buf[0] == '#' || !isalnum(buf[0]) )
- continue;
- if(buf[0] == 'U' && strstr(buf, "UNHANDLED "))
- break;
- if(isdigit(buf[0]))
- {
- if(!strstr(buf, "ERROR:"))
- {
- /* the symbol is stored as oooo sssssssss cccc\n */
- cfsscanf(buf, "%d %s %d", &ordinal, &symbol[1], &argcnt);
-
- /* Delete the symbol from msyms */
- symlen = strlen(symbol);
- dupnum = 0;
- for(;;)
- {
- int result = cffind_dupnum(msyms, symbol, symlen, &symval, &dupnum);
-
- if(result >= FOUND)
- {
- symval.unused = 0;
- match = 0;
- if(saveval.sn)
- {
- if(symval.sn == saveval.sn && symval.libtype == 3)
- {
- match = 1;
- }
- }
- else
- {/* first */
- if(symval.libtype == 3)
- {/* check if the dll names match */
- int snum = symval.libnum;
- symval.libnum = 0;
-
- if(cfget(qipaths, &symval, 8, buf, 256) >= FOUND)
- {
- if(!strcmp(buf, dllname))
- {
- symval.libnum = snum;
- saveval = symval;
- match = 1;
- }
- }
- }/* END: symval.libtype == 3 */
- }/* END: first */
- if(match)
- {
- if(cfdelete_dupnum(msyms, symbol, symlen, dupnum) != OK)
- cfprintf("cfar: ERROR can't delete %s dumpnum=%d\n",
- symbol, dupnum);
- break;
- }
- ++dupnum;
- }/* END: result >= FOUND */
- else break;
- }/* END: for(;;) */
- }/* END: !strstr(ERROR) */
- }/* END: isdigit(buf[0]) */
- else if((cp = strstr(buf, ".dll")))
- {/* new dll encountered */
- cp[4]=0;
- if(saveval.sn)
- {/* delete previous dll name from qipath */
- int u = saveval.unused;
- int n = saveval.libnum;
- saveval.unused = 0;
- saveval.libnum = 0;
- cfdelete(qipaths, &saveval, 8);
- saveval.unused = u;
- saveval.libnum = n;
- }
- strcpy(dllname, buf);
- saveval.sn = 0;
- if(verbose)
- cfprintf("delete %s\n", dllname);
- continue;
- }/* END: new dll encountered */
- }/* END: while(cffgets()) */
-
- /* delete last dllname from qipaths */
- if(saveval.sn)
- {
- saveval.unused = 0;
- saveval.libnum = 0;
- cfdelete(qipaths, &saveval, 8);
- }
- cffclose(df); /* auto delete of tempfile yy */
-
- /* Delete the internal copy of dlldef */
- cfdelete(plib, dlldef, deflen);
- /* Delete the origin linkage */
- strcat(dlldef, ".org");
- cfdelete(plib, dlldef, deflen+4);
- dlldef[deflen] = 0;
- }/* END: DELETE OLD SYMBOLS */
-
- if(add || replace)
- {/* INSERT NEW SYMBOLS */
-
- /* get the compressed file size */
- filesize = cfzip(0,0,xx1,0);
-
- /* create a chunk to hold the compressed file */
- xx = cfmake_chunk(plib, dlldef, deflen, filesize);
- if(!xx)
- {
- cfprintf("cfar: cannot create internal file %s\n", filename);
- cfclose(xx1);
- return;
- }
- #if 1
- /* compress the external file into the internal chunk */
- cfseek(xx1, 0, S_SET);
- if((filesize1 = cfzip(xx,0,xx1,0)) != filesize)
- cfprintf("cfar: ERROR ziperr fs1=%d fs=%d\n", filesize1, filesize);
- #else
- /* copy the external file into the internal chunk */
- cfseek(xx1, 0, S_SET);
- if(cfcopy_file(xx, xx1) != sbuf.st_filesize)
- {
- cfprintf("cfar: ERROR copying %s\n", filename);
- cfclose(xx);
- cfclose(xx1);
- return;
- }
- #endif
- cfclose(xx); /* close the internal dlldef file chunk */
-
- /* Process the external dlldef file */
- cfseek(xx1, 0, S_SET);
- df = cffdopen(xx1, "rt");
- while(cffgets(buf, sizeof(buf)-1, df))
- {
- if( buf[0] == '#' || !isalnum(buf[0]) )
- continue;
- if((buf[0] == 'U') && strstr(buf, "UNHANDLED "))
- break;
- if(isdigit(buf[0]))
- {
- if(!strstr(buf, "ERROR:"))
- {
- /* the symbol is stored as oooo sssssssss cccc\n */
- cfsscanf(buf, "%d %s %d", &ordinal, &symbol[1], &argcnt);
-
- /* INSERT THE SYMBOL IN MSYMS, symval links to dllname */
- symlen = strlen(symbol);
- symval.sn = dll_sn;
- symval.libtype = 3;
- symval.unused = ordinal;
- symval.libnum = (argcnt&15) | dlltype;
- cfinsert_dupnum(msyms, symbol, symlen, &symval, NULL);
- if(verbose)
- cfprintf("ord:%d argcnt:%d %s\n", ordinal, argcnt, symbol);
- }
- }
- else if((cp = strstr(buf, ".dll")))
- {/* new dll encountered */
- cp[4]=0;
- strcpy(dllname, buf);
- /* insert in qipaths */
- dll_sn = new_sn("SN0");
- symval.sn = dll_sn;
- symval.libtype = 3;
- symval.unused = 0;
- symval.libnum = 0;
- symval.tag = STO_VALUE;
- if(verbose)
- cfprintf("%s\n", dllname);
- if(!cfput(qipaths, &symval, 8, dllname, strlen(dllname)+1,NULL))
- cfprintf("cfar: ERROR put dllname `%s' failed\n", dllname);
- }
- }/* END: while(cffgets()) */
-
- cffclose(df);
-
- /* save the backlink to the origin */
- strcat(dlldef, ".org");
- cfinsert(plib, dlldef, deflen+4, &cur_org);
-
- }/* END: INSERT NEW SYMBOLS */
- }/* proc_dllmode() */
-
- /* +++++++++++++++++++++++++++++ FILEMODE ++++++++++++++++++++++++++++++ */
- static int filemode;
- static int chunk;
- static int newname;
- static void *subdir;
- static char *midpart;
- static char *lastpart;
- static char basefile[256];
- static char midpath[1024];
- static char innerpath[1024];
-
- static void
- proc_filemode(char *filepath)
- {
- void *fit;
- void *h = (subdir) ? subdir : archive;
- void *fd;
- char *filename;
- char *cfname;
- Item item;
- CFSTAT sbuf;
- int cfnamlen;
- int filesize;
- char *tag;
- int exists = 0;
-
- filename = strrchr(filepath, '/');
- if(filename)
- ++filename;
- else filename = filepath;
-
- if(newname)
- cfname = lastpart;
- else
- cfname = filename;
-
- cfnamlen = strlen(cfname);
-
- if((fit = cfopen(filepath, F_RDONLY, NULL)) != NULL)
- {
- /* check for existance of the archive item */
- if(cfsubstat(h, cfname, &sbuf) == OK)
- {
- if(!replace)
- {
- cfclose(fit);
- cfprintf("cfar: %s exists and replace not enabled\n", cfname);
- return;
- }
- exists = 1;
- cfunlink(h, cfname);
- }
- cfstat(fit, &sbuf);
- filesize = sbuf.st_filesize;
- setup_origin(sbuf.st_mtime, 1);
-
- if(verbose || act == arUPDATE)
- {
- if(act == arUPDATE)
- cfprintf("updating %s\n", cfname);
- else cfprintf("%s\n", cfname);
- }
- if(chunk)
- {
- if(!(fd = cfmake_chunk(h, cfname, cfnamlen, filesize)))
- {
- cfprintf("cfar: cannot make chunk for %s\n", cfname);
- cfclose(fit);
- return;
- }
- }
- else
- {
- if(!(fd = cfsubopen(h, cfname, F_RDWR|F_CREAT|F_FILEONLY, NULL)))
- {
- cfprintf("cfar: could not create file %s\n", cfname);
- cfclose(fit);
- return;
- }
- }
-
- if(cfcopy_file(fd, fit) != filesize)
- cfprintf("cfar: ERROR copying %s\n", cfname);
-
- cfclose(fd);
- cfclose(fit);
-
- /* Store the backlink to the origin, time + origin serial number */
- if(newname)
- tag = "?";
- else
- tag = " ";
-
- curobjlen = cfsprintf(curobj, "%s/%s%s", innerpath, cfname, tag);
- if(exists || act == arUPDATE)
- {
- cfreinsert(fipaths, curobj, curobjlen, &cur_org);
- }
- else
- {
- cfinsert(fipaths, curobj, curobjlen, &cur_org);
- }
- }
- else
- {
- cfprintf("cfar: input file %s not found\n", filepath);
- }
- }
- static void *
- create_middle(char *path, void *basehandle)
- {
- char *cp;
-
- cp = path;
- while((cp = (char*)strchr(cp, '/')) != NULL)
- {
- void *subhandle;
- *cp = '\0';
- subhandle = cfsubopen(basehandle, path, F_RDWR|F_CREAT, NULL);
- cfclose(subhandle);
- *cp = '/';
- ++cp;
- }
- return cfsubopen(basehandle, path, F_RDWR|F_CREAT, NULL);
- }
- static void *
- open_middle(void *basehandle)
- {
- void *subhandle = NULL;
-
- if(newname)
- {
- if(midpart)
- {
- subhandle = cfsubopen(basehandle, midpath, F_RDWR|F_CREAT, NULL);
- if(subhandle == NULL)
- {/* create the path in pieces */
- subhandle = create_middle(midpath, basehandle);
- }
- }
- }
- else /* not newname */
- {
- if(innerpath[0])
- {
- subhandle = cfsubopen(basehandle, &innerpath[1], F_RDWR|F_CREAT, NULL);
- if(subhandle == NULL)
- {/* create the path in pieces */
- subhandle = create_middle(&innerpath[1], basehandle);
- }
- }
- }
- #if 0
- if(subhandle)
- cfsetverylazy(subhandle);
- #endif
- return subhandle;
- }
- static void
- del_entry()
- {
- CFSTAT sbuf;
- char forgpath[1024];
-
- if(innerpath[0])
- {
- if(verbose)
- cfprintf("%s\n", lastpart);
-
- if(cfunlink(archive, innerpath) != OK)
- {
- cfprintf("cfar: delete failed for `%s'\n", innerpath);
- }
- else
- {
- cfsprintf(forgpath, "/fipaths%s ", innerpath);
- if(cfunlink(archive, forgpath) != OK)
- {
- cfsprintf(forgpath, "/fipath/%s?", innerpath);
- if(cfunlink(archive, forgpath) != OK)
- cfprintf("cfar: delerror, fipath:%s\n", forgpath);
- }
- }
- }
- else
- {
- cfprintf("cfar: delete, path missing\n");
- }
- }
- static void
- out_entry()
- {
- void *in, *of;
-
- if(innerpath[0])
- {
- if((in = cfsubopen(archive, innerpath, F_RDONLY, NULL)) == NULL)
- {
- cfprintf("cfar: extract, `%s' does not exist\n", innerpath);
- return;
- }
- if((of = cfopen(lastpart, F_RDWR|F_CREAT, NULL)) == NULL)
- {
- cfprintf("cfar: extract, cannot create output file `%s'\n", lastpart);
- cfclose(in);
- }
- if(verbose)
- cfprintf("%s\n", lastpart);
- cfcopy_file(of, in);
- cfclose(in);
- cfclose(of);
- }
- else
- {
- cfprintf("cfar: extract, path missing\n");
- }
- }
- /* ====================== END FILEMODE =================================== */
- static int
- open_curlib()
- {
- if(lib)
- {/* library is already open */
- if(libtype == oldlibtype && libnum == oldlibnum)
- return 1;
-
- cfclose(lib);
- if(oldlibtype != libtype)
- {
- cfclose(plib);
- cfsprintf(curlib, "ltype%d", libtype);
- plib = cfsubopen(archive, curlib, F_RDWR|F_CREAT, NULL);
- }
- oldlibtype = libtype;
- oldlibnum = libnum;
- }
- if(oldlibtype != libtype) {
- cfsprintf(curlib, "ltype%d", libtype);
- plib = cfsubopen(archive, curlib, F_RDWR|F_CREAT, NULL);
- }
- curliblen = cfsprintf(curlib, "ltype%d/lib%d", libtype, libnum);
- lib = cfsubopen(archive, curlib, F_RDWR|F_CREAT|F_SORTED, NULL);
- if(!lib)
- {
- cfprintf("cfar: can't open library %s\n", curlib);
- return 0;
- }
- #if 0
- cfsetverylazy(lib);
- cfsetverylazy(plib);
- #endif
- return 1;
- }
- static void *
- make_scratch()
- {
- return cfsubopen(MEMTEMP, "", F_TEMPFILE|F_BITMAP, NULL);
- }
- static void
- get_libtypes(char *name)
- {
- void *dirh;
- CFDIRENT *d;
- memclr(ltypes, MAXLIBTYPE);
- dirh = cfopendir(name);
- while((d = cfreaddir(dirh)) != NULL) {
- if( d->d_name[0] == 'l'
- && d->d_name[1] == 't')
- {
- long x = atol(&d->d_name[5]);
- ltypes[x] = 1;
- }
- }
- cfclosedir(dirh);
- }
- static void
- get_libnums(char *name)
- {
- void *dirh;
- CFDIRENT *d;
- memclr(lnums, 4096);
- dirh = cfopendir(name);
- while((d = cfreaddir(dirh)) != NULL)
- {
- if( d->d_name[0] == 'l'
- && d->d_name[1] == 'i')
- {
- long x = atol(&d->d_name[3]);
- lnums[x] = 1;
- }
- }
- cfclosedir(dirh);
- }
- static char *
- fileof(char *path)
- {
- int len = strlen(path);
- char *cp = &path[len-1];
- char *cp1;
- while(cp != path)
- {
- if(*cp == '/' || *cp == '\\' || *cp == ':') {
- ++cp;
- break;
- }
- --cp;
- }
- len = strlen(cp);
- cp1 = malloc(len+1);
- strcpy(cp1, cp);
- return cp1;
- }
- static char *
- objof(char *name)
- {
- if(issymbol) {
- long dupnum = 0;
- SymItem symval;
- int symlen = strlen(name);
- for(;;)
- {
- int result = cffind_dupnum(msyms, name, symlen, &symval, &dupnum);
-
- if(result >= FOUND)
- {
- if( (act == arCHECK)
- || ( symval.libtype == libtype
- && symval.libnum == libnum))
- {
- char curpath[256];
- if(cfget(qipaths, &symval, 8, curpath, 256) >= FOUND) {
- if(act == arCHECK)
- cfprintf("symbol %s is defined in %s\n", name, curpath);
- else return fileof(curpath);
- }
- }
- ++dupnum;
- }
- else return NULL;
- }
- }
- else return fileof(name);
- }
- static void
- delete_file(char *name, int internal)
- {
- char *objname = objof(name);
- int objlen;
- Item packval;
- SymItem symval;
- char cpath[256];
- int cpathlen;
- Item objloc;
-
- if(!objname)
- return;
-
- cpathlen = cfsprintf(cpath, "%s/%s", curlib, objname);
-
- /* Delete the data chunk */
-
- objlen = strlen(objname);
- if(cffind(lib, objname, objlen, &objloc) < FOUND) {
- if(!internal)
- cfprintf("cfar: %s not found\n", cpath);
- return;
- }
- if(verbose && !internal)
- cfprintf("%s\n", objname);
-
- cfdelete(lib, objname, objlen);
-
- /* Read the quick access symbol pack and delete the symbols */
- objname[objlen-1] = 'x';
- if(cffind(lib, objname, objlen, &packval) >= FOUND)
- {
- char *cp, *sp, symlen;
- cp = cflocalize(lib, &packval);
- for(sp = cp; *sp ; sp += symlen+1)
- {
- long dupnum = 0;
- symlen = strlen(sp);
- for(;;)
- {
- int result = cffind_dupnum(msyms, sp, symlen, &symval, &dupnum);
- if(result >= FOUND)
- {
- if( symval.libtype == libtype
- && symval.libnum == libnum)
- {
- cfdelete_dupnum(msyms, sp, symlen, dupnum);
- break;
- }
- ++dupnum;
- }
- else break;
- }
- }
- cfrelease(cp, R_CLEAN);
- /* Delete the symbol pack */
- cfdelete(lib, objname, objlen);
- /* Delete the origin linkage */
- objname[objlen-1] = 't';
- cfdelete(lib, objname, objlen);
- }
- /* Delete the path info */
- cfdelete(ipaths, cpath, cpathlen);
- cfdelete(qipaths, &symval, 8);
- free(objname);
- }
- static void
- extract_file(char *name)
- {
- char *objname = objof(name);
- int objlen;
- Item objloc;
-
- if(!objname)
- return;
-
- objlen = strlen(objname);
- if(cffind(lib, objname, objlen, &objloc) == FOUND)
- {
- void *hobj;
- void *fd;
-
- if((hobj = cfopen_chunk(lib, &objloc)) != NULL)
- {
- if((fd = cfopen(objname, F_RDWR|F_CREAT, NULL)) != NULL)
- {
- cfcopy_file(fd, hobj);
- cfclose(fd);
- if(verbose)
- cfprintf("%s\n", objname);
- }
- cfclose(hobj);
- }
- }
- free(objname);
- }
- static void
- setup_origin(unsigned long filetime, int flag)
- {
- int orglen;
- char *cp;
- Item orgsn;
-
- cur_org.filetime = filetime;
- cur_org.tag = STO_VALUE;
- cp = &cur_orgpath[strlen(cur_orgpath)-1];
-
- if(!flag && (*cp != 'a' || cp[-1] != '.'))
- {/* origin is not a library */
- cp = strrchr(cur_orgpath, '/');
- *cp = 0;
- }
- if(flag && !newname)
- {
- cp = strrchr(cur_orgpath, '/');
- *cp = 0;
- }
- /* Check if the origin is in the system */
- orglen = strlen(cur_orgpath);
- if(cffind(origins, cur_orgpath, orglen, &orgsn) >= FOUND)
- {/* It is in the system, get the serial number */
- cur_org.sn = orgsn.a0;
- }
- else
- {/* Enter this origin into the system */
- orgsn.item = new_sn("SN1");
- orgsn.a2.type = STO_VALUE;
- cur_org.sn = orgsn.a0;
-
- /* Store the origin, indexed both ways */
- cfinsert(origins, cur_orgpath, orglen, &orgsn);
- cfput(qorigins, &orgsn, 4, cur_orgpath, orglen+1, NULL);
- }
- if(*cp == 0) *cp = '/';
- }
- static void
- insert_file(char *path)
- {
- void *desc;
-
- /* Open the input file */
- if((desc = cfopen(path, F_RDONLY, NULL)) != NULL)
- {
- int numobjs;
- int i, j;
- char *objname;
- char *sympack;
- int packx;
- void *scratch;
- CFSTAT s;
-
- cfstat(desc, &s);
- setup_origin(s.st_mtime, 0);
-
- /* Create a scratch object in memory */
- scratch = make_scratch();
-
- /* Take a look at the input file */
- numobjs = oxlink_scan_file(desc, scratch);
-
- /* oxlink_scan_file returns results in 'scratch'
- and on the 'scratch' stack */
- for(i = 0; i < numobjs; ++i, free(objname), free(sympack))
- {
- unsigned long numsyms;
- unsigned long symsize;
- unsigned long objsize;
- unsigned long objoffset;
- unsigned long objnum;
- unsigned long objnamlen;
- SymItem objval;
- int objexists = 0;
- int clash = 0;
-
- cfpop_value(scratch, &symsize);
- cfpop_value(scratch, &numsyms);
- cfpop_value(scratch, &objnum);
- cfpop_value(scratch, &objnamlen);
- if(objnamlen > 0) {
- objname = malloc(objnamlen);
- cfpop_data(scratch, objname, objnamlen);
- } else {
- objname = fileof(path);
- objnamlen = strlen(objname)+1;
- }
- cfpop_value(scratch, &objsize);
- cfpop_value(scratch, &objoffset);
-
- /* Get space for a chunk of symbols */
- sympack = malloc(symsize+1);
- packx = 0;
-
- if((objnamlen + curliblen) > 255)
- {
- cfprintf("%s -- name too long. CONTINUING\n", objname);
- continue;
- }
- /* Check the object file for current existence */
- curobjlen = cfsprintf(curobj, "%s/%s", curlib, objname);
- if(cffind(ipaths, curobj, curobjlen, &objval) >= FOUND)
- {
- objexists = 1;
- if(!(act & (arREPLACE|arUPDATE))) {
- cfprintf("%s found in archive. CONTINUING\n", curobj);
- continue;
- }
- }
- /* Pass 1 over the symbols, check for clashes */
- for(j = 0; j < numsyms; ++j)
- {/* The global symbols for each .o file have been saved
- in 'sratch', keyed by (objnum<<18+symnum) */
- Item symptr;
- long key = (objnum<<18)+j;
- SymItem symval;
- int x;
- if(cffind(scratch, &key, 4, &symptr) == FOUND)
- {
- char *cp = cflocalize(scratch, &symptr);
- if(cp)
- {
- /* Add to the quick access pack of symbols */
- x = _strcpy(&sympack[packx], cp)+1;
- if(!objexists)
- {/* Check for symbol clash with other .o files in lib */
- long dupnum = 0;
- for(;;)
- {/* Duplicate symbols are allowed, in separate libs */
- int result = cffind_dupnum(msyms,cp,x-1,&symval,&dupnum);
- if(result >= FOUND)
- {
- if( symval.libtype == libtype
- && symval.libnum == libnum)
- {
- clash = 1;
- }
- if(!clash && result > FOUND)
- {/* Duplicate symbols exist */
- ++dupnum;
- continue;
- } else break;
- } else break;
- }
- }/* if(!objexists) */
- cfrelease(cp, R_CLEAN);
- if(clash)
- {
- char pathname[256];
-
- pathname[0] = 0;
- cfget(qipaths, &symval, 8, pathname, 256);
- cfprintf("cfar: symbol `%s' in %s clashes with `%s' CONTINUING\n",
- &sympack[packx], objname, pathname);
- break;
- }
- packx += x;
- }/* if(cp) */
- }/* if(cffind ) */
- }/* END: for(j ) symbol pass 1 */
- if(clash || !(act & (arADD|arREPLACE|arUPDATE)))
- continue;
-
- /* NOW add or replace the object file */
- if(verbose || act == arUPDATE)
- {
- if(act == arUPDATE)
- cfprintf("updating %s\n",objname);
- else cfprintf("%s\n", objname);
- }
- if(objexists) {
- delete_file(objname, 1);
- } else {/* Get a new serial number for the .o file */
- objval.sn = new_sn("SN0");
- objval.libnum = libnum;
- objval.libtype = libtype;
- objval.unused = 0;
- objval.tag = STO_VALUE;
- }
-
- /* Store the object file in a chunk */
- #if 1 /* the easy slow way, not much memory usage */
- {
- void *of;
- if((of = cfmake_chunk(lib, objname, objnamlen-1, objsize)))
- {
- if(cfcopy_file(of, desc) != objsize)
- {
- cfclose(of);
- cfprintf("cfar: ERROR copying %s\n", objname);
- break;
- }
- cfclose(of);
- }
- else
- {
- cfprintf("cfar: ERROR can't make chunk for %s\n", objname);
- break;
- }
- }
- #else /* the hard fast way, may use a LOT of memory */
- {
- Item space;
- char *loc;
- if(cfgetspace(lib, objsize, &space) != NULL)
- {/* ensure that there is enough space in the localizer bufs */
- long curbufs, objbufs;
- objbufs = (objsize / 1024)+1;
- curbufs = cfcurbufs();
- if(objbufs > curbufs)
- {
- cfmodbufs((objbufs-curbufs)+16);
- objbufs = cfcurbufs();
- }
- if((loc = cflocalize(lib, &space)) != NULL) {
- cfseek(desc, objoffset, S_SET);
- cfread(desc, loc, objsize);
- cfrelease(loc, R_DIRTY);
- cfinsert(lib, objname, objnamlen-1, &space);
- } else {
- cfretspace(lib, &space);
- cfprintf("cfar: ERROR can't localize space for %s\n", objname);
- break;
- }
- }
- else
- {
- cfprintf("cfar: ERROR can't allocate space for %s\n", objname);
- break;
- }
- }
- #endif
- /* Store the quick access package of symbols */
- objname[objnamlen-2] = 'x';
- sympack[symsize] = 0;
- cfput(lib, objname, objnamlen-1, sympack, symsize+1, NULL);
-
- /* Store the backlink to the origin, time + origin serial number */
- objname[objnamlen-2] = 't';
- cfinsert(lib, objname, objnamlen-1, &cur_org);
-
- /* Store the path, indexed both ways */
- cfinsert(ipaths, curobj, curobjlen, &objval);
- cfput(qipaths, &objval, 8, curobj, curobjlen+1, NULL);
-
- /* Store the symbols, symname is the key, objval is the item */
- /* Pass 2 over the symbols */
- for(j = 0; j < numsyms; ++j)
- {/* The global symbols for each .o file have been saved
- in 'scratch', keyed by (objnum<<18+symnum) */
- Item symptr;
- long key = (objnum<<18)+j;
- if(cffind(scratch, &key, 4, &symptr) == FOUND)
- {
- char *cp;
- if((cp = cflocalize(scratch, &symptr)) != NULL) {
- cfinsert_dupnum(msyms, cp, strlen(cp), &objval, NULL);
- cfrelease(cp, R_CLEAN);
- } else {
- cfprintf("cfar: ERROR can't localize space for symbol %d\n", j);
- break;
- }
- }
- }
- }/* END: for(numobjs) */
- cfclose(scratch);
- cfclose(desc);
- }/* END: if(desc) */
- else cfprintf("cfar: can't open file %s, CONTINUING\n", path);
- }
- static void
- proc_objfile(char *path)
- {
- if(issymbol && (act == arCHECK))
- {
- objof(path);
- return;
- }
- if(act & arEXTRACT)
- extract_file(path);
- if(act & arDELETE)
- delete_file(path, 0);
- if(act & (arADD|arREPLACE|arCHECK|arUPDATE))
- insert_file(path);
- }
- static void
- print_map(char *arch)
- {
- char path[256];
- void *dirh;
- CFDIRENT *d;
- int i, j;
-
- cfprintf("MAP of %s\n", arch);
- if(map_entries) {
- cfprintentries(arch);
- cfsprintf(path, "%s/ipaths", arch);
- cfprintentries(path);
- cfsprintf(path, "%s/qipaths", arch);
- cfprintentries(path);
- cfsprintf(path, "%s/origins", arch);
- cfprintentries(path);
- cfsprintf(path, "%s/qorigins", arch);
- cfprintentries(path);
- cfsprintf(path, "%s/msyms", arch);
- cfprintentries(path);
- }
- /* Print a list of origins */
- cfprintf("\n-------- OUTSIDE ORIGINS ----------\n\n");
- cfsprintf(path, "%s/origins", arch);
- if((origins = cfopen(path, F_STAT, NULL)) != NULL)
- {
- Item orgnum;
- if(cfhead(origins, &orgnum) == OK)
- {
- do {
- memclr(path, 255);
- cfkey(origins, path, 255);
- cfprintf("oid:%u\t%s\n", orgnum.a0, path);
- } while(cfnext(origins, &orgnum) == OK);
- }
- cfclose(origins);
- }
- /* Print the various libraries and entries */
- cfprintf("\n-------- LIBRARIES ----------\n\n");
-
- get_libtypes(arch);
- for(i = 0; i < MAXLIBTYPE; ++i)
- {
- if(!ltypes[i])
- continue;
- cfsprintf(path, "%s/ltype%d", arch, i);
- cfprintf("\nLibrary type %d\n", i);
- get_libnums(path);
- if(map_entries) {
- cfprintf("------------ RAW ENTRIES -----------\n");
- cfprintentries(path);
- }
- if(i == 3)
- {/* dllmode library */
- cfprintf("DLL SYMBOL ENTRIES\n");
- continue;
- }
- for(j = 0; j < 4096; ++j)
- {
- void *clib;
- if(!lnums[j])
- continue;
- cfsprintf(path, "%s/ltype%d/lib%d", arch, i, j);
- if((clib = cfopen(path, F_STAT, NULL)) != NULL) {
- if(verbose)
- cfprintf("------- lib%d %d bytes -------\n",
- j, cfbytesused(clib));
- else
- cfprintf("------- lib%d --------\n", j);
- cfhead(clib, NULL);
- do {
- char key[256];
- int keylen;
- memclr(key,256);
- cfkey(clib, key, 255);
- keylen = strlen(key);
- if(key[keylen-1] == 'o') {
- if(verbose) {
- int dlen;
- OrgItem oi;
- cfdatalen(clib, &dlen);
- key[keylen-1] = 't';
- cffind(clib, key, keylen, &oi);
- key[keylen-1] = 'o';
- cfprintf(" %s bytes:%u oid:%u %s",
- key, dlen, oi.sn, ctime(&oi.filetime));
- }
- else
- cfprintf(" %s\n", key);
- if(verbose) {
- Item pakval;
- char *cp, *sp;
- key[keylen-1] = 'x';
- cfmark(clib);
- cffind(clib, key, keylen, &pakval);
- cp = cflocalize(clib, &pakval);
- for(sp=cp; *sp; sp += strlen(sp)+1)
- {
- cfprintf(" %s\n", sp);
- }
- cfrelease(cp, R_CLEAN);
- cffind_mark(clib, NULL);
- }
- }
- } while (cfnext(clib, NULL) == OK);
- if(map_entries) {
- cfprintf("------------ RAW ENTRIES -----------\n");
- cfprintentries(clib);
- }
- cfclose(clib);
- }
- }
- }
- /* Print the list of stored files */
- cfprintf("\n---------- STORED FILES ----------\n\n");
- cfsprintf(path, "%s/fipaths", arch);
- if((fipaths = cfopen(path, F_STAT, NULL)) != NULL)
- {
- OrgItem oi;
- if(cfhead(fipaths, &oi) == OK)
- {
- do {
- memclr(path, 255);
- cfkey(fipaths, path, 255);
- cfprintf("%s\toid:%u %s",
- path, oi.sn, ctime(&oi.filetime));
- } while(cfnext(fipaths, &oi) == OK);
- }
- if(map_entries) {
- cfprintf("------------ RAW ENTRIES -----------\n");
- cfprintentries(fipaths);
- }
- cfclose(fipaths);
- }
- if(map_bitmaps) {
- cfprintf("\n------------ BITMAPS ---------------\n");
- cfprintbitmaps(arch);
- }
- }
- static void
- Usage()
- {
- cfprintf("\
- Usage: cfar [-acdflmrstvxCDFMNS] cfpath [file...]\n\
- Switch -- Meaning\n\
- a Add file, do not overwrite\n\
- c Check input files against library for clashes\n\
- d Delete file\n\
- f Freshen the archive (replace outdated files)\n\
- l# Place file in libnum #, max:4095\n\
- m Print archive map to stdout\n\
- r Replace/Add file\n\
- s 'file' is a symbol name not a file name (for extract/delete)\n\
- t# Set libtype # 0=module, 1=class, 2=subsystem, max:15\n\
- v Verbose\n\
- x Extract file\n\
- M Print to stdout, commands which would recreate the archive\n\
- S Shrink archive\n\
- D Dll mode, deal with symbols stored in dlls\n\
- F File mode, symbols not saved\n\
- C If File mode, put file in a chunk\n\
- N If File mode, give input file a new name (last part of cfpath)\n\
- ");
- }
- static int
- get_nameparts(char *name)
- {
- int namlen = strlen(name);
- int i,j;
-
- basefile[0] = 0;
- midpath[0] = 0;
- innerpath[0] = 0;
- midpart = 0;
- if((lastpart = strrchr(name, '/')) != NULL)
- ++lastpart;
- if(newname && !lastpart)
- {
- cfprintf("cfar: new filename enabled but not supplied\n");
- Usage();
- return 1;
- }
- for(i = namlen-1; i >= 0; --i)
- {
- if( name[i] == 'f'
- && name[i-1] == 'f'
- && name[i-2] == 'c'
- && name[i-3] == '.')
- {
- _strncpy(basefile, name, i+1);
-
- if(&name[i] > lastpart)
- {/* basefile is all there is */
- lastpart = NULL;
- }
- else if(&name[i] != lastpart-2)
- {/* there is more than just a root directory mentioned */
- midpart = &name[i]+2;
- _strncpy(midpath, midpart, (int)(lastpart-midpart-1));
- }
- j = 0;
- if(midpart)
- {
- innerpath[0] = '/';
- j = _strcpy(&innerpath[1], midpath);
- ++j;
- }
- if(lastpart && !newname)
- {
- innerpath[j++] = '/';
- strcpy(&innerpath[j], lastpart);
- }
- }
- }
- return 0;
- }
- static void
- shrink_archive(char *name)
- {
- void *x;
- void *y;
-
- cfprintf("cfar: shrink_archive %s\n", name);
- if(verbose)
- cfprintf("cfar: copy in\n");
- x = cfcopy("MEMORY/shrink", name);
- if(verbose)
- cfprintf("cfar: copy out\n");
- y = cfcopy(name, x);
- if(verbose)
- cfprintf("cfar: clean up\n");
- cfunlink(x, NULL);
- cfclose(y);
- }
- static void
- stat_file(OrgItem *op, char *name, long namlen, long typ, long num,
- char *arch, void *scratch)
- {
- Item orgtag;
- char orgpath[1024];
- char *in;
- long orglen;
- long sn = op->sn;
-
- cfget(qorigins, &sn, 4, &orgpath, 1023);
- orglen = strlen(orgpath);
-
- if(typ >= 0 && orgpath[orglen-1] == 'a' && orgpath[orglen-2] == '.')
- {/* This origin is a library */
- /* Mark this origin or return if it has been marked */
- orgtag.a2.size = op->sn;
- orgtag.a0 = typ<<4 + num;
- orgtag.a2.type = STO_VALUE;
- /* libraries are handled differently */
- if(cfinsert(scratch, &orgtag, 8, &orgtag) != OK)
- return;
- }
- else if(typ == -3 || typ >= 0)
- {/* This origin is a directory, with an embedded file */
- orgpath[orglen] = '/';
- ++orglen;
- orglen += _strcpy(&orgpath[orglen], name);
- }
- else if(typ == -1)
- {/* this origin is for a filemode entry */
- in = strrchr(name, '/');
- if(name[namlen-1] == '?')
- typ = -2; /* the entry was made with newname */
- else
- {
- orglen += _strcpy(&orgpath[orglen], in);
- orgpath[orglen-1] = 0; /* strip tag */
- }
- }
- /* The origin has not been examined, do it */
- if(freshen)
- {
- CFSTAT s;
- if(cfstat(orgpath, &s) == OK)
- {
- if(s.st_mtime > op->filetime)
- { /* REFRESH THIS ITEM */
- ++orglen;
- if(typ < 0 && typ != -3)
- {
- --namlen; /* clip tag */
- cfpush_data(scratch, name, namlen);
- cfpush_value(scratch, &namlen);
- ++namlen;
- }
- cfpush_data(scratch, orgpath, orglen);
- cfpush_value(scratch, &orglen);
- cfpush_value(scratch, &typ);
- cfpush_value(scratch, &num);
- }
- }
- else
- cfprintf("cannot stat %s, CONTINUING\n", orgpath);
- }
- if(batfile)
- {
- if(typ == -3)
- {/* dllmode entry */
- cfprintf("cfar -Dr %s %s\n", arch, orgpath);
- }
- else if(typ < 0)
- {/* filemode entry */
- int c = (num == 1) ? 'C' : ' '; /* chunk flag */
- if(typ == -2)
- {/* rename needed */
- name[namlen-1] = 0; /* clip off the tag */
- cfprintf("cfar -FNr%c %s%s %s\n", c, arch, name, orgpath);
- }
- else
- {/* no rename, clip off the last part of name */
- *in = 0;
- cfprintf("cfar -Fr%c %s%s %s\n", c, arch, name, orgpath);
- *in = '/';
- }
- }
- else
- {/* object file entry */
- cfprintf("cfar -rt%dl%d %s %s\n", typ, num, arch, orgpath);
- }
- }
- }
- static void
- scan_archive(char *archname, void *scratch)
- {
- int i;
- OrgItem oi;
- void *clib;
-
- /* Check stored object files */
- get_libtypes(archname);
- for(i = 0; i < MAXLIBTYPE; ++i)
- {
- char path[256];
- int j;
- if(!ltypes[i])
- continue;
- cfsprintf(path, "%s/ltype%d", archname, i);
- get_libnums(path);
- if(i == 3)
- {/* dllmode libtype */
- if((clib = cfopen(path, F_RDONLY, NULL)))
- {
- if(cfhead(clib, &oi) == OK)
- {
- do {
- char key[256];
- int keylen;
- char *cp;
- memclr(key,256);
- cfkey(clib, key, 255);
- keylen = strlen(key);
-
- if((cp = strstr(key, ".org")))
- {
- *cp = 0;
- stat_file(&oi, key, keylen-4, -3, 0, archname, scratch);
- }
- } while (cfnext(clib, &oi) == OK);
- }
- cfclose(clib);
- }
- }
- else
- { /* objmode libtype */
- for(j = 0; j < 4096; ++j)
- {
- if(!lnums[j])
- continue;
- cfsprintf(path, "%s/ltype%d/lib%d", archname, i, j);
- if((clib = cfopen(path, F_RDONLY, NULL)))
- {
- if(cfhead(clib, &oi) == OK)
- {
- do {
- char key[256];
- int keylen;
- memclr(key,256);
- cfkey(clib, key, 255);
- keylen = strlen(key);
- if(key[keylen-1] == 't') {
- key[keylen-1] = 'o';
- stat_file(&oi, key, keylen, i, j, archname, scratch);
- }
- } while (cfnext(clib, &oi) == OK);
- }
- cfclose(clib);
- }
- }
- }
- }
- /* Check stored FILEMODE files */
- if(cfhead(fipaths, &oi) == OK)
- {
- do {
- char key[1024];
- int keylen;
- char tag;
- int ischunk;
- CFSTAT sbuf;
- memclr(key,1024);
- cfkey(fipaths, key, 1023);
- keylen = strlen(key);
- tag = key[keylen-1];
- key[keylen-1] = 0;
- if(cfsubstat(archive, &key[1], &sbuf) != OK)
- {
- cfprintf("cfar: can't stat internal file %s\n", key);
- continue;
- }
- if(sbuf.st_mode & M_CHUNK)
- ischunk = 1;
- else
- ischunk = 0;
- key[keylen-1] = tag;
- stat_file(&oi, key, keylen, -1, ischunk, archname, scratch);
- } while (cfnext(fipaths, &oi) == OK);
- }
- }
- static void
- setup_version(int flag, char *archname)
- {
- KeyItem snval = 0;
- cfinsert(archive, "ArVer", 5, &prgversion);
- cfinsert(archive, "SN0", 3, &snval);
- cfinsert(archive, "SN1", 3, &snval);
- cfinsert(archive, "SN2", 3, &snval);
- if(flag)
- cfprintf("cfar: add archive property to %s\n", archname);
- else cfprintf("cfar: create archive %s\n", archname);
- }
- static void
- lose_backslashes(char *cp)
- {
- while(*cp) {
- if(*cp == '\\')
- *cp = '/';
- ++cp;
- }
- }
- #ifdef SKELETON
- int cfar(int argc, char **argv)
- #else
- int main(int argc, char **argv)
- #endif
- {
- int err = 0;
- int i, j;
- long curbufs, newbufs;
-
- #ifndef SKELETON
- cfinit("cfar", 400, NULL);
- if((err = oxlink_init(cf_find_file(argv[0], 0))) == 0)
- {
- #endif
- /* Get the switches */
- for(i = 1; i < argc; ++i)
- {
- int trimsize = 1;
- lose_backslashes(argv[i]);
- if(argv[i][0] == '-')
- {
- for(j=1; argv[i][j]; ++j)
- {
- switch(argv[i][j])
- {
- case 'f':
- freshen = 1;
- break;
- case 'r':
- act = arREPLACE;
- replace = 1;
- break;
- case 'a':
- act = arADD;
- add = 1;
- replace = 0;
- break;
- case 'x':
- act |= arEXTRACT;
- break;
- case 'd':
- act |= arDELETE;
- delete = 1;
- break;
- case 'v':
- verbose = 1;
- break;
- case 'c':
- act = arCHECK;
- add = 0;
- replace = 0;
- break;
- case 'S':
- shrink = 1;
- break;
- case 'l':
- libnum = atol(&argv[i][j+1]);
- if(libnum < 0 || libnum > 4095)
- err = 1;
- break;
- case 't':
- libtype = atol(&argv[i][j+1]);
- if(libtype < 0 || libtype >= MAXLIBTYPE)
- err = 1;
- break;
- case 'm':
- map = 1;
- break;
- case 's':
- issymbol = 1;
- break;
- case 'B':
- map_bitmaps = 1;
- break;
- case 'C':
- chunk = 1;
- break;
- case 'F':
- filemode = 1;
- dllmode = 0;
- break;
- case 'D':
- dllmode = 1;
- filemode = 0;
- break;
- case 'N':
- newname = 1;
- break;
- case 'E':
- map_entries = 1;
- break;
- case 'M':
- batfile = 1;
- break;
- case '?':
- err = 1;
- break;
- default:
- break;
- }
- }/* END: switch */
- trim:
- /* Trim switch */
- for(j = i; j < argc-trimsize; ++j)
- argv[j] = argv[j+trimsize];
- argc -= trimsize;
- --i;
- }/* END: if('-') */
- }/* END: for(argc) (get switches) */
- if(verbose) {
- cfprintf("cff archiver Version:%u Copyright 1993, 1995 Norman D. Culver\n",
- prgversion.a0);
- }
- if(err) Usage();
-
- if(argc > 1)
- err = get_nameparts(argv[1]);
-
- /* Get the archive */
- if(!err && ( (map|shrink|freshen|batfile)
- || (act && argc > 2)
- || (filemode && (act & (arDELETE|arEXTRACT)))
- )
- )
- {
- int mode = F_RDWR;
- int new = 0;
-
- if(act & (arADD|arREPLACE))
- mode |= F_CREAT;
-
- curbufs = cfcurbufs(); /* current size of localizer space */
-
- #ifdef SKELETON
- oxlink_close_libs();
- #endif
- if((archive = cfopen(basefile, mode, NULL)) != NULL)
- {
- if(!(cfobtype(archive) & OB_XFILE))
- {
- #if 0
- cfsetverylazy(archive);
- #endif
- if(cfisnew(archive))
- {/* new file, set up version and serial numbers */
- setup_version(0, basefile);
- new = 1;
- }
- else
- {
- if(cffind(archive, "ArVer", 5, &arversion) < FOUND)
- {/* old .cff file without archive property, enable it */
- setup_version(1, basefile);
- new = 1;
- }
- }
- if(cffind(archive, "ArVer", 5, &arversion) >= FOUND)
- {
- if(arversion.a0 <= prgversion.a0)
- {
- ipaths = cfsubopen(archive,"ipaths",F_RDWR|F_CREAT|F_SORTED,NULL);
- qipaths = cfsubopen(archive,"qipaths",F_RDWR|F_CREAT, NULL);
- origins = cfsubopen(archive,"origins",F_RDWR|F_CREAT|F_SORTED|F_BIGDIR, NULL);
- qorigins = cfsubopen(archive,"qorigins",F_RDWR|F_CREAT, NULL);
- msyms = cfsubopen(archive,"msyms",F_RDWR|F_CREAT|F_SORTED|F_HUGEDIR,NULL);
- fipaths = cfsubopen(archive,"fipaths",F_RDWR|F_CREAT|F_SORTED,NULL);
-
- if(!ipaths) {
- cfprintf("cfar: can't open subdir `ipaths'\n");
- goto xt;
- }
- if(!qipaths) {
- cfprintf("cfar: can't open subdir `ipaths'\n");
- goto xt;
- }
- if(!origins) {
- cfprintf("cfar: can't open subdir `origins'\n");
- goto xt;
- }
- if(!qorigins) {
- cfprintf("cfar: can't open subdir `qorigins'\n");
- goto xt;
- }
- if(!msyms) {
- cfprintf("cfar: can't open subdir `msyms'\n");
- goto xt;
- }
- if(!fipaths) {
- cfprintf("cfar: can't open subdir `fipaths'\n");
- goto xt;
- }
- #if 0
- cfsetverylazy(msyms);
- cfsetverylazy(ipaths);
- cfsetverylazy(qipaths);
- cfsetverylazy(origins);
- cfsetverylazy(qorigins);
- cfsetverylazy(fipaths);
- #endif
- if(dllmode && argc >= 3 && (add || replace || delete))
- {
- libtype = 3;
- libnum = 0;
- for(i = 2; i < argc; ++i)
- {
- lose_backslashes(argv[i]);
- strlwr(argv[i]);
- cur_orgtype = cfpathtrn(argv[i], &cur_orgpath);
- proc_dllmode(argv[i]);
- free(cur_orgpath);
- }
- }
- else if(filemode)
- {/* PROCESS FILES STORED IN FILEMODE */
-
- if(act & (arEXTRACT|arDELETE))
- {
- if(act & arEXTRACT)
- out_entry();
- else
- del_entry();
- }
- else if(add || chunk || newname || replace)
- {
- subdir = open_middle(archive);
- for(i = 2; i < argc; ++i)
- {
- lose_backslashes(argv[i]);
- strlwr(argv[i]);
- cur_orgtype = cfpathtrn(argv[i], &cur_orgpath);
- proc_filemode(argv[i]);
- free(cur_orgpath);
- }
- if(subdir)
- cfclose(subdir);
- }
- else
- {
- cfprintf("cfar: incorrect filemode spec\n");
- }
- }
- else if((argc < 3) && (freshen|batfile) && (!new))
- {/* FRESHEN FILES IN ARCHIVE, OR PRINT BATCHFILE */
- void *scratch = make_scratch();
-
- /* check for files to freshen, print batfile if requested */
- scan_archive(basefile, scratch);
- act = arUPDATE;
- replace = 1;
-
- /* files to freshen will be on the stack */
- while(cfstackdepth(scratch) > 0)
- {
- long filelen;
- cfpop_value(scratch, &libnum);
- cfpop_value(scratch, &libtype);
- cfpop_value(scratch, &filelen);
- cur_orgpath = malloc(filelen);
- cfpop_data(scratch, cur_orgpath, filelen);
-
- if(libtype == -3)
- {/* freshen a dllmode file */
- libtype = 3;
- libnum = 0;
- proc_dllmode(cur_orgpath);
- }
- else if(libtype < 0)
- {/* Freshen a filemode file */
- long namlen, x;
- char *cur_name;
- cfpop_value(scratch, &namlen);
- cur_name = calloc(1, namlen+strlen(basefile)+2);
- x = _strcpy(cur_name, basefile);
- cfpop_data(scratch, &cur_name[x], namlen);
- chunk = (libnum == 1) ? 1 : 0;
- newname = (libtype == -2) ? 1 : 0;
- if(!newname) cur_name[x] = 0;
-
- get_nameparts(cur_name);
- subdir = open_middle(archive);
-
- proc_filemode(cur_orgpath);
- if(subdir)
- cfclose(subdir);
- free(cur_name);
- }
- else if(open_curlib())
- {/* Freshen an object file */
- proc_objfile(cur_orgpath);
- }
- free(cur_orgpath);
- }/* END: freshen files on stack */
- cfclose(scratch);
- }
- else if(argc > 2)
- {/* PROCESS OBJECT FILES STORED WITH SYMBOL TABLES */
- if(open_curlib())
- {/* Process the input files */
- for(i = 2; i < argc; ++i)
- {
- if(!issymbol)
- {
- lose_backslashes(argv[i]);
- strlwr(argv[i]);
- }
- cur_orgtype = cfpathtrn(argv[i], &cur_orgpath);
- proc_objfile(argv[i]);
- free(cur_orgpath);
- }
- }
- }
- cfclose(lib);
- cfclose(plib);
- cfclose(msyms);
- cfclose(ipaths);
- cfclose(qipaths);
- cfclose(origins);
- cfclose(qorigins);
- cfclose(fipaths);
- cfclose(archive);
-
- if(shrink) shrink_archive(basefile);
- if(map) print_map(basefile);
-
- cfmodbufs(curbufs-cfcurbufs()); /* reset localizer space */
-
- } else cfprintf("cfar: a version %u archive cannot be processed by a version %u program\n", arversion.a0, prgversion.a0);
- } else cfprintf("cfar: %s is not an archive\n", basefile);
- } else cfprintf("cfar: %s is not a cff database\n", basefile);
- } else cfprintf("cfar: can't open archive %s\n", basefile);
- } else {cfprintf("cfar: insufficient args\n"); Usage();}
- #ifndef SKELETON
- } else cfprintf("cfar: cannot find executable %s\n", argv[0]);
- xt:
- cfexit();
- return 0;
- #else
- xt:
- return 0;
- #endif
- }
-