4 * Server functions which handle file transfers and room directories.
23 #include "sysdep_decls.h"
29 #include "citserver.h"
31 void cmd_delf(char *filename)
36 if (CtdlAccessCheck(ac_room_aide)) return;
38 if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) {
39 cprintf("%d No directory in this room.\n",ERROR+NOT_HERE);
43 if (strlen(filename)==0) {
44 cprintf("%d You must specify a file name.\n",
45 ERROR+FILE_NOT_FOUND);
48 for (a=0; a<strlen(filename); ++a)
49 if (filename[a]=='/') filename[a] = '_';
50 snprintf(pathname,sizeof pathname,"./files/%s/%s",
51 CC->quickroom.QRdirname,filename);
53 if (a==0) cprintf("%d File '%s' deleted.\n",OK,pathname);
54 else cprintf("%d File '%s' not found.\n",ERROR+FILE_NOT_FOUND,pathname);
61 * move a file from one room directory to another
63 void cmd_movf(char *cmdbuf)
71 struct quickroom qrbuf;
73 extract(filename,cmdbuf,0);
74 extract(newroom,cmdbuf,1);
76 if (CtdlAccessCheck(ac_room_aide)) return;
78 if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) {
79 cprintf("%d No directory in this room.\n",ERROR+NOT_HERE);
83 if (strlen(filename)==0) {
84 cprintf("%d You must specify a file name.\n",
85 ERROR+FILE_NOT_FOUND);
89 for (a=0; a<strlen(filename); ++a)
90 if (filename[a]=='/') filename[a] = '_';
91 snprintf(pathname,sizeof pathname,"./files/%s/%s",
92 CC->quickroom.QRdirname,filename);
93 if (access(pathname,0)!=0) {
94 cprintf("%d File '%s' not found.\n",
95 ERROR+FILE_NOT_FOUND,pathname);
99 if (getroom(&qrbuf, newroom)!=0) {
100 cprintf("%d '%s' does not exist.\n",
104 if ((qrbuf.QRflags & QR_DIRECTORY) == 0) {
105 cprintf("%d '%s' is not a directory room.\n",
106 ERROR+NOT_HERE,qrbuf.QRname);
109 snprintf(newpath,sizeof newpath,"./files/%s/%s",qrbuf.QRdirname,
111 if (link(pathname,newpath)!=0) {
112 cprintf("%d Couldn't move file: %s\n",ERROR,strerror(errno));
117 /* this is a crude method of copying the file description */
118 snprintf(buf, sizeof buf,
119 "cat ./files/%s/filedir |grep %s >>./files/%s/filedir",
120 CC->quickroom.QRdirname,
124 cprintf("%d File '%s' has been moved.\n",OK,filename);
129 * send a file over the net
131 void cmd_netf(char *cmdbuf)
133 char pathname[256],filename[256],destsys[256],buf[256],outfile[256];
138 extract(filename,cmdbuf,0);
139 extract(destsys,cmdbuf,1);
141 if (CtdlAccessCheck(ac_room_aide)) return;
143 if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) {
144 cprintf("%d No directory in this room.\n",ERROR+NOT_HERE);
148 if (strlen(filename)==0) {
149 cprintf("%d You must specify a file name.\n",
150 ERROR+FILE_NOT_FOUND);
154 for (a=0; a<strlen(filename); ++a)
155 if (filename[a]=='/') filename[a] = '_';
156 snprintf(pathname,sizeof pathname,"./files/%s/%s",
157 CC->quickroom.QRdirname,filename);
158 if (access(pathname,0)!=0) {
159 cprintf("%d File '%s' not found.\n",
160 ERROR+FILE_NOT_FOUND,pathname);
163 snprintf(buf,sizeof buf,"sysop@%s",destsys);
166 cprintf("%d No such system: '%s'\n",
167 ERROR+NO_SUCH_SYSTEM,destsys);
170 snprintf(outfile,sizeof outfile,"%s/network/spoolin/nsf.%d",BBSDIR,
172 ofp=fopen(outfile,"a");
174 cprintf("%d internal error\n",ERROR);
179 putc(MES_NORMAL,ofp);
181 fprintf(ofp,"Pcit%ld",CC->usersupp.usernum); putc(0,ofp);
183 fprintf(ofp,"T%ld",(long)now); putc(0,ofp);
184 fprintf(ofp,"A%s",CC->usersupp.fullname); putc(0,ofp);
185 fprintf(ofp,"O%s",CC->quickroom.QRname); putc(0,ofp);
186 fprintf(ofp,"N%s",NODENAME); putc(0,ofp);
187 fprintf(ofp,"D%s",destsys); putc(0,ofp);
188 fprintf(ofp,"SFILE"); putc(0,ofp);
192 snprintf(buf,sizeof buf,
193 "cd ./files/%s; uuencode %s <%s 2>/dev/null >>%s",
194 CC->quickroom.QRdirname,filename,filename,outfile);
197 ofp = fopen(outfile,"a");
201 cprintf("%d File '%s' has been sent to %s.\n",OK,filename,destsys);
202 system("nohup ./netproc -i >/dev/null 2>&1 &");
207 * This code is common to all commands which open a file for downloading.
208 * It examines the file and displays the OK result code and some information
209 * about the file. NOTE: this stuff is Unix dependent.
211 void OpenCmdResult(char *filename, char *mime_type) {
216 fstat(fileno(CC->download_fp), &statbuf);
217 filesize = (long) statbuf.st_size;
218 modtime = (time_t) statbuf.st_mtime;
220 cprintf("%d %ld|%ld|%s|%s\n",
221 OK, filesize, modtime, filename, mime_type);
226 * open a file for downloading
228 void cmd_open(char *cmdbuf)
234 extract(filename,cmdbuf,0);
236 if (CtdlAccessCheck(ac_logged_in)) return;
238 if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) {
239 cprintf("%d No directory in this room.\n",ERROR+NOT_HERE);
243 if (strlen(filename)==0) {
244 cprintf("%d You must specify a file name.\n",
245 ERROR+FILE_NOT_FOUND);
249 if (CC->download_fp != NULL) {
250 cprintf("%d You already have a download file open.\n",ERROR);
254 for (a=0; a<strlen(filename); ++a)
255 if (filename[a]=='/') filename[a] = '_';
257 snprintf(pathname,sizeof pathname,
258 "./files/%s/%s",CC->quickroom.QRdirname,filename);
259 CC->download_fp = fopen(pathname,"r");
261 if (CC->download_fp==NULL) {
262 cprintf("%d cannot open %s: %s\n",
263 ERROR,pathname,strerror(errno));
267 OpenCmdResult(filename, "application/octet-stream");
273 void cmd_oimg(char *cmdbuf)
277 struct usersupp usbuf;
282 extract(filename,cmdbuf,0);
284 if (strlen(filename)==0) {
285 cprintf("%d You must specify a file name.\n",
286 ERROR+FILE_NOT_FOUND);
290 if (CC->download_fp != NULL) {
291 cprintf("%d You already have a download file open.\n",ERROR);
295 if (!strcasecmp(filename, "_userpic_")) {
296 extract(which_user, cmdbuf, 1);
297 if (getuser(&usbuf, which_user) != 0) {
298 cprintf("%d No such user.\n", ERROR+NO_SUCH_USER);
301 snprintf(pathname, sizeof pathname, "./userpics/%ld.gif",
304 else if (!strcasecmp(filename, "_floorpic_")) {
305 which_floor = extract_int(cmdbuf, 1);
306 snprintf(pathname, sizeof pathname, "./images/floor.%d.gif",
309 else if (!strcasecmp(filename, "_roompic_")) {
310 assoc_file_name(pathname, &CC->quickroom, "images");
313 for (a=0; a<strlen(filename); ++a) {
314 filename[a] = tolower(filename[a]);
315 if (filename[a]=='/') filename[a] = '_';
317 snprintf(pathname,sizeof pathname,"./images/%s.gif",filename);
320 CC->download_fp = fopen(pathname,"r");
321 if (CC->download_fp == NULL) {
322 cprintf("%d Cannot open %s: %s\n",
323 ERROR+FILE_NOT_FOUND,pathname,strerror(errno));
327 OpenCmdResult(pathname, "image/gif");
331 * open a file for uploading
333 void cmd_uopn(char *cmdbuf)
337 extract(CC->upl_file,cmdbuf,0);
338 extract(CC->upl_comment,cmdbuf,1);
340 if (CtdlAccessCheck(ac_logged_in)) return;
342 if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) {
343 cprintf("%d No directory in this room.\n",ERROR+NOT_HERE);
347 if (strlen(CC->upl_file)==0) {
348 cprintf("%d You must specify a file name.\n",
349 ERROR+FILE_NOT_FOUND);
353 if (CC->upload_fp != NULL) {
354 cprintf("%d You already have a upload file open.\n",ERROR);
358 for (a=0; a<strlen(CC->upl_file); ++a)
359 if (CC->upl_file[a]=='/') CC->upl_file[a] = '_';
360 snprintf(CC->upl_path,sizeof CC->upl_path,"./files/%s/%s",
361 CC->quickroom.QRdirname,CC->upl_file);
362 snprintf(CC->upl_filedir,sizeof CC->upl_filedir,"./files/%s/filedir",
363 CC->quickroom.QRdirname);
365 CC->upload_fp = fopen(CC->upl_path,"r");
366 if (CC->upload_fp != NULL) {
367 fclose(CC->upload_fp);
368 CC->upload_fp = NULL;
369 cprintf("%d '%s' already exists\n",
370 ERROR+ALREADY_EXISTS,CC->upl_path);
374 CC->upload_fp = fopen(CC->upl_path,"wb");
375 if (CC->upload_fp == NULL) {
376 cprintf("%d Cannot open %s: %s\n",
377 ERROR,CC->upl_path,strerror(errno));
380 cprintf("%d Ok\n",OK);
386 * open an image file for uploading
388 void cmd_uimg(char *cmdbuf)
390 int is_this_for_real;
395 if (num_parms(cmdbuf) < 2) {
396 cprintf("%d Usage error.\n", ERROR);
400 is_this_for_real = extract_int(cmdbuf,0);
401 extract(basenm, cmdbuf, 1);
402 if (CC->upload_fp != NULL) {
403 cprintf("%d You already have an upload file open.\n", ERROR);
407 strcpy(CC->upl_path, "");
409 for (a=0; a<strlen(basenm); ++a) {
410 basenm[a] = tolower(basenm[a]);
411 if (basenm[a]=='/') basenm[a] = '_';
414 if (CC->usersupp.axlevel >= 6) {
415 snprintf(CC->upl_path, sizeof CC->upl_path, "./images/%s",
419 if (!strcasecmp(basenm, "_userpic_")) {
420 snprintf(CC->upl_path, sizeof CC->upl_path,
421 "./userpics/%ld.gif", CC->usersupp.usernum);
424 if ( (!strcasecmp(basenm, "_floorpic_")) && (CC->usersupp.axlevel >= 6) ) {
425 which_floor = extract_int(cmdbuf, 2);
426 snprintf(CC->upl_path, sizeof CC->upl_path,
427 "./images/floor.%d.gif", which_floor);
430 if ( (!strcasecmp(basenm, "_roompic_")) && (is_room_aide()) ) {
431 assoc_file_name(CC->upl_path, &CC->quickroom, "images");
434 if (strlen(CC->upl_path) == 0) {
435 cprintf("%d Higher access required.\n",
436 ERROR+HIGHER_ACCESS_REQUIRED);
440 if (is_this_for_real == 0) {
441 cprintf("%d Ok to send image\n", OK);
445 CC->upload_fp = fopen(CC->upl_path,"wb");
446 if (CC->upload_fp == NULL) {
447 cprintf("%d Cannot open %s: %s\n",
448 ERROR,CC->upl_path,strerror(errno));
451 cprintf("%d Ok\n",OK);
452 CC->upload_type = UPL_IMAGE;
457 * close the download file
459 void cmd_clos(void) {
462 if (CC->download_fp == NULL) {
463 cprintf("%d You don't have a download file open.\n",ERROR);
467 fclose(CC->download_fp);
468 CC->download_fp = NULL;
470 if (CC->dl_is_net == 1) {
472 snprintf(buf,sizeof buf,"%s/network/spoolout/%s",BBSDIR,
477 cprintf("%d Ok\n",OK);
484 void abort_upl(struct CitContext *who)
486 if (who->upload_fp != NULL) {
487 fclose(who->upload_fp);
488 who->upload_fp = NULL;
489 unlink(CC->upl_path);
496 * close the upload file
498 void cmd_ucls(char *cmd)
501 char upload_notice[512];
503 if (CC->upload_fp == NULL) {
504 cprintf("%d You don't have an upload file open.\n",ERROR);
508 fclose(CC->upload_fp);
509 CC->upload_fp = NULL;
511 if ((!strcasecmp(cmd,"1")) && (CC->upload_type != UPL_FILE)) {
512 CC->upload_type = UPL_FILE;
513 cprintf("%d Upload completed.\n", OK);
515 if (CC->upload_type == UPL_NET) {
517 execlp("./netproc", "netproc", "-i", NULL);
525 if (!strcasecmp(cmd,"1")) {
526 cprintf("%d File '%s' saved.\n",OK,CC->upl_path);
527 fp = fopen(CC->upl_filedir,"a");
528 if (fp==NULL) fp=fopen(CC->upl_filedir,"w");
530 fprintf(fp,"%s %s\n",CC->upl_file,CC->upl_comment);
534 /* put together an upload notice */
535 sprintf(upload_notice,
536 "NEW UPLOAD: '%s'\n %s\n",
537 CC->upl_file,CC->upl_comment);
538 quickie_message(CC->curr_user, NULL, CC->quickroom.QRname,
543 cprintf("%d File '%s' aborted.\n",OK,CC->upl_path);
550 * read from the download file
552 void cmd_read(char *cmdbuf)
558 start_pos = extract_long(cmdbuf,0);
559 bytes = extract_int(cmdbuf,1);
561 if (CC->download_fp == NULL) {
562 cprintf("%d You don't have a download file open.\n",ERROR);
567 cprintf("%d You may not read more than 4096 bytes.\n",ERROR);
571 fseek(CC->download_fp,start_pos,0);
572 fread(buf,bytes,1,CC->download_fp);
573 cprintf("%d %d\n",BINARY_FOLLOWS,bytes);
574 client_write(buf, bytes);
580 * write to the upload file
582 void cmd_writ(char *cmdbuf)
587 bytes = extract_int(cmdbuf,0);
589 if (CC->upload_fp == NULL) {
590 cprintf("%d You don't have an upload file open.\n",ERROR);
595 cprintf("%d You may not write more than 4096 bytes.\n",ERROR);
599 cprintf("%d %d\n",SEND_BINARY,bytes);
600 client_read(buf, bytes);
601 fwrite(buf,bytes,1,CC->upload_fp);
607 * cmd_netp() - identify as network poll session
609 void cmd_netp(char *cmdbuf)
613 extract(buf,cmdbuf,1);
614 if (strcasecmp(buf,config.c_net_password)) {
615 cprintf("%d authentication failed\n",ERROR);
618 extract(CC->net_node,cmdbuf,0);
619 cprintf("%d authenticated as network node '%s'\n",OK,CC->net_node);
623 * cmd_ndop() - open a network spool file for downloading
625 void cmd_ndop(char *cmdbuf)
630 if (strlen(CC->net_node)==0) {
631 cprintf("%d Not authenticated as a network node.\n",
632 ERROR+NOT_LOGGED_IN);
636 if (CC->download_fp != NULL) {
637 cprintf("%d You already have a download file open.\n",ERROR);
641 snprintf(pathname,sizeof pathname,"%s/network/spoolout/%s",BBSDIR,
644 /* first open the file in append mode in order to create a
645 * zero-length file if it doesn't already exist
647 CC->download_fp = fopen(pathname,"a");
648 if (CC->download_fp != NULL) fclose(CC->download_fp);
651 CC->download_fp = fopen(pathname,"r");
652 if (CC->download_fp==NULL) {
653 cprintf("%d cannot open %s: %s\n",
654 ERROR,pathname,strerror(errno));
659 /* set this flag so other routines know that the download file
660 * currently open is a network spool file
664 stat(pathname,&statbuf);
665 cprintf("%d %ld\n",OK,statbuf.st_size);
669 * cmd_nuop() - open a network spool file for uploading
671 void cmd_nuop(char *cmdbuf)
673 if (strlen(CC->net_node)==0) {
674 cprintf("%d Not authenticated as a network node.\n",
675 ERROR+NOT_LOGGED_IN);
679 if (CC->upload_fp != NULL) {
680 cprintf("%d You already have an upload file open.\n",ERROR);
684 snprintf(CC->upl_path,sizeof CC->upl_path,"%s/network/spoolin/%s.%d",
685 BBSDIR,CC->net_node,getpid());
687 CC->upload_fp = fopen(CC->upl_path,"r");
688 if (CC->upload_fp != NULL) {
689 fclose(CC->upload_fp);
690 CC->upload_fp = NULL;
691 cprintf("%d '%s' already exists\n",
692 ERROR+ALREADY_EXISTS,CC->upl_path);
696 CC->upload_fp = fopen(CC->upl_path,"w");
697 if (CC->upload_fp == NULL) {
698 cprintf("%d Cannot open %s: %s\n",
699 ERROR,CC->upl_path,strerror(errno));
703 CC->upload_type = UPL_NET;
704 cprintf("%d Ok\n",OK);