Skip to content
Snippets Groups Projects
Commit 93804ef7 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Officially deprecate the ADDFILES and DELFILES utilities

These were problematic (crash, could corrupt filebases) and unsupported,
so just change the programs to stubs that alert the sysop that they need to
switch to using the JS versions of these utilities immediately.
parent 892e5caa
No related branches found
No related tags found
1 merge request!455Update branch with changes from master
/* Add files to a Synchronet file database(s) */
/* DEPRECATED: Add files to a Synchronet file database(s) */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
......@@ -19,807 +19,12 @@
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "nopen.h"
#include "str_util.h"
#include "datewrap.h"
#include "date_str.h"
#include "userdat.h"
#include "filedat.h"
#include "load_cfg.h"
#include "getstats.h"
#include "smblib.h"
#include "git_branch.h"
#include "git_hash.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#define ADDFILES_VER "3.19"
scfg_t scfg;
long files=0,removed=0,mode=0;
char lib[LEN_GSNAME+1];
const char* datefmt = NULL;
#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)
#define CHECK_DATE (1L<<15)
/****************************************************************************/
/* This is needed by load_cfg.c */
/****************************************************************************/
int lprintf(int level, const char *fmat, ...)
{
va_list argptr;
char sbuf[512];
int chcount;
va_start(argptr,fmat);
chcount=vsprintf(sbuf,fmat,argptr);
va_end(argptr);
truncsp(sbuf);
printf("%s\n",sbuf);
return(chcount);
}
/****************************************************************************/
/* Updates dsts.ini file */
/****************************************************************************/
void updatestats(off_t size)
int main(int argc, char** argv)
{
inc_upload_stats(&scfg, 1, size);
fprintf(stderr, "\nThe 'addfiles' utility has been deprecated and replaced by 'addfiles.js'\n");
fprintf(stderr, "\nSee https://wiki.synchro.net/module:addfiles for details\n");
return EXIT_FAILURE;
}
bool reupload(smb_t* smb, file_t* f)
{
char path[MAX_PATH + 1];
if(smb_renewfile(smb, f, SMB_SELFPACK, getfilepath(&scfg, f, path)) != SMB_SUCCESS) {
fprintf(stderr, "!Error renewing: %s\n", f->name);
return false;
}
return true;
}
bool get_file_diz(file_t* f, char* ext, size_t maxlen)
{
char path[MAX_PATH + 1];
printf("Extracting DIZ from: %s\n", getfilepath(&scfg, f, path));
char diz_fpath[MAX_PATH + 1];
if(!extract_diz(&scfg, f, /* diz_fnames */NULL, diz_fpath, sizeof(diz_fpath))) {
printf("DIZ does not exist in: %s\n", getfilepath(&scfg, f, path));
return false;
}
printf("Parsing DIZ: %s\n", diz_fpath);
char* lines = read_diz(diz_fpath, NULL);
format_diz(lines, ext, maxlen, 0, false);
free_diz(lines);
remove(diz_fpath);
if(mode&ASCII_ONLY)
strip_exascii(ext, ext);
if(!(mode&KEEP_DESC)) {
char* fdesc = strdup(ext);
smb_new_hfield_str(f, SMB_FILEDESC, prep_file_desc(fdesc, fdesc));
free(fdesc);
}
return true;
}
void addlist(char *inpath, uint dirnum, const char* uploader, 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 *p;
char ext[1024];
int i;
off_t l;
BOOL exist;
FILE *stream;
DIR* dir;
DIRENT* dirent;
smb_t smb;
file_t f;
int result = smb_open_dir(&scfg, &smb, dirnum);
if(result != SMB_SUCCESS) {
fprintf(stderr, "!Error %d (%s) opening %s\n", result, smb.last_error, smb.file);
return;
}
str_list_t fname_list = loadfilenames(&smb, ALLFILES, /* time: */0, FILE_SORT_NATURAL, /* count: */NULL);
if(mode&SEARCH_DIR) {
SAFECOPY(str, scfg.dir[dirnum]->path);
printf("Searching %s\n\n",str);
dir=opendir(str);
while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
SAFEPRINTF2(filepath, "%s%s"
,scfg.dir[dirnum]->path
,dirent->d_name);
if(isdir(filepath))
continue;
const char* fname = getfname(filepath);
printf("%s ", fname);
if(strListFind(fname_list, fname, /* case-sensitive: */FALSE) && (mode&NO_UPDATE)) {
printf("already added.\n");
continue;
}
memset(ext, 0, sizeof(ext));
memset(&f, 0, sizeof(f));
char fdesc[LEN_FDESC + 1] = {0};
off_t cdt = flength(filepath);
time_t file_timestamp = fdate(filepath);
printf("%10"PRIuOFF" %s\n"
,cdt, unixtodstr(&scfg,(time32_t)file_timestamp,str));
exist = smb_findfile(&smb, fname, &f) == SMB_SUCCESS;
if(exist) {
if(mode&NO_UPDATE)
continue;
if((mode&CHECK_DATE) && file_timestamp <= f.idx.time)
continue;
if(mode&ULDATE_ONLY) {
reupload(&smb, &f);
continue;
}
}
if(mode&TODAYS_DATE) { /* put today's date in desc */
time_t now = time(NULL);
if(datefmt) {
struct tm tm = {0};
localtime_r(&now, &tm);
strftime(fdesc, sizeof(fdesc), datefmt, &tm);
} else
unixtodstr(&scfg, (time32_t)now, fdesc);
SAFECAT(fdesc," ");
}
else if(mode&FILE_DATE) { /* get the file date and put into desc */
if(datefmt) {
struct tm tm = {0};
localtime_r(&file_timestamp, &tm);
strftime(fdesc, sizeof(fdesc), datefmt, &tm);
} else
unixtodstr(&scfg,(time32_t)file_timestamp,fdesc);
SAFECAT(fdesc," ");
}
char* ext_desc = NULL;
if(mode&FILE_ID) {
if(get_file_diz(&f, ext, sizeof(ext))) {
ext_desc = ext;
}
}
prep_file_desc(fdesc, fdesc);
if(mode&ASCII_ONLY)
strip_exascii(fdesc, fdesc);
smb_hfield_str(&f, SMB_FILENAME, fname);
smb_hfield_str(&f, SMB_FILEDESC, fdesc);
smb_hfield_str(&f, SENDER, uploader);
smb_hfield_bin(&f, SMB_COST, cdt);
truncsp(ext_desc);
if(exist) {
result = smb_updatemsg(&smb, &f);
if(!(mode&NO_NEWDATE))
reupload(&smb, &f);
}
else
result = smb_addfile(&smb, &f, SMB_SELFPACK, ext_desc, NULL, filepath);
smb_freefilemem(&f);
if(result != SMB_SUCCESS)
fprintf(stderr, "!Error %d (%s) adding file to %s", result, smb.last_error, smb.file);
if(mode&UL_STATS)
updatestats(cdt);
files++;
}
if(dir!=NULL)
closedir(dir);
smb_close(&smb);
strListFree(&fname_list);
return;
}
SAFECOPY(listpath,inpath);
fexistcase(listpath);
if((stream=fopen(listpath,"r"))==NULL) {
fprintf(stderr,"Error %d (%s) opening %s\n"
,errno,strerror(errno),listpath);
SAFEPRINTF2(listpath, "%s%s", scfg.dir[dirnum]->path, inpath);
fexistcase(listpath);
if((stream=fopen(listpath,"r"))==NULL) {
printf("Can't open: %s\n"
" or: %s\n",inpath,listpath);
smb_close(&smb);
strListFree(&fname_list);
return;
}
}
printf("Adding %s to %s %s\n\n"
,listpath,scfg.lib[scfg.dir[dirnum]->lib]->sname,scfg.dir[dirnum]->sname);
if(fgets(nextline,255,stream) == NULL)
*nextline = '\0';
do {
char fdesc[LEN_FDESC + 1] = {0};
memset(ext, 0, sizeof(ext));
SAFECOPY(curline,nextline);
nextline[0]=0;
if(fgets(nextline,255,stream) == NULL)
*nextline = '\0';
truncsp(curline);
if(curline[0]<=' ' || (mode&ASCII_ONLY && (uchar)curline[0]>=0x7e))
continue;
printf("%s\n",curline);
SAFECOPY(fname,curline);
p=strchr(fname,' ');
if(p) *p=0;
#if 0 // allow import of bare filename list
else /* no space after filename? */
continue;
#endif
if(!IS_ALPHANUMERIC(*fname)) { // filename doesn't begin with an alpha-numeric char?
continue;
}
SAFEPRINTF2(filepath, "%s%s", scfg.dir[dirnum]->path, fname);
if(strcspn(fname,"\\/|<>+[]:=\";,")!=strlen(fname)) {
fprintf(stderr, "!Illegal filename: %s\n", fname);
continue;
}
time_t file_timestamp = fdate(filepath);
memset(&f, 0, sizeof(f));
exist = smb_findfile(&smb, fname, &f) == SMB_SUCCESS;
if(exist) {
if(mode&NO_UPDATE)
continue;
if((mode&CHECK_DATE) && file_timestamp <= f.idx.time)
continue;
if(mode&ULDATE_ONLY) {
reupload(&smb, &f);
continue;
}
}
if(mode&FILE_DATE) { /* get the file date and put into desc */
unixtodstr(&scfg,(time32_t)file_timestamp, fdesc);
strcat(fdesc, " ");
}
if(mode&TODAYS_DATE) { /* put today's date in desc */
l=time32(NULL);
unixtodstr(&scfg,(time32_t)l,fdesc);
strcat(fdesc, " ");
}
if(dskip && strlen(curline)>=dskip) p=curline+dskip;
else {
p = curline;
FIND_WHITESPACE(p);
SKIP_WHITESPACE(p);
}
SAFECOPY(tmp,p);
prep_file_desc(tmp, tmp);
sprintf(fdesc + strlen(fdesc), "%.*s", (int)(LEN_FDESC-strlen(fdesc)), tmp);
char* ext_desc = NULL;
if(nextline[0]==' ' || strlen(p)>LEN_FDESC) { /* ext desc */
if(!(mode&NO_EXTEND)) {
memset(ext, 0, sizeof(ext));
sprintf(ext,"%s\r\n",p);
ext_desc = ext;
}
if(nextline[0]==' ') {
SAFECOPY(str,nextline); /* tack on to end of desc */
p=str+dskip;
while(*p>0 && *p<=' ') p++;
i=LEN_FDESC-strlen(fdesc);
if(i>1) {
p[i-1]=0;
truncsp(p);
if(p[0]) {
SAFECAT(fdesc," ");
SAFECAT(fdesc,p);
}
}
}
while(!feof(stream) && !ferror(stream) && strlen(ext)<512) {
if(nextline[0]!=' ')
break;
truncsp(nextline);
printf("%s\n",nextline);
if(!(mode&NO_EXTEND)) {
p=nextline+dskip;
ext_desc = ext;
while(*p==' ') p++;
SAFECAT(ext,p);
SAFECAT(ext,"\r\n");
}
nextline[0]=0;
if(fgets(nextline,255,stream) == NULL)
*nextline = '\0';
}
}
l=flength(filepath);
if(l<0L) {
printf("%s not found.\n",filepath);
continue;
}
if(l == 0L) {
printf("%s is a zero length file.\n",filepath);
continue;
}
if(sskip) l=atol(fname+sskip);
if(mode&FILE_ID)
get_file_diz(&f, ext, sizeof(ext));
prep_file_desc(fdesc, fdesc);
if(mode&ASCII_ONLY)
strip_exascii(fdesc, fdesc);
uint32_t cdt = (uint32_t)l;
smb_hfield_bin(&f, SMB_COST, cdt);
smb_hfield_str(&f, SMB_FILENAME, fname);
smb_hfield_str(&f, SMB_FILEDESC, fdesc);
smb_hfield_str(&f, SENDER, uploader);
if(exist) {
result = smb_updatemsg(&smb, &f);
if(!(mode&NO_NEWDATE))
reupload(&smb, &f);
}
else
result = smb_addfile(&smb, &f, SMB_SELFPACK, ext_desc, NULL, filepath);
smb_freefilemem(&f);
if(result != SMB_SUCCESS)
fprintf(stderr, "!ERROR %d (%s) writing to %s\n"
, result, smb.last_error, smb.file);
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);
}
smb_close(&smb);
strListFree(&fname_list);
}
void synclist(char *inpath, int dirnum)
{
char str[1024];
char listpath[MAX_PATH+1];
char* p;
int found;
long l;
FILE* stream;
file_t* f;
file_t* file_list;
smb_t smb;
SAFECOPY(listpath,inpath);
if((stream=fopen(listpath,"r"))==NULL) {
sprintf(listpath,"%s%s", scfg.dir[dirnum]->path,inpath);
if((stream=fopen(listpath,"r"))==NULL) {
printf("Can't open: %s\n"
" or: %s\n",inpath,listpath);
return;
}
}
int result = smb_open_dir(&scfg, &smb, dirnum);
if(result != SMB_SUCCESS) {
fprintf(stderr, "!Error %d (%s) opening %s\n", result, smb.last_error, smb.file);
fclose(stream);
return;
}
size_t file_count;
file_list = loadfiles(&smb, NULL, 0, file_detail_normal, FILE_SORT_NATURAL, &file_count);
printf("\nSynchronizing %s with %s %s\n\n"
,listpath,scfg.lib[scfg.dir[dirnum]->lib]->sname,scfg.dir[dirnum]->sname);
for(l = 0; l < (long)file_count; l++) {
f = &file_list[l];
rewind(stream);
found=0;
while(!found) {
if(!fgets(str,1000,stream))
break;
truncsp(str);
p=strchr(str,' ');
if(p) *p=0;
if(!stricmp(str, f->name))
found=1;
}
if(found)
continue;
printf("%s not found in list - ", f->name);
if(smb_removefile(&smb, f) != SMB_SUCCESS)
fprintf(stderr, "!ERROR (%s) removing file from database\n", smb.last_error);
else {
if(remove(getfilepath(&scfg, f, str)))
printf("Error removing %s\n",str);
removed++;
printf("Removed from database\n");
}
}
freefiles(file_list, file_count);
if(mode&DEL_LIST) {
printf("\nDeleting %s\n",listpath);
remove(listpath);
}
smb_close(&smb);
fclose(stream);
}
char *usage="\nusage: addfiles code [-opts] +list "
"[desc_off] [size_off]"
"\n or: addfiles code [-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 -F <fmt> include file date in descriptions, using strftime format"
"\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)"
"\n"
"\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];
const char *p;
char exist,listgiven=0,namegiven=0,ext[LEN_EXTDESC + 1]
,auto_name[MAX_PATH+1]="FILES.BBS";
int i,j;
uint desc_offset=0, size_offset=0;
long l;
smb_t smb;
file_t f;
int dirnum = INVALID_DIR;
fprintf(stderr,"\nADDFILES v%s-%s %s/%s - Adds Files to Synchronet "
"Filebase\n"
,ADDFILES_VER
,PLATFORM_DESC
,GIT_BRANCH
,GIT_HASH
);
if(argc<2) {
puts(usage);
return(1);
}
p = get_ctrl_dir(/* warn: */true);
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, /* text: */NULL, /* prep: */TRUE, /* node: */FALSE, error, sizeof(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));
memset(&smb, 0, sizeof(smb));
if(argv[1][0]=='*' || argv[1][0]=='-') {
if(argv[1][1]=='?') {
puts(usage);
exit(0);
}
if(argv[1][1])
SAFECOPY(auto_name,argv[1]+1);
mode|=AUTO_ADD;
i=0;
} else {
if(!IS_ALPHANUMERIC(argv[1][0]) && argc==2) {
puts(usage);
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);
}
dirnum = i;
}
memset(&f,0,sizeof(f));
const char* uploader = "-> ADDFILES <-";
for(j=2;j<argc;j++) {
if(argv[j][0]=='*') /* set the uploader name (legacy) */
uploader = 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) {
puts(usage);
return(-1);
}
SAFECOPY(lib,argv[j]);
i=strlen(argv[j])-1;
break;
case 'X':
j++;
if(argv[j]==NULL) {
puts(usage);
return(-1);
}
uploader = 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 'P':
mode|=CHECK_DATE;
break;
case 'U':
mode|=NO_NEWDATE;
break;
case 'F':
mode|=FILE_DATE;
if(argv[j][i] == 'F') {
j++;
if(argv[j]==NULL) {
puts(usage);
return(-1);
}
datefmt = argv[j];
i=strlen(argv[j]) - 1;
break;
}
break;
case 'T':
mode|=TODAYS_DATE;
break;
case 'S':
mode|=SEARCH_DIR;
break;
default:
puts(usage);
return(1);
}
}
else if(IS_DIGIT(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;
if(argc > j+1
&& IS_DIGIT(argv[j+1][0])) { /* skip x characters before description */
if(argc > j+2
&& IS_DIGIT(argv[j+2][0])) { /* skip x characters before size */
addlist(argv[j]+1, dirnum, uploader, atoi(argv[j+1]), atoi(argv[j+2]));
j+=2;
}
else {
addlist(argv[j]+1, dirnum, uploader, atoi(argv[j+1]), 0);
j++;
}
}
else
addlist(argv[j]+1, dirnum, uploader, 0, 0);
if(mode&SYNC_LIST)
synclist(argv[j]+1, dirnum);
}
else {
namegiven=1;
const char* fname = argv[j];
char fdesc[LEN_FDESC + 1] = {0};
if(j+1==argc) {
printf("%s no description given.\n",fname);
SAFECOPY(fdesc, "no description given");
}
SAFEPRINTF2(str,"%s%s", scfg.dir[dirnum]->path, fname);
if(mode&FILE_DATE)
SAFEPRINTF(fdesc, "%s ", unixtodstr(&scfg,(time32_t)fdate(str),tmp));
else if(mode&TODAYS_DATE)
SAFEPRINTF(fdesc, "%s ", unixtodstr(&scfg,time32(NULL),tmp));
j++;
SAFECAT(fdesc, argv[j]);
l=(long)flength(str);
if(l==-1) {
printf("%s not found.\n",str);
continue;
}
if(SMB_IS_OPEN(&smb))
smb_close(&smb);
int result = smb_open_dir(&scfg, &smb, dirnum);
if(result != SMB_SUCCESS) {
fprintf(stderr, "!ERROR %d (%s) opening %s\n", result, smb.last_error, smb.file);
exit(EXIT_FAILURE);
}
exist = smb_findfile(&smb, fname, &f) == SMB_SUCCESS;
if(exist) {
if(mode&NO_UPDATE)
continue;
if((mode&CHECK_DATE) && fdate(str) <= f.idx.time)
continue;
if(mode&ULDATE_ONLY) {
reupload(&smb, &f);
continue;
}
}
memset(&f, 0, sizeof(f));
prep_file_desc(fdesc, fdesc);
if(mode&ASCII_ONLY)
strip_exascii(fdesc, fdesc);
smb_hfield_str(&f, SMB_FILENAME, fname);
smb_hfield_str(&f, SMB_FILEDESC, fdesc);
smb_hfield_str(&f, SENDER, uploader);
uint32_t cdt = (uint32_t)l;
smb_hfield_bin(&f, SMB_COST, cdt);
printf("%s %7"PRIu64" %s\n",fname, (int64_t)l, fdesc);
char* ext_desc = NULL;
if(get_file_diz(&f, ext, sizeof(ext)))
ext_desc = ext;
if(exist) {
if(!(mode&NO_NEWDATE))
reupload(&smb, &f);
else
result = smb_updatemsg(&smb, &f);
}
else
result = smb_addfile(&smb, &f, SMB_SELFPACK, ext_desc, NULL, str);
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;
dirnum = i;
if(mode&SEARCH_DIR) {
addlist("", dirnum, uploader, desc_offset, size_offset);
continue;
}
sprintf(str,"%s%s.lst",scfg.dir[dirnum]->path,scfg.dir[dirnum]->code);
if(fexistcase(str) && flength(str)>0L) {
printf("Auto-adding %s\n",str);
addlist(str, dirnum, uploader, desc_offset, size_offset);
if(mode&SYNC_LIST)
synclist(str,i);
continue;
}
SAFEPRINTF2(str,"%s%s",scfg.dir[dirnum]->path,auto_name);
if(fexistcase(str) && flength(str)>0L) {
printf("Auto-adding %s\n",str);
addlist(str, dirnum, uploader, desc_offset, size_offset);
if(mode&SYNC_LIST)
synclist(str,i);
continue;
}
}
}
else {
if(!listgiven && !namegiven) {
sprintf(str,"%s%s.lst",scfg.dir[dirnum]->path, scfg.dir[dirnum]->code);
if(!fexistcase(str) || flength(str)<=0L)
SAFEPRINTF2(str,"%s%s",scfg.dir[dirnum]->path, auto_name);
addlist(str, dirnum, uploader, desc_offset, size_offset);
if(mode&SYNC_LIST)
synclist(str, dirnum);
}
}
printf("\n%lu file(s) added.",files);
if(removed)
printf("\n%lu files(s) removed.",removed);
printf("\n");
return(0);
}
......@@ -158,32 +158,6 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="dat_rec.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="date_str.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="filedat.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="getstats.c" />
<ClCompile Include="sauce.c" />
<ClCompile Include="userdat.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\smblib\smblib.vcxproj">
......
/* Program to delete expired files from a Synchronet file database */
/* DEPRECATED: Program to delete expired files from a Synchronet file database */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
......@@ -19,276 +19,12 @@
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "scfgdefs.h"
#include "load_cfg.h"
#include "filedat.h"
#include "nopen.h"
#include "smblib.h"
#include "str_util.h"
#include <stdarg.h>
#include <stdbool.h>
#include "git_branch.h"
#include "git_hash.h"
#include <stdio.h>
#include <stdlib.h>
#define DELFILES_VER "3.19"
char tmp[256];
char *crlf="\r\n";
#define MAX_NOTS 25
#define ALL (1L<<0)
#define OFFLINE (1L<<1)
#define NO_LINK (1L<<2)
#define REPORT (1L<<3)
void bail(int code)
{
exit(code);
}
long lputs(char *str)
{
char tmp[256];
int i,j,k;
j=strlen(str);
for(i=k=0;i<j;i++) /* remove CRs */
if(str[i]==CR && str[i+1]==LF)
continue;
else
tmp[k++]=str[i];
tmp[k]=0;
return(fputs(tmp,stdout));
}
/****************************************************************************/
/* Performs printf() through local assembly routines */
/* Called from everywhere */
/****************************************************************************/
int lprintf(const char *fmat, ...)
{
va_list argptr;
char sbuf[256];
int chcount;
va_start(argptr,fmat);
chcount=vsprintf(sbuf,fmat,argptr);
va_end(argptr);
lputs(sbuf);
return(chcount);
}
bool delfile(const char *filename)
{
if(remove(filename) != 0) {
fprintf(stderr, "ERROR %u (%s) removing file %s\n"
,errno, strerror(errno), filename);
return false;
}
return true;
}
int main(int argc, char **argv)
int main(int argc, char** argv)
{
char str[256],not[MAX_NOTS][LEN_EXTCODE + 1],nots=0;
const char *p;
char fpath[MAX_PATH+1];
int i,j,dirnum,libnum;
size_t fi;
long misc=0;
time_t now = time(NULL);
scfg_t cfg;
glob_t gl;
setvbuf(stdout,NULL,_IONBF,0);
fprintf(stderr,"\nDELFILES Version %s-%s %s/%s - Removes files from Synchronet "
"Filebase\n" ,DELFILES_VER, PLATFORM_DESC, GIT_BRANCH, GIT_HASH);
if(argc<2) {
printf("\n usage: %s <dir_code or * for ALL> [switches]\n", argv[0]);
printf("\nswitches: -lib name All directories of specified library\n");
printf(" -all Search all directories\n");
printf(" -not code Exclude specific directory\n");
printf(" -off Remove files that are offline "
"(don't exist on disk)\n");
printf(" -nol Remove files with no link "
"(don't exist in database)\n");
printf(" -rpt Report findings only "
"(don't delete any files)\n");
return(0);
}
p = get_ctrl_dir(/* warn: */TRUE);
memset(&cfg, 0, sizeof(cfg));
cfg.size=sizeof(cfg);
SAFECOPY(cfg.ctrl_dir, p);
backslash(cfg.ctrl_dir);
load_cfg(&cfg, /* text: */NULL, /* prep: */TRUE, /* node: */FALSE, str, sizeof(str));
if(chdir(cfg.ctrl_dir) != 0) {
fprintf(stderr, "ERROR %d (%s) changing directory to: %s"
,errno, strerror(errno), cfg.ctrl_dir);
return EXIT_FAILURE;
}
dirnum=libnum=-1;
if(argv[1][0]=='*')
misc|=ALL;
else if(argv[1][0]!='/' && argv[1][0]!='-') {
strupr(argv[1]);
for(i=0;i<cfg.total_dirs;i++)
if(!stricmp(argv[1],cfg.dir[i]->code))
break;
if(i>=cfg.total_dirs) {
printf("\nDirectory code '%s' not found.\n",argv[1]);
return(1);
}
dirnum=i;
}
for(i=1;i<argc;i++) {
if(!stricmp(argv[i]+1,"LIB")) {
if(dirnum!=-1) {
printf("\nBoth directory code and /LIB parameters were used.\n");
return(1);
}
i++;
if(i>=argc) {
printf("\nLibrary short name must follow /LIB parameter.\n");
return(1);
}
strupr(argv[i]);
for(j=0;j<cfg.total_libs;j++)
if(!stricmp(cfg.lib[j]->sname,argv[i]))
break;
if(j>=cfg.total_libs) {
printf("\nLibrary short name '%s' not found.\n",argv[i]);
return(1);
}
libnum=j;
}
else if(!stricmp(argv[i]+1,"NOT")) {
if(nots>=MAX_NOTS) {
printf("\nMaximum number of /NOT options (%u) exceeded.\n"
,MAX_NOTS);
return(1);
}
i++;
if(i>=argc) {
printf("\nDirectory internal code must follow /NOT parameter.\n");
return(1);
}
SAFECOPY(not[nots], argv[i]);
nots++;
}
else if(!stricmp(argv[i]+1,"OFF"))
misc|=OFFLINE;
else if(!stricmp(argv[i]+1,"NOL"))
misc|=NO_LINK;
else if(!stricmp(argv[i]+1,"RPT"))
misc|=REPORT;
else if(!stricmp(argv[i]+1,"ALL")) {
if(dirnum!=-1) {
printf("\nBoth directory code and /ALL parameters were used.\n");
return(1);
}
if(libnum!=-1) {
printf("\nBoth library name and /ALL parameters were used.\n");
return(1);
}
misc|=ALL;
}
}
for(i=0;i<cfg.total_dirs;i++) {
if(!(misc&ALL) && i!=dirnum && cfg.dir[i]->lib!=libnum)
continue;
for(j=0;j<nots;j++)
if(!stricmp(not[j], cfg.dir[i]->code))
break;
if(j<nots)
continue;
smb_t smb;
int result = smb_open_dir(&cfg, &smb, i);
if(result != SMB_SUCCESS) {
fprintf(stderr, "!ERROR %d (%s) opening %s\n", result, smb.last_error, smb.file);
continue;
}
if(misc&NO_LINK && cfg.dir[i]->misc&DIR_FCHK) {
printf("\nSearching %s for unlinked files\n", cfg.dir[i]->path);
sprintf(str, "%s%s", cfg.dir[i]->path, ALLFILES);
if(glob(str, GLOB_MARK, NULL, &gl) == 0) {
for(j=0; j<(int)gl.gl_pathc; j++) {
const char* fname = gl.gl_pathv[j];
/* emulate _A_NORMAL */
if(isdir(fname))
continue;
if(access(fname, R_OK|W_OK))
continue;
if(!smb_findfile(&smb, getfname(fname), /* file: */NULL)) {
printf("Not in database: %s\n", fname);
if(!(misc&REPORT))
delfile(fname);
}
}
}
globfree(&gl);
}
if(!cfg.dir[i]->maxage && !(misc&OFFLINE)) {
smb_close(&smb);
continue;
}
printf("\nScanning %s %s\n", cfg.lib[cfg.dir[i]->lib]->sname, cfg.dir[i]->lname);
size_t file_count;
file_t* file_list = loadfiles(&smb, NULL, /* since: */0, file_detail_normal, FILE_SORT_NATURAL, &file_count);
for(fi = 0; fi < file_count; fi++) {
file_t* f = &file_list[fi];
getfilepath(&cfg, f, fpath);
if(cfg.dir[i]->maxage && cfg.dir[i]->misc&DIR_SINCEDL && f->hdr.last_downloaded
&& (now - f->hdr.last_downloaded)/86400L > cfg.dir[i]->maxage) {
printf("Deleting %s (%ld days since last download)\n"
,f->name
,(long)(now - f->hdr.last_downloaded)/86400L);
if(!(misc&REPORT)) {
if(smb_removefile(&smb, f) == SMB_SUCCESS)
delfile(fpath);
else
printf("ERROR (%s) removing file from database\n", smb.last_error);
}
}
else if(cfg.dir[i]->maxage
&& !(f->hdr.last_downloaded && cfg.dir[i]->misc&DIR_SINCEDL)
&& (now - f->hdr.when_imported.time)/86400L > cfg.dir[i]->maxage) {
printf("Deleting %s (uploaded %ld days ago)\n"
,f->name
,(long)(now - f->hdr.when_imported.time)/86400L);
if(!(misc&REPORT)) {
if(smb_removefile(&smb, f) == SMB_SUCCESS)
delfile(fpath);
else
printf("ERROR (%s) removing file from database\n", smb.last_error);
}
}
else if(misc&OFFLINE && cfg.dir[i]->misc&DIR_FCHK && !fexist(fpath)) {
printf("Removing %s (doesn't exist)\n", f->name);
if(!(misc&REPORT)) {
if(smb_removefile(&smb, f) != SMB_SUCCESS)
printf("ERROR (%s) removing file from database\n", smb.last_error);
}
}
}
freefiles(file_list, file_count);
smb_close(&smb);
}
return(0);
fprintf(stderr, "\nThe 'delfiles' utility has been deprecated and replaced by 'delfiles.js'\n");
fprintf(stderr, "\nSee https://wiki.synchro.net/module:delfiles for details\n");
return EXIT_FAILURE;
}
......@@ -144,27 +144,12 @@
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dat_rec.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="delfiles.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="filedat.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="getstats.c" />
<ClCompile Include="sauce.c" />
<ClCompile Include="userdat.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\smblib\smblib.vcxproj">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment