home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume18 / ftptool-4.3 / part09 < prev    next >
Text File  |  1992-08-18  |  51KB  |  2,316 lines

  1. Path: uunet!usc!elroy.jpl.nasa.gov!swrinde!mips!msi!dcmartin
  2. From: Mike.Sullivan@EBay.Sun.COM (Mike Sullivan {AKA Simon BarSinister})
  3. Newsgroups: comp.sources.x
  4. Subject: v18i091: Ftptool 4.3 (XVIEW), Part09/12
  5. Message-ID: <1992Aug18.153737.29024@msi.com>
  6. Date: 18 Aug 92 15:37:37 GMT
  7. References: <csx-18i083-ftptool-4.3@uunet.UU.NET>
  8. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  9. Organization: Molecular Simulations, Inc.
  10. Lines: 2302
  11. Approved: dcmartin@msi.com
  12. Originator: dcmartin@fascet
  13.  
  14. Submitted-by: Mike.Sullivan@EBay.Sun.COM (Mike Sullivan {AKA Simon BarSinister})
  15. Posting-number: Volume 18, Issue 91
  16. Archive-name: ftptool-4.3/part09
  17.  
  18. #!/bin/sh
  19. # this is part.09 (part 9 of a multipart archive)
  20. # do not concatenate these parts, unpack them in order with /bin/sh
  21. # file ftp.c continued
  22. #
  23. if test ! -r _shar_seq_.tmp; then
  24.     echo 'Please unpack part 1 first!'
  25.     exit 1
  26. fi
  27. (read Scheck
  28.  if test "$Scheck" != 9; then
  29.     echo Please unpack part "$Scheck" next!
  30.     exit 1
  31.  else
  32.     exit 0
  33.  fi
  34. ) < _shar_seq_.tmp || exit 1
  35. if test ! -f _shar_wnt_.tmp; then
  36.     echo 'x - still skipping ftp.c'
  37. else
  38. echo 'x - continuing file ftp.c'
  39. sed 's/^X//' << 'SHAR_EOF' >> 'ftp.c' &&
  40. X            dig++;
  41. X            if (c == EOF) {
  42. X                if (expecteof) {
  43. X                    code = 221;
  44. X                    notify_no_dispatch();
  45. X                    return (0);
  46. X                }
  47. X                lostpeer();
  48. X                if (verbose) {
  49. X                    sprintf(scratch, "421 Service not available, remote server has closed connection\n");
  50. X                    log_message(scratch);
  51. X                }
  52. X                code = 421;
  53. X                notify_no_dispatch();
  54. X                return(4);
  55. X            }
  56. X            if (c != '\r' && (verbose > 0 ||
  57. X                (verbose > -1 && n == '5' && dig > 4))) {
  58. X                /*
  59. X                (void) putchar(c);
  60. X                 */
  61. X                log_char(c);
  62. X            }
  63. X            if (dig < 4 && isdigit(c))
  64. X                code = code * 10 + (c - '0');
  65. X            if (!pflag && code == 227)
  66. X                pflag = 1;
  67. X            if (dig > 4 && pflag == 1 && isdigit(c))
  68. X                pflag = 2;
  69. /*
  70. X            if (pflag == 2) {
  71. X                if (c != '\r' && c != ')')
  72. X                    *pt++ = c;
  73. X                else {
  74. X                    *pt = '\0';
  75. X                    pflag = 3;
  76. X                }
  77. X            }
  78. */
  79. X            if (dig == 4 && c == '-') {
  80. X                if (continuation)
  81. X                    code = 0;
  82. X                continuation++;
  83. X            }
  84. X            if (n == 0)
  85. X                n = c;
  86. X            if (cp < &response_line[sizeof(response_line) - 1])
  87. X                *cp++ = c;
  88. X        }
  89. X        if (verbose > 0 || verbose > -1 && n == '5') {
  90. X            /*
  91. X            (void) putchar(c);
  92. X             */
  93. X            log_char(c);
  94. X            (void) fflush (stdout);
  95. X        }
  96. X        if (continuation && code != originalcode) {
  97. X            if (originalcode == 0)
  98. X                originalcode = code;
  99. X            continue;
  100. X        }
  101. X        *cp = '\0';
  102. X        if (n != '1')
  103. X            cpend = 0;
  104. X        if (code == 421 || originalcode == 421)
  105. X            lostpeer();
  106. X        notify_no_dispatch();
  107. X        return (n - '0');
  108. X    }
  109. }
  110. X
  111. #ifdef USE_PROTOTYPES
  112. int empty(fd_set *mask, int sec)
  113. #else
  114. int empty(mask, sec)
  115. fd_set *mask;
  116. int sec;
  117. #endif
  118. {
  119. X    struct timeval t;
  120. X
  121. X    t.tv_sec = (long) sec;
  122. X    t.tv_usec = 0;
  123. X    return select(32, mask, (fd_set *)NULL, (fd_set *)NULL, &t);
  124. }
  125. X
  126. jmp_buf    sendabort;
  127. X
  128. #define HASHBYTES 1024
  129. X
  130. #ifdef USE_PROTOTYPES
  131. int sendrequest(char *cmd, char *local, char *remote, size_t size)
  132. #else
  133. int sendrequest(cmd, local, remote, size)
  134. char    *cmd, *local, *remote;
  135. size_t    size;
  136. #endif
  137. {
  138. X    struct stat st;
  139. X    struct timeval start, stop;
  140. X    register int c, d;
  141. X    FILE *fin = NULL, *dout = 0, *popen();
  142. X    int (*closefunc)(), pclose(), fclose();
  143. X    long bytes = 0;
  144. X    char *lmode, buf[BUFSIZ], *bufp;
  145. X    char    *ftperr;
  146. X    int        errormsg=0;
  147. X
  148. X    closefunc = NULL;
  149. X    lmode = "w";
  150. X    update_status_label("Sending", remote, size);
  151. X    if (setjmp(sendabort)) {
  152. X        while (cpend) {
  153. X            (void) getreply(0);
  154. X        }
  155. X        if (data >= 0) {
  156. X            (void) close(data);
  157. X            data = -1;
  158. X        }
  159. X        code = -1;
  160. X        return 0;
  161. X    }
  162. X    fin = fopen(local, "r");
  163. X    if (fin == NULL) {
  164. X        local_footer_message("Open: %s: %s.", local, strerror(errno),
  165. X            (char *)NULL);
  166. X        /*
  167. X        fprintf(stderr, "local: %s: %s\n", local,
  168. X            strerror(errno));
  169. X         */
  170. X        code = -1;
  171. X        return 0;
  172. X    }
  173. X    closefunc = fclose;
  174. X    if (fstat(fileno(fin), &st) < 0 ||
  175. X        (st.st_mode&S_IFMT) != S_IFREG) {
  176. X        local_footer_message("%s: not a plain file.", local, (char *)NULL);
  177. X        fclose(fin);
  178. X        fin = NULL;
  179. X        code = -1;
  180. X        return 1;
  181. X    }
  182. X    if (initconn()) {
  183. X        code = -1;
  184. X        if (closefunc != NULL)
  185. X            (*closefunc)(fin);
  186. X        return 0;
  187. X    }
  188. X    if (setjmp(sendabort))
  189. X        goto abort;
  190. X
  191. X    if (restart_point &&
  192. X        (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
  193. X        if (fseek(fin, (long) restart_point, 0) < 0) {
  194. X            local_footer_message("Seek: %s: %s.", local, strerror(errno),
  195. X                (char *)NULL);
  196. X            /*
  197. X            fprintf(stderr, "local: %s: %s\n", local,
  198. X                strerror(errno));
  199. X             */
  200. X            restart_point = 0;
  201. X            if (closefunc != NULL)
  202. X                (*closefunc)(fin);
  203. X            return 0;
  204. X        }
  205. X        if (command("REST %ld", (long) restart_point)
  206. X            != CONTINUE) {
  207. X            restart_point = 0;
  208. X            if (closefunc != NULL)
  209. X                (*closefunc)(fin);
  210. X            return 0;
  211. X        }
  212. X        restart_point = 0;
  213. X        lmode = "r+w";
  214. X    }
  215. X    if (remote) {
  216. X        if (command_dataconn(&dout, lmode, "%s %s", cmd, remote) != PRELIM) {
  217. #ifdef notdef
  218. X        if (command("%s %s", cmd, remote) != PRELIM) {
  219. #endif
  220. X            if (closefunc != NULL)
  221. X                (*closefunc)(fin);
  222. X            /*
  223. X            fprintf(stderr, "remote-command != PRELIM\n");
  224. X             */
  225. X            /* Permission denied */
  226. X
  227. X            sprintf(scratch, "Put %s failed.", remote);
  228. X            ftperr = ftp_error(' ', scratch);
  229. X            local_footer_message(ftperr, (char *)NULL);
  230. X
  231. X            return 1;
  232. X        }
  233. X    } else
  234. X        if (command_dataconn(&dout, lmode, "%s", cmd) != PRELIM) {
  235. #ifdef notdef
  236. X        if (command("%s", cmd) != PRELIM) {
  237. #endif
  238. X            if (closefunc != NULL)
  239. X                (*closefunc)(fin);
  240. X            fprintf(stderr, "command != PRELIM\n");
  241. X            return 1;
  242. X        }
  243. #ifdef notdef
  244. X    dout = dataconn(lmode);
  245. #endif
  246. X    if (dout == NULL)
  247. X        goto abort;
  248. X    (void) gettimeofday(&start, (struct timezone *)0);
  249. X    switch (curtype) {
  250. X
  251. X    case TYPE_I:
  252. X    case TYPE_L:
  253. X        errno = d = 0;
  254. X        notify_do_dispatch();
  255. X        while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
  256. X            if (abort_transfer) {
  257. X                notify_no_dispatch();
  258. X                goto abort;
  259. X            }
  260. X            bytes += c;
  261. X            for (bufp = buf; c > 0; c -= d, bufp += d)
  262. X                if ((d = write(fileno(dout), bufp, c)) <= 0) {
  263. X                    break;
  264. X                } else {
  265. X                    /* change image */
  266. X                    update_status_gauge(d);
  267. X                }
  268. X            if (abort_transfer) {
  269. X                notify_no_dispatch();
  270. X                goto abort;
  271. X            }
  272. X        }
  273. X        notify_no_dispatch();
  274. X        if (c < 0) {
  275. X            footer_message("Read %s: %s.", local, strerror(errno), (char *)NULL);
  276. X            /*
  277. X            fprintf(stderr, "local: %s: %s\n", local,
  278. X                strerror(errno));
  279. X             */
  280. X            errormsg = 1;
  281. X        }
  282. X        if (d < 0) {
  283. X            local_footer_message("Write failed (remote file system full?).", 
  284. X                (char *)NULL);
  285. X            errormsg = 1;
  286. X            goto abort;
  287. X        }
  288. X        break;
  289. X
  290. X    case TYPE_A:
  291. X        notify_do_dispatch();
  292. X        while ((c = getc(fin)) != EOF) {
  293. X            if (abort_transfer) {
  294. X                notify_no_dispatch();
  295. X                goto abort;
  296. X            }
  297. X            if (c == '\n') {
  298. X                if (ferror(dout))
  299. X                    break;
  300. X                (void) putc('\r', dout);
  301. X                /* change image */
  302. X                update_status_gauge(1);
  303. X                bytes++;
  304. X            }
  305. X            (void) putc(c, dout);
  306. X            /* change image */
  307. X            update_status_gauge(1);
  308. X            if (abort_transfer) {
  309. X                notify_no_dispatch();
  310. X                goto abort;
  311. X            }
  312. X            bytes++;
  313. X    /*        if (c == '\r') {                  */
  314. X    /*        (void)    putc('\0', dout);*/ /*this violates rfc */
  315. X    /*            bytes++;                */
  316. X    /*        }                                      */    
  317. X        }
  318. X        notify_no_dispatch();
  319. X        if (ferror(fin)) {
  320. X            errormsg = 1;
  321. X            local_footer_message("%s: %s.", local, strerror(errno), 
  322. X                (char *)NULL);
  323. X            /*
  324. X            fprintf(stderr, "local: %s: %s\n", local,
  325. X                strerror(errno));
  326. X             */
  327. X        }
  328. X        if (ferror(dout)) {
  329. X            if (errno != EPIPE)
  330. X                perror("netout");
  331. X            bytes = -1;
  332. X        }
  333. X        break;
  334. X    }
  335. X    (void) gettimeofday(&stop, (struct timezone *)0);
  336. X    if (closefunc != NULL)
  337. X        (*closefunc)(fin);
  338. X    (void) fclose(dout);
  339. X    dout = NULL;
  340. X    (void) getreply(0);
  341. X    if (!errormsg)
  342. X        local_footer_message("Send of %s complete.", remote, (char *)NULL);
  343. X    return 0;
  344. abort:
  345. X    (void) gettimeofday(&stop, (struct timezone *)0);
  346. X    if (!cpend) {
  347. X        code = -1;
  348. X        return 0;
  349. X    }
  350. X    if (data >= 0) {
  351. X        (void) close(data);
  352. X        data = -1;
  353. X    }
  354. X    if (dout) {
  355. X        (void) fclose(dout);
  356. X        dout = NULL;
  357. X    }
  358. X    (void) getreply(0);
  359. X    code = -1;
  360. X    if (closefunc != NULL && fin != NULL)
  361. X        (*closefunc)(fin);
  362. X    if (!errormsg)
  363. X        local_footer_message("Send of %s aborted.", remote, (char *)NULL);
  364. X    return 2;
  365. }
  366. X
  367. jmp_buf    recvabort;
  368. X
  369. #ifdef USE_PROTOTYPES
  370. int recvrequest(char *cmd, char *local, char *remote, 
  371. X    char *lmode, size_t size)
  372. #else
  373. int recvrequest(cmd, local, remote, lmode, size)
  374. char    *cmd, *local, *remote, *lmode;
  375. size_t    size;
  376. #endif
  377. {
  378. X    FILE *fout = NULL, *din = 0, *popen();
  379. X    int (*closefunc)(), pclose(), fclose();
  380. X    int is_retr, tcrflag, bare_lfs = 0;
  381. X    char *gunique();
  382. X    static int bufsize;
  383. X    static char *buf;
  384. X    long bytes = 0;
  385. X    register int c, d;
  386. X    struct timeval start, stop;
  387. X    struct stat st;
  388. X    off_t lseek();
  389. X    char    *ftperr;
  390. X    int        errormsg=0;
  391. X
  392. X    update_status_label("Receiving", remote, size);
  393. X    is_retr = strcmp(cmd, "RETR") == 0;
  394. X    closefunc = NULL;
  395. X    tcrflag = !crflag && is_retr;
  396. X    if (setjmp(recvabort)) {
  397. X        while (cpend) {
  398. X            (void) getreply(0);
  399. X        }
  400. X        if (data >= 0) {
  401. X            (void) close(data);
  402. X            data = -1;
  403. X        }
  404. X        code = -1;
  405. X        return 0;
  406. X    }
  407. X    if (strcmp(local, "-") && *local != '|') {
  408. X        if (access(local, 2) < 0) {
  409. X            char *dir = rindex(local, '/');
  410. X
  411. X            if (errno != ENOENT && errno != EACCES) {
  412. X                footer_message("Access: %s: %s.", local, strerror(errno),
  413. X                    (char *)NULL);
  414. X                /*
  415. X                fprintf(stderr, "local: %s: %s\n", local,
  416. X                    strerror(errno));
  417. X                 */
  418. X                code = -1;
  419. X                return 0;
  420. X            }
  421. X            if (dir != NULL)
  422. X                *dir = 0;
  423. X            d = access(dir ? local : ".", 2);
  424. X            if (dir != NULL)
  425. X                *dir = '/';
  426. X            if (d < 0) {
  427. X                footer_message("Access: %s: %s.", local, strerror(errno),
  428. X                    (char *)NULL);
  429. X                /*
  430. X                fprintf(stderr, "local: %s: %s\n", local,
  431. X                    strerror(errno));
  432. X                 */
  433. X                code = -1;
  434. X                return 0;
  435. X            }
  436. X            if (!unique_local_names && errno == EACCES &&
  437. X                chmod(local, 0600) < 0) {
  438. X                footer_message("Chmod: %s: %s.", local, strerror(errno),
  439. X                    (char *)NULL);
  440. X                /*
  441. X                fprintf(stderr, "local: %s: %s\n", local,
  442. X                    strerror(errno));
  443. X                 */
  444. X                code = -1;
  445. X                return 1;
  446. X            }
  447. X            if (unique_local_names && errno == EACCES &&
  448. X               (local = gunique(local)) == NULL) {
  449. X                code = -1;
  450. X                return 1;
  451. X            }
  452. X        }
  453. X        else if (unique_local_names && (local = gunique(local)) == NULL) {
  454. X            code = -1;
  455. X            return 1;
  456. X        }
  457. X    }
  458. X    if (initconn()) {
  459. X        code = -1;
  460. X        return 0;
  461. X    }
  462. X    if (setjmp(recvabort))
  463. X        goto abort;
  464. X    if (is_retr && restart_point &&
  465. X        command("REST %ld", (long) restart_point) != CONTINUE)
  466. X        return 0;
  467. X    if (remote) {
  468. X        if (command_dataconn(&din, "r", "%s %s", cmd, remote) != PRELIM) {
  469. #ifdef notdef
  470. X        if (command("%s %s", cmd, remote) != PRELIM) {
  471. #endif
  472. X            /*Not a plain file/Permission denied/No such file or directory*/
  473. X
  474. X            sprintf(scratch, "Get %s failed.", remote);
  475. X            ftperr = ftp_error(' ', scratch);
  476. X            footer_message(ftperr, (char *)NULL);
  477. X            return 1;
  478. X        }
  479. X    } else {
  480. X        if (command_dataconn(&din, "r", "%s", cmd) != PRELIM) {
  481. #ifdef notdef
  482. X        if (command("%s", cmd) != PRELIM) {
  483. #endif
  484. X            footer_message("command != PRELIM", (char *)NULL);
  485. X            /*
  486. X            fprintf(stderr, "command != PRELIM\n");
  487. X             */
  488. X            return 1;
  489. X        }
  490. X    }
  491. #ifdef notdef
  492. X    din = dataconn("r");
  493. #endif
  494. X    if (din == NULL)
  495. X        goto abort;
  496. X    if (strcmp(local, "-") == 0)
  497. X        fout = stdout;
  498. X    else if (*local == '|') {
  499. X        fout = popen(local + 1, "w");
  500. X        if (fout == NULL) {
  501. X            perror(local+1);
  502. X            goto abort;
  503. X        }
  504. X        closefunc = pclose;
  505. X    } else {
  506. X        fout = fopen(local, lmode);
  507. X        if (fout == NULL) {
  508. X            footer_message("Open: %s: %s.", local, strerror(errno),
  509. X                (char *)NULL);
  510. X            /*
  511. X            fprintf(stderr, "local: %s: %s\n", local,
  512. X                strerror(errno));
  513. X             */
  514. X            errormsg = 1;
  515. X            goto abort;
  516. X        }
  517. X        closefunc = fclose;
  518. X    }
  519. X    if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
  520. X        st.st_blksize = BUFSIZ;
  521. X    if (st.st_blksize > bufsize) {
  522. X        if (buf)
  523. X            (void) free(buf);
  524. X        buf = malloc((unsigned)st.st_blksize);
  525. X        if (buf == NULL) {
  526. X            perror("malloc");
  527. X            bufsize = 0;
  528. X            goto abort;
  529. X        }
  530. X        bufsize = st.st_blksize;
  531. X    }
  532. X    (void) gettimeofday(&start, (struct timezone *)0);
  533. X    switch (curtype) {
  534. X
  535. X    case TYPE_I:
  536. X    case TYPE_L:
  537. X        if (restart_point &&
  538. X            lseek(fileno(fout), (long) restart_point, SEEK_SET) < 0) {
  539. X            footer_message("Seek: %s: %s.", local, strerror(errno),
  540. X                (char *)NULL);
  541. X            /*
  542. X            fprintf(stderr, "local: %s: %s\n", local,
  543. X                strerror(errno));
  544. X             */
  545. X            if (closefunc != NULL)
  546. X                (*closefunc)(fout);
  547. X            return 0;
  548. X        }
  549. X        errno = d = 0;
  550. X        notify_do_dispatch();
  551. X        while ((c = read(fileno(din), buf, bufsize)) > 0) {
  552. X            if (abort_transfer) {
  553. X                notify_no_dispatch();
  554. X                goto abort;
  555. X            }
  556. X            if ((d = write(fileno(fout), buf, c)) <= 0)
  557. X                break;
  558. X            /* change image */
  559. X            update_status_gauge(d);
  560. X            if (d != c)
  561. X                break;
  562. X            /*
  563. X            if ((d = write(fileno(fout), buf, c)) != c)
  564. X                break;
  565. X             */
  566. X            if (abort_transfer) {
  567. X                notify_no_dispatch();
  568. X                goto abort;
  569. X            }
  570. X            bytes += c;
  571. X        }
  572. X        notify_no_dispatch();
  573. X        if (c < 0) {
  574. X            if (errno != EPIPE)
  575. X                perror("netin");
  576. X            bytes = -1;
  577. X        }
  578. X        if (d < c) {
  579. X            errormsg = 1;
  580. X            if (d < 0) {
  581. X                /*
  582. X                fprintf(stderr, "local: %s: %s\n", local,
  583. X                    strerror(errno));
  584. X                 */
  585. X                footer_message("Write failed: %s",strerror(errno),(char *)NULL);
  586. X                goto abort;
  587. X            } else {
  588. X              /*
  589. X                fprintf(stderr, "%s: short write\n", local);
  590. X               */
  591. X                footer_message("Short write: %s",strerror(errno),(char *)NULL);
  592. X            }
  593. X        }
  594. X        break;
  595. X
  596. X    case TYPE_A:
  597. X        if (restart_point) {
  598. X            register int i, n, ch;
  599. X
  600. X            if (fseek(fout, 0L, SEEK_SET) < 0)
  601. X                goto done;
  602. X            n = restart_point;
  603. X            for (i = 0; i++ < n;) {
  604. X                if ((ch = getc(fout)) == EOF)
  605. X                    goto done;
  606. X                if (ch == '\n')
  607. X                    i++;
  608. X            }
  609. X            if (fseek(fout, 0L, SEEK_CUR) < 0) {
  610. done:
  611. X                footer_message("Seek: %s: %s.", local, strerror(errno),
  612. X                    (char *)NULL);
  613. X                /*
  614. X                fprintf(stderr, "local: %s: %s\n", local,
  615. X                    strerror(errno));
  616. X                 */
  617. X                if (closefunc != NULL)
  618. X                    (*closefunc)(fout);
  619. X                return 0;
  620. X            }
  621. X        }
  622. X        notify_do_dispatch();
  623. X        while ((c = getc(din)) != EOF) {
  624. X            if (abort_transfer) {
  625. X                notify_no_dispatch();
  626. X                goto abort;
  627. X            }
  628. X            if (c == '\n')
  629. X                bare_lfs++;
  630. X            while (c == '\r') {
  631. X                bytes++;
  632. X                if ((c = getc(din)) != '\n' || tcrflag) {
  633. X                    if (ferror(fout))
  634. X                        goto break2;
  635. X                    (void) putc('\r', fout);
  636. X                    /* change image */
  637. X                    update_status_gauge(1);
  638. X                    if (c == '\0') {
  639. X                        bytes++;
  640. X                        goto contin2;
  641. X                    }
  642. X                    if (c == EOF)
  643. X                        goto contin2;
  644. X                }
  645. X            }
  646. X            (void) putc(c, fout);
  647. X            /* change image */
  648. X            update_status_gauge(1);
  649. X            if (abort_transfer) {
  650. X                notify_no_dispatch();
  651. X                goto abort;
  652. X            }
  653. X            bytes++;
  654. X    contin2:    ;
  655. X        }
  656. break2:
  657. X        notify_no_dispatch();
  658. X        if (bare_lfs) {
  659. X            fprintf(stderr,"WARNING! %d bare linefeeds received in ASCII mode\n",
  660. X                bare_lfs);
  661. X            fprintf(stderr,"File may not have transferred correctly.\n");
  662. X        }
  663. X        if (ferror(din)) {
  664. X            if (errno != EPIPE)
  665. X                perror("netin");
  666. X            bytes = -1;
  667. X        }
  668. X        if (ferror(fout)) {
  669. X            errormsg = 1;
  670. X            footer_message("%s: %s.", local, strerror(errno),
  671. X                (char *)NULL);
  672. X            /*
  673. X            fprintf(stderr, "local: %s: %s\n", local,
  674. X                strerror(errno));
  675. X             */
  676. X        }
  677. X        break;
  678. X    }
  679. X    if (closefunc != NULL)
  680. X        (*closefunc)(fout);
  681. X    (void) gettimeofday(&stop, (struct timezone *)0);
  682. X    (void) fclose(din);
  683. X    din = NULL;
  684. X    (void) getreply(0);
  685. X    if (!errormsg)
  686. X        footer_message("Receive of %s complete.", remote, (char *)NULL);
  687. X    return 0;
  688. abort:
  689. X
  690. /* abort using RFC959 recommended IP,SYNC sequence  */
  691. X
  692. X    (void) gettimeofday(&stop, (struct timezone *)0);
  693. X    if (!cpend) {
  694. X        code = -1;
  695. X        return 0;
  696. X    }
  697. X
  698. X    abort_remote(din);
  699. X    code = -1;
  700. X    if (data >= 0) {
  701. X        (void) close(data);
  702. X        data = -1;
  703. X    }
  704. X    if (closefunc != NULL && fout != NULL)
  705. X        (*closefunc)(fout);
  706. X    if (din) {
  707. X        (void) fclose(din);
  708. X        din = NULL;
  709. X    }
  710. X    if (!errormsg)
  711. X        footer_message("Receive of %s aborted.", remote, (char *)NULL);
  712. X    return 2;
  713. }
  714. X
  715. /*
  716. X * Need to start a listen on the data channel before we send the command,
  717. X * otherwise the server's connect may fail.
  718. X */
  719. #ifdef USE_PROTOTYPES
  720. int initconn(void)
  721. #else
  722. int initconn()
  723. #endif
  724. {
  725. X    register char *p, *a;
  726. X    int result, len, tmpno = 0;
  727. X    int on = 1;
  728. #ifdef SYSV386
  729. X    ushort    data_port;
  730. #endif
  731. X
  732. noport:
  733. X    data_addr = myctladdr;
  734. X    if (sendport)
  735. X        data_addr.sin_port = 0;    /* let system pick one */ 
  736. X    if (data != -1) {
  737. X        (void) close(data);
  738. X        data = -1;
  739. X    }
  740. X    data = socket(AF_INET, SOCK_STREAM, 0);
  741. X    if (data < 0) {
  742. X        perror("ftptool: socket");
  743. X        if (tmpno)
  744. X            sendport = 1;
  745. X        return (1);
  746. X    }
  747. X    if (!sendport)
  748. X        if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
  749. X            perror("ftptool: setsockopt (reuse address)");
  750. X            goto bad;
  751. X        }
  752. X    if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
  753. X        perror("ftptool: bind");
  754. X        goto bad;
  755. X    }
  756. /*
  757. X    if (options & SO_DEBUG &&
  758. X        setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
  759. X        perror("ftptool: setsockopt (ignored)");
  760. */
  761. X    len = sizeof (data_addr);
  762. X    if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
  763. X        perror("ftptool: getsockname");
  764. X        goto bad;
  765. X    }
  766. X    if (listen(data, 5) < 0)
  767. X        perror("ftptool: listen");
  768. X    if (sendport) {
  769. X        a = (char *)&data_addr.sin_addr;
  770. #ifdef SYSV386
  771. X    data_port = htons(data_addr.sin_port);
  772. X    p = (char *)&data_port;
  773. X    p[0] += p[1];        /* Switches variables, without a temp var */
  774. X    p[1] = p[0] - p[1];
  775. X    p[0] -= p[1];
  776. #else
  777. X        p = (char *)&data_addr.sin_port;
  778. #endif
  779. #define    UC(b)    (((int)b)&0xff)
  780. X        result =
  781. X            command("PORT %d,%d,%d,%d,%d,%d",
  782. X              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
  783. X              UC(p[0]), UC(p[1]));
  784. X        if (result == ERROR && sendport == -1) {
  785. X            sendport = 0;
  786. X            tmpno = 1;
  787. X            goto noport;
  788. X        }
  789. X        return (result != COMPLETE);
  790. X    }
  791. X    if (tmpno)
  792. X        sendport = 1;
  793. X    return (0);
  794. bad:
  795. X    (void) close(data), data = -1;
  796. X    if (tmpno)
  797. X        sendport = 1;
  798. X    return (1);
  799. }
  800. X
  801. #ifdef USE_PROTOTYPES
  802. FILE *dataconn(char *lmode)
  803. #else
  804. FILE *dataconn(lmode)
  805. char *lmode;
  806. #endif
  807. {
  808. X    struct sockaddr_in from;
  809. X    int s, fromlen = sizeof (from);
  810. X
  811. restart:
  812. X    s = accept(data, (struct sockaddr *) &from, &fromlen);
  813. X    if (s < 0) {
  814. X        if (errno == EINTR)
  815. X            goto restart;
  816. X        perror("ftptool: accept");
  817. X        (void) close(data);
  818. X        data = -1;
  819. X        return (NULL);
  820. X    }
  821. X    (void) close(data);
  822. X    data = s;
  823. X    return (fdopen(data, lmode));
  824. }
  825. X
  826. #ifdef USE_PROTOTYPES
  827. char *gunique(char *local)
  828. #else
  829. char *gunique(local)
  830. char    *local;
  831. #endif
  832. {
  833. X    static char new[MAXPATHLEN + 1];
  834. X    static char first[MAXPATHLEN + 1], last[MAXNAMLEN + 1];
  835. X    char *slash;
  836. X    int d, count=0;
  837. X    extern char *newname; /* from view_remote_file */
  838. X
  839. X    if ((strlen(local) + 3) > (size_t)MAXPATHLEN) {
  840. X        sprintf(scratch, "Unique name for %s too long.", local);
  841. X        footer_message(scratch, (char *)NULL);
  842. X        log_message(scratch);
  843. X        log_char('\n');
  844. X        return NULL;
  845. X    }
  846. X    slash = rindex(local, '/');
  847. X    if (slash) {
  848. X        *slash = '\0';
  849. X        strcpy(first, local);
  850. X        strcpy(last, slash + 1);
  851. X        *slash = '/';
  852. X    } else {
  853. X        *first = '\0';
  854. X        strcpy(last, local);
  855. X    }
  856. X    d = 0;
  857. X    while (!d) {
  858. X        if (++count == 100) {
  859. X            sprintf(scratch, "Cannot find unique name for %s.", local);
  860. X            footer_message(scratch, (char *)NULL);
  861. X            log_message(scratch);
  862. X            log_char('\n');
  863. X            return NULL;
  864. X        }
  865. X        if (slash)
  866. X            sprintf(new, "%s/%02d.%s", first, count, last);
  867. X        else
  868. X            sprintf(new, "%02d.%s", count, last);
  869. X        if ((d = access(new, 0)) < 0)
  870. X            break;
  871. X    }
  872. X        
  873. X    newname = new;
  874. X    footer_message("Unique name %s generated.", new, (char *)NULL);
  875. X    return new ;
  876. }
  877. X
  878. #ifdef USE_PROTOTYPES
  879. void abort_remote(FILE *din)
  880. #else
  881. void abort_remote(din)
  882. FILE *din;
  883. #endif
  884. {
  885. X    char buf[BUFSIZ];
  886. X    int nfnd;
  887. X    fd_set mask;
  888. X    int    rval;
  889. X
  890. X    /*
  891. X     * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
  892. X     * after urgent byte rather than before as is protocol now
  893. X     */
  894. X    sprintf(buf, "%c%c%c", IAC, IP, IAC);
  895. restart:
  896. X    rval = send(fileno(commandfp), buf, 3, MSG_OOB);
  897. X    if (rval == -1 && errno == EINTR)
  898. X        goto restart;
  899. X    if (rval != 3)
  900. X        perror("abort_remote1");
  901. X    fprintf(commandfp,"%cABOR\r\n", DM);
  902. X    (void) fflush(commandfp);
  903. X    FD_ZERO(&mask);
  904. X    FD_SET(fileno(responsefp), &mask);
  905. X    if (din) { 
  906. X        FD_SET(fileno(din), &mask);
  907. X    }
  908. X    if ((nfnd = empty(&mask, 10)) <= 0) {
  909. X        if (nfnd < 0) {
  910. X            perror("abort_remote2");
  911. X        }
  912. X        /*
  913. X        if (ptabflg)
  914. X            code = -1;
  915. X        */
  916. X        lostpeer();
  917. X    }
  918. X    if (din && FD_ISSET(fileno(din), &mask)) {
  919. X        while (read(fileno(din), buf, BUFSIZ) > 0)
  920. X            /* LOOP */;
  921. X    }
  922. X    if (getreply(0) == ERROR && code == 552) {
  923. X        /* 552 needed for nic style abort */
  924. X        (void) getreply(0);
  925. X    }
  926. X    (void) getreply(0);
  927. }
  928. X
  929. #ifdef USE_PROTOTYPES
  930. void lostpeer(void)
  931. #else
  932. void lostpeer()
  933. #endif
  934. {
  935. X    if (connected) {
  936. X        if (commandfp != NULL) {
  937. X            (void) shutdown(fileno(commandfp), 1+1);
  938. X            (void) fclose(commandfp);
  939. X            commandfp = NULL;
  940. X        }
  941. X        if (data >= 0) {
  942. X            (void) shutdown(data, 1+1);
  943. X            (void) close(data);
  944. X            data = -1;
  945. X        }
  946. X        connected = 0;
  947. X    }
  948. }
  949. X
  950. #ifdef USE_PROTOTYPES
  951. FILE *open_remote_ls(int nlst)
  952. #else
  953. FILE *open_remote_ls(nlst)
  954. int    nlst;
  955. #endif
  956. {
  957. X    char    *ftperr;
  958. X    char    *cmd;
  959. X    FILE *din = 0;
  960. X    char *gunique();
  961. X    off_t lseek();
  962. X
  963. X    if (nlst)
  964. X        cmd = "NLST"; /* dir */
  965. X    else
  966. X        cmd = "LIST"; /* ls */
  967. X
  968. X    settype(ASCII);
  969. X    if (initconn()) {
  970. X        code = -1;
  971. X        return NULL;
  972. X    }
  973. X    if (command_dataconn(&din, "r", "%s", cmd) != PRELIM) {
  974. #ifdef notdef
  975. X    if (command("%s", cmd) != PRELIM) {
  976. #endif
  977. X        if (code == 530) {
  978. X            /* 530 You must define working directory with CWD */
  979. X            ftperr = ftp_error(' ', "cd somewhere first or invalid directory");
  980. X        } else if (code == 550) {
  981. X            /* 550 No files found. */
  982. X            ftperr = ftp_error(' ', "No files found.");
  983. X        } else
  984. X            ftperr = "Unknown error.";
  985. X        footer_message(ftperr, (char *)NULL);
  986. X        return NULL;
  987. X    }
  988. #ifdef notdef
  989. X    din = dataconn("r");
  990. #endif
  991. X    if (din == NULL)
  992. X        return NULL;
  993. X    return din;
  994. }
  995. X
  996. #ifdef USE_PROTOTYPES
  997. char *next_remote_line(FILE *din)
  998. #else
  999. char *next_remote_line(din)
  1000. FILE    *din;
  1001. #endif
  1002. {
  1003. X    char    *str = response_line;
  1004. X    char    *cptr = str;
  1005. X    int        c;
  1006. X
  1007. X    notify_do_dispatch();
  1008. X    while ((c = getc(din)) != '\n' && c != EOF && c != '\0') {
  1009. X        if (c == '\r')
  1010. X            continue;
  1011. X        *cptr++ = (char)c;
  1012. X    }
  1013. X    *cptr = '\0';
  1014. X    notify_no_dispatch();
  1015. X    if (c == EOF)
  1016. X        return NULL;
  1017. X    return str;
  1018. }
  1019. X
  1020. #ifdef USE_PROTOTYPES
  1021. void close_remote_ls(FILE *din)
  1022. #else
  1023. void close_remote_ls(din)
  1024. FILE    *din;
  1025. #endif
  1026. {
  1027. X    if (ferror(din))
  1028. X        perror("netin");
  1029. X    (void) fclose(din);
  1030. X    (void) getreply(0);
  1031. X    return;
  1032. }
  1033. X
  1034. struct    types {
  1035. X    char    *t_name;
  1036. X    char    *t_mode;
  1037. X    int    t_type;
  1038. X    char    *t_arg;
  1039. } types[] = {
  1040. X    { "binary",    "I",    TYPE_I,    0 },
  1041. X    { "ascii",    "A",    TYPE_A,    0 },
  1042. X    { "tenex",    "L",    TYPE_L,    "8" },
  1043. /*
  1044. X    { "image",    "I",    TYPE_I,    0 },
  1045. X    { "ebcdic",    "E",    TYPE_E,    0 },
  1046. */
  1047. };
  1048. X
  1049. /*
  1050. X * Set transfer type.
  1051. X */
  1052. #ifdef USE_PROTOTYPES
  1053. void settype(int type)
  1054. #else
  1055. void settype(type)
  1056. int    type;
  1057. #endif
  1058. {
  1059. X    register struct types *p;
  1060. X    int comret;
  1061. X
  1062. X    if (type > (sizeof(types)/sizeof(types[0]))) {
  1063. X        printf("%d: unknown mode\n", type);
  1064. X        code = -1;
  1065. X        return;
  1066. X    }
  1067. X    /* make sure values in window match table! */
  1068. X    p = &types[type];
  1069. X
  1070. X    if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
  1071. X        comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
  1072. X    else
  1073. X        comret = command("TYPE %s", p->t_mode);
  1074. X    if (comret == COMPLETE) {
  1075. X        curtype = p->t_type;
  1076. X    }
  1077. }
  1078. SHAR_EOF
  1079. echo 'File ftp.c is complete' &&
  1080. chmod 0644 ftp.c ||
  1081. echo 'restore of ftp.c failed'
  1082. Wc_c="`wc -c < 'ftp.c'`"
  1083. test 30712 -eq "$Wc_c" ||
  1084.     echo 'ftp.c: original size 30712, current size' "$Wc_c"
  1085. rm -f _shar_wnt_.tmp
  1086. fi
  1087. # ============= host_list.c ==============
  1088. if test -f 'host_list.c' -a X"$1" != X"-c"; then
  1089.     echo 'x - skipping host_list.c (File already exists)'
  1090.     rm -f _shar_wnt_.tmp
  1091. else
  1092. > _shar_wnt_.tmp
  1093. echo 'x - extracting host_list.c (Text)'
  1094. sed 's/^X//' << 'SHAR_EOF' > 'host_list.c' &&
  1095. #include "ftptool.h"
  1096. X
  1097. #ifdef USE_PROTOTYPES
  1098. void host_list_clean_proc(Panel_item item, Event *event)
  1099. #else
  1100. void host_list_clean_proc(item, event)
  1101. Panel_item    item;
  1102. Event    *event;
  1103. #endif
  1104. {
  1105. X    xv_set(host_window.advanced.alias, 
  1106. X        PANEL_VALUE, "", 
  1107. X        NULL);
  1108. X    xv_set(host_window.advanced.last_visited, 
  1109. X        PANEL_LABEL_STRING, "Never", 
  1110. X        NULL);
  1111. X    xv_set(host_window.basic.host, 
  1112. X        PANEL_VALUE, "", 
  1113. X        NULL);
  1114. X    if (!strcmp((char *)xv_get(item, PANEL_LABEL_STRING), "New")) {
  1115. X        xv_set(host_window.basic.login, 
  1116. X            PANEL_VALUE, "", 
  1117. X            NULL);
  1118. X        xv_set(host_window.basic.password, 
  1119. X            PANEL_VALUE, "", 
  1120. X            NULL);
  1121. X    } else {
  1122. X        xv_set(host_window.basic.login, 
  1123. X            PANEL_VALUE, "anonymous", 
  1124. X            NULL);
  1125. X        xv_set(host_window.basic.password, 
  1126. X            PANEL_VALUE, anonftp_password, 
  1127. X            NULL);
  1128. X        xv_set(host_window.basic.panel,
  1129. X            PANEL_CARET_ITEM, host_window.basic.host,
  1130. X            NULL);
  1131. X    }
  1132. X    xv_set(host_window.advanced.proxy, 
  1133. X        PANEL_VALUE, DEFAULT_PROXY, 
  1134. X        NULL);
  1135. X    xv_set(host_window.advanced.transfer_mode, 
  1136. X        PANEL_VALUE, BINARY, 
  1137. X        NULL);
  1138. X    xv_set(host_window.advanced.remote_auto_cd, 
  1139. X        PANEL_VALUE, ".", 
  1140. X        NULL);
  1141. X    xv_set(host_window.advanced.local_auto_cd, 
  1142. X        PANEL_VALUE, ".", 
  1143. X        NULL);
  1144. X    xv_set(host_window.advanced.dir_parse, 
  1145. X        PANEL_VALUE, DEFAULT_PARSE, 
  1146. X        NULL);
  1147. X    xv_set(host_window.advanced.comment, 
  1148. X        PANEL_VALUE, "", 
  1149. X        NULL);
  1150. X
  1151. X    if (try_proxy) {
  1152. X        xv_set(host_window.advanced.proxy, 
  1153. X            XV_SHOW, TRUE, 
  1154. X            NULL);
  1155. X    } else {
  1156. X        xv_set(host_window.advanced.proxy, 
  1157. X            XV_SHOW, FALSE, 
  1158. X            NULL);
  1159. X    }
  1160. X    xv_set(item, 
  1161. X        PANEL_NOTIFY_STATUS, XV_ERROR, 
  1162. X        NULL);
  1163. }
  1164. X
  1165. #ifdef USE_PROTOTYPES
  1166. void host_list_item_proc(Menu menu, Menu_item menu_item)
  1167. #else
  1168. void host_list_item_proc(menu, menu_item)
  1169. Menu    menu;
  1170. Menu_item menu_item;
  1171. #endif
  1172. {
  1173. X    char    *alias = (char *)xv_get(menu_item, MENU_STRING);
  1174. X    struct    hostlist *tmp;
  1175. X
  1176. X    tmp = gethostlist(hostlist_head, alias);
  1177. X    if (tmp == NULL) {
  1178. X        fprintf(stderr, "Entry %s in menu not found in list.\n", alias);
  1179. X        exit(1);
  1180. X    }
  1181. X    xv_set(host_window.advanced.alias, 
  1182. X        PANEL_VALUE, tmp->aliasname, 
  1183. X        NULL);
  1184. X    xv_set(host_window.advanced.last_visited, 
  1185. X        PANEL_LABEL_STRING, tmp->last_visited, 
  1186. X        NULL);
  1187. X    xv_set(host_window.basic.host, 
  1188. X        PANEL_VALUE, tmp->host, 
  1189. X        NULL);
  1190. X    xv_set(host_window.basic.login, 
  1191. X        PANEL_VALUE, tmp->login, 
  1192. X        NULL);
  1193. X    xv_set(host_window.basic.password, 
  1194. X        PANEL_VALUE, tmp->password, 
  1195. X        NULL);
  1196. X    xv_set(host_window.advanced.proxy, 
  1197. X        PANEL_VALUE, tmp->proxy, 
  1198. X        NULL);
  1199. X    xv_set(host_window.advanced.transfer_mode, 
  1200. X        PANEL_VALUE, tmp->transfer_mode, 
  1201. X        NULL);
  1202. X    xv_set(host_window.advanced.remote_auto_cd, 
  1203. X        PANEL_VALUE, tmp->remote_directory, 
  1204. X        NULL);
  1205. X    xv_set(host_window.advanced.local_auto_cd, 
  1206. X        PANEL_VALUE, tmp->local_directory, 
  1207. X        NULL);
  1208. X    xv_set(host_window.advanced.dir_parse, 
  1209. X        PANEL_VALUE, tmp->dir_parse, 
  1210. X        NULL);
  1211. X    xv_set(host_window.advanced.comment, 
  1212. X        PANEL_VALUE, tmp->comment, 
  1213. X        NULL);
  1214. X
  1215. X    if (try_proxy) {
  1216. X        xv_set(host_window.advanced.proxy, 
  1217. X            XV_SHOW, TRUE, 
  1218. X            NULL);
  1219. X    } else {
  1220. X        xv_set(host_window.advanced.proxy, 
  1221. X            XV_SHOW, FALSE, 
  1222. X            NULL);
  1223. X    }
  1224. X    xv_set(menu, 
  1225. X        MENU_NOTIFY_STATUS, XV_ERROR, 
  1226. X        NULL);
  1227. X    if (!connected && auto_connect == TRUE) {
  1228. X        dowhat = DOCONNECT;
  1229. X        notify_stop();
  1230. X    }
  1231. }
  1232. X
  1233. X
  1234. #ifdef USE_PROTOTYPES
  1235. void host_list_add_proc(Menu menu, Menu_item menu_item)
  1236. #else
  1237. void host_list_add_proc(menu, menu_item)
  1238. Menu    menu;
  1239. Menu_item menu_item;
  1240. #endif
  1241. {
  1242. X    enter_host_info(1);
  1243. X    xv_set(menu, 
  1244. X        MENU_NOTIFY_STATUS, XV_ERROR, 
  1245. X        NULL);
  1246. }
  1247. X
  1248. #ifdef USE_PROTOTYPES
  1249. void host_list_change_proc(Menu menu, Menu_item menu_item)
  1250. #else
  1251. void host_list_change_proc(menu, menu_item)
  1252. Menu    menu;
  1253. Menu_item menu_item;
  1254. #endif
  1255. {
  1256. X    enter_host_info(0);
  1257. X    xv_set(menu, 
  1258. X        MENU_NOTIFY_STATUS, XV_ERROR, 
  1259. X        NULL);
  1260. }
  1261. X
  1262. #ifdef USE_PROTOTYPES
  1263. void    host_save_proc(Menu menu, Menu_item menu_item)
  1264. #else
  1265. void    host_save_proc(menu, menu_item)
  1266. Menu    menu;
  1267. Menu_item    menu_item;
  1268. #endif
  1269. {
  1270. X    write_ftptoolrc();
  1271. X    list_changed = 0;
  1272. X    timestamped = 0;
  1273. X    reload_host_list_menu(hostlist_head);
  1274. X    xv_set(menu, 
  1275. X        MENU_NOTIFY_STATUS, XV_ERROR, 
  1276. X        NULL);
  1277. }
  1278. X
  1279. #ifdef USE_PROTOTYPES
  1280. void    host_load_proc(Menu menu, Menu_item menu_item)
  1281. #else
  1282. void    host_load_proc(menu, menu_item)
  1283. Menu    menu;
  1284. Menu_item    menu_item;
  1285. #endif
  1286. {
  1287. X    int answer;
  1288. #ifdef XVIEW3
  1289. X    Xv_notice    notice;
  1290. #endif
  1291. X
  1292. X    if (timestamped || list_changed) {
  1293. #ifdef XVIEW3
  1294. X        notice = xv_create(host_window.panel, NOTICE,
  1295. X            NOTICE_MESSAGE_STRINGS,
  1296. X                "Your host list has changed since the last save.",
  1297. X                "Really load original?",
  1298. X                NULL,
  1299. X            NOTICE_BUTTON_YES, "Yes",
  1300. X            NOTICE_BUTTON_NO, "No",
  1301. X            NOTICE_STATUS, &answer,
  1302. X            XV_SHOW, TRUE,
  1303. X            NULL);
  1304. X        xv_destroy_safe(notice);
  1305. #else
  1306. X        answer = notice_prompt(host_window.panel, NULL,
  1307. X            NOTICE_MESSAGE_STRINGS,
  1308. X                "Your host list has changed since the last save.",
  1309. X                "Really load original?",
  1310. X                NULL,
  1311. X            NOTICE_BUTTON_YES, "Yes",
  1312. X            NOTICE_BUTTON_NO, "No",
  1313. X            NULL);
  1314. #endif
  1315. X        if (answer != NOTICE_YES)
  1316. X            return;
  1317. X    }
  1318. X    free_hostlist(hostlist_head);
  1319. X    hostlist_head = new_hostlist();
  1320. X    read_ftptoolrc();
  1321. X    list_changed = 0;
  1322. X    timestamped = 0;
  1323. X    reload_host_list_menu(hostlist_head);
  1324. X    xv_set(menu, 
  1325. X        MENU_NOTIFY_STATUS, XV_ERROR, 
  1326. X        NULL);
  1327. }
  1328. X
  1329. #ifdef USE_PROTOTYPES
  1330. void update_timestamp(void)
  1331. #else
  1332. void update_timestamp()
  1333. #endif
  1334. {
  1335. X    time_t    t;
  1336. X    time_t    time();
  1337. X    char    *ctime();
  1338. X    char    *s, *nl;
  1339. X    char    *aliasname;
  1340. X    struct hostlist *tmp;
  1341. X
  1342. X    t = time((time_t *)NULL);
  1343. X    s = ctime(&t);
  1344. X    if (nl = index(s, '\n'))
  1345. X        *nl = '\0';
  1346. X    xv_set(host_window.advanced.last_visited,
  1347. X        PANEL_LABEL_STRING, s,
  1348. X        NULL);
  1349. X    aliasname = (char *)xv_get(host_window.advanced.alias, PANEL_VALUE);
  1350. X    tmp = gethostlist(hostlist_head, aliasname);
  1351. X    if (tmp == NULL) {
  1352. X        return;
  1353. X    }
  1354. X    free(tmp->last_visited);
  1355. X    tmp->last_visited = strdup(s);
  1356. X    if (tmp->last_visited == NULL) {
  1357. X        fprintf(stderr, "Out of memory.\n");
  1358. X        goto out;
  1359. X    }
  1360. X
  1361. X    timestamped++;
  1362. out:
  1363. X    return;
  1364. }
  1365. X
  1366. #ifdef USE_PROTOTYPES
  1367. void enter_host_info(int warnchange)
  1368. #else
  1369. void enter_host_info(warnchange)
  1370. int        warnchange;
  1371. #endif
  1372. {
  1373. X    char    *aliasname;
  1374. X    char    *last_visited="Never";
  1375. X    char     *proxy;
  1376. X    char     *host;
  1377. X    char    *login;
  1378. X    char    *password;
  1379. X    char    *comment;
  1380. X    int        transfer_mode;
  1381. X    char    *remote_directory;
  1382. X    char    *local_directory;
  1383. X    char    *dir_parse;
  1384. X    int        answer;
  1385. #ifdef XVIEW3
  1386. X    Xv_notice notice;
  1387. #endif
  1388. X
  1389. X    aliasname = (char *)xv_get(host_window.advanced.alias, PANEL_VALUE);
  1390. X    if (aliasname[0] == '\0') {
  1391. X        xv_set(host_window.frame, 
  1392. X            FRAME_SHOW_FOOTER, TRUE, 
  1393. X            FRAME_LEFT_FOOTER, "Please specify an alias name.",
  1394. X            NULL);
  1395. X        goto out;
  1396. X    }
  1397. X    proxy = (char *)xv_get(host_window.advanced.proxy, PANEL_VALUE);
  1398. X    host = (char *)xv_get(host_window.basic.host, PANEL_VALUE);
  1399. X    login = (char *)xv_get(host_window.basic.login, PANEL_VALUE);
  1400. X    password = (char *)xv_get(host_window.basic.password, PANEL_VALUE);
  1401. X    transfer_mode = xv_get(host_window.advanced.transfer_mode, PANEL_VALUE);
  1402. X    remote_directory = (char *)xv_get(host_window.advanced.remote_auto_cd, 
  1403. X        PANEL_VALUE);
  1404. X    local_directory = (char *)xv_get(host_window.advanced.local_auto_cd, 
  1405. X        PANEL_VALUE);
  1406. X    dir_parse = (char *)xv_get(host_window.advanced.dir_parse, PANEL_VALUE);
  1407. X    comment = (char *)xv_get(host_window.advanced.comment, PANEL_VALUE);
  1408. X
  1409. X    if (gethostlist(hostlist_head, aliasname)) {
  1410. X        if (warnchange) {
  1411. #ifdef XVIEW3
  1412. X            notice = xv_create(host_window.panel, NOTICE,
  1413. X                NOTICE_MESSAGE_STRINGS,
  1414. X                    "That alias exists. Do you really want to change it?",
  1415. X                    NULL,
  1416. X                NOTICE_BUTTON_YES, "Yes",
  1417. X                NOTICE_BUTTON_NO, "No",
  1418. X                NOTICE_STATUS, &answer,
  1419. X                XV_SHOW, TRUE,
  1420. X                NULL);
  1421. X            xv_destroy_safe(notice);
  1422. #else
  1423. X            answer = notice_prompt(host_window.panel, NULL,
  1424. X                NOTICE_MESSAGE_STRINGS,
  1425. X                    "That alias exists. Do you really want to change it?",
  1426. X                    NULL,
  1427. X                NOTICE_BUTTON_YES, "Yes",
  1428. X                NOTICE_BUTTON_NO, "No",
  1429. X                NULL);
  1430. #endif
  1431. X            if (answer != NOTICE_YES)
  1432. X                goto out;
  1433. X        }
  1434. X        last_visited = (char *)xv_get(host_window.advanced.last_visited, 
  1435. X            PANEL_LABEL_STRING);
  1436. X        delete_hostlist(hostlist_head, aliasname);
  1437. X    }
  1438. X    if ((hostlist_head = add_hostalias(hostlist_head, aliasname, 
  1439. X        last_visited, proxy, host, login, password, transfer_mode,
  1440. X        remote_directory, local_directory, dir_parse, comment)) == NULL) {
  1441. X        xv_set(host_window.frame, 
  1442. X            FRAME_SHOW_FOOTER, TRUE, 
  1443. X            FRAME_LEFT_FOOTER, "Add failed.",
  1444. X            NULL);
  1445. X        goto out;
  1446. X    }
  1447. X    list_changed++;
  1448. X    reload_host_list_menu(hostlist_head);
  1449. out:
  1450. X    return;
  1451. }
  1452. X
  1453. #ifdef USE_PROTOTYPES
  1454. void host_list_delete_proc(Menu menu, Menu_item menu_item)
  1455. #else
  1456. void host_list_delete_proc(menu, menu_item)
  1457. Menu    menu;
  1458. Menu_item menu_item;
  1459. #endif
  1460. {
  1461. X    char    *aliasname;
  1462. X
  1463. X    aliasname = (char *)xv_get(host_window.advanced.alias, PANEL_VALUE);
  1464. X
  1465. X    if (gethostlist(hostlist_head, aliasname) == NULL) {
  1466. X        xv_set(host_window.frame, 
  1467. X            FRAME_SHOW_FOOTER, TRUE, 
  1468. X            FRAME_LEFT_FOOTER, "No such alias",
  1469. X            NULL);
  1470. X        return;
  1471. X    }
  1472. X    delete_hostlist(hostlist_head, aliasname);
  1473. X    list_changed++;
  1474. X    reload_host_list_menu(hostlist_head);
  1475. X    xv_set(menu, 
  1476. X        MENU_NOTIFY_STATUS, XV_ERROR, 
  1477. X        NULL);
  1478. }
  1479. X
  1480. #ifdef USE_PROTOTYPES
  1481. int host_list_use_proc(Panel_item item, char *string, 
  1482. X    Xv_opaque client_data, Panel_list_op op, Event *event)
  1483. #else
  1484. int host_list_use_proc(item,string,client_data,op,event)
  1485. Panel_item        item;
  1486. char            *string;
  1487. XXv_opaque        client_data;
  1488. Panel_list_op   op;
  1489. Event            *event;
  1490. #endif
  1491. {
  1492. X    struct hostlist *tmp;
  1493. X
  1494. X    switch(op) {
  1495. X    case PANEL_LIST_OP_SELECT:
  1496. X        tmp = gethostlist(hostlist_head, string);
  1497. X        if (tmp == NULL) {
  1498. X            fprintf(stderr, "gethostlist failed in select\n");
  1499. X            return XV_ERROR;
  1500. X        }
  1501. X        xv_set(host_window.advanced.alias, 
  1502. X            PANEL_VALUE, tmp->aliasname, 
  1503. X            NULL);
  1504. X        xv_set(host_window.advanced.last_visited, 
  1505. X            PANEL_LABEL_STRING, tmp->last_visited, 
  1506. X            NULL);
  1507. X        if (try_proxy) {
  1508. X            xv_set(host_window.advanced.proxy, 
  1509. X                XV_SHOW, TRUE, 
  1510. X                NULL);
  1511. X        } else {
  1512. X            xv_set(host_window.advanced.proxy, 
  1513. X                XV_SHOW, FALSE, 
  1514. X                NULL);
  1515. X        }
  1516. X        xv_set(host_window.basic.host, 
  1517. X            PANEL_VALUE, tmp->host, 
  1518. X            NULL);
  1519. X        xv_set(host_window.basic.login, 
  1520. X            PANEL_VALUE, tmp->login, 
  1521. X            NULL);
  1522. X        xv_set(host_window.basic.password, 
  1523. X            PANEL_VALUE, tmp->password, 
  1524. X            NULL);
  1525. X        xv_set(host_window.advanced.transfer_mode, 
  1526. X            PANEL_VALUE, tmp->transfer_mode, 
  1527. X            NULL);
  1528. X        xv_set(host_window.advanced.remote_auto_cd, 
  1529. X            PANEL_VALUE, tmp->remote_directory, 
  1530. X            NULL);
  1531. X        xv_set(host_window.advanced.local_auto_cd, 
  1532. X            PANEL_VALUE, tmp->local_directory, 
  1533. X            NULL);
  1534. X        xv_set(host_window.advanced.dir_parse, 
  1535. X            PANEL_VALUE, tmp->dir_parse, 
  1536. X            NULL);
  1537. X        xv_set(host_window.advanced.comment, 
  1538. X            PANEL_VALUE, tmp->comment, 
  1539. X            NULL);
  1540. X        break;
  1541. X    case PANEL_LIST_OP_DESELECT:
  1542. X        break;
  1543. X    default:
  1544. X        break;
  1545. X    }
  1546. X
  1547. X    return XV_OK;
  1548. }
  1549. X
  1550. #ifdef USE_PROTOTYPES
  1551. struct hostlist *new_hostlist(void)
  1552. #else
  1553. struct hostlist *new_hostlist()
  1554. #endif
  1555. {
  1556. X    struct hostlist *tmp;
  1557. X
  1558. X    tmp = (struct hostlist *)malloc(sizeof(struct hostlist));
  1559. X    if (tmp == NULL)
  1560. X        return NULL;
  1561. X    bzero((char *)tmp, sizeof(struct hostlist));
  1562. X    tmp->next = NULL;
  1563. X    tmp->aliasname = NULL;
  1564. X    tmp->last_visited = NULL;
  1565. X    tmp->proxy = NULL;
  1566. X    tmp->host = NULL;
  1567. X    tmp->login = NULL;
  1568. X    tmp->password = NULL;
  1569. X    tmp->remote_directory = NULL;
  1570. X    tmp->local_directory = NULL;
  1571. X    tmp->dir_parse = NULL;
  1572. X    tmp->comment = NULL;
  1573. X    return tmp;
  1574. }
  1575. X
  1576. #ifdef USE_PROTOTYPES
  1577. struct hostlist *add_hostalias(struct hostlist *head, char *aliasname, 
  1578. X    char *last_visited, char *proxy, char *host, char *login, 
  1579. X    char *password, int transfer_mode, char *remote_directory, 
  1580. X    char *local_directory, char *dir_parse, char *comment)
  1581. #else
  1582. struct hostlist *add_hostalias(head, aliasname, last_visited, proxy, 
  1583. X    host, login, password, transfer_mode, remote_directory, 
  1584. X    local_directory, dir_parse, comment)
  1585. struct hostlist *head;
  1586. char    *aliasname;
  1587. char    *last_visited;
  1588. char    *proxy;
  1589. char    *host;
  1590. char    *login;
  1591. char    *password;
  1592. int        transfer_mode;
  1593. char    *remote_directory;
  1594. char    *local_directory;
  1595. char    *dir_parse;
  1596. char    *comment;
  1597. #endif
  1598. {
  1599. X    struct hostlist *tmp;
  1600. X    struct hostlist *oldnext;
  1601. X    int        rval = 0;
  1602. X
  1603. X    /* add in sorted order */
  1604. X    for (tmp = head; tmp->next != NULL; tmp = tmp->next)  {
  1605. X        if (ignore_case)
  1606. X            rval = strcasecmp(aliasname, tmp->next->aliasname);
  1607. X        else
  1608. X            rval = strcmp(aliasname, tmp->next->aliasname);
  1609. X        if (rval < 0)
  1610. X            break;
  1611. X    }
  1612. X    oldnext = tmp->next;
  1613. X    tmp->next = new_hostlist();
  1614. X    if (tmp->next == NULL) {
  1615. X        tmp->next = oldnext;
  1616. X        return NULL;
  1617. X    }
  1618. X
  1619. X    tmp->next->aliasname = strdup(aliasname);
  1620. X    if (tmp->next->aliasname == NULL) {
  1621. X        goto out;
  1622. X    }
  1623. X
  1624. X    tmp->next->last_visited = strdup(last_visited);
  1625. X    if (tmp->next->last_visited == NULL) {
  1626. X        goto out;
  1627. X    }
  1628. X
  1629. X    tmp->next->proxy = strdup(proxy);
  1630. X    if (tmp->next->proxy == NULL) {
  1631. X        goto out;
  1632. X    }
  1633. X
  1634. X    tmp->next->host = strdup(host);
  1635. X    if (tmp->next->host == NULL) {
  1636. X        goto out;
  1637. X    }
  1638. X
  1639. X    tmp->next->login = strdup(login);
  1640. X    if (tmp->next->login == NULL) {
  1641. X        goto out;
  1642. X    }
  1643. X
  1644. X    tmp->next->password = strdup(password);
  1645. X    if (tmp->next->password == NULL) {
  1646. X        goto out;
  1647. X    }
  1648. X
  1649. X    tmp->next->transfer_mode = transfer_mode;
  1650. X
  1651. X    tmp->next->remote_directory = strdup(remote_directory);
  1652. X    if (tmp->next->remote_directory == NULL) {
  1653. X        goto out;
  1654. X    }
  1655. X
  1656. X    tmp->next->local_directory = strdup(local_directory);
  1657. X    if (tmp->next->local_directory == NULL) {
  1658. X        goto out;
  1659. X    }
  1660. X
  1661. X    tmp->next->dir_parse = strdup(dir_parse);
  1662. X    if (tmp->next->dir_parse == NULL) {
  1663. X        goto out;
  1664. X    }
  1665. X
  1666. X    tmp->next->comment = strdup(comment);
  1667. X    if (tmp->next->comment == NULL) {
  1668. X        goto out;
  1669. X    }
  1670. X
  1671. X    tmp->next->next = oldnext;
  1672. X    return head;
  1673. out:
  1674. X    tmp->next->next = NULL;
  1675. X    free_hostlist(tmp->next);
  1676. X    tmp->next = oldnext;
  1677. X    return NULL;
  1678. }
  1679. X
  1680. #ifdef USE_PROTOTYPES
  1681. void free_hostlist(struct hostlist *head)
  1682. #else
  1683. void free_hostlist(head)
  1684. struct hostlist *head;
  1685. #endif
  1686. {
  1687. X    struct hostlist *tmp;
  1688. X
  1689. X    while (head) {
  1690. X        tmp = head->next;
  1691. X        if (head->aliasname)
  1692. X            free(head->aliasname);
  1693. X        if (head->last_visited)
  1694. X            free(head->last_visited);
  1695. X        if (head->proxy)
  1696. X            free(head->proxy);
  1697. X        if (head->host)
  1698. X            free(head->host);
  1699. X        if (head->login)
  1700. X            free(head->login);
  1701. X        if (head->password)
  1702. X            free(head->password);
  1703. X        if (head->remote_directory)
  1704. X            free(head->remote_directory);
  1705. X        if (head->local_directory)
  1706. X            free(head->local_directory);
  1707. X        if (head->dir_parse)
  1708. X            free(head->dir_parse);
  1709. X        if (head->comment)
  1710. X            free(head->comment);
  1711. X        free((char *)head);
  1712. X        head = tmp;
  1713. X    }
  1714. }
  1715. X
  1716. #ifdef USE_PROTOTYPES
  1717. struct hostlist *gethostlist(struct hostlist *head, char *aliasname)
  1718. #else
  1719. struct hostlist *gethostlist(head, aliasname)
  1720. struct hostlist *head;
  1721. char    *aliasname;
  1722. #endif
  1723. {
  1724. X    struct hostlist *tmp;
  1725. X
  1726. X    for (tmp = head->next; tmp != NULL; tmp = tmp->next)
  1727. X        if (!strcmp(aliasname, tmp->aliasname)) 
  1728. X            return tmp;
  1729. X    return NULL;
  1730. }
  1731. X
  1732. #ifdef USE_PROTOTYPES
  1733. int delete_hostlist(struct hostlist *head, char *aliasname)
  1734. #else
  1735. int delete_hostlist(head, aliasname)
  1736. struct hostlist *head;
  1737. char    *aliasname;
  1738. #endif
  1739. {
  1740. X    struct hostlist *tmp;
  1741. X    struct hostlist *tmp2;
  1742. X
  1743. X    for (tmp = head; tmp->next != NULL; tmp = tmp->next) {
  1744. X        if (!strcmp(aliasname, tmp->next->aliasname)) {
  1745. X            /* delete existing entry */
  1746. X            tmp2 = tmp->next->next;
  1747. X            tmp->next->next = NULL;
  1748. X            free_hostlist(tmp->next);
  1749. X            tmp->next = tmp2;
  1750. X            return 1;
  1751. X        }
  1752. X    }
  1753. X    return 0;
  1754. }
  1755. X
  1756. #ifdef USE_PROTOTYPES
  1757. void read_ftptoolrc(void)
  1758. #else
  1759. void read_ftptoolrc()
  1760. #endif
  1761. {
  1762. X    int    fd;
  1763. X    static char    aliasname[MAXCOMMENTLEN + 1];
  1764. X    static char    host[MAXHOSTNAMELEN + 1];
  1765. X    static char    login[MAXLOGINLEN + 1];
  1766. X    static char    password[MAXHOSTNAMELEN + 1];
  1767. X    static char    comment[MAXCOMMENTLEN + 1];
  1768. X    FILE    *fp;
  1769. X    int ch;
  1770. X
  1771. X    fd = ftptoolrc_fd(O_RDONLY, 0600);
  1772. X    if (fd == -1) {
  1773. X        if (netrc_filename)
  1774. X            host_append_netrc_proc();
  1775. X        return;
  1776. X    }
  1777. X    /* ftptoolrc file format */
  1778. X    /*
  1779. X     Alias
  1780. X     direct (ignored)
  1781. X     host
  1782. X     login
  1783. X     password
  1784. X     Comment
  1785. X     */
  1786. X    fp = fdopen(fd, "r");
  1787. X    if (fp == NULL) {
  1788. X        close(fd);
  1789. X        return;
  1790. X    }
  1791. X    /* see if it's a 'new' format */
  1792. X    ch = getc(fp);
  1793. X    if (ch == '#') {
  1794. X        fclose(fp);
  1795. X        read_newftptoolrc();
  1796. X        return;
  1797. X    }
  1798. X    ungetc(ch, fp);
  1799. X    while (read_entry(0, fp,aliasname,(char *)NULL, (char *)NULL,
  1800. X        host,login, password,(int *)NULL, (char *)NULL, (char *)NULL, 
  1801. X        DEFAULT_PARSE, comment))
  1802. X            if (add_hostalias(hostlist_head, aliasname, "Never", 
  1803. X                DEFAULT_PROXY, host, login, password, BINARY,
  1804. X                ".", ".", DEFAULT_PARSE, comment) == NULL)
  1805. X                    break;
  1806. X    fclose(fp);
  1807. }
  1808. X
  1809. #ifdef USE_PROTOTYPES
  1810. int read_entry(int version, FILE *fp, char *aliasname, char *last_visited, 
  1811. X    char *proxy, char *host, char *login, char *password, int *transfer_mode, 
  1812. X    char *rdir, char *ldir, char *dir_parse, char *comment)
  1813. #else
  1814. int read_entry(version, fp, aliasname, last_visited, proxy, host, 
  1815. X    login, password, transfer_mode, rdir, ldir, dir_parse, comment)
  1816. int        version;
  1817. FILE    *fp;
  1818. char    *aliasname;
  1819. char    *last_visited;
  1820. char    *proxy;
  1821. char    *host;
  1822. char    *login;
  1823. char    *password;
  1824. int        *transfer_mode;
  1825. char    *rdir;
  1826. char    *ldir;
  1827. char    *dir_parse;
  1828. char    *comment;
  1829. #endif
  1830. {
  1831. X    char    *nl;
  1832. X    char    *dpasswd;
  1833. X
  1834. X    if (fgets(aliasname, MAXCOMMENTLEN+1,fp) == NULL) 
  1835. X        if (feof(fp))
  1836. X            return 0;
  1837. X        else
  1838. X            goto out;
  1839. X    if (nl = index(aliasname, '\n'))
  1840. X        *nl = '\0';
  1841. X    if (version > 2) {
  1842. X        if (fgets(last_visited, MAXPATHLEN+1,fp) == NULL) 
  1843. X            goto out;
  1844. X        if (nl = index(last_visited, '\n'))
  1845. X            *nl = '\0';
  1846. X    }
  1847. X    if (fgets(scratch, MAXHOSTNAMELEN+1,fp) == NULL) 
  1848. X        goto out;
  1849. X    if (version > 0) {
  1850. X        if (fgets(proxy, MAXHOSTNAMELEN+1,fp) == NULL) 
  1851. X            goto out;
  1852. X        if (nl = index(proxy, '\n'))
  1853. X            *nl = '\0';
  1854. X    }
  1855. X    if (fgets(host, MAXHOSTNAMELEN+1,fp) == NULL) 
  1856. X        goto out;
  1857. X    if (nl = index(host, '\n'))
  1858. X        *nl = '\0';
  1859. X    if (fgets(login, MAXLOGINLEN+1,fp) == NULL) 
  1860. X        goto out;
  1861. X    if (nl = index(login, '\n'))
  1862. X        *nl = '\0';
  1863. X    if (fgets(password, MAXPASSWORDLEN+1,fp) == NULL) 
  1864. X        goto out;
  1865. X    if (nl = index(password, '\n'))
  1866. X        *nl = '\0';
  1867. X    if (version > 2) {
  1868. X        /* decrypt it */
  1869. X        if (version > 3)
  1870. X            dpasswd = ftptool_decrypt(password, login_name);
  1871. X        else
  1872. X            dpasswd = old_ftptool_decrypt(password, login_name);
  1873. X        if (dpasswd != NULL) {
  1874. X            strcpy(password, dpasswd);
  1875. X            free(dpasswd);
  1876. X        }
  1877. X    } 
  1878. X    if (version > 4) {
  1879. X        if (fgets(scratch, MAXHOSTNAMELEN+1,fp) == NULL) 
  1880. X            goto out;
  1881. X        *transfer_mode = atoi(scratch);
  1882. X    }
  1883. X    if (version > 0) {
  1884. X        if (fgets(rdir, MAXPATHLEN+1,fp) == NULL) 
  1885. X            goto out;
  1886. X        if (nl = index(rdir, '\n'))
  1887. X            *nl = '\0';
  1888. X    }
  1889. X    if (version > 1) {
  1890. X        if (fgets(ldir, MAXPATHLEN+1,fp) == NULL) 
  1891. X            goto out;
  1892. X        if (nl = index(ldir, '\n'))
  1893. X            *nl = '\0';
  1894. X    }
  1895. X    if (version > 2) {
  1896. X        if (fgets(dir_parse, MAXPATHLEN+1,fp) == NULL) 
  1897. X            goto out;
  1898. X        if (nl = index(dir_parse, '\n'))
  1899. X            *nl = '\0';
  1900. X    }
  1901. X    if (fgets(comment, MAXCOMMENTLEN+1,fp) == NULL) 
  1902. X        goto out;
  1903. X    if (nl = index(comment, '\n'))
  1904. X        *nl = '\0';
  1905. X    return 1;
  1906. out:
  1907. X    fprintf(stderr, "bad entry for %s in .netrc\n", aliasname);
  1908. X    return 0;
  1909. }
  1910. X
  1911. #ifdef USE_PROTOTYPES
  1912. void read_newftptoolrc(void)
  1913. #else
  1914. void read_newftptoolrc()
  1915. #endif
  1916. {
  1917. X    int    fd;
  1918. X    static char    aliasname[MAXALIASLEN + 1];
  1919. X    static char    last_visited[41];
  1920. X    static int        transfer_mode;
  1921. X    static char    proxy[MAXHOSTNAMELEN + 1];
  1922. X    static char    host[MAXHOSTNAMELEN + 1];
  1923. X    static char    login[MAXLOGINLEN + 1];
  1924. X    static char    password[MAXPASSWORDLEN + 1];
  1925. X    static char    remote_directory[MAXPATHLEN + 1];
  1926. X    static char    local_directory[MAXPATHLEN + 1];
  1927. X    static char    dir_parse[MAXPATHLEN + 1];
  1928. X    static char    comment[MAXCOMMENTLEN + 1];
  1929. X    FILE    *fp;
  1930. X    int    version, patch;
  1931. X    int    list_version;
  1932. X
  1933. X    fd = ftptoolrc_fd(O_RDONLY, 0600);
  1934. X    if (fd == -1) {
  1935. X        if (netrc_filename)
  1936. X            host_append_netrc_proc();
  1937. X        return;
  1938. X    }
  1939. X    /* new ftptoolrc file format */
  1940. X    /* first line */
  1941. X    /* # Host List : Ftptool Version 3.3 */
  1942. X    /*
  1943. X     Alias
  1944. X     direct (ignored)
  1945. X     proxy
  1946. X     host
  1947. X     login
  1948. X     password
  1949. X     remote directory
  1950. X     local directory
  1951. X     dir parse line
  1952. X     Comment
  1953. X     */
  1954. X    fp = fdopen(fd, "r");
  1955. X    if (fp == NULL) {
  1956. X        close(fd);
  1957. X        return;
  1958. X    }
  1959. X    /* first line is a comment line */
  1960. X    fgets(comment, MAXCOMMENTLEN + 1, fp);
  1961. X    sscanf(comment, "# Host List : Ftptool Version %d.%d\n", &version, &patch);
  1962. X    if (version >= 4 && patch >= 1)
  1963. X        list_version = 5;
  1964. X    else if (version == 4 && patch == 0)
  1965. X        list_version = 4;
  1966. X    else if (version == 3 && patch == 3)
  1967. X        list_version = 3;
  1968. X    else if (version == 3 && patch == 2)
  1969. X        list_version = 2;
  1970. X    else
  1971. X        list_version = 1;
  1972. X
  1973. X    while (read_entry(list_version, fp, 
  1974. X        aliasname, last_visited, proxy, host, login, password, 
  1975. X        &transfer_mode, remote_directory, local_directory, dir_parse, 
  1976. X        comment)) {
  1977. X            if (add_hostalias(hostlist_head, aliasname, 
  1978. X                list_version >= 3 ? last_visited : "Never", 
  1979. X                proxy, host, login, password, 
  1980. X                list_version >= 5 ? transfer_mode : BINARY,
  1981. X                remote_directory, 
  1982. X                list_version >= 2 ? local_directory : ".", 
  1983. X                list_version >= 3 ? dir_parse : DEFAULT_PARSE,
  1984. X                comment) == NULL)
  1985. X                    break;
  1986. X    }
  1987. X    fclose(fp);
  1988. }
  1989. X
  1990. #ifdef USE_PROTOTYPES
  1991. void write_ftptoolrc(void)
  1992. #else
  1993. void write_ftptoolrc()
  1994. #endif
  1995. {
  1996. X    int    fd;
  1997. X    struct hostlist *tmp;
  1998. X    FILE    *fp;
  1999. X    char    *epasswd;
  2000. X
  2001. X    fd = ftptoolrc_fd(O_WRONLY | O_TRUNC | O_CREAT, 0600);
  2002. X    if (fd == -1) {
  2003. X        perror("writing host list");
  2004. X        return;
  2005. X    }
  2006. X    /* ftptoolrc file format */
  2007. X    /*
  2008. X     Alias
  2009. X     Last Visited
  2010. X     direct (ignored) XXX
  2011. X     proxy
  2012. X     host
  2013. X     login
  2014. X     password
  2015. X     transfer_mode
  2016. X     remote directory
  2017. X     local directory
  2018. X     dir parse
  2019. X     Comment
  2020. X     */
  2021. X    fp = fdopen(fd, "w"); 
  2022. X    if (fp == NULL) {
  2023. X        close(fd);
  2024. X        return;
  2025. X    }
  2026. X    fprintf(fp, "# Host List : %s\n", header_name);
  2027. X    for (tmp = hostlist_head->next; tmp != NULL; tmp = tmp->next) {
  2028. X        epasswd = ftptool_encrypt(tmp->password, login_name);
  2029. X        if (epasswd == NULL) {
  2030. X            fprintf(stderr, "Out of memory.\n");
  2031. X            exit(1);
  2032. X        }
  2033. X        fprintf(fp, "%s\n", tmp->aliasname);
  2034. X        fprintf(fp, "%s\n", tmp->last_visited);
  2035. X        fprintf(fp, "%d\n", 1);
  2036. X        fprintf(fp, "%s\n", tmp->proxy);
  2037. X        fprintf(fp, "%s\n", tmp->host);
  2038. X        fprintf(fp, "%s\n", tmp->login);
  2039. X        fprintf(fp, "%s\n", epasswd);
  2040. X        fprintf(fp, "%d\n", tmp->transfer_mode);
  2041. X        fprintf(fp, "%s\n", tmp->remote_directory);
  2042. X        fprintf(fp, "%s\n", tmp->local_directory);
  2043. X        fprintf(fp, "%s\n", tmp->dir_parse);
  2044. X        fprintf(fp, "%s\n", tmp->comment);
  2045. X        free(epasswd);
  2046. X    }
  2047. X
  2048. X    fclose(fp);
  2049. }
  2050. X
  2051. #ifdef USE_PROTOTYPES
  2052. int ftptoolrc_fd(int flags, int mode)
  2053. #else
  2054. int ftptoolrc_fd(flags, mode)
  2055. int        flags;
  2056. int        mode;
  2057. #endif
  2058. {
  2059. X    char    *filename=NULL;
  2060. X    int        fd;
  2061. X
  2062. X    filename = find_dotfile(FTPTOOL_RC);
  2063. X    if (filename == NULL) {
  2064. X        if (flags == O_RDONLY) {
  2065. X            /* try global one */
  2066. X            filename = strdup(GLOBAL_FTPTOOLRC);
  2067. X            if (filename == NULL) {
  2068. X                return -1;
  2069. X            }
  2070. X        } else {
  2071. X            if ((filename = create_dotfile(FTPTOOL_RC, 0600)) == NULL)
  2072. X                return -1;
  2073. X        }
  2074. X    }
  2075. X
  2076. X    /* try current directory */
  2077. X    if ((fd = open(filename, flags, mode)) != -1) {
  2078. X        free(filename);
  2079. X        return fd;
  2080. X    }
  2081. X    free(filename);
  2082. X    return -1;
  2083. }
  2084. X
  2085. #ifdef USE_PROTOTYPES
  2086. void reload_host_list_menu(struct hostlist *head)
  2087. #else
  2088. void reload_host_list_menu(head)
  2089. struct hostlist *head;
  2090. #endif
  2091. {
  2092. X    Menu    menu = xv_get(host_window.hosts, PANEL_ITEM_MENU);
  2093. X    int    nitems = xv_get(menu, MENU_NITEMS);
  2094. X    int    row;
  2095. X    struct hostlist *tmp;
  2096. X    Menu_item    mi;
  2097. X    Frame    frame;
  2098. X    int        isshown;
  2099. X    int        maxwidth=0;
  2100. X    int        width=0;
  2101. X    double    cols;
  2102. X
  2103. X    frame = (Panel)xv_get(menu, MENU_PIN_WINDOW);
  2104. X    isshown = FALSE;
  2105. X    if (frame) 
  2106. X        isshown = xv_get(frame, XV_SHOW);
  2107. X
  2108. X    if (isshown) {
  2109. X        xv_set(frame, 
  2110. #ifdef XVIEW3
  2111. X            FRAME_CMD_PIN_STATE, FRAME_CMD_PIN_OUT,
  2112. #else
  2113. X            FRAME_CMD_PUSHPIN_IN, FALSE,
  2114. #endif
  2115. X            XV_SHOW, FALSE,
  2116. X            NULL);
  2117. X    }
  2118. X    /* 2 items minimum, 1 for title */
  2119. X    for (row = nitems; row > 1; row--)
  2120. X        xv_set(menu,
  2121. X            MENU_REMOVE, row,
  2122. X            NULL);
  2123. X
  2124. X    nhostlist_items = 0;
  2125. X    for (tmp=head->next; tmp != NULL; tmp=tmp->next) {
  2126. X        width = strlen(tmp->aliasname);
  2127. X        maxwidth = MAX(maxwidth, width);
  2128. X        mi = (Menu_item)xv_create(XV_NULL, MENUITEM,
  2129. X            MENU_STRING, tmp->aliasname,
  2130. X            MENU_NOTIFY_PROC, host_list_item_proc,
  2131. X            MENU_RELEASE,
  2132. X            NULL);
  2133. X        if (mi == XV_NULL) {
  2134. X            fprintf(stderr, "Out of memory for menu item.\n");
  2135. X            exit(1);
  2136. X        }
  2137. X        xv_set(menu,
  2138. X            MENU_APPEND_ITEM, mi,
  2139. X            PANEL_PAINT, PANEL_NONE,
  2140. X            NULL);
  2141. X        nhostlist_items++;
  2142. X    }
  2143. X    if (nhostlist_items == 0) {
  2144. X        mi = (Menu_item)xv_create(XV_NULL, MENUITEM,
  2145. X            MENU_STRING, "No Hosts!",
  2146. X            MENU_RELEASE,
  2147. X            NULL);
  2148. X        if (mi == XV_NULL) {
  2149. X            fprintf(stderr, "Out of memory for menu item.\n");
  2150. X            exit(1);
  2151. X        }
  2152. X        xv_set(menu,
  2153. X            MENU_APPEND_ITEM, mi,
  2154. X            NULL);
  2155. X    }
  2156. X
  2157. X    if (maxwidth == 0)
  2158. X        maxwidth = 1;
  2159. X    
  2160. X    cols = 2.0 * nhostlist_items;
  2161. X    cols /= maxwidth;
  2162. X    cols = ceil(sqrt(cols));
  2163. X    xv_set(menu,
  2164. X        MENU_NCOLS,(int)cols,
  2165. X        NULL);
  2166. X    if (isshown) {
  2167. X        xv_set(frame, 
  2168. #ifdef XVIEW3
  2169. X            FRAME_CMD_PIN_STATE, FRAME_CMD_PIN_IN,
  2170. #else
  2171. X            FRAME_CMD_PUSHPIN_IN, TRUE,
  2172. #endif
  2173. X            XV_SHOW, TRUE,
  2174. X            NULL);
  2175. X    }
  2176. }
  2177. X
  2178. #ifdef USE_PROTOTYPES
  2179. char *create_dotfile(char *dotfile, int mode)
  2180. #else
  2181. char *create_dotfile(dotfile, mode)
  2182. char    *dotfile;
  2183. int        mode;
  2184. #endif
  2185. {
  2186. X    char    *home;
  2187. X    char    *filename=NULL;
  2188. X    int        fd;
  2189. X
  2190. X    home = getenv("HOME");
  2191. X    if (home != NULL && home[0] != '\0') {
  2192. X        /* try $HOME/dotfile */
  2193. X        filename = malloc((unsigned int)(strlen(home)+1+strlen(dotfile)+1));
  2194. X        if (filename == NULL)
  2195. X            return NULL;
  2196. X        sprintf(filename, "%s/%s", home, dotfile);
  2197. X        if ((fd = creat(filename, mode)) == -1) {
  2198. X            free(filename);
  2199. X            return NULL;
  2200. X        }
  2201. X        close(fd);
  2202. X        /* found it */
  2203. X        return filename;
  2204. X    }
  2205. X    filename = strdup(dotfile);
  2206. X    if (filename == NULL)
  2207. X        return NULL;
  2208. X    if ((fd = creat(filename, mode)) == -1) {
  2209. X        free(filename);
  2210. X        return NULL;
  2211. X    }
  2212. X    close(fd);
  2213. X
  2214. X    return filename;
  2215. }
  2216. X
  2217. #ifdef USE_PROTOTYPES
  2218. char *find_dotfile(char *dotfile)
  2219. #else
  2220. char *find_dotfile(dotfile)
  2221. char    *dotfile;
  2222. #endif
  2223. {
  2224. X    char    *home;
  2225. X    char    *filename=NULL;
  2226. X
  2227. X    home = getenv("HOME");
  2228. X    if (home != NULL && home[0] != '\0') {
  2229. X        /* try $HOME/dotfile */
  2230. X        filename = malloc((unsigned int)(strlen(home)+1+strlen(dotfile)+1));
  2231. X        if (filename == NULL)
  2232. X            return NULL;
  2233. X        sprintf(filename, "%s/%s", home, dotfile);
  2234. X        if (access(filename, F_OK) == -1) {
  2235. X            free(filename);
  2236. X            return NULL;
  2237. X        }
  2238. X        /* found it */
  2239. X        return filename;
  2240. X    }
  2241. X    filename = strdup(dotfile);
  2242. X    if (filename == NULL)
  2243. X        return NULL;
  2244. X    if (access(filename, F_OK) == -1) {
  2245. X        free(filename);
  2246. X        return NULL;
  2247. X    }
  2248. X
  2249. X    return filename;
  2250. }
  2251. X
  2252. #define MACHINE        1
  2253. #define LOGIN        2
  2254. #define PASSWORD    3
  2255. #define ACCOUNT        4
  2256. #define MACDEF        5
  2257. X
  2258. #ifdef USE_PROTOTYPES
  2259. int netrc_token(FILE *fp)
  2260. #else
  2261. int netrc_token(fp)
  2262. FILE    *fp;
  2263. #endif
  2264. {
  2265. X    char    keyword[MAXPATHLEN + 1];
  2266. X    int        ch, lastchar;
  2267. X
  2268. X    for (;;) {
  2269. X        if (fscanf(fp,"%s", keyword) == EOF)
  2270. X            return EOF;
  2271. X        if (!strcmp(keyword, "machine"))
  2272. X            return MACHINE;
  2273. X        if (!strcmp(keyword, "login"))
  2274. X            return LOGIN;
  2275. X        if (!strcmp(keyword, "password"))
  2276. X            return PASSWORD;
  2277. X        if (!strcmp(keyword, "macdef")) {
  2278. X            lastchar = 'e';
  2279. X            ch = 'f';
  2280. X            do {
  2281. X                lastchar = ch;
  2282. X                ch = getc(fp);
  2283. X            } while (ch != EOF && (ch != '\n' && lastchar != '\n'));
  2284. X        }
  2285. X    }
  2286. }
  2287. X
  2288. X
  2289. #ifdef USE_PROTOTYPES
  2290. void    host_append_netrc_proc(void)
  2291. #else
  2292. void    host_append_netrc_proc()
  2293. #endif
  2294. {
  2295. X    FILE     *fp;
  2296. X    char    machine[MAXHOSTNAMELEN + 1];
  2297. X    char    login[MAXHOSTNAMELEN + 1];
  2298. X    char    password[MAXPASSWORDLEN+ 1];
  2299. X    int        foundmachine=0;
  2300. X
  2301. X    if ((fp = fopen(netrc_filename, "r")) == NULL) {
  2302. X        footer_message("%s exists but can not be read.", 
  2303. SHAR_EOF
  2304. true || echo 'restore of host_list.c failed'
  2305. fi
  2306. echo 'End of  part 9'
  2307. echo 'File host_list.c is continued in part 10'
  2308. echo 10 > _shar_seq_.tmp
  2309. exit 0
  2310. -- 
  2311. Senior Systems Scientist        mail: dcmartin@msi.com
  2312. Molecular Simulations, Inc.        uucp: uunet!dcmartin
  2313. 796 North Pastoria Avenue        at&t: 408/522-9236
  2314. Sunnyvale, California 94086        fax: 408/732-0831
  2315.