📄 cfar.c
字号:
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
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -