Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commits (1)
......@@ -273,3 +273,92 @@ bool sbbs_t::movefile(smb_t* smb, file_t* f, int newdir)
return true;
}
bool sbbs_t::editfilename(file_t* f)
{
char str[MAX_FILENAME_LEN + 1];
char tmp[MAX_PATH + 1];
char path[MAX_PATH + 1];
char dirpath[MAX_PATH + 1];
bputs(text[EditFilename]);
SAFECOPY(str, f->name);
if(!getstr(str, sizeof(str) - 1, K_EDIT|K_AUTODEL))
return false;
if(strcmp(str,f->name) != 0) { /* rename */
if(stricmp(str,f->name)
&& findfile(&cfg, f->dir, path, NULL))
bprintf(text[FileAlreadyThere],path);
else {
SAFEPRINTF2(path,"%s%s",dirpath,f->name);
SAFEPRINTF2(tmp,"%s%s",dirpath,str);
if(fexistcase(path) && rename(path,tmp))
bprintf(text[CouldntRenameFile],path,tmp);
else {
bprintf(text[FileRenamed],path,tmp);
smb_new_hfield_str(f, SMB_FILENAME, str);
updatefile(&cfg, f);
}
}
}
return true;
}
bool sbbs_t::editfileinfo(file_t* f)
{
char str[MAX_PATH + 1];
// Description
bputs(text[EditDescription]);
char fdesc[LEN_FDESC + 1];
SAFECOPY(fdesc, f->desc);
getstr(fdesc, sizeof(fdesc)-1, K_LINE|K_EDIT|K_AUTODEL|K_TRIM);
if(sys_status&SS_ABORT)
return false;
if(strcmp(fdesc, f->desc))
smb_new_hfield_str(f, SMB_FILEDESC, fdesc);
// Tags
if((cfg.dir[f->dir]->misc & DIR_FILETAGS) || dir_op(f->dir)) {
char tags[64] = "";
bputs(text[TagFilePrompt]);
if(f->tags != NULL)
SAFECOPY(tags, f->tags);
getstr(tags, sizeof(tags)-1, K_LINE|K_EDIT|K_AUTODEL|K_TRIM);
if(sys_status&SS_ABORT)
return false;
if((f->tags == NULL && *tags != '\0') || (f->tags != NULL && strcmp(tags, f->tags)))
smb_new_hfield_str(f, SMB_TAGS, tags);
}
// Extended Description
if(f->extdesc != NULL && *f->extdesc) {
if(!noyes(text[DeleteExtDescriptionQ])) {
// TODO
}
}
if(dir_op(f->dir)) {
char uploader[LEN_ALIAS + 1];
SAFECOPY(uploader, f->from);
bputs(text[EditUploader]);
if(!getstr(uploader, sizeof(uploader), K_EDIT|K_AUTODEL))
return false;
smb_new_hfield_str(f, SMB_FILEUPLOADER, uploader);
ultoa(f->cost,str,10);
bputs(text[EditCreditValue]);
getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL);
if(sys_status&SS_ABORT)
return false;
f->cost = atol(str);
smb_new_hfield(f, SMB_COST, sizeof(f->cost), &f->cost);
ultoa(f->hdr.times_downloaded,str,10);
bputs(text[EditTimesDownloaded]);
getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL);
if(sys_status&SS_ABORT)
return false;
f->hdr.times_downloaded=atoi(str);
if(sys_status&SS_ABORT)
return false;
inputnstime32((time32_t*)&f->hdr.when_imported.time);
}
return updatefile(&cfg, f);
}
......@@ -834,82 +834,10 @@ int sbbs_t::listfileinfo(uint dirnum, const char *filespec, long mode)
continue;
case 'E': /* edit file information */
if(dir_op(dirnum)) {
bputs(text[EditFilename]);
SAFECOPY(str, f->name);
if(!getstr(str, MAX_FILENAME_LEN, K_EDIT|K_AUTODEL))
if(!editfilename(f))
break;
if(strcmp(str,f->name) != 0) { /* rename */
if(stricmp(str,f->name)
&& findfile(&cfg, f->dir, path, NULL))
bprintf(text[FileAlreadyThere],path);
else {
SAFEPRINTF2(path,"%s%s",dirpath,f->name);
SAFEPRINTF2(tmp,"%s%s",dirpath,str);
if(fexistcase(path) && rename(path,tmp))
bprintf(text[CouldntRenameFile],path,tmp);
else {
bprintf(text[FileRenamed],path,tmp);
smb_new_hfield_str(f, SMB_FILENAME, str);
updatefile(&cfg, f);
}
}
}
}
// Description
bputs(text[EditDescription]);
char fdesc[LEN_FDESC + 1];
SAFECOPY(fdesc, f->desc);
getstr(fdesc, sizeof(fdesc)-1, K_LINE|K_EDIT|K_AUTODEL|K_TRIM);
if(sys_status&SS_ABORT)
break;
if(strcmp(fdesc, f->desc))
smb_new_hfield_str(f, SMB_FILEDESC, fdesc);
// Tags
if((cfg.dir[dirnum]->misc & DIR_FILETAGS) || dir_op(dirnum)) {
char tags[64] = "";
bputs(text[TagFilePrompt]);
if(f->tags != NULL)
SAFECOPY(tags, f->tags);
getstr(tags, sizeof(tags)-1, K_LINE|K_EDIT|K_AUTODEL|K_TRIM);
if(sys_status&SS_ABORT)
break;
if((f->tags == NULL && *tags != '\0') || (f->tags != NULL && strcmp(tags, f->tags)))
smb_new_hfield_str(f, SMB_TAGS, tags);
}
// Extended Description
if(f->extdesc != NULL && *f->extdesc) {
if(!noyes(text[DeleteExtDescriptionQ])) {
// TODO
}
}
if(!dir_op(dirnum)) {
updatefile(&cfg, f);
break;
}
char uploader[LEN_ALIAS + 1];
SAFECOPY(uploader, f->from);
bputs(text[EditUploader]);
if(!getstr(uploader, sizeof(uploader), K_EDIT|K_AUTODEL))
break;
smb_new_hfield_str(f, SMB_FILEUPLOADER, uploader);
ultoa(f->cost,str,10);
bputs(text[EditCreditValue]);
getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL);
if(sys_status&SS_ABORT)
break;
f->cost = atol(str);
smb_new_hfield(f, SMB_COST, sizeof(f->cost), &f->cost);
ultoa(f->hdr.times_downloaded,str,10);
bputs(text[EditTimesDownloaded]);
getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL);
if(sys_status&SS_ABORT)
break;
f->hdr.times_downloaded=atoi(str);
if(sys_status&SS_ABORT)
break;
inputnstime32((time32_t*)&f->hdr.when_imported.time);
updatefile(&cfg, f);
editfileinfo(f);
break;
case 'F': /* delete file only */
SAFEPRINTF2(str,"%s%s",dirpath,f->name);
......
......@@ -1046,6 +1046,8 @@ public:
bool addtobatdl(file_t*);
bool clearbatdl(void);
bool clearbatul(void);
bool editfilename(file_t*);
bool editfileinfo(file_t*);
long delfiles(const char *inpath, const char *spec, size_t keep = 0);
/* listfile.cpp */
......
......@@ -241,7 +241,7 @@ enum {
,ProtocolBatchOrQuit
,BatchUlQueueIsFull
,FileAddedToUlQueue
,UserToUserXferNodeMsg
,FileInfoEditPrompt
,FileInfoPrompt
,QuitOrNext
,RExemptRemoveFilePrompt
......
......@@ -376,14 +376,17 @@ const char * const text_defaults[TOTAL_TEXT]={
,"\x0d\x0a\x01\x6e\x01\x6d\x01\x68\x25\x73\x20\x01\x6e\x01\x6d\x61\x64\x64\x65\x64\x20\x74\x6f\x20\x62\x61\x74\x63\x68\x20\x75\x70"
"\x6c\x6f\x61\x64\x20\x71\x75\x65\x75\x65\x01\x63\x20\x2d\x20\x46\x69\x6c\x65\x73\x3a\x20\x01\x68\x25\x75\x20\x01\x6e\x01\x63\x28"
"\x01\x68\x25\x75\x01\x6e\x01\x63\x20\x4d\x61\x78\x29\x0d\x0a" // 230 FileAddedToUlQueue
,"\x55\x6e\x75\x73\x65\x64\x20\x32\x33\x31" // 231 UserToUserXferNodeMsg
,"\x01\x6e\x01\x3f\x01\x67\x01\x68\x25\x73\x01\x79\x3a\x20\x01\x77\x7e\x42\x01\x79\x61\x74\x63\x68\x20\x64\x6f\x77\x6e\x6c\x6f\x61"
"\x64\x2c\x20\x01\x77\x7e\x45\x01\x79\x64\x69\x74\x20\x69\x6e\x66\x6f\x2c\x20\x01\x77\x7e\x56\x01\x79\x69\x65\x77\x20\x66\x69\x6c"
"\x65\x2c\x20\x01\x77\x7e\x51\x01\x79\x75\x69\x74\x2c\x20\x01\x77\x7e\x50\x01\x79\x72\x65\x76\x20\x6f\x72\x20\x5b\x7e\x4e\x65\x78"
"\x74\x5d\x3a\x20\x01\x77" // 231 FileInfoEditPrompt
,"\x01\x6e\x01\x3f\x01\x67\x01\x68\x25\x73\x01\x79\x3a\x20\x01\x77\x7e\x42\x01\x79\x61\x74\x63\x68\x20\x64\x6f\x77\x6e\x6c\x6f\x61"
"\x64\x2c\x20\x01\x77\x7e\x45\x01\x79\x78\x74\x65\x6e\x64\x65\x64\x20\x69\x6e\x66\x6f\x2c\x20\x01\x77\x7e\x56\x01\x79\x69\x65\x77"
"\x20\x66\x69\x6c\x65\x2c\x20\x01\x77\x7e\x51\x01\x79\x75\x69\x74\x2c\x20\x01\x77\x7e\x50\x01\x79\x72\x65\x76\x20\x6f\x72\x20\x5b"
"\x7e\x4e\x65\x78\x74\x5d\x3a\x20\x01\x77" // 232 FileInfoPrompt
,"\x0d\x0a\x7e\x51\x75\x69\x74\x20\x6f\x72\x20\x5b\x7e\x4e\x65\x78\x74\x5d\x3a\x20" // 233 QuitOrNext
,"\x7e\x52\x65\x6d\x6f\x76\x65\x2c\x20\x7e\x4d\x6f\x76\x65\x2c\x20\x7e\x45\x64\x69\x74\x2c\x20\x7e\x56\x69\x65\x77\x2c\x20\x7e\x51"
"\x75\x69\x74\x2c\x20\x6f\x72\x20\x5b\x7e\x4e\x65\x78\x74\x5d\x3a\x20" // 234 RExemptRemoveFilePrompt
"\x75\x69\x74\x2c\x20\x7e\x50\x72\x65\x76\x20\x6f\x72\x20\x5b\x7e\x4e\x65\x78\x74\x5d\x3a\x20" // 234 RExemptRemoveFilePrompt
,"\x01\x6e\x28\x25\x64\x29\x20\x25\x73\x0d\x0a" // 235 MoveToLibLstFmt
,"\x01\x5f\x0d\x0a\x01\x79\x01\x68\x4c\x69\x62\x72\x61\x72\x79\x20\x5b\x25\x64\x5d\x3a\x20\x01\x6e" // 236 MoveToLibPrompt
,"\x01\x6e\x28\x25\x64\x29\x20\x25\x73\x0d\x0a" // 237 MoveToDirLstFmt
......@@ -393,8 +396,8 @@ const char * const text_defaults[TOTAL_TEXT]={
,"\x7e\x52\x65\x6d\x6f\x76\x65\x2c\x20\x7e\x43\x72\x65\x64\x69\x74\x73\x20\x6f\x6e\x6c\x79\x2c\x20\x7e\x46\x69\x6c\x65\x20\x6f\x6e"
"\x6c\x79\x2c\x20\x7e\x4d\x6f\x76\x65\x2c\x20\x7e\x45\x64\x69\x74\x2c\x20\x7e\x56\x69\x65\x77\x2c\x20\x7e\x51\x75\x69\x74\x2c\x20"
"\x7e\x50\x72\x65\x76\x20\x6f\x72\x20\x5b\x7e\x4e\x65\x78\x74\x5d\x3a\x20" // 241 SysopRemoveFilePrompt
,"\x7e\x52\x65\x6d\x6f\x76\x65\x2c\x20\x7e\x45\x64\x69\x74\x2c\x20\x7e\x56\x69\x65\x77\x2c\x20\x7e\x51\x75\x69\x74\x2c\x20\x6f\x72"
"\x20\x5b\x7e\x4e\x65\x78\x74\x5d\x3a\x20" // 242 UserRemoveFilePrompt
,"\x7e\x52\x65\x6d\x6f\x76\x65\x2c\x20\x7e\x45\x64\x69\x74\x2c\x20\x7e\x56\x69\x65\x77\x2c\x20\x7e\x51\x75\x69\x74\x2c\x20\x7e\x50"
"\x72\x65\x76\x20\x6f\x72\x20\x5b\x7e\x4e\x65\x78\x74\x5d\x3a\x20" // 242 UserRemoveFilePrompt
,"\x0d\x0a\x01\x6e\x01\x72\x01\x68\x46\x69\x6c\x65\x20\x64\x6f\x65\x73\x20\x6e\x6f\x74\x20\x65\x78\x69\x73\x74\x3a\x20\x01\x63\x25"
"\x73\x01\x6e\x0d\x0a" // 243 FileDoesNotExist
,"\x07\x0d\x0a\x01\x72\x01\x68\x01\x69\x43\x6f\x75\x6c\x64\x6e\x27\x74\x20\x72\x65\x6d\x6f\x76\x65\x20\x27\x25\x73\x27\x2e\x01\x6e"
......
......@@ -35,14 +35,17 @@ int sbbs_t::viewfile(file_t* f, bool ext)
format_filename(f->name, fname, sizeof(fname)-1, /* pad: */FALSE);
curdirnum=f->dir; /* for ARS */
bool can_edit = dir_op(f->dir) || useron.exempt&FLAG('R') || stricmp(f->from, useron.alias) == 0;
while(online) {
sys_status &= ~SS_ABORT;
if(ext)
SAFEPRINTF(str, text[FileInfoPrompt], fname);
if(ext) {
showfileinfo(f);
else
if(can_edit)
SAFEPRINTF(str, text[FileInfoEditPrompt], fname);
} else
viewfilecontents(f);
ASYNC;
SAFEPRINTF(str, text[FileInfoPrompt], fname);
mnemonics(str);
ch=(char)getkeys("BEVQPN\b-\r",0);
if(ch=='Q' || sys_status&SS_ABORT)
......@@ -53,10 +56,13 @@ int sbbs_t::viewfile(file_t* f, bool ext)
CRLF;
return(-1);
case 'E':
ext=1;
if(ext && can_edit)
editfileinfo(f);
else
ext = true;
continue;
case 'V':
ext=0;
ext = false;
continue;
case 'P':
case '\b':
......