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

  1. Newsgroups: comp.sources.x
  2. From: ferguson@cs.rochester.edu (George Ferguson)
  3. Subject: v20i041:  xarchie - An X browser interface to Archie, v2.0.6, Part13/24
  4. Message-ID: <1993Jun15.223352.808@sparky.imd.sterling.com>
  5. X-Md4-Signature: 5b815cfce8a609b8aefbd25d6bfb1c48
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Tue, 15 Jun 1993 22:33:52 GMT
  9. Approved: chris@sparky.imd.sterling.com
  10.  
  11. Submitted-by: ferguson@cs.rochester.edu (George Ferguson)
  12. Posting-number: Volume 20, Issue 41
  13. Archive-name: xarchie/part13
  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/part13
  19.  
  20. #!/bin/sh
  21. # this is Part.13 (part 13 of xarchie-2.0.6)
  22. # do not concatenate these parts, unpack them in order with /bin/sh
  23. # file xarchie-2.0.6/pfs.h 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" != 13; 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/pfs.h'
  39. else
  40. echo 'x - continuing file xarchie-2.0.6/pfs.h'
  41. sed 's/^X//' << 'SHAR_EOF' >> 'xarchie-2.0.6/pfs.h' &&
  42. #  include <stdio.h>
  43. # else
  44. #  define NULL 0
  45. # endif /* MSDOS */
  46. #endif /* NULL */
  47. X
  48. #define        PFS_RELEASE    "Beta.4.2E"
  49. #define        PFS_SW_ID    "B42E"
  50. X
  51. /* moved up for vdir_init */
  52. #define BZERO(p)        bzero((char *)(p), sizeof(*(p)))
  53. X
  54. /* General Definitions */
  55. X
  56. #define        MAX_PTXT_LEN    1250     /* Max length of PTEXT structure   */
  57. #define        MAX_PTXT_HDR    32       /* Max offset for start            */
  58. #define        P_ERR_STRING_SZ 100     /* Size of error string        */
  59. #define        MAX_VPATH    1024     /* Max length of virtual pathname  */
  60. X
  61. /* Definition of text structure used to pass text around */
  62. X
  63. struct ptext {
  64. X    int            length;          /* Length of text (from start)    */
  65. X    char        *start;          /* Start of text            */
  66. X    char        dat[MAX_PTXT_LEN+2*MAX_PTXT_HDR];/* The data itself */
  67. X    unsigned long     mbz;          /* ZERO to catch runaway strings  */
  68. X    struct ptext    *previous;        /* Previous element in list       */
  69. X    struct ptext    *next;          /* Next element in linked list    */
  70. X    int            seq;          /* Sequence Number            */
  71. };
  72. X
  73. typedef struct ptext *PTEXT;
  74. typedef struct ptext PTEXT_ST;
  75. X
  76. /* Request structure: maintains information about server requests */
  77. struct preq {
  78. X    int            cid;          /* Connection ID                  */
  79. X    short        priority;      /* Connection priority            */
  80. X    int            pf_priority;      /* Priority assigned by pri_func  */
  81. X    int            recv_tot;      /* Total # of packets received    */
  82. X    int            trns_tot;      /* Total # of packets to transmit */
  83. X    struct ptext    *cpkt;          /* Current packet being filled in */
  84. X    struct ptext    *recv;          /* Received packets               */
  85. X    struct ptext    *trns;          /* Transmitted packets            */
  86. X    int            rcvd_thru;      /* Received all packets through # */
  87. X    struct preq        *previous;        /* Previous element in list       */
  88. X    struct preq        *next;          /* Next element in linked list    */
  89. X    struct sockaddr_in    fromto;       /* Sender/Destination            */
  90. };
  91. X
  92. typedef struct preq *PREQ;
  93. typedef struct preq PREQ_ST;
  94. X
  95. X
  96. /* Definition of structure containing information on virtual link */
  97. X
  98. struct vlink {
  99. X    int            dontfree;      /* Flag: don't free this link     */
  100. X    char        *name;          /* Component of path name        */
  101. X    char        linktype;      /* L = Link, U = Union, N= Native */
  102. X    int            expanded;      /* Has a union link been expanded */
  103. X    char        *type;            /* Type of object pointed to      */
  104. X    struct vlink    *filters;      /* Filters associated with link   */
  105. X    struct vlink    *replicas;      /* Replicas (* see comment below) */
  106. X    char        *hosttype;      /* Type of hostname            */
  107. X    char        *host;          /* Files physical location        */
  108. X    char        *nametype;      /* Type of filename            */
  109. X    char        *filename;      /* System level filename        */
  110. X    long        version;      /* Version number of destination  */
  111. X    long        f_magic_no;      /* File's magic number        */
  112. X    struct acl        *acl;          /* ACL for link            */
  113. X    long        dest_exp;      /* Expiration for dest of link    */
  114. X    long        link_exp;      /* Expiration of link itself      */
  115. X    char        *args;          /* Arguments if this is a filter  */
  116. X    struct pattrib    *lattrib;      /* Attributes associated w/ link  */
  117. X    struct pfile    *f_info;      /* Info to be assoicated w/ file  */
  118. X    struct vlink    *previous;        /* Previous elt in linked list    */
  119. X    struct vlink    *next;          /* Next element in linked list    */
  120. };
  121. X
  122. typedef struct vlink *VLINK;
  123. typedef struct vlink VLINK_ST;
  124. X
  125. /* * Note that vlink->replicas is not really a list of replicas of the  */
  126. /*   object.  Instead, it is a list of the objects returned during name */
  127. /*   resolution that share the same name as the current object.  Such   */
  128. /*   an object should only be considered a replica if it also shares    */
  129. /*   the same non-zero magic number.                                    */
  130. X
  131. /* Definition of structure continiaing virtual directory information    */
  132. X
  133. struct vdir {
  134. X    int            version;      /* Version of local directory fmt  */
  135. X    int            inc_native;      /* Include the native directory    */
  136. X    long        magic_no;      /* Magic number of current file    */
  137. X    struct acl        *dacl;            /* Default acl for links in dir    */
  138. X    struct pfile    *f_info;      /* Directory file info             */
  139. X    struct vlink    *links;          /* The directory entries         */
  140. X    struct vlink    *lastlink;      /* Last directory entry            */
  141. X    struct vlink    *ulinks;      /* The entries for union links     */
  142. X    struct vdir        *previous;        /* Previous element in linked list */
  143. X    struct vdir        *next;          /* Next element in linked list     */
  144. };
  145. X
  146. typedef struct vdir *PVDIR;
  147. typedef struct vdir VDIR_ST;
  148. X
  149. /* Initialize directory */
  150. #define vdir_init(dir)  BZERO(dir)
  151. /* XXX: was
  152. X
  153. X  dir->version = 0;     dir->inc_native = 0; \
  154. X  dir->magic_no = 0;    dir->f_info = NULL; \
  155. X  dir->links = NULL;    dir->lastlink = NULL; \
  156. X  dir->ulinks = NULL;   dir->dacl = NULL; \
  157. X  dir->previous = NULL; dir->next = NULL;
  158. */
  159. X
  160. #define vdir_copy(d1,d2) d2->version = d1->version; \
  161. X                         d2->inc_native = d1->inc_native; \
  162. X                         d2->magic_no = d1->magic_no; \
  163. X                 d2->f_info = d1->f_info; \
  164. X                         d2->links = d1->links; \
  165. X                         d2->lastlink = d1->lastlink; \
  166. X                         d2->ulinks = d1->ulinks; \
  167. X                         d2->dacl = d1->dacl; \
  168. X                         d2->previous = d1->previous; \
  169. X                         d2->next = d1->next; 
  170. X                         
  171. /* Values of ->inc_native in vdir structure */
  172. #define VDIN_REALONLY    -1   /* Include native files, but not . and ..       */
  173. #define VDIN_NONATIVE     0   /* Do not include files from native directory   */
  174. #define VDIN_INCLNATIVE     1   /* Include files from native directory          */
  175. #define VDIN_NATIVEONLY  2   /* All entries in directory are from native dir */
  176. #define VDIN_PSEUDO      3   /* Directory is not real                        */
  177. X
  178. X
  179. /* Definition of structure containing information on a specific file */
  180. X
  181. union avalue {
  182. X    char        *ascii;        /* Character string                */
  183. X    struct vlink    *link;        /* A link               */
  184. };
  185. X
  186. X
  187. struct pattrib {
  188. X    char        precedence;    /* Precedence for link attribute   */
  189. X    char        *aname;        /* Name of the attribute           */
  190. X    char        *avtype;    /* Type of the attribute value     */
  191. X    union avalue    value;        /* Attribute Value                 */
  192. X    struct pattrib    *previous;      /* Previous element in linked list */
  193. X    struct pattrib    *next;        /* Next element in linked list     */
  194. };
  195. X
  196. typedef struct pattrib *PATTRIB;
  197. typedef struct pattrib PATTRIB_ST;
  198. X
  199. #define     ATR_PREC_OBJECT  'O'   /* Authoritative answer for object */
  200. #define     ATR_PREC_LINK    'L'   /* Authoritative answer for link   */
  201. #define     ATR_PREC_CACHED  'C'   /* Object info cached w/ link      */
  202. #define     ATR_PREC_REPLACE 'R'   /* From link (replaces O)          */
  203. #define     ATR_PREC_ADD     'A'   /* From link (additional value)    */
  204. X
  205. /* **** Incomplete **** */
  206. struct pfile {
  207. X    int            version;      /* Version of local finfo format   */
  208. X    long        f_magic_no;      /* Magic number of current file    */
  209. X    long        exp;          /* Expiration date of timeout      */
  210. X    long        ttl;          /* Time to live after reference    */
  211. X    long        last_ref;      /* Time of last reference          */
  212. X    struct vlink    *forward;      /* List of forwarding pointers     */
  213. X    struct vlink    *backlinks;      /* Partial list of back links      */
  214. X    struct pattrib    *attributes;      /* List of file attributes         */
  215. X    struct pfile    *previous;        /* Previous element in linked list */
  216. X    struct pfile    *next;          /* Next element in linked list     */
  217. };
  218. X
  219. typedef struct pfile *PFILE;
  220. typedef struct pfile PFILE_ST;
  221. X
  222. /* Definition of structure contining an access control list entry */
  223. X
  224. struct acl {
  225. X    int            acetype;      /* Access Contol Entry type       */
  226. X    char        *atype;           /* Authentication type            */
  227. X    char        *rights;          /* Rights                         */
  228. X    char        *principals;      /* Authorized principals          */
  229. X    struct restrict     *restrictions;    /* Restrictions on use            */
  230. X    struct acl        *previous;        /* Previous elt in linked list    */
  231. X    struct acl        *next;          /* Next element in linked list    */
  232. };
  233. typedef struct acl *ACL;
  234. typedef struct acl ACL_ST;
  235. X
  236. #define ACL_NONE        0         /* Nobody authorized by ths entry */
  237. #define ACL_DEFAULT        1         /* System default                 */
  238. #define ACL_SYSTEM        2         /* System administrator           */
  239. #define ACL_OWNER               3         /* Directory owner                */
  240. #define ACL_DIRECTORY           4         /* Same as directory              */
  241. #define ACL_ANY                 5         /* Any user                       */
  242. #define ACL_AUTHENT             6         /* Authenticated principal        */
  243. #define ACL_LGROUP              7         /* Local group                    */
  244. #define ACL_GROUP               8         /* External group                 */
  245. #define ACL_ASRTHOST            10        /* Check host and asserted userid */
  246. #define ACL_TRSTHOST            11        /* ASRTHOST from privileged port  */
  247. X
  248. X
  249. /* Definition of structure contining access restrictions */
  250. /* for future extensions                                 */
  251. struct restrict {
  252. X    struct acl        *previous;        /* Previous elt in linked list    */
  253. X    struct acl        *next;          /* Next element in linked list    */
  254. };
  255. X
  256. /* Definitions for send_to_dirsrv */
  257. #define    CLIENT_DIRSRV_TIMEOUT        4    /* time between retries      */
  258. #define CLIENT_DIRSRV_BACKOFF(x)  (2 * x)    /* Backoff algorithm         */
  259. #define CLIENT_DIRSRV_RETRY        3    /* retry this many times     */
  260. X
  261. /* Definitions for rd_vlink and rd_vdir */
  262. #define        SYMLINK_NESTING 10       /* Max nesting depth for sym links */
  263. X
  264. /* Definition fo check_acl */
  265. #define        ACL_NESTING     10       /* Max depth for ACL group nesting */
  266. X
  267. /* Flags for mk_vdir */
  268. #define         MKVD_LPRIV     1   /* Minimize privs for creator in new ACL    */
  269. X
  270. /* Flags for get_vdir */
  271. #define         GVD_UNION      0    /* Do not expand union links              */
  272. #define      GVD_EXPAND     1   /* Expand union links locally             */
  273. #define         GVD_LREMEXP    3   /* Request remote expansion of local links   */
  274. #define         GVD_REMEXP     7   /* Request remote expansion of all links     */
  275. #define         GVD_VERIFY     8    /* Only verify args are for a directory      */
  276. #define      GVD_FIND       16   /* Stop expanding when match is found        */
  277. #define         GVD_ATTRIB    32   /* Request attributes from remote server     */
  278. #define         GVD_NOSORT       64   /* Do not sort links when adding to dir      */
  279. X
  280. /* Flags for rd_vdir */
  281. #define         RVD_UNION      GVD_UNION
  282. #define         RVD_EXPAND     GVD_EXPAND 
  283. #define         RVD_LREMEXP    GVD_LREMEXP
  284. #define         RVD_REMEXP     GVD_REMEXP
  285. #define         RVD_DFILE_ONLY GVD_VERIFY /* Only return ptr to dir file        */
  286. #define      RVD_FIND       GVD_FIND   
  287. #define      RVD_ATTRIB     GVD_ATTRIB
  288. #define         RVD_NOSORT        GVD_NOSORT
  289. #define         RVD_NOCACHE    128
  290. X
  291. /* Flags for add_vlink */
  292. #define         AVL_UNION      1   /* Link is a union link                      */
  293. X
  294. /* Flags for vl_insert */
  295. #define         VLI_NOCONFLICT 0   /* Do not insert links w/ conflicting names  */
  296. #define      VLI_ALLOW_CONF 1   /* Allow links with conflicting names        */
  297. #define         VLI_NOSORT     2   /* Allow conflicts and don't sort            */
  298. X
  299. /* Flags for mapname */
  300. #define      MAP_READWRITE  0   /* Named file to be read and written         */
  301. #define         MAP_READONLY   1   /* Named file to be read only                */
  302. X
  303. /* Flags for modify_acl */
  304. #define         MACL_NOSYSTEM   0x01
  305. #define      MACL_NOSELF     0x02
  306. #define      MACL_DEFAULT    0x08
  307. #define      MACL_SET        0x0C
  308. #define      MACL_INSERT     0x14
  309. #define      MACL_DELETE     0x10
  310. #define      MACL_ADD        0x1C
  311. #define      MACL_SUBTRACT   0x18
  312. #define      MACL_LINK       0x00
  313. #define      MACL_DIRECTORY  0x20
  314. #define      MACL_OBJECT     0x60
  315. #define      MACL_INCLUDE    0x40
  316. X
  317. #define      MACL_OP    (MACL_DEFAULT|MACL_SET|MACL_INSERT|\
  318. X             MACL_DELETE|MACL_ADD|MACL_SUBTRACT)
  319. X
  320. #define      MACL_OTYPE (MACL_LINK|MACL_DIRECTORY|MACL_OBJECT|MACL_INCLUDE)
  321. X
  322. /* Flags for dsrdir */
  323. #define DSRD_ATTRIBUTES                      0x1 /* Fill in attributes for links */
  324. X
  325. /* Access methods returned by Pget_am */
  326. #define P_AM_ERROR            0
  327. #define P_AM_FTP            1
  328. #define P_AM_AFTP            2  /* Anonymous FTP  */
  329. #define P_AM_NFS            4
  330. #define P_AM_KNFS            8  /* Kerberized NFS */
  331. #define P_AM_AFS               16
  332. X
  333. /* Return codes */
  334. X
  335. #define        PSUCCESS    0
  336. #define        PFAILURE    255
  337. X
  338. /* Hush up warnings.  */
  339. void vllfree();
  340. X
  341. /* Procedures in libpfs.a */
  342. X
  343. char *pget_wdhost(), *pget_wdfile(), *pget_wd(), *pget_hdhost();
  344. char *pget_hdfile(), *pget_hd(), *pget_rdhost(), *pget_rdfile();
  345. char *pget_dhost(), *pget_dfile(), *pget_vsname(), *nlsindex();
  346. char *sindex(), *nxtline(), *unquote(), *stcopy();
  347. char *stcopyr(), *readheader(), *month_sname();
  348. X
  349. long        asntotime();
  350. void        procquery();
  351. X
  352. PTEXT        ptalloc();
  353. PTEXT        dirsend();
  354. void        ptfree();
  355. void        ptlfree();
  356. X
  357. PREQ        pralloc();
  358. PREQ        get_next_request();
  359. X
  360. VLINK        rd_slink();
  361. VLINK        rd_vlink();
  362. VLINK        vl_delete();
  363. VLINK        vlalloc();
  364. VLINK        vlcopy();
  365. void        vlfree();
  366. X
  367. PFILE        pfalloc();
  368. X
  369. PATTRIB         parse_attribute();
  370. PATTRIB         atalloc();
  371. PATTRIB     pget_at();
  372. void        atfree();
  373. void        atlfree();
  374. X
  375. ACL             acalloc();
  376. ACL             get_acl();
  377. X
  378. void        stfree();
  379. X
  380. /* Miscellaneous useful definitions */
  381. #ifndef TRUE
  382. #define TRUE        1
  383. #define FALSE        0
  384. #endif
  385. X
  386. #define AUTHORIZED      1
  387. #define NOT_AUTHORIZED  0
  388. #define NEG_AUTHORIZED  -1
  389. X
  390. #ifndef NULL
  391. #define NULL        0
  392. #endif
  393. X
  394. #define FAILED        -1
  395. X
  396. #endif /* PFS_H */
  397. SHAR_EOF
  398. echo 'File xarchie-2.0.6/pfs.h is complete' &&
  399. chmod 0644 xarchie-2.0.6/pfs.h ||
  400. echo 'restore of xarchie-2.0.6/pfs.h failed'
  401. Wc_c="`wc -c < 'xarchie-2.0.6/pfs.h'`"
  402. test 14346 -eq "$Wc_c" ||
  403.     echo 'xarchie-2.0.6/pfs.h: original size 14346, current size' "$Wc_c"
  404. rm -f _shar_wnt_.tmp
  405. fi
  406. # ============= xarchie-2.0.6/pmachine.h ==============
  407. if test -f 'xarchie-2.0.6/pmachine.h' -a X"$1" != X"-c"; then
  408.     echo 'x - skipping xarchie-2.0.6/pmachine.h (File already exists)'
  409.     rm -f _shar_wnt_.tmp
  410. else
  411. > _shar_wnt_.tmp
  412. echo 'x - extracting xarchie-2.0.6/pmachine.h (Text)'
  413. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/pmachine.h' &&
  414. /*
  415. X * This is where we drop in the various dependencies for different systems.
  416. X * Someday this might be remotely complete.
  417. X *
  418. X * I kept the name pmachine.h because it was already in all of the files...this
  419. X * barely resembles the pmachine.h that comes with the real Prospero, though.
  420. X *
  421. X * $Revision: 1.12 $
  422. X * gf 23 Nov 1992 : Added section for defining malloc() & co.
  423. X */
  424. X
  425. #ifdef u3b2
  426. # define USG
  427. # define NOREGEX
  428. # define MAXPATHLEN 1024       /* There's no maxpathlen in any 3b2 .h file.  */
  429. #endif
  430. X
  431. #ifdef m88k
  432. #define MAXPATHLEN 1024
  433. #endif
  434. X
  435. #ifdef hpux
  436. # ifndef bcopy
  437. #  define FUNCS            /* HP/UX 8.0 has the fns.  */
  438. # endif
  439. # define NOREGEX
  440. # define NEED_STRING_H
  441. #endif
  442. X
  443. /* These are required for a Sequent running Dynix/PTX, their SysV variant.
  444. X   Archie builds fine untouched on a system running their BSD-based OS.  */
  445. #ifdef _SEQUENT_
  446. # define NOREGEX
  447. # define USG
  448. #endif
  449. X
  450. #if defined(USG) || defined(SYSV)
  451. # define FUNCS
  452. #endif
  453. X
  454. #ifdef SOLARIS2
  455. #define FUNCS
  456. #define NOREGEX
  457. #define NEED_STRING_H
  458. #endif
  459. X
  460. #ifdef ISC
  461. # define FUNCS
  462. # define STRSPN
  463. # define NOREGEX
  464. #endif
  465. X
  466. #ifdef PCNFS
  467. # define FUNCS
  468. # define NEED_STRING_H
  469. #ifndef MSDOS
  470. # define MSDOS
  471. #endif
  472. #endif
  473. X
  474. #ifdef CUTCP
  475. # define FUNCS
  476. # define NOREGEX
  477. # define NEED_STRING_H
  478. # define SELECTARG int
  479. # ifndef MSDOS
  480. #  define MSDOS
  481. # endif
  482. #endif
  483. X
  484. #ifdef _AUX_SOURCE
  485. # define AUX
  486. # define NOREGEX
  487. # define NBBY 8    /* Number of bits in a byte.  */
  488. typedef long Fd_mask;
  489. # define NFDBITS (sizeof(Fd_mask) * NBBY)    /* bits per mask */
  490. #endif
  491. X
  492. #ifdef OS2
  493. # define NOREGEX
  494. # include <pctcp.h>
  495. #endif
  496. #ifdef MSDOS
  497. # define USG
  498. # define NOREGEX
  499. # include <string.h>
  500. # include <stdlib.h>
  501. #endif
  502. X
  503. #ifdef _AIX
  504. # ifdef u370
  505. #  define FUNCS
  506. # endif /* AIX/370 */
  507. # define _NONSTD_TYPES
  508. # define _BSD_INCLUDES
  509. # define NEED_STRING_H
  510. # define NEED_SELECT_H
  511. # define NEED_TIME_H
  512. #endif
  513. X
  514. /* General problems.  */
  515. X
  516. #ifdef FUNCS
  517. # define index        strchr
  518. /* According to mycroft@gnu.ai.mit.edu. */
  519. # ifdef _IBMR2
  520. char *strchr();
  521. # endif
  522. # define rindex        strrchr
  523. # ifndef _AUX_SOURCE
  524. #  define bcopy(a,b,n)    memcpy(b,a,n)
  525. #  define bzero(a,n)    memset(a,0,n)
  526. # ifdef _IBMR2
  527. char *memset();
  528. # endif
  529. # endif
  530. #endif
  531. X
  532. #if defined(_IBMR2) || defined(_BULL_SOURCE)
  533. # define NEED_SELECT_H
  534. #endif
  535. #if defined(USG) || defined(UTS)
  536. # define NEED_STRING_H
  537. #endif
  538. #if defined(USG) || defined(UTS) || defined(_AUX_SOURCE)
  539. # define NEED_TIME_H
  540. # ifdef UTS
  541. #  define WANT_BOTH_TIME
  542. # endif
  543. #endif
  544. X
  545. #ifdef VMS
  546. /* Get the system status stuff.  */
  547. # include <ssdef.h>
  548. #endif /* VMS */
  549. X
  550. /*
  551. X * FD_SET: lib/pfs/dirsend.c, user/vget/ftp.c
  552. X */
  553. #ifndef CUTCP
  554. X
  555. #define SELECTARG fd_set
  556. #if !defined(FD_SET) && !defined(VMS) && !defined(NEED_SELECT_H)
  557. #define    FD_SETSIZE    32
  558. #define    FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  559. #define    FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  560. #define    FD_ISSET(n, p)    ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  561. #undef FD_ZERO
  562. #define FD_ZERO(p)    bzero((char *)(p), sizeof(*(p)))
  563. #endif
  564. X
  565. #endif /* not CUTCP */
  566. SHAR_EOF
  567. chmod 0644 xarchie-2.0.6/pmachine.h ||
  568. echo 'restore of xarchie-2.0.6/pmachine.h failed'
  569. Wc_c="`wc -c < 'xarchie-2.0.6/pmachine.h'`"
  570. test 3020 -eq "$Wc_c" ||
  571.     echo 'xarchie-2.0.6/pmachine.h: original size 3020, current size' "$Wc_c"
  572. rm -f _shar_wnt_.tmp
  573. fi
  574. # ============= xarchie-2.0.6/popups.c ==============
  575. if test -f 'xarchie-2.0.6/popups.c' -a X"$1" != X"-c"; then
  576.     echo 'x - skipping xarchie-2.0.6/popups.c (File already exists)'
  577.     rm -f _shar_wnt_.tmp
  578. else
  579. > _shar_wnt_.tmp
  580. echo 'x - extracting xarchie-2.0.6/popups.c (Text)'
  581. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/popups.c' &&
  582. /*
  583. X * popups.c : Generic blocking popup routines
  584. X *
  585. X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  586. X */
  587. X
  588. #include <stdio.h>
  589. #include <X11/Intrinsic.h>
  590. #include <X11/StringDefs.h>
  591. #include <X11/Shell.h>
  592. #include <X11/Xaw/Dialog.h>
  593. extern Widget toplevel;        /* this is the only external */
  594. X
  595. /*
  596. X * Functions defined here:
  597. X */
  598. Widget createPopup();                /* Generic popup routines */
  599. void setPopupLabel();
  600. void popupMainLoop();
  601. void popupDone();                /* Call this when done */
  602. X
  603. static void centerWidgetAndMouse();
  604. X
  605. /*
  606. X * Data defined here:
  607. X */
  608. static int popupIsDone;
  609. X
  610. /*    -    -    -    -    -    -    -    -    */
  611. X
  612. Widget
  613. createPopup(basename,num_buttons,callback)
  614. char *basename;
  615. int num_buttons;
  616. XXtCallbackProc callback;
  617. {
  618. X    Widget shell,dialog;
  619. X    char name[256];
  620. X    int i;
  621. X
  622. X    sprintf(name,"%sShell",basename);
  623. X    shell = XtCreatePopupShell(name,transientShellWidgetClass,toplevel,NULL,0);
  624. X    sprintf(name,"%sDialog",basename);
  625. X    dialog = XtCreateManagedWidget(name,dialogWidgetClass,shell,NULL,0);
  626. X    for (i=0; i < num_buttons; i++) {
  627. X    sprintf(name,"%sButton%d",basename,i);
  628. X    XawDialogAddButton(dialog,name,callback,(XtPointer)i);
  629. X    }
  630. X    XtRealizeWidget(shell);
  631. X    return(shell);
  632. }
  633. X
  634. void
  635. setPopupLabel(w,basename,str)
  636. Widget w;
  637. char *basename,*str;
  638. {
  639. X    char name[256];
  640. X    Widget dialog;
  641. X    Arg args[1];
  642. X
  643. X    sprintf(name,"%sDialog",basename);
  644. X    dialog = XtNameToWidget(w,name);
  645. X    XtSetArg(args[0],XtNlabel,str);
  646. X    XtSetValues(dialog,args,1);
  647. }
  648. X
  649. /*
  650. X * Popup "shell" with an exclusive grab, then dispatch events until
  651. X * popupDone becomes True, then pop "shell" down.
  652. X */
  653. void
  654. popupMainLoop(shell)
  655. Widget shell;
  656. {
  657. X    /* Go synchronous or the widgets don't resize properly */
  658. X    XSynchronize(XtDisplay(toplevel),True);
  659. X    /* Center the popup */
  660. X    centerWidgetAndMouse(shell,toplevel,shell);
  661. X    /* Beep */
  662. X    XBell(XtDisplay(toplevel),0);
  663. X    /* Pop it up and block until one of the buttons is clicked */
  664. X    popupIsDone = 0;
  665. X    XtPopup(shell,XtGrabExclusive);
  666. X    while (!popupIsDone) {
  667. X    /*
  668. X     * Only dispatch XEvents since we don't want input events or
  669. X     * timers to get in the way
  670. X     */
  671. X    XtAppProcessEvent(XtWidgetToApplicationContext(toplevel),XtIMXEvent);
  672. X    }
  673. X    /* Okay, pop it down */
  674. X    XtPopdown(shell);
  675. #ifndef DEBUG
  676. X    /* Back to normal */
  677. X    XSynchronize(XtDisplay(toplevel),False);
  678. #endif
  679. }
  680. X
  681. void
  682. popupDone()
  683. {
  684. X    popupIsDone = 1;
  685. }
  686. X
  687. /*    -    -    -    -    -    -    -    -    */
  688. /*
  689. X * Center widget "widget" inside widget "pwidget" and warp mouse to middle
  690. X * of "mwidget".
  691. X */
  692. static void
  693. centerWidgetAndMouse(widget,pwidget,mwidget)
  694. Widget widget,pwidget,mwidget;
  695. {
  696. X    Arg args[2];
  697. X    Window rwin,child;
  698. X    int x,y,px,py;
  699. X    unsigned int w,h,pw,ph,bw,d;
  700. X
  701. X    /* Get child size */
  702. X    XGetGeometry(XtDisplay(widget),XtWindow(widget),
  703. X         &rwin,&x,&y,&w,&h,&bw,&d);
  704. X    /* Get parent size, position */
  705. X    XGetGeometry(XtDisplay(pwidget),XtWindow(pwidget),
  706. X         &rwin,&px,&py,&pw,&ph,&bw,&d);
  707. X    /* Need position in root window coords, don't ask me why */
  708. X    XTranslateCoordinates(XtDisplay(widget),XtWindow(pwidget),rwin,
  709. X              px,py,&x,&y,&child);
  710. X    px = x;
  711. X    py = y;
  712. X    /* Compute child position */
  713. X    x = px + pw/2 - w/2;
  714. X    if (x < 0)
  715. X    x = 0;
  716. X    else if (x > WidthOfScreen(XtScreen(widget))-w)
  717. X    x = WidthOfScreen(XtScreen(widget))-w;
  718. X    y = py + ph/2 - h/2;
  719. X    if (y < 0)
  720. X    y = 0;
  721. X    else if (y > HeightOfScreen(XtScreen(widget))-h)
  722. X    y = WidthOfScreen(XtScreen(widget))-h;
  723. X    /* Set child position */
  724. X    XtSetArg(args[0],XtNx,x);
  725. X    XtSetArg(args[1],XtNy,y);
  726. X    XtSetValues(widget,args,2);
  727. X    /* Get dest size, position */
  728. X    XGetGeometry(XtDisplay(mwidget),XtWindow(mwidget),
  729. X         &rwin,&x,&y,&w,&h,&bw,&d);
  730. X    /* Move mouse there */
  731. X    XWarpPointer(XtDisplay(mwidget),None,XtWindow(mwidget),
  732. X         0,0,0,0,w/2,h/2);
  733. }
  734. SHAR_EOF
  735. chmod 0644 xarchie-2.0.6/popups.c ||
  736. echo 'restore of xarchie-2.0.6/popups.c failed'
  737. Wc_c="`wc -c < 'xarchie-2.0.6/popups.c'`"
  738. test 3747 -eq "$Wc_c" ||
  739.     echo 'xarchie-2.0.6/popups.c: original size 3747, current size' "$Wc_c"
  740. rm -f _shar_wnt_.tmp
  741. fi
  742. # ============= xarchie-2.0.6/popups.h ==============
  743. if test -f 'xarchie-2.0.6/popups.h' -a X"$1" != X"-c"; then
  744.     echo 'x - skipping xarchie-2.0.6/popups.h (File already exists)'
  745.     rm -f _shar_wnt_.tmp
  746. else
  747. > _shar_wnt_.tmp
  748. echo 'x - extracting xarchie-2.0.6/popups.h (Text)'
  749. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/popups.h' &&
  750. /*
  751. X * popups.h : External defs for alert, confirm, and dialog boxes
  752. X *
  753. X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  754. X */
  755. X
  756. #ifndef POPUPS_H
  757. #define POPUPS_H
  758. X
  759. extern Widget createPopup();            /* Generic popup routines */
  760. extern void setPopupLabel();
  761. extern void popupMainLoop();
  762. extern void popupDone();            /* Call this when done */
  763. X
  764. #endif
  765. SHAR_EOF
  766. chmod 0644 xarchie-2.0.6/popups.h ||
  767. echo 'restore of xarchie-2.0.6/popups.h failed'
  768. Wc_c="`wc -c < 'xarchie-2.0.6/popups.h'`"
  769. test 350 -eq "$Wc_c" ||
  770.     echo 'xarchie-2.0.6/popups.h: original size 350, current size' "$Wc_c"
  771. rm -f _shar_wnt_.tmp
  772. fi
  773. # ============= xarchie-2.0.6/pprot.h ==============
  774. if test -f 'xarchie-2.0.6/pprot.h' -a X"$1" != X"-c"; then
  775.     echo 'x - skipping xarchie-2.0.6/pprot.h (File already exists)'
  776.     rm -f _shar_wnt_.tmp
  777. else
  778. > _shar_wnt_.tmp
  779. echo 'x - extracting xarchie-2.0.6/pprot.h (Text)'
  780. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/pprot.h' &&
  781. /*
  782. X * Copyright (c) 1989, 1990, 1991 by the University of Washington
  783. X *
  784. X * For copying and distribution information, please see the file
  785. X * <copyright.h>.
  786. X */
  787. X
  788. #include <copyright.h>
  789. X
  790. #ifndef MAXPATHLEN
  791. # ifdef VMS
  792. #  define MAXPATHLEN 32
  793. # else /* not VMS */
  794. #  if defined(MSDOS) && !defined(OS2)
  795. #   define MAXPATHLEN 255
  796. #  else /* not MSDOS */
  797. #   ifdef ISC
  798. #    define MAXPATHLEN 512
  799. #   else /* not Interactive..normal! (gasp) */
  800. #    include <sys/param.h>
  801. #   endif /* ISC */
  802. #  endif /* MSDOS && !OS2 */
  803. # endif /* VMS */
  804. #endif
  805. X
  806. /* Protocol Definitions */
  807. X
  808. #define           VFPROT_VNO    1      /* Protocol Version Number           */
  809. X
  810. #define           DIRSRV_PORT      1525   /* Server port used if not in srvtab */
  811. #define        PROSPERO_PORT    191    /* Officially assigned prived port   */
  812. #define           PROS_FIRST_PRIVP 901    /* First privileged port to try      */
  813. #define        PROS_NUM_PRIVP   20     /* Number of privileged ports to try */
  814. X
  815. #define           MAXPKT            1024   /* Max size of response from server  */
  816. #define           SEQ_SIZE        32     /* Max size of sequence text in resp */ 
  817. #define           MAX_DIR_LINESIZE 160+MAXPATHLEN /* Max linesize in directory */
  818. X
  819. #define           MAX_FWD_DEPTH    20     /* Max fwd pointers to follow        */
  820. X
  821. #define S_AD_SZ        sizeof(struct sockaddr_in)
  822. X
  823. /* Replacement for strtok that doesn't keep state.  Both the variable  */
  824. /* S and the variable S_next must be defined.  To initialize, assign   */
  825. /* the string to be stepped through to S_next, then call get_token on  */
  826. /* S.  The first token will be in S, and S_next will point to the next */
  827. /* token.  Like strtok, this macro does modify the string passed to it */
  828. #ifdef __GNUC__
  829. #define get_token(S,C) \
  830. X  do { \
  831. X    S = S##_next; \
  832. X    if(S) { \
  833. X     while(*S == C) S++; \
  834. X     S##_next = index(S,C); \
  835. X     if(S##_next) *(S##_next++) = '\0'; \
  836. X     if(!*S) S = NULL; \
  837. X    } \
  838. X  } while (0)
  839. #else
  840. #define get_token(S,C) \
  841. X    S = S/**/_next; \
  842. X  do { \
  843. X    if(S) { \
  844. X     while(*S == C) S++; \
  845. X     S/**/_next = index(S,C); \
  846. X     if(S/**/_next) *(S/**/_next++) = '\0'; \
  847. X     if(!*S) S = NULL; \
  848. X    } \
  849. X  } while (0)
  850. #endif /* __GNUC__ */
  851. SHAR_EOF
  852. chmod 0644 xarchie-2.0.6/pprot.h ||
  853. echo 'restore of xarchie-2.0.6/pprot.h failed'
  854. Wc_c="`wc -c < 'xarchie-2.0.6/pprot.h'`"
  855. test 2159 -eq "$Wc_c" ||
  856.     echo 'xarchie-2.0.6/pprot.h: original size 2159, current size' "$Wc_c"
  857. rm -f _shar_wnt_.tmp
  858. fi
  859. # ============= xarchie-2.0.6/ptalloc.c ==============
  860. if test -f 'xarchie-2.0.6/ptalloc.c' -a X"$1" != X"-c"; then
  861.     echo 'x - skipping xarchie-2.0.6/ptalloc.c (File already exists)'
  862.     rm -f _shar_wnt_.tmp
  863. else
  864. > _shar_wnt_.tmp
  865. echo 'x - extracting xarchie-2.0.6/ptalloc.c (Text)'
  866. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/ptalloc.c' &&
  867. /*
  868. X * Copyright (c) 1989, 1990, 1991 by the University of Washington
  869. X *
  870. X * For copying and distribution information, please see the file
  871. X * <copyright.h>.
  872. X *
  873. X * v1.3.2 - bpk - for Archie client 1.3.2, except gf ZERO->BZERO
  874. X * v1.1.2 - gf  11/02/91 - renamed ZERO() to BZERO() for X
  875. X */
  876. X
  877. #include <copyright.h>
  878. #include <stdio.h>
  879. X
  880. #include <pfs.h>
  881. #include "config.h"    /* gf */
  882. #include "stringdefs.h"    /* for correct definition of bzero used by BZERO */
  883. #ifdef MSDOS
  884. # define free _pfree   /* otherwise we get conflicts with free() */
  885. #endif
  886. X
  887. static PTEXT    free = NULL;
  888. int         ptext_count = 0;
  889. int        ptext_max = 0;
  890. X
  891. /*
  892. X * ptalloc - allocate and initialize ptext structure
  893. X *
  894. X *    PTALLOC returns a pointer to an initialized structure of type
  895. X *    PTEXT.  If it is unable to allocate such a structure, it
  896. X *    returns NULL.
  897. X */
  898. PTEXT
  899. ptalloc()
  900. X    {
  901. X    PTEXT    vt;
  902. X    if(free) {
  903. X        vt = free;
  904. X        free = free->next;
  905. X    }
  906. X    else {
  907. X        vt = (PTEXT) malloc(sizeof(PTEXT_ST));
  908. X        if (!vt) return(NULL);
  909. X        ptext_max++;
  910. X    }
  911. X    ptext_count++;
  912. X
  913. X    /* nearly all parts are 0 [or NULL] */
  914. X    BZERO(vt);
  915. X    /* The offset is to leave room for additional headers */
  916. X    vt->start = vt->dat + MAX_PTXT_HDR;
  917. X
  918. X    return(vt);
  919. X    }
  920. X
  921. /*
  922. X * ptfree - free a VTEXT structure
  923. X *
  924. X *    VTFREE takes a pointer to a VTEXT structure and adds it to
  925. X *    the free list for later reuse.
  926. X */
  927. void
  928. ptfree(vt)
  929. X    PTEXT    vt;
  930. X    {
  931. X    vt->next = free;
  932. X    vt->previous = NULL;
  933. X    free = vt;
  934. X    ptext_count--;
  935. X    }
  936. X
  937. /*
  938. X * ptlfree - free a VTEXT structure
  939. X *
  940. X *    VTLFREE takes a pointer to a VTEXT structure frees it and any linked
  941. X *    VTEXT structures.  It is used to free an entrie list of VTEXT
  942. X *    structures.
  943. X */
  944. void
  945. ptlfree(vt)
  946. X    PTEXT    vt;
  947. X    {
  948. X    PTEXT    nxt;
  949. X
  950. X    while(vt != NULL) {
  951. X        nxt = vt->next;
  952. X        ptfree(vt);
  953. X        vt = nxt;
  954. X    }
  955. X    }
  956. X
  957. SHAR_EOF
  958. chmod 0644 xarchie-2.0.6/ptalloc.c ||
  959. echo 'restore of xarchie-2.0.6/ptalloc.c failed'
  960. Wc_c="`wc -c < 'xarchie-2.0.6/ptalloc.c'`"
  961. test 1798 -eq "$Wc_c" ||
  962.     echo 'xarchie-2.0.6/ptalloc.c: original size 1798, current size' "$Wc_c"
  963. rm -f _shar_wnt_.tmp
  964. fi
  965. # ============= xarchie-2.0.6/query.c ==============
  966. if test -f 'xarchie-2.0.6/query.c' -a X"$1" != X"-c"; then
  967.     echo 'x - skipping xarchie-2.0.6/query.c (File already exists)'
  968.     rm -f _shar_wnt_.tmp
  969. else
  970. > _shar_wnt_.tmp
  971. echo 'x - extracting xarchie-2.0.6/query.c (Text)'
  972. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/query.c' &&
  973. /*
  974. X * query.c : Programmatic Prospero interface to Archie
  975. X *
  976. X * Copyright (c) 1991 by the University of Washington
  977. X *
  978. X * For copying and distribution information, please see the file
  979. X * <copyright.h>.
  980. X *
  981. X * Originally part of the Prospero Archie client by Clifford 
  982. X * Neuman (bcn@isi.edu).  Modifications, addition of programmatic interface,
  983. X * and new sorting code by George Ferguson (ferguson@cs.rochester.edu) 
  984. X * and Brendan Kehoe (brendan@cs.widener.edu).
  985. X *
  986. X * v2.0   - 04/23/93 (gf)  - for xarchie 2.0 - and now we part company...
  987. X * v1.3.2 - bpk - for Archie client 1.3.2
  988. X * v1.2.0 - 09/17/91 (bpk) - added BULL & USG stuff, thanks to Jim Sillas
  989. X * v1.1.3 - 08/30/91 (bpk) - cast index()
  990. X * v1.1.2 - 08/20/91 (bcn) - make it do it properly (new invdatecmplink)
  991. X * v1.1.1 - 08/20/91 (bpk) - made sorting go inverted as we purport it does
  992. X */
  993. #include <copyright.h>
  994. #include <stdio.h>
  995. #include <pfs.h>
  996. #include <perrno.h>
  997. #include <archie.h>
  998. X
  999. #include "config.h"
  1000. #ifdef TM_IN_SYS_TIME
  1001. # include <sys/time.h>
  1002. #else
  1003. # include <time.h>
  1004. #endif
  1005. #include "stringdefs.h"
  1006. #include "xtypes.h"
  1007. #include "db.h"
  1008. #include "appres.h"
  1009. #include "browser.h"
  1010. #include "alert.h"
  1011. #include "status.h"
  1012. #include "debug.h"
  1013. extern DbEntry *db;
  1014. X
  1015. /* These are in dirsend.c */
  1016. extern int client_dirsrv_timeout,client_dirsrv_retry,rdgram_priority;
  1017. X
  1018. /* Functions defined here: */
  1019. void queryItemAndParse(),queryHostAndParse(),queryLocationAndParse();
  1020. VLINK stringQuery();
  1021. int parseArchieQueryResults(), parseStringQueryResults();
  1022. int handleProsperoErrors();
  1023. X
  1024. static void doQueryAndParse();
  1025. static void parseHostAndFilename(), parseAttributes();
  1026. X
  1027. /* Data defined here */
  1028. int pfs_debug;
  1029. X
  1030. /*    -    -    -    -    -    -    -    -    */
  1031. /*
  1032. X * Main function to call to process a query from the user.
  1033. X */
  1034. void
  1035. queryItemAndParse(query)
  1036. char *query;
  1037. {
  1038. X    char qstring[MAX_VPATH];
  1039. X
  1040. X    DEBUG1("queryItemAndParse: \"%s\"\n",query);
  1041. X    sprintf(qstring,"ARCHIE/MATCH(%d,%d,%c)/%s",
  1042. X        appResources.maxHits,appResources.offset,appResources.searchType,
  1043. X        query);
  1044. X    doQueryAndParse(qstring);
  1045. X    DEBUG0("queryItemAndParse: done\n");
  1046. }
  1047. X
  1048. /*
  1049. X * Main function to open a host specified by the user.
  1050. X */
  1051. void
  1052. queryHostAndParse(hostname)
  1053. char *hostname;
  1054. {
  1055. X    char qstring[MAX_VPATH];
  1056. X
  1057. X    DEBUG1("queryHostAndParse: \"%s\"\n",hostname);
  1058. X    sprintf(qstring,"ARCHIE/HOST/%s",hostname);
  1059. X    doQueryAndParse(qstring);
  1060. X    DEBUG0("queryHostAndParse: done\n");
  1061. }
  1062. X
  1063. /*
  1064. X * Main function to open a host specified by the user.
  1065. X */
  1066. void
  1067. queryLocationAndParse(hostname,location)
  1068. char *hostname,*location;
  1069. {
  1070. X    char qstring[MAX_VPATH];
  1071. X
  1072. X    DEBUG2("queryLocationAndParse: \"%s:%s\"\n",hostname,location);
  1073. X    sprintf(qstring,"ARCHIE/HOST/%s%s",hostname,location);
  1074. X    doQueryAndParse(qstring);
  1075. X    DEBUG0("queryLocationAndParse: done\n");
  1076. }
  1077. X
  1078. /*
  1079. X * Used by both query functions to send the string to Archie and interpret
  1080. X * the results into the browser.
  1081. X */
  1082. static void
  1083. doQueryAndParse(str)
  1084. char *str;
  1085. {
  1086. X    VLINK links;
  1087. X    int num;
  1088. X
  1089. X    /* Send the query to Archie */
  1090. X    DEBUG1("doQueryAndParse: \"%s\"\n",str);
  1091. X    DEBUG0("calling stringQuery...\n");
  1092. X    links = stringQuery(appResources.archieHost,str);
  1093. X    DEBUG0("calling handleProsperoErrors...\n");
  1094. X    (void)handleProsperoErrors();
  1095. X    /* If we aborted or had an error, then don't clear the db */
  1096. X    if (links == NULL ) {
  1097. X    /* Wasn't an error... */
  1098. X    if (perrno == PSUCCESS)
  1099. X        status0("No matches -- Ready.");
  1100. X    return;
  1101. X    }
  1102. X    /* Reset browser to leftmost position */
  1103. X    resetBrowser();
  1104. X    /* Empty (and free) previous contents of database */
  1105. X    clearEntries(db);
  1106. X    /* Process the results into the database */
  1107. X    status0("Parsing...");
  1108. X    DEBUG0("calling parseArchieQueryResults\n");
  1109. X    switch(appResources.sortType) {
  1110. X    case GfName:
  1111. X        num = parseArchieQueryResults(db,links,cmpEntryNames);
  1112. X        break;
  1113. X    case GfDate:
  1114. X        num = parseArchieQueryResults(db,links,cmpEntryDates);
  1115. X        break;
  1116. X    case GfWeight:
  1117. X        num = parseArchieQueryResults(db,links,cmpEntryWeights);
  1118. X        break;
  1119. X    }
  1120. X    /* Display results in browser */
  1121. X    DEBUG0("calling displayEntries\n");
  1122. X    displayEntries(db,0);
  1123. X    status1("Found %d matches -- Ready",(char *)num);
  1124. X    DEBUG0("doQueryAndParse: done\n");
  1125. }
  1126. X
  1127. /*    -    -    -    -    -    -    -    -    */
  1128. /*
  1129. X * Returns an unsorted, untranslated list of vlinks for string from host.
  1130. X */
  1131. VLINK
  1132. stringQuery(host,string)
  1133. char *host,*string;
  1134. {
  1135. X    VLINK links;        /* Matches returned by server */
  1136. X    VDIR_ST dir_st;        /* Filled in by get_vdir      */
  1137. X    PVDIR dir = &dir_st;
  1138. X    VLINK p,nextp,r;
  1139. X    int    tmp;
  1140. X    
  1141. X    /* initialize Prospero globals from appResources */
  1142. X    pfs_debug = appResources.debugLevel;
  1143. X    rdgram_priority = appResources.niceLevel;
  1144. X    client_dirsrv_timeout = appResources.timeout;
  1145. X    client_dirsrv_retry = appResources.retries;
  1146. X
  1147. X    /* Initialize Prospero structures */
  1148. X    perrno = PSUCCESS; *p_err_string = '\0';
  1149. X    pwarn = PNOWARN; *p_warn_string = '\0';
  1150. X    vdir_init(dir);
  1151. X    
  1152. X    /* Retrieve the list of matches, return error if there was one */
  1153. #if defined(MSDOS)
  1154. X    if ((tmp=get_vdir(host,string,"",dir,
  1155. X              (long)GVD_ATTRIB|GVD_NOSORT,NULL,NULL)) != 0) {
  1156. #else
  1157. X    if ((tmp=get_vdir(host,string,"",dir,
  1158. X              GVD_ATTRIB|GVD_NOSORT,NULL,NULL)) != 0) {
  1159. # endif
  1160. X    perrno = tmp;
  1161. X    return(NULL);
  1162. X    }
  1163. X    
  1164. X    /* Save the links, and clear in dir in case it's used again   */
  1165. X    links = dir->links; dir->links = NULL;
  1166. X    
  1167. X    /* As returned, list is sorted by suffix, and conflicting     */
  1168. X    /* suffixes appear on a list of "replicas".  We want to       */
  1169. X    /* create a one-dimensional list sorted by host then filename */
  1170. X    /* and maybe by some other parameter                          */
  1171. X    
  1172. X    /* First flatten the doubly-linked list */
  1173. X    for (p = links; p != NULL; p = nextp) {
  1174. X    nextp = p->next;
  1175. X    if (p->replicas != NULL) {
  1176. X        p->next = p->replicas;
  1177. X        p->next->previous = p;
  1178. X        for (r = p->replicas; r->next != NULL; r = r->next)
  1179. X        /*EMPTY*/ ;
  1180. X        r->next = nextp;
  1181. X        nextp->previous = r;
  1182. X        p->replicas = NULL;
  1183. X    }
  1184. X    }
  1185. X    perrno = PSUCCESS;
  1186. X    return(links);
  1187. }
  1188. X
  1189. /*    -    -    -    -    -    -    -    -    */
  1190. /*
  1191. X * Here take the list of untranslated unsorted links and put them into the
  1192. X * database, translating and sorting as needed. The entries are added to
  1193. X * make a host-location-file hierarchy as appropriate for the top of the
  1194. X * database query for a query. Returns number of entries returned from query.
  1195. X * This routine is also used by the routine that reloads a database.
  1196. X */
  1197. int
  1198. parseArchieQueryResults(parent,links,cmp_proc)
  1199. DbEntry *parent;
  1200. VLINK links;
  1201. int (*cmp_proc)();
  1202. {
  1203. X    VLINK vl;
  1204. X    DbEntry *firstHost,*firstLoc;
  1205. X    DbEntry *thisHost,*thisLoc,*thisFile;
  1206. X    char hostname[MAX_VPATH],location[MAX_VPATH],filename[MAX_VPATH];
  1207. X    int type;
  1208. #ifdef MSDOS
  1209. X    unsigned long size;
  1210. #else
  1211. X    int size;
  1212. #endif
  1213. X    char *modes,*gt_date,*archie_date;
  1214. X    int num;
  1215. X
  1216. X    DEBUG0("parseArchieQueryResults: parsing links...\n");
  1217. X    num = 0;
  1218. X    firstHost = firstLoc = NULL;
  1219. X    for (vl=links; vl != NULL; vl = vl->next) {
  1220. X    parseHostAndFilename(vl,hostname,location,filename);
  1221. X    parseAttributes(vl,&type,&size,&modes,&archie_date,>_date);
  1222. X    if (firstHost == NULL) {
  1223. X        firstHost = thisHost = addEntry(parent,NULL);
  1224. X        firstLoc = thisLoc = addEntry(firstHost,NULL);
  1225. X        thisFile = addEntry(firstLoc,NULL);
  1226. X    } else {
  1227. X        if ((thisHost=findEntryFromString(parent,hostname)) == NULL)
  1228. X        thisHost = addEntry(parent,NULL);
  1229. X        if ((thisLoc=findEntryFromString(thisHost,location)) == NULL)
  1230. X        thisLoc = addEntry(thisHost,NULL);
  1231. X        thisFile = addEntry(thisLoc,NULL);
  1232. X    }
  1233. X    setEntryData(thisHost,hostname,DB_HOST,0,"","","",NULL);
  1234. X    setEntryData(thisLoc,location,DB_LOCATION,0,"","","",NULL);
  1235. X    setEntryData(thisFile,filename,type,size,modes,archie_date,gt_date,vl);
  1236. X    num += 1;
  1237. X    }
  1238. X    DEBUG0("parseArchieQueryResults: sorting entries...\n");
  1239. X    sortEntriesRecursively(parent,cmp_proc);
  1240. X    DEBUG1("parseArchieQueryResults: returning %d matches\n",num);
  1241. X    return(num);
  1242. }
  1243. X
  1244. /*
  1245. X * Like parseArchieQueryresults(), but all the entries for the links are
  1246. X * added as immediate children of parent, rather than a three-level tree.
  1247. X * This is used to expand the browser below some item.
  1248. X */
  1249. int
  1250. parseStringQueryResults(parent,links,cmp_proc)
  1251. DbEntry *parent;
  1252. VLINK links;
  1253. int (*cmp_proc)();
  1254. {
  1255. X    VLINK vl;
  1256. X    DbEntry *dbp;
  1257. X    char hostname[MAX_VPATH],location[MAX_VPATH],filename[MAX_VPATH];
  1258. X    int type,size;
  1259. X    char *modes,*gt_date,*archie_date;
  1260. X    int num;
  1261. X
  1262. X    DEBUG0("parseStringQueryResults: parsing links...\n");
  1263. X    num = 0;
  1264. X    for (vl=links; vl != NULL; vl = vl->next) {
  1265. X    parseHostAndFilename(vl,hostname,location,filename);
  1266. X    parseAttributes(vl,&type,&size,&modes,&archie_date,>_date);
  1267. X    dbp = addEntry(parent,NULL);
  1268. X    setEntryData(dbp,filename,type,size,modes,archie_date,gt_date,vl);
  1269. X    num += 1;
  1270. X    }
  1271. X    DEBUG0("parseStringQueryResults: sortign entries...\n");
  1272. X    sortEntriesRecursively(parent,cmp_proc);
  1273. X    DEBUG1("parseStringQueryResults: returning %d matches\n",num);
  1274. X    return(num);
  1275. }
  1276. X    
  1277. /*
  1278. X * Fills in hostname, location, and filename with the appropriately-translated
  1279. X * and adjusted information from the link vl.
  1280. X */
  1281. static void
  1282. parseHostAndFilename(vl,hostname,location,filename)
  1283. VLINK vl;
  1284. char *hostname,*location,*filename;
  1285. {
  1286. X    char *slash;
  1287. X
  1288. X    DEBUG3(" input:host=\"%s\"\n       filename=\"%s\"\n       name=\"%s\"\n",
  1289. X       vl->host,vl->filename,vl->name);
  1290. X    /* If the link is for an Archie pseudo-directory, adjust names. */
  1291. X    if (strcmp(vl->type,"DIRECTORY") == 0 &&
  1292. X    strncmp(vl->filename,"ARCHIE/HOST",11) == 0) {
  1293. X    strcpy(hostname,vl->filename+12);
  1294. X    slash = index(hostname,'/');
  1295. X    if (slash != NULL) {
  1296. X        strcpy(filename,slash);
  1297. X        *slash = '\0';
  1298. X    } else
  1299. X        strcpy(filename,"/");
  1300. X    } else {
  1301. X    /* else just use the names as is */
  1302. X    strcpy(hostname,vl->host);
  1303. X    strcpy(filename,vl->filename);
  1304. X    }
  1305. X    /* The "location" is the leading part of the pathname */
  1306. X    strcpy(location,filename);
  1307. X    slash = rindex(location,'/');
  1308. X    /* If filename ends with slash, try going back one more slash */
  1309. X    if (slash && *(slash+1) == '\0')
  1310. X    slash = (char *)rindex(slash,'/');
  1311. X    if (slash) {
  1312. X    strcpy(filename,slash+1);
  1313. X    *slash = '\0';
  1314. X    } else
  1315. X    strcpy(location,"/");
  1316. X    /* If filename was /foo, then we need to leave the slash there */
  1317. X    if (*location == '\0')
  1318. X    strcpy(location,"/");
  1319. X    DEBUG3(" output:host=\"%s\"\n        location=\"%s\"\n        filename=\"%s\"\n",
  1320. X       hostname,location,filename);
  1321. }
  1322. X
  1323. /*
  1324. X * Fills in *sizep, *modesp, and archie_date with the information in the
  1325. X * attribute list of the link vl.
  1326. X */
  1327. static void
  1328. parseAttributes(vl,typep,sizep,modesp,archie_datep,gt_datep)
  1329. VLINK vl;
  1330. int *typep;
  1331. #ifdef MSDOS
  1332. unsigned long *sizep;
  1333. #else
  1334. int *sizep;
  1335. #endif
  1336. char **modesp,**archie_datep,**gt_datep;
  1337. {
  1338. X    static char date[64];
  1339. X    PATTRIB ap;
  1340. X    int  gt_year,gt_mon,gt_day,gt_hour,gt_min;
  1341. X    struct tm *presenttime;
  1342. X    long now;
  1343. X
  1344. X    (void)time(&now);
  1345. X    presenttime = localtime(&now);
  1346. X    if (strcmp(vl->type,"DIRECTORY") == 0) {
  1347. X    *typep = DB_DIRECTORY;
  1348. X    } else {
  1349. X    *typep = DB_FILE;
  1350. X    }
  1351. X    *sizep = 0;
  1352. X    *modesp = "";
  1353. X    *archie_datep = "";
  1354. X    *gt_datep = "";
  1355. X    gt_year = gt_mon = gt_day = gt_hour = gt_min = 0;
  1356. X    for (ap = vl->lattrib; ap; ap = ap->next) {
  1357. X    if (strcmp(ap->aname,"SIZE") == 0) {
  1358. #ifdef MSDOS
  1359. X        sscanf(ap->value.ascii,"%lu",sizep);
  1360. #else
  1361. X        sscanf(ap->value.ascii,"%d",sizep);
  1362. #endif
  1363. X    } else if(strcmp(ap->aname,"UNIX-MODES") == 0) {
  1364. X        *modesp = ap->value.ascii;
  1365. X    } else if(strcmp(ap->aname,"LAST-MODIFIED") == 0) {
  1366. X        *gt_datep = ap->value.ascii;
  1367. X        sscanf(*gt_datep,"%4d%2d%2d%2d%2d",>_year,
  1368. X           >_mon, >_day, >_hour, >_min);
  1369. X        if ((12 * (presenttime->tm_year + 1900 - gt_year) +
  1370. X         presenttime->tm_mon - gt_mon) > 6)
  1371. X        sprintf(date,"%s %2d %4d",month_sname(gt_mon),
  1372. X            gt_day, gt_year);
  1373. X        else
  1374. X        sprintf(date,"%s %2d %02d:%02d",month_sname(gt_mon),
  1375. X            gt_day, gt_hour, gt_min);
  1376. X        *archie_datep = date;
  1377. X    }
  1378. X    }
  1379. }
  1380. X
  1381. /*
  1382. X * Pops up alerts depending on perrno and pwarn.
  1383. X * Used in several places after calling Archie.
  1384. X */
  1385. int
  1386. handleProsperoErrors()
  1387. {
  1388. X    int err = 0;
  1389. X
  1390. X    /* Error? */
  1391. X    if (perrno != PSUCCESS) {
  1392. X    if (p_err_text[perrno]) {
  1393. X      if (*p_err_string)
  1394. X        alert2("Prospero error: %.100s - %.100s",p_err_text[perrno],
  1395. X            p_err_string);
  1396. X      else
  1397. X        alert1("Prospero error: %.200s",p_err_text[perrno]);
  1398. X    } else
  1399. X        alert1("Prospero error: Undefined error %d (prospero)",(char*)perrno);
  1400. X    err = 1;
  1401. X    }
  1402. X    /* Warning? */
  1403. X    if (pwarn != PNOWARN) {
  1404. X        if (*p_warn_string)
  1405. X            alert2("Prospero warning: %.100s - %.100s",
  1406. X                   p_warn_text[pwarn], p_warn_string);
  1407. X        else
  1408. X            alert1("Prospero warning: %.200s",p_warn_text[pwarn]);
  1409. X        status0("Ready");
  1410. X    }
  1411. X    return(err);
  1412. }
  1413. SHAR_EOF
  1414. chmod 0644 xarchie-2.0.6/query.c ||
  1415. echo 'restore of xarchie-2.0.6/query.c failed'
  1416. Wc_c="`wc -c < 'xarchie-2.0.6/query.c'`"
  1417. test 12690 -eq "$Wc_c" ||
  1418.     echo 'xarchie-2.0.6/query.c: original size 12690, current size' "$Wc_c"
  1419. rm -f _shar_wnt_.tmp
  1420. fi
  1421. # ============= xarchie-2.0.6/query.h ==============
  1422. if test -f 'xarchie-2.0.6/query.h' -a X"$1" != X"-c"; then
  1423.     echo 'x - skipping xarchie-2.0.6/query.h (File already exists)'
  1424.     rm -f _shar_wnt_.tmp
  1425. else
  1426. > _shar_wnt_.tmp
  1427. echo 'x - extracting xarchie-2.0.6/query.h (Text)'
  1428. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/query.h' &&
  1429. /*
  1430. X * query.h : Interface routines to Prospero querying
  1431. X *
  1432. X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  1433. X */
  1434. X
  1435. #include "pfs.h"
  1436. X
  1437. extern void queryItemAndParse(),queryHostAndParse(),queryLocationAndParse();
  1438. extern VLINK stringQuery();
  1439. extern int parseArchieQueryResults(), parseStringQueryResults();
  1440. extern int handleProsperoErrors();
  1441. SHAR_EOF
  1442. chmod 0644 xarchie-2.0.6/query.h ||
  1443. echo 'restore of xarchie-2.0.6/query.h failed'
  1444. Wc_c="`wc -c < 'xarchie-2.0.6/query.h'`"
  1445. test 347 -eq "$Wc_c" ||
  1446.     echo 'xarchie-2.0.6/query.h: original size 347, current size' "$Wc_c"
  1447. rm -f _shar_wnt_.tmp
  1448. fi
  1449. # ============= xarchie-2.0.6/rdgram.h ==============
  1450. if test -f 'xarchie-2.0.6/rdgram.h' -a X"$1" != X"-c"; then
  1451.     echo 'x - skipping xarchie-2.0.6/rdgram.h (File already exists)'
  1452.     rm -f _shar_wnt_.tmp
  1453. else
  1454. > _shar_wnt_.tmp
  1455. echo 'x - extracting xarchie-2.0.6/rdgram.h (Text)'
  1456. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/rdgram.h' &&
  1457. /*
  1458. X * Copyright (c) 1991 by the University of Washington
  1459. X *
  1460. X * For copying and distribution information, please see the file
  1461. X * <copyright.h>.
  1462. X */
  1463. X
  1464. #include <copyright.h>
  1465. X
  1466. /* Queuing priorities for datagrams */
  1467. #define           RDGRAM_MAX_PRI   32765  /* Maximum user proiority          */
  1468. #define           RDGRAM_MAX_SPRI  32767  /* Maximum priority for system use */
  1469. #define           RDGRAM_MIN_PRI  -32765  /* Maximum user proiority          */
  1470. #define           RDGRAM_MIN_SPRI -32768  /* Maximum priority for system use */
  1471. SHAR_EOF
  1472. chmod 0644 xarchie-2.0.6/rdgram.h ||
  1473. echo 'restore of xarchie-2.0.6/rdgram.h failed'
  1474. Wc_c="`wc -c < 'xarchie-2.0.6/rdgram.h'`"
  1475. test 519 -eq "$Wc_c" ||
  1476.     echo 'xarchie-2.0.6/rdgram.h: original size 519, current size' "$Wc_c"
  1477. rm -f _shar_wnt_.tmp
  1478. fi
  1479. # ============= xarchie-2.0.6/regex.c ==============
  1480. if test -f 'xarchie-2.0.6/regex.c' -a X"$1" != X"-c"; then
  1481.     echo 'x - skipping xarchie-2.0.6/regex.c (File already exists)'
  1482.     rm -f _shar_wnt_.tmp
  1483. else
  1484. > _shar_wnt_.tmp
  1485. echo 'x - extracting xarchie-2.0.6/regex.c (Text)'
  1486. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/regex.c' &&
  1487. /*
  1488. X * These routines are BSD regex(3)/ed(1) compatible regular-expression
  1489. X * routines written by Ozan S. Yigit, Computer Science, York University.
  1490. X * Parts of the code that are not needed by Prospero have been removed,
  1491. X * but most of the accompanying information has been left intact. 
  1492. X * This file is to be included on those operating systems that do not
  1493. X * support re_comp and re_exec.
  1494. X */
  1495. X
  1496. /*
  1497. X * regex - Regular expression pattern matching
  1498. X *         and replacement
  1499. X *
  1500. X * by:  Ozan S. Yigit (oz@nexus.yorku.ca)
  1501. X *    Dept. of Computing Services
  1502. X *      York University
  1503. X *
  1504. X * These routines are the PUBLIC DOMAIN equivalents 
  1505. X * of regex routines as found in 4.nBSD UN*X, with minor
  1506. X * extensions.
  1507. X *
  1508. X * Modification history:
  1509. X *
  1510. X * Log:    regex.c,v
  1511. X * Revision 1.3  89/04/01  14:18:09  oz
  1512. X * Change all references to a dfa: this is actually an nfa.
  1513. X * 
  1514. X * Revision 1.2  88/08/28  15:36:04  oz
  1515. X * Use a complement bitmap to represent NCL.
  1516. X * This removes the need to have seperate 
  1517. X * code in the pmatch case block - it is 
  1518. X * just CCL code now.
  1519. X * 
  1520. X * Use the actual CCL code in the CLO
  1521. X * section of pmatch. No need for a recursive
  1522. X * pmatch call.
  1523. X * 
  1524. X * Use a bitmap table to set char bits in an
  1525. X * 8-bit chunk.
  1526. X * 
  1527. X * Routines:
  1528. X *      re_comp:        compile a regular expression into
  1529. X *                      a NFA.
  1530. X *
  1531. X *            char *re_comp(s)
  1532. X *            char *s;
  1533. X *
  1534. X *      re_exec:        execute the NFA to match a pattern.
  1535. X *
  1536. X *            int re_exec(s)
  1537. X *            char *s;
  1538. X *
  1539. X * Regular Expressions:
  1540. X *
  1541. X *      [1]     char    matches itself, unless it is a special
  1542. X *                      character (metachar): . \ [ ] * + ^ $
  1543. X *
  1544. X *      [2]     .       matches any character.
  1545. X *
  1546. X *      [3]     \       matches the character following it, except
  1547. X *            when followed by a left or right round bracket,
  1548. X *            a digit 1 to 9 or a left or right angle bracket. 
  1549. X *            (see [7], [8] and [9])
  1550. X *            It is used as an escape character for all 
  1551. X *            other meta-characters, and itself. When used
  1552. X *            in a set ([4]), it is treated as an ordinary
  1553. X *            character.
  1554. X *
  1555. X *      [4]     [set]   matches one of the characters in the set.
  1556. X *                      If the first character in the set is "^",
  1557. X *                      it matches a character NOT in the set, i.e. 
  1558. X *            complements the set. A shorthand S-E is 
  1559. X *            used to specify a set of characters S upto 
  1560. X *            E, inclusive. The special characters "]" and 
  1561. X *            "-" have no special meaning if they appear 
  1562. X *            as the first chars in the set.
  1563. X *                      examples:        match:
  1564. X *
  1565. X *                              [a-z]    any lowercase alpha
  1566. X *
  1567. X *                              [^]-]    any char except ] and -
  1568. X *
  1569. X *                              [^A-Z]   any char except uppercase
  1570. X *                                       alpha
  1571. X *
  1572. X *                              [a-zA-Z] any alpha
  1573. X *
  1574. X *      [5]     *       any regular expression form [1] to [4], followed by
  1575. X *                      closure char (*) matches zero or more matches of
  1576. X *                      that form.
  1577. X *
  1578. X *      [6]     +       same as [5], except it matches one or more.
  1579. X *
  1580. X *      [7]             a regular expression in the form [1] to [10], enclosed
  1581. X *                      as \(form\) matches what form matches. The enclosure
  1582. X *                      creates a set of tags, used for [8] and for
  1583. X *                      pattern substution. The tagged forms are numbered
  1584. X *            starting from 1.
  1585. X *
  1586. X *      [8]             a \ followed by a digit 1 to 9 matches whatever a
  1587. X *                      previously tagged regular expression ([7]) matched.
  1588. X *
  1589. X *    [9]    \<    a regular expression starting with a \< construct
  1590. X *        \>    and/or ending with a \> construct, restricts the
  1591. X *            pattern matching to the beginning of a word, and/or
  1592. X *            the end of a word. A word is defined to be a character
  1593. X *            string beginning and/or ending with the characters
  1594. X *            A-Z a-z 0-9 and _. It must also be preceded and/or
  1595. X *            followed by any character outside those mentioned.
  1596. X *
  1597. X *      [10]            a composite regular expression xy where x and y
  1598. X *                      are in the form [1] to [10] matches the longest
  1599. X *                      match of x followed by a match for y.
  1600. X *
  1601. X *      [11]    ^    a regular expression starting with a ^ character
  1602. X *        $    and/or ending with a $ character, restricts the
  1603. X *                      pattern matching to the beginning of the line,
  1604. X *                      or the end of line. [anchors] Elsewhere in the
  1605. X *            pattern, ^ and $ are treated as ordinary characters.
  1606. X *
  1607. X *
  1608. X * Acknowledgements:
  1609. X *
  1610. X *    HCR's Hugh Redelmeier has been most helpful in various
  1611. X *    stages of development. He convinced me to include BOW
  1612. X *    and EOW constructs, originally invented by Rob Pike at
  1613. X *    the University of Toronto.
  1614. X *
  1615. X * References:
  1616. X *              Software tools            Kernighan & Plauger
  1617. X *              Software tools in Pascal        Kernighan & Plauger
  1618. X *              Grep [rsx-11 C dist]            David Conroy
  1619. X *        ed - text editor        Un*x Programmer's Manual
  1620. X *        Advanced editing on Un*x    B. W. Kernighan
  1621. X *        regexp routines            Henry Spencer
  1622. X *
  1623. X * Notes:
  1624. X *
  1625. X *    This implementation uses a bit-set representation for character
  1626. X *    classes for speed and compactness. Each character is represented 
  1627. X *    by one bit in a 128-bit block. Thus, CCL always takes a 
  1628. X *    constant 16 bytes in the internal nfa, and re_exec does a single
  1629. X *    bit comparison to locate the character in the set.
  1630. X *
  1631. X * Examples:
  1632. X *
  1633. X *    pattern:    foo*.*
  1634. X *    compile:    CHR f CHR o CLO CHR o END CLO ANY END END
  1635. SHAR_EOF
  1636. true || echo 'restore of xarchie-2.0.6/regex.c failed'
  1637. fi
  1638. echo 'End of xarchie-2.0.6 part 13'
  1639. echo 'File xarchie-2.0.6/regex.c is continued in part 14'
  1640. echo 14 > _shar_seq_.tmp
  1641. exit 0
  1642.  
  1643. exit 0 # Just in case...
  1644. -- 
  1645.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  1646. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  1647.  "It's intuitively obvious to the |
  1648.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1649.