home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / xarchie / part07 < prev    next >
Encoding:
Text File  |  1993-06-14  |  50.4 KB  |  1,922 lines

  1. Newsgroups: comp.sources.x
  2. From: ferguson@cs.rochester.edu (George Ferguson)
  3. Subject: v20i035:  xarchie - An X browser interface to Archie, v2.0.6, Part07/24
  4. Message-ID: <1993Jun15.223239.239@sparky.imd.sterling.com>
  5. X-Md4-Signature: a9ad0a18199263559626bac125a090d1
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Tue, 15 Jun 1993 22:32:39 GMT
  9. Approved: chris@sparky.imd.sterling.com
  10.  
  11. Submitted-by: ferguson@cs.rochester.edu (George Ferguson)
  12. Posting-number: Volume 20, Issue 35
  13. Archive-name: xarchie/part07
  14. Environment: X11
  15. Supersedes: xarchie: Volume 14, Issue 82-90
  16.  
  17. Submitted-by: ferguson@cs.rochester.edu
  18. Archive-name: xarchie-2.0.6/part07
  19.  
  20. #!/bin/sh
  21. # this is Part.07 (part 7 of xarchie-2.0.6)
  22. # do not concatenate these parts, unpack them in order with /bin/sh
  23. # file xarchie-2.0.6/dirsend.c continued
  24. #
  25. if test ! -r _shar_seq_.tmp; then
  26.     echo 'Please unpack part 1 first!'
  27.     exit 1
  28. fi
  29. (read Scheck
  30.  if test "$Scheck" != 7; then
  31.     echo Please unpack part "$Scheck" next!
  32.     exit 1
  33.  else
  34.     exit 0
  35.  fi
  36. ) < _shar_seq_.tmp || exit 1
  37. if test ! -f _shar_wnt_.tmp; then
  38.     echo 'x - still skipping xarchie-2.0.6/dirsend.c'
  39. else
  40. echo 'x - continuing file xarchie-2.0.6/dirsend.c'
  41. sed 's/^X//' << 'SHAR_EOF' >> 'xarchie-2.0.6/dirsend.c' &&
  42. X * returns the descriptor if successful, otherwise -1 to indicate that
  43. X * dirsend() should return NULL immediately.
  44. X */
  45. static int
  46. initDirsend()
  47. {
  48. #if defined(XARCHIE) || defined(VARCHIE)
  49. X    status0("Initializing");
  50. #endif
  51. X
  52. X    if(one == 0) one = htons((short) 1);
  53. X
  54. X    priority = htons(rdgram_priority);
  55. X
  56. X    timeout.tv_sec = client_dirsrv_timeout;
  57. X    timeout.tv_usec = 0;
  58. X
  59. X    ackwait.tv_sec = 0;
  60. X    ackwait.tv_usec = 500000;
  61. X
  62. X    gapwait.tv_sec = (client_dirsrv_timeout < 5 ? client_dirsrv_timeout : 5);
  63. X    gapwait.tv_usec = 0;
  64. X
  65. X    comp_thru = NULL;
  66. X    perrno = 0;
  67. X    nd_pkts = 0;
  68. X    no_pkts = 0;
  69. X    pkt_cid = 0;
  70. X
  71. X    /* Find first connection ID */
  72. X    if(next_conn_id == 0) {
  73. X    srand(getpid()+time(0)); /* XXX: arg ok, but not right type. */
  74. X    next_conn_id = rand();
  75. X    }
  76. X
  77. X
  78. X    /* If necessary, find out what udp port to send to */
  79. X    if (dir_udp_port == 0) {
  80. X        register struct servent *sp;
  81. X    tmp = pfs_enable; pfs_enable = PMAP_DISABLE;
  82. #ifdef USE_ASSIGNED_PORT
  83. X    /* UCX needs 0 & -1 */
  84. X    sp = getservbyname("prospero","udp");
  85. X    if (sp == (struct servent *)0 || sp == (struct servent *)-1) {
  86. #ifdef DEBUG
  87. X        if (pfs_debug)
  88. X        fprintf(stderr, "dirsrv: udp/prospero unknown service - using %d\n", 
  89. X            PROSPERO_PORT);
  90. #endif
  91. X        dir_udp_port = htons((u_short) PROSPERO_PORT);
  92. X        }
  93. #else
  94. X    /* UCX needs 0 & -1 */
  95. X    sp = getservbyname("dirsrv","udp");
  96. X    if (sp == (struct servent *)0 || sp == (struct servent *)-1) {
  97. #ifdef DEBUG
  98. X        if (pfs_debug)
  99. X        fprintf(stderr, "dirsrv: udp/dirsrv unknown service - using %d\n", 
  100. X            DIRSRV_PORT);
  101. #endif
  102. X        dir_udp_port = htons((u_short) DIRSRV_PORT);
  103. X        }
  104. #endif
  105. X    else dir_udp_port = sp->s_port;
  106. X    pfs_enable = tmp;
  107. #ifdef DEBUG
  108. X        if (pfs_debug > 3)
  109. X            fprintf(stderr,"dir_udp_port is %d\n", ntohs(dir_udp_port));
  110. #endif
  111. X    }
  112. X
  113. X    /* If we were given the host address, then use it.  Otherwise  */
  114. X    /* lookup the hostname.  If we were passed a host address of   */
  115. X    /* 0, we must lookup the host name, then replace the old value */
  116. X    if(!hostaddr || (hostaddr->sin_addr.s_addr == 0)) {
  117. X    /* I we have a null host name, return an error */
  118. X    if((hostname == NULL) || (*hostname == '\0')) {
  119. #ifdef DEBUG
  120. X            if (pfs_debug)
  121. X                fprintf(stderr, "dirsrv: Null hostname specified\n");
  122. #endif
  123. X        perrno = DIRSEND_BAD_HOSTNAME;
  124. X        ptlfree(pkt);
  125. X            /* return(NULL); */
  126. X        return(-1);
  127. X    }
  128. X    /* If a port is included, save it away */
  129. X    if(openparen = index(hostname,'(')) {
  130. X        sscanf(openparen+1,"%d",&req_udp_port);
  131. X        strncpy(hostnoport,hostname,400);
  132. X        if((openparen - hostname) < 400) {
  133. X        *(hostnoport + (openparen - hostname)) = '\0';
  134. X        hostname = hostnoport;
  135. X        }
  136. X    }
  137. #if defined(XARCHIE) || defined(VARCHIE)
  138. X    status1("Getting address for host \"%s\"",hostname);
  139. #endif
  140. X    tmp = pfs_enable; pfs_enable = PMAP_DISABLE;
  141. X    if((host = gethostbyname(hostname)) == NULL) {
  142. X        pfs_enable = tmp;
  143. X        /* Check if a numeric address */
  144. X        newhostaddr = inet_addr(hostname);
  145. X        if(newhostaddr == -1) {
  146. #ifdef DEBUG
  147. X        if (pfs_debug)
  148. X          fprintf(stderr, "dirsrv: Can't resolve host %s\n",hostname);
  149. #endif
  150. X        perrno = DIRSEND_BAD_HOSTNAME;
  151. X        ptlfree(pkt);
  152. X        /* return(NULL); */
  153. X        return(-1);
  154. X        }
  155. X        bzero((char *)&to, S_AD_SZ);
  156. X        to.sin_family = AF_INET;
  157. X        bcopy((char *) &newhostaddr, (char *)&to.sin_addr, 4);
  158. X        if(hostaddr) bcopy(&to,hostaddr, S_AD_SZ);
  159. X    }
  160. X    else {
  161. X        pfs_enable = tmp;
  162. X        bzero((char *)&to, S_AD_SZ);
  163. X        to.sin_family = host->h_addrtype;
  164. #ifdef CUTCP
  165. X        bcopy((char *) &host->h_addr, (char *)&to.sin_addr, host->h_length);
  166. #else
  167. X        bcopy(host->h_addr, (char *)&to.sin_addr, host->h_length);
  168. #endif
  169. X        if(hostaddr) bcopy(&to,hostaddr, S_AD_SZ);
  170. X    }
  171. X    }
  172. X    else bcopy(hostaddr,&to, S_AD_SZ);
  173. X    /* lmjm: Save away the hostname */
  174. X    strncpy(to_hostname,inet_ntoa(to.sin_addr),sizeof(to_hostname)-1);
  175. X
  176. X    if(req_udp_port) to.sin_port = htons(req_udp_port);
  177. X    else to.sin_port = dir_udp_port;
  178. X
  179. X    /* If a port was specified in hostaddr, use it, otherwise fill it in */
  180. X    if(hostaddr) {
  181. X    if(hostaddr->sin_port) to.sin_port = hostaddr->sin_port;
  182. X    else hostaddr->sin_port = to.sin_port;
  183. X    }
  184. X
  185. #ifndef CUTCP
  186. X    /* Must open a new port each time. we do not want to see old */
  187. X    /* responses to messages we are done with                    */
  188. X    if ((lp = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  189. #ifdef DEBUG
  190. X        if (pfs_debug)
  191. X            fprintf(stderr,"dirsrv: Can't open socket\n");
  192. #endif
  193. X    perrno = DIRSEND_UDP_CANT;
  194. X    ptlfree(pkt);
  195. X        /* return(NULL); */
  196. X    return(-1);
  197. X    }
  198. #endif /* not CUTCP */
  199. X
  200. X    /* Try to bind it to a privileged port - loop through candidate */
  201. X    /* ports trying to bind.  If failed, that's OK, we will let the */
  202. X    /* system assign a non-privileged port later                    */
  203. #ifndef CUTCP
  204. X    if(!notprived) {
  205. X    for(tmp = PROS_FIRST_PRIVP; tmp < PROS_FIRST_PRIVP+PROS_NUM_PRIVP; 
  206. X        tmp++) {
  207. #endif
  208. X        bzero((char *)&us, sizeof(us));
  209. X        us.sin_family = AF_INET;
  210. #ifndef CUTCP
  211. X        us.sin_port = htons((u_short) tmp);
  212. X        if (bind(lp, (struct sockaddr *)&us, sizeof(us))) {
  213. X        if(errno != EADDRINUSE) {
  214. X            notprived++;
  215. X            break;
  216. X        }
  217. X        }
  218. X        else break;
  219. X    }
  220. X    }
  221. #else
  222. X    us.sin_port = htons(PROS_FIRST_PRIVP);
  223. X    netulisten(PROS_FIRST_PRIVP);
  224. #endif
  225. X
  226. #ifndef USE_V3_PROT
  227. X    /* Add header */
  228. X    if(rdgram_priority) {
  229. X    pkt->start -= 15;
  230. X    pkt->length += 15;
  231. X    *(pkt->start) = (char) 15;
  232. X    bzero(pkt->start+9,4);
  233. X    *(pkt->start+11) = 0x02;
  234. X    bcopy(&priority,pkt->start+13,2);
  235. X    }
  236. X    else {
  237. X    pkt->start -= 9;
  238. X    pkt->length += 9;
  239. X    *(pkt->start) = (char) 9;
  240. X    }
  241. X    this_conn_id = htons(next_conn_id++);
  242. X    if(next_conn_id == 0) next_conn_id++;
  243. X    bcopy(&this_conn_id,pkt->start+1,2);
  244. X    bcopy(&one,pkt->start+3,2);
  245. X    bcopy(&one,pkt->start+5,2);
  246. X    bzero(pkt->start+7,2);
  247. #endif
  248. X
  249. #ifdef DEBUG
  250. X    if (pfs_debug > 2) {
  251. #ifndef USE_V3_PROT
  252. X        if (to.sin_family == AF_INET) {
  253. X        if(req_udp_port) 
  254. X        fprintf(stderr,"Sending message to %s+%d(%d)...",
  255. X            to_hostname, req_udp_port, ntohs(this_conn_id));
  256. X        else fprintf(stderr,"Sending message to %s(%d)...",
  257. X             to_hostname, ntohs(this_conn_id));
  258. X    }
  259. #else
  260. X        if (to.sin_family == AF_INET) 
  261. X        fprintf(stderr,"Sending message to %s...", to_hostname);
  262. #endif /* USE_V3_PROT */
  263. X        else
  264. X            fprintf(stderr,"Sending message...");
  265. X        (void) fflush(stderr);
  266. X    }
  267. #endif /* DEBUG */
  268. X
  269. X    first = ptalloc();
  270. X    next = first;
  271. X
  272. #if defined(XARCHIE) || defined(VARCHIE)
  273. X    status2("Connecting to %s (%s)",to_hostname,hostname);
  274. X    packetCounter = 0;
  275. #endif
  276. X
  277. #ifndef CUTCP
  278. X    return(lp);
  279. #else
  280. X    return(1);
  281. #endif /* CUTCP */
  282. }
  283. X
  284. /*    -    -    -    -    -    -    -    -    */
  285. /*
  286. X * This used to be a label to goto to retry the last packet. Now we resend
  287. X * the packet and call keepWaitingDirsend() to wait for a reply. (We
  288. X * call keepWaitingDirsend() because formerly the code dropped through
  289. X * the keep_waiting label.)
  290. X */
  291. static void
  292. retryDirsend()
  293. {
  294. #ifdef CUTCP
  295. X    int lretry = 3;
  296. #endif
  297. X    gaps = ackpend = 0;
  298. X
  299. #ifndef CUTCP
  300. X    ns = sendto(lp,(char *)(pkt->start), pkt->length, 0, (struct sockaddr *)&to, S_AD_SZ);
  301. #else
  302. X    while(--lretry) {
  303. X        ns = netusend(&to.sin_addr,ntohs(to.sin_port),ntohs(us.sin_port),
  304. X              (char *) pkt->start, pkt->length);
  305. X        if(!ns)
  306. X        break;
  307. X        Stask();
  308. X        Stask();
  309. X        Stask();
  310. X    }
  311. #endif /* CUTCP */
  312. X
  313. #ifndef CUTCP
  314. X    if(ns != pkt->length) {
  315. #else
  316. X    if(ns != 0) {
  317. #endif
  318. #ifdef DEBUG
  319. X    if (pfs_debug) {
  320. X    fprintf(stderr,"\nsent only %d/%d: ",ns, pkt->length);
  321. X        perror("");
  322. X    }
  323. #endif
  324. X    close(lp);
  325. X    perrno = DIRSEND_NOT_ALL_SENT;
  326. X    ptlfree(first);
  327. X    ptlfree(pkt);
  328. X    /* return(NULL); */
  329. X    dirsendReturn = NULL;
  330. X    dirsendDone = DSRET_SEND_ERROR;
  331. X    }
  332. #ifdef DEBUG
  333. X    if (pfs_debug > 2) fprintf(stderr,"Sent.\n");
  334. #endif
  335. X    keepWaitingDirsend();
  336. }
  337. X
  338. /*    -    -    -    -    -    -    -    -    */
  339. /*
  340. X * This used to be a label to goto to set the appropriate timeout value
  341. X * and blocked in select(). Now we set selwait and the fd_sets to the
  342. X * appropriate values, and in X register a new timeout, then return to
  343. X * allow event processing.
  344. X */
  345. static void
  346. keepWaitingDirsend()
  347. {
  348. X    /* We come back to this point (by a goto) if the packet */
  349. X    /* received is only part of the response, or if the     */
  350. X    /* response came from the wrong host            */
  351. X
  352. #ifdef DEBUG
  353. X    if (pfs_debug > 2) fprintf(stderr,"Waiting for reply...");
  354. #endif
  355. X
  356. #ifndef CUTCP
  357. X    FD_ZERO(&readfds);
  358. X    FD_SET(lp, &readfds);
  359. #endif
  360. X
  361. X    if(ackpend) selwait = &ackwait;
  362. X    else if(gaps) selwait = &gapwait;
  363. X    else selwait = &timeout;
  364. X
  365. X    addTimeOut();
  366. }
  367. X
  368. /*    -    -    -    -    -    -    -    -    */
  369. /*
  370. X * This routine is called when a timeout occurs. It includes the code that
  371. X * was formerly used when select() returned 0 (indicating a timeout).
  372. X */
  373. /*ARGSUSED*/
  374. static void
  375. timeoutProc(client_data,id)
  376. XXtPointer client_data;
  377. XXtIntervalId *id;
  378. {
  379. X    if (gaps || ackpend) { /* Send acknowledgment */
  380. X    /* Acks are piggybacked on retries - If we have received */
  381. X    /* an ack from the server, then the packet sent is only  */
  382. X    /* an ack and the rest of the message will be empty      */
  383. #ifdef DEBUG
  384. X    if (pfs_debug > 2) {
  385. X            fprintf(stderr,"Acknowledging (%s).\n",
  386. X            (ackpend ? "requested" : "gaps"));
  387. X    }    
  388. #endif
  389. X    retryDirsend();
  390. X    return;
  391. X    }
  392. X
  393. X    if (retries-- > 0) {
  394. X    timeout.tv_sec = CLIENT_DIRSRV_BACKOFF(timeout.tv_sec);
  395. #ifdef DEBUG
  396. X    if (pfs_debug > 2) {
  397. X            fprintf(stderr,"Timed out.  Setting timeout to %d seconds.\n",
  398. X            timeout.tv_sec);
  399. X    }
  400. #endif
  401. #if defined(XARCHIE) || defined(VARCHIE)
  402. X        status1("Timed out -- retrying (%d seconds)",timeout.tv_sec);
  403. #endif
  404. X    retryDirsend();
  405. X    return;
  406. X    }
  407. X
  408. #ifdef DEBUG
  409. X    if (pfs_debug) {
  410. X    fprintf(stderr, "select failed(timeoutProc): readfds=%x ",
  411. X        readfds);
  412. X    perror("");
  413. X    }
  414. #endif
  415. #ifndef CUTCP
  416. X    close(lp);
  417. #endif
  418. X    perrno = DIRSEND_SELECT_FAILED;
  419. X    ptlfree(first);
  420. X    ptlfree(pkt);
  421. X    /* return(NULL); */
  422. X    dirsendReturn = NULL;
  423. X    dirsendDone = DSRET_TIMEOUT;
  424. }
  425. X
  426. /*    -    -    -    -    -    -    -    -    */
  427. /*
  428. X * This function is called whenever there's something to read on the
  429. X * connection. It includes the code that was run when select() returned
  430. X * greater than 0 (indicating read ready).
  431. X */
  432. /*ARGSUSED*/
  433. static void
  434. readProc(client_data,source,id)
  435. XXtPointer client_data;
  436. int *source;
  437. XXtInputId *id;
  438. {
  439. #ifdef CUTCP
  440. X    int lretry = 3;
  441. #endif
  442. X
  443. X    /* We got something to read, so clear the timer */
  444. X    removeTimeOut();
  445. X
  446. X    from_sz = sizeof(from);
  447. X    next->start = next->dat;
  448. X
  449. #ifndef CUTCP
  450. X    if ((nr = recvfrom(lp, next->start, sizeof(next->dat), 0, (struct sockaddr *)&from, &from_sz)) < 0) {
  451. #else
  452. X    nr = neturead(next->start);
  453. X    if (nr < 1) {
  454. #endif
  455. #ifdef DEBUG
  456. X        if (pfs_debug) perror("recvfrom");
  457. #endif
  458. #ifndef CUTCP
  459. X    close(lp);
  460. #endif
  461. X    perrno = DIRSEND_BAD_RECV;
  462. X    ptlfree(first);
  463. X    ptlfree(pkt);
  464. X    /* return(NULL) */
  465. X    dirsendReturn = NULL;
  466. X    dirsendDone = DSRET_RECV_ERROR;
  467. X        return;
  468. X    }
  469. X
  470. X    next->length = nr;
  471. X    next->start[next->length] = 0;
  472. X
  473. #ifdef DEBUG
  474. X    if (pfs_debug > 2)
  475. X        fprintf(stderr,"Received packet from %s\n",inet_ntoa(from.sin_addr));
  476. #endif
  477. X
  478. #if defined(XARCHIE) || defined(VARCHIE)
  479. X    if (packetCounter == 0)
  480. X    status2("Connected to %s (%s)",to_hostname,hostname);
  481. X    else
  482. X    status1("Receiving...%d",packetCounter);
  483. X    packetCounter += 1;
  484. #endif
  485. X
  486. X    /* For the current format, if the first byte is less than             */
  487. X    /* 20, then the first two bits are a version number and the next six  */
  488. X    /* are the header length (including the first byte).                  */
  489. X    if((hdr_len = (unsigned char) *(next->start)) < 20) {
  490. X    ctlptr = next->start + 1;
  491. X    next->seq = 0;
  492. X    if(hdr_len >= 3) {     /* Connection ID */
  493. X        bcopy(ctlptr,&stmp,2);
  494. X        if(stmp) pkt_cid = ntohs(stmp);
  495. X        ctlptr += 2;
  496. X    }
  497. X    /*
  498. X     * Problem noted by eanders+@cmu.edu against the V5 Prospero server:
  499. X     * "the problem is that clients look at a unsigned short as a signed
  500. X     * integer.  Then they do comparisons, and naturally they are not
  501. X     * equal." This fix is as opposed to some kind of casting, and
  502. X     * will be moot when the new clients are written for the new servers.
  503. X     */
  504. X    if (pkt_cid < 0)
  505. X        pkt_cid = 65536+pkt_cid;
  506. X    if(pkt_cid && this_conn_id && (pkt_cid != ntohs(this_conn_id))) {
  507. X        /* The packet is not for us */
  508. X        /* goto keep_waiting; */
  509. #ifdef DEBUG
  510. X        if (pfs_debug > 20)
  511. X        fprintf(stderr,"Packet not for us %d,%d,%d\n",
  512. X            pkt_cid,this_conn_id,ntohs(this_conn_id));
  513. #endif
  514. X        keepWaitingDirsend();
  515. X        return;
  516. X    }
  517. X    if(hdr_len >= 5) {    /* Packet number */
  518. X        bcopy(ctlptr,&stmp,2);
  519. X        next->seq = ntohs(stmp);
  520. X        ctlptr += 2;
  521. X    }
  522. X    else { /* No packet number specified, so this is the only one */
  523. X        next->seq = 1;
  524. X        nd_pkts = 1;
  525. X    }
  526. X    if(hdr_len >= 7) {        /* Total number of packets */
  527. X        bcopy(ctlptr,&stmp,2);  /* 0 means don't know      */
  528. X        if(stmp) nd_pkts = ntohs(stmp);
  529. X        ctlptr += 2;
  530. X    }
  531. X    if(hdr_len >= 9) {    /* Receievd through */
  532. X        bcopy(ctlptr,&stmp,2);  /* 1 means received request */
  533. #ifndef USE_V3_PROT
  534. X        if((stmp) && (ntohs(stmp) == 1)) {
  535. X        /* Future retries will be acks only */
  536. X        pkt->length = 9;
  537. X        bcopy(&zero,pkt->start+3,2);
  538. #ifdef DEBUG
  539. X        if(pfs_debug > 2) 
  540. X            fprintf(stderr,"Server acked request - retries will be acks only\n");
  541. #endif
  542. X        }
  543. #endif
  544. X        ctlptr += 2;
  545. X    }
  546. X    if(hdr_len >= 11) {    /* Backoff */
  547. X        bcopy(ctlptr,&stmp,2);
  548. X        if(stmp) {
  549. X        backoff = (short)ntohs(stmp);
  550. #ifdef DEBUG
  551. X        if(pfs_debug > 2) 
  552. X            fprintf(stderr,"Backing off to %d seconds\n", backoff);
  553. #endif
  554. X        timeout.tv_sec = backoff;
  555. X        if ((backoff > 60) && (first == next) && (no_pkts == 0)) {
  556. X            /* Probably a long queue on the server - don't give up */
  557. X            retries = client_dirsrv_retry;
  558. X        }
  559. X        }
  560. X        ctlptr += 2;
  561. X    }
  562. X    if(hdr_len >= 12) {    /* Flags (1st byte) */
  563. X        bcopy(ctlptr,&rdflag11,1);
  564. X        if(rdflag11 & 0x80) {
  565. #ifdef DEBUG
  566. X        if(pfs_debug > 2) 
  567. X            fprintf(stderr,"Ack requested\n");
  568. #endif
  569. X        ackpend++;
  570. X        }
  571. X        if(rdflag11 & 0x40) {
  572. #ifdef DEBUG
  573. X        if(pfs_debug > 2) 
  574. X            fprintf(stderr,"Sequenced control packet\n");
  575. #endif
  576. X        next->length = -1;
  577. X        scpflag++;
  578. X        }
  579. X        ctlptr += 1;
  580. X    }
  581. X    if(hdr_len >= 13) {    /* Flags (2nd byte) */
  582. X        /* Reserved for future use */
  583. X        bcopy(ctlptr,&rdflag12,1);
  584. X        ctlptr += 1;
  585. X    }
  586. X    if(next->seq == 0) {
  587. X        /* goto keep_waiting; */
  588. X        keepWaitingDirsend();
  589. X        return;
  590. X    }
  591. X    if(next->length >= 0) next->length -= hdr_len;
  592. X    next->start += hdr_len;
  593. X    goto done_old;
  594. X    }
  595. X
  596. X    pkt_cid = 0;
  597. X
  598. X    /* if intermediate format (between old and new), then process */
  599. X    /* and go to done_old                                         */
  600. X    ctlptr = next->start + max(0,next->length-20);
  601. X    while(*ctlptr) ctlptr++;
  602. X    /* Control fields start after the terminating null */
  603. X    ctlptr++;
  604. X    /* Until old version are gone, must be 4 extra bytes minimum */
  605. X    /* When no version 3 servers, can remove the -4              */
  606. X    if(ctlptr < (next->start + next->length - 4)) {
  607. X    /* Connection ID */
  608. X    bcopy(ctlptr,&stmp,2);
  609. X    if(stmp) pkt_cid = ntohs(stmp);
  610. X    ctlptr += 2;
  611. X    if(pkt_cid && this_conn_id && (pkt_cid != ntohs(this_conn_id))) {
  612. X        /* The packet is not for us */
  613. X        /* goto keep_waiting; */
  614. X        keepWaitingDirsend();
  615. X        return;
  616. X    }
  617. X    /* Packet number */
  618. X    if(ctlptr < (next->start + next->length)) {
  619. X        bcopy(ctlptr,&stmp,2);
  620. X        next->seq = ntohs(stmp);
  621. X        ctlptr += 2;
  622. X    }
  623. X    /* Total number of packets */
  624. X    if(ctlptr < (next->start + next->length)) {
  625. X        bcopy(ctlptr,&stmp,2);
  626. X        if(stmp) nd_pkts = ntohs(stmp);
  627. X        ctlptr += 2;
  628. X    }
  629. X    /* Receievd through */
  630. X    if(ctlptr < (next->start + next->length)) {
  631. X        /* Not supported by clients */
  632. X        ctlptr += 2;
  633. X    }
  634. X    /* Backoff */
  635. X    if(ctlptr < (next->start + next->length)) {
  636. X        bcopy(ctlptr,&stmp,2);
  637. X        backoff = ntohs(stmp);
  638. #ifdef DEBUG
  639. X        if(pfs_debug > 2) 
  640. X        fprintf(stderr,"Backing off to %d seconds\n", backoff);
  641. #endif
  642. X        if(backoff) timeout.tv_sec = backoff;
  643. X        ctlptr += 2;
  644. X    }
  645. X    if(next->seq == 0) {
  646. X        /* goto keep_waiting; */
  647. X        keepWaitingDirsend();
  648. X        return;
  649. X    }
  650. X    goto done_old;
  651. X
  652. X    }
  653. X
  654. X    /* Notes that we have to start searching 11 bytes before the    */
  655. X    /* expected start of the MULTI-PACKET line because the message  */
  656. X    /* might include up to 10 bytes of data after the trailing null */
  657. X    /* The order of those bytes is two bytes each for Connection ID */
  658. X    /* Packet-no, of, Received-through, Backoff                     */
  659. X    seqtxt = nlsindex(next->start + max(0,next->length - 40),"MULTI-PACKET"); 
  660. X    if(seqtxt) seqtxt+= 13;
  661. X
  662. X    if((nd_pkts == 0) && (no_pkts == 0) && (seqtxt == NULL)) goto all_done;
  663. X
  664. X    tmp = sscanf(seqtxt,"%d OF %d", &(next->seq), &nd_pkts);
  665. #ifdef DEBUG    
  666. X    if (pfs_debug && (tmp == 0)) 
  667. X    fprintf(stderr,"Cant read packet sequence number: %s", seqtxt);    
  668. #endif
  669. X done_old:
  670. #ifdef DEBUG
  671. X    if(pfs_debug > 2) fprintf(stderr,"Packet %d of %d\n",next->seq,nd_pkts);
  672. #endif
  673. X    if ((first == next) && (no_pkts == 0)) {
  674. X    if(first->seq == 1) {
  675. X        comp_thru = first;
  676. X        /* If only one packet, then return it */
  677. X        if(nd_pkts == 1) goto all_done;
  678. X    }
  679. X    else gaps++;
  680. X    no_pkts = 1;
  681. X    next = ptalloc();
  682. X    /* goto keep_waiting; */
  683. X    keepWaitingDirsend();
  684. X    return;
  685. X    }
  686. X    
  687. X    if(comp_thru && (next->seq <= comp_thru->seq))
  688. X    ptfree(next);
  689. X    else if (next->seq < first->seq) {
  690. X    vtmp = first;
  691. X    first = next;
  692. X    first->next = vtmp;
  693. X    first->previous = NULL;
  694. X    vtmp->previous = first;
  695. X    if(first->seq == 1) comp_thru = first;
  696. X    no_pkts++;
  697. X    }
  698. X    else {
  699. X    vtmp = (comp_thru ? comp_thru : first);
  700. X    while (vtmp->seq < next->seq) {
  701. X        if(vtmp->next == NULL) {
  702. X        vtmp->next = next;
  703. X        next->previous = vtmp;
  704. X        next->next = NULL;
  705. X        no_pkts++;
  706. X        goto ins_done;
  707. X        }
  708. X        vtmp = vtmp->next;
  709. X    }
  710. X    if(vtmp->seq == next->seq)
  711. X        ptfree(next);
  712. X    else {
  713. X        vtmp->previous->next = next;
  714. X        next->previous = vtmp->previous;
  715. X        next->next = vtmp;
  716. X        vtmp->previous = next;
  717. X        no_pkts++;
  718. X    }
  719. X    }   
  720. X
  721. ins_done:
  722. X    
  723. X    while(comp_thru && comp_thru->next && 
  724. X      (comp_thru->next->seq == (comp_thru->seq + 1))) {
  725. X    comp_thru = comp_thru->next;
  726. #ifndef USE_V3_PROT
  727. X    recvd_thru = htons(comp_thru->seq);
  728. X    bcopy(&recvd_thru,pkt->start+7,2); /* Let server know we got it */
  729. #endif
  730. X    /* We've made progress, so reset retry count */
  731. X    retries = client_dirsrv_retry;
  732. X    /* Also, next retry will be only an acknowledgement */
  733. X    /* but for now, we can't fill in the ack field      */
  734. #ifdef DEBUG
  735. X    if(pfs_debug > 2) 
  736. X        fprintf(stderr,"Packets now received through %d\n",comp_thru->seq);
  737. #endif
  738. X    }
  739. X
  740. X    /* See if there are any gaps */
  741. X    if(!comp_thru || comp_thru->next) gaps++;
  742. X    else gaps = 0;
  743. X
  744. X    if ((nd_pkts == 0) || (no_pkts < nd_pkts)) {
  745. X    next = ptalloc();
  746. X    /* goto keep_waiting; */
  747. X    keepWaitingDirsend();
  748. X    return;
  749. X    }
  750. X
  751. X all_done:
  752. X    if(ackpend) { /* Send acknowledgement if requested */
  753. #ifdef DEBUG
  754. X    if (pfs_debug > 2) {
  755. X        if (to.sin_family == AF_INET)
  756. X        fprintf(stderr,"Acknowledging final packet to %s(%d)\n",
  757. X            to_hostname, ntohs(this_conn_id));
  758. X            else
  759. X                fprintf(stderr,"Acknowledging final packet\n");
  760. X        (void) fflush(stderr);
  761. X    }
  762. #endif
  763. #ifndef CUTCP
  764. X    ns = sendto(lp,(char *)(pkt->start), pkt->length, 0, (struct sockaddr *)&to, S_AD_SZ);
  765. #else
  766. X    while(--lretry) {
  767. X        ns = netusend(&to.sin_addr, ntohs(to.sin_port), ntohs(us.sin_port),(char *) pkt->start, pkt->length);
  768. X        if(!ns)
  769. X            break;
  770. X        Stask();
  771. X        Stask();
  772. X    }
  773. #endif
  774. X
  775. #ifndef CUTCP
  776. X    if(ns != pkt->length) {
  777. #else
  778. X    if(ns != 0) {
  779. #endif
  780. X
  781. #ifdef DEBUG
  782. X        if (pfs_debug) {
  783. X        fprintf(stderr,"\nsent only %d/%d: ",ns, pkt->length);
  784. X        perror("");
  785. X        }
  786. #endif
  787. X    }
  788. X
  789. X    }
  790. #ifndef CUTCP
  791. X    close(lp);
  792. #endif
  793. X    ptlfree(pkt);
  794. X
  795. X    /* Get rid of any sequenced control packets */
  796. X    if(scpflag) {
  797. X    while(first && (first->length < 0)) {
  798. X        vtmp = first;
  799. X        first = first->next;
  800. X        if(first) first->previous = NULL;
  801. X        ptfree(vtmp);
  802. X    }
  803. X    vtmp = first;
  804. X    while(vtmp && vtmp->next) {
  805. X        if(vtmp->next->length < 0) {
  806. X        if(vtmp->next->next) {
  807. X            vtmp->next = vtmp->next->next;
  808. X            ptfree(vtmp->next->previous);
  809. X            vtmp->next->previous = vtmp;
  810. X        }
  811. X        else {
  812. X            ptfree(vtmp->next);
  813. X            vtmp->next = NULL;
  814. X        }
  815. X        }
  816. X        vtmp = vtmp->next;
  817. X    }
  818. X    }
  819. X
  820. X    /* return(first); */
  821. X    dirsendReturn = first;
  822. X    dirsendDone = DSRET_DONE;
  823. X
  824. }
  825. /*    -    -    -    -    -    -    -    -    */
  826. /* These routines allow dirsend() to run with or without X by providing
  827. X * wrappers around the calls that handle the asynchronous communication.
  828. X * All parameters are passed using globals.
  829. X * Under X: The input sources and timeouts are set using Xt calls, and
  830. X *        processEvent() just calls XtAppProcessEvent().
  831. X * Non-X: None of the input sources and timeouts are used, and
  832. X *      processEvent() calls select() to handle both timeouts and the
  833. X *      socket file descriptor. The return value of select() is used
  834. X *      to determine which callback routine to call.
  835. X */
  836. X
  837. static void
  838. addInputSource()
  839. {
  840. #ifdef XARCHIE
  841. X    inputId = XtAppAddInput(appContext,lp,(XtPointer)XtInputReadMask,
  842. X                readProc,NULL);
  843. #endif
  844. }
  845. X
  846. static void
  847. removeInputSource()
  848. {
  849. #ifdef XARCHIE
  850. X    XtRemoveInput(inputId);
  851. #endif
  852. }
  853. X
  854. static void
  855. addTimeOut()
  856. {
  857. #ifdef XARCHIE
  858. X    unsigned long timeoutLen = selwait->tv_sec*1000 + selwait->tv_usec/1000;
  859. X
  860. X    /* old timeout can still be there if we are being called after the
  861. X     * file descriptor was read, so we remove it just to be sure. */
  862. X    removeTimeOut();
  863. X    timerId = XtAppAddTimeOut(appContext,timeoutLen,timeoutProc,NULL);
  864. #endif
  865. }
  866. X
  867. static void
  868. removeTimeOut()
  869. {
  870. #ifdef XARCHIE
  871. X    if (timerId != (XtIntervalId)0) {
  872. X    XtRemoveTimeOut(timerId);
  873. X    timerId = (XtIntervalId)0;
  874. X    }
  875. #endif
  876. }
  877. X
  878. /*
  879. X * In X, this just calls the X routine that blocks waiting for an event,
  880. X * timer, or input source and dispatches it.
  881. X *
  882. X * Otherwise, for Unix we call select() with the appropriate arguments,
  883. X * and act on its return calue as follows:
  884. X *  == 0 : The timer expired, call timeoutProc() then return to, presumably,
  885. X *         the loop that calling processEvent() until dirsendDone.
  886. X *  < 0 :  If we were interrupted (errno == EINTR) then don't do anything.
  887. X *         Presumably the signal handler set flags if needed, and we'll
  888. X *         come back to select() again on the next pass of the outer loop
  889. X *         if we're supposed to. Otherwise, puke on the error.
  890. X *  > 0 :  The socket is ready for reading, so call readProc().
  891. X *
  892. X * Otherwise, if we're in MSDOS (CUTCP defined) then I (gf) have no idea
  893. X * what's going on. Ask Brendan.
  894. X */
  895. static void
  896. processEvent()
  897. {
  898. #ifdef CUTCP
  899. X    unsigned long now;
  900. #endif
  901. #ifdef XARCHIE
  902. X    XtAppProcessEvent(appContext,XtIMAll);
  903. #else
  904. X    /* select - either recv is ready, or timeout */
  905. X    /* see if timeout or error or wrong descriptor */
  906. #ifndef CUTCP
  907. X    tmp = select(lp + 1, &readfds, (fd_set *)0, (fd_set *)0, selwait);
  908. X    if (tmp == 0) {
  909. X    timeoutProc(NULL,&timerId);
  910. X    } else if (tmp < 0 && errno == EINTR) {    /* gf: new for ^C in varchie */
  911. X    fprintf(stderr,"select interrupted\n");    /* do nothing, we'll be back */
  912. X    } else if ((tmp < 0) || !FD_ISSET(lp,&readfds)) {
  913. #ifdef DEBUG
  914. X    if (pfs_debug) {
  915. X        fprintf(stderr, "select failed(processEvent): readfds=%x ",
  916. X            readfds);
  917. X        perror("");
  918. X    }
  919. #endif
  920. X    close(lp);
  921. #else /* CUTCP's flood. */
  922. X    /* while not timeout in selwait loop, stask looking for uevents */
  923. X    now = time(NULL) + selwait->tv_sec;
  924. #ifdef    DEBUG
  925. X    if(pfs_debug) {
  926. X        fprintf(stderr,"Waiting %d seconds\n",selwait->tv_sec);
  927. X    }
  928. X
  929. #endif
  930. X    while(now > time(NULL)) {
  931. X        int    i, cl, dat;
  932. X
  933. X        Stask();
  934. X        if (0 < (i = Sgetevent(USERCLASS, &cl, &dat))) {
  935. X            /* got a user class event */
  936. X            if(cl == USERCLASS &&
  937. X                i == UDPDATA) {
  938. X                    readProc(NULL,&lp,&inputId);
  939. X                    return;
  940. X            }
  941. X        }
  942. X        if(kbhit()) {
  943. X            int c = getch();
  944. X            if(c == 27 || c == 3)
  945. X                break;
  946. X            fprintf(stderr,"Press <ESCAPE> to abort\n");
  947. X        }
  948. X    }
  949. X    if(now <= time(NULL)) { /* timeout */
  950. X        timeoutProc(NULL,&timerId);
  951. X         return;
  952. X    }
  953. X
  954. #endif /* CUTCP */
  955. X    perrno = DIRSEND_SELECT_FAILED;
  956. X    ptlfree(first);
  957. X    ptlfree(pkt);
  958. X    /* return(NULL); */
  959. X    dirsendReturn = NULL;
  960. X    dirsendDone = DSRET_SELECT_ERROR;
  961. #ifndef CUTCP
  962. X    } else {
  963. X    readProc(NULL,&lp,&inputId);
  964. X    }
  965. #endif /* CUTCP */
  966. #endif /* XARCHIE */
  967. }
  968. X
  969. void
  970. abortDirsend()
  971. {
  972. X    if (!dirsendDone) {
  973. #ifndef CUTCP
  974. X    close(lp);
  975. #endif
  976. X    ptlfree(first);
  977. X    ptlfree(pkt);
  978. X    dirsendReturn = NULL;
  979. X    dirsendDone = DSRET_ABORTED;
  980. X    }
  981. X    return;
  982. }
  983. SHAR_EOF
  984. echo 'File xarchie-2.0.6/dirsend.c is complete' &&
  985. chmod 0644 xarchie-2.0.6/dirsend.c ||
  986. echo 'restore of xarchie-2.0.6/dirsend.c failed'
  987. Wc_c="`wc -c < 'xarchie-2.0.6/dirsend.c'`"
  988. test 34011 -eq "$Wc_c" ||
  989.     echo 'xarchie-2.0.6/dirsend.c: original size 34011, current size' "$Wc_c"
  990. rm -f _shar_wnt_.tmp
  991. fi
  992. # ============= xarchie-2.0.6/display-x.c ==============
  993. if test -f 'xarchie-2.0.6/display-x.c' -a X"$1" != X"-c"; then
  994.     echo 'x - skipping xarchie-2.0.6/display-x.c (File already exists)'
  995.     rm -f _shar_wnt_.tmp
  996. else
  997. > _shar_wnt_.tmp
  998. echo 'x - extracting xarchie-2.0.6/display-x.c (Text)'
  999. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/display-x.c' &&
  1000. /*
  1001. X * display-x.c : Display routines for xarchie
  1002. X *
  1003. X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  1004. X * 14 May 1993: Need <stdio.h> when DEBUG defined.
  1005. X *        Need to resize List in redrawBrowserPane() when MULTILIST
  1006. X *        not defined. 
  1007. X */
  1008. X
  1009. #include <stdio.h>
  1010. #include <X11/Intrinsic.h>
  1011. #include <X11/StringDefs.h>
  1012. #include <X11/Xaw/AsciiText.h>
  1013. #ifdef MULTILIST
  1014. #include <MultiList.h>
  1015. #else
  1016. #include <X11/Xaw/List.h>
  1017. #endif
  1018. #include "xarchie.h"
  1019. #include "appres.h"
  1020. #include "browser.h"
  1021. #include "alert.h"
  1022. #include "xutil.h"
  1023. #include "stringdefs.h"            /* bezro, bcopy */
  1024. #include "debug.h"
  1025. X
  1026. /*
  1027. X * Functions defined here:
  1028. X */
  1029. /* Text output routines */
  1030. void setTitleText(), setStatusText();
  1031. void setSearchText(), setHostText(), setLocationText(), setFileText();
  1032. void setSizeText(), setModesText(), setDateText();
  1033. X
  1034. /* Button sensitivity routines */
  1035. void setQuerySensitive(), setAbortSensitive();
  1036. void setUpSensitive(), setDownSensitive();
  1037. X
  1038. /* Browser routines */
  1039. void initBrowser(),clearBrowser(),redrawBrowser();
  1040. void clearBrowserPane(), redrawBrowserPane(), unhighlightBrowserPane();
  1041. void clearBrowserItem(), redrawBrowserItem(), unhighlightBrowserItem();
  1042. void highlightBrowserItem(), setBrowserItem();
  1043. /* Browser action routines */
  1044. void nextBrowserPane(),prevBrowserPane();
  1045. void nextBrowserItem(),prevBrowserItem();
  1046. void toggleCurrentBrowserItem(),selectCurrentBrowserItem();
  1047. X
  1048. /* Misc. display routines */
  1049. void beep();
  1050. X
  1051. /* Internal routines */
  1052. static void updatePasteBuffer(), setListString();
  1053. X
  1054. /*
  1055. X * Data defined here:
  1056. X */
  1057. /*
  1058. X * These string arrays are needed since the only way to set a List
  1059. X * widget in X is to pass it an array of strings. That is, there's
  1060. X * no way to add items incrementally. Blech. Still, the arrays are
  1061. X * grown as needed, so these values can be way off, as they are.
  1062. X */
  1063. #define INIT_NUM_BROWSER_STRINGS 1
  1064. #define REALLOC_INCR(num) (2*(num))
  1065. X
  1066. static char **browserStrings[NUM_BROWSER_PANES];
  1067. static int numBrowserStrings[NUM_BROWSER_PANES];
  1068. X
  1069. /*    -    -    -    -    -    -    -    -    */
  1070. /* Text output */
  1071. X
  1072. /*ARGSUSED*/
  1073. void
  1074. setTitleText(str)
  1075. char *str;
  1076. {
  1077. X    /*EMPTY*/
  1078. }
  1079. X
  1080. void
  1081. setStatusText(str)
  1082. char *str;
  1083. {
  1084. X    setWidgetString(statusText,str);
  1085. X    XFlush(display);
  1086. }
  1087. X
  1088. void
  1089. setSearchText(str)
  1090. char *str;
  1091. {
  1092. X    setWidgetString(searchText,str);
  1093. }
  1094. X
  1095. void
  1096. setHostText(str)
  1097. char *str;
  1098. {
  1099. X    setWidgetString(hostText,str);
  1100. X    if (appResources.pasteBuffer)
  1101. X    updatePasteBuffer();
  1102. }
  1103. X
  1104. void
  1105. setLocationText(str)
  1106. char *str;
  1107. {
  1108. X    setWidgetString(locationText,str);
  1109. X    if (appResources.pasteBuffer)
  1110. X    updatePasteBuffer();
  1111. }
  1112. X
  1113. void
  1114. setFileText(str)
  1115. char *str;
  1116. {
  1117. X    setWidgetString(fileText,str);
  1118. X    if (appResources.pasteBuffer)
  1119. X    updatePasteBuffer();
  1120. }
  1121. X
  1122. void
  1123. setSizeText(str)
  1124. char *str;
  1125. {
  1126. X    setWidgetString(sizeText,str);
  1127. }
  1128. X
  1129. void
  1130. setModesText(str)
  1131. char *str;
  1132. {
  1133. X    setWidgetString(modesText,str);
  1134. }
  1135. X
  1136. void
  1137. setDateText(str)
  1138. char *str;
  1139. {
  1140. X    setWidgetString(dateText,str);
  1141. }
  1142. X
  1143. static void
  1144. updatePasteBuffer()
  1145. {
  1146. X    char *host,*loc,*file,*buf;
  1147. X
  1148. X    host = getWidgetString(hostText);
  1149. X    loc = getWidgetString(locationText);
  1150. X    file = getWidgetString(fileText);
  1151. X    buf = XtMalloc(strlen(host)+strlen(loc)+strlen(file)+3);
  1152. X    sprintf(buf,"%s:%s/%s",host,loc,file);
  1153. X    XStoreBytes(display,buf,strlen(buf));
  1154. X    XtFree(buf);
  1155. }
  1156. X
  1157. /*    -    -    -    -    -    -    -    -    */
  1158. /* Buttons */
  1159. X
  1160. void
  1161. setQuerySensitive(state)
  1162. int state;
  1163. {
  1164. X    int i;
  1165. X
  1166. X    XtSetSensitive(queryButton,(state > 0 ? True : False));
  1167. X    /* Disable the Lists so they get redrawn in "gray" */
  1168. X    for (i=0; i < NUM_BROWSER_PANES; i++)
  1169. X    XtSetSensitive(browserLists[i],(state > 0 ? True : False));
  1170. X    /* This is a simple way to disable the up/down buttons */
  1171. X    XtSetSensitive(browserForm,(state > 0 ? True : False));
  1172. X    /* Update the icon also (True=busy, when query off ie. state = 0) */
  1173. X    setIconStatus((state > 0) ? False : True);
  1174. }
  1175. X
  1176. void
  1177. setAbortSensitive(state)
  1178. int state;
  1179. {
  1180. X    XtSetSensitive(abortButton,(state > 0 ? True : False));
  1181. }
  1182. X
  1183. void
  1184. setUpSensitive(state)
  1185. int state;
  1186. {
  1187. X    XtSetSensitive(browserUpButton,(state > 0 ? True : False));
  1188. }
  1189. X
  1190. void
  1191. setDownSensitive(state)
  1192. int state;
  1193. {
  1194. X    XtSetSensitive(browserDownButton,(state > 0 ? True : False));
  1195. }
  1196. X
  1197. /*    -    -    -    -    -    -    -    -    */
  1198. /* Browser */
  1199. X
  1200. void
  1201. initBrowser()
  1202. {
  1203. X    /*EMPTY*//* Done by widget creation */
  1204. }
  1205. X
  1206. void
  1207. clearBrowser()
  1208. {
  1209. X    int pane;
  1210. X
  1211. X    for (pane=0; pane < NUM_BROWSER_PANES; pane++) {
  1212. X    clearBrowserPane(pane);
  1213. X    }
  1214. }
  1215. X
  1216. void
  1217. redrawBrowser()
  1218. {
  1219. X    /*EMPTY*/
  1220. }
  1221. X
  1222. /* Browser panes */
  1223. X
  1224. void
  1225. clearBrowserPane(pane)
  1226. int pane;
  1227. {
  1228. X    static char *emptyNames[] = { NULL };
  1229. X
  1230. #ifdef MULTILIST
  1231. X    XfwfMultiListSetNewData((XfwfMultiListWidget)browserLists[pane],
  1232. X                emptyNames,0,0,False,(Boolean *)NULL);
  1233. #else
  1234. X    XawListChange(browserLists[pane],emptyNames,0,0,False);
  1235. #endif
  1236. }
  1237. X
  1238. void
  1239. redrawBrowserPane(pane)
  1240. int pane;
  1241. {
  1242. #ifdef MULTILIST
  1243. X    XfwfMultiListSetNewData((XfwfMultiListWidget)browserLists[pane],
  1244. X                browserStrings[pane],0,0,True,(Boolean *)NULL);
  1245. #else
  1246. X    XawListChange(browserLists[pane],browserStrings[pane],0,0,True);
  1247. #endif
  1248. }
  1249. X
  1250. void
  1251. unhighlightBrowserPane(pane)
  1252. int pane;
  1253. {
  1254. #ifdef MULTILIST
  1255. X    XfwfMultiListUnhighlightAll((XfwfMultiListWidget)browserLists[pane]);
  1256. #else
  1257. X    XawListUnhighlight(browserLists[pane]);
  1258. #endif
  1259. }
  1260. X
  1261. /* Browser items */
  1262. X
  1263. /*ARGSUSED*/
  1264. void
  1265. clearBrowserItem(pane,item)
  1266. int pane,item;
  1267. {
  1268. X    /*EMPTY*/
  1269. }
  1270. X
  1271. /*ARGSUSED*/
  1272. void
  1273. redrawBrowserItem(pane,item)
  1274. int pane,item;
  1275. {
  1276. X    /*EMPTY*/
  1277. }
  1278. X
  1279. void
  1280. unhighlightBrowserItem(pane,item)
  1281. int pane,item;
  1282. {
  1283. #ifdef MULTILIST
  1284. X    XfwfMultiListUnhighlightItem((XfwfMultiListWidget)browserLists[pane],item);
  1285. #else
  1286. X    XawListUnhighlight(browserLists[pane]);
  1287. #endif
  1288. }
  1289. X
  1290. void
  1291. highlightBrowserItem(pane,item)
  1292. int pane,item;
  1293. {
  1294. X    Arg args[1];
  1295. X    int number;
  1296. X    float percent;
  1297. X
  1298. #ifdef MULTILIST
  1299. X    XfwfMultiListHighlightItem((XfwfMultiListWidget)browserLists[pane],item);
  1300. #else
  1301. X    XawListHighlight(browserLists[pane],item);
  1302. #endif
  1303. X    /* Move the scrollbar so we see the item */
  1304. X    if (appResources.autoScroll) {
  1305. X    XtSetArg(args[0],XtNnumberStrings,&number);
  1306. X    XtGetValues(browserLists[pane],args,1);
  1307. X    percent = (float)(item-1) / (float)number;
  1308. X    if (percent < 0.0)
  1309. X        percent = 0.0;
  1310. X    else if (percent > 100.)
  1311. X        percent = 100.0;
  1312. X    XtCallCallbacks(browserScrollbars[pane],
  1313. X            "jumpProc",(XtPointer)&percent);
  1314. X    }
  1315. }
  1316. X
  1317. void
  1318. setBrowserItem(pane,item,str)
  1319. int pane,item;
  1320. char *str;
  1321. {
  1322. X    /* Set the actual value */
  1323. X    setListString(pane,item,str);
  1324. X    /* Need a terminating NULL later, so add it now */
  1325. X    setListString(pane,item+1,NULL);
  1326. }
  1327. X
  1328. /* Browser actions */
  1329. X
  1330. void
  1331. nextBrowserPane()
  1332. {
  1333. X    /*EMPTY*//* Done with mouse */
  1334. }
  1335. X
  1336. void
  1337. prevBrowserPane()
  1338. {
  1339. X    /*EMPTY*//* Done with mouse */
  1340. }
  1341. X
  1342. void
  1343. nextBrowserItem()
  1344. {
  1345. X    /*EMPTY*//* Done with mouse */
  1346. }
  1347. X
  1348. void
  1349. prevBrowserItem()
  1350. {
  1351. X    /*EMPTY*//* Done with mouse */
  1352. }
  1353. X
  1354. void
  1355. toggleCurrentBrowserItem()
  1356. {
  1357. X    /*EMPTY*//* Done by X */
  1358. }
  1359. X
  1360. void
  1361. selectCurrentBrowserItem()
  1362. {
  1363. X    /*EMPTY*//* Done by X */
  1364. }
  1365. X
  1366. /*    -    -    -    -    -    -    -    -    */
  1367. /* Misc. display routines */
  1368. X
  1369. void
  1370. beep()
  1371. {
  1372. X    XBell(display,0);
  1373. }
  1374. X
  1375. /*    -    -    -    -    -    -    -    -    */
  1376. /*
  1377. X * setListString() : This routine provides access to the dynamically-grown
  1378. X *    lists of strings. I bzero() the allocated space even though I shouldn't
  1379. X *    need to.
  1380. X */
  1381. static void
  1382. setListString(pane,index,string)
  1383. int pane,index;
  1384. char *string;
  1385. {
  1386. X    char **oldStr;
  1387. X    int oldNum;
  1388. X
  1389. X    DEBUG3("setting index %d of pane %d to \"%s\"\n",index,pane,string);
  1390. X    if (pane >= NUM_BROWSER_PANES) {
  1391. X    alert2("Attempt to set string in pane %d: \"%s\"",(char *)pane,string);
  1392. X    return;
  1393. X    }
  1394. X    /* Free old string if there was one */
  1395. X    if (index < numBrowserStrings[pane]) {
  1396. X    XtFree((XtPointer)(*(browserStrings[pane]+index)));
  1397. X    DEBUG0("  freed old string\n");
  1398. X    }
  1399. X    /* If this is the first call, get the initial string array */
  1400. X    if (numBrowserStrings[pane] == 0) {
  1401. X    DEBUG0("  getting initial string array\n");
  1402. X    numBrowserStrings[pane] = INIT_NUM_BROWSER_STRINGS;
  1403. X    browserStrings[pane] = (char **)XtCalloc(numBrowserStrings[pane],
  1404. X                         sizeof(char *));
  1405. X    bzero((char *)(browserStrings[pane]),
  1406. X          numBrowserStrings[pane]*sizeof(char *));
  1407. X    }
  1408. X    DEBUG1("  string array is size %d\n",numBrowserStrings[pane]);
  1409. X    /* Grow the array until it's big enough for this string */
  1410. X    while (index >= numBrowserStrings[pane]) {
  1411. X    DEBUG0("  growing string array\n");
  1412. X    oldStr = browserStrings[pane];
  1413. X    oldNum = numBrowserStrings[pane];
  1414. X    numBrowserStrings[pane] = REALLOC_INCR(numBrowserStrings[pane]);
  1415. X    browserStrings[pane] = (char **)XtCalloc(numBrowserStrings[pane],
  1416. X                         sizeof(char *));
  1417. X    bzero((char *)(browserStrings[pane]),
  1418. X          numBrowserStrings[pane]*sizeof(char *));
  1419. X    bcopy((char *)oldStr,(char *)(browserStrings[pane]),
  1420. X          oldNum*sizeof(char *));
  1421. X    XtFree((XtPointer)oldStr);
  1422. X    }
  1423. X    DEBUG1("  string array is now size %d\n",numBrowserStrings[pane]);
  1424. X    /* Finally, set this value */
  1425. X    if (string == (char *)NULL)
  1426. X    *(browserStrings[pane]+index) = (char *)NULL;
  1427. X    else
  1428. X    *(browserStrings[pane]+index) = XtNewString(string);
  1429. X    DEBUG1("  done setting string \"%s\"\n",string);
  1430. }
  1431. SHAR_EOF
  1432. chmod 0644 xarchie-2.0.6/display-x.c ||
  1433. echo 'restore of xarchie-2.0.6/display-x.c failed'
  1434. Wc_c="`wc -c < 'xarchie-2.0.6/display-x.c'`"
  1435. test 8929 -eq "$Wc_c" ||
  1436.     echo 'xarchie-2.0.6/display-x.c: original size 8929, current size' "$Wc_c"
  1437. rm -f _shar_wnt_.tmp
  1438. fi
  1439. # ============= xarchie-2.0.6/display.h ==============
  1440. if test -f 'xarchie-2.0.6/display.h' -a X"$1" != X"-c"; then
  1441.     echo 'x - skipping xarchie-2.0.6/display.h (File already exists)'
  1442.     rm -f _shar_wnt_.tmp
  1443. else
  1444. > _shar_wnt_.tmp
  1445. echo 'x - extracting xarchie-2.0.6/display.h (Text)'
  1446. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/display.h' &&
  1447. /*
  1448. X * display.h : Definitions of device-independent interface functions
  1449. X *
  1450. X * This header file is used for both the X and Curses display routines.
  1451. X * Not all functions are needed for both types of display.
  1452. X *
  1453. X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  1454. X */
  1455. X
  1456. #ifndef DISPLAY_H
  1457. #define DISPLAY_H
  1458. X
  1459. #ifdef __STDC__
  1460. /* Text output routines */
  1461. extern void setTitleText(char *str), setStatusText(char *str);
  1462. extern void setSearchText(char *str), setHostText(char *str);
  1463. extern void setLocationText(char *str), setFileText(char *str);
  1464. extern void setSizeText(char *str), setModesText(char *str);
  1465. extern void setDateText(char *str);
  1466. X
  1467. /* Button sensitivity routines */
  1468. extern void setQuerySensitive(int state), setAbortSensitive(int state);
  1469. extern void setUpSensitive(int state), setDownSensitive(int state);
  1470. X
  1471. /* Browser routines */
  1472. extern void initBrowser(void),clearBrowser(void),redrawBrowser(void);
  1473. extern void clearBrowserPane(int pane), redrawBrowserPane(int pane);
  1474. extern void unhighlightBrowserPane(int pane);
  1475. extern void clearBrowserItem(int pane, int item);
  1476. extern void redrawBrowserItem(int pane, int item);
  1477. extern void unhighlightBrowserItem(int pane, int item);
  1478. extern void highlightBrowserItem(int pane, int item);
  1479. extern void setBrowserItem(int pane, int item, char *str);
  1480. /* Browser action routines */
  1481. extern void nextBrowserPane(void),prevBrowserPane(void);
  1482. extern void nextBrowserItem(void),prevBrowserItem(void);
  1483. extern void toggleCurrentBrowserItem(void),selectCurrentBrowserItem(void);
  1484. X
  1485. /* Misc. display routines */
  1486. extern void beep(void);
  1487. X
  1488. #else /*!__STDC__*/
  1489. X
  1490. /* Text output routines */
  1491. extern void setTitleText(), setStatusText();
  1492. extern void setSearchText(), setHostText(), setLocationText(), setFileText();
  1493. extern void setSizeText(), setModesText(), setDateText();
  1494. X
  1495. /* Button sensitivity routines */
  1496. extern void setQuerySensitive(), setAbortSensitive();
  1497. extern void setUpSensitive(), setDownSensitive();
  1498. X
  1499. /* Browser routines */
  1500. extern void initBrowser(),clearBrowser(),redrawBrowser();
  1501. extern void clearBrowserPane(), redrawBrowserPane(), unhighlightBrowserPane();
  1502. extern void clearBrowserItem(), redrawBrowserItem(), unhighlightBrowserItem();
  1503. extern void highlightBrowserItem(), setBrowserItem();
  1504. X
  1505. /* Browser action routines */
  1506. extern void nextBrowserPane(),prevBrowserPane();
  1507. extern void nextBrowserItem(),prevBrowserItem();
  1508. extern void toggleCurrentBrowserItem(),selectCurrentBrowserItem();
  1509. X
  1510. /* Misc. display routines */
  1511. extern void beep();
  1512. X
  1513. #endif /*!__STDC__*/
  1514. #endif /* DISPLAY_H */
  1515. SHAR_EOF
  1516. chmod 0644 xarchie-2.0.6/display.h ||
  1517. echo 'restore of xarchie-2.0.6/display.h failed'
  1518. Wc_c="`wc -c < 'xarchie-2.0.6/display.h'`"
  1519. test 2521 -eq "$Wc_c" ||
  1520.     echo 'xarchie-2.0.6/display.h: original size 2521, current size' "$Wc_c"
  1521. rm -f _shar_wnt_.tmp
  1522. fi
  1523. # ============= xarchie-2.0.6/fchooser.c ==============
  1524. if test -f 'xarchie-2.0.6/fchooser.c' -a X"$1" != X"-c"; then
  1525.     echo 'x - skipping xarchie-2.0.6/fchooser.c (File already exists)'
  1526.     rm -f _shar_wnt_.tmp
  1527. else
  1528. > _shar_wnt_.tmp
  1529. echo 'x - extracting xarchie-2.0.6/fchooser.c (Text)'
  1530. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/fchooser.c' &&
  1531. /*
  1532. X * fchooser.c : Xarchie interface to the FileChooser
  1533. X *
  1534. X * The FileChooser enforces very little policy. This wrapper adds
  1535. X * the following:
  1536. X * - The FileChooser is created with several other widgets: a Text
  1537. X *   widget, and OK button, and a cancel button. These are created in
  1538. X *   the sameparent, but other widgets can also be there.
  1539. X * - Selecting a file in the FileChooser just puts the string in the
  1540. X *   Text widget. You have to hit Ok to use it.
  1541. X * - When ok is clicked or Return typed, the directory from the fileChooser
  1542. X *   and the file from the Text are concatenated. If the result is a
  1543. X *   directory, the fileChooser is reset to that directory. Otherwise
  1544. X *   the callback is called with the filename as call_data.
  1545. X * - Leading tildes are expanded in directories entered in the Text widget.
  1546. X *
  1547. X * Oh yeah, if FILECHOOSER is not defined, ignore all that about it. In that
  1548. X * case we just have a Text and two buttons.
  1549. X *
  1550. X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  1551. X * 13 May 1993: Fixes for when FILECHOOSER not defined.
  1552. X * 14 May 1993: More of the same (find MAXPATHLEN), initialize dir.
  1553. X *
  1554. X */
  1555. #include "config.h"
  1556. #ifdef HAVE_SYS_PARAM_H
  1557. # include <sys/param.h>
  1558. #endif
  1559. X
  1560. #include <stdio.h>
  1561. #include <sys/types.h>
  1562. #include <sys/stat.h>
  1563. #include <X11/Intrinsic.h>
  1564. #include <X11/StringDefs.h>
  1565. #include <X11/keysym.h>
  1566. #include <X11/Xaw/Form.h>
  1567. #include <X11/Xaw/Label.h>
  1568. #include <X11/Xaw/AsciiText.h>
  1569. #include <X11/Xaw/Command.h>
  1570. #ifdef FILECHOOSER
  1571. #include <FChooser.h>
  1572. #endif
  1573. #include "fchooser.h"
  1574. #include "xarchie.h"
  1575. #include "xutil.h"
  1576. #include "tilde.h"
  1577. #include "status.h"
  1578. #include "alert.h"
  1579. #include "debug.h"
  1580. X
  1581. /*
  1582. X * Functions defined here:
  1583. X */
  1584. FileChooserInfo *createFileChooser(
  1585. #if NeedFunctionPrototypes
  1586. X    Widget shell,
  1587. X    Widget parent,
  1588. X    char *basename,
  1589. X    FileChooserOkProc okCallback,
  1590. X    FileChooserCancelProc cancelCallback,
  1591. X    XtPointer client_data
  1592. #endif
  1593. );
  1594. X
  1595. #ifdef FILECHOOSER
  1596. static void fileChooserCallback();
  1597. #endif
  1598. static void okButtonCallback(),cancelButtonCallback();
  1599. static void keyPressEventHandler(),nonmaskableEventHandler();
  1600. X
  1601. /*    -    -    -    -    -    -    -    -    */
  1602. X
  1603. FileChooserInfo *
  1604. createFileChooser(shell,parent,basename,okCallback,cancelCallback,client_data)
  1605. Widget shell,parent;
  1606. char *basename;
  1607. FileChooserOkProc okCallback;
  1608. FileChooserCancelProc cancelCallback;
  1609. XXtPointer client_data;
  1610. {
  1611. X    FileChooserInfo *info;
  1612. X    char name[64];
  1613. X    Arg args[1];
  1614. X
  1615. X    info = XtNew(FileChooserInfo);
  1616. X    info->shell = shell;
  1617. X    info->okCallback = okCallback;
  1618. X    info->cancelCallback = cancelCallback;
  1619. X    info->client_data = client_data;
  1620. #ifdef FILECHOOSER
  1621. X    status0("Initializing File Selector...");
  1622. X    sprintf(name,"%sFileChooser",basename);
  1623. X    info->fcw =
  1624. X    XtCreateManagedWidget(name,xfwfFileChooserWidgetClass,parent,NULL,0);
  1625. X    XtAddCallback(info->fcw,XtNcallback,fileChooserCallback,(XtPointer)info);
  1626. X    status0("Done.");
  1627. X    XtSetArg(args[0],XtNfromVert,info->fcw);
  1628. #else
  1629. X    XtSetArg(args[0],XtNfromVert,NULL);
  1630. #endif
  1631. X    sprintf(name,"%sTextLabel",basename);
  1632. X    (void)XtCreateManagedWidget(name,labelWidgetClass,parent,args,1);
  1633. X    sprintf(name,"%sText",basename);
  1634. X    info->text =
  1635. X    XtCreateManagedWidget(name,asciiTextWidgetClass,parent,args,1);
  1636. X    sprintf(name,"%sOkButton",basename);
  1637. X    info->okButton =
  1638. X    XtCreateManagedWidget(name,commandWidgetClass,parent,NULL,0);
  1639. X    XtAddCallback(info->okButton,XtNcallback,okButtonCallback,(XtPointer)info);
  1640. X    /* Allow Return in the Text to be Ok */
  1641. X    XtAddEventHandler(info->text,KeyPressMask,False,
  1642. X              keyPressEventHandler,(XtPointer)info);
  1643. X    sprintf(name,"%sCancelButton",basename);
  1644. X    info->cancelButton =
  1645. X    XtCreateManagedWidget(name,commandWidgetClass,parent,NULL,0);
  1646. X    XtAddCallback(info->cancelButton,XtNcallback,
  1647. X          cancelButtonCallback,(XtPointer)info);
  1648. X    /* Allow WM_DELETE_WINDOW to the Shell to be Cancel */
  1649. X    if (info->shell != NULL)
  1650. X    XtAddEventHandler(info->shell,NoEventMask,True,
  1651. X              nonmaskableEventHandler,(XtPointer)info);
  1652. X    return(info);
  1653. }
  1654. X
  1655. #ifdef FILECHOOSER
  1656. /*
  1657. X * When a selection is made, put the string in the Text item. If background
  1658. X * selected, clear the Text item.
  1659. X */
  1660. /*ARGSUSED*/
  1661. static void
  1662. fileChooserCallback(w,client_data,call_data)
  1663. Widget w;
  1664. XXtPointer client_data;    /* info */
  1665. XXtPointer call_data;    /* return struct */
  1666. {
  1667. X    FileChooserInfo *fcinfo = (FileChooserInfo *)client_data;
  1668. X    XfwfFileChooserReturnStruct *ret =
  1669. X    (XfwfFileChooserReturnStruct *)call_data;
  1670. X    Arg args[1];
  1671. X
  1672. X    DEBUG1("fileChooserCallback: fcinfo=0x%lx\n",fcinfo);
  1673. X    if (fcinfo == NULL || fcinfo->text == NULL)        /* creating */
  1674. X    return;
  1675. X    if (ret->file == NULL) {
  1676. X    XtSetArg(args[0],XtNstring,"");
  1677. X    } else {
  1678. X    XtSetArg(args[0],XtNstring,ret->file);
  1679. X    }
  1680. X    XtSetValues(fcinfo->text,args,1);
  1681. X    DEBUG0("fileChooserCallback: done\n");
  1682. }
  1683. #endif /* FILECHOOSER */
  1684. X
  1685. /*
  1686. X * If Ok is clicked, get the directory from the FileChooser (if FILECHOOSER)
  1687. X * and get the filename from the Text. Do tilde expansion. If result is
  1688. X * a directory, use it in the FileChooser, otherwise invoke the callback
  1689. X * passing filename and client_data. Finally free the info.
  1690. X */
  1691. /*ARGSUSED*/
  1692. static void
  1693. okButtonCallback(w,client_data,call_data)
  1694. Widget w;
  1695. XXtPointer client_data;    /* info */
  1696. XXtPointer call_data;    /* not used */
  1697. {
  1698. X    FileChooserInfo *fcinfo = (FileChooserInfo *)client_data;
  1699. X    static char filename[MAXPATHLEN];
  1700. X    struct stat statbuf;
  1701. X    char *dir,*file;
  1702. X
  1703. X    DEBUG1("okButtonCallback: fcinfo=0x%lx\n",fcinfo);
  1704. X    filename[0] = '\0';
  1705. #ifdef FILECHOOSER
  1706. X    dir = XfwfFileChooserCurrentDirectory((XfwfFileChooserWidget)(fcinfo->fcw));
  1707. X    DEBUG1("okButtonCallback: dir=\"%s\"\n",dir);
  1708. #else
  1709. X    dir = "";
  1710. #endif
  1711. X    file = getWidgetString(fcinfo->text);
  1712. X    if (file == NULL || *file == '\0') {
  1713. X    alert0("No filename specified!");
  1714. X    return;
  1715. X    }
  1716. X    DEBUG1("okButtonCallback: file=\"%s\"\n",file);
  1717. X    if (*file == '/') {                    /* absolute path */
  1718. X    strcpy(filename,file);
  1719. X    } else if (*file == '~') {                /* tilde path */
  1720. X    strcpy(filename,tildeExpand(file));
  1721. X    } else {                        /* relative to fcw */
  1722. X    sprintf(filename,"%s%s",dir,file);
  1723. X    }
  1724. X    DEBUG1("okButtonCallback: filename=\"%s\"\n",filename);
  1725. #ifdef FILECHOOSER
  1726. X    /* If we got a directory, go open it rather than use it */
  1727. X    if (stat(filename,&statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
  1728. X    XfwfFileChooserChangeDirectory((XfwfFileChooserWidget)fcinfo->fcw,
  1729. X                       filename);
  1730. X    return;
  1731. X    }
  1732. #endif    
  1733. X    if (fcinfo->okCallback != NULL) {
  1734. X    DEBUG0("okButtonCallback: calling okCallback...\n");
  1735. X    (*(fcinfo->okCallback))(fcinfo,filename,fcinfo->client_data);
  1736. X    }
  1737. X    DEBUG0("okButtonCallback: done\n");
  1738. }
  1739. X
  1740. /*
  1741. X * If Cancel is clicked, invoke the callback passing client_data.
  1742. X * Finally free the info.
  1743. X */
  1744. /*ARGSUSED*/
  1745. static void
  1746. cancelButtonCallback(w,client_data,call_data)
  1747. Widget w;
  1748. XXtPointer client_data;    /* fcinfo */
  1749. XXtPointer call_data;    /* not used */
  1750. {
  1751. X    FileChooserInfo *fcinfo = (FileChooserInfo *)client_data;
  1752. X
  1753. X    DEBUG1("cancelButtonCallback: fcinfo=0x%lx\n",fcinfo);
  1754. X    if (fcinfo->cancelCallback != NULL) {
  1755. X    DEBUG0("cancelButtonCallback: calling cancelCallback\n");
  1756. X    (*(fcinfo->cancelCallback))(fcinfo,fcinfo->client_data);
  1757. X    }
  1758. X    DEBUG0("cancelButtonCallback: done\n");
  1759. }
  1760. X
  1761. /*
  1762. X * KeyPress event handler for Text item: When Return is typed, act as if
  1763. X * OK had been clicked. If this event isn't Return, just let it be
  1764. X * dispatched normally.
  1765. X */
  1766. /*ARGSUSED*/
  1767. static void
  1768. keyPressEventHandler(w,client_data,event,continue_to_dispatch)
  1769. Widget w;
  1770. XXtPointer client_data;
  1771. XXEvent *event;
  1772. Boolean *continue_to_dispatch;
  1773. {
  1774. X    KeySym keysym;
  1775. X    char str[8];
  1776. X
  1777. X    DEBUG1("keyPressHandler: w=0x%x\n",w);
  1778. X    (void)XLookupString((XKeyEvent*)event,str,sizeof(str),&keysym,NULL);
  1779. X    if (keysym == XK_Return) {
  1780. X    DEBUG0("keyPressHandler: calling okButtonCallback...\n");
  1781. X    okButtonCallback(NULL,client_data,NULL);
  1782. X    }
  1783. X    DEBUG0("keyPressHandler: done\n");
  1784. }
  1785. X
  1786. /*
  1787. X * Nonmaskable event handler for Shell: If the event is a ClientMessage
  1788. X * of WM_PROTOCOLS then act as if Cancel had been clicked.
  1789. X */
  1790. /*ARGSUSED*/
  1791. static void
  1792. nonmaskableEventHandler(w,client_data,event,continue_to_dispatch)
  1793. Widget w;
  1794. XXtPointer client_data;
  1795. XXEvent *event;
  1796. Boolean *continue_to_dispatch;
  1797. {
  1798. X    DEBUG1("nonmaskableHandler: w=0x%x\n",w);
  1799. X    if (event->type == ClientMessage &&
  1800. X        event->xclient.data.l[0] == WM_DELETE_WINDOW) {
  1801. X    DEBUG0("nonmaskableHandler: calling cancelButtonCallback\n");
  1802. X    cancelButtonCallback(NULL,client_data,NULL);
  1803. X    }
  1804. X    DEBUG0("nonmaskableHandler: done\n");
  1805. }
  1806. SHAR_EOF
  1807. chmod 0644 xarchie-2.0.6/fchooser.c ||
  1808. echo 'restore of xarchie-2.0.6/fchooser.c failed'
  1809. Wc_c="`wc -c < 'xarchie-2.0.6/fchooser.c'`"
  1810. test 8468 -eq "$Wc_c" ||
  1811.     echo 'xarchie-2.0.6/fchooser.c: original size 8468, current size' "$Wc_c"
  1812. rm -f _shar_wnt_.tmp
  1813. fi
  1814. # ============= xarchie-2.0.6/fchooser.h ==============
  1815. if test -f 'xarchie-2.0.6/fchooser.h' -a X"$1" != X"-c"; then
  1816.     echo 'x - skipping xarchie-2.0.6/fchooser.h (File already exists)'
  1817.     rm -f _shar_wnt_.tmp
  1818. else
  1819. > _shar_wnt_.tmp
  1820. echo 'x - extracting xarchie-2.0.6/fchooser.h (Text)'
  1821. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/fchooser.h' &&
  1822. /*
  1823. X * fchooser.c : Xarchie interface to the FileChooser
  1824. X *
  1825. X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  1826. X */
  1827. X
  1828. #if NeedFunctionPrototypes
  1829. struct _FileChooserInfo;
  1830. #endif
  1831. X
  1832. typedef void (*FileChooserOkProc)(
  1833. #if NeedFunctionPrototypes
  1834. X    struct _FileChooserInfo *fcinfo,
  1835. X    char *filename,
  1836. X    XtPointer client_data
  1837. #endif
  1838. );
  1839. X
  1840. typedef void (*FileChooserCancelProc)(
  1841. #if NeedFunctionPrototypes
  1842. X    struct _FileChooserInfo *fcinfo,
  1843. X    XtPointer client_data
  1844. #endif
  1845. );
  1846. X
  1847. typedef struct _FileChooserInfo {
  1848. X    Widget shell;
  1849. #ifdef FILECHOOSER
  1850. X    Widget fcw;
  1851. #endif
  1852. X    Widget text;
  1853. X    Widget okButton,cancelButton;
  1854. X    FileChooserOkProc okCallback;
  1855. X    FileChooserCancelProc cancelCallback;
  1856. X    XtPointer client_data;
  1857. } FileChooserInfo;
  1858. X
  1859. extern FileChooserInfo *
  1860. createFileChooser(
  1861. #if NeedFunctionPrototypes
  1862. X    Widget shell,
  1863. X    Widget parent,
  1864. X    char *basename,
  1865. X    FileChooserOkProc okCallback,
  1866. X    FileChooserCancelProc cancelCallback,
  1867. X    XtPointer client_data
  1868. #endif
  1869. );
  1870. SHAR_EOF
  1871. chmod 0644 xarchie-2.0.6/fchooser.h ||
  1872. echo 'restore of xarchie-2.0.6/fchooser.h failed'
  1873. Wc_c="`wc -c < 'xarchie-2.0.6/fchooser.h'`"
  1874. test 988 -eq "$Wc_c" ||
  1875.     echo 'xarchie-2.0.6/fchooser.h: original size 988, current size' "$Wc_c"
  1876. rm -f _shar_wnt_.tmp
  1877. fi
  1878. # ============= xarchie-2.0.6/file-panel.c ==============
  1879. if test -f 'xarchie-2.0.6/file-panel.c' -a X"$1" != X"-c"; then
  1880.     echo 'x - skipping xarchie-2.0.6/file-panel.c (File already exists)'
  1881.     rm -f _shar_wnt_.tmp
  1882. else
  1883. > _shar_wnt_.tmp
  1884. echo 'x - extracting xarchie-2.0.6/file-panel.c (Text)'
  1885. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/file-panel.c' &&
  1886. /*
  1887. X * file-panel.c : The save-load-write panel
  1888. X *
  1889. X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  1890. X * 14 May 1993: Fixed #endif followed by non-comment.
  1891. X */
  1892. X
  1893. #include <stdio.h>
  1894. #include <X11/Intrinsic.h>
  1895. #include <X11/Shell.h>
  1896. #include <X11/StringDefs.h>
  1897. #include <X11/Xaw/Form.h>
  1898. #include <X11/Xaw/MenuButton.h>
  1899. #include <X11/Xaw/Label.h>
  1900. #ifdef FILECHOOSER
  1901. # include <FChooser.h>
  1902. #endif
  1903. #include "config.h"
  1904. #ifdef HAVE_SYS_PARAM_H
  1905. #include <sys/param.h>
  1906. #endif
  1907. #include "xarchie.h"
  1908. SHAR_EOF
  1909. true || echo 'restore of xarchie-2.0.6/file-panel.c failed'
  1910. fi
  1911. echo 'End of xarchie-2.0.6 part 7'
  1912. echo 'File xarchie-2.0.6/file-panel.c is continued in part 8'
  1913. echo 8 > _shar_seq_.tmp
  1914. exit 0
  1915.  
  1916. exit 0 # Just in case...
  1917. -- 
  1918.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  1919. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  1920.  "It's intuitively obvious to the |
  1921.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1922.