|
|
1.1 root 1: /* upload.cpp */
2:
3: /* Synchronet file upload-related routines */
4:
1.1.1.2 ! root 5: /* $Id: upload.cpp,v 1.57 2011/09/21 03:10:53 rswindell Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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[MAX_PATH+1];
49: char str[MAX_PATH+1],fname[25];
50: char ext[F_EXBSIZE+1];
51: char desc[F_EXBSIZE+1];
52: char tmp[MAX_PATH+1];
53: int file;
54: uint i;
55: long length;
56: FILE* stream;
57:
58: // f->misc=0; Removed AUG-22-2001 - broken anonymous uploads
59: curdirnum=f->dir;
60: if(findfile(&cfg,f->dir,f->name)) {
61: errormsg(WHERE,ERR_CHK,f->name,f->dir);
62: return(0);
63: }
64: sprintf(path,"%s%s",f->altpath>0 && f->altpath<=cfg.altpaths
65: ? cfg.altpath[f->altpath-1]
66: : cfg.dir[f->dir]->path,unpadfname(f->name,fname));
67: sprintf(tmp,"%s%s",cfg.temp_dir,fname);
68: if(!fexistcase(path) && fexistcase(tmp))
69: mv(tmp,path,0);
70: if(!fexistcase(path)) {
71: bprintf(text[FileNotReceived],f->name);
72: sprintf(str,"%s attempted to upload %s to %s %s (Not received)"
73: ,useron.alias
74: ,f->name
75: ,cfg.lib[cfg.dir[f->dir]->lib]->sname,cfg.dir[f->dir]->sname);
1.1.1.2 ! root 76: logline(LOG_NOTICE,"U!",str);
1.1 root 77: return(0);
78: }
79: strcpy(tmp,f->name);
80: truncsp(tmp);
81: for(i=0;i<cfg.total_ftests;i++)
82: if(cfg.ftest[i]->ext[0]=='*' || !stricmp(tmp+9,cfg.ftest[i]->ext)) {
1.1.1.2 ! root 83: if(!chk_ar(cfg.ftest[i]->ar,&useron,&client))
1.1 root 84: continue;
85: attr(LIGHTGRAY);
86: bputs(cfg.ftest[i]->workstr);
87:
88: sprintf(sbbsfilename,"SBBSFILENAME=%.64s",unpadfname(f->name,fname));
89: putenv(sbbsfilename);
90: sprintf(sbbsfiledesc,"SBBSFILEDESC=%.*s",LEN_FDESC,f->desc);
91: putenv(sbbsfiledesc);
92: sprintf(str,"%ssbbsfile.nam",cfg.node_dir);
93: if((stream=fopen(str,"w"))!=NULL) {
94: fwrite(fname,1,strlen(fname),stream);
95: fclose(stream);
96: }
97: sprintf(str,"%ssbbsfile.des",cfg.node_dir);
98: if((stream=fopen(str,"w"))!=NULL) {
99: fwrite(f->desc,1,strlen(f->desc),stream);
100: fclose(stream);
101: }
102: if(external(cmdstr(cfg.ftest[i]->cmd,path,f->desc,NULL),EX_OFFLINE)) {
103: sprintf(str,"%s attempted to upload %s to %s %s (%s Errors)"
104: ,useron.alias
105: ,f->name
106: ,cfg.lib[cfg.dir[f->dir]->lib]->sname,cfg.dir[f->dir]->sname,cfg.ftest[i]->ext);
1.1.1.2 ! root 107: logline(LOG_NOTICE,"U!",str);
1.1 root 108: #if 0
109: sprintf(str,"Failed test: %s", cmdstr(cfg.ftest[i]->cmd,path,f->desc,NULL));
110: logline(" ",str);
111: #endif
112: bprintf(text[FileHadErrors],f->name,cfg.ftest[i]->ext);
113: if(!SYSOP || yesno(text[DeleteFileQ]))
114: remove(path);
115: return(0);
116: } else {
117: sprintf(str,"%ssbbsfile.nam",cfg.node_dir);
118: if((stream=fopen(str,"r"))!=NULL) {
119: if(fgets(str,128,stream)) {
120: truncsp(str);
121: padfname(str,f->name);
122: strcpy(tmp,f->name);
123: truncsp(tmp);
124: sprintf(path,"%s%s",f->altpath>0 && f->altpath<=cfg.altpaths
125: ? cfg.altpath[f->altpath-1] : cfg.dir[f->dir]->path
126: ,unpadfname(f->name,fname));
127: }
128: fclose(stream);
129: }
130: sprintf(str,"%ssbbsfile.des",cfg.node_dir);
131: if((stream=fopen(str,"r"))!=NULL) {
132: if(fgets(str,128,stream)) {
133: truncsp(str);
134: sprintf(f->desc,"%.*s",LEN_FDESC,str);
135: }
136: fclose(stream);
137: }
138: CRLF;
139: }
140: }
141:
1.1.1.2 ! root 142: if((length=(long)flength(path))==0L) {
1.1 root 143: bprintf(text[FileZeroLength],f->name);
144: remove(path);
145: sprintf(str,"%s attempted to upload %s to %s %s (Zero length)"
146: ,useron.alias
147: ,f->name
148: ,cfg.lib[cfg.dir[f->dir]->lib]->sname,cfg.dir[f->dir]->sname);
1.1.1.2 ! root 149: logline(LOG_NOTICE,"U!",str);
1.1 root 150: return(0);
151: }
152: if(cfg.dir[f->dir]->misc&DIR_DIZ) {
153: for(i=0;i<cfg.total_fextrs;i++)
1.1.1.2 ! root 154: if(!stricmp(cfg.fextr[i]->ext,tmp+9) && chk_ar(cfg.fextr[i]->ar,&useron,&client))
1.1 root 155: break;
156: if(i<cfg.total_fextrs) {
157: sprintf(str,"%sFILE_ID.DIZ",cfg.temp_dir);
158: if(fexistcase(str))
159: remove(str);
160: external(cmdstr(cfg.fextr[i]->cmd,path,"FILE_ID.DIZ",NULL),EX_OFFLINE);
161: if(!fexistcase(str)) {
162: sprintf(str,"%sDESC.SDI",cfg.temp_dir);
163: if(fexistcase(str))
164: remove(str);
165: external(cmdstr(cfg.fextr[i]->cmd,path,"DESC.SDI",NULL),EX_OFFLINE);
166: fexistcase(str);
167: }
168: if((file=nopen(str,O_RDONLY))!=-1) {
169: memset(ext,0,F_EXBSIZE+1);
170: read(file,ext,F_EXBSIZE);
171: for(i=F_EXBSIZE;i;i--)
172: if(ext[i-1]>' ')
173: break;
174: ext[i]=0;
175: if(!f->desc[0]) {
176: strcpy(desc,ext);
1.1.1.2 ! root 177: strip_exascii(desc, desc);
! 178: prep_file_desc(desc, desc);
1.1 root 179: for(i=0;desc[i];i++)
180: if(isalnum(desc[i]))
181: break;
182: sprintf(f->desc,"%.*s",LEN_FDESC,desc+i);
183: }
184: close(file);
185: remove(str);
186: f->misc|=FM_EXTDESC;
187: }
188: }
189: }
190:
191: if(!(cfg.dir[f->dir]->misc&DIR_NOSTAT)) {
192: logon_ulb+=length; /* Update 'this call' stats */
193: logon_uls++;
194: }
195: if(cfg.dir[f->dir]->misc&DIR_AONLY) /* Forced anonymous */
196: f->misc|=FM_ANON;
197: f->cdt=length;
198: f->dateuled=time(NULL);
199: f->timesdled=0;
200: f->datedled=0L;
201: f->opencount=0;
202: strcpy(f->uler,useron.alias);
203: bprintf(text[FileNBytesReceived],f->name,ultoac(length,tmp));
204: if(!f->desc[0]) {
205: if(stricmp(f->name,getfname(path)))
206: SAFECOPY(f->desc,getfname(path));
207: else
208: sprintf(f->desc,"%.*s",LEN_FDESC,text[NoDescription]);
209: }
210: if(!addfiledat(&cfg,f))
211: return(0);
212:
213: if(f->misc&FM_EXTDESC)
214: putextdesc(&cfg,f->dir,f->datoffset,ext);
215:
216: sprintf(str,"%s uploaded %s to %s %s"
217: ,useron.alias
218: ,f->name,cfg.lib[cfg.dir[f->dir]->lib]->sname
219: ,cfg.dir[f->dir]->sname);
220: if(cfg.dir[f->dir]->upload_sem[0])
221: ftouch(cmdstr(cfg.dir[f->dir]->upload_sem,nulstr,nulstr,NULL));
222: logline("U+",str);
223: /**************************/
224: /* Update Uploader's Info */
225: /**************************/
226: user_uploaded(&cfg, &useron, 1, length);
227: if(cfg.dir[f->dir]->up_pct && cfg.dir[f->dir]->misc&DIR_CDTUL) { /* credit for upload */
228: if(cfg.dir[f->dir]->misc&DIR_CDTMIN && cur_cps) /* Give min instead of cdt */
229: useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10
230: ,((ulong)(length*(cfg.dir[f->dir]->up_pct/100.0))/cur_cps)/60);
231: else
232: useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10
233: ,(ulong)(f->cdt*(cfg.dir[f->dir]->up_pct/100.0)));
234: }
235:
236: user_event(EVENT_UPLOAD);
237:
238: return(true);
239: }
240:
241: /****************************************************************************/
242: /* Uploads files */
243: /****************************************************************************/
244: bool sbbs_t::upload(uint dirnum)
245: {
246: char descbeg[25]={""},descend[25]={""}
247: ,fname[13],keys[256],ch,*p;
248: char str[MAX_PATH+1];
249: char path[MAX_PATH+1];
250: char spath[MAX_PATH+1];
251: char tmp[512];
252: time_t start,end;
253: uint i,j,k,destuser[MAX_USERXFER],destusers=0;
254: int file;
255: ulong space;
256: file_t f;
257: user_t user;
258: node_t node;
259:
260: /* Security Checks */
261: if(useron.rest&FLAG('U')) {
262: bputs(text[R_Upload]);
263: return(false);
264: }
265: if(dirnum==INVALID_DIR) {
266: bputs(text[CantUploadHere]);
267: return(false);
268: }
1.1.1.2 ! root 269: if(!(useron.exempt&FLAG('U')) && !dir_op(dirnum)) {
! 270: if(!chk_ar(cfg.dir[dirnum]->ul_ar,&useron,&client)) {
! 271: bputs(dirnum==cfg.user_dir ? text[CantUploadToUser] :
! 272: dirnum==cfg.sysop_dir ? text[CantUploadToSysop] : text[CantUploadHere]);
! 273: return(false);
! 274: }
! 275: if(cfg.dir[dirnum]->maxfiles && getfiles(&cfg,dirnum)>=cfg.dir[dirnum]->maxfiles) {
! 276: bputs(dirnum==cfg.user_dir ? text[UserDirFull] : text[DirFull]);
! 277: return(false);
! 278: }
1.1 root 279: }
280:
281: if(sys_status&SS_EVENT && online==ON_REMOTE && !dir_op(dirnum))
282: bprintf(text[UploadBeforeEvent],timeleft/60);
283: if(altul)
284: strcpy(path,cfg.altpath[altul-1]);
285: else
286: strcpy(path,cfg.dir[dirnum]->path);
287:
1.1.1.2 ! root 288: if(!isdir(path)) {
! 289: bprintf(text[DirectoryDoesNotExist], path);
! 290: lprintf(LOG_ERR,"File directory does not exist: %s", path);
! 291: return(false);
! 292: }
1.1 root 293:
294: /* get free disk space */
295: space=getfreediskspace(path,1024);
296: if(space<(ulong)cfg.min_dspace) {
297: bputs(text[LowDiskSpace]);
1.1.1.2 ! root 298: lprintf(LOG_ERR,"Diskspace is low: %s (%lu kilobytes)",path,space);
1.1 root 299: if(!dir_op(dirnum))
300: return(false);
301: }
302: bprintf(text[DiskNBytesFree],ultoac(space,tmp));
303:
304: f.dir=curdirnum=dirnum;
305: f.misc=0;
306: f.altpath=altul;
307: bputs(text[Filename]);
308: if(!getstr(fname,12,0) || strchr(fname,'?') || strchr(fname,'*')
309: || !checkfname(fname) || (trashcan(fname,"file") && !dir_op(dirnum))) {
310: if(fname[0])
311: bputs(text[BadFilename]);
312: return(false);
313: }
314: if(dirnum==cfg.sysop_dir)
315: sprintf(str,text[UploadToSysopDirQ],fname);
316: else if(dirnum==cfg.user_dir)
317: sprintf(str,text[UploadToUserDirQ],fname);
318: else
319: sprintf(str,text[UploadToCurDirQ],fname,cfg.lib[cfg.dir[dirnum]->lib]->sname
320: ,cfg.dir[dirnum]->sname);
321: if(!yesno(str)) return(false);
322: action=NODE_ULNG;
323: sprintf(str,"%s%s",path,fname);
324: if(fexistcase(str)) { /* File is on disk */
325: #ifdef _WIN32
326: GetShortPathName(str, spath, sizeof(spath));
327: #else
328: SAFECOPY(spath,str);
329: #endif
330: SAFECOPY(fname,getfname(spath));
331: if(!dir_op(dirnum) && online!=ON_LOCAL) { /* local users or sysops */
332: bprintf(text[FileAlreadyThere],fname);
333: return(false);
334: }
335: if(!yesno(text[FileOnDiskAddQ]))
336: return(false);
337: }
338: padfname(fname,f.name);
339: strcpy(str,cfg.dir[dirnum]->exts);
340: strcpy(tmp,f.name);
341: truncsp(tmp);
342: j=strlen(str);
343: for(i=0;i<j;i+=ch+1) { /* Check extension of upload with allowable exts */
344: p=strchr(str+i,',');
345: if(p!=NULL)
346: *p=0;
347: ch=strlen(str+i);
348: if(!stricmp(tmp+9,str+i))
349: break;
350: }
351: if(j && i>=j) {
352: bputs(text[TheseFileExtsOnly]);
353: bputs(cfg.dir[dirnum]->exts);
354: CRLF;
355: if(!dir_op(dirnum)) return(false);
356: }
357: bputs(text[SearchingForDupes]);
358: if(findfile(&cfg,dirnum,f.name)) {
359: bputs(text[SearchedForDupes]);
360: bprintf(text[FileAlreadyOnline],fname);
361: return(false); /* File is already in database */
362: }
363: for(i=k=0;i<usrlibs;i++) {
364: for(j=0;j<usrdirs[i];j++,k++) {
365: outchar('.');
366: if(k && !(k%5))
367: bputs("\b\b\b\b\b \b\b\b\b\b");
368: if(usrdir[i][j]==dirnum)
369: continue; /* we already checked this dir */
370: if(cfg.dir[usrdir[i][j]]->misc&DIR_DUPES
371: && findfile(&cfg,usrdir[i][j],f.name)) {
372: bputs(text[SearchedForDupes]);
373: bprintf(text[FileAlreadyOnline],fname);
374: if(!dir_op(dirnum))
375: return(false); /* File is in database for another dir */
376: }
377: }
378: }
379: bputs(text[SearchedForDupes]);
380: if(dirnum==cfg.user_dir) { /* User to User transfer */
381: bputs(text[EnterAfterLastDestUser]);
382: while((!dir_op(dirnum) && destusers<cfg.max_userxfer) || destusers<MAX_USERXFER) {
383: bputs(text[SendFileToUser]);
384: if(!getstr(str,LEN_ALIAS,cfg.uq&UQ_NOUPRLWR ? K_NONE:K_UPRLWR))
385: break;
386: if((user.number=finduser(str))!=0) {
387: if(!dir_op(dirnum) && user.number==useron.number) {
388: bputs(text[CantSendYourselfFiles]);
389: continue;
390: }
391: for(i=0;i<destusers;i++)
392: if(user.number==destuser[i])
393: break;
394: if(i<destusers) {
395: bputs(text[DuplicateUser]);
396: continue;
397: }
398: getuserdat(&cfg,&user);
399: if((user.rest&(FLAG('T')|FLAG('D')))
1.1.1.2 ! root 400: || !chk_ar(cfg.lib[cfg.dir[cfg.user_dir]->lib]->ar,&user,/* client: */NULL)
! 401: || !chk_ar(cfg.dir[cfg.user_dir]->dl_ar,&user,/* client: */NULL)) {
1.1 root 402: bprintf(text[UserWontBeAbleToDl],user.alias);
403: } else {
404: bprintf(text[UserAddedToDestList],user.alias);
405: destuser[destusers++]=user.number;
406: }
407: }
408: else {
409: CRLF;
410: }
411: }
412: if(!destusers)
413: return(false);
414: }
415: if(cfg.dir[dirnum]->misc&DIR_RATE) {
416: SYNC;
417: bputs(text[RateThisFile]);
418: ch=getkey(K_ALPHA);
419: if(!isalpha(ch) || sys_status&SS_ABORT)
420: return(false);
421: CRLF;
422: sprintf(descbeg,text[Rated],toupper(ch));
423: }
424: if(cfg.dir[dirnum]->misc&DIR_ULDATE) {
425: now=time(NULL);
426: if(descbeg[0])
427: strcat(descbeg," ");
428: sprintf(str,"%s ",unixtodstr(&cfg,now,tmp));
429: strcat(descbeg,str);
430: }
431: if(cfg.dir[dirnum]->misc&DIR_MULT) {
432: SYNC;
433: if(!noyes(text[MultipleDiskQ])) {
434: bputs(text[HowManyDisksTotal]);
435: if((int)(i=getnum(99))<2)
436: return(false);
437: bputs(text[NumberOfFile]);
438: if((int)(j=getnum(i))<1)
439: return(false);
440: if(j==1)
441: upload_lastdesc[0]=0;
442: if(i>9)
443: sprintf(descend,text[FileOneOfTen],j,i);
444: else
445: sprintf(descend,text[FileOneOfTwo],j,i);
446: } else
447: upload_lastdesc[0]=0;
448: }
449: else
450: upload_lastdesc[0]=0;
451: bputs(text[EnterDescNow]);
452: i=LEN_FDESC-(strlen(descbeg)+strlen(descend));
453: getstr(upload_lastdesc,i,K_LINE|K_EDIT|K_AUTODEL);
454: if(sys_status&SS_ABORT)
455: return(false);
456: if(descend[0]) /* end of desc specified, so pad desc with spaces */
457: sprintf(f.desc,"%s%-*s%s",descbeg,i,upload_lastdesc,descend);
458: else /* no end specified, so string ends at desc end */
459: sprintf(f.desc,"%s%s",descbeg,upload_lastdesc);
460:
461: if(cfg.dir[dirnum]->misc&DIR_ANON && !(cfg.dir[dirnum]->misc&DIR_AONLY)
462: && (dir_op(dirnum) || useron.exempt&FLAG('A'))) {
463: if(!noyes(text[AnonymousQ]))
464: f.misc|=FM_ANON;
465: }
466: sprintf(str,"%s%s",path,fname);
467: if(fexistcase(str)) { /* File is on disk */
468: if(!uploadfile(&f))
469: return(false);
470: } else {
471: xfer_prot_menu(XFER_UPLOAD);
472: SYNC;
473: strcpy(keys,"Q");
474: if(dirnum==cfg.user_dir || !cfg.max_batup) /* no batch user to user xfers */
475: mnemonics(text[ProtocolOrQuit]);
476: else {
477: mnemonics(text[ProtocolBatchOrQuit]);
478: strcat(keys,"B");
479: }
480: for(i=0;i<cfg.total_prots;i++)
1.1.1.2 ! root 481: if(cfg.prot[i]->ulcmd[0] && chk_ar(cfg.prot[i]->ar,&useron,&client)) {
1.1 root 482: sprintf(tmp,"%c",cfg.prot[i]->mnemonic);
483: strcat(keys,tmp);
484: }
485: ch=(char)getkeys(keys,0);
486: if(ch=='Q')
487: return(false);
488: if(ch=='B') {
489: if(batup_total>=cfg.max_batup)
490: bputs(text[BatchUlQueueIsFull]);
491: else {
492: for(i=0;i<batup_total;i++)
493: if(!strcmp(batup_name[i],f.name)) {
494: bprintf(text[FileAlreadyInQueue],fname);
495: return(false);
496: }
497: strcpy(batup_name[batup_total],f.name);
498: strcpy(batup_desc[batup_total],f.desc);
499: batup_dir[batup_total]=dirnum;
500: batup_misc[batup_total]=f.misc;
501: batup_alt[batup_total]=altul;
502: batup_total++;
503: bprintf(text[FileAddedToUlQueue]
504: ,fname,batup_total,cfg.max_batup);
505: }
506: } else {
507: for(i=0;i<cfg.total_prots;i++)
508: if(cfg.prot[i]->ulcmd[0] && cfg.prot[i]->mnemonic==ch
1.1.1.2 ! root 509: && chk_ar(cfg.prot[i]->ar,&useron,&client))
1.1 root 510: break;
511: if(i<cfg.total_prots) {
512: start=time(NULL);
513: protocol(cfg.prot[i],XFER_UPLOAD,str,nulstr,true);
514: end=time(NULL);
515: if(!(cfg.dir[dirnum]->misc&DIR_ULTIME)) /* Don't deduct upload time */
516: starttime+=end-start;
517: ch=uploadfile(&f);
518: autohangup();
519: if(!ch) /* upload failed, don't process user to user xfer */
520: return(false);
521: }
522: }
523: }
524: if(dirnum==cfg.user_dir) { /* Add files to XFER.IXT in INDX dir */
525: sprintf(str,"%sxfer.ixt",cfg.data_dir);
526: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
527: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
528: return(false);
529: }
530: for(j=0;j<destusers;j++) {
531: for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */
532: getnodedat(i,&node,0);
533: if(node.useron==destuser[j] && !(node.misc&NODE_POFF)
534: && (node.status==NODE_INUSE || node.status==NODE_QUIET)) {
535: sprintf(str,text[UserToUserXferNodeMsg],cfg.node_num,useron.alias);
536: putnmsg(&cfg,i,str);
537: break;
538: }
539: }
540: if(i>cfg.sys_nodes) { /* User not online */
541: sprintf(str,text[UserSentYouFile],useron.alias);
542: putsmsg(&cfg,destuser[j],str);
543: }
544: sprintf(str,"%4.4u %12.12s %4.4u\r\n"
545: ,destuser[j],f.name,useron.number);
546: write(file,str,strlen(str));
547: }
548: close(file);
549: }
550: return(true);
551: }
552:
553: /****************************************************************************/
554: /* Checks directory for 'dir' and prompts user to enter description for */
555: /* the files that aren't in the database. */
556: /* Returns 1 if the user aborted, 0 if not. */
557: /****************************************************************************/
558: bool sbbs_t::bulkupload(uint dirnum)
559: {
560: char str[MAX_PATH+1];
561: char path[MAX_PATH+1];
562: char spath[MAX_PATH+1];
563: file_t f;
564: DIR* dir;
565: DIRENT* dirent;
566:
567: memset(&f,0,sizeof(file_t));
568: f.dir=dirnum;
569: f.altpath=altul;
570: bprintf(text[BulkUpload],cfg.lib[cfg.dir[dirnum]->lib]->sname,cfg.dir[dirnum]->sname);
571: strcpy(path,altul>0 && altul<=cfg.altpaths ? cfg.altpath[altul-1]
572: : cfg.dir[dirnum]->path);
573: action=NODE_ULNG;
574: SYNC;
575: dir=opendir(path);
576: while(dir!=NULL && (dirent=readdir(dir))!=NULL && !msgabort()) {
577: sprintf(str,"%s%s",path,dirent->d_name);
578: if(isdir(str))
579: continue;
580: #ifdef _WIN32
581: /* Skip hidden/system files on Win32 */
582: if(getfattr(str)&(_A_HIDDEN|_A_SYSTEM))
583: continue;
584: #endif
585: #ifdef _WIN32
586: GetShortPathName(str,spath,sizeof(spath));
587: #else
588: strcpy(spath,str);
589: #endif
590: padfname(getfname(spath),str);
591:
592: if(findfile(&cfg,f.dir,str)==0) {
593: strcpy(f.name,str);
1.1.1.2 ! root 594: f.cdt=(long)flength(spath);
1.1 root 595: bprintf(text[BulkUploadDescPrompt],f.name,f.cdt/1024);
596: getstr(f.desc,LEN_FDESC,K_LINE);
597: if(sys_status&SS_ABORT)
598: break;
1.1.1.2 ! root 599: if(strcmp(f.desc,"-")==0) /* don't add this file */
! 600: continue;
1.1 root 601: uploadfile(&f);
602: }
603: }
604: if(dir!=NULL)
605: closedir(dir);
606: if(sys_status&SS_ABORT)
607: return(true);
608: return(false);
609: }
610:
611: bool sbbs_t::recvfile(char *fname, char prot)
612: {
613: char keys[32];
614: char ch;
615: size_t i;
616: bool result=false;
617:
618: if(prot)
619: ch=toupper(prot);
620: else {
621: xfer_prot_menu(XFER_UPLOAD);
622: mnemonics(text[ProtocolOrQuit]);
623: strcpy(keys,"Q");
624: for(i=0;i<cfg.total_prots;i++)
1.1.1.2 ! root 625: if(cfg.prot[i]->ulcmd[0] && chk_ar(cfg.prot[i]->ar,&useron,&client))
1.1 root 626: sprintf(keys+strlen(keys),"%c",cfg.prot[i]->mnemonic);
627:
628: ch=(char)getkeys(keys,0);
629:
630: if(ch=='Q' || sys_status&SS_ABORT)
631: return(false);
632: }
633: for(i=0;i<cfg.total_prots;i++)
1.1.1.2 ! root 634: if(cfg.prot[i]->mnemonic==ch && chk_ar(cfg.prot[i]->ar,&useron,&client))
1.1 root 635: break;
636: if(i<cfg.total_prots) {
637: if(protocol(cfg.prot[i],XFER_UPLOAD,fname,fname,true)==0)
638: result=true;
639: autohangup();
640: }
641:
642: return(result);
643: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.