Newer
Older
/* Program to add files to a Synchronet file database */
/* $Id$ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sbbs.h"
#include <stdbool.h>
#define ADDFILES_VER "3.04"
scfg_t scfg;
int cur_altpath=0;
long files=0,removed=0,mode=0;
char lib[LEN_GSNAME+1];
#define DEL_LIST (1L<<0)
#define NO_EXTEND (1L<<1)
#define FILE_DATE (1L<<2)
#define TODAYS_DATE (1L<<3)
#define FILE_ID (1L<<4)
#define NO_UPDATE (1L<<5)
#define NO_NEWDATE (1L<<6)
#define ASCII_ONLY (1L<<7)
#define UL_STATS (1L<<8)
#define ULDATE_ONLY (1L<<9)
#define KEEP_DESC (1L<<10)
#define AUTO_ADD (1L<<11)
#define SEARCH_DIR (1L<<12)
#define SYNC_LIST (1L<<13)
#define KEEP_SPACE (1L<<14)
/****************************************************************************/
/* This is needed by load_cfg.c */
/****************************************************************************/
int lprintf(int level, const char *fmat, ...)
int chcount;
va_start(argptr,fmat);
chcount=vsprintf(sbuf,fmat,argptr);
va_end(argptr);
truncsp(sbuf);
printf("%s\n",sbuf);
void prep_desc(char *str)
{
char tmp[1024];
int i,j;
for(i=j=0;str[i] && j < sizeof(tmp)-1;i++) {
if(j && str[i]==' ' && tmp[j-1]==' ' && (mode&KEEP_SPACE))
tmp[j++]=str[i];
else if(j && str[i]<=' ' && str[i] > 0&& tmp[j-1]==' ')
continue;
else if(i && !isalnum((uchar)str[i]) && str[i]==str[i-1])
continue;
else if(str[i]>=' ' || str[i]<0)
tmp[j++]=str[i];
else if(str[i]==TAB || (str[i]==CR && str[i+1]==LF))
}
tmp[j]=0;
strcpy(str,tmp);
}
/*****************************************************************************/
/* Returns command line generated from instr with %c replacments */
/*****************************************************************************/
char *mycmdstr(const char *instr, const char *fpath, const char *fspec, char *outstr)
{
static char cmd[MAX_PATH+1];
char str[MAX_PATH+1];
int i,j,len;
#ifdef _WIN32
char sfpath[MAX_PATH+1];
#endif
len=strlen(instr);
for(i=j=0;i<len && j<128;i++) {
if(instr[i]=='%') {
i++;
cmd[j]=0;
switch(toupper(instr[i])) {
case 'F': /* File path */
strcat(cmd,fpath);
break;
case '~': /* DOS-compatible (8.3) filename */
#ifdef _WIN32
SAFECOPY(sfpath,fpath);
GetShortPathName(fpath,sfpath,sizeof(sfpath));
strcat(cmd,sfpath);
#else
strcat(cmd,fpath);
#endif
break;
case 'G': /* Temp directory */
strcat(cmd,scfg.temp_dir);
break;
case 'J':
strcat(cmd,scfg.data_dir);
break;
case 'K':
strcat(cmd,scfg.ctrl_dir);
break;
case 'N': /* Node Directory (same as SBBSNODE environment var) */
strcat(cmd,scfg.node_dir);
break;
case 'S': /* File Spec */
strcat(cmd,fspec);
break;
case 'Z':
strcat(cmd,scfg.text_dir);
break;
case '!': /* EXEC Directory */
strcat(cmd,scfg.exec_dir);
break;
case '@': /* EXEC Directory for DOS/OS2/Win32, blank for Unix */
#ifndef __unix__
strcat(cmd,scfg.exec_dir);
#endif
break;
case '#': /* Node number (same as SBBSNNUM environment var) */
sprintf(str,"%d",scfg.node_num);
strcat(cmd,str);
break;
case '%': /* %% for percent sign */
strcat(cmd,"%");
break;
default: /* unknown specification */
break;
j=strlen(cmd);
cmd[j++]=instr[i];
}
cmd[j]=0;
return(cmd);
}
/****************************************************************************/
/* Updates dstst.dab file */
/****************************************************************************/
void updatestats(ulong size)
{
char str[MAX_PATH+1];
int file;
sprintf(str,"%sdsts.dab",scfg.ctrl_dir);
if((file=nopen(str,O_RDWR|O_BINARY))==-1) {
printf("ERR_OPEN %s\n",str);
return;
}
lseek(file,20L,SEEK_SET); /* Skip timestamp, logons and logons today */
read(file,&l,4); /* Uploads today */
l++;
lseek(file,-4L,SEEK_CUR);
write(file,&l,4);
read(file,&l,4); /* Upload bytes today */
l+=size;
lseek(file,-4L,SEEK_CUR);
write(file,&l,4);
close(file);
}
bool get_file_diz(file_t* f, const char* filepath)
{
int i,file;
char tmp[MAX_PATH+1];
char ext[1024],tmpext[513];
for(i=0;i<scfg.total_fextrs;i++)
if(!stricmp(scfg.fextr[i]->ext,f->name+9)
&& chk_ar(&scfg,scfg.fextr[i]->ar,/* user: */NULL, /* client: */NULL))
break;
// If we could not find an extractor which matches our requirements, use any
if(i >= scfg.total_fextrs) {
for(i=0;i<scfg.total_fextrs;i++)
if(!stricmp(scfg.fextr[i]->ext,f->name+9))
break;
}
if(i >= scfg.total_fextrs)
return false;
SAFEPRINTF(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
removecase(tmp);
system(mycmdstr(scfg.fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
if(!fexistcase(tmp)) {
SAFEPRINTF(tmp,"%sDESC.SDI",scfg.temp_dir);
removecase(tmp);
system(mycmdstr(scfg.fextr[i]->cmd,filepath,"DESC.SDI",NULL));
fexistcase(tmp);
if((file=nopen(tmp,O_RDONLY|O_BINARY)) == -1)
return false;
memset(ext,0,513);
read(file,ext,512);
for(i=512;i;i--)
if(ext[i-1]>' ' || ext[i-1]<0)
break;
ext[i]=0;
if(mode&ASCII_ONLY)
strip_exascii(ext, ext);
if(!(mode&KEEP_DESC)) {
sprintf(tmpext,"%.256s",ext);
prep_desc(tmpext);
for(i=0;tmpext[i];i++)
if(isalpha((uchar)tmpext[i]))
break;
sprintf(f->desc,"%.*s",LEN_FDESC,tmpext+i);
for(i=0;(f->desc[i]>=' ' || f->desc[i]<0) && i<LEN_FDESC;i++)
;
f->desc[i]=0; }
close(file);
f->misc|=FM_EXTDESC;
return true;
}
void addlist(char *inpath, file_t f, uint dskip, uint sskip)
{
char str[MAX_PATH+1];
char tmp[MAX_PATH+1];
char fname[MAX_PATH+1];
char listpath[MAX_PATH+1];
char filepath[MAX_PATH+1];
char curline[256],nextline[256];
char ext[1024];
int i;
FILE *stream;
DIR* dir;
DIRENT* dirent;
if(mode&SEARCH_DIR) {
SAFECOPY(str,cur_altpath ? scfg.altpath[cur_altpath-1] : scfg.dir[f.dir]->path);
printf("Searching %s\n\n",str);
dir=opendir(str);
while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
sprintf(tmp,"%s%s"
,cur_altpath ? scfg.altpath[cur_altpath-1] : scfg.dir[f.dir]->path
,dirent->d_name);
if(isdir(tmp))
continue;
#ifdef _WIN32
GetShortPathName(tmp, filepath, sizeof(filepath));
#else
SAFECOPY(filepath,tmp);
#endif
f.misc=0;
f.desc[0]=0;
f.cdt=flength(filepath);
padfname(getfname(filepath),f.name);
,f.name,f.cdt,unixtodstr(&scfg,(time32_t)file_timestamp,str));
exist=findfile(&scfg,f.dir,f.name);
if(exist) {
if(mode&NO_UPDATE)
continue;
if(!getfileixb(&scfg,&f)) {
fprintf(stderr, "!ERROR reading index of directory %u\n", f.dir);
continue;
}
if((mode&CHECK_DATE) && file_timestamp <= f.dateuled)
continue;
update_uldate(&scfg, &f);
continue;
}
}
if(mode&FILE_DATE) { /* get the file date and put into desc */
unixtodstr(&scfg,(time32_t)file_timestamp,f.desc);
strcat(f.desc," ");
}
if(mode&TODAYS_DATE) { /* put today's date in desc */
unixtodstr(&scfg,time32(NULL),f.desc);
strcat(f.desc," ");
if(mode&FILE_ID)
get_file_diz(&f, filepath);
prep_desc(f.desc);
strip_exascii(f.desc, f.desc);
if(exist) {
putfiledat(&scfg,&f);
if(!(mode&NO_NEWDATE))
update_uldate(&scfg, &f);
}
else
addfiledat(&scfg,&f);
if(f.misc&FM_EXTDESC) {
truncsp(ext);
putextdesc(&scfg,f.dir,f.datoffset,ext);
}
if(mode&UL_STATS)
updatestats(f.cdt);
files++;
}
if(dir!=NULL)
closedir(dir);
return;
SAFECOPY(listpath,inpath);
if((stream=fopen(listpath,"r"))==NULL) {
fprintf(stderr,"Error %d (%s) opening %s\n"
,errno,strerror(errno),listpath);
sprintf(listpath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
: scfg.dir[f.dir]->path,inpath);
fexistcase(listpath);
if((stream=fopen(listpath,"r"))==NULL) {
printf("Can't open: %s\n"
" or: %s\n",inpath,listpath);
return;
}
}
printf("Adding %s to %s %s\n\n"
,listpath,scfg.lib[scfg.dir[f.dir]->lib]->sname,scfg.dir[f.dir]->sname);
fgets(nextline,255,stream);
do {
f.misc=0;
f.desc[0]=0;
SAFECOPY(curline,nextline);
nextline[0]=0;
fgets(nextline,255,stream);
truncsp(curline);
if(curline[0]<=' ' || (mode&ASCII_ONLY && (uchar)curline[0]>=0x7e))
continue;
printf("%s\n",curline);
SAFECOPY(fname,curline);
#if 0 /* Files without dots are valid on modern systems */
p=strchr(fname,'.');
if(!p || p==fname || p>fname+8) /* no dot or invalid dot location */
continue;
#endif
p=strchr(fname,' ');
if(p) *p=0;
else /* no space after filename? */
continue;
#if 0
#endif
SAFECOPY(fname,unpadfname(fname,tmp));
sprintf(filepath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
: scfg.dir[f.dir]->path,fname);
#ifdef _WIN32
{
char shortpath[MAX_PATH+1];
GetShortPathName(filepath, shortpath, sizeof(shortpath));
SAFECOPY(fname, getfname(shortpath));
}
#endif
padfname(fname,f.name);
if(strcspn(f.name,"\\/|<>+[]:=\";,")!=strlen(f.name))
continue;
for(i=0;i<12;i++)
if(f.name[i]<' ' || (mode&ASCII_ONLY && (uchar)f.name[i]>0x7e))
break;
if(i<12) /* Ctrl chars or EX-ASCII in filename? */
continue;
exist=findfile(&scfg,f.dir,f.name);
if(exist) {
if(mode&NO_UPDATE)
continue;
if(!getfileixb(&scfg,&f)) {
fprintf(stderr, "!ERROR reading index of directory %u\n", f.dir);
continue;
}
if((mode&CHECK_DATE) && file_timestamp <= f.dateuled)
continue;
update_uldate(&scfg, &f);
continue;
}
}
if(mode&FILE_DATE) { /* get the file date and put into desc */
unixtodstr(&scfg,(time32_t)file_timestamp,f.desc);
strcat(f.desc," ");
}
if(mode&TODAYS_DATE) { /* put today's date in desc */
unixtodstr(&scfg,l,f.desc);
strcat(f.desc," ");
}
if(dskip && strlen(curline)>=dskip) p=curline+dskip;
else {
p = curline;
FIND_WHITESPACE(p);
SKIP_WHITESPACE(p);
}
SAFECOPY(tmp,p);
prep_desc(tmp);
sprintf(f.desc+strlen(f.desc),"%.*s",(int)(LEN_FDESC-strlen(f.desc)),tmp);
if(nextline[0]==' ' || strlen(p)>LEN_FDESC) { /* ext desc */
if(!(mode&NO_EXTEND)) {
memset(ext,0,513);
f.misc|=FM_EXTDESC;
sprintf(ext,"%s\r\n",p);
}
SAFECOPY(str,nextline); /* tack on to end of desc */
while(*p>0 && *p<=' ') p++;
i=LEN_FDESC-strlen(f.desc);
if(i>1) {
p[i-1]=0;
truncsp(p);
if(p[0]) {
strcat(f.desc," ");
strcat(f.desc,p);
}
}
}
while(!feof(stream) && !ferror(stream) && strlen(ext)<512) {
break;
truncsp(nextline);
printf("%s\n",nextline);
if(!(mode&NO_EXTEND)) {
f.misc|=FM_EXTDESC;
p=nextline+dskip;
strcat(ext,"\r\n");
}
fgets(nextline,255,stream);
}
}
if(sskip) l=atol(fname+sskip);
else {
l=flength(filepath);
if(l<0L) {
printf("%s not found.\n",filepath);
continue;
}
if(l == 0L) {
printf("%s is a zero-0length file.\n",filepath);
continue;
}
}
if(mode&FILE_ID)
get_file_diz(&f, filepath);
prep_desc(f.desc);
strip_exascii(f.desc, f.desc);
if(exist) {
putfiledat(&scfg,&f);
if(!(mode&NO_NEWDATE))
update_uldate(&scfg, &f);
}
else
addfiledat(&scfg,&f);
if(f.misc&FM_EXTDESC) {
truncsp(ext);
putextdesc(&scfg,f.dir,f.datoffset,ext);
}
if(mode&UL_STATS)
updatestats(l);
files++;
} while(!feof(stream) && !ferror(stream));
fclose(stream);
if(mode&DEL_LIST && !(mode&SYNC_LIST)) {
printf("\nDeleting %s\n",listpath);
remove(listpath);
}
}
void synclist(char *inpath, int dirnum)
{
char fname[MAX_PATH+1];
char listpath[MAX_PATH+1];
uchar* ixbbuf;
int i,file,found;
long l,m,length;
FILE* stream;
file_t f;
sprintf(str,"%s%s.ixb",scfg.dir[dirnum]->data_dir,scfg.dir[dirnum]->code);
if((file=nopen(str,O_RDONLY|O_BINARY))==-1) {
printf("ERR_OPEN %s\n",str);
return;
}
length=filelength(file);
if(length%F_IXBSIZE) {
close(file);
return;
}
if((ixbbuf=(uchar *)malloc(length))==NULL) {
close(file);
printf("ERR_ALLOC %s\n",str);
return;
}
if(lread(file,ixbbuf,length)!=length) {
close(file);
printf("ERR_READ %s\n",str);
return;
}
SAFECOPY(listpath,inpath);
if((stream=fopen(listpath,"r"))==NULL) {
sprintf(listpath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
: scfg.dir[dirnum]->path,inpath);
if((stream=fopen(listpath,"r"))==NULL) {
printf("Can't open: %s\n"
" or: %s\n",inpath,listpath);
return;
}
}
printf("\nSynchronizing %s with %s %s\n\n"
,listpath,scfg.lib[scfg.dir[dirnum]->lib]->sname,scfg.dir[dirnum]->sname);
for(l=0;l<length;l+=F_IXBSIZE) {
m=l;
for(i=0;i<12 && l<length;i++)
if(i==8)
str[i]=ixbbuf[m]>' ' ? '.' : ' ';
else
str[i]=ixbbuf[m++]; /* Turns FILENAMEEXT into FILENAME.EXT */
str[i]=0;
unpadfname(str,fname);
rewind(stream);
found=0;
while(!found) {
if(!fgets(str,1000,stream))
break;
truncsp(str);
if(p) *p=0;
if(!stricmp(str,fname))
found=1;
}
if(found)
continue;
padfname(fname,f.name);
printf("%s not found in list - ",f.name);
f.dir=dirnum;
f.datoffset=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
if(!getfiledat(&scfg,&f)) {
fprintf(stderr, "!ERROR reading index of directory %u\n", f.dir);
continue;
}
if(f.opencount) {
printf("currently OPEN by %u users\n",f.opencount);
continue;
}
if(remove(getfilepath(&scfg,&f,str)))
printf("Error removing %s\n",str);
removed++;
printf("Removed from database\n");
}
if(mode&DEL_LIST) {
printf("\nDeleting %s\n",listpath);
remove(listpath);
}
char *usage="\nusage: addfiles code [.alt_path] [-opts] +list "
"\n or: addfiles code [.alt_path] [-opts] file "
"\"description\"\n"
"\navailable opts:"
"\n -a import ASCII only (no extended ASCII)"
"\n -b synchronize database with file list (use with caution)"
"\n -c do not remove extra spaces from file description"
"\n -d delete list after import"
"\n -e do not import extended descriptions"
"\n -f include file date in descriptions"
"\n -t include today's date in descriptions"
"\n -i include added files in upload statistics"
"\n -n do not update information for existing files"
"\n -o update upload date only for existing files"
"\n -p compare file date with upload date for existing files"
"\n -u do not update upload date for existing files"
"\n -z check for and import FILE_ID.DIZ and DESC.SDI"
"\n -k keep original short description (not DIZ)"
"\n -s search directory for files (no file list)"
"\n -l <lib> specify library (short name) to Auto-ADD"
"\n -x <name> specify uploader's user name (may require quotes)"
"\nAuto-ADD: use - in place of code for Auto-ADD of FILES.BBS"
"\n use -filename to Auto-ADD a different filename"
"\n use -l \"libname\" to only Auto-ADD files to a specific library"
;
/*********************/
/* Entry point (duh) */
/*********************/
int main(int argc, char **argv)
{
char error[512];
char str[MAX_PATH+1];
char tmp[MAX_PATH+1];
char *p;
char exist,listgiven=0,namegiven=0,ext[513]
,auto_name[MAX_PATH+1]="FILES.BBS";
int i,j;
uint desc_offset=0, size_offset=0;
long l;
file_t f;
sscanf("$Revision$", "%*s %s", revision);
fprintf(stderr,"\nADDFILES v%s-%s (rev %s) - Adds Files to Synchronet "
"Filebase\n"
,ADDFILES_VER
,PLATFORM_DESC
return(1);
}
p=getenv("SBBSCTRL");
if(p==NULL) {
printf("\nSBBSCTRL environment variable not set.\n");
printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
exit(1);
memset(&scfg,0,sizeof(scfg));
scfg.size=sizeof(scfg);
SAFECOPY(scfg.ctrl_dir,p);
if(chdir(scfg.ctrl_dir)!=0)
fprintf(stderr,"!ERROR changing directory to: %s", scfg.ctrl_dir);
printf("\nLoading configuration files from %s\n",scfg.ctrl_dir);
if(!load_cfg(&scfg,NULL,TRUE,error)) {
fprintf(stderr,"!ERROR loading configuration files: %s\n",error);
exit(1);
}
SAFECOPY(scfg.temp_dir,"../temp");
prep_dir(scfg.ctrl_dir, scfg.temp_dir, sizeof(scfg.temp_dir));
if(argv[1][0]=='*' || argv[1][0]=='-') {
if(argv[1][1]=='?') {
exit(0);
}
SAFECOPY(auto_name,argv[1]+1);
i=0;
} else {
if(!isalnum((uchar)argv[1][0]) && argc==2) {
return(1);
}
for(i=0;i<scfg.total_dirs;i++)
if(!stricmp(scfg.dir[i]->code,argv[1])) /* use matchmatchi() instead? */
break;
if(i>=scfg.total_dirs) {
printf("Directory code '%s' not found.\n",argv[1]);
exit(1);
}
}
memset(&f,0,sizeof(file_t));
f.dir=i;
SAFECOPY(f.uler,"-> ADDFILES <-");
for(j=2;j<argc;j++) {
if(argv[j][0]=='*') /* set the uploader name (legacy) */
SAFECOPY(f.uler,argv[j]+1);
else
if(argv[j][0]=='-'
|| argv[j][0]=='/'
) { /* options */
for(i=1;argv[j][i];i++)
switch(toupper(argv[j][i])) {
case 'A':
mode|=ASCII_ONLY;
break;
case 'B':
mode|=(SYNC_LIST|NO_UPDATE);
break;
case 'C':
mode|=KEEP_SPACE;
break;
case 'D':
mode|=DEL_LIST;
break;
case 'E':
mode|=NO_EXTEND;
break;
case 'I':
mode|=UL_STATS;
break;
case 'L':
j++;
if(argv[j]==NULL) {
return(-1);
}
SAFECOPY(lib,argv[j]);
i=strlen(argv[j])-1;
break;
case 'X':
j++;
if(argv[j]==NULL) {
return(-1);
}
SAFECOPY(f.uler,argv[j]);
i=strlen(argv[j])-1;
break;
case 'Z':
mode|=FILE_ID;
break;
case 'K':
mode|=KEEP_DESC; /* Don't use DIZ for short desc */
break;
case 'N':
mode|=NO_UPDATE;
break;
case 'O':
mode|=ULDATE_ONLY;
break;
case 'U':
mode|=NO_NEWDATE;
break;
case 'F':
mode|=FILE_DATE;
break;
case 'T':
mode|=TODAYS_DATE;
break;
case 'S':
mode|=SEARCH_DIR;
break;
default:
return(1);
}
}
else if(isdigit((uchar)argv[j][0])) {
if(desc_offset==0)
desc_offset=atoi(argv[j]);
else
size_offset=atoi(argv[j]);
continue;
}
else if(argv[j][0]=='+') { /* filelist - FILES.BBS */
listgiven=1;
&& isdigit((uchar)argv[j+1][0])) { /* skip x characters before description */
&& isdigit((uchar)argv[j+2][0])) { /* skip x characters before size */
addlist(argv[j]+1,f,atoi(argv[j+1]),atoi(argv[j+2]));
j+=2;
}
else {
addlist(argv[j]+1,f,atoi(argv[j+1]),0);
j++;
}
}
else
addlist(argv[j]+1,f,0,0);
if(mode&SYNC_LIST)
synclist(argv[j]+1,f.dir);
}
else if(argv[j][0]=='.') { /* alternate file path */
cur_altpath=atoi(argv[j]+1);
if(cur_altpath>scfg.altpaths) {
printf("Invalid alternate path.\n");
exit(1);
}
}
else {
namegiven=1;
padfname(argv[j],f.name);
f.desc[0]=0;
#if 0
#endif
if(j+1==argc) {
printf("%s no description given.\n",f.name);
continue;
}
sprintf(str,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
: scfg.dir[f.dir]->path,argv[j]);
if(mode&FILE_DATE)
sprintf(f.desc,"%s ",unixtodstr(&scfg,(time32_t)fdate(str),tmp));
sprintf(f.desc,"%s ",unixtodstr(&scfg,time32(NULL),tmp));
sprintf(tmp,"%.*s",(int)(LEN_FDESC-strlen(f.desc)),argv[++j]);
SAFECOPY(f.desc,tmp);
l=flength(str);
if(l==-1) {
printf("%s not found.\n",str);
continue;
}
exist=findfile(&scfg,f.dir,f.name);
if(exist) {
if(mode&NO_UPDATE)
continue;
if(!getfileixb(&scfg,&f)) {
fprintf(stderr, "!ERROR reading index of directory %u\n", f.dir);
continue;
}
if((mode&CHECK_DATE) && fdate(str) <= f.dateuled)
continue;
update_uldate(&scfg, &f);
continue;
}
}
prep_desc(f.desc);
strip_exascii(f.desc, f.desc);
if(mode&FILE_ID)
get_file_diz(&f, str);
if(exist) {
putfiledat(&scfg,&f);
if(!(mode&NO_NEWDATE))
update_uldate(&scfg, &f);
}
else
addfiledat(&scfg,&f);
if(f.misc&FM_EXTDESC)
putextdesc(&scfg,f.dir,f.datoffset,ext);
if(mode&UL_STATS)
updatestats(l);
files++;
}
}
if(mode&AUTO_ADD) {
for(i=0;i<scfg.total_dirs;i++) {
if(lib[0] && stricmp(scfg.lib[scfg.dir[i]->lib]->sname,lib))
continue;
if(scfg.dir[i]->misc&DIR_NOAUTO)
continue;
f.dir=i;
if(mode&SEARCH_DIR) {
addlist("",f,desc_offset,size_offset);
continue;
}
sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path,scfg.dir[f.dir]->code);
if(fexistcase(str) && flength(str)>0L) {
printf("Auto-adding %s\n",str);
addlist(str,f,desc_offset,size_offset);
if(mode&SYNC_LIST)
synclist(str,i);
continue;
}
sprintf(str,"%s%s",scfg.dir[f.dir]->path,auto_name);
if(fexistcase(str) && flength(str)>0L) {
printf("Auto-adding %s\n",str);
addlist(str,f,desc_offset,size_offset);
if(mode&SYNC_LIST)
synclist(str,i);
continue;
}
}
}
else {
if(!listgiven && !namegiven) {
sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path, scfg.dir[f.dir]->code);
if(!fexistcase(str) || flength(str)<=0L)
sprintf(str,"%s%s",scfg.dir[f.dir]->path, auto_name);
addlist(str,f,desc_offset,size_offset);
synclist(str,f.dir);
}
}