ftp.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:35k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* Copyright (c) 1985, 1989 Regents of the University of California.  All    */
  2. /* rights reserved.                                                          */
  3. /*                                                                           */
  4. /* Redistribution and use in source and binary forms, with or without        */
  5. /* modification, are permitted provided that the following conditions are    */
  6. /* met: 1. Redistributions of source code must retain the above copyright    */
  7. /*    notice, this list of conditions and the following disclaimer.          */
  8. /* 2. Redistributions in binary form must reproduce the above copyright      */
  9. /*    notice, this list of conditions and the following disclaimer in the    */
  10. /*    documentation and/or other materials provided with the distribution.   */
  11. /* 3. All advertising materials mentioning features or use of this software  */
  12. /*    must display the following acknowledgement:                            */
  13. /*  This product includes software developed by the University of        */
  14. /*  California, Berkeley and its contributors.  4. Neither the name      */
  15. /* of the University nor the names of its contributors                       */
  16. /*    may be used to endorse or promote products derived from this software  */
  17. /*    without specific prior written permission.                             */
  18. /*                                                                           */
  19. /* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND   */
  20. /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE     */
  21. /* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        */
  22. /* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE */
  23. /* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR       */
  24. /* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF      */
  25. /* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  */
  26. /* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN   */
  27. /* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)   */
  28. /* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF    */
  29. /* THE POSSIBILITY OF SUCH DAMAGE.                                           */
  30. #include "ftp_var.h"
  31. #define DONT_NEED_SIGBLOCK
  32. #define DONT_NEED_SIGPAUSE
  33. #define DONT_NEED_SIGUNBLOCK
  34. #define DONT_NEED_SIGPENDING
  35. #include "sigfix.h"
  36. #ifdef HAVE_SYS_IOCTL_H
  37. #include <sys/ioctl.h>
  38. #endif
  39. #include <netinet/ip.h>
  40. #include <arpa/ftp.h>
  41. #include <arpa/telnet.h>
  42. #ifdef HAVE_FCNTL_H
  43. #include <fcntl.h>
  44. #endif
  45. #include <varargs.h>
  46. #ifdef FASCIST
  47. #include <syslog.h>
  48. #endif
  49. #ifdef HAVE_BSTRING_H
  50. #include <bstring.h>
  51. #endif
  52. #ifndef HAVE_BCOPY
  53. #define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len))
  54. #endif
  55. #ifndef HAVE_BZERO
  56. #define bzero(b,len)     memset(b, 0, (size_t)(len))
  57. #endif
  58. #ifndef HAVE_BCMP
  59. #define bcmp(b1,b2,len)  memcmp(b1, b2, (size_t)(len))
  60. #endif
  61. sig_t lostpeer();
  62. struct sockaddr_in hisctladdr;
  63. struct sockaddr_in data_addr;
  64. struct sockaddr_in myctladdr;
  65. int data = -1;
  66. int abrtflag = 0;
  67. int ptflag = 0;
  68. off_t restart_point = 0;
  69. unsigned long socks_bind_remoteAddr; /* Socks */
  70. extern int connected, errno;
  71. FILE *cin, *cout;
  72. FILE *dataconn();
  73. jmp_buf ptabort;
  74. int ptabflg;
  75. #ifndef HAVE_HERROR
  76. char *h_errlist[] = {
  77.     "Error 0",
  78.     "Unknown host", /* 1 HOST_NOT_FOUND */
  79.     "Host name lookup failure", /* 2 TRY_AGAIN */
  80.     "Unknown server error", /* 3 NO_RECOVERY */
  81.     "No address associated with name", /* 4 NO_ADDRESS */
  82. };
  83. int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) };
  84. int h_errno;
  85. /* herror --                                                                 */
  86. /* print the error indicated by the h_errno value.                           */
  87. /*                                                                           */
  88. void herror(const char *s) {
  89.     if (s && *s) {
  90. fprintf(stderr, "%s: ", s);
  91.     }
  92.     if ((h_errno < 0) || (h_errno >= h_nerr)) {
  93. fprintf(stderr, "Unknown errorn");
  94.     } else if (h_errno == 0) {
  95. #ifdef sun
  96. fprintf(stderr, "Host unknownn");
  97. #endif
  98.     } else {
  99. fprintf(stderr, "%sn", h_errlist[h_errno]);
  100.     }
  101. }
  102. #endif
  103. char *hookup(char *host, int port) {
  104.     register struct hostent *hp = 0;
  105.     static char hostnamebuf[80];
  106.     int s, len, tos;
  107.     bzero((char *)&hisctladdr, sizeof (hisctladdr));
  108.     hisctladdr.sin_addr.s_addr = inet_addr(host);
  109.     if (hisctladdr.sin_addr.s_addr != -1) {
  110. hisctladdr.sin_family = AF_INET;
  111. strncpy(hostnamebuf, host, sizeof(hostnamebuf));
  112.     } else {
  113. if ((hp = gethostbyname(host)) == NULL) {
  114.     fprintf(stderr, "ftp: %s: ", host);
  115.     herror(NULL);
  116.     code = -1;
  117.     return NULL;
  118. }
  119. hisctladdr.sin_family = hp->h_addrtype;
  120. bcopy(hp->h_addr_list[0], (caddr_t)&hisctladdr.sin_addr, hp->h_length);
  121. strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
  122.     }
  123.     hostname = hostnamebuf;
  124.     
  125.     if ((s = socket(hisctladdr.sin_family, SOCK_STREAM, 0)) < 0) {
  126. perror("ftp: socket");
  127. code = -1;
  128. return NULL;
  129.     }
  130.     hisctladdr.sin_port = port;
  131.     while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
  132. if (hp && hp->h_addr_list[1]) {
  133.     int oerrno = errno;
  134.     fprintf(stderr, "ftp: connect to address %s: ", inet_ntoa(hisctladdr.sin_addr));
  135.     errno = oerrno;
  136.     perror(NULL);
  137.     hp->h_addr_list++;
  138.     bcopy(hp->h_addr_list[0], (caddr_t)&hisctladdr.sin_addr, hp->h_length);
  139.     fprintf(stdout, "Trying %s...n", inet_ntoa(hisctladdr.sin_addr));
  140.     close(s);
  141.     if ((s = socket(hisctladdr.sin_family, SOCK_STREAM, 0)) < 0) {
  142. perror("ftp: socket");
  143. code = -1;
  144. return NULL;
  145.     }
  146.     continue;
  147. }
  148. perror("ftp: connect");
  149. code = -1;
  150. goto bad;
  151.     }
  152.     socks_bind_remoteAddr = hisctladdr.sin_addr.s_addr;  /* Socks */
  153.     len = sizeof (myctladdr);
  154.     if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
  155. perror("ftp: getsockname");
  156. code = -1;
  157. goto bad;
  158.     }
  159. #if defined(IP_TOS) && defined(IPTOS_LOWDELAY)
  160.     tos = IPTOS_LOWDELAY;
  161.     if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
  162. perror("ftp: setsockopt TOS (ignored)");
  163. #endif
  164.     cin  = fdopen(s, "r");
  165.     cout = fdopen(dup(s), "w"); /* when (if ever) do we need the dup ? */
  166.     if (cin == NULL || cout == NULL) {
  167. fprintf(stderr, "ftp: fdopen failed.n");
  168. if (cin)  fclose(cin);
  169. if (cout) fclose(cout);
  170. code = -1;
  171. goto bad;
  172.     }
  173.     
  174.     if (verbose) printf("Connected to %s.n", hostname);
  175.     if (getreply(0) > 2) {  /* read startup message from server */
  176. if (cin)  fclose(cin);
  177. if (cout) fclose(cout);
  178. code = -1;
  179. goto bad;
  180.     }
  181. #ifdef SO_OOBINLINE
  182.     {
  183. int on = 1;
  184.     
  185. if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0 && debug) {
  186.     perror("ftp: setsockopt");
  187. }
  188.     }
  189. #endif
  190.     return (hostname);
  191. bad:
  192.     close(s);
  193.     return NULL;
  194. }
  195. void cmdabort() {
  196.     extern jmp_buf ptabort;
  197.     
  198.     printf("n");
  199.     fflush(stdout);
  200.     abrtflag++;
  201.     if (!ptflag) return;
  202.     longjmp(ptabort,1);
  203. }
  204. /*VARARGS*/
  205. int command(va_alist) va_dcl {
  206.     va_list ap;
  207.     char *fmt;
  208.     int r;
  209.     sig_t oldintr;
  210.     
  211.     abrtflag = 0;
  212.     if (debug) {
  213. printf("---> ");
  214. va_start(ap);
  215. fmt = va_arg(ap, char *);
  216. if (strncmp("PASS ", fmt, 5) == 0)
  217.     printf("PASS XXXX");
  218. else 
  219.     vfprintf(stdout, fmt, ap);
  220. va_end(ap);
  221. printf("n");
  222. fflush(stdout);
  223.     }
  224.     if (cout == NULL) {
  225. perror ("No control connection for command");
  226. code = -1;
  227. return (0);
  228.     }
  229.     oldintr = (sig_t)Signal(SIGINT, cmdabort);
  230.     va_start(ap);
  231.     fmt = va_arg(ap, char *);
  232.     vfprintf(cout, fmt, ap);
  233.     va_end(ap);
  234.     fprintf(cout, "rn");
  235.     fflush(cout);
  236.     cpend = 1;
  237.     r = getreply(!strcmp(fmt, "QUIT"));
  238.     if (abrtflag && oldintr != SIG_IGN) (*oldintr)(SIGINT);
  239.     Signal(SIGINT, oldintr);
  240.     return(r);
  241. }
  242. int login(char *host) {
  243.     char tmp[80];
  244.     char *user, *pass, *acct, *getlogin(), *getpass();
  245.     int n, aflag = 0;
  246.     user = pass = acct = 0;
  247.     if (ruserpass(host, &user, &pass, &acct) < 0) {
  248. code = -1;
  249. return(0);
  250.     }
  251.     while (user == NULL) {
  252. char *myname = getlogin();
  253. if (myname == NULL) {
  254.     struct passwd *pp = getpwuid(getuid());
  255.     if (pp != NULL)
  256. myname = pp->pw_name;
  257. }
  258. if (myname)
  259.     printf("Name (%s:%s): ", host, myname);
  260. else
  261.     printf("Name (%s): ", host);
  262. fgets(tmp, sizeof(tmp) - 1, stdin);
  263. tmp[strlen(tmp) - 1] = '';
  264. if (*tmp == '')
  265.     user = myname;
  266. else
  267.     user = tmp;
  268.     }
  269.     n = command("USER %s", user);
  270.     if (n == CONTINUE) {
  271. if (pass == NULL) {
  272.     if (!strcmp(user, "anonymous") || !strcmp(user, "ftp")) {
  273. printf("Password: "); fflush(stdout);
  274. fgets(tmp, sizeof(tmp) - 1, stdin);
  275. tmp[strlen(tmp) - 1] = '';
  276. pass = tmp;
  277.     } else
  278. pass = getpass("Password:");
  279. }
  280. n = command("PASS %s", pass);
  281.     }
  282.     if (n == CONTINUE) {
  283. aflag++;
  284. acct = getpass("Account:");
  285. n = command("ACCT %s", acct);
  286.     }
  287.     if (n != COMPLETE) {
  288. fprintf(stderr, "Login failed.n");
  289. return (0);
  290.     }
  291.     if (!aflag && acct != NULL)
  292. command("ACCT %s", acct);
  293.     if (proxy)
  294. return(1);
  295.     for (n = 0; n < macnum; ++n) {
  296. if (!strcmp("init", macros[n].mac_name)) {
  297.     strcpy(line, "$init");
  298.     makeargv();
  299.     domacro(margc, margv);
  300.     break;
  301. }
  302.     }
  303.     return (1);
  304. }
  305. char reply_string[BUFSIZ]; /* last line of previous reply */
  306. #include <ctype.h>
  307. int getreply(int expecteof) {
  308.     register int c, n;
  309.     register int dig;
  310.     register char *cp;
  311.     int originalcode = 0, continuation = 0;
  312.     sig_t oldintr;
  313.     int pflag = 0;
  314.     char *pt = pasv;
  315.     void cmdabort();
  316.     oldintr = (sig_t)Signal(SIGINT, cmdabort);
  317.     for (;;) {
  318. dig = n = code = 0;
  319. cp = reply_string;
  320. while ((c = getc(cin)) != 'n') {
  321.     if (c == IAC) {     /* handle telnet commands */
  322. switch (c = getc(cin)) {
  323.     case WILL:
  324.     case WONT:
  325. c = getc(cin);
  326. fprintf(cout, "%c%c%c", IAC, DONT, c);
  327. fflush(cout);
  328. break;
  329.     case DO:
  330.     case DONT:
  331. c = getc(cin);
  332. fprintf(cout, "%c%c%c", IAC, WONT, c);
  333. fflush(cout);
  334. break;
  335.     default:
  336. break;
  337. }
  338. continue;
  339.     }
  340.     dig++;
  341.     if (c == EOF) {
  342. if (expecteof) {
  343.     Signal(SIGINT,oldintr);
  344.     code = 221;
  345.     return (0);
  346. }
  347. lostpeer();
  348. if (verbose) {
  349.     printf("421 Service not available, remote server has closed connectionn");
  350.     fflush(stdout);
  351. }
  352. code = 421;
  353. return(4);
  354.     }
  355.     if (c != 'r' && (verbose > 0 ||
  356.       (verbose > -1 && n == '5' && dig > 4))) {
  357. if (proxflag && (dig == 1 || (dig == 5 && verbose == 0)))
  358.     printf("%s:",hostname);
  359. putchar(c);
  360.     }
  361.     if (dig < 4 && isdigit(c))
  362. code = code * 10 + (c - '0');
  363.     if (!pflag && code == 227)
  364. pflag = 1;
  365.     if (dig > 4 && pflag == 1 && isdigit(c))
  366. pflag = 2;
  367.     if (pflag == 2) {
  368. if (c != 'r' && c != ')')
  369.     *pt++ = c;
  370. else {
  371.     *pt = '';
  372.     pflag = 3;
  373. }
  374.     }
  375.     if (dig == 4 && c == '-') {
  376. if (continuation) code = 0;
  377. continuation++;
  378.     }
  379.     if (n == 0)
  380. n = c;
  381.     if (cp < &reply_string[sizeof(reply_string) - 1])
  382. *cp++ = c;
  383. }
  384. if (verbose > 0 || (verbose > -1 && n == '5')) {
  385.     putchar(c);
  386.     fflush(stdout);
  387. }
  388. if (continuation && code != originalcode) {
  389.     if (originalcode == 0) originalcode = code;
  390.     continue;
  391. }
  392. *cp = '';
  393. if (n != '1')
  394.     cpend = 0;
  395. Signal(SIGINT,oldintr);
  396. if (code == 421 || originalcode == 421)
  397.     lostpeer();
  398. if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
  399.     (*oldintr)(SIGINT);
  400. return (n - '0');
  401.     }
  402. }
  403. int empty(fd_set *mask, int sec) {
  404.     struct timeval t;
  405.     
  406.     t.tv_sec = (long) sec;
  407.     t.tv_usec = 0;
  408.     return(select(32, mask, NULL, NULL, &t));
  409. }
  410. jmp_buf sendabort;
  411. void abortsend() {
  412.     mflag = 0;
  413.     abrtflag = 0;
  414.     printf("nsend abortednwaiting for remote to finish abortn");
  415.     fflush(stdout);
  416.     longjmp(sendabort, 1);
  417. }
  418. #define HASHBYTES 1024
  419. void tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0) {
  420.     tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
  421.     tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
  422.     
  423.     if (tdiff->tv_usec < 0) tdiff->tv_sec--, tdiff->tv_usec += 1000000;
  424. }
  425. void ptransfer(char *direction, long bytes, struct timeval *t0, struct timeval *t1) {
  426.     struct timeval td;
  427.     float s, bs;
  428.     
  429.     if (verbose) {
  430. tvsub(&td, t1, t0);
  431. s = td.tv_sec + (td.tv_usec / 1000000.);
  432. #define nz(x) ((x) ? (x) : 1)
  433. bs = bytes / nz(s);
  434. printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)n",
  435.        bytes, direction, s, bs / 1024.);
  436.     }
  437. }
  438. void abort_remote(FILE *din) {
  439.     char buf[BUFSIZ];
  440.     int nfnd;
  441.     fd_set mask;
  442.     /*
  443.      * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
  444.      * after urgent byte rather than before as is protocol now
  445.      */
  446.     sprintf(buf, "%c%c%c", IAC, IP, IAC);
  447.     if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
  448. perror("abort");
  449.     fprintf(cout,"%cABORrn", DM);
  450.     fflush(cout);
  451.     FD_ZERO(&mask);
  452.     FD_SET(fileno(cin), &mask);
  453.     if (din) { 
  454. FD_SET(fileno(din), &mask);
  455.     }
  456.     if ((nfnd = empty(&mask, 10)) <= 0) {
  457. if (nfnd < 0) {
  458.     perror("abort");
  459. }
  460. if (ptabflg)
  461.     code = -1;
  462. lostpeer();
  463.     }
  464.     if (din && FD_ISSET(fileno(din), &mask)) {
  465. while (read(fileno(din), buf, BUFSIZ) > 0)
  466.     /* LOOP */;
  467.     }
  468.     if (getreply(0) == ERROR && code == 552) {
  469. /* 552 needed for nic style abort */
  470. getreply(0);
  471.     }
  472.     getreply(0);
  473. }
  474. void proxtrans(char *cmd, char *local, char *remote) {
  475.     sig_t oldintr;
  476.     int secndflag = 0, prox_type, nfnd;
  477.     extern jmp_buf ptabort;
  478.     char *cmd2;
  479.     fd_set mask;
  480.     void abortpt();
  481.     if (strcmp(cmd, "RETR"))
  482. cmd2 = "RETR";
  483.     else
  484. cmd2 = runique ? "STOU" : "STOR";
  485.     if ((prox_type = type) == 0) {
  486. if (unix_server && unix_proxy)
  487.     prox_type = TYPE_I;
  488. else
  489.     prox_type = TYPE_A;
  490.     }
  491.     if (curtype != prox_type) changetype(prox_type, 1);
  492.     if (command("PASV") != COMPLETE) {
  493. printf("proxy server does not support third party transfers.n");
  494. return;
  495.     }
  496.     pswitch(0);
  497.     if (!connected) {
  498. printf("No primary connectionn");
  499. pswitch(1);
  500. code = -1;
  501. return;
  502.     }
  503.     if (curtype != prox_type) changetype(prox_type, 1);
  504.     if (command("PORT %s", pasv) != COMPLETE) {
  505. pswitch(1);
  506. return;
  507.     }
  508.     if (setjmp(ptabort)) goto abort;
  509.     oldintr = (sig_t)Signal(SIGINT, abortpt);
  510.     if (command("%s %s", cmd, remote) != PRELIM) {
  511. Signal(SIGINT, oldintr);
  512. pswitch(1);
  513. return;
  514.     }
  515.     sleep(2);
  516.     pswitch(1);
  517.     secndflag++;
  518.     if (command("%s %s", cmd2, local) != PRELIM)
  519. goto abort;
  520.     ptflag++;
  521.     getreply(0);
  522.     pswitch(0);
  523.     getreply(0);
  524.     Signal(SIGINT, oldintr);
  525.     pswitch(1);
  526.     ptflag = 0;
  527.     printf("local: %s remote: %sn", local, remote);
  528.     return;
  529. abort:
  530.     Signal(SIGINT, SIG_IGN);
  531.     ptflag = 0;
  532.     if (strcmp(cmd, "RETR") && !proxy) pswitch(1);
  533.     else if (!strcmp(cmd, "RETR") && proxy) pswitch(0);
  534.     if (!cpend && !secndflag) {  /* only here if cmd = "STOR" (proxy=1) */
  535. if (command("%s %s", cmd2, local) != PRELIM) {
  536.     pswitch(0);
  537.     if (cpend) abort_remote((FILE *) NULL);
  538. }
  539. pswitch(1);
  540. if (ptabflg) code = -1;
  541. Signal(SIGINT, oldintr);
  542. return;
  543.     }
  544.     if (cpend)
  545. abort_remote((FILE *) NULL);
  546.     pswitch(!proxy);
  547.     if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */
  548. if (command("%s %s", cmd2, local) != PRELIM) {
  549.     pswitch(0);
  550.     if (cpend) abort_remote((FILE *) NULL);
  551.     pswitch(1);
  552.     if (ptabflg) code = -1;
  553.     Signal(SIGINT, oldintr);
  554.     return;
  555. }
  556.     }
  557.     if (cpend) abort_remote((FILE *) NULL);
  558.     pswitch(!proxy);
  559.     if (cpend) {
  560. FD_ZERO(&mask);
  561. FD_SET(fileno(cin), &mask);
  562. if ((nfnd = empty(&mask, 10)) <= 0) {
  563.     if (nfnd < 0) perror("abort");
  564.     if (ptabflg) code = -1;
  565.     lostpeer();
  566. }
  567. getreply(0);
  568. getreply(0);
  569.     }
  570.     if (proxy) pswitch(0);
  571.     pswitch(1);
  572.     if (ptabflg) code = -1;
  573.     Signal(SIGINT, oldintr);
  574. }
  575. /*
  576.  * Need to start a listen on the data channel before we send the command,
  577.  * otherwise the server's connect may fail.
  578.  */
  579. int initconn() {
  580.     register char *p, *a;
  581.     int result, len, tmpno = 0;
  582.     int on = 1;
  583. noport:
  584.     data_addr = myctladdr;
  585.     if (sendport)
  586. data_addr.sin_port = 0; /* let system pick one */ 
  587.     if (data != -1)
  588. close(data);
  589.     data = socket(AF_INET, SOCK_STREAM, 0);
  590.     if (data < 0) {
  591. perror("ftp: socket");
  592. if (tmpno)
  593.     sendport = 1;
  594. return (1);
  595.     }
  596.     if (!sendport)
  597. if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
  598.     perror("ftp: setsockopt (reuse address)");
  599.     goto bad;
  600. }
  601.     if (bind(data, (struct sockaddr *)&data_addr, sizeof(data_addr)) < 0) {
  602. perror("ftp: bind");
  603. goto bad;
  604.     }
  605.     if (options & SO_DEBUG &&
  606. setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
  607. perror("ftp: setsockopt (ignored)");
  608.     len = sizeof (data_addr);
  609.     if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
  610. perror("ftp: getsockname");
  611. goto bad;
  612.     }
  613.     if (listen(data, 1) < 0)
  614. perror("ftp: listen");
  615.     if (sendport) {
  616. a = (char *)&data_addr.sin_addr;
  617. p = (char *)&data_addr.sin_port;
  618. #define UC(b) (((int)b)&0xff)
  619. result =
  620.     command("PORT %d,%d,%d,%d,%d,%d",
  621.     UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
  622.     UC(p[0]), UC(p[1]));
  623. if (result == ERROR && sendport == -1) {
  624.     sendport = 0;
  625.     tmpno = 1;
  626.     goto noport;
  627. }
  628. return (result != COMPLETE);
  629.     }
  630.     if (tmpno)
  631. sendport = 1;
  632. #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
  633.     on = IPTOS_THROUGHPUT;
  634.     if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
  635. perror("ftp: setsockopt TOS (ignored)");
  636. #endif
  637.     return (0);
  638. bad:
  639.     close(data), data = -1;
  640.     if (tmpno)
  641. sendport = 1;
  642.     return (1);
  643. }
  644. void sendrequest(char *cmd, char *local, char *remote, int printnames) {
  645.     struct stat st;
  646.     struct timeval start, stop;
  647.     register int c, d;
  648.     FILE *fin, *dout = 0, *popen();
  649.     int (*closefunc)(), pclose(), fclose();
  650.     sig_t oldintr, oldintp;
  651.     long bytes = 0, hashbytes = HASHBYTES;
  652.     char *lmode, buf[BUFSIZ], *bufp;
  653.     void abortsend();
  654.     if (verbose && printnames) {
  655. if (local && *local != '-')
  656.     printf("local: %s ", local);
  657. if (remote)
  658.     printf("remote: %sn", remote);
  659.     }
  660.     if (proxy) {
  661. proxtrans(cmd, local, remote);
  662. return;
  663.     }
  664.     if (curtype != type)
  665. changetype(type, 0);
  666.     closefunc = NULL;
  667.     oldintr = NULL;
  668.     oldintp = NULL;
  669.     lmode = "w";
  670.     if (setjmp(sendabort)) {
  671. while (cpend) {
  672.     getreply(0);
  673. }
  674. if (data >= 0) {
  675.     close(data);
  676.     data = -1;
  677. }
  678. if (oldintr)
  679.     Signal(SIGINT,oldintr);
  680. if (oldintp)
  681.     Signal(SIGPIPE,oldintp);
  682. code = -1;
  683. return;
  684.     }
  685.     oldintr = (sig_t)Signal(SIGINT, abortsend);
  686.     if (strcmp(local, "-") == 0)
  687. fin = stdin;
  688.     else if (*local == '|') {
  689. oldintp = (sig_t)Signal(SIGPIPE,SIG_IGN);
  690. fin = popen(local + 1, "r");
  691. if (fin == NULL) {
  692.     perror(local + 1);
  693.     Signal(SIGINT, oldintr);
  694.     Signal(SIGPIPE, oldintp);
  695.     code = -1;
  696.     return;
  697. }
  698. closefunc = pclose;
  699.     } else {
  700. fin = fopen(local, "r");
  701. if (fin == NULL) {
  702.     fprintf(stderr, "local: %s: %sn", local,
  703.     strerror(errno));
  704.     Signal(SIGINT, oldintr);
  705.     code = -1;
  706.     return;
  707. }
  708. closefunc = fclose;
  709. if (fstat(fileno(fin), &st) < 0 ||
  710.     (st.st_mode&S_IFMT) != S_IFREG) {
  711.     fprintf(stdout, "%s: not a plain file.n", local);
  712.     Signal(SIGINT, oldintr);
  713.     fclose(fin);
  714.     code = -1;
  715.     return;
  716. }
  717.     }
  718.     if (initconn()) {
  719. Signal(SIGINT, oldintr);
  720. if (oldintp)
  721.     Signal(SIGPIPE, oldintp);
  722. code = -1;
  723. if (closefunc != NULL)
  724.     (*closefunc)(fin);
  725. return;
  726.     }
  727.     if (setjmp(sendabort))
  728. goto abort;
  729.     if (restart_point &&
  730. (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
  731. if (fseek(fin, (long) restart_point, 0) < 0) {
  732.     fprintf(stderr, "local: %s: %sn", local,
  733.     strerror(errno));
  734.     restart_point = 0;
  735.     if (closefunc != NULL)
  736. (*closefunc)(fin);
  737.     return;
  738. }
  739. if (command("REST %ld", (long) restart_point)
  740.     != CONTINUE) {
  741.     restart_point = 0;
  742.     if (closefunc != NULL)
  743. (*closefunc)(fin);
  744.     return;
  745. }
  746. restart_point = 0;
  747. lmode = "r+w";
  748.     }
  749.     if (remote) {
  750. if (command("%s %s", cmd, remote) != PRELIM) {
  751.     Signal(SIGINT, oldintr);
  752.     if (oldintp)
  753. Signal(SIGPIPE, oldintp);
  754.     if (closefunc != NULL)
  755. (*closefunc)(fin);
  756.     return;
  757. }
  758.     } else
  759. if (command("%s", cmd) != PRELIM) {
  760.     Signal(SIGINT, oldintr);
  761.     if (oldintp)
  762. Signal(SIGPIPE, oldintp);
  763.     if (closefunc != NULL)
  764. (*closefunc)(fin);
  765.     return;
  766. }
  767.     dout = dataconn(lmode);
  768.     if (dout == NULL)
  769. goto abort;
  770.     gettimeofday(&start, (struct timezone *)0);
  771.     oldintp = (sig_t)Signal(SIGPIPE, SIG_IGN);
  772.     switch (curtype) {
  773. case TYPE_I:
  774. case TYPE_L:
  775.     errno = d = 0;
  776.     while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
  777. bytes += c;
  778. for (bufp = buf; c > 0; c -= d, bufp += d)
  779.     if ((d = write(fileno(dout), bufp, c)) <= 0)
  780. break;
  781. if (hash) {
  782.     while (bytes >= hashbytes) {
  783. putchar('#');
  784. hashbytes += HASHBYTES;
  785.     }
  786.     fflush(stdout);
  787. }
  788.     }
  789.     if (hash && bytes > 0) {
  790. if (bytes < HASHBYTES)
  791.     putchar('#');
  792. putchar('n');
  793. fflush(stdout);
  794.     }
  795.     if (c < 0)
  796. fprintf(stderr, "local: %s: %sn", local,
  797. strerror(errno));
  798.     if (d < 0) {
  799. if (errno != EPIPE) 
  800.     perror("netout");
  801. bytes = -1;
  802.     }
  803.     break;
  804. case TYPE_A:
  805.     while ((c = getc(fin)) != EOF) {
  806. if (c == 'n') {
  807.     while (hash && (bytes >= hashbytes)) {
  808. putchar('#');
  809. fflush(stdout);
  810. hashbytes += HASHBYTES;
  811.     }
  812.     if (ferror(dout))
  813. break;
  814.     putc('r', dout);
  815.     bytes++;
  816. }
  817. putc(c, dout);
  818. bytes++;
  819. /* if (c == 'r') {    */
  820. /* (void) putc('', dout);  /* this violates rfc */
  821. /* bytes++; */
  822. /* }                           */
  823.     }
  824.     if (hash) {
  825. if (bytes < hashbytes)
  826.     putchar('#');
  827. putchar('n');
  828. fflush(stdout);
  829.     }
  830.     if (ferror(fin))
  831. fprintf(stderr, "local: %s: %sn", local,
  832. strerror(errno));
  833.     if (ferror(dout)) {
  834. if (errno != EPIPE)
  835.     perror("netout");
  836. bytes = -1;
  837.     }
  838.     break;
  839.     }
  840.     gettimeofday(&stop, (struct timezone *)0);
  841.     if (closefunc != NULL)
  842. (*closefunc)(fin);
  843.     fclose(dout);
  844.     getreply(0);
  845.     Signal(SIGINT, oldintr);
  846.     if (oldintp)
  847. Signal(SIGPIPE, oldintp);
  848.     if (bytes > 0) {
  849. #ifdef FASCIST
  850. syslog(LOG_NOTICE, "Sent local file %s as %s -- %d bytes", local, remote, bytes);
  851. #endif
  852. ptransfer("sent", bytes, &start, &stop);
  853.     }
  854.     return;
  855. abort:
  856.     gettimeofday(&stop, (struct timezone *)0);
  857.     Signal(SIGINT, oldintr);
  858.     if (oldintp)
  859. Signal(SIGPIPE, oldintp);
  860.     if (!cpend) {
  861. code = -1;
  862. return;
  863.     }
  864.     if (data >= 0) {
  865. close(data);
  866. data = -1;
  867.     }
  868.     if (dout)
  869. fclose(dout);
  870.     getreply(0);
  871.     code = -1;
  872.     if (closefunc != NULL && fin != NULL)
  873. (*closefunc)(fin);
  874.     if (bytes > 0) {
  875. #ifdef FASCIST
  876. syslog(LOG_NOTICE, "Sent local file %s as %s -- %d bytes", local, remote, bytes);
  877. #endif
  878. ptransfer("sent", bytes, &start, &stop);
  879.     }
  880. }
  881. jmp_buf recvabort;
  882. void
  883. abortrecv()
  884. {
  885.     mflag = 0;
  886.     abrtflag = 0;
  887.     printf("nreceive abortednwaiting for remote to finish abortn");
  888.     fflush(stdout);
  889.     longjmp(recvabort, 1);
  890. }
  891. void recvrequest(char *cmd, char *local, char *remote, char *lmode, int printnames) {
  892.     FILE *fout, *din = 0, *popen();
  893.     int (*closefunc)(), pclose(), fclose();
  894.     sig_t oldintr, oldintp;
  895.     int is_retr, tcrflag, bare_lfs = 0;
  896.     char *gunique();
  897.     static int bufsize;
  898.     static char *buf;
  899.     long bytes = 0, hashbytes = HASHBYTES;
  900.     register int c, d;
  901.     struct timeval start, stop;
  902.     struct stat st;
  903.     off_t lseek();
  904.     void abortrecv();
  905.     is_retr = strcmp(cmd, "RETR") == 0;
  906.     if (is_retr && verbose && printnames) {
  907. if (local && *local != '-')
  908.     printf("local: %s ", local);
  909. if (remote)
  910.     printf("remote: %sn", remote);
  911.     }
  912.     if (proxy && is_retr) {
  913. proxtrans(cmd, local, remote);
  914. return;
  915.     }
  916.     closefunc = NULL;
  917.     oldintr = NULL;
  918.     oldintp = NULL;
  919.     tcrflag = !crflag && is_retr;
  920.     if (setjmp(recvabort)) {
  921. while (cpend) {
  922.     getreply(0);
  923. }
  924. if (data >= 0) {
  925.     close(data);
  926.     data = -1;
  927. }
  928. if (oldintr)
  929.     Signal(SIGINT, oldintr);
  930. code = -1;
  931. return;
  932.     }
  933.     oldintr = (sig_t)Signal(SIGINT, abortrecv);
  934.     if (strcmp(local, "-") && *local != '|') {
  935. if (access(local, 2) < 0) {
  936.     char *dir = rindex(local, '/');
  937.     if (errno != ENOENT && errno != EACCES) {
  938. fprintf(stderr, "local: %s: %sn", local,
  939. strerror(errno));
  940. Signal(SIGINT, oldintr);
  941. code = -1;
  942. return;
  943.     }
  944.     if (dir != NULL)
  945. *dir = 0;
  946.     d = access(dir ? local : ".", 2);
  947.     if (dir != NULL)
  948. *dir = '/';
  949.     if (d < 0) {
  950. fprintf(stderr, "local: %s: %sn", local,
  951. strerror(errno));
  952. Signal(SIGINT, oldintr);
  953. code = -1;
  954. return;
  955.     }
  956.     if (!runique && errno == EACCES &&
  957. chmod(local, 0600) < 0) {
  958. fprintf(stderr, "local: %s: %sn", local,
  959. strerror(errno));
  960. Signal(SIGINT, oldintr);
  961. Signal(SIGINT, oldintr);
  962. code = -1;
  963. return;
  964.     }
  965.     if (runique && errno == EACCES &&
  966. (local = gunique(local)) == NULL) {
  967. Signal(SIGINT, oldintr);
  968. code = -1;
  969. return;
  970.     }
  971. }
  972. else if (runique && (local = gunique(local)) == NULL) {
  973.     Signal(SIGINT, oldintr);
  974.     code = -1;
  975.     return;
  976. }
  977.     }
  978.     if (!is_retr) {
  979. if (curtype != TYPE_A)
  980.     changetype(TYPE_A, 0);
  981.     } else if (curtype != type)
  982. changetype(type, 0);
  983.     if (initconn()) {
  984. Signal(SIGINT, oldintr);
  985. code = -1;
  986. return;
  987.     }
  988.     if (setjmp(recvabort))
  989. goto abort;
  990.     if (is_retr && restart_point &&
  991. command("REST %ld", (long) restart_point) != CONTINUE)
  992. return;
  993.     if (remote) {
  994. if (command("%s %s", cmd, remote) != PRELIM) {
  995.     Signal(SIGINT, oldintr);
  996.     return;
  997. }
  998.     } else {
  999. if (command("%s", cmd) != PRELIM) {
  1000.     Signal(SIGINT, oldintr);
  1001.     return;
  1002. }
  1003.     }
  1004.     din = dataconn("r");
  1005.     if (din == NULL)
  1006. goto abort;
  1007.     if (strcmp(local, "-") == 0)
  1008. fout = stdout;
  1009.     else if (*local == '|') {
  1010. oldintp = (sig_t)Signal(SIGPIPE, SIG_IGN);
  1011. fout = popen(local + 1, "w");
  1012. if (fout == NULL) {
  1013.     perror(local+1);
  1014.     goto abort;
  1015. }
  1016. closefunc = pclose;
  1017.     } else {
  1018. fout = fopen(local, lmode);
  1019. if (fout == NULL) {
  1020.     fprintf(stderr, "local: %s: %sn", local,
  1021.     strerror(errno));
  1022.     goto abort;
  1023. }
  1024. closefunc = fclose;
  1025.     }
  1026. #ifndef SVR3
  1027.     if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
  1028. #endif
  1029. st.st_blksize = BUFSIZ;
  1030.     if (st.st_blksize > bufsize) {
  1031. if (buf) free(buf);
  1032. buf = malloc((unsigned)st.st_blksize);
  1033. if (buf == NULL) {
  1034.     perror("malloc");
  1035.     bufsize = 0;
  1036.     goto abort;
  1037. }
  1038.     
  1039. bufsize = st.st_blksize;
  1040.     
  1041.     }
  1042.     gettimeofday(&start, (struct timezone *)0);
  1043.     switch (curtype) {
  1044. case TYPE_I:
  1045. case TYPE_L:
  1046. #ifdef SEEK_SET
  1047. #define FTP_SEEK_SET SEEK_SET
  1048. #else
  1049. #define FTP_SEEK_SET L_SET
  1050. #endif
  1051. #ifdef SEEK_CUR
  1052. #define FTP_SEEK_CUR SEEK_CUR
  1053. #else
  1054. #define FTP_SEEK_CUR L_CUR
  1055. #endif
  1056.     if (restart_point && lseek(fileno(fout), (long) restart_point, FTP_SEEK_SET) < 0) {
  1057. fprintf(stderr, "local: %s: %sn", local, strerror(errno));
  1058. if (closefunc != NULL) (*closefunc)(fout);
  1059. return;
  1060.     }
  1061.     errno = d = 0;
  1062.     while ((c = read(fileno(din), buf, bufsize)) > 0) {
  1063. if ((d = write(fileno(fout), buf, c)) != c) break;
  1064. bytes += c;
  1065.   
  1066. if (hash) {
  1067.     while (bytes >= hashbytes) {
  1068. putchar('#');
  1069. hashbytes += HASHBYTES;
  1070.     }
  1071.     fflush(stdout);
  1072. }
  1073.     }
  1074.     if (hash && bytes > 0) {
  1075. if (bytes < HASHBYTES) putchar('#');
  1076. putchar('n');
  1077. fflush(stdout);
  1078.     }
  1079.     if (c < 0) {
  1080. if (errno != EPIPE) perror("netin");
  1081. bytes = -1;
  1082.     }
  1083.     if (d < c) {
  1084. if (d < 0) fprintf(stderr, "local: %s: %sn", local, strerror(errno));
  1085. else fprintf(stderr, "%s: short writen", local);
  1086.     }
  1087.     break;
  1088. case TYPE_A:
  1089.     if (restart_point) {
  1090. register int i, n, ch;
  1091. if (fseek(fout, 0L, FTP_SEEK_SET) < 0) goto done;
  1092. n = restart_point;
  1093. for (i = 0; i++ < n;) {
  1094.     if ((ch = getc(fout)) == EOF) goto done;
  1095.     if (ch == 'n') i++;
  1096. }
  1097.   
  1098. if (fseek(fout, 0L, FTP_SEEK_CUR) < 0) {
  1099. done:
  1100.     fprintf(stderr, "local: %s: %sn", local, strerror(errno));
  1101.     if (closefunc != NULL) (*closefunc)(fout);
  1102.     return;
  1103. }
  1104.     }
  1105.     while ((c = getc(din)) != EOF) {
  1106. if (c == 'n') bare_lfs++;
  1107. while (c == 'r') {
  1108.     while (hash && (bytes >= hashbytes)) {
  1109. putchar('#');
  1110. fflush(stdout);
  1111. hashbytes += HASHBYTES;
  1112.     }
  1113.     bytes++;
  1114.     if ((c = getc(din)) != 'n' || tcrflag) {
  1115. if (ferror(fout)) goto break2;
  1116. putc('r', fout);
  1117. if (c == '') {
  1118.     bytes++;
  1119.     goto contin2;
  1120. }
  1121. if (c == EOF) goto contin2;
  1122.     }
  1123. }
  1124. putc(c, fout);
  1125. bytes++;
  1126.     contin2: ;
  1127.     }
  1128.     break2:
  1129.     if (bare_lfs) {
  1130. printf("WARNING! %d bare linefeeds received in ASCII moden", bare_lfs);
  1131. printf("File may not have transferred correctly.n");
  1132.     }
  1133.     if (hash) {
  1134. if (bytes < hashbytes) putchar('#');
  1135. putchar('n');
  1136. fflush(stdout);
  1137.     }
  1138.     if (ferror(din)) {
  1139. if (errno != EPIPE) perror("netin");
  1140. bytes = -1;
  1141.     }
  1142.     if (ferror(fout)) fprintf(stderr, "local: %s: %sn", local, strerror(errno));
  1143.     break;
  1144.     }
  1145.     if (closefunc != NULL) (*closefunc)(fout);
  1146.     Signal(SIGINT, oldintr);
  1147.     if (oldintp) Signal(SIGPIPE, oldintp);
  1148.     gettimeofday(&stop, (struct timezone *)0);
  1149.     fclose(din);
  1150.     getreply(0);
  1151.     if (bytes > 0 && is_retr) {
  1152. #ifdef FASCIST
  1153. syslog(LOG_NOTICE, "Received remote file %s as %s -- %d bytes", remote, local, bytes);
  1154. #endif
  1155. ptransfer("received", bytes, &start, &stop);
  1156.     }
  1157.     return;
  1158. abort:
  1159.     /* abort using RFC959 recommended IP,SYNC sequence  */
  1160.   
  1161.     gettimeofday(&stop, (struct timezone *)0);
  1162.     if (oldintp) Signal(SIGPIPE, oldintr);
  1163.     Signal(SIGINT, SIG_IGN);
  1164.     if (!cpend) {
  1165. code = -1;
  1166. Signal(SIGINT, oldintr);
  1167. return;
  1168.     }
  1169.   
  1170.     abort_remote(din);
  1171.     code = -1;
  1172.     if (data >= 0) {
  1173. close(data);
  1174. data = -1;
  1175.     }
  1176.     if (closefunc != NULL && fout != NULL) (*closefunc)(fout);
  1177.     if (din) fclose(din);
  1178.     if (bytes > 0) {
  1179. #ifdef FASCIST
  1180. syslog(LOG_NOTICE, "Received remote file %s as %s -- %d bytes", remote, local, bytes);
  1181. #endif
  1182. ptransfer("received", bytes, &start, &stop);
  1183.     }
  1184.     Signal(SIGINT, oldintr);
  1185. }
  1186. FILE *
  1187. dataconn(lmode)
  1188.     char *lmode;
  1189. {
  1190.     struct sockaddr_in from;
  1191.     int s, fromlen = sizeof (from), tos;
  1192.     if ((s = accept(data, (struct sockaddr *) &from, &fromlen)) < 0) {
  1193. perror("ftp: accept");
  1194. close(data), data = -1;
  1195. return (NULL);
  1196.     }
  1197.     close(data);
  1198.     data = s;
  1199. #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
  1200.     tos = IPTOS_THROUGHPUT;
  1201.     if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
  1202. perror("ftp: setsockopt TOS (ignored)");
  1203. #endif
  1204.     return (fdopen(data, lmode));
  1205. }
  1206. void psabort() {
  1207.     extern int abrtflag;
  1208.     abrtflag++;
  1209. }
  1210. void pswitch(int flag) {
  1211.     extern int proxy, abrtflag;
  1212.     sig_t oldintr;
  1213.     static struct comvars {
  1214. int connect;
  1215. char name[MAXHOSTNAMELEN];
  1216. struct sockaddr_in mctl;
  1217. struct sockaddr_in hctl;
  1218. FILE *in;
  1219. FILE *out;
  1220. int tpe;
  1221. int curtpe;
  1222. int cpnd;
  1223. int sunqe;
  1224. int runqe;
  1225. int mcse;
  1226. int ntflg;
  1227. char nti[17];
  1228. char nto[17];
  1229. int mapflg;
  1230. char mi[MAXPATHLEN];
  1231. char mo[MAXPATHLEN];
  1232.     } proxstruct, tmpstruct;
  1233.     struct comvars *ip, *op;
  1234.     abrtflag = 0;
  1235.     oldintr = (sig_t)Signal(SIGINT, psabort);
  1236.     if (flag) {
  1237. if (proxy) return;
  1238. ip = &tmpstruct;
  1239. op = &proxstruct;
  1240. proxy++;
  1241.     } else {
  1242. if (!proxy) return;
  1243. ip = &proxstruct;
  1244. op = &tmpstruct;
  1245. proxy = 0;
  1246.     }
  1247.     ip->connect = connected;
  1248.     connected = op->connect;
  1249.     if (hostname) {
  1250. strncpy(ip->name, hostname, sizeof(ip->name) - 1);
  1251. ip->name[strlen(ip->name)] = '';
  1252.     } else {
  1253. ip->name[0] = '';
  1254.     }
  1255.     hostname = op->name;
  1256.     ip->hctl = hisctladdr;
  1257.     hisctladdr = op->hctl;
  1258.     ip->mctl = myctladdr;
  1259.     myctladdr = op->mctl;
  1260.     ip->in = cin;
  1261.     cin = op->in;
  1262.     ip->out = cout;
  1263.     cout = op->out;
  1264.     ip->tpe = type;
  1265.     type = op->tpe;
  1266.     ip->curtpe = curtype;
  1267.     curtype = op->curtpe;
  1268.     ip->cpnd = cpend;
  1269.     cpend = op->cpnd;
  1270.     ip->sunqe = sunique;
  1271.     sunique = op->sunqe;
  1272.     ip->runqe = runique;
  1273.     runique = op->runqe;
  1274.     ip->mcse = mcase;
  1275.     mcase = op->mcse;
  1276.     ip->ntflg = ntflag;
  1277.     ntflag = op->ntflg;
  1278.     strncpy(ip->nti, ntin, 16);
  1279.     (ip->nti)[strlen(ip->nti)] = '';
  1280.     strcpy(ntin, op->nti);
  1281.     strncpy(ip->nto, ntout, 16);
  1282.     (ip->nto)[strlen(ip->nto)] = '';
  1283.     strcpy(ntout, op->nto);
  1284.     ip->mapflg = mapflag;
  1285.     mapflag = op->mapflg;
  1286.     strncpy(ip->mi, mapin, MAXPATHLEN - 1);
  1287.     (ip->mi)[strlen(ip->mi)] = '';
  1288.     strcpy(mapin, op->mi);
  1289.     strncpy(ip->mo, mapout, MAXPATHLEN - 1);
  1290.     (ip->mo)[strlen(ip->mo)] = '';
  1291.     strcpy(mapout, op->mo);
  1292.     Signal(SIGINT, oldintr);
  1293.     if (abrtflag) {
  1294. abrtflag = 0;
  1295. (*oldintr)(SIGINT);
  1296.     }
  1297. }
  1298. void abortpt() {
  1299.     printf("n");
  1300.     fflush(stdout);
  1301.     ptabflg++;
  1302.     mflag    = 0;
  1303.     abrtflag = 0;
  1304.     longjmp(ptabort, 1);
  1305. }
  1306. void reset() {
  1307.     fd_set mask;
  1308.     int nfnd = 1;
  1309.     
  1310.     FD_ZERO(&mask);
  1311.     while (nfnd > 0) {
  1312. FD_SET(fileno(cin), &mask);
  1313. if ((nfnd = empty(&mask,0)) < 0) {
  1314.     perror("reset");
  1315.     code = -1;
  1316.     lostpeer();
  1317. } else if (nfnd) {
  1318.     getreply(0);
  1319. }
  1320.     }
  1321. }
  1322. char *gunique(char *local) {
  1323.     static char new[MAXPATHLEN];
  1324.     char *cp = rindex(local, '/');
  1325.     int d, count=0;
  1326.     char ext = '1';
  1327.     if (cp) *cp = '';
  1328.     d = access(cp ? local : ".", 2);
  1329.     if (cp) *cp = '/';
  1330.     if (d < 0) {
  1331. fprintf(stderr, "local: %s: %sn", local, strerror(errno));
  1332. return((char *) 0);
  1333.     }
  1334.     
  1335.     strcpy(new, local);
  1336.     cp = new + strlen(new);
  1337.     *cp++ = '.';
  1338.     while (!d) {
  1339. if (++count == 100) {
  1340.     printf("runique: can't find unique file name.n");
  1341.     return((char *) 0);
  1342. }
  1343. *cp++ = ext;
  1344. *cp = '';
  1345. if (ext == '9') ext = '0';
  1346. else            ext++;
  1347. if ((d = access(new, 0)) < 0) break;
  1348. if (ext != '0') cp--;
  1349. else if (*(cp - 2) == '.') *(cp - 1) = '1';
  1350. else {
  1351.     *(cp - 2) = *(cp - 2) + 1;
  1352.     cp--;
  1353. }
  1354.     }
  1355.     return(new);
  1356. }