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

  1. Path: uunet!sun-barr!ames!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: v18i086: Ftptool 4.3 (XVIEW), Part04/12
  5. Message-ID: <1992Aug18.153610.28729@msi.com>
  6. Date: 18 Aug 92 15:36:10 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: 2211
  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 86
  16. Archive-name: ftptool-4.3/part04
  17.  
  18. #!/bin/sh
  19. # this is part.04 (part 4 of a multipart archive)
  20. # do not concatenate these parts, unpack them in order with /bin/sh
  21. # file lex.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" != 4; 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 lex.c'
  37. else
  38. echo 'x - continuing file lex.c'
  39. sed 's/^X//' << 'SHAR_EOF' >> 'lex.c' &&
  40. struct yysvf yysvec[] = {
  41. 0,    0,    0,
  42. yycrank+-1,    0,        0,    
  43. yycrank+-20,    yysvec+1,    0,    
  44. yycrank+0,    0,        yyvstop+1,
  45. yycrank+3,    0,        yyvstop+3,
  46. yycrank+0,    yysvec+4,    yyvstop+6,
  47. yycrank+4,    0,        yyvstop+8,
  48. yycrank+1,    0,        yyvstop+10,
  49. yycrank+1,    0,        yyvstop+12,
  50. yycrank+1,    0,        yyvstop+14,
  51. yycrank+8,    0,        yyvstop+16,
  52. yycrank+10,    0,        yyvstop+18,
  53. yycrank+1,    0,        yyvstop+20,
  54. yycrank+17,    0,        yyvstop+22,
  55. yycrank+3,    0,        yyvstop+24,
  56. yycrank+10,    0,        yyvstop+26,
  57. yycrank+2,    0,        0,    
  58. yycrank+5,    0,        0,    
  59. yycrank+16,    0,        0,    
  60. yycrank+21,    0,        0,    
  61. yycrank+23,    0,        0,    
  62. yycrank+25,    0,        0,    
  63. yycrank+28,    0,        0,    
  64. yycrank+25,    0,        0,    
  65. yycrank+18,    0,        0,    
  66. yycrank+36,    0,        0,    
  67. yycrank+33,    0,        0,    
  68. yycrank+2,    0,        0,    
  69. yycrank+34,    0,        0,    
  70. yycrank+0,    0,        yyvstop+28,
  71. yycrank+27,    0,        0,    
  72. yycrank+38,    0,        0,    
  73. yycrank+30,    0,        0,    
  74. yycrank+4,    0,        0,    
  75. yycrank+30,    0,        0,    
  76. yycrank+39,    0,        0,    
  77. yycrank+48,    0,        0,    
  78. yycrank+38,    0,        0,    
  79. yycrank+50,    0,        0,    
  80. yycrank+38,    0,        0,    
  81. yycrank+52,    0,        0,    
  82. yycrank+42,    0,        0,    
  83. yycrank+40,    0,        0,    
  84. yycrank+52,    0,        0,    
  85. yycrank+0,    0,        yyvstop+30,
  86. yycrank+47,    0,        0,    
  87. yycrank+43,    0,        0,    
  88. yycrank+0,    0,        yyvstop+32,
  89. yycrank+0,    0,        yyvstop+34,
  90. yycrank+0,    0,        yyvstop+36,
  91. yycrank+0,    0,        yyvstop+38,
  92. yycrank+1,    0,        0,    
  93. yycrank+0,    0,        yyvstop+40,
  94. yycrank+0,    0,        yyvstop+42,
  95. yycrank+0,    0,        yyvstop+44,
  96. yycrank+54,    0,        0,    
  97. yycrank+0,    0,        yyvstop+46,
  98. yycrank+0,    0,        yyvstop+48,
  99. yycrank+40,    0,        0,    
  100. yycrank+0,    0,        yyvstop+50,
  101. 0,    0,    0};
  102. struct yywork *yytop = yycrank+128;
  103. struct yysvf *yybgin = yysvec+1;
  104. char yymatch[] = {
  105. 00  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  106. 01  ,011 ,012 ,01  ,01  ,01  ,01  ,01  ,
  107. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  108. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  109. 011 ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  110. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  111. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  112. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  113. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  114. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  115. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  116. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  117. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  118. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  119. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  120. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  121. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  122. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  123. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  124. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  125. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  126. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  127. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  128. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  129. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  130. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  131. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  132. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  133. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  134. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  135. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  136. 01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
  137. 0};
  138. char yyextra[] = {
  139. 0,0,0,0,0,0,0,0,
  140. 0,0,0,0,0,0,0,0,
  141. 0};
  142. /*    Copyright (c) 1989 AT&T    */
  143. /*      All Rights Reserved      */
  144. X
  145. /*    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T    */
  146. /*    The copyright notice above does not evidence any       */
  147. /*    actual or intended publication of such source code.    */
  148. X
  149. #ident    "@(#)RELEASE VERSION SC2.0 3/27/92"
  150. X
  151. int yylineno =1;
  152. # define YYU(x) x
  153. # define NLSTATE yyprevious=YYNEWLINE
  154. char yytext[YYLMAX];
  155. struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp;
  156. char yysbuf[YYLMAX];
  157. char *yysptr = yysbuf;
  158. int *yyfnd;
  159. extern struct yysvf *yyestate;
  160. int yyprevious = YYNEWLINE;
  161. #if defined(__cplusplus) || defined(__STDC__)
  162. int yylook(void)
  163. #else
  164. yylook()
  165. #endif
  166. {
  167. X    register struct yysvf *yystate, **lsp;
  168. X    register struct yywork *yyt;
  169. X    struct yysvf *yyz;
  170. X    int yych, yyfirst;
  171. X    struct yywork *yyr;
  172. # ifdef LEXDEBUG
  173. X    int debug;
  174. # endif
  175. X    char *yylastch;
  176. X    /* start off machines */
  177. # ifdef LEXDEBUG
  178. X    debug = 0;
  179. # endif
  180. X    yyfirst=1;
  181. X    if (!yymorfg)
  182. X        yylastch = yytext;
  183. X    else {
  184. X        yymorfg=0;
  185. X        yylastch = yytext+yyleng;
  186. X        }
  187. X    for(;;){
  188. X        lsp = yylstate;
  189. X        yyestate = yystate = yybgin;
  190. X        if (yyprevious==YYNEWLINE) yystate++;
  191. X        for (;;){
  192. # ifdef LEXDEBUG
  193. X            if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1);
  194. # endif
  195. X            yyt = yystate->yystoff;
  196. X            if(yyt == yycrank && !yyfirst){  /* may not be any transitions */
  197. X                yyz = yystate->yyother;
  198. X                if(yyz == 0)break;
  199. X                if(yyz->yystoff == yycrank)break;
  200. X                }
  201. X            *yylastch++ = yych = input();
  202. X            if(yylastch > &yytext[YYLMAX]) {
  203. X                fprintf(yyout,"Input string too long, limit %d\n",YYLMAX);
  204. X                exit(1);
  205. X            }
  206. X            yyfirst=0;
  207. X        tryagain:
  208. # ifdef LEXDEBUG
  209. X            if(debug){
  210. X                fprintf(yyout,"char ");
  211. X                allprint(yych);
  212. X                putchar('\n');
  213. X                }
  214. # endif
  215. X            yyr = yyt;
  216. X            if ( (int)yyt > (int)yycrank){
  217. X                yyt = yyr + yych;
  218. X                if (yyt <= yytop && yyt->verify+yysvec == yystate){
  219. X                    if(yyt->advance+yysvec == YYLERR)    /* error transitions */
  220. X                        {unput(*--yylastch);break;}
  221. X                    *lsp++ = yystate = yyt->advance+yysvec;
  222. X                    if(lsp > &yylstate[YYLMAX]) {
  223. X                        fprintf(yyout,"Input string too long, limit %d\n",YYLMAX);
  224. X                        exit(1);
  225. X                    }
  226. X                    goto contin;
  227. X                    }
  228. X                }
  229. # ifdef YYOPTIM
  230. X            else if((int)yyt < (int)yycrank) {        /* r < yycrank */
  231. X                yyt = yyr = yycrank+(yycrank-yyt);
  232. # ifdef LEXDEBUG
  233. X                if(debug)fprintf(yyout,"compressed state\n");
  234. # endif
  235. X                yyt = yyt + yych;
  236. X                if(yyt <= yytop && yyt->verify+yysvec == yystate){
  237. X                    if(yyt->advance+yysvec == YYLERR)    /* error transitions */
  238. X                        {unput(*--yylastch);break;}
  239. X                    *lsp++ = yystate = yyt->advance+yysvec;
  240. X                    if(lsp > &yylstate[YYLMAX]) {
  241. X                        fprintf(yyout,"Input string too long, limit %d\n",YYLMAX);
  242. X                        exit(1);
  243. X                    }
  244. X                    goto contin;
  245. X                    }
  246. X                yyt = yyr + YYU(yymatch[yych]);
  247. # ifdef LEXDEBUG
  248. X                if(debug){
  249. X                    fprintf(yyout,"try fall back character ");
  250. X                    allprint(YYU(yymatch[yych]));
  251. X                    putchar('\n');
  252. X                    }
  253. # endif
  254. X                if(yyt <= yytop && yyt->verify+yysvec == yystate){
  255. X                    if(yyt->advance+yysvec == YYLERR)    /* error transition */
  256. X                        {unput(*--yylastch);break;}
  257. X                    *lsp++ = yystate = yyt->advance+yysvec;
  258. X                    if(lsp > &yylstate[YYLMAX]) {
  259. X                        fprintf(yyout,"Input string too long, limit %d\n",YYLMAX);
  260. X                        exit(1);
  261. X                    }
  262. X                    goto contin;
  263. X                    }
  264. X                }
  265. X            if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){
  266. # ifdef LEXDEBUG
  267. X                if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1);
  268. # endif
  269. X                goto tryagain;
  270. X                }
  271. # endif
  272. X            else
  273. X                {unput(*--yylastch);break;}
  274. X        contin:
  275. # ifdef LEXDEBUG
  276. X            if(debug){
  277. X                fprintf(yyout,"state %d char ",yystate-yysvec-1);
  278. X                allprint(yych);
  279. X                putchar('\n');
  280. X                }
  281. # endif
  282. X            ;
  283. X            }
  284. # ifdef LEXDEBUG
  285. X        if(debug){
  286. X            fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1);
  287. X            allprint(yych);
  288. X            putchar('\n');
  289. X            }
  290. # endif
  291. X        while (lsp-- > yylstate){
  292. X            *yylastch-- = 0;
  293. X            if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){
  294. X                yyolsp = lsp;
  295. X                if(yyextra[*yyfnd]){        /* must backup */
  296. X                    while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){
  297. X                        lsp--;
  298. X                        unput(*yylastch--);
  299. X                        }
  300. X                    }
  301. X                yyprevious = YYU(*yylastch);
  302. X                yylsp = lsp;
  303. X                yyleng = yylastch-yytext+1;
  304. X                yytext[yyleng] = 0;
  305. # ifdef LEXDEBUG
  306. X                if(debug){
  307. X                    fprintf(yyout,"\nmatch ");
  308. X                    sprint(yytext);
  309. X                    fprintf(yyout," action %d\n",*yyfnd);
  310. X                    }
  311. # endif
  312. X                return(*yyfnd++);
  313. X                }
  314. X            unput(*yylastch);
  315. X            }
  316. X        if (yytext[0] == 0  /* && feof(yyin) */)
  317. X            {
  318. X            yysptr=yysbuf;
  319. X            return(0);
  320. X            }
  321. X        yyprevious = yytext[0] = input();
  322. X        if (yyprevious>0)
  323. X            output(yyprevious);
  324. X        yylastch=yytext;
  325. # ifdef LEXDEBUG
  326. X        if(debug)putchar('\n');
  327. # endif
  328. X        }
  329. X    }
  330. #if defined(__cplusplus) || defined(__STDC__)
  331. int yyback(int *p, int m)
  332. #else
  333. yyback(p, m)
  334. X    int *p;
  335. #endif
  336. {
  337. X    if (p==0) return(0);
  338. X    while (*p) {
  339. X        if (*p++ == m)
  340. X            return(1);
  341. X    }
  342. X    return(0);
  343. }
  344. X    /* the following are only used in the lex library */
  345. #if defined(__cplusplus) || defined(__STDC__)
  346. int yyinput(void)
  347. #else
  348. yyinput()
  349. #endif
  350. {
  351. X    return(input());
  352. X    }
  353. #if defined(__cplusplus) || defined(__STDC__)
  354. void yyoutput(int c)
  355. #else
  356. yyoutput(c)
  357. X  int c; 
  358. #endif
  359. {
  360. X    output(c);
  361. X    }
  362. #if defined(__cplusplus) || defined(__STDC__)
  363. void yyunput(int c)
  364. #else
  365. yyunput(c)
  366. X   int c; 
  367. #endif
  368. {
  369. X    unput(c);
  370. X    }
  371. SHAR_EOF
  372. echo 'File lex.c is complete' &&
  373. chmod 0644 lex.c ||
  374. echo 'restore of lex.c failed'
  375. Wc_c="`wc -c < 'lex.c'`"
  376. test 11513 -eq "$Wc_c" ||
  377.     echo 'lex.c: original size 11513, current size' "$Wc_c"
  378. rm -f _shar_wnt_.tmp
  379. fi
  380. # ============= readdir.c ==============
  381. if test -f 'readdir.c' -a X"$1" != X"-c"; then
  382.     echo 'x - skipping readdir.c (File already exists)'
  383.     rm -f _shar_wnt_.tmp
  384. else
  385. > _shar_wnt_.tmp
  386. echo 'x - extracting readdir.c (Text)'
  387. sed 's/^X//' << 'SHAR_EOF' > 'readdir.c' &&
  388. #include "ftptool.h"
  389. X
  390. extern int dirlastmtime;
  391. X
  392. #ifdef USE_PROTOTYPES
  393. struct dirlist *read_local_dir(char *dirname)
  394. #else
  395. struct dirlist *read_local_dir(dirname)
  396. char    *dirname;
  397. #endif
  398. {
  399. X    struct dirlist *head;
  400. X    DIR    *dir;
  401. X    struct dirent *dp;
  402. X    struct passwd *psswd;
  403. X    struct group *grp;
  404. X    struct stat buf;
  405. X    time_t    curtime;
  406. X    time_t    time();
  407. X    char    date[DATELEN];
  408. X    struct tm *tm;
  409. X    char    owner[20];
  410. X    char    group[20];
  411. X    
  412. X
  413. X    head = new_dirlist("", "", "", "", 0, (size_t)0);
  414. X    if (head == NULL) {
  415. X        fprintf(stderr, "Out of memory\n");
  416. X        goto out;
  417. X    }
  418. X
  419. X    if (lstat(dirname, &buf) == -1) {
  420. X        local_footer_message("Could not stat directory %s.", 
  421. X            dirname, (char *)NULL);
  422. X        goto out;
  423. X    }
  424. X
  425. X    dirlastmtime = buf.st_mtime;
  426. X
  427. X    if ((dir = opendir(dirname)) == NULL) {
  428. X        local_footer_message("Could not open directory %s.", 
  429. X            dirname, (char *)NULL);
  430. X        goto out;
  431. X    }
  432. X    curtime = time((time_t *)NULL);
  433. X
  434. X
  435. X    while (dp = readdir(dir)) {
  436. X        if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
  437. X            continue;
  438. X        bzero((char *)&buf, sizeof(buf));
  439. X        if (lstat(dp->d_name, &buf) == -1) {
  440. X            buf.st_mode = 0;
  441. X            buf.st_uid = 0;
  442. X            buf.st_gid = 0;
  443. X            buf.st_size = 0;
  444. X            buf.st_mtime = 0;
  445. X        }
  446. X        tm = localtime(&buf.st_mtime);
  447. X        if ((curtime - buf.st_mtime) < (6 * 30 * 24 * 60 * 60))
  448. X            strftime(date, sizeof(date), "%h %e %H:%M", tm);
  449. X        else
  450. X            strftime(date, sizeof(date), "%h %e  %Y", tm);
  451. X
  452. X        /* determine user and group ids */
  453. X        psswd = getpwuid(buf.st_uid);
  454. X        if (psswd == NULL) {
  455. X            sprintf(owner, "%d", buf.st_uid);
  456. X        } else
  457. X            strcpy(owner, psswd->pw_name);
  458. X
  459. X        grp = getgrgid(buf.st_gid);
  460. X        if (grp == NULL) {
  461. X            sprintf(group, "%d", buf.st_gid);
  462. X        } else
  463. X            strcpy(group, grp->gr_name);
  464. X
  465. X        /* if a link, format name to 'name -> link' as ftp would */
  466. X        if (S_ISLNK(buf.st_mode)) {
  467. X            char    *linkvalue;
  468. X            int        nbytes;
  469. X
  470. X            linkvalue = (char *)malloc(MAXPATHLEN + 1);
  471. X            if ((nbytes = readlink(dp->d_name,linkvalue,(int)buf.st_size))== -1)
  472. X                strcpy(linkvalue, "unknown");
  473. X            else
  474. X                linkvalue[nbytes] = '\0';
  475. X            sprintf(scratch, "%s -> %s", dp->d_name, linkvalue);
  476. X            free(linkvalue);
  477. X        } else
  478. X            strcpy(scratch, dp->d_name);
  479. X        if (add_dirname(head, scratch, date, owner, group, buf.st_mode, 
  480. X            (size_t)buf.st_size, local_sort_mode, local_sort_direction) == NULL)
  481. X            goto out;
  482. X    }
  483. X    closedir(dir);
  484. X
  485. out:
  486. X    if (head)
  487. X        return (head);
  488. X    return NULL;
  489. }
  490. X
  491. #ifdef USE_PROTOTYPES
  492. struct dirlist *read_remote_dir(char *dname)
  493. #else
  494. struct dirlist *read_remote_dir(dname)
  495. char    *dname;
  496. #endif
  497. {
  498. X    struct dirlist *head = NULL;
  499. X    int    old_unix, temp_non_unix = 0;
  500. X    FILE    *din = NULL, *open_remote_ls();
  501. X    char    *next_remote_line();
  502. X
  503. restart:
  504. X    old_unix = temp_non_unix;
  505. X    head = new_dirlist("", "", "", "", 0, (size_t)0);
  506. X    if (head == NULL) {
  507. X        fprintf(stderr, "Out of memory\n");
  508. X        goto out;
  509. X    }
  510. X    /* read the remote directory, adding files and directories to a list */
  511. X    /* send dir command */
  512. X    if (non_unix || temp_non_unix) {
  513. X        din = open_remote_ls(1);
  514. X    } else {
  515. X        din = open_remote_ls(0);
  516. X    }
  517. X    if (din == NULL) {
  518. X        /* always have .. */
  519. X        return head;
  520. X    }
  521. X
  522. X    for (;;) {
  523. X        if (next_remote_line(din) == NULL)
  524. X            goto out;
  525. X        if (!strncmp(response_line, "226", 3) || !strncmp(response_line,"250", 3)) {
  526. X            /* done */
  527. X            log_message(response_line);
  528. X            break;
  529. X        }
  530. X        /* ignore blank lines */
  531. X        if (*response_line == '\n' || *response_line == '\0')
  532. X            continue;
  533. X        /* VMS also prints the directory name */
  534. X        if (dname && !strncmp(response_line, dname, strlen(dname))
  535. X            && (response_line[strlen(dname)] == '\n')) {
  536. X            continue;
  537. X        }
  538. X        /* VMS goofy total line before 226 */
  539. X        if (!strncmp(response_line, "Total of", 8))
  540. X            continue;
  541. X        if (parse_line(head, response_line, &temp_non_unix)) {
  542. X            goto out;
  543. X        }
  544. X        if (old_unix != temp_non_unix) {
  545. X            /* start over */
  546. X            free_dirlist(head);
  547. X            head = NULL;
  548. X            while (getc(din) != -1)
  549. X                /* NULL */ ;
  550. X            close_remote_ls(din);
  551. X            din = NULL;
  552. X            goto restart;
  553. X        }
  554. X    }
  555. out:
  556. X    if (din)
  557. X        close_remote_ls(din);
  558. X    if (timedout) {
  559. X        if (head)
  560. X            free_dirlist(head);
  561. X        timeout_disconnect();
  562. X        return NULL;
  563. X    }
  564. X    if (head)
  565. X        return (head);
  566. X    return (NULL);
  567. }
  568. X
  569. X
  570. #define NULLCHECK() if (*curr == '\0') {non_unix = 1; goto restart;}
  571. X
  572. #ifdef USE_PROTOTYPES
  573. int    parse_line(struct dirlist *head, char *line, int *temp_non_unix)
  574. #else
  575. int    parse_line(head, line, temp_non_unix)
  576. struct dirlist *head;
  577. char    *line;
  578. int        *temp_non_unix;
  579. #endif
  580. {
  581. X    /* default mode is a symbolic link. This is so if you don't have */
  582. X    /* UNIX PERMS, it can be either a file or a directory. Maybe.  */
  583. X    mode_t    mode = S_IFLNK;
  584. X    int        intmode;
  585. X    char    *curr;
  586. X    static char    date[20];
  587. X    static char    month[10];
  588. X    static char    day[10];
  589. X    static char    timeyear[10];
  590. X    static char    name[MAXPATHLEN + 1];
  591. X    static char owner[25];
  592. X    static char group[25];
  593. X    size_t    size = (size_t)-1;
  594. X    char    *tmp;
  595. X    char    *dirtmp;
  596. X
  597. X    month[0] = '\0';
  598. X    day[0] = '\0';
  599. X    timeyear[0] = '\0';
  600. X    date[0] = '\0';
  601. X    name[0] = '\0';
  602. X    strcpy(owner, "unknown");
  603. X    strcpy(group, "unknown");
  604. restart: /* really only get here if non-unix machine */
  605. X    /* Or, actually, assume that if the first character is upper case, */
  606. X    /* it is non-unix (since ls never puts upper case as the type */
  607. X    /* And it appears that the filename is all the characters at the */
  608. X    /* start of the line up to but not including white space on VMS and */
  609. X    /* tops20. This would make it functional, partially at least */
  610. X    /* Also, may need to turn on temp_non_unix_mode, so that cd is */
  611. X    /* possible on anything, since we can't tell if they're directories. */
  612. X    /* or not */
  613. X    curr=line;
  614. X
  615. X    if (non_unix || *temp_non_unix) {
  616. X    /*
  617. X        if (curr[1] == ':') {
  618. X            ftperr = ftp_error(' ', "Permission denied");
  619. X            footer_message(ftperr, (char *)NULL);
  620. X            return 0;
  621. X        } else if (!strncmp(curr, ". unreadable", 12)) {
  622. X            footer_message(". unreadable", (char *)NULL);
  623. X            return 0;
  624. X        }
  625. X    */
  626. X        while (*curr && isspace(*curr))
  627. X            curr++;
  628. X        tmp = name;
  629. X        while (*curr && !isspace(*curr)) {
  630. X            *tmp = *curr;
  631. X            tmp++;
  632. X            curr++;
  633. X        }
  634. X        *tmp = '\0';
  635. X        curr++;
  636. X        if (add_dirname(head, name, "unknown", "unknown", "unknown", S_IFLNK, 
  637. X            (size_t)-1, remote_sort_mode, remote_sort_direction) == NULL) {
  638. X            fprintf(stderr, "add_dirname failed!\n");
  639. X            return 1;
  640. X        }
  641. X        return 0;
  642. X    }
  643. X    dirtmp = dir_pattern;
  644. X    while (*dirtmp != '\0') {
  645. X        NULLCHECK();
  646. X        switch(*dirtmp) {
  647. X        case ' ':
  648. X            while (isspace(*curr))
  649. X                curr++;
  650. X            break;
  651. X        case SKIP:
  652. X            while (!isspace(*curr))
  653. X                curr++;
  654. X            break;
  655. X        case PERMS:
  656. X            intmode = perms(curr, temp_non_unix);
  657. X            if (intmode == 0)
  658. X                return 0;
  659. X            else if (intmode == -1)
  660. X                goto restart;
  661. X            mode = (mode_t)intmode;
  662. X            while (!isspace(*curr))
  663. X                curr++;
  664. X            break;
  665. X        case LINKS:
  666. X            /* dump link count */
  667. X            while (isdigit(*curr))
  668. X                curr++;
  669. X            break;
  670. X        case USER:
  671. X            /*
  672. X             * this should be the user name, surrounded by white space
  673. X             */
  674. X            tmp = owner;
  675. X            while (!isspace(*curr)) {
  676. X                *tmp = *curr;
  677. X                tmp++;
  678. X                curr++;
  679. X            }
  680. X            *tmp = '\0';
  681. X            break;
  682. X        case GROUP:
  683. X            /*
  684. X             * this should be the group name, surrounded by white space
  685. X             */
  686. X            tmp = group;
  687. X            while (!isspace(*curr)) {
  688. X                *tmp = *curr;
  689. X                tmp++;
  690. X                curr++;
  691. X            }
  692. X            *tmp = '\0';
  693. X            break;
  694. X        case SIZE:
  695. X            /* first test only true for UNIX case, where we have */
  696. X            /* seen the perms */
  697. X            if (S_ISCHR(mode) || S_ISBLK(mode)) {
  698. X                /* size is actually major, minor */
  699. X                while (isdigit(*curr) || *curr == ',')
  700. X                    curr++;
  701. X                NULLCHECK();
  702. X                while (isspace(*curr))
  703. X                    curr++;
  704. X                NULLCHECK();
  705. X                while (isdigit(*curr))
  706. X                    curr++;
  707. X                size = -1;
  708. X            } else {
  709. X                sscanf(curr, "%d", &size);
  710. X                while (isdigit(*curr))
  711. X                    curr++;
  712. X            }
  713. X            break;
  714. X        case MONTH:
  715. X            tmp = month;
  716. X            while (isalpha(*curr)) {
  717. X                *tmp = *curr;
  718. X                tmp++;
  719. X                curr++;
  720. X            }
  721. X            *tmp = '\0';
  722. X            break;
  723. X        case DAY:
  724. X            tmp = day;
  725. X            while (isdigit(*curr)) {
  726. X                *tmp = *curr;
  727. X                tmp++;
  728. X                curr++;
  729. X            }
  730. X            *tmp = '\0';
  731. X            break;
  732. X        case TIME:
  733. X            tmp = timeyear;
  734. X            while (isdigit(*curr) || (*curr == ':')) {
  735. X                *tmp = *curr;
  736. X                tmp++;
  737. X                curr++;
  738. X            }
  739. X            *tmp = '\0';
  740. X            break;
  741. X        case NAME:
  742. X        case LOWERNAME:
  743. X            tmp = name;
  744. X            /* the following test makes sure we have seen the PERMS field */
  745. X            /* if not, the permissions will still be 0. symlinks normally */
  746. X            /* have 777 for permissions */
  747. X            if (mode != S_IFLNK && S_ISLNK(mode)) {
  748. X                while (*curr && *curr != '\n') {
  749. X                    *tmp = *curr;
  750. X                    tmp++;
  751. X                    curr++;
  752. X                }
  753. X            } else {
  754. X                while (!isspace(*curr) && *curr != ';') {
  755. X                    *tmp = *curr;
  756. X                    tmp++;
  757. X                    curr++;
  758. X                }
  759. X                /* VMS */
  760. X                if (*curr == ';') {
  761. X                    while (!isspace(*curr))
  762. X                        curr++;
  763. X                }
  764. X            }
  765. X            *tmp = '\0';
  766. X            if (*dirtmp == LOWERNAME) {
  767. X                for (tmp = name; *tmp != '\0'; tmp++)
  768. X                    if (isupper(*tmp))
  769. X                        *tmp = tolower(*tmp);
  770. X            }
  771. X            break;
  772. X        default:
  773. X            if (*dirtmp == *curr) {
  774. X                curr++;
  775. X            } else {
  776. X                *temp_non_unix=1;
  777. X                goto restart;
  778. X            }
  779. X        }
  780. X        dirtmp++;
  781. X    }
  782. X    sprintf(date, "%s %2s %5s", month, day, timeyear);
  783. X
  784. X    if (add_dirname(head, name, date, owner, group, mode, size, 
  785. X        remote_sort_mode, remote_sort_direction) == NULL) {
  786. X        fprintf(stderr, "add_dirname failed!\n");
  787. X        return 1;
  788. X    }
  789. X    return 0;
  790. }
  791. X
  792. X
  793. /*
  794. X take the dir_parse string, in the form of
  795. X    PERMS LINKS USER GROUP SIZE MONTH DAY TIME NAME
  796. X and return a NULL-terminated array of character values of the above
  797. X
  798. X The values would be control-characters, so they are not in danger
  799. X of being typed (right!). A ' ' represents whitespace, any other character
  800. X must be matched exactly.
  801. X */
  802. X
  803. char    *lex_string;
  804. X
  805. #ifdef USE_PROTOTYPES
  806. char *dir_parse_to_pattern(char *dir_parse)
  807. #else
  808. char *dir_parse_to_pattern(dir_parse)
  809. char    *dir_parse;
  810. #endif
  811. {
  812. X    static char pattern[MAXPATHLEN+1];
  813. X    char    *nextpos = pattern;
  814. X    char    *s;
  815. X    int        token;
  816. X    int        found_bitmask = 0;
  817. X    int        yylex();
  818. X    static char *tokval[] = {
  819. X        "",
  820. X        "PERMS",
  821. X        "LINKS",
  822. X        "USER",
  823. X        "GROUP",
  824. X        "SIZE",
  825. X        "MONTH",
  826. X        "DAY",
  827. X        "TIME",
  828. X        "NAME",
  829. X        "SKIP",
  830. X        "NONUNIX",
  831. X        "LOWERNAME",
  832. X    };
  833. X
  834. X    lex_string = strdup(dir_parse);
  835. X    if (lex_string == NULL) {
  836. X        fprintf(stderr, "Out of memory\n");
  837. X        exit(1);
  838. X    }
  839. X    s = lex_string;
  840. X    while (token = yylex()) {
  841. X        *nextpos = (char)token;
  842. X        nextpos++;
  843. X        if (token <= MAXTOKENS) {
  844. X            if (found_bitmask & (1 << token)) {
  845. X                fprintf(stderr, "Duplicate token %s in DIR template.\n", 
  846. X                    tokval[token]);
  847. X                free(s);
  848. X                return NULL;
  849. X            }
  850. X            if (token != SKIP)
  851. X                found_bitmask |= 1 << token;
  852. X        }
  853. X    }
  854. X    *nextpos = '\0';
  855. X    free(s);
  856. X    if ((found_bitmask & (1 << NONUNIX)) != 0) {
  857. X        pattern[0] = (char)NONUNIX;
  858. X        return pattern;
  859. X    }
  860. X    /* make sure that we have a filename, at least */
  861. X    if ((found_bitmask & (1 << NAME)) == 0  
  862. X        && (found_bitmask & (1 << LOWERNAME)) == 0) {
  863. X        fprintf(stderr,"You must specify a NAME token in your parse field.\n");
  864. X        return NULL;
  865. X    }
  866. X    return pattern;
  867. }
  868. X
  869. #undef NULLCHECK
  870. #define NULLCHECK() if (*s == '\0') {*temp_non_unix = 1; return -1;}
  871. X
  872. #ifdef USE_PROTOTYPES
  873. int perms(char *s, int *temp_non_unix)
  874. #else
  875. int perms(s, temp_non_unix)
  876. char    *s;
  877. int        *temp_non_unix;
  878. #endif
  879. {
  880. X    int mode;
  881. X
  882. X    switch (*s) {
  883. X    case 'd':
  884. X            mode = S_IFDIR;
  885. X            break;
  886. X    case 'F':
  887. X    case 'f':
  888. X    case 'm': /* Cray and convex migrated files */
  889. X    case '-':
  890. X            mode = S_IFREG;
  891. X            break;
  892. X    case 'l':
  893. X            mode = S_IFLNK;
  894. X            break;
  895. X    case 'b':
  896. X            mode = S_IFBLK;
  897. X            break;
  898. X    case 'c':
  899. X            mode = S_IFCHR;
  900. X            break;
  901. X    case 's':
  902. X            mode = S_IFSOCK;
  903. X            break;
  904. X    case 'p':
  905. X            mode = S_IFIFO;
  906. X            break;
  907. X    case 'D':
  908. X            mode = S_IFDIR;
  909. X            break;
  910. X    case 'B':
  911. X            mode = S_IFBLK;
  912. X            break;
  913. X    case 'C':
  914. X            mode = S_IFCHR;
  915. X            break;
  916. X    case 'S':
  917. X            mode = S_IFSOCK;
  918. X            break;
  919. X    case 'P':
  920. X            mode = S_IFIFO;
  921. X            break;
  922. X    case 't':
  923. X            if (!strncmp(s, "total", 5))
  924. X                return 0;
  925. X            /* fall through */
  926. #ifdef notdef
  927. X    case '.':
  928. X        if (s[1] == ':') {
  929. X            ftperr = ftp_error(' ', "Permission denied");
  930. X            footer_message(ftperr, (char *)NULL);
  931. X            return 0;
  932. X        } else if (!strncmp(s, ". unreadable", 12)) {
  933. X            footer_message(". unreadable", (char *)NULL);
  934. X            return 0;
  935. X        }
  936. #endif
  937. X    default:
  938. X            *temp_non_unix = 1;
  939. #ifdef notdef
  940. X            sprintf(scratch, "%s (non-UNIX?)", 
  941. X                (char *)xv_get(base_window.frame, XV_LABEL));
  942. X            xv_set(base_window.frame, XV_LABEL, scratch, NULL);
  943. X            remote_sort_mode = SORTBYNAME;
  944. X            xv_set(tool_property_window.directory_lists.remote_sort, 
  945. X                PANEL_VALUE, remote_sort_mode,
  946. X                PANEL_INACTIVE, TRUE,
  947. X                NULL);
  948. X            set_remote_sort_order(SORTBYNAME);
  949. #endif
  950. X            return -1;
  951. X            break;
  952. X    }
  953. X
  954. X    s++;
  955. X    if (*s == ' ' || *s == '\0' || *s == '\t')
  956. X        return mode; /* OK to not have permissions */
  957. X    NULLCHECK();
  958. X    /*
  959. X     Determine permissions.
  960. X     */
  961. X    if (*s++ == 'r')
  962. X        mode |= S_IRUSR;
  963. X    NULLCHECK();
  964. X    if (*s++ == 'w')
  965. X        mode |= S_IWUSR;
  966. X    NULLCHECK();
  967. X    if (*s == 'x' || *s == 's')
  968. X        mode |= S_IXUSR;
  969. X    s++;
  970. X    NULLCHECK();
  971. X    if (*s++ == 'r')
  972. X        mode |= S_IRGRP;
  973. X    NULLCHECK();
  974. X    if (*s++ == 'w')
  975. X        mode |= S_IWGRP;
  976. X    NULLCHECK();
  977. X    if (*s == 'x' || *s == 's')
  978. X        mode |= S_IXGRP;
  979. X    s++;
  980. X    NULLCHECK();
  981. X    if (*s++ == 'r')
  982. X        mode |= S_IROTH;
  983. X    NULLCHECK();
  984. X    if (*s++ == 'w')
  985. X        mode |= S_IWOTH;
  986. X    NULLCHECK();
  987. X    if (*s == 'x' || *s == 't')
  988. X        mode |= S_IXOTH;
  989. X    s++;
  990. X    NULLCHECK();
  991. X    return mode;
  992. }
  993. SHAR_EOF
  994. chmod 0644 readdir.c ||
  995. echo 'restore of readdir.c failed'
  996. Wc_c="`wc -c < 'readdir.c'`"
  997. test 13063 -eq "$Wc_c" ||
  998.     echo 'readdir.c: original size 13063, current size' "$Wc_c"
  999. rm -f _shar_wnt_.tmp
  1000. fi
  1001. # ============= change_dir.c ==============
  1002. if test -f 'change_dir.c' -a X"$1" != X"-c"; then
  1003.     echo 'x - skipping change_dir.c (File already exists)'
  1004.     rm -f _shar_wnt_.tmp
  1005. else
  1006. > _shar_wnt_.tmp
  1007. echo 'x - extracting change_dir.c (Text)'
  1008. sed 's/^X//' << 'SHAR_EOF' > 'change_dir.c' &&
  1009. #include "ftptool.h"
  1010. X
  1011. int dirlastmtime;
  1012. X
  1013. #ifdef USE_PROTOTYPES
  1014. int    checkdir(char *dirname)
  1015. #else
  1016. int    checkdir(dirname)
  1017. char    *dirname;
  1018. #endif
  1019. {
  1020. X    struct stat buf;
  1021. X
  1022. X    if (lstat(dirname, &buf) == -1) {
  1023. X        if (errno == ENOENT) 
  1024. X            return ENOENT;
  1025. X        return 1;
  1026. X    }
  1027. X
  1028. X    if (buf.st_mtime > local_dircache.first->mtime) {
  1029. X        return 1;
  1030. X    }
  1031. X    return 0;
  1032. }
  1033. X
  1034. #ifdef USE_PROTOTYPES
  1035. int dirwasmodified(void)
  1036. #else
  1037. int dirwasmodified()
  1038. #endif
  1039. {
  1040. X    int    error;
  1041. X    char    *dirname = local_dircache.first->name;
  1042. X
  1043. X    if (cache_lookup(&local_dircache, dirname) == NULL)
  1044. X        return 0;
  1045. X    /* first now */
  1046. X
  1047. X    error = checkdir(dirname);
  1048. X    if (error == ENOENT) {
  1049. X        if (xv_get(local_window.frame, XV_SHOW) == FALSE) {
  1050. X            xv_set(local_window.frame, 
  1051. X                XV_SHOW, TRUE, 
  1052. X                NULL);
  1053. X        }
  1054. X        local_footer_message("Current directory was deleted. Changing to /tmp.",
  1055. X            (char *)NULL);
  1056. X        clear_slist(local_window.list);
  1057. X        xv_set(local_window.list, 
  1058. X            XV_SHOW, TRUE, 
  1059. X            NULL);
  1060. X        dircache_delete(&local_dircache, dirname);
  1061. X        change_local_dir("/tmp", 0);
  1062. X        return 1;
  1063. X    } else if (error != 0) {
  1064. X        local_footer_message("Current directory was modified. Rereading.", 
  1065. X            (char *)NULL);
  1066. X        if (xv_get(local_window.frame, XV_SHOW) == FALSE) {
  1067. X            xv_set(local_window.frame, 
  1068. X                XV_SHOW, TRUE, 
  1069. X                NULL);
  1070. X        }
  1071. X        clear_slist(local_window.list);
  1072. X        xv_set(local_window.list, 
  1073. X            XV_SHOW, TRUE, 
  1074. X            NULL);
  1075. X        dircache_delete(&local_dircache, dirname);
  1076. X        change_local_dir(dirname, 0);
  1077. X        return 1;
  1078. X    }
  1079. X    return 0;
  1080. }
  1081. X
  1082. #ifdef USE_PROTOTYPES
  1083. int change_local_dir(char *s, int force)
  1084. #else
  1085. int change_local_dir(s, force)
  1086. char    *s;
  1087. int        force;
  1088. #endif
  1089. {
  1090. X    static char    cld[MAXPATHLEN + 2];
  1091. X    extern char *sys_errlist[];
  1092. X    struct dirlist *head = NULL;
  1093. X    int        wasinactive;
  1094. X    int        rval = 0;
  1095. X    int        error;
  1096. X    char    *dir = NULL;
  1097. #if defined(SYSV) || defined(SYSV386)
  1098. X    struct statvfs fsbuf;
  1099. #else
  1100. X    struct statfs fsbuf;
  1101. #endif
  1102. X
  1103. X    wasinactive = xv_get(local_window.list, PANEL_INACTIVE);
  1104. X    if (wasinactive == FALSE) {
  1105. X        xv_set(local_window.list, 
  1106. X            PANEL_INACTIVE, TRUE, 
  1107. X            NULL);
  1108. X    }
  1109. X    cursor_busy();
  1110. X    local_footer_message("Reading directory...", (char *)NULL);
  1111. X    local_right_footer_message("", (char *)NULL);
  1112. X    dir = expand_dirname(s);
  1113. X    if (dir == NULL) {
  1114. X        fprintf(stderr, "out of memory\n");
  1115. X        goto out;
  1116. X    }
  1117. X    if (chdir(dir) == -1) {
  1118. X        if (errno == ENOENT) {
  1119. X            if (rval = ask_make_dir(dir)) { 
  1120. X                if (rval == -1) {
  1121. X                    local_footer_message("", (char *)NULL);
  1122. X                    /* user canceled. */
  1123. X                    goto out;
  1124. X                }
  1125. X                local_footer_message("Could not make directory: %s",
  1126. X                        sys_errlist[rval], (char *)NULL);
  1127. X                goto out;
  1128. X            }
  1129. X            if (chdir(dir) == -1) {
  1130. X                rval = errno;
  1131. X                local_footer_message("Could not change to directory: %s",
  1132. X                        sys_errlist[rval], (char *)NULL);
  1133. X                goto out;
  1134. X            }
  1135. X        } else {
  1136. X            rval = errno;
  1137. X            local_footer_message("Could not change to directory: %s",
  1138. X                    sys_errlist[rval], (char *)NULL);
  1139. X            goto out;
  1140. X        }
  1141. X    }
  1142. X
  1143. X    clear_slist(local_window.list);
  1144. X
  1145. X    local_list_ndirs = 0;
  1146. X    local_list_nfiles = 0;
  1147. X    local_list_nothers = 0;
  1148. X    change_local_list_menu();
  1149. X
  1150. X    if (getcwd(cld, sizeof(cld)) == NULL) {
  1151. X        /* Failure */
  1152. X        goto out;
  1153. X    }
  1154. X
  1155. X    xv_set(local_window.directory, 
  1156. X        PANEL_VALUE, cld, 
  1157. X        NULL);
  1158. X
  1159. #if defined(SYSV) || defined(SYSV386)
  1160. X    if (statvfs(cld, &fsbuf) == -1) {
  1161. X        sprintf(scratch, "statvfs failed: %s", sys_errlist[errno]);
  1162. X    } 
  1163. #else
  1164. X    if (statfs(cld, &fsbuf) == -1) {
  1165. X        sprintf(scratch, "statfs failed: %s", sys_errlist[errno]);
  1166. X    }
  1167. #endif
  1168. X    else {
  1169. X        sprintf(scratch, "%d Kbytes (%d%% free)", 
  1170. X            (int)(fsbuf.f_bsize / 1024.0 * fsbuf.f_bavail), 
  1171. X            (int)(100.0 * fsbuf.f_bavail / 
  1172. X                (fsbuf.f_blocks - (fsbuf.f_bfree - fsbuf.f_bavail))));
  1173. X    }
  1174. X    xv_set(local_window.space,
  1175. X        PANEL_LABEL_STRING, scratch,
  1176. X        NULL);
  1177. X
  1178. X    if (force)
  1179. X        dircache_delete(&local_dircache, cld);
  1180. X
  1181. X    head = cache_lookup(&local_dircache, cld);
  1182. X    if (head == NULL) {
  1183. X        /* cache miss */
  1184. X        head = read_local_dir(cld);
  1185. X        if (head == NULL) {
  1186. X            fprintf(stderr, "Out of memory\n");
  1187. X            rval = 1;
  1188. X            goto out;
  1189. X        }
  1190. X        /* add to cache */
  1191. X        dircache_add(&local_dircache, cld, head);
  1192. X        local_dircache.first->mtime = dirlastmtime;
  1193. X    } else if (error = checkdir(cld)) {
  1194. X        dircache_delete(&local_dircache, cld);
  1195. X        if (error == ENOENT) {
  1196. X            local_footer_message("%s does not exist.", cld, (char *)NULL);
  1197. X            goto out;
  1198. X        }
  1199. X        /* else reread */
  1200. X        head = read_local_dir(cld);
  1201. X        if (head == NULL) {
  1202. X            fprintf(stderr, "Out of memory\n");
  1203. X            rval = 1;
  1204. X            goto out;
  1205. X        }
  1206. X        /* add to cache */
  1207. X        dircache_add(&local_dircache, cld, head);
  1208. X        local_dircache.first->mtime = dirlastmtime;
  1209. X    }
  1210. X
  1211. X
  1212. X    dirlist_to_slist(local_window.list, head);
  1213. X
  1214. X    local_show_items();
  1215. X    local_footer_message("", (char *)NULL);
  1216. out:
  1217. X    cursor_normal();
  1218. X
  1219. X    if (dir)
  1220. X        free(dir);
  1221. X    if (wasinactive == FALSE) {
  1222. X        xv_set(local_window.list, 
  1223. X            PANEL_INACTIVE, FALSE, 
  1224. X            NULL);
  1225. X    }
  1226. X    XFlush(dpy);
  1227. X    return rval;
  1228. }
  1229. X
  1230. #ifdef USE_PROTOTYPES
  1231. int change_remote_dir(char *s, int force)
  1232. #else
  1233. int change_remote_dir(s, force)
  1234. char    *s;
  1235. int    force;
  1236. #endif
  1237. {
  1238. X    char    *ftperr;
  1239. X    char    crd[MAXPATHLEN + 1];
  1240. X    struct dirlist *head = NULL;
  1241. X    int        wasinactive;
  1242. X    char    *dir=NULL;
  1243. X    int        rval=0;
  1244. X    int        pwdfailed = 0;
  1245. X    char    *quote;
  1246. X
  1247. X    wasinactive = xv_get(base_window.list, PANEL_INACTIVE);
  1248. X    if (wasinactive == FALSE) {
  1249. X        xv_set(base_window.list, 
  1250. X            PANEL_INACTIVE, TRUE, 
  1251. X            NULL);
  1252. X    }
  1253. X    if (ping_server())
  1254. X        goto out;
  1255. X    cursor_busy();
  1256. X    /* send cd command */
  1257. X    footer_message("Reading directory...", (char *)NULL);
  1258. X    right_footer_message("", (char *)NULL);
  1259. X    dir = strdup(s);
  1260. X    if (dir == NULL)
  1261. X        goto out;
  1262. X    if (!strcmp(dir, "..")) {
  1263. X        if (up_one_level())
  1264. X            goto out;
  1265. X    } else if (strcmp(dir, ".")) {
  1266. X        extern int code;
  1267. X
  1268. X        code = -1;
  1269. X        command("CWD %s", dir);
  1270. X        /* success */
  1271. X        /*
  1272. X         250 CWD command successful.
  1273. X         */
  1274. X        /* failure */
  1275. X        /*
  1276. X         550 k: No such file or directory
  1277. X         */
  1278. X         if (code == 550) {
  1279. X            ftperr = index(response_line, ':');
  1280. X            if (ftperr == NULL) {
  1281. X                rval = 1;
  1282. X                goto out;
  1283. X            }
  1284. X            if (!strncmp(ftperr, ": Not a directory.", 18)) {
  1285. X                footer_message("%s is not a directory.", dir, (char *)NULL);
  1286. X                rval = ENOTDIR;
  1287. X                goto out;
  1288. X            }
  1289. X            if (rval = ask_make_remote_dir(dir)) {
  1290. X                if (rval == -1) {
  1291. X                    footer_message("", (char *)NULL);
  1292. X                    /* user cancelled */
  1293. X                    goto out;
  1294. X                }
  1295. X                footer_message("Could not make directory.", (char *)NULL);
  1296. X                goto out;
  1297. X            }
  1298. X            command("CWD %s", dir);
  1299. X            if (code == 550) {
  1300. X                sprintf(scratch, "%s: No such file or directory.", dir);
  1301. X                ftperr = ftp_error(' ', scratch);
  1302. X                footer_message(ftperr, (char *)NULL);
  1303. X                rval = 1;
  1304. X                goto out;
  1305. X            }
  1306. X        } 
  1307. X    }
  1308. X
  1309. X    clear_slist(base_window.list);
  1310. X
  1311. X    remote_list_ndirs = 0;
  1312. X    remote_list_nfiles = 0;
  1313. X    remote_list_nothers = 0;
  1314. X
  1315. X    change_remote_list_menu();
  1316. X
  1317. X    /* set current directory */
  1318. X    if (command("PWD") == ERROR && code == 500) {
  1319. X        /*
  1320. X        footer_message("pwd not recognized.", (char *)NULL);
  1321. X        */
  1322. X        /* try quote xpwd */
  1323. X        if (command("XPWD") == ERROR && code == 500) {
  1324. X            footer_message("pwd and xpwd not recognized.", (char *)NULL);
  1325. X            pwdfailed = 1;
  1326. X        }
  1327. X    }
  1328. X    /* response */
  1329. X    /*
  1330. X     25[17] "/" is current directory.
  1331. X     257 PWD: "/Print_Output" is current directory.
  1332. X     * 
  1333. X     * Skip to first double-quote, since they seem to have that.
  1334. X     */
  1335. X    crd[0] = '\0';
  1336. X    if (pwdfailed) {
  1337. X        force = 1;
  1338. X    } else if (!strncmp(response_line, "257", 3)) {
  1339. X        quote = strchr(response_line, '\"');
  1340. X        if (quote != NULL)
  1341. X            sscanf (quote, "\"%[^\"]\"", crd);
  1342. X    } else if (!strncmp(response_line, "251", 3)) {
  1343. X        quote = strchr(response_line, '\"');
  1344. X        if (quote != NULL)
  1345. X            sscanf (response_line, "\"%[^\"]\"", crd);
  1346. X    } else {
  1347. X        footer_message("pwd or xpwd returned bad response.", (char *)NULL);
  1348. X        force = 1;
  1349. X    }
  1350. X    xv_set(base_window.directory, 
  1351. X        PANEL_VALUE, crd, 
  1352. X        NULL);
  1353. X
  1354. X    if (force)
  1355. X        dircache_delete(&remote_dircache, crd);
  1356. X    head = cache_lookup(&remote_dircache, crd);
  1357. X    if (head == NULL) {
  1358. X        /* cache miss */
  1359. X        head = read_remote_dir(crd);
  1360. X        if (head == NULL) {
  1361. X            rval = ETIMEDOUT;
  1362. X            goto out;
  1363. X        }
  1364. X        dircache_add(&remote_dircache, crd, head);
  1365. X    }
  1366. X
  1367. X
  1368. X    dirlist_to_slist(base_window.list, head);
  1369. X
  1370. X    remote_show_items();
  1371. out:
  1372. X    if (rval == 0)
  1373. X        footer_message("", (char *)NULL);
  1374. X    cursor_normal();
  1375. X    if (dir)
  1376. X        free(dir);
  1377. /*
  1378. X    if (head)
  1379. X        free_dirlist(head);
  1380. */
  1381. X    if (wasinactive == FALSE) {
  1382. X        xv_set(base_window.list, 
  1383. X            PANEL_INACTIVE, FALSE, 
  1384. X            NULL);
  1385. X    }
  1386. X    if (timedout)
  1387. X        timeout_disconnect();
  1388. X    XFlush(dpy);
  1389. X    return rval;
  1390. }
  1391. X
  1392. #ifdef USE_PROTOTYPES
  1393. char *expand_dirname(char *arg)
  1394. #else
  1395. char *expand_dirname(arg)
  1396. char    *arg;
  1397. #endif
  1398. {
  1399. X    char     *slash;
  1400. X    char    *lastpart = "";
  1401. X    char    *path;
  1402. X    struct passwd *pwd;
  1403. X    char    *firstpart="";
  1404. X    char    *s;
  1405. X
  1406. X    if (arg[0] == '/' || (arg[0] != '~' && arg[0] != '$')) {
  1407. X        path = strdup(arg);
  1408. X        return path;
  1409. X    }
  1410. X    s = strdup(arg);
  1411. X    if (s == NULL)
  1412. X        return NULL;
  1413. X    if (slash = index(s, '/')) {
  1414. X        *slash = 0;
  1415. X        lastpart = slash + 1;
  1416. X    }
  1417. X    switch (s[0]) {
  1418. X    case '~': /* ~ or ~user */
  1419. X        if (s[1] == '\0') {
  1420. X            pwd = getpwuid(getuid());
  1421. X            if (pwd == NULL) {
  1422. X                footer_message("You are unknown to the system.", (char *)NULL);
  1423. X                free(s);
  1424. X                return NULL;
  1425. X            }
  1426. X        } else {
  1427. X            pwd = getpwnam(&s[1]);
  1428. X            if (pwd == NULL) {
  1429. X                footer_message("Unknown user %s.", &s[1], (char *)NULL);
  1430. X                free(s);
  1431. X                return NULL;
  1432. X            }
  1433. X        }
  1434. X        firstpart = pwd->pw_dir;
  1435. X        break;
  1436. X    case '$': /* Environment variable */
  1437. X        firstpart = getenv(&s[1]);
  1438. X        if (firstpart == NULL) {
  1439. X            footer_message("Unknown variable %s.", &s[1], (char *)NULL);
  1440. X            free(s);
  1441. X            return NULL;
  1442. X        }
  1443. X        break;
  1444. X    }
  1445. X    path = (char *)malloc((unsigned int)(strlen(firstpart)+1+strlen(lastpart)+1));
  1446. X    if (path == NULL) {
  1447. X        footer_message("Memory allocation failed.", (char *)NULL);
  1448. X        free(s);
  1449. X        return NULL;
  1450. X    }
  1451. X    if (lastpart[0] != '\0')
  1452. X        sprintf(path, "%s/%s", firstpart, lastpart);
  1453. X    else
  1454. X        strcpy(path, firstpart);
  1455. X    free(s);
  1456. X    return (path);
  1457. }
  1458. X
  1459. #ifdef USE_PROTOTYPES
  1460. int    delete_local_dir(char *dir)
  1461. #else
  1462. int    delete_local_dir(dir)
  1463. char    *dir;
  1464. #endif
  1465. {
  1466. X    struct dirlist *head = NULL;
  1467. X    struct dirlist *tmp;
  1468. X    extern char *sys_errlist[];
  1469. X    int    rval = 0;
  1470. X
  1471. X    if (chdir(dir) == -1) {
  1472. X        local_footer_message("Can not change to %s: %s", 
  1473. X            dir, sys_errlist[errno], (char *)NULL);
  1474. X        return errno;
  1475. X    }
  1476. X    head = read_local_dir(".");
  1477. X    if (head == NULL) {
  1478. X        fprintf(stderr, "Out of memory\n");
  1479. X        rval = ENOMEM;
  1480. X        goto out;
  1481. X    }
  1482. X    for (tmp = head->next; tmp != NULL; tmp = tmp->next)
  1483. X        if (S_ISDIR(tmp->mode)) {
  1484. X            if (rval = delete_local_dir(tmp->name))
  1485. X                goto out;
  1486. X        } else if (rval = delete_local_file(tmp->name, unlink))
  1487. X                goto out;
  1488. out:
  1489. X    if (head)
  1490. X        free_dirlist(head);
  1491. X    if (chdir("..") == -1) {
  1492. X        local_footer_message("Can not cd ..: %s", 
  1493. X            sys_errlist[errno], (char *)NULL);
  1494. X        return errno;
  1495. X    }
  1496. X    /* delete parent */
  1497. X    if (rval == 0)
  1498. X        rval = delete_local_file(dir, rmdir);
  1499. X    return rval;
  1500. }
  1501. X
  1502. #ifdef USE_PROTOTYPES
  1503. int delete_local_file(char *filename, int (*deletefunc)(const char *filename))
  1504. #else
  1505. int delete_local_file(filename, deletefunc)
  1506. char    *filename;
  1507. int        (*deletefunc)();
  1508. #endif
  1509. {
  1510. X    int    answer;
  1511. X    extern char *sys_errlist[];
  1512. #ifdef XVIEW3
  1513. X    Xv_notice notice;
  1514. #endif
  1515. X
  1516. X    if (confirmdeletes) {
  1517. X        sprintf(scratch, "Really delete %s?", filename);
  1518. #ifdef XVIEW3
  1519. X        notice = xv_create(base_window.panel, NOTICE,
  1520. X            NOTICE_MESSAGE_STRINGS,
  1521. X                scratch,
  1522. X                NULL,
  1523. X            NOTICE_BUTTON_YES, "Cancel",
  1524. X            NOTICE_BUTTON_NO, "Delete",
  1525. X            NOTICE_STATUS, &answer,
  1526. X            XV_SHOW, TRUE,
  1527. X            NULL);
  1528. X        xv_destroy_safe(notice);
  1529. #else
  1530. X        answer =  notice_prompt(base_window.panel, NULL,
  1531. X            NOTICE_MESSAGE_STRINGS,
  1532. X                scratch,
  1533. X                NULL,
  1534. X            NOTICE_BUTTON_YES, "Cancel",
  1535. X            NOTICE_BUTTON_NO, "Delete",
  1536. X            NULL);
  1537. #endif
  1538. X    } else
  1539. X        answer = NOTICE_NO;
  1540. X
  1541. X    if (answer == NOTICE_NO) {
  1542. X        local_footer_message("Deleting %s", filename, (char *)NULL);
  1543. X        if ((*deletefunc)(filename) == -1) {
  1544. X            local_footer_message("delete %s failed: %s", filename,
  1545. X                sys_errlist[errno], (char *)NULL);
  1546. X            return 1;
  1547. X        }
  1548. X        return 0;
  1549. X    }
  1550. X    return 1; /* deletion aborted */
  1551. }
  1552. X
  1553. #ifdef USE_PROTOTYPES
  1554. int    delete_remote_dir(char *dir)
  1555. #else
  1556. int    delete_remote_dir(dir)
  1557. char    *dir;
  1558. #endif
  1559. {
  1560. X    struct dirlist *head = NULL;
  1561. X    struct dirlist *tmp;
  1562. X    int    rval = 0;
  1563. X    char    *ftperr;
  1564. X
  1565. X    if (command("CWD %s", dir) == ERROR && code == 550) {
  1566. X        sprintf(scratch, "Can not change to %s", dir);
  1567. X        ftperr = ftp_error(' ', scratch);
  1568. X        footer_message(ftperr, (char *)NULL);
  1569. X        return 1;
  1570. X    }
  1571. X    head = read_remote_dir((char *)NULL);
  1572. X    if (head == NULL) {
  1573. X        rval = ENOMEM;
  1574. X        goto out;
  1575. X    }
  1576. X    for (tmp = head->next; tmp != NULL; tmp = tmp->next)
  1577. X        if (S_ISDIR(tmp->mode)) {
  1578. X            if (rval = delete_remote_dir(tmp->name))
  1579. X                goto out;
  1580. X        } else if (rval = delete_remote_file(tmp->name, "DELE"))
  1581. X                goto out;
  1582. out:
  1583. X    if (head)
  1584. X        free_dirlist(head);
  1585. X    if (up_one_level())
  1586. X        footer_message("Can not cd ..", (char *)NULL);
  1587. X        
  1588. X    /* delete parent */
  1589. X    if (rval == 0)
  1590. X        rval = delete_remote_file(dir, "RMD");
  1591. X    return rval;
  1592. }
  1593. X
  1594. #ifdef USE_PROTOTYPES
  1595. int delete_remote_file(char *filename, char *deletecmd)
  1596. #else
  1597. int delete_remote_file(filename, deletecmd)
  1598. char    *filename;
  1599. char    *deletecmd;
  1600. #endif
  1601. {
  1602. X    char    *ftperr;
  1603. X    int    answer;
  1604. #ifdef XVIEW3
  1605. X    Xv_notice notice;
  1606. #endif
  1607. X
  1608. X    if (confirmdeletes) {
  1609. X        sprintf(scratch, "Really delete %s?", filename);
  1610. #ifdef XVIEW3
  1611. X        notice = xv_create(base_window.panel, NOTICE,
  1612. X            NOTICE_MESSAGE_STRINGS,
  1613. X                scratch,
  1614. X                NULL,
  1615. X            NOTICE_BUTTON_YES, "Cancel",
  1616. X            NOTICE_BUTTON_NO, "Delete",
  1617. X            NOTICE_STATUS, &answer,
  1618. X            XV_SHOW, TRUE,
  1619. X            NULL);
  1620. X        xv_destroy_safe(notice);
  1621. #else
  1622. X        answer = notice_prompt(base_window.panel, NULL,
  1623. X            NOTICE_MESSAGE_STRINGS,
  1624. X                scratch,
  1625. X                NULL,
  1626. X            NOTICE_BUTTON_YES, "Cancel",
  1627. X            NOTICE_BUTTON_NO, "Delete",
  1628. X            NULL);
  1629. #endif
  1630. X    } else
  1631. X        answer = NOTICE_NO;
  1632. X
  1633. X    if (answer == NOTICE_NO) {
  1634. X        footer_message("Deleting %s", filename, (char *)NULL);
  1635. X        sprintf(scratch, "%s %s", deletecmd, filename);
  1636. X        if (command(scratch) == ERROR) {
  1637. X            sprintf(scratch, "delete %s failed", filename);
  1638. X            ftperr = ftp_error(' ', scratch);
  1639. X            footer_message(ftperr, (char *)NULL);
  1640. X            return 1;
  1641. X        }
  1642. X        return 0;
  1643. X    }
  1644. X    return 1; /* deletion aborted */
  1645. }
  1646. X
  1647. #ifdef USE_PROTOTYPES
  1648. int up_one_level(void)
  1649. #else
  1650. int up_one_level()
  1651. #endif
  1652. {
  1653. X    if (command("CDUP") == ERROR && code == 500) {
  1654. X        if (!strncmp(response_line, "500", 3)) {
  1655. X            /*
  1656. X            footer_message("cdup not recognized.", (char *)NULL);
  1657. X            */
  1658. X            /* try quote xcup */
  1659. X            if (command("XCUP") == ERROR && code == 500) {
  1660. X                /* try cd .. */
  1661. X                code = -1;
  1662. X                if (command("CWD ..") == ERROR && code == 550) {
  1663. X                    footer_message("cdup, xcup, and 'cd ..' failed. Try manually.", (char *)NULL);
  1664. X                    return 1;
  1665. X                }
  1666. X            }
  1667. X        }
  1668. X    } 
  1669. X    return 0;
  1670. }
  1671. SHAR_EOF
  1672. chmod 0644 change_dir.c ||
  1673. echo 'restore of change_dir.c failed'
  1674. Wc_c="`wc -c < 'change_dir.c'`"
  1675. test 14252 -eq "$Wc_c" ||
  1676.     echo 'change_dir.c: original size 14252, current size' "$Wc_c"
  1677. rm -f _shar_wnt_.tmp
  1678. fi
  1679. # ============= event.c ==============
  1680. if test -f 'event.c' -a X"$1" != X"-c"; then
  1681.     echo 'x - skipping event.c (File already exists)'
  1682.     rm -f _shar_wnt_.tmp
  1683. else
  1684. > _shar_wnt_.tmp
  1685. echo 'x - extracting event.c (Text)'
  1686. sed 's/^X//' << 'SHAR_EOF' > 'event.c' &&
  1687. #include "ftptool.h"
  1688. X
  1689. #ifdef USE_PROTOTYPES
  1690. void    local_cd_select(void)
  1691. #else
  1692. void    local_cd_select()
  1693. #endif
  1694. {
  1695. X    int     nitems, selection, row;
  1696. X    struct dirlist *tmp;
  1697. X
  1698. X    local_footer_message("", (char *)NULL);
  1699. X    /* check to see that only one item is selected, and it is a directory */
  1700. X    nitems = xv_get(local_window.list, PANEL_LIST_NROWS);
  1701. X
  1702. X    selection = 0;
  1703. X    for (row = 0; row < nitems; row++)
  1704. X        if (xv_get(local_window.list, PANEL_LIST_SELECTED, row)) {
  1705. X            tmp = (struct dirlist *)xv_get(local_window.list, 
  1706. X                PANEL_LIST_CLIENT_DATA, row);
  1707. X            if (S_ISDIR(tmp->mode)) {
  1708. X                selection = row;
  1709. X                break;
  1710. X            }
  1711. X        }
  1712. X
  1713. X    tmp = (struct dirlist *)xv_get(local_window.list, 
  1714. X        PANEL_LIST_CLIENT_DATA, selection);
  1715. X
  1716. X    xv_set(local_window.list, 
  1717. X        PANEL_LIST_SELECT, selection, FALSE, 
  1718. X        NULL);
  1719. X    change_local_dir(tmp->name, 0);
  1720. }
  1721. X
  1722. #ifdef USE_PROTOTYPES
  1723. void    local_cd_text(void)
  1724. #else
  1725. void    local_cd_text()
  1726. #endif
  1727. {
  1728. X    char    *dir;
  1729. X
  1730. X    local_footer_message("", (char *)NULL);
  1731. X    dir = (char *)xv_get(local_window.directory, PANEL_VALUE);
  1732. X    if (*dir == '\0') {
  1733. X        local_footer_message("Please type in a pathname first.",(char *)NULL);
  1734. X        return;
  1735. X    }
  1736. X    change_local_dir(dir, 0);
  1737. }
  1738. X
  1739. #ifdef USE_PROTOTYPES
  1740. void    local_cd_dotdot(void)
  1741. #else
  1742. void    local_cd_dotdot()
  1743. #endif
  1744. {
  1745. X    local_footer_message("", (char *)NULL);
  1746. X    change_local_dir("..", 0);
  1747. }
  1748. X
  1749. #ifdef USE_PROTOTYPES
  1750. void    remote_cd_select(void)
  1751. #else
  1752. void    remote_cd_select()
  1753. #endif
  1754. {
  1755. X    int     nitems, selection, row;
  1756. X    struct dirlist *tmp;
  1757. X
  1758. X    footer_message("", (char *)NULL);
  1759. X    /* check to see that only one item is selected, and it is a directory */
  1760. X    nitems = xv_get(base_window.list, PANEL_LIST_NROWS);
  1761. X    selection = 0;
  1762. X    for (row = 0; row < nitems; row++)
  1763. X        if (xv_get(base_window.list, PANEL_LIST_SELECTED, row)) {
  1764. X            tmp = (struct dirlist *)xv_get(base_window.list, 
  1765. X                PANEL_LIST_CLIENT_DATA, row);
  1766. X            if (non_unix || S_ISDIR(tmp->mode)) {
  1767. X                selection = row;
  1768. X                break;
  1769. X            }
  1770. X        }
  1771. X
  1772. X    tmp = (struct dirlist *)xv_get(base_window.list, 
  1773. X        PANEL_LIST_CLIENT_DATA, selection);
  1774. X
  1775. X    xv_set(base_window.list, 
  1776. X        PANEL_LIST_SELECT, selection, FALSE, 
  1777. X        NULL);
  1778. X    which_remote_file = strdup(tmp->name);
  1779. X    if (which_remote_file == NULL) {
  1780. X        fprintf(stderr, "Out of memory.\n");
  1781. X        return;
  1782. X    }
  1783. X    dowhat = DOREMOTECD;
  1784. X    notify_stop();
  1785. }
  1786. X
  1787. #ifdef USE_PROTOTYPES
  1788. void    remote_cd_text(void)
  1789. #else
  1790. void    remote_cd_text()
  1791. #endif
  1792. {
  1793. X    footer_message("", (char *)NULL);
  1794. X    which_remote_file = (char *)xv_get(base_window.directory, PANEL_VALUE);
  1795. X    if (*which_remote_file == '\0') {
  1796. X        footer_message("Please type in a pathname first.",(char *)NULL);
  1797. X        return;
  1798. X    }
  1799. X    if (!non_unix)
  1800. X        which_remote_file = expand_dirname(which_remote_file);
  1801. X    else
  1802. X        which_remote_file = strdup(which_remote_file);
  1803. X    if (which_remote_file == NULL)
  1804. X        return;
  1805. X    dowhat = DOREMOTECD;
  1806. X    notify_stop();
  1807. }
  1808. X
  1809. #ifdef USE_PROTOTYPES
  1810. void    remote_cd_dotdot(void)
  1811. #else
  1812. void    remote_cd_dotdot()
  1813. #endif
  1814. {
  1815. X    footer_message("", (char *)NULL);
  1816. X    which_remote_file = strdup("..");
  1817. X    if (which_remote_file == NULL) {
  1818. X        fprintf(stderr,"Out of memory.\n");
  1819. X        return;
  1820. X    }
  1821. X    dowhat = DOREMOTECD;
  1822. X    notify_stop();
  1823. }
  1824. X
  1825. #ifdef USE_PROTOTYPES
  1826. Notify_value destroy_func(Notify_client client, Destroy_status status)
  1827. #else
  1828. Notify_value destroy_func(client, status)
  1829. Notify_client    client;
  1830. Destroy_status    status;
  1831. #endif
  1832. {
  1833. X    int    answer;
  1834. X    static int triedonce;
  1835. #ifdef XVIEW3
  1836. X    Xv_notice notice;
  1837. #endif
  1838. X
  1839. X    if (status == DESTROY_SAVE_YOURSELF) {
  1840. X        /* save state. Not a death */
  1841. X        return NOTIFY_DONE;
  1842. X    }
  1843. X    if (connected) {
  1844. #ifdef XVIEW3
  1845. X        notice = xv_create(base_window.panel, NOTICE,
  1846. X            NOTICE_MESSAGE_STRINGS,
  1847. X                "You are still connected.",
  1848. X                NULL,
  1849. X            NOTICE_BUTTON_YES,  "Cancel",
  1850. X            NOTICE_BUTTON_NO,    "Quit anyway",
  1851. X            NOTICE_STATUS, &answer,
  1852. X            XV_SHOW, TRUE,
  1853. X            NULL);
  1854. X        xv_destroy_safe(notice);
  1855. #else
  1856. X        answer = notice_prompt(base_window.panel, NULL,
  1857. X            NOTICE_MESSAGE_STRINGS,
  1858. X                "You are still connected.",
  1859. X                NULL,
  1860. X            NOTICE_BUTTON_YES,  "Cancel",
  1861. X            NOTICE_BUTTON_NO,    "Quit anyway",
  1862. X            NULL);
  1863. #endif
  1864. X        if (answer == NOTICE_YES)
  1865. X            return (Notify_value)notify_veto_destroy(client);
  1866. X    }
  1867. X    if (list_changed) {
  1868. X        if (status == DESTROY_CHECKING) {
  1869. #ifdef XVIEW3
  1870. X            notice = xv_create(base_window.panel, NOTICE,
  1871. X                NOTICE_MESSAGE_STRINGS,
  1872. X                    "Your host list has changed. You can",
  1873. X                    NULL,
  1874. X                NOTICE_BUTTON_YES,  "Save changes",
  1875. X                NOTICE_BUTTON,      "Quit anyway", 2,
  1876. X                NOTICE_BUTTON,      "Cancel quit", 3,
  1877. X                NOTICE_STATUS, &answer,
  1878. X                XV_SHOW, TRUE,
  1879. X                NULL);
  1880. X            xv_destroy_safe(notice);
  1881. #else
  1882. X            answer = notice_prompt(base_window.panel, NULL,
  1883. X                NOTICE_MESSAGE_STRINGS,
  1884. X                    "Your host list has changed. You can",
  1885. X                    NULL,
  1886. X                NOTICE_BUTTON_YES,  "Save changes",
  1887. X                NOTICE_BUTTON,      "Quit anyway", 2,
  1888. X                NOTICE_BUTTON,      "Cancel quit", 3,
  1889. X                NULL);
  1890. #endif
  1891. X            triedonce = 1;
  1892. X        } else if (!triedonce) {
  1893. #ifdef XVIEW3
  1894. X            notice = xv_create(base_window.panel, NOTICE,
  1895. X                NOTICE_MESSAGE_STRINGS,
  1896. X                    "Your host list has changed. You can",
  1897. X                    NULL,
  1898. X                NOTICE_BUTTON_YES,  "Save changes",
  1899. X                NOTICE_BUTTON,      "Quit anyway", 2,
  1900. X                NOTICE_STATUS, &answer,
  1901. X                XV_SHOW, TRUE,
  1902. X                NULL);
  1903. X            xv_destroy_safe(notice);
  1904. #else
  1905. X            answer = notice_prompt(base_window.panel, NULL,
  1906. X                NOTICE_MESSAGE_STRINGS,
  1907. X                    "Your host list has changed. You can",
  1908. X                    NULL,
  1909. X                NOTICE_BUTTON_YES,  "Save changes",
  1910. X                NOTICE_BUTTON,      "Quit anyway", 2,
  1911. X                NULL);
  1912. #endif
  1913. X        } else {
  1914. X            /* perhaps something has gone wrong. */
  1915. X            answer = 2;
  1916. X        }
  1917. X
  1918. X        switch (answer) {
  1919. X        case NOTICE_YES:
  1920. X            list_changed=0;
  1921. X            timestamped = 0;
  1922. X            write_ftptoolrc();
  1923. X            break;
  1924. X        case 2:
  1925. X            /* avoid saving timestamps, if they are there */
  1926. X            timestamped = 0;
  1927. X            break;
  1928. X        case 3:
  1929. X            return (Notify_value)notify_veto_destroy(client);
  1930. X            break;
  1931. X        }
  1932. X    }
  1933. X    if (timestamped) {
  1934. X        timestamped = 0;
  1935. X        write_ftptoolrc();
  1936. X    }
  1937. X
  1938. X    quit_ftp();
  1939. X
  1940. X    dowhat = DOQUIT;
  1941. X
  1942. X    switch(status) {
  1943. X    case DESTROY_CHECKING:
  1944. X        break;
  1945. X    case DESTROY_CLEANUP:
  1946. X        return notify_next_destroy_func(client, status);
  1947. X        break;
  1948. X    case DESTROY_PROCESS_DEATH:
  1949. X        exit(1);
  1950. X        break;
  1951. X    case DESTROY_SAVE_YOURSELF:
  1952. X        fprintf(stderr, "Impossible DESTROY_SAVE_YOURSELF event in last switch of destroy_func.\n");
  1953. X        break;
  1954. X    }
  1955. X    return NOTIFY_DONE;
  1956. }
  1957. X
  1958. #ifdef USE_PROTOTYPES
  1959. Notify_value sig_func(void)
  1960. #else
  1961. Notify_value sig_func()
  1962. #endif
  1963. {
  1964. X    if (xv_destroy_safe(base_window.frame) == XV_OK) {
  1965. X        quit_ftp();
  1966. X        exit(1);
  1967. X    }
  1968. X    return NOTIFY_DONE;
  1969. }
  1970. X
  1971. #ifdef USE_PROTOTYPES
  1972. void cycle_busy_icon(void)
  1973. #else
  1974. void cycle_busy_icon()
  1975. #endif
  1976. {
  1977. X    static int i;
  1978. X
  1979. X    xv_set(frame_icon, 
  1980. X        ICON_IMAGE, busy_glyphs[i], 
  1981. X        ICON_TRANSPARENT, TRUE,
  1982. X        NULL);
  1983. X    i++;
  1984. X    if (i == nbusyicons)
  1985. X        i = 0;
  1986. }
  1987. X
  1988. static struct itimerval busy_itimer = {
  1989. X    {0, 200000,},
  1990. X    {0, 200000,}
  1991. };
  1992. X
  1993. #ifdef USE_PROTOTYPES
  1994. void start_busy_cycle(void)
  1995. #else
  1996. void start_busy_cycle()
  1997. #endif
  1998. {
  1999. X    notify_set_itimer_func(base_window.frame, (Notify_func)cycle_busy_icon, 
  2000. X        ITIMER_REAL, &busy_itimer, (struct itimerval *)NULL);
  2001. }
  2002. X
  2003. #ifdef USE_PROTOTYPES
  2004. void end_busy_cycle(void)
  2005. #else
  2006. void end_busy_cycle()
  2007. #endif
  2008. {
  2009. X    notify_set_itimer_func(base_window.frame, NOTIFY_FUNC_NULL, ITIMER_REAL,
  2010. X        &busy_itimer, (struct itimerval *)NULL);
  2011. X    xv_set(frame_icon, 
  2012. X        ICON_IMAGE, ftptool_glyph,
  2013. X        ICON_TRANSPARENT, TRUE,
  2014. X        NULL);
  2015. }
  2016. X
  2017. #ifdef USE_PROTOTYPES
  2018. void props_event_proc(Panel panel, Event *event)
  2019. #else
  2020. void props_event_proc(panel, event)
  2021. Panel    panel;
  2022. Event *event;
  2023. #endif
  2024. {
  2025. X    if (event_action(event) == ACTION_PROPS) {
  2026. X        xv_set(tool_property_window.frame, 
  2027. X            XV_SHOW, TRUE, 
  2028. X            NULL);
  2029. X    }
  2030. }
  2031. X
  2032. #ifdef USE_PROTOTYPES
  2033. void base_event_proc(Xv_Window window, Event *event)
  2034. #else
  2035. void base_event_proc(window, event)
  2036. XXv_Window    window;
  2037. Event *event;
  2038. #endif
  2039. {
  2040. X    int height;
  2041. X    int    y;
  2042. X    int    rows;
  2043. X    int    rowsize;
  2044. X    int    width;
  2045. X
  2046. X    switch(event_id(event)) {
  2047. X    case WIN_RESIZE:
  2048. X        height = xv_get(base_window.panel, XV_HEIGHT);
  2049. X        width = xv_get(base_window.panel, XV_WIDTH);
  2050. X        y = xv_get(base_window.list, PANEL_ITEM_Y);
  2051. X        rowsize = xv_get(base_window.list, PANEL_LIST_ROW_HEIGHT);
  2052. X        rows = (height - y - 45) / rowsize;
  2053. X        if (rows <= 0)
  2054. X            rows = 1;
  2055. X        xv_set(base_window.list, 
  2056. X            PANEL_LIST_DISPLAY_ROWS, rows,
  2057. X            PANEL_LIST_WIDTH, width - 30, 
  2058. X            PANEL_PAINT, PANEL_NONE,
  2059. X            NULL);
  2060. X        panel_paint(base_window.list, PANEL_CLEAR);
  2061. X        break;
  2062. X    default:
  2063. X        break;
  2064. X    }
  2065. }
  2066. X
  2067. #ifdef USE_PROTOTYPES
  2068. void resize_window(Panel panel, Panel_item list, Panel_item dismiss)
  2069. #else
  2070. void resize_window(panel, list, dismiss)
  2071. Panel    panel;
  2072. Panel_item    list;
  2073. Panel_item    dismiss;
  2074. #endif
  2075. {
  2076. X    int height;
  2077. X    int    y;
  2078. X    int    rows;
  2079. X    int    rowsize;
  2080. X    int    width;
  2081. X    Rect    *butrect;
  2082. X
  2083. X    height = xv_get(panel, XV_HEIGHT);
  2084. X    width = xv_get(panel, XV_WIDTH);
  2085. X    y = xv_get(list, PANEL_ITEM_Y);
  2086. X    rowsize = xv_get(list, PANEL_LIST_ROW_HEIGHT);
  2087. X    rows = (height - y - 45) / rowsize;
  2088. X    /* leave room for dismiss button */
  2089. X    if (!openlook_mode)
  2090. X        rows -= 1;
  2091. X    if (rows <= 0)
  2092. X        rows = 1;
  2093. X    xv_set(list, 
  2094. X        PANEL_LIST_DISPLAY_ROWS, rows,
  2095. X        PANEL_LIST_WIDTH, width - 30, 
  2096. X        PANEL_PAINT, PANEL_NONE,
  2097. X        NULL);
  2098. X    panel_paint(list, PANEL_CLEAR);
  2099. X    /* for non-openlook mode */
  2100. X    butrect = (Rect *)xv_get(dismiss, XV_RECT);
  2101. X    xv_set(dismiss,
  2102. X        XV_X, width/2 - butrect->r_width/2,
  2103. X        XV_Y, height - butrect->r_height,
  2104. X        NULL);
  2105. }
  2106. X
  2107. #ifdef USE_PROTOTYPES
  2108. void local_event_proc(Xv_Window window, Event *event)
  2109. #else
  2110. void local_event_proc(window, event)
  2111. XXv_Window    window;
  2112. Event *event;
  2113. #endif
  2114. {
  2115. X    switch(event_id(event)) {
  2116. X    case WIN_RESIZE:
  2117. X        resize_window(local_window.panel, local_window.list,
  2118. X            local_window.dismiss);
  2119. X        break;
  2120. X    default:
  2121. X        break;
  2122. X    }
  2123. }
  2124. X
  2125. #ifdef USE_PROTOTYPES
  2126. void schedule_event_proc(Xv_Window window, Event *event)
  2127. #else
  2128. void schedule_event_proc(window, event)
  2129. XXv_Window    window;
  2130. Event *event;
  2131. #endif
  2132. {
  2133. X    int height;
  2134. X    int    y;
  2135. X    int    rows;
  2136. X    int    rowsize;
  2137. X    int    width;
  2138. X
  2139. X    switch(event_id(event)) {
  2140. X    case WIN_RESIZE:
  2141. X        height = xv_get(schedule_window.panel, XV_HEIGHT);
  2142. X        width = xv_get(schedule_window.panel, XV_WIDTH);
  2143. X        y = xv_get(schedule_window.send_list, PANEL_ITEM_Y);
  2144. X        rowsize = xv_get(schedule_window.send_list, PANEL_LIST_ROW_HEIGHT);
  2145. X        rows = (height - y - 45) / rowsize;
  2146. X        if (rows <= 0)
  2147. X            rows = 1;
  2148. X        xv_set(schedule_window.send_list, 
  2149. X            PANEL_LIST_DISPLAY_ROWS, rows,
  2150. X            PANEL_LIST_WIDTH, width - 30, 
  2151. X            PANEL_PAINT, PANEL_NONE,
  2152. X            NULL);
  2153. X        xv_set(schedule_window.receive_list, 
  2154. X            PANEL_LIST_DISPLAY_ROWS, rows,
  2155. X            PANEL_LIST_WIDTH, width - 30, 
  2156. X            PANEL_PAINT, PANEL_NONE,
  2157. X            NULL);
  2158. X        if (xv_get(schedule_window.send_list, XV_SHOW) == TRUE)
  2159. X            panel_paint(schedule_window.send_list, PANEL_CLEAR);
  2160. X        else
  2161. X            panel_paint(schedule_window.receive_list, PANEL_CLEAR);
  2162. X        break;
  2163. X    default:
  2164. X        break;
  2165. X    }
  2166. }
  2167. X
  2168. #ifdef USE_PROTOTYPES
  2169. void host_event_proc(Xv_Window window, Event *event)
  2170. #else
  2171. void host_event_proc(window, event)
  2172. XXv_Window    window;
  2173. Event *event;
  2174. #endif
  2175. {
  2176. X    int    width;
  2177. X    int panelwidth;
  2178. X    Rect    *connect_rect;
  2179. X    Rect    *dismiss_rect;
  2180. X    int    space;
  2181. X    int    pos;
  2182. X    int    y;
  2183. X    Panel_item    item;
  2184. X    Panel_item_type    item_type;
  2185. X
  2186. X    switch(event_id(event)) {
  2187. X    case WIN_RESIZE:
  2188. X        width = xv_get(host_window.frame, XV_WIDTH);
  2189. X        if (xv_get(host_window.advanced.panel, XV_SHOW) == TRUE)
  2190. X            panelwidth = width / 2;
  2191. X        else
  2192. X            panelwidth = width - 2;
  2193. X        xv_set(host_window.panel, 
  2194. X            XV_WIDTH, width,
  2195. X            NULL);
  2196. X        xv_set(host_window.basic.panel, 
  2197. X            XV_WIDTH, panelwidth,
  2198. X            NULL);
  2199. X        xv_set(host_window.advanced.panel, 
  2200. X            XV_WIDTH, panelwidth + 2,
  2201. X            XV_X, panelwidth - 3,
  2202. X            NULL);
  2203. X        PANEL_EACH_ITEM(host_window.basic.panel, item) {
  2204. X            item_type = (Panel_item_type)xv_get(item, PANEL_ITEM_CLASS);
  2205. X            if (item_type == PANEL_TEXT_ITEM)
  2206. X                resize_text_item(host_window.basic.panel, item);
  2207. X        } PANEL_END_EACH;
  2208. X        PANEL_EACH_ITEM(host_window.advanced.panel, item) {
  2209. X            item_type = (Panel_item_type)xv_get(item, PANEL_ITEM_CLASS);
  2210. X            if (item_type == PANEL_TEXT_ITEM)
  2211. SHAR_EOF
  2212. true || echo 'restore of event.c failed'
  2213. fi
  2214. echo 'End of  part 4'
  2215. echo 'File event.c is continued in part 5'
  2216. echo 5 > _shar_seq_.tmp
  2217. exit 0
  2218. -- 
  2219. Senior Systems Scientist        mail: dcmartin@msi.com
  2220. Molecular Simulations, Inc.        uucp: uunet!dcmartin
  2221. 796 North Pastoria Avenue        at&t: 408/522-9236
  2222. Sunnyvale, California 94086        fax: 408/732-0831
  2223.