date and time created 83/07/02 17:56:28 by sam
[unix-history] / usr / src / usr.bin / uucp / uucico / cntrl.c
CommitLineData
48688564
SL
1#ifndef lint
2static char sccsid[] = "@(#)cntrl.c 5.1 (Berkeley) %G%";
3#endif
4
5#include "uucp.h"
6#include <sys/types.h>
7#include <sys/stat.h>
8
9
10
11struct Proto {
12 char P_id;
13 int (*P_turnon)();
14 int (*P_rdmsg)();
15 int (*P_wrmsg)();
16 int (*P_rddata)();
17 int (*P_wrdata)();
18 int (*P_turnoff)();
19};
20
21
22extern int gturnon(), gturnoff();
23extern int grdmsg(), grddata();
24extern int gwrmsg(), gwrdata();
25extern int imsg(), omsg();
26
27struct Proto Ptbl[]={
28 'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,
29 '\0'
30};
31
32int (*Imsg)() = imsg, (*Omsg)() = omsg; /* avoid SEL compiler limitation */
33
34int (*Rdmsg)()=imsg, (*Rddata)();
35int (*Wrmsg)()=omsg, (*Wrdata)();
36int (*Turnon)(), (*Turnoff)();
37
38
39#define YES "Y"
40#define NO "N"
41
42/* failure messages */
43#define EM_MAX 6
44#define EM_LOCACC "N1" /* local access to file denied */
45#define EM_RMTACC "N2" /* remote access to file/path denied */
46#define EM_BADUUCP "N3" /* a bad uucp command was generated */
47#define EM_NOTMP "N4" /* remote error - can't create temp */
48#define EM_RMTCP "N5" /* can't copy to remote directory - file in public */
49#define EM_LOCCP "N6" /* can't copy on local system */
50
51char *Em_msg[] = {
52 "COPY FAILED (reason not given by remote)",
53 "local access to file denied",
54 "remote access to path/file denied",
55 "system error - bad uucp command generated",
56 "remote system can't create temp file",
57 "can't copy to file/directory - file left in PUBDIR/user/file",
58 "can't copy to file/directory - file left in PUBDIR/user/file"
59};
60
61/* */
62
63
64#define XUUCP 'X' /* execute uucp (string) */
65#define SLTPTCL 'P' /* select protocol (string) */
66#define USEPTCL 'U' /* use protocol (character) */
67#define RCVFILE 'R' /* receive file (string) */
68#define SNDFILE 'S' /* send file (string) */
69#define RQSTCMPT 'C' /* request complete (string - yes | no) */
70#define HUP 'H' /* ready to hangup (string - yes | no) */
71#define RESET 'X' /* reset line modes */
72
73
74#define W_TYPE wrkvec[0]
75#define W_FILE1 wrkvec[1]
76#define W_FILE2 wrkvec[2]
77#define W_USER wrkvec[3]
78#define W_OPTNS wrkvec[4]
79#define W_DFILE wrkvec[5]
80#define W_MODE wrkvec[6]
81#define W_NUSER wrkvec[7]
82
83#define XFRRATE 350000L
84#define RMESG(m, s, n) if (rmesg(m, s, n) != 0) {(*Turnoff)(); return(FAIL);} else
85#define RAMESG(s, n) if (rmesg('\0', s, n) != 0) {(*Turnoff)(); return(FAIL);} else
86#define WMESG(m, s) if(wmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);} else
87
88char Wfile[MAXFULLNAME] = {'\0'};
89char Dfile[MAXFULLNAME];
90
91/*
92 * To avoid a huge backlog of X. files, start uuxqt every so often.
93 * To avoid a huge number of uuxqt zombies,
94 * wait for one occasionally!
95 */
96static int nXfiles = 0; /* number of X files since last uuxqt start */
97static int nXQTs = 0; /* number of uuxqts started */
98
99/*******
100 * cntrl(role, wkpre)
101 * int role;
102 * char *wkpre;
103 *
104 * cntrl - this routine will execute the conversation
105 * between the two machines after both programs are
106 * running.
107 *
108 * return codes
109 * SUCCESS - ok
110 * FAIL - failed
111 */
112
113cntrl(role, wkpre)
114int role;
115char *wkpre;
116{
117 char msg[BUFSIZ], rqstr[BUFSIZ];
118 register FILE *fp;
119 int filemode;
120 struct stat stbuf;
121 char filename[MAXFULLNAME], wrktype, *wrkvec[20];
122 extern (*Rdmsg)(), (*Wrmsg)();
123 extern char *index(), *lastpart();
124 int status = 1;
125 register int i, narg;
126 int mailopt, ntfyopt;
127 int ret;
128 static int pnum, tmpnum = 0;
129
130 pnum = getpid();
131/*
132 * ima.247, John Levine, IECC, PO Box 349, Cambridge MA 02238; (617) 491-5450
133 * zap Wfile to prevent reuse of wrong C. file
134 */
135 Wfile[0] = '\0';
136top:
137 for (i = 0; i < sizeof wrkvec / sizeof wrkvec[0]; i++)
138 wrkvec[i] = 0;
139 DEBUG(4, "*** TOP *** - role=%d, ", role);
140 setline(RESET);
141 if (role == MASTER) {
142 /* get work */
143 if ((narg = gtwvec(Wfile, Spool, wkpre, wrkvec)) == 0) {
144 WMESG(HUP, "");
145 RMESG(HUP, msg, 1);
146 goto process;
147 }
148 wrktype = W_TYPE[0];
149 mailopt = index(W_OPTNS, 'm') != NULL;
150 ntfyopt = index(W_OPTNS, 'n') != NULL;
151
152 msg[0] = '\0';
153 for (i = 1; i < narg; i++) {
154 strcat(msg, " ");
155 strcat(msg, wrkvec[i]);
156 }
157
158 if (wrktype == XUUCP) {
159 sprintf(rqstr, "X %s", msg);
160 logent(rqstr, "REQUEST");
161 goto sendmsg;
162 }
163
164 ASSERT(narg > 4, "ARG COUNT<5", "", i);
165 sprintf(User, "%.9s", W_USER);
166 sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,
167 W_FILE2, W_USER);
168 logent(rqstr, "REQUEST");
169 if (wrktype == SNDFILE ) {
170 strcpy(filename, W_FILE1);
171 i = expfile(filename);
172 DEBUG(4, "expfile type - %d", i);
173 if (i != 0 && chkpth(User, "", filename))
174 goto e_access;
175 strcpy(Dfile, W_DFILE);
176 fp = NULL;
177 if (index(W_OPTNS, 'c') == NULL) {
178 fp = fopen(subfile(Dfile), "r");
179 if (fp != NULL)
180 i = 0;
181 }
182 if (fp == NULL &&
183 (fp = fopen(subfile(filename), "r")) == NULL) {
184 /* can not read data file */
185 logent("CAN'T READ DATA", "FAILED");
186 unlinkdf(Dfile);
187 lnotify(User, filename, "can't access");
188 goto top;
189 }
190 /* if file exists but is not generally readable... */
191 if (i != 0 && fstat(fileno(fp), &stbuf) == 0
192 && (stbuf.st_mode & ANYREAD) == 0) {
193 e_access:;
194 /* access denied */
195 fclose(fp);
196 fp = NULL;
197 logent("DENIED", "ACCESS");
198 unlinkdf(W_DFILE);
199 lnotify(User, filename, "access denied");
200 goto top;
201 }
202
203 setline(SNDFILE);
204 }
205
206 if (wrktype == RCVFILE) {
207 strcpy(filename, W_FILE2);
208 expfile(filename);
209 if (chkpth(User, "", filename)
210 || chkperm(filename, index(W_OPTNS, 'd'))) {
211 /* access denied */
212 logent("DENIED", "ACCESS");
213 lnotify(User, filename, "access denied");
214 goto top;
215 }
216 sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
217 if ((fp = fopen(subfile(Dfile), "w")) == NULL) {
218 /* can not create temp */
219 logent("CAN'T CREATE TM", "FAILED");
220 unlinkdf(Dfile);
221 goto top;
222 }
223 setline(RCVFILE);
224 }
225sendmsg:
226 DEBUG(4, "wrktype - %c\n ", wrktype);
227 WMESG(wrktype, msg);
228 RMESG(wrktype, msg, 1);
229 goto process;
230 }
231
232 /* role is slave */
233 RAMESG(msg, 1);
234 goto process;
235
236process:
237/* rti!trt: ultouch is now done in gio.c (yes, kludge)
238 * ultouch();
239 */
240 DEBUG(4, " PROCESS: msg - %s\n", msg);
241 switch (msg[0]) {
242
243 case RQSTCMPT:
244 DEBUG(4, "%s\n", "RQSTCMPT:");
245 if (msg[1] == 'N') {
246 i = atoi(&msg[2]);
247 if (i<0 || i>EM_MAX) i=0;
248 /* duke!rti: only note failed requests */
249 logent(msg, "REQUESTED");
250 }
251 if (role == MASTER) {
252 notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
253 }
254 goto top;
255
256 case HUP:
257 DEBUG(4, "%s\n", "HUP:");
258 if (msg[1] == 'Y') {
259 WMESG(HUP, YES);
260 (*Turnoff)();
261 Rdmsg = Imsg;
262 Wrmsg = Omsg;
263 return(0);
264 }
265
266 if (msg[1] == 'N') {
267 ASSERT(role == MASTER, "WRONG ROLE", "", role);
268 role = SLAVE;
269 goto top;
270 }
271
272 /* get work */
273 if (!iswrk(Wfile, "chk", Spool, wkpre)) {
274 WMESG(HUP, YES);
275 RMESG(HUP, msg, 1);
276 goto process;
277 }
278
279 WMESG(HUP, NO);
280 role = MASTER;
281 goto top;
282
283 case XUUCP:
284 if (role == MASTER) {
285 goto top;
286 }
287
288 /* slave part */
289 i = getargs(msg, wrkvec);
290 strcpy(filename, W_FILE1);
291 if (index(filename, ';') != NULL
292 || index(W_FILE2, ';') != NULL
293 || i < 3) {
294 WMESG(XUUCP, NO);
295 goto top;
296 }
297 expfile(filename);
298 if (chkpth("", Rmtname, filename)) {
299 WMESG(XUUCP, NO);
300 logent("XUUCP DENIED", filename);
301 goto top;
302 }
303 sprintf(rqstr, "%s %s", filename, W_FILE2);
304 xuucp(rqstr);
305 WMESG(XUUCP, YES);
306 goto top;
307
308 case SNDFILE:
309 /* MASTER section of SNDFILE */
310
311 DEBUG(4, "%s\n", "SNDFILE:");
312 if (msg[1] == 'N') {
313 i = atoi(&msg[2]);
314 if (i < 0 || i > EM_MAX)
315 i = 0;
316 logent(Em_msg[i], "REQUEST");
317 notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
318 ASSERT(role == MASTER, "WRONG ROLE", "", role);
319 fclose(fp);
320 fp = NULL;
321 if (msg[1] != '4')
322 unlinkdf(W_DFILE);
323 goto top;
324 }
325
326 if (msg[1] == 'Y') {
327 /* send file */
328 ASSERT(role == MASTER, "WRONG ROLE", "", role);
329 ret = fstat(fileno(fp), &stbuf);
330 ASSERT(ret != -1, "STAT FAILED", filename, 0);
331 i = 1 + (int)(stbuf.st_size / XFRRATE);
332 ret = (*Wrdata)(fp, Ofn);
333 fclose(fp);
334 fp = NULL;
335 if (ret != 0) {
336 (*Turnoff)();
337 return(FAIL);
338 }
339 RMESG(RQSTCMPT, msg, i);
340/* put the unlink *after* the RMESG -- fortune!Dave-Yost */
341 unlinkdf(W_DFILE);
342 goto process;
343 }
344
345 /* SLAVE section of SNDFILE */
346 ASSERT(role == SLAVE, "WRONG ROLE", "", role);
347
348 /* request to receive file */
349 /* check permissions */
350 i = getargs(msg, wrkvec);
351 ASSERT(i > 4, "ARG COUNT<5", "", i);
352 sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,
353 W_FILE2, W_USER);
354 logent(rqstr, "REQUESTED");
355 DEBUG(4, "msg - %s\n", msg);
356 strcpy(filename, W_FILE2);
357 /* Run uuxqt occasionally */
358 if (filename[0] == XQTPRE) {
359 if (++nXfiles > 10) {
360 nXfiles = 0;
361 /* I sure hope the wait(II) does not hang.
362 * One can never tell about UNIX variants.
363 */
364 if (++nXQTs > 2)
365 wait((int *)0);
366 xuuxqt();
367 }
368 }
369 /* rti!trt: expand filename, i is set to 0 if this is
370 * is a vanilla spool file, so no stat(II)s are needed */
371 i = expfile(filename);
372 DEBUG(4, "expfile type - %d\n", i);
373 if (i != 0) {
374 if (chkpth("", Rmtname, filename)
375 || chkperm(filename, index(W_OPTNS, 'd'))) {
376 WMESG(SNDFILE, EM_RMTACC);
377 logent("DENIED", "PERMISSION");
378 goto top;
379 }
380 if (isdir(filename)) {
381 strcat(filename, "/");
382 strcat(filename, lastpart(W_FILE1));
383 }
384 }
385 sprintf(User, "%.9s", W_USER);
386
387 DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
388 sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
389 if((fp = fopen(subfile(Dfile), "w")) == NULL) {
390 WMESG(SNDFILE, EM_NOTMP);
391 logent("CAN'T OPEN", "DENIED");
392 unlinkdf(Dfile);
393 goto top;
394 }
395
396 WMESG(SNDFILE, YES);
397 ret = (*Rddata)(Ifn, fp);
398 /* ittvax!swatt: (try to) make sure IO successful */
399 fflush(fp);
400 if (ferror(fp) || fclose(fp))
401 ret = FAIL;
402 if (ret != 0) {
403 (*Turnoff)();
404 return(FAIL);
405 }
406 /* copy to user directory */
407 ntfyopt = index(W_OPTNS, 'n') != NULL;
408 status = xmv(Dfile, filename);
409 WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
410 if (status == 0) {
411 sscanf(W_MODE, "%o", &filemode);
412 if (filemode <= 0)
413 filemode = BASEMODE;
414 chmod(subfile(filename), filemode | BASEMODE);
415 arrived(ntfyopt, filename, W_NUSER, Rmtname, User);
416 }
417 else {
418 logent("FAILED", "COPY");
419 status = putinpub(filename, Dfile, W_USER);
420 DEBUG(4, "->PUBDIR %d\n", status);
421 if (status == 0)
422 arrived(ntfyopt, filename, W_NUSER,
423 Rmtname, User);
424 }
425
426 goto top;
427
428 case RCVFILE:
429 /* MASTER section of RCVFILE */
430
431 DEBUG(4, "%s\n", "RCVFILE:");
432 if (msg[1] == 'N') {
433 i = atoi(&msg[2]);
434 if (i < 0 || i > EM_MAX)
435 i = 0;
436 logent(Em_msg[i], "REQUEST");
437 notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
438 ASSERT(role == MASTER, "WRONG ROLE", "", role);
439 fclose(fp);
440 unlinkdf(Dfile);
441 goto top;
442 }
443
444 if (msg[1] == 'Y') {
445 /* receive file */
446 ASSERT(role == MASTER, "WRONG ROLE", "", role);
447 ret = (*Rddata)(Ifn, fp);
448 /* ittvax!swatt: (try to) make sure IO successful */
449 fflush(fp);
450 if (ferror(fp) || fclose(fp))
451 ret = FAIL;
452 if (ret != 0) {
453 (*Turnoff)();
454 return(FAIL);
455 }
456 /* copy to user directory */
457 if (isdir(filename)) {
458 strcat(filename, "/");
459 strcat(filename, lastpart(W_FILE1));
460 }
461 status = xmv(Dfile, filename);
462 WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
463 notify(mailopt, W_USER, filename, Rmtname,
464 status ? EM_LOCCP : YES);
465 if (status == 0) {
466 sscanf(&msg[2], "%o", &filemode);
467 if (filemode <= 0)
468 filemode = BASEMODE;
469 chmod(subfile(filename), filemode | BASEMODE);
470 }
471 else {
472 logent("FAILED", "COPY");
473 putinpub(filename, Dfile, W_USER);
474 }
475 goto top;
476 }
477
478 /* SLAVE section of RCVFILE */
479 ASSERT(role == SLAVE, "WRONG ROLE", "", role);
480
481 /* request to send file */
482 strcpy(rqstr, msg);
483 logent(rqstr, "REQUESTED");
484
485 /* check permissions */
486 i = getargs(msg, wrkvec);
487 ASSERT(i > 3, "ARG COUNT<4", "", i);
488 DEBUG(4, "msg - %s\n", msg);
489 DEBUG(4, "W_FILE1 - %s\n", W_FILE1);
490 strcpy(filename, W_FILE1);
491 expfile(filename);
492 if (isdir(filename)) {
493 strcat(filename, "/");
494 strcat(filename, lastpart(W_FILE2));
495 }
496 sprintf(User, "%.9s", W_USER);
497 if (chkpth("", Rmtname, filename) || anyread(filename)) {
498 WMESG(RCVFILE, EM_RMTACC);
499 logent("DENIED", "PERMISSION");
500 goto top;
501 }
502 DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
503
504 if ((fp = fopen(subfile(filename), "r")) == NULL) {
505 WMESG(RCVFILE, EM_RMTACC);
506 logent("CAN'T OPEN", "DENIED");
507 goto top;
508 }
509
510 /* ok to send file */
511 ret = fstat(fileno(fp), &stbuf);
512 ASSERT(ret != -1, "STAT FAILED", filename, 0);
513 i = 1 + (int)(stbuf.st_size / XFRRATE);
514 sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777);
515 WMESG(RCVFILE, msg);
516 ret = (*Wrdata)(fp, Ofn);
517 fclose(fp);
518 if (ret != 0) {
519 (*Turnoff)();
520 return(FAIL);
521 }
522 RMESG(RQSTCMPT, msg, i);
523 goto process;
524 }
525 (*Turnoff)();
526 return(FAIL);
527}
528
529
530/***
531 * rmesg(c, msg, n) read message 'c'
532 * try 'n' times
533 * char *msg, c;
534 *
535 * return code: 0 | FAIL
536 */
537
538rmesg(c, msg, n)
539register char *msg, c;
540register int n;
541{
542 char str[50];
543
544 DEBUG(4, "rmesg - '%c' ", c);
545 if (n != 1) {
546 sprintf(str, "%d", n);
547 logent(str, "PATIENCE");
548 }
549 while ((*Rdmsg)(msg, Ifn) != 0) {
550 if (--n > 0)
551 continue;
552 DEBUG(4, "got %s\n", "FAIL");
553 sprintf(str, "expected '%c' got FAIL", c);
554 logent(str, "BAD READ");
555 return(FAIL);
556 }
557 if (c != '\0' && msg[0] != c) {
558 DEBUG(4, "got %s\n", msg);
559 sprintf(str, "expected '%c' got %.25s", c, msg);
560 logent(str, "BAD READ");
561 return(FAIL);
562 }
563 DEBUG(4, "got %.25s\n", msg);
564 return(0);
565}
566
567
568/***
569 * wmesg(m, s) write a message (type m)
570 * char *s, m;
571 *
572 * return codes: 0 - ok | FAIL - ng
573 */
574
575wmesg(m, s)
576register char *s, m;
577{
578 DEBUG(4, "wmesg '%c'", m);
579 DEBUG(4, "%.25s\n", s);
580 return((*Wrmsg)(m, s, Ofn));
581}
582
583
584/***
585 * notify mail results of command
586 *
587 * return codes: none
588 */
589
590notify(mailopt, user, file, sys, msgcode)
591char *user, *file, *sys, *msgcode;
592{
593 char str[200];
594 int i;
595 char *msg;
596
597 if (!mailopt && *msgcode == 'Y')
598 return;
599 if (*msgcode == 'Y')
600 msg = "copy succeeded";
601 else {
602 i = atoi(msgcode + 1);
603 if (i < 1 || i > EM_MAX)
604 i = 0;
605 msg = Em_msg[i];
606 }
607 sprintf(str, "file %s, system %s\n%s\n",
608 file, sys, msg);
609 mailst(user, str, "");
610 return;
611}
612
613/***
614 * lnotify(user, file, mesg) - local notify
615 *
616 * return code - none
617 */
618
619lnotify(user, file, mesg)
620char *user, *file, *mesg;
621{
622 char mbuf[200];
623 sprintf(mbuf, "file %s on %s\n%s\n", file, Myname, mesg);
624 mailst(user, mbuf, "");
625 return;
626}
627
628
629/***
630 * startup(role)
631 * int role;
632 *
633 * startup - this routine will converse with the remote
634 * machine, agree upon a protocol (if possible) and start the
635 * protocol.
636 *
637 * return codes:
638 * SUCCESS - successful protocol selection
639 * FAIL - can't find common or open failed
640 */
641
642startup(role)
643int role;
644{
645 extern (*Rdmsg)(), (*Wrmsg)();
646 extern char *blptcl(), fptcl();
647 char msg[BUFSIZ], str[BUFSIZ];
648
649 Rdmsg = Imsg;
650 Wrmsg = Omsg;
651 if (role == MASTER) {
652 RMESG(SLTPTCL, msg, 1);
653 if ((str[0] = fptcl(&msg[1])) == NULL) {
654 /* no protocol match */
655 WMESG(USEPTCL, NO);
656 return(FAIL);
657 }
658 str[1] = '\0';
659 WMESG(USEPTCL, str);
660 if (stptcl(str) != 0)
661 return(FAIL);
662 DEBUG(4, "protocol %s\n", str);
663 return(SUCCESS);
664 }
665 else {
666 WMESG(SLTPTCL, blptcl(str));
667 RMESG(USEPTCL, msg, 1);
668 if (msg[1] == 'N') {
669 return(FAIL);
670 }
671
672 if (stptcl(&msg[1]) != 0)
673 return(FAIL);
674 DEBUG(4, "Protocol %s\n", msg);
675 return(SUCCESS);
676 }
677}
678
679
680/*******
681 * char
682 * fptcl(str)
683 * char *str;
684 *
685 * fptcl - this routine will choose a protocol from
686 * the input string (str) and return the found letter.
687 *
688 * return codes:
689 * '\0' - no acceptable protocol
690 * any character - the chosen protocol
691 */
692
693char
694fptcl(str)
695register char *str;
696{
697 register struct Proto *p;
698
699 for (p = Ptbl; p->P_id != '\0'; p++) {
700 if (index(str, p->P_id) != NULL) {
701 return(p->P_id);
702 }
703 }
704
705 return('\0');
706}
707
708
709/***
710 * char *
711 * blptcl(str)
712 * char *str;
713 *
714 * blptcl - this will build a string of the
715 * letters of the available protocols and return
716 * the string (str).
717 *
718 * return:
719 * a pointer to string (str)
720 */
721
722char *
723blptcl(str)
724register char *str;
725{
726 register struct Proto *p;
727 register char *s;
728
729 for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++);
730 return(str);
731}
732
733/***
734 * stptcl(c)
735 * char *c;
736 *
737 * stptcl - this routine will set up the six routines
738 * (Rdmsg, Wrmsg, Rddata, Wrdata, Turnon, Turnoff) for the
739 * desired protocol.
740 *
741 * return codes:
742 * SUCCESS - ok
743 * FAIL - no find or failed to open
744 *
745 */
746
747stptcl(c)
748register char *c;
749{
750 register struct Proto *p;
751
752 for (p = Ptbl; p->P_id != '\0'; p++) {
753 if (*c == p->P_id) {
754 /* found protocol - set routines */
755 Rdmsg = p->P_rdmsg;
756 Wrmsg = p->P_wrmsg;
757 Rddata = p->P_rddata;
758 Wrdata = p->P_wrdata;
759 Turnon = p->P_turnon;
760 Turnoff = p->P_turnoff;
761 if ((*Turnon)() != 0)
762 return(FAIL);
763 DEBUG(4, "Proto started %c\n", *c);
764 return(SUCCESS);
765 }
766 }
767 DEBUG(4, "Proto start-fail %c\n", *c);
768 return(FAIL);
769}
770
771/***
772 * putinpub put file in public place
773 * if successful, filename is modified
774 *
775 * return code 0 | FAIL
776 */
777
778putinpub(file, tmp, user)
779register char *file, *user, *tmp;
780{
781 char fullname[MAXFULLNAME];
782 char *lastpart();
783 int status;
784
785 sprintf(fullname, "%s/%s/", PUBDIR, user);
786 if (mkdirs(fullname) != 0) {
787 /* can not make directories */
788 return(FAIL);
789 }
790 strcat(fullname, lastpart(file));
791 status = xmv(tmp, fullname);
792 if (status == 0) {
793 strcpy(file, fullname);
794 chmod(subfile(fullname), BASEMODE);
795 }
796 return(status);
797}
798
799/***
800 * unlinkdf(file) - unlink D. file
801 *
802 * return code - none
803 */
804
805unlinkdf(file)
806register char *file;
807{
808 if (strlen(file) > 6)
809 unlink(subfile(file));
810 return;
811}
812
813/***
814 * arrived - notify receiver of arrived file
815 *
816 * return code - none
817 */
818
819arrived(opt, file, nuser, rmtsys, rmtuser)
820char *file, *nuser, *rmtsys, *rmtuser;
821{
822 char mbuf[200];
823
824 if (!opt)
825 return;
826 sprintf(mbuf, "%s from %s!%s arrived\n", file, rmtsys, rmtuser);
827 mailst(nuser, mbuf, "");
828 return;
829}