|
|
1.1 root 1: /* upload.cpp */
2:
3: /* Synchronet file upload-related routines */
4:
5: /* $Id: upload.cpp,v 1.8 2000/12/31 03:41:55 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
39:
40: /****************************************************************************/
41: /* Adds file data in 'f' to DIR#.DAT and DIR#.IXB and updates user */
42: /* info for uploader. Must have .name, .desc and .dir fields filled prior */
43: /* to a call to this function. */
44: /* Returns 1 if file uploaded sucessfully, 0 if not. */
45: /****************************************************************************/
46: bool sbbs_t::uploadfile(file_t *f)
47: {
48: char path[256],str[256],fname[25],ext[513],desc[513],tmp[128];
49: int file;
50: uint i;
51: long length;
52: FILE *stream;
53:
54: f->misc=0;
55: curdirnum=f->dir;
56: if(findfile(&cfg,f->dir,f->name)) {
57: errormsg(WHERE,ERR_CHK,f->name,f->dir);
58: return(0); }
59: sprintf(path,"%s%s",f->altpath>0 && f->altpath<=cfg.altpaths
60: ? cfg.altpath[f->altpath-1]
61: : cfg.dir[f->dir]->path,unpadfname(f->name,fname));
62: if(!fexist(path)) {
63: bprintf(text[FileNotReceived],f->name);
64: sprintf(str,"Attempted to upload %s to %s %s (Not received)",f->name
65: ,cfg.lib[cfg.dir[f->dir]->lib]->sname,cfg.dir[f->dir]->sname);
66: logline("U!",str);
67: return(0); }
68: strcpy(tmp,f->name);
69: truncsp(tmp);
70: for(i=0;i<cfg.total_ftests;i++)
71: if(cfg.ftest[i]->ext[0]=='*' || !strcmp(tmp+9,cfg.ftest[i]->ext)) {
72: if(!chk_ar(cfg.ftest[i]->ar,&useron))
73: continue;
74: attr(LIGHTGRAY);
75: bputs(cfg.ftest[i]->workstr);
76:
77: sprintf(sbbsfilename,"SBBSFILENAME=%.12s",unpadfname(f->name,fname));
78: putenv(sbbsfilename);
79: sprintf(sbbsfiledesc,"SBBSFILEDESC=%.*s",LEN_FDESC,f->desc);
80: putenv(sbbsfiledesc);
81: sprintf(str,"%sSBBSFILE.NAM",cfg.node_dir);
82: if((stream=fopen(str,"w"))!=NULL) {
83: fwrite(fname,1,strlen(fname),stream);
84: fclose(stream); }
85: sprintf(str,"%sSBBSFILE.DES",cfg.node_dir);
86: if((stream=fopen(str,"w"))!=NULL) {
87: fwrite(f->desc,1,strlen(f->desc),stream);
88: fclose(stream); }
89: if(external(cmdstr(cfg.ftest[i]->cmd,path,f->desc,NULL),0)) { /* EX_OUTL */
90: bprintf(text[FileHadErrors],f->name,cfg.ftest[i]->ext);
91: if(SYSOP) {
92: if(!yesno(text[DeleteFileQ])) return(0); }
93: remove(path);
94: sprintf(str,"Attempted to upload %s to %s %s (%s Errors)",f->name
95: ,cfg.lib[cfg.dir[f->dir]->lib]->sname,cfg.dir[f->dir]->sname,cfg.ftest[i]->ext);
96: logline("U!",str);
97: return(0); }
98: else {
99: sprintf(str,"%ssbbsfile.nam",cfg.node_dir);
100: if((stream=fopen(str,"r"))!=NULL) {
101: if(fgets(str,128,stream)) {
102: truncsp(str);
103: strupr(str);
104: padfname(str,f->name);
105: strcpy(tmp,f->name);
106: truncsp(tmp);
107: sprintf(path,"%s%s",f->altpath>0 && f->altpath<=cfg.altpaths
108: ? cfg.altpath[f->altpath-1] : cfg.dir[f->dir]->path
109: ,unpadfname(f->name,fname)); }
110: fclose(stream);
111: }
112: sprintf(str,"%ssbbsfile.des",cfg.node_dir);
113: if((stream=fopen(str,"r"))!=NULL) {
114: if(fgets(str,128,stream)) {
115: truncsp(str);
116: sprintf(f->desc,"%.*s",LEN_FDESC,str); }
117: fclose(stream); }
118: CRLF; } }
119:
120: if((length=flength(path))<=0L) {
121: bprintf(text[FileZeroLength],f->name);
122: remove(path);
123: sprintf(str,"Attempted to upload %s to %s %s (Zero length)",f->name
124: ,cfg.lib[cfg.dir[f->dir]->lib]->sname,cfg.dir[f->dir]->sname);
125: logline("U!",str);
126: return(0); }
127: if(cfg.dir[f->dir]->misc&DIR_DIZ) {
128: for(i=0;i<cfg.total_fextrs;i++)
129: if(!stricmp(cfg.fextr[i]->ext,tmp+9) && chk_ar(cfg.fextr[i]->ar,&useron))
130: break;
131: if(i<cfg.total_fextrs) {
132: sprintf(str,"%sFILE_ID.DIZ",cfg.temp_dir);
133: remove(str);
134: external(cmdstr(cfg.fextr[i]->cmd,path,"FILE_ID.DIZ",NULL),EX_OUTL);
135: if(!fexist(str)) {
136: sprintf(str,"%sDESC.SDI",cfg.temp_dir);
137: remove(str);
138: external(cmdstr(cfg.fextr[i]->cmd,path,"DESC.SDI",NULL),EX_OUTL); }
139: if((file=nopen(str,O_RDONLY))!=-1) {
140: memset(ext,0,513);
141: read(file,ext,512);
142: for(i=512;i;i--)
143: if(ext[i-1]>SP)
144: break;
145: ext[i]=0;
146: if(!f->desc[0]) {
147: strcpy(desc,ext);
148: strip_exascii(desc);
149: strip_ctrl(desc);
150: for(i=0;desc[i];i++)
151: if(isalnum(desc[i]))
152: break;
153: sprintf(f->desc,"%.*s",LEN_FDESC,desc+i); }
154: close(file);
155: remove(str);
156: f->misc|=FM_EXTDESC; } } }
157:
158: logon_ulb+=length; /* Update 'this call' stats */
159: logon_uls++;
160: if(cfg.dir[f->dir]->misc&DIR_AONLY) /* Forced anonymous */
161: f->misc|=FM_ANON;
162: f->cdt=length;
163: f->dateuled=time(NULL);
164: f->timesdled=0;
165: f->datedled=0L;
166: f->opencount=0;
167: strcpy(f->uler,useron.alias);
168: bprintf(text[FileNBytesReceived],f->name,ultoac(length,tmp));
169: if(!f->desc[0])
170: sprintf(f->desc,"%.*s",LEN_FDESC,text[NoDescription]);
171: if(!addfiledat(&cfg,f))
172: return(0);
173:
174: if(f->misc&FM_EXTDESC)
175: putextdesc(f->dir,f->datoffset,ext);
176:
177: sprintf(str,"Uploaded %s to %s %s",f->name,cfg.lib[cfg.dir[f->dir]->lib]->sname
178: ,cfg.dir[f->dir]->sname);
179: if(cfg.dir[f->dir]->upload_sem[0])
180: if((file=nopen(cmdstr(cfg.dir[f->dir]->upload_sem,nulstr,nulstr,NULL)
181: ,O_WRONLY|O_CREAT|O_TRUNC))!=-1)
182: close(file);
183: logline("U+",str);
184: /**************************/
185: /* Update Uploader's Info */
186: /**************************/
187: useron.uls=(ushort)adjustuserrec(&cfg,useron.number,U_ULS,5,1);
188: useron.ulb=(ushort)adjustuserrec(&cfg,useron.number,U_ULB,10,length);
189: if(cfg.dir[f->dir]->up_pct && cfg.dir[f->dir]->misc&DIR_CDTUL) { /* credit for upload */
190: if(cfg.dir[f->dir]->misc&DIR_CDTMIN && cur_cps) /* Give min instead of cdt */
191: useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10
192: ,((ulong)(length*(cfg.dir[f->dir]->up_pct/100.0))/cur_cps)/60);
193: else
194: useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10
195: ,(ulong)(f->cdt*(cfg.dir[f->dir]->up_pct/100.0))); }
196:
197: return(true);
198: }
199:
200:
201: /****************************************************************************/
202: /* Update the upload date for the file 'f' */
203: /****************************************************************************/
204: void sbbs_t::update_uldate(file_t* f)
205: {
206: char str[256],fname[13];
207: int i,file;
208: long l,length;
209:
210: /*******************/
211: /* Update IXB File */
212: /*******************/
213: sprintf(str,"%s%s.ixb",cfg.dir[f->dir]->data_dir,cfg.dir[f->dir]->code);
214: if((file=nopen(str,O_RDWR))==-1) {
215: errormsg(WHERE,ERR_OPEN,str,O_RDWR);
216: return; }
217: length=filelength(file);
218: if(length%F_IXBSIZE) {
219: close(file);
220: errormsg(WHERE,ERR_LEN,str,length);
221: return; }
222: strcpy(fname,f->name);
223: for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */
224: fname[i]=fname[i+1];
225: for(l=0;l<length;l+=F_IXBSIZE) {
226: read(file,str,F_IXBSIZE); /* Look for the filename in the IXB file */
227: str[11]=0;
228: if(!strcmp(fname,str)) break; }
229: if(l>=length) {
230: close(file);
231: errormsg(WHERE,ERR_CHK,f->name,length);
232: return; }
233: lseek(file,l+14,SEEK_SET);
234: write(file,&f->dateuled,4);
235: close(file);
236:
237: /*******************************************/
238: /* Update last upload date/time stamp file */
239: /*******************************************/
240: sprintf(str,"%s%s.dab",cfg.dir[f->dir]->data_dir,cfg.dir[f->dir]->code);
241: if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
242: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT);
243: else {
244: write(file,&f->dateuled,4);
245: close(file);
246: }
247: }
248:
249: /****************************************************************************/
250: /* Uploads files */
251: /****************************************************************************/
252: void sbbs_t::upload(uint dirnum)
253: {
254: char str[256],src[256]={""},descbeg[25]={""},descend[25]={""},path[256]
255: ,fname[13],keys[256],ch,*p;
256: char tmp[512];
257: time_t start,end;
258: uint i,j,k,destuser[MAX_USERXFER],destusers=0;
259: int file;
260: ulong space;
261: file_t f;
262: user_t user;
263: node_t node;
264:
265: if(sys_status&SS_EVENT && online==ON_REMOTE && !dir_op(dirnum))
266: bprintf(text[UploadBeforeEvent],timeleft/60);
267: if(altul)
268: strcpy(path,cfg.altpath[altul-1]);
269: else
270: strcpy(path,cfg.dir[dirnum]->path);
271:
272:
273: /* get free disk space */
274: space=getfreediskspace(path);
275: if(space<(ulong)cfg.min_dspace*1024L) {
276: bputs(text[LowDiskSpace]);
277: sprintf(str,"Diskspace is low: %s (%lu bytes)",path,space);
278: errorlog(str);
279: if(!dir_op(dirnum))
280: return; }
281: bprintf(text[DiskNBytesFree],ultoac(space,tmp));
282:
283: f.dir=curdirnum=dirnum;
284: f.misc=0;
285: f.altpath=altul;
286: bputs(text[Filename]);
287: if(!getstr(fname,12,K_UPPER) || strchr(fname,'?') || strchr(fname,'*')
288: || !checkfname(fname) || (trashcan(fname,"file") && !dir_op(dirnum))) {
289: if(fname[0])
290: bputs(text[BadFilename]);
291: return; }
292: if(dirnum==cfg.sysop_dir)
293: sprintf(str,text[UploadToSysopDirQ],fname);
294: else if(dirnum==cfg.user_dir)
295: sprintf(str,text[UploadToUserDirQ],fname);
296: else
297: sprintf(str,text[UploadToCurDirQ],fname,cfg.lib[cfg.dir[dirnum]->lib]->sname
298: ,cfg.dir[dirnum]->sname);
299: if(!yesno(str)) return;
300: action=NODE_ULNG;
301: padfname(fname,f.name);
302: sprintf(str,"%s%s",path,fname);
303: if(fexist(str)) { /* File is on disk */
304: if(!dir_op(dirnum) && online!=ON_LOCAL) { /* local users or sysops */
305: bprintf(text[FileAlreadyThere],fname);
306: return; }
307: if(!yesno(text[FileOnDiskAddQ]))
308: return; }
309: else if(online==ON_LOCAL) {
310: bputs(text[FileNotOnDisk]);
311: bputs(text[EnterPath]);
312: if(!getstr(tmp,60,K_LINE|K_UPPER))
313: return;
314: backslash(tmp);
315: sprintf(src,"%s%s",tmp,fname); }
316: strcpy(str,cfg.dir[dirnum]->exts);
317: strcpy(tmp,f.name);
318: truncsp(tmp);
319: j=strlen(str);
320: for(i=0;i<j;i+=ch+1) { /* Check extension of upload with allowable exts */
321: p=strchr(str+i,',');
322: if(p!=NULL)
323: *p=0;
324: ch=strlen(str+i);
325: if(!strcmp(tmp+9,str+i))
326: break; }
327: if(j && i>=j) {
328: bputs(text[TheseFileExtsOnly]);
329: bputs(cfg.dir[dirnum]->exts);
330: CRLF;
331: if(!dir_op(dirnum)) return; }
332: bputs(text[SearchingForDupes]);
333: for(i=k=0;i<usrlibs;i++)
334: for(j=0;j<usrdirs[i];j++,k++) {
335: outchar('.');
336: if(k && !(k%5))
337: bputs("\b\b\b\b\b \b\b\b\b\b");
338: if((usrdir[i][j]==dirnum || cfg.dir[usrdir[i][j]]->misc&DIR_DUPES)
339: && findfile(&cfg,usrdir[i][j],f.name)) {
340: bputs(text[SearchedForDupes]);
341: bprintf(text[FileAlreadyOnline],f.name);
342: if(!dir_op(dirnum))
343: return; /* File is in database for another dir */
344: if(usrdir[i][j]==dirnum)
345: return; } } /* don't allow duplicates */
346: bputs(text[SearchedForDupes]);
347: if(dirnum==cfg.user_dir) { /* User to User transfer */
348: bputs(text[EnterAfterLastDestUser]);
349: while((!dir_op(dirnum) && destusers<cfg.max_userxfer) || destusers<MAX_USERXFER) {
350: bputs(text[SendFileToUser]);
351: if(!getstr(str,LEN_ALIAS,K_UPRLWR))
352: break;
353: if((user.number=finduser(str))!=0) {
354: if(!dir_op(dirnum) && user.number==useron.number) {
355: bputs(text[CantSendYourselfFiles]);
356: continue; }
357: for(i=0;i<destusers;i++)
358: if(user.number==destuser[i])
359: break;
360: if(i<destusers) {
361: bputs(text[DuplicateUser]);
362: continue; }
363: getuserdat(&cfg,&user);
364: if((user.rest&(FLAG('T')|FLAG('D')))
365: || !chk_ar(cfg.lib[cfg.dir[cfg.user_dir]->lib]->ar,&user)
366: || !chk_ar(cfg.dir[cfg.user_dir]->dl_ar,&user)) {
367: bprintf(text[UserWontBeAbleToDl],user.alias); }
368: else {
369: bprintf(text[UserAddedToDestList],user.alias);
370: destuser[destusers++]=user.number; } }
371: else {
372: CRLF; } }
373: if(!destusers)
374: return; }
375: if(cfg.dir[dirnum]->misc&DIR_RATE) {
376: SYNC;
377: bputs(text[RateThisFile]);
378: ch=getkey(K_ALPHA);
379: if(!isalpha(ch) || sys_status&SS_ABORT)
380: return;
381: CRLF;
382: sprintf(descbeg,text[Rated],toupper(ch)); }
383: if(cfg.dir[dirnum]->misc&DIR_ULDATE) {
384: now=time(NULL);
385: if(descbeg[0])
386: strcat(descbeg," ");
387: sprintf(str,"%s ",unixtodstr(&cfg,now,tmp));
388: strcat(descbeg,str); }
389: if(cfg.dir[dirnum]->misc&DIR_MULT) {
390: SYNC;
391: if(!noyes(text[MultipleDiskQ])) {
392: bputs(text[HowManyDisksTotal]);
393: if((int)(i=getnum(99))<2)
394: return;
395: bputs(text[NumberOfFile]);
396: if((int)(j=getnum(i))<1)
397: return;
398: if(j==1)
399: upload_lastdesc[0]=0;
400: if(i>9)
401: sprintf(descend,text[FileOneOfTen],j,i);
402: else
403: sprintf(descend,text[FileOneOfTwo],j,i); }
404: else
405: upload_lastdesc[0]=0; }
406: else
407: upload_lastdesc[0]=0;
408: bputs(text[EnterDescNow]);
409: i=LEN_FDESC-(strlen(descbeg)+strlen(descend));
410: getstr(upload_lastdesc,i,K_LINE|K_EDIT|K_AUTODEL);
411: if(sys_status&SS_ABORT)
412: return;
413: if(descend[0]) /* end of desc specified, so pad desc with spaces */
414: sprintf(f.desc,"%s%-*s%s",descbeg,i,upload_lastdesc,descend);
415: else /* no end specified, so string ends at desc end */
416: sprintf(f.desc,"%s%s",descbeg,upload_lastdesc);
417:
418: if(cfg.dir[dirnum]->misc&DIR_ANON && !(cfg.dir[dirnum]->misc&DIR_AONLY)
419: && (dir_op(dirnum) || useron.exempt&FLAG('A'))) {
420: if(!noyes(text[AnonymousQ]))
421: f.misc|=FM_ANON; }
422: sprintf(str,"%s%s",path,fname);
423: if(src[0]) { /* being copied from another local dir */
424: bprintf(text[RetrievingFile],fname);
425: if(mv(src,str,1))
426: return;
427: CRLF; }
428: if(fexist(str)) { /* File is on disk */
429: if(!uploadfile(&f))
430: return; }
431: else {
432: menu("ulprot");
433: SYNC;
434: strcpy(keys,"Q");
435: if(dirnum==cfg.user_dir || !cfg.max_batup) /* no batch user to user xfers */
436: mnemonics(text[ProtocolOrQuit]);
437: else {
438: mnemonics(text[ProtocolBatchOrQuit]);
439: strcat(keys,"B"); }
440: for(i=0;i<cfg.total_prots;i++)
441: if(cfg.prot[i]->ulcmd[0] && chk_ar(cfg.prot[i]->ar,&useron)) {
442: sprintf(tmp,"%c",cfg.prot[i]->mnemonic);
443: strcat(keys,tmp); }
444: ch=(char)getkeys(keys,0);
445: if(ch=='Q')
446: return;
447: if(ch=='B') {
448: if(batup_total>=cfg.max_batup)
449: bputs(text[BatchUlQueueIsFull]);
450: else {
451: for(i=0;i<batup_total;i++)
452: if(!strcmp(batup_name[i],f.name)) {
453: bprintf(text[FileAlreadyInQueue],f.name);
454: return; }
455: strcpy(batup_name[batup_total],f.name);
456: strcpy(batup_desc[batup_total],f.desc);
457: batup_dir[batup_total]=dirnum;
458: batup_misc[batup_total]=f.misc;
459: batup_alt[batup_total]=altul;
460: batup_total++;
461: bprintf(text[FileAddedToUlQueue]
462: ,f.name,batup_total,cfg.max_batup); } }
463: else {
464: for(i=0;i<cfg.total_prots;i++)
465: if(cfg.prot[i]->ulcmd[0] && cfg.prot[i]->mnemonic==ch
466: && chk_ar(cfg.prot[i]->ar,&useron))
467: break;
468: if(i<cfg.total_prots) {
469: start=time(NULL);
470: protocol(cmdstr(cfg.prot[i]->ulcmd,str,nulstr,NULL),0);
471: end=time(NULL);
472: if(!(cfg.dir[dirnum]->misc&DIR_ULTIME)) /* Don't deduct upload time */
473: starttime+=end-start;
474: ch=uploadfile(&f);
475: autohangup();
476: if(!ch) /* upload failed, don't process user to user xfer */
477: return; } } }
478: if(dirnum==cfg.user_dir) { /* Add files to XFER.IXT in INDX dir */
479: sprintf(str,"%sxfer.ixt",cfg.data_dir);
480: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
481: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
482: return; }
483: for(j=0;j<destusers;j++) {
484: for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */
485: getnodedat(i,&node,0);
486: if(node.useron==destuser[j] && !(node.misc&NODE_POFF)
487: && (node.status==NODE_INUSE || node.status==NODE_QUIET)) {
488: sprintf(str,text[UserToUserXferNodeMsg],cfg.node_num,useron.alias);
489: putnmsg(i,str);
490: break; } }
491: if(i>cfg.sys_nodes) { /* User not online */
492: sprintf(str,text[UserSentYouFile],useron.alias);
493: putsmsg(&cfg,destuser[j],str); }
494: sprintf(str,"%4.4u %12.12s %4.4u\r\n"
495: ,destuser[j],f.name,useron.number);
496: write(file,str,strlen(str)); }
497: close(file);
498: }
499: }
500:
501: /****************************************************************************/
502: /* Checks directory for 'dir' and prompts user to enter description for */
503: /* the files that aren't in the database. */
504: /* Returns 1 if the user aborted, 0 if not. */
505: /****************************************************************************/
506: bool sbbs_t::bulkupload(uint dirnum)
507: {
508: char str[MAX_PATH];
509: char path[MAX_PATH];
510: char spath[MAX_PATH];
511: file_t f;
512: DIR* dir;
513: DIRENT* dirent;
514:
515: memset(&f,0,sizeof(file_t));
516: f.dir=dirnum;
517: f.altpath=altul;
518: bprintf(text[BulkUpload],cfg.lib[cfg.dir[dirnum]->lib]->sname,cfg.dir[dirnum]->sname);
519: strcpy(path,altul>0 && altul<=cfg.altpaths ? cfg.altpath[altul-1]
520: : cfg.dir[dirnum]->path);
521: action=NODE_ULNG;
522: SYNC;
523: dir=opendir(path);
524: while((dirent=readdir(dir))!=NULL && !msgabort()) {
525: if(gettotalfiles(dirnum)>cfg.dir[dirnum]->maxfiles) {
526: bputs(text[DirFull]);
527: break;
528: }
529: sprintf(str,"%s%s",path,dirent->d_name);
530: if(isdir(str))
531: continue;
532: #ifdef _WIN32
533: GetShortPathName(str,spath,sizeof(spath));
534: #else
535: strcpy(spath,str);
536: #endif
537: padfname(getfname(spath),str);
538:
539: if(findfile(&cfg,f.dir,str)==0) {
540: strcpy(f.name,str);
541: f.cdt=flength(spath);
542: bprintf(text[BulkUploadDescPrompt],f.name,f.cdt);
543: getstr(f.desc,LEN_FDESC,K_LINE);
544: if(sys_status&SS_ABORT)
545: break;
546: uploadfile(&f);
547: }
548: }
549: closedir(dir);
550: if(sys_status&SS_ABORT)
551: return(true);
552: return(false);
553: }
554:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.