home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / archie / part04 < prev    next >
Encoding:
Text File  |  1992-11-10  |  54.1 KB  |  1,870 lines

  1. Newsgroups: comp.sources.misc
  2. From: brendan@cygnus.com (Brendan Kehoe)
  3. Subject:  v33i053:  archie - A client to query the Archie FTP databases, v1.4.1, Part04/07
  4. Message-ID: <1992Nov5.210345.25162@sparky.imd.sterling.com>
  5. X-Md4-Signature: 861e6a15a74812d0893e91df5696bb69
  6. Date: Thu, 5 Nov 1992 21:03:45 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: brendan@cygnus.com (Brendan Kehoe)
  10. Posting-number: Volume 33, Issue 53
  11. Archive-name: archie/part04
  12. Environment: UNIX, VMS, DOS
  13. Supersedes: archie: Volume 27, Issue 79-84
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # Contents:  get_vdir.c make.com msdos/netevent.h regex.c
  20. # Wrapped by kent@sparky on Thu Nov  5 12:53:08 1992
  21. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 4 (of 7)."'
  24. if test -f 'get_vdir.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'get_vdir.c'\"
  26. else
  27.   echo shar: Extracting \"'get_vdir.c'\" \(14094 characters\)
  28.   sed "s/^X//" >'get_vdir.c' <<'END_OF_FILE'
  29. X/*
  30. X * Copyright (c) 1989, 1990, 1991 by the University of Washington
  31. X *
  32. X * For copying and distribution information, please see the file
  33. X * <copyright.h>.
  34. X */
  35. X
  36. X#include <stdio.h>
  37. X
  38. X#include <pfs.h>
  39. X#include <pprot.h>
  40. X#include <perrno.h>
  41. X#include <pcompat.h>
  42. X#include <pauthent.h>
  43. X#include <pmachine.h>
  44. X
  45. X#ifdef NEED_STRING_H
  46. X# include <string.h>
  47. X#else
  48. X# include <strings.h>
  49. X#endif
  50. X
  51. X#ifdef DEBUG
  52. Xextern int    pfs_debug;
  53. X#endif
  54. X
  55. Xextern int    pwarn;
  56. Xextern char    p_warn_string[];
  57. Xextern int    perrno;
  58. Xextern char    p_err_string[];
  59. X
  60. X/*
  61. X * get_vdir - Get contents of a directory given its location
  62. X *
  63. X *          GET_VDIR takes a directory location, a list of desired
  64. X *          components, a pointer to a directory structure to be 
  65. X *          filled in, and flags.  It then queries the appropriate 
  66. X *          directory server and retrieves the desired information.
  67. X *
  68. X *      ARGS:   dhost       - Host on which directory resides
  69. X *              dfile       - Directory on that host
  70. X *              components  - The names from the directory we want
  71. X *        dir        - Structure to be filled in
  72. X *            flags       - Options.  See FLAGS
  73. X *        filters     - filters to be applied to result 
  74. X *              acomp       - Pointer to remaining components
  75. X *
  76. X *     FLAGS:    GVD_UNION   - Do not expand union links
  77. X *        GVD_EXPAND  - Expand union links locally
  78. X *        GVD_REMEXP  - Request remote expansion (& local if refused)
  79. X *        GVD_LREMEXP - Request remote expansion of local union links
  80. X *        GVD_VERIFY  - Only verify that args are for a directory
  81. X *              GVD_ATTRIB  - Request attributes from directory server
  82. X *              GVD_NOSORT  - Do not sort links when adding to directory
  83. X *
  84. X *   RETURNS:   PSUCCESS (0) or error code
  85. X *        On some codes addition information in p_err_string
  86. X *
  87. X *     NOTES:   If acomp is non-null the string it points to might be modified
  88. X *
  89. X *              If the directory passed as an argument already has
  90. X *        links or union links, then those lists will be freed
  91. X *              before the new contents are filled in.
  92. X *
  93. X *              If a filter is passed to the procedure, and application of
  94. X *              the filter results in additional union link, then those links
  95. X *              will (or will not) be expanded as specified in the FLAGS field.
  96. X *
  97. X *              If the list of components in NULL, or the null string, then
  98. X *              get_vdir will return all links in the requested directory.
  99. X *
  100. X *      BUGS:   Doesn't process union links yet
  101. X *              Doesn't process errors returned from server
  102. X *        Doesn't expand union links if requested to
  103. X */
  104. Xint
  105. Xget_vdir(dhost,dfile,components,dir,flags,filters,acomp)
  106. X    char    *dhost;        /* Host on which directory resides           */
  107. X    char    *dfile;        /* Name of file on that host                 */
  108. X    char    *components;    /* Component name (wildcards allowed)        */
  109. X    PVDIR    dir;        /* Structure to be filled in             */
  110. X    long    flags;        /* Flags                         */
  111. X    VLINK    filters;    /* Filters to be applied to result           */
  112. X    char    *acomp;        /* Components left to be resolved            */
  113. X    {
  114. X        PTEXT    request;    /* Text of request to dir server             */
  115. X    PTEXT    resp;            /* Response from dir server                 */
  116. X
  117. X    char    ulcomp[MAX_VPATH];/* Work space for new current component    */
  118. X    char    *comp = components;
  119. X
  120. X    VLINK    cur_link = NULL;/* Current link being filled in              */
  121. X    VLINK     exp = NULL;     /* The current ulink being expanded         */
  122. X    VLINK    pul = NULL;     /* Prev union link (insert new one after it) */
  123. X    VLINK    l;        /* Temp link pointer                  */
  124. X    int    mcomp;        /* Flag - check multiple components          */
  125. X    int    unresp;        /* Flag - received unresolved response       */
  126. X    int    getattrib = 0;  /* Get attributes from server                */
  127. X    int    vl_insert_flag; /* Flags to vl_insert                        */
  128. X
  129. X    int    fwdcnt = MAX_FWD_DEPTH;
  130. X
  131. X    int    no_links = 0;   /* Count of number of links found         */
  132. X
  133. X    char    options[40];    /* LIST option                               */
  134. X    char    *opt;           /* After leading +                           */
  135. X
  136. X    PAUTH    authinfo;
  137. X
  138. X    /* Treat null string like NULL (return entire directory) */
  139. X    if(!components || !*components) comp = NULL;
  140. X
  141. X    if(acomp && !filters) mcomp = 1;
  142. X    else mcomp = 0;
  143. X
  144. X    if(flags&GVD_ATTRIB) {
  145. X        getattrib++;
  146. X        flags &= (~GVD_ATTRIB);
  147. X    }
  148. X
  149. X    if(flags&GVD_NOSORT) vl_insert_flag = VLI_NOSORT;
  150. X    else vl_insert_flag = VLI_ALLOW_CONF;
  151. X    flags &= (~GVD_NOSORT);
  152. X
  153. X    if(filters) comp = NULL;
  154. X
  155. X    perrno = 0;
  156. X
  157. X    authinfo = get_pauth(PFSA_UNAUTHENTICATED);
  158. X
  159. X    *options = '\0';
  160. X
  161. X    if(getattrib) {
  162. X        strcat(options,"+ATTRIBUTES");
  163. X        flags &= (~GVD_ATTRIB);
  164. X    }
  165. X
  166. X    if(!filters) { /* Can't do remote expansion if filters to be applied */
  167. X        if(flags == GVD_REMEXP) strcat(options,"+EXPAND");
  168. X        if(flags == GVD_LREMEXP) strcat(options,"+LEXPAND");
  169. X    }
  170. X
  171. X    /* If all we are doing is verifying that dfile is a directory */
  172. X    /* then we do not want a big response from the directory      */
  173. X    /* server.  A NOT-FOUND is sufficient.                  */
  174. X    if(flags == GVD_VERIFY)
  175. X#ifdef NEWVERIFYOPT
  176. X        strcat(options,"+VERIFY");
  177. X#else
  178. X    comp = "%#$PRobably_nOn_existaNT$#%";
  179. X#endif
  180. X
  181. X    if(*options) opt = options+1;
  182. X    else opt = "''";
  183. X
  184. X    startover:
  185. X    request = ptalloc();
  186. X
  187. X    sprintf(request->start,
  188. X        "VERSION %d %s\nAUTHENTICATOR %s %s\nDIRECTORY ASCII %s\nLIST %s COMPONENTS %s%s%s\n",
  189. X        VFPROT_VNO, PFS_SW_ID, authinfo->auth_type,
  190. X        authinfo->authenticator, dfile, opt,
  191. X        (comp ? comp : ""), (mcomp ? "/" : ""),
  192. X        (mcomp ? acomp : ""));
  193. X
  194. X    request->length = strlen(request->start);
  195. X
  196. X#ifdef DEBUG
  197. X    if(pfs_debug > 2)
  198. X        fprintf(stderr,"Sending message to dirsrv:\n%s",request->start);
  199. X#endif
  200. X
  201. X#if defined(MSDOS)
  202. X    resp = dirsend(request,dhost,0L);
  203. X#else
  204. X    resp = dirsend(request,dhost,0);
  205. X#endif
  206. X
  207. X#ifdef DEBUG
  208. X    if(pfs_debug && (resp == NULL)) {
  209. X        fprintf(stderr,"Dirsend failed: %d\n",perrno);
  210. X    }
  211. X#endif
  212. X
  213. X    /* If we don't get a response, then if the requested       */
  214. X    /* directory, return error, if a ulink, mark it unexpanded */
  215. X    if(resp == NULL) {
  216. X        if(exp) exp->expanded = FAILED;
  217. X        else return(perrno);
  218. X    }
  219. X
  220. X    unresp = 0;
  221. X
  222. X    /* Here we must parse reponse and put in directory */
  223. X    /* While looking at each packet            */
  224. X    while(resp) {
  225. X        PTEXT        vtmp;
  226. X        char        *line;
  227. X
  228. X        vtmp = resp;
  229. X#ifdef DEBUG
  230. X        if(pfs_debug > 3) fprintf(stderr,"%s\n",resp->start);
  231. X#endif
  232. X        /* Look at each line in packet */
  233. X        for(line = resp->start;line != NULL;line = nxtline(line)) {
  234. X        switch (*line) {
  235. X            
  236. X            /* Temporary variables to hold link info */
  237. X            char    l_linktype;
  238. X            char     l_name[MAX_DIR_LINESIZE];
  239. X            char    l_type[MAX_DIR_LINESIZE];
  240. X            char     l_htype[MAX_DIR_LINESIZE];
  241. X            char     l_host[MAX_DIR_LINESIZE];
  242. X            char     l_ntype[MAX_DIR_LINESIZE];
  243. X            char     l_fname[MAX_DIR_LINESIZE];
  244. X            int        l_version;
  245. X            char     t_unresolved[MAX_DIR_LINESIZE];
  246. X            int        l_magic;
  247. X            int        tmp;
  248. X
  249. X        case 'L': /* LINK or LINK-INFO */
  250. X            if(strncmp(line,"LINK-INFO",9) == 0) {
  251. X            PATTRIB        at;
  252. X            PATTRIB        last_at;
  253. X            at = parse_attribute(line);
  254. X            if(!at) break;
  255. X
  256. X            /* Cant have link info without a link */
  257. X            if(!cur_link) {
  258. X                perrno = DIRSRV_BAD_FORMAT;
  259. X                atfree(at);
  260. X                break;
  261. X            }
  262. X            
  263. X            if(cur_link->lattrib) {
  264. X                last_at = cur_link->lattrib;
  265. X                while(last_at->next) last_at = last_at->next;
  266. X                at->previous = last_at;
  267. X                last_at->next = at;
  268. X            }
  269. X            else {
  270. X                cur_link->lattrib = at;
  271. X                at->previous = NULL;
  272. X            }
  273. X            break;
  274. X            }
  275. X
  276. X            /* Not LINK-INFO, must be LINK - if not check for error */
  277. X            if(strncmp(line,"LINK",4) != 0) goto scanerr;
  278. X
  279. X            /* If only verifying, don't want to change dir */
  280. X            if(flags == GVD_VERIFY) {
  281. X            break;
  282. X            }
  283. X            /* If first link and some links in dir, free them */
  284. X            if(!no_links++) {
  285. X            if(dir->links) vllfree(dir->links); dir->links=NULL;
  286. X            if(dir->ulinks) vllfree(dir->ulinks); dir->ulinks=NULL;
  287. X            }
  288. X            
  289. X            cur_link = vlalloc();
  290. X
  291. X            /* parse and insert file info */
  292. X            tmp = sscanf(line,"LINK %c %s %s %s %s %s %s %d %d", &l_linktype,
  293. X                 l_type, l_name, l_htype, l_host, 
  294. X                 l_ntype, l_fname, &(cur_link->version),
  295. X                 &(cur_link->f_magic_no));
  296. X
  297. X            if(tmp != 9) {
  298. X            perrno = DIRSRV_BAD_FORMAT;
  299. X            vlfree(cur_link);
  300. X            break;
  301. X            }
  302. X
  303. X            cur_link->linktype = l_linktype;
  304. X            cur_link->type = stcopyr(l_type,cur_link->type);
  305. X            cur_link->name = stcopyr(unquote(l_name),cur_link->name);
  306. X            cur_link->hosttype = stcopyr(l_htype,cur_link->hosttype);
  307. X            cur_link->host = stcopyr(l_host,cur_link->host);
  308. X            cur_link->nametype = stcopyr(l_ntype,cur_link->nametype);
  309. X            cur_link->filename = stcopyr(l_fname,cur_link->filename);
  310. X
  311. X            /* Double check to make sure we don't get */
  312. X            /* back unwanted components              */
  313. X            /* OK to keep if special (URP) links      */
  314. X            /* or if mcomp specified                  */
  315. X            if(!mcomp && (cur_link->linktype == 'L') && 
  316. X               (!wcmatch(cur_link->name,comp))) {
  317. X            vlfree(cur_link);
  318. X            break;
  319. X            }
  320. X
  321. X            /* If other optional info was sent back, it must */
  322. X            /* also be parsed before inserting link     ***  */
  323. X            
  324. X            
  325. X            if(cur_link->linktype == 'L') 
  326. X            vl_insert(cur_link,dir,vl_insert_flag);
  327. X            else {
  328. X            tmp = ul_insert(cur_link,dir,pul);
  329. X
  330. X            /* If inserted after pul, next one after cur_link */
  331. X            if(pul && (!tmp || (tmp == UL_INSERT_SUPERSEDING)))
  332. X                pul = cur_link;
  333. X            }
  334. X            
  335. X            break;
  336. X
  337. X        case 'F': /* FILTER, FAILURE or FORWARDED */
  338. X            /* FORWARDED */
  339. X            if(strncmp(line,"FORWARDED",9) == 0) {
  340. X            if(fwdcnt-- <= 0) {
  341. X                ptlfree(resp);
  342. X                perrno = PFS_MAX_FWD_DEPTH;
  343. X                return(perrno);
  344. X            }
  345. X            /* parse and start over */
  346. X
  347. X            tmp = sscanf(line,"FORWARDED %s %s %s %s %d %d", 
  348. X                     l_htype,l_host,l_ntype,l_fname,
  349. X                     &l_version, &l_magic);
  350. X
  351. X            dhost = stcopy(l_host);
  352. X            dfile = stcopy(l_fname);
  353. X
  354. X            if(tmp < 4) {
  355. X                perrno = DIRSRV_BAD_FORMAT;
  356. X                break;
  357. X            }
  358. X
  359. X            ptlfree(resp);
  360. X            goto startover;
  361. X            }
  362. X            if(strncmp(line,"FILTER",6) != 0) goto scanerr;
  363. X            break;
  364. X
  365. X
  366. X        case 'M': /* MULTI-PACKET (processed by dirsend) */
  367. X        case 'P': /* PACKET (processed by dirsend) */
  368. X            break;
  369. X
  370. X        case 'N': /* NOT-A-DIRECTORY or NONE-FOUND */
  371. X            /* NONE-FOUND, we just have no links to insert */
  372. X            /* It is not an error, but we must clear any   */
  373. X            /* old links in the directory arg              */
  374. X            if(strncmp(line,"NONE-FOUND",10) == 0) {
  375. X            /* If only verifying, don't want to change dir */
  376. X            if(flags == GVD_VERIFY) {
  377. X                break;
  378. X            }
  379. X
  380. X            /* If first link and some links in dir, free them */
  381. X            if(!no_links++) {
  382. X                if(dir->links) vllfree(dir->links);
  383. X                if(dir->ulinks) vllfree(dir->ulinks);
  384. X                dir->links = NULL;
  385. X                dir->ulinks = NULL;
  386. X            }
  387. X            break;
  388. X            }
  389. X            /* If NOT-A-DIRECTORY or anything else, scan error */
  390. X            goto scanerr;
  391. X
  392. X        case 'U': /* UNRESOLVED */
  393. X            if(strncmp(line,"UNRESOLVED",10) != 0) {
  394. X            goto scanerr;
  395. X            }
  396. X            tmp = sscanf(line,"UNRESOLVED %s", t_unresolved);
  397. X            if(tmp < 1) {
  398. X            perrno = DIRSRV_BAD_FORMAT;
  399. X            break;
  400. X            }
  401. X            /* If multiple components were resolved */
  402. X            if(strlen(t_unresolved) < strlen(acomp)) {
  403. X            strcpy(ulcomp,acomp);
  404. X            /* ulcomp is the components that were resolved */
  405. X            *(ulcomp+strlen(acomp)-strlen(t_unresolved)-1) = '\0';
  406. X            /* Comp gets the last component resolved */
  407. X            comp = (char *) rindex(ulcomp,'/');
  408. X            if(comp) comp++;
  409. X            else comp = ulcomp;
  410. X            /* Let rd_vdir know what remains */
  411. X            strcpy(acomp,t_unresolved);
  412. X            }
  413. X            unresp = 1;
  414. X            break;
  415. X
  416. X        case 'V': /* VERSION-NOT-SUPPORTED */
  417. X            if(strncmp(line,"VERSION-NOT-SUPPORTED",21) == 0) {
  418. X            perrno = DIRSRV_BAD_VERS;
  419. X            return(perrno);
  420. X            }
  421. X            goto scanerr;
  422. X
  423. X        scanerr:
  424. X        default:
  425. X            if(*line && (tmp = scan_error(line))) {
  426. X            ptlfree(resp);
  427. X            return(tmp);
  428. X            }
  429. X            break;
  430. X        }
  431. X        }
  432. X
  433. X        resp = resp->next;
  434. X
  435. X        ptfree(vtmp);
  436. X    }
  437. X
  438. X    /* We sent multiple components and weren't told any */
  439. X    /* were unresolved                                  */
  440. X    if(mcomp && !unresp) {
  441. X        /* ulcomp is the components that were resolved */
  442. X        strcpy(ulcomp,acomp);
  443. X        /* Comp gets the last component resolved */
  444. X        comp = (char *) rindex(ulcomp,'/');
  445. X        if(comp) comp++;
  446. X        else comp = ulcomp;
  447. X        /* If we have union links to resolve, only one component remains */
  448. X        mcomp = 0;
  449. X        /* Let rd_vdir know what remains */
  450. X        *acomp = '\0';
  451. X    }
  452. X
  453. X    /* If only verifying, we already know it is a directory */
  454. X    if(flags == GVD_VERIFY) return(PSUCCESS);
  455. X
  456. X    /* Don't return if matching was delayed by the need to filter    */
  457. X    /* if FIND specified, and dir->links is non null, then we have   */
  458. X    /* found a match, and should return.                             */
  459. X    if((flags & GVD_FIND) && dir->links && (!filters))
  460. X        return(PSUCCESS);
  461. X
  462. X    /* If expand specified, and ulinks must be expanded, making sure */
  463. X        /* that the order of the links is maintained properly            */
  464. X
  465. Xexpand_ulinks:
  466. X
  467. X    if((flags != GVD_UNION) && (flags != GVD_VERIFY)) {
  468. X
  469. X        l = dir->ulinks;
  470. X
  471. X        /* Find first unexpanded ulink */
  472. X        while(l && l->expanded && (l->linktype == 'U')) l = l->next;
  473. X        
  474. X        /* Only expand if a FILE or DIRECTORY -  Mark as  */
  475. X            /* failed otherwise                               */
  476. X        /* We must still add support for symbolic ulinks */
  477. X        if(l) {
  478. X        if ((strcmp(l->type,"DIRECTORY") == 0) || 
  479. X            (strcmp(l->type,"FILE") == 0)) {
  480. X            l->expanded = TRUE;
  481. X            exp = l;
  482. X            pul = l;
  483. X            dhost = l->host;
  484. X            dfile = l->filename;
  485. X            goto startover; /* was get_contents; */
  486. X        }
  487. X        else l->expanded = FAILED;
  488. X        }
  489. X    }
  490. X
  491. X    /* Double check to make sure we don't get */
  492. X    /* back unwanted components          */
  493. X    /* OK to keep if special (URP) links      */
  494. X    if(components && *components) {
  495. X        l = dir->links;
  496. X        while(l) {
  497. X        VLINK    ol;
  498. X        if((l->linktype == 'L') && (!wcmatch(l->name,components))) {
  499. X            if(l == dir->links)
  500. X            dir->links = l->next;
  501. X            else l->previous->next = l->next;
  502. X            if(l->next) l->next->previous = l->previous;
  503. X            ol = l;
  504. X            l = l->next;
  505. X            vlfree(ol);
  506. X        }
  507. X        else l = l->next;
  508. X        }
  509. X    }
  510. X
  511. X    return(PSUCCESS);
  512. X    }
  513. END_OF_FILE
  514.   if test 14094 -ne `wc -c <'get_vdir.c'`; then
  515.     echo shar: \"'get_vdir.c'\" unpacked with wrong size!
  516.   fi
  517.   # end of 'get_vdir.c'
  518. fi
  519. if test -f 'make.com' -a "${1}" != "-c" ; then 
  520.   echo shar: Will not clobber existing file \"'make.com'\"
  521. else
  522.   echo shar: Extracting \"'make.com'\" \(17686 characters\)
  523.   sed "s/^X//" >'make.com' <<'END_OF_FILE'
  524. X$! --- MAKE.COM ---                        !x=f$verify(0)
  525. X$! Description:
  526. X$!  build the Archie client for VAX/VMS
  527. X$!
  528. X$! Written by Luke Brennan  <brennan@cchs.su.oz.AU>
  529. X$!
  530. X$! Modifications:
  531. X$!    Date    Programmer    Reason for modification.
  532. X$! 26-Oct-92       bpk        1.11 Remove ALLOCA.
  533. X$! 26-Oct-92       ldcb         1.10 HMMM... alloca.c required by VAXC!!!!
  534. X$!                                   (this is a built-in for GNU_CC)
  535. X$!                                   add support for NON_GNU_CC (p3 arg) on
  536. X$!                                   source entries.
  537. X$! 26-Oct-92       ldcb         1.09 Add NOGNU command-line switch so that I
  538. X$!                                   can force it to use VAXC rather than GNU.
  539. X$! 26-Oct-92       ldcb         1.08 Add GETOPT sources for Archie 1.4
  540. X$! 13-Oct-92       bpk        1.07 Add Japan and Taiwan servers.
  541. X$! 10-Oct-92       ldcb        1.06 Add (Israel) archie server.
  542. X$! 25-Sep-92       ldcb        1.05 Add (USA [NE]) archie server.
  543. X$! 23-Sep-92       ldcb       1.04 Details... details..
  544. X$!                                   cope with SUPPORT files being used...
  545. X$!                                   You will need to enter your OWN stuff
  546. X$!                                   into the CREATE_SUPPORT_OPTIONS gosub,
  547. X$!                                   as I don't know what you're using!
  548. X$! 22-Sep-92       ldcb         1.03 Oops! GCC now works correctly...
  549. X$! 22-Sep-92       ldcb        1.02 Clean up a few tiny details.
  550. X$! 22-Jan-92       ldcb        1.01 Fix some bugs (so I rushed..)
  551. X$! 20-Jan-92       ldcb        1.00 Initial coding.
  552. X$!
  553. X$ make_version := 1.10
  554. X$!
  555. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  556. X$ Archie_EXECUTABLE := "archie.exe"
  557. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  558. X$! add a new call here with the appropriate new Archie server host(s)
  559. X$!
  560. X$ arg == 1
  561. X$ Call AddHost "archie.au"        "(Australia)"
  562. X$ Call AddHost "archie.mcgill.ca"    "(Canada)"
  563. X$ Call AddHost "archie.doc.ic.ac.uk"    "(Great Britain/Ireland)"
  564. X$ Call AddHost "archie.funet.fi"    "(Finland/Mainland Europe)"
  565. X$ Call AddHost "archie.cs.huji.ac.il"    "(Israel)
  566. X$ Call AddHost "archie.wide.ad.jp"    "(Japan)"
  567. X$ Call AddHost "archie.ncu.edu.tw"    "(Taiwan)"
  568. X$ Call AddHost "archie.unl.edu"        "(USA [NE])"
  569. X$ Call AddHost "archie.ans.net"        "(USA [NY])"
  570. X$ Call AddHost "archie.rutgers.edu"    "(USA [NJ])"
  571. X$ Call AddHost "archie.sura.net"    "(USA [MD])"
  572. X$ MAXHOSTS = arg - 1
  573. X$!
  574. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  575. X$! add a new call here with any new source file(s)
  576. X$! (P2 should be "SUPPORT" if intended for supporting an unknown TCPIP)
  577. X$! (P3 should be "NON_GNU_CC" if a GNU_CC supported function isn't yet in VAXC,
  578. X$!                            which means WE have to provide it to VAXC)
  579. X$!
  580. X$ arg == 1
  581. X$ Call AddSource "AQUERY"
  582. X$ Call AddSource "ARCHIE"
  583. X$ Call AddSource "ATALLOC"
  584. X$ Call AddSource "DIRSEND"
  585. X$ Call AddSource "GETOPT"
  586. X$ Call AddSource "GETOPT1"
  587. X$ Call AddSource "GET_PAUTH"
  588. X$ Call AddSource "GET_VDIR"
  589. X$ Call AddSource "PERRMESG"
  590. X$ Call AddSource "PROCQUERY"
  591. X$ Call AddSource "PTALLOC"
  592. X$ Call AddSource "REGEX"
  593. X$ Call AddSource "STCOPY"
  594. X$ Call AddSource "SUPPORT"
  595. X$ Call AddSource "VLALLOC"
  596. X$ Call AddSource "VL_COMP"
  597. X$ Call AddSource "VMS_SUPPORT"    "SUPPORT"
  598. X$ MAXSOURCEFILES = arg - 1
  599. X$!
  600. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  601. X$! add a call here with any supported TCP/IP implementations
  602. X$!  P1 = name of TCP/IP product, P2 = cc/define to set,
  603. X$!  P3 = logical to look for,    P4 = location of link/OPT,
  604. X$!  P5 = MINIMUM VERSION of TCP/IP to support
  605. X$!
  606. X$!  Multinet should be last, as it can 'fake' a UCX if you want it to, so
  607. X$!  UCX would come up as the 'real' net even though Multinet is used.
  608. X$!
  609. X$ arg == 1
  610. X$ Call AddTCPIP "UCX"        "UCX"         "UCX$DEVICE" "[.vms]ucx.opt"
  611. X$ Call AddTCPIP "WOLLONGONG" "WOLLONGONG"  "TWG$TCP"    "[.vms]woll.opt"
  612. X$ Call AddTCPIP "MULTINET"   "MULTINET_30" "MULTINET"   "[.vms]multi.opt" "V3.0"
  613. X$ MAXTCPIPTYPES = arg - 1
  614. X$!
  615. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  616. X$!
  617. X$ YES = (1.eq.1)
  618. X$ NO  = (1.eq.0)
  619. X$!
  620. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  621. X$!
  622. X$ GoSub get_command_line_args
  623. X$ GoSub check_for_GNU_cc        ! use GNU if it's available..
  624. X$ GoSub check_which_TCPIP
  625. X$ GoSub ask_nearest_ARCHIE_HOST
  626. X$ GoSub check_for_strings_H
  627. X$ GoSub set_cc_defines
  628. X$ GoSub do_compiles
  629. X$ If (LINKAGE_REQUIRED)
  630. X$ Then GoSub do_link
  631. X$ Else Write Sys$OutPut "ARCHIE is up to date."
  632. X$ EndIF
  633. X$ Exit
  634. X$!
  635. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  636. X$!
  637. X$get_command_line_args:
  638. X$ cmdline = P1 + P2 + P3 + P4 + P5 + P6 + P7 + P8
  639. X$ If ((f$locate("DEBUG",cmdline) .ne. f$length(cmdline)) -
  640. X .or. (f$locate("DBG",cmdline)   .ne. f$length(cmdline)))
  641. X$ Then debug := "/DeBug"
  642. X$ Else debug := "/NOdebug"
  643. X$ EndIF
  644. X$ If (f$locate("FORCE",cmdline) .ne. f$length(cmdline))
  645. X$ Then FORCEBUILD = YES
  646. X$ Else FORCEBUILD = NO
  647. X$ EndIF
  648. X$ If (f$locate("LINK",cmdline) .ne. f$length(cmdline))
  649. X$ Then FORCELINK = YES
  650. X$ Else FORCELINK = NO
  651. X$ EndIF
  652. X$ If (f$locate("NOGNU",cmdline) .ne. f$length(cmdline))
  653. X$ Then FORCEVAXCC = YES
  654. X$ Else FORCEVAXCC = NO
  655. X$ EndIF
  656. X$ If ((f$locate("?",cmdline) .ne. f$length(cmdline)) -
  657. X .or. (f$locate("H",cmdline) .ne. f$length(cmdline)))
  658. X$ Then
  659. X$   Write Sys$Output "Usage:"
  660. X$   Write Sys$OutPut "     @MAKE [<debug>|<force>|<link>|<nognu>|<help>]
  661. X$   EXIT
  662. X$ EndIF
  663. X$ RETURN
  664. X$!
  665. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  666. X$!
  667. X$CHECK_FOR_GNU_CC:
  668. X$ If (f$trnlnm("GNU_CC") .nes. "")
  669. X$ Then
  670. X$   If (.NOT. FORCEVAXCC)
  671. X$   Then
  672. X$     cc := "GCC/Optimize/Include=([])"
  673. X$     gnu_cc = YES
  674. X$   Else        ! I'm forcing it to use VAXC
  675. X$     cc := "CC/Optimize=NOinline/Include=([])"
  676. X$     gnu_cc = NO
  677. X$   EndIF
  678. X$ Else            ! I can only use VAXC..
  679. X$   cc := "CC/Optimize=NOinline/Include=([])"
  680. X$   gnu_cc = NO
  681. X$ EndIF
  682. X$!
  683. X$ RETURN
  684. X$!
  685. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  686. X$! for product P1, cc/define=P2 if logical P3 present on system.
  687. X$! Libs/option = P4 if present. ALL get disregarded if less than version P5
  688. X$!
  689. X$CHECK_WHICH_TCPIP:
  690. X$ tcpip_flag :=
  691. X$ tcpip_libs :=
  692. X$ NO_TCPIP_SUPPORT = YES
  693. X$ i = 1
  694. X$tcp_loop:
  695. X$ If (i .gt. MAXTCPIPTYPES) Then GoTo tcp_check_done
  696. X$ If (f$type(tcpip_P2_'i') .eqs. "") Then GoTo tcp_check_done
  697. X$ If (f$type(tcpip_P3_'i') .nes. "")
  698. X$ Then
  699. X$   tcpip_logical = tcpip_P3_'i'
  700. X$   If (tcpip_logical .nes. "")
  701. X$   Then                    ! logical to look for
  702. X$     If (f$logical(tcpip_logical) .nes. "")
  703. X$     Then
  704. X$       tcpip_flag = tcpip_P2_'i'
  705. X$       tcpip_flag = f$fao(",!AS=1",tcpip_flag)
  706. X$       NO_TCPIP_SUPPORT = NO
  707. X$       If (f$type(tcpip_P4_'i') .nes. "")
  708. X$       Then                    ! link/OPT file location
  709. X$        tcpip_linkOPTs = tcpip_P4_'i'
  710. X$         If (tcpip_linkOPTs .nes. "")
  711. X$         Then
  712. X$           If (f$search(tcpip_linkOPTs) .nes. "")
  713. X$           Then
  714. X$             tcpip_libs = tcpip_P4_'i'
  715. X$             tcpip_libs = f$fao("!AS/Option",tcpip_libs)
  716. X$           EndIF
  717. X$         EndIF
  718. X$       EndIF
  719. X$       If (f$type(tcpip_P5_'i') .nes. "")
  720. X$       Then                    ! minimum version specified
  721. X$         If (tcpip_P5_'i' .nes. "")
  722. X$         Then
  723. X$           GoSub CheckIfVersionOK
  724. X$           If VERSION_TOO_EARLY
  725. X$           Then                ! too early.. use SUPPORT files
  726. X$             tcpip_flag :=
  727. X$             tcpip_libs :=
  728. X$             NO_TCPIP_SUPPORT = YES
  729. X$          tcp_ver = tcpip_P5_'i'
  730. X$             tcp_name = tcpip_P1_'i'
  731. X$             Write Sys$OutPut f$fao( -
  732. X           "Your version of !AS is earlier than !AS.",tcp_name,tcp_ver)
  733. X          Write Sys$OutPut "MAKE will use STD support files instead."
  734. X$          If (f$mode() .eqs. "INTERACTIVE")
  735. X$          Then
  736. X$            Read/Prompt="enter <CR> to continue" SYS$COMMAND dummy
  737. X$          EndIF
  738. X$           EndIF
  739. X$         EndIF
  740. X$       EndIF
  741. X$     EndIF
  742. X$   EndIF
  743. X$ EndIF
  744. X$ i = i + 1
  745. X$ Goto tcp_loop
  746. X$tcp_check_done:
  747. X$ RETURN
  748. X$!
  749. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  750. X$!
  751. X$ASK_NEAREST_ARCHIE_HOST:
  752. X$GoSub CLRSCN
  753. X$ Write Sys$OutPut f$fao("archie make V!AS!/!/!AS!/!/", -
  754. X    make_version, -
  755. X    "           Enter the number of the ARCHIE HOST nearest you.")
  756. X$!
  757. X$ i = 1
  758. X$_display_loop:
  759. X$ If (i .gt. MAXHOSTS) Then GoTo _display_done
  760. X$  Write Sys$OutPut f$fao("!2SL) !25AS  !AS",i,host_P1_'i',host_P2_'i')
  761. X$  i = i + 1
  762. X$ GoTo _display_loop
  763. X$_display_done:
  764. X$!
  765. X$ If (f$mode() .eqs. "INTERACTIVE")
  766. X$ Then
  767. X$   Assign/User_Mode/NOlog Sys$Command Sys$InPut
  768. X$_select_loop:                ! get their selection
  769. X$   selection = 99
  770. X$   Read     Sys$Command selection    -
  771. X        /End=_selection_made    -
  772. X        /Prompt="Enter number of your selection: "
  773. X$_selection_made:
  774. X$   If (selection .gt. MAXHOSTS)
  775. X$   Then
  776. X$     Write Sys$Error f$fao("!AS !2SL", "error: Options only go to", MAXHOSTS)
  777. X$     GoTo _select_loop
  778. X$   EndIF
  779. X$   ascii_string = f$edit(selection,"COLLAPSE,UPCASE")
  780. X$   ascii_char = f$extract(0,1,ascii_string)
  781. X$   If (ascii_char .eqs. "Q") Then EXIT
  782. X$   If (f$length(ascii_string) .eq. 1) Then ascii_string = "0" + ascii_string
  783. X$   If .NOT. (("00".lts.ascii_string) .and. (ascii_string.les."''MAXHOSTS'"))
  784. X$   Then
  785. X$     Write Sys$Error -
  786. X        f$fao("error: Enter option NUMBER (up to !2SL)", MAXHOSTS)
  787. X$     Goto _select_loop
  788. X$   EndIF
  789. X$ Else            ! BATCH can't be queried - assume selection 1
  790. X$   selection = 1
  791. X$ EndIF
  792. X$!
  793. X$ local_archie = host_P1_'selection'
  794. X$!
  795. X$ RETURN
  796. X$!
  797. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  798. X$! If we're using VAXC then we need to grab STRINGS.H from SYS$LIBRARY.
  799. X$CHECK_FOR_STRINGS_H:
  800. X$ delete := delete
  801. X$ copy   := copy
  802. X$ If (f$search("strings.h") .nes. "") Then delete/nolog/noconfirm []strings.h;*
  803. X$ If ((.NOT. (GNU_CC)) -
  804. X  .or. (FORCEVAXCC)) Then copy/noconfirm sys$library:string.h []strings.h
  805. X$!
  806. X$ RETURN
  807. X$!
  808. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  809. X$! **NOTE** use of global symbol!!!
  810. X$! **NOTE** this is the only way I could pass it to the compile subroutine
  811. X$! **NOTE** without DCL and/or CC stripping off too many layers of quotes..
  812. X$! **NOTE** yeah.. I know.. It's ugly...  you work it out!! :-)
  813. X$SET_CC_DEFINES:
  814. X$ archie_host = " """"""ARCHIE_HOST=""""""""''local_archie'"""""""" """""" "
  815. X$ cflags :== /define=(debug=1,funcs=1,noregex=1'tcpip_flag','archie_host')
  816. X$!
  817. X$RETURN
  818. X$!
  819. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  820. X$!
  821. X$DO_COMPILES:
  822. X$ GoSub CLRSCN
  823. X$ LINKAGE_REQUIRED == NO
  824. X$ If ("''f$type(Archie_EXECUTABLE)'" .nes. "")
  825. X$ Then
  826. X$   If (Archie_EXECUTABLE .nes. "")
  827. X$   Then If (f$search(Archie_EXECUTABLE) .eqs. "") Then LINKAGE_REQUIRED == YES
  828. X$   Else If (f$search("Archie.exe") .eqs. "") Then LINKAGE_REQUIRED == YES
  829. X$   EndIF
  830. X$ Else
  831. X$   If (f$search("Archie.exe") .nes. "") Then LINKAGE_REQUIRED == YES
  832. X$ EndIF
  833. X$ i = 1
  834. X$cc_loop:
  835. X$ If (i .gt. MAXSOURCEFILES) Then GoTo cc_done
  836. X$ source_file = source_P1_'i'
  837. X$ If ((.NOT. GNU_CC) -
  838. X  .or.((GNU_CC).and.((f$type(source_P3_'i').eqs."").or.(source_P3_'i'.eqs.""))))
  839. X$ Then
  840. X$   If ((f$type(source_P2_'i') .eqs. "") .or. (source_P2_'i' .eqs. ""))
  841. X$   Then Call Compile "''cc'" "''source_file'" "''debug'" 'FORCEBUILD'
  842. X$   Else
  843. X$     If ((NO_TCPIP_SUPPORT) .and. (source_P2_'i' .eqs. "SUPPORT"))
  844. X$     Then Call Compile "''cc'" "''source_file'" "''debug'" 'FORCEBUILD'
  845. X$     EndIF
  846. X$   EndIF
  847. X$ EndIF
  848. X$ i = i + 1
  849. X$ GoTo cc_loop
  850. X$cc_done:
  851. X$ If (FORCELINK) Then LINKAGE_REQUIRED == YES
  852. X$!
  853. X$ RETURN
  854. X$!
  855. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  856. X$!
  857. X$DO_LINK:
  858. X$ If (f$type(Archie_EXECUTABLE) .nes. "")
  859. X$ Then
  860. X$   If (Archie_EXECUTABLE .nes. "")
  861. X$   Then executable := /Exec='Archie_EXECUTABLE'
  862. X$   Else executable := /Exec=Archie.exe
  863. X$   EndIF
  864. X$ Else
  865. X$   executable := /Exec=Archie.exe
  866. X$ EndIF
  867. X$ i = 1
  868. X$ object_files :=
  869. X$object_files_loop:
  870. X$ If (i .gt. MAXSOURCEFILES) Then GoTo object_files_done
  871. X$ object_file = source_P1_'i'
  872. X$ If ((.NOT. GNU_CC) -
  873. X  .or.((GNU_CC).and.((f$type(source_P3_'i').eqs."").or.(source_P3_'i'.eqs.""))))
  874. X$ Then
  875. X$   If ((f$type(source_P2_'i') .eqs. "") .or. (source_P2_'i' .eqs. ""))
  876. X$   Then object_files := 'object_files'+'object_file'
  877. X$   Else
  878. X$     If ((NO_TCPIP_SUPPORT) .and. (source_P2_'i' .eqs. "SUPPORT"))
  879. X$     Then object_files := 'object_files'+'object_file'
  880. X$     EndIF
  881. X$   EndIF
  882. X$ EndIF
  883. X$ i = i + 1
  884. X$ GoTo object_files_loop
  885. X$object_files_done:
  886. X$ If (f$extract(0,1,object_files) .eqs. "+")
  887. X$ Then object_files = f$extract(1,f$length(object_files),object_files)
  888. X$ EndIF
  889. X$!
  890. X$ If (gnu_cc)
  891. X$ Then
  892. X$   If (tcpip_libs .nes. "")
  893. X$   Then tcpip_libs = tcpip_libs + ",GNU_CC:[000000]GCCLIB/Library"
  894. X$   Else tcpip_libs = "GNU_CC:[000000]GCCLIB/Library"
  895. X$   EndIF
  896. X$ EndIF
  897. X$!
  898. X$ If (NO_TCPIP_SUPPORT)
  899. X$ Then
  900. X$   dev=f$TrnLnm("SYS$DISK")
  901. X$   If (f$search("NO_SUPPORT.OPT") .eqs. "") Then GoSub Create_Support_Options
  902. X$   If (tcpip_libs .nes. "")
  903. X$   Then tcpip_libs = tcpip_libs + ",'dev'[]No_Support.opt/OPTION"
  904. X$   Else tcpip_libs = "'dev'[]No_Support.opt/OPTION"
  905. X$   EndIF
  906. X$ EndIF
  907. X$!
  908. X$ If (tcpip_libs .nes. "")
  909. X$ Then object_files = object_files + ","
  910. X$ EndIF
  911. X$!
  912. X$ Set Verify
  913. X$ Link'debug''executable' 'object_files''tcpip_libs'
  914. X$ x='f$verify(0)'
  915. X$!
  916. X$ here =f$environment("procedure") ! assume .EXE is in same directory as MAKE.
  917. X$ here = f$parse(here,,,"DEVICE") + f$parse(here,,,"DIRECTORY")
  918. X$!
  919. X$ Write Sys$OutPut " "
  920. X$ Write Sys$OutPut " "
  921. X$ Write Sys$OutPut "Done! Define the symbol ARCHIE & fire away."
  922. X$ Write Sys$OutPut "e.g."
  923. X$ Write Sys$OutPut f$fao("  $ archie :== $!AS!AS",here,archie_executable)
  924. X$ Write Sys$OutPut "  $ archie GOPHER"
  925. X$!
  926. X$ RETURN
  927. X$!
  928. X$! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  929. X$!
  930. X$CLRSCN:
  931. X$If (f$GetDVI("TT:","TT_ANSICRT"))            ! ANSI compatible?
  932. X$Then
  933. X$  CSI = "x["
  934. X$  CSI[0,8] = 27
  935. X$  CLS = CSI + "H" + CSI +"2J"
  936. X$  Write Sys$OutPut CLS
  937. X$Else                    ! otherwise pump out some <CR>s..
  938. X$  lines=f$GetDVI("TT:","TT_PAGE")
  939. X$  Write Sys$Output f$fao("!''lines'(/)")
  940. X$EndIF
  941. X$Return
  942. X$!
  943. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  944. X$!
  945. X$AddHOST: SUBROUTINE
  946. X$ host_P1_'arg' :== "''P1'"
  947. X$ host_P2_'arg' :== "''P2'"
  948. X$ arg == arg + 1    ! *NOTE* global symbols used...
  949. X$ENDSUBROUTINE
  950. X$!
  951. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  952. X$!
  953. X$AddSOURCE: SUBROUTINE
  954. X$ source_P1_'arg' :== "''P1'"
  955. X$ source_P2_'arg' :== "''P2'"
  956. X$ source_P3_'arg' :== "''P3'"
  957. X$ arg == arg + 1    ! *NOTE* global symbols used...
  958. X$ENDSUBROUTINE
  959. X$!
  960. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  961. X$!
  962. X$AddTCPIP: SUBROUTINE
  963. X$ tcpip_P1_'arg' :== "''P1'"
  964. X$ tcpip_P2_'arg' :== "''P2'"
  965. X$ tcpip_P3_'arg' :== "''P3'"
  966. X$ tcpip_P4_'arg' :== "''P4'"
  967. X$ tcpip_P5_'arg' :== "''P5'"
  968. X$ arg == arg + 1    ! *NOTE* global symbols used...
  969. X$ENDSUBROUTINE
  970. X$!
  971. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  972. X$! **NOTE** cflags is a GLOBAL symbol due to problems with quoted /Defines
  973. X$! **NOTE** not passing down correctly.. (I gave up!)
  974. X$Compile: SUBROUTINE
  975. X$ YES = (1.eq.1)
  976. X$! --- do a Make of only that source which has been modified since its
  977. X$!     object code was generated or that is missing its object code.
  978. X$ cc       = "''P1'"
  979. X$ source   = "''P2'"
  980. X$ dbg      = "''P3'"
  981. X$ FORCED   = P4
  982. X$!
  983. X$source = source - ".C" + ".C"
  984. X$ t1 = f$search("''source'")                ! source exists?
  985. X$  If (t1 .eqs. "") Then GoTo _error_source_missing    ! YIPE!
  986. X$   source = source - ".C"
  987. X$    if (FORCED) Then GoTo _compile_the_source        ! forced to compile
  988. X$     t1 = f$search("''source'.OBJ")            ! object exist?
  989. X$     If (t1 .eqs. "") Then GoTo _compile_the_source    ! object missing
  990. X$     t1 = f$file_attributes("''source'.OBJ","RDT")    ! when was the OBJECT
  991. X$    t1 = f$cvtime(t1)                    ! produced? (rev date)
  992. X$   t2 = f$file_attributes("''source'.C","RDT")        ! when was source last
  993. X$  t2 = f$cvtime(t2)                    ! modified?
  994. X$ If (t1 .ges. t2) Then GoTo _bypass_compile        ! object still current
  995. X$_compile_the_source:
  996. X$ set verify
  997. X$ 'cc -
  998. X  'cflags -
  999. X  'dbg 'source
  1000. X$ x='f$verify(0)'
  1001. X$ LINKAGE_REQUIRED == YES
  1002. X$  GoTo _cc_done
  1003. X$_bypass_compile:                    ! didn't need to
  1004. X$  GoTo _cc_done                    ! generate new OBJ file
  1005. X$_error_source_missing:
  1006. X$ Write Sys$Error "ERROR: unable to locate source file ''source'"
  1007. X$_cc_done:
  1008. X$ENDSUBROUTINE
  1009. X$!
  1010. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1011. X$!
  1012. X$CHECKIFVERSIONOK:
  1013. X$ required_version = tcpip_P5_'i'
  1014. X$ tcpip_type = tcpip_P1_'i'
  1015. X$ If ("MULTINET" .eqs. tcpip_type)
  1016. X$ Then                        ! I know how to check MULTINET
  1017. X$   If (f$search("MULTINET:MULTINET_VERSION.;") .nes. "")
  1018. X$   Then
  1019. X$     Open/share=READ fd MULTINET:MULTINET_VERSION.;
  1020. X$     Read fd buffer
  1021. X$     Close fd
  1022. X$     v = buffer - "VERSION"
  1023. X$     v = f$edit(v,"TRIM,COMPRESS")
  1024. X$     If (v .ges. required_version)
  1025. X$     Then VERSION_TOO_EARLY = NO
  1026. X$     Else VERSION_TOO_EARLY = YES
  1027. X$     EndIF
  1028. X$   Else
  1029. X$     VERSION_TOO_EARLY = YES
  1030. X$   EndIF
  1031. X$ Else                        ! don't know, so assume current
  1032. X$   VERSION_TOO_EARLY = NO
  1033. X$ EndIF
  1034. X$!
  1035. X$ RETURN
  1036. X$!
  1037. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1038. X$!
  1039. X$CREATE_SUPPORT_OPTIONS:
  1040. X$ Open/Write fd No_Support.OPT
  1041. X$ Write fd "! --- No_Support.OPT ---"
  1042. X$ Write fd "!"
  1043. X$ Write fd "! provides the VaxCrtl linkage for the client that has no"
  1044. X$ Write fd "! known supported TCP/IP implementation."
  1045. X$ Write fd "!"
  1046. X$ Write fd "Sys$Share:VaxCrtl.exe/Share"
  1047. X$ Write fd "!"
  1048. X$ Write fd "! You will have to add in your specific TCP/IP libraries here."
  1049. X$!
  1050. X$! Early MULTINETs would look something like this... (I don't remember!)
  1051. X$! I assume CMUTEK would need something along these lines too...
  1052. X$!
  1053. X$! If (F$TrnLnm("MULTINET") .nes. "")
  1054. X$! Then
  1055. X$!   Write fd "Multinet:Multinet_Socket_Library.exe/Share
  1056. X$! EndIF
  1057. X$!
  1058. X$ Write fd "!"
  1059. X$ Close fd
  1060. X$!
  1061. X$ RETURN
  1062. X$!
  1063. X$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1064. END_OF_FILE
  1065.   if test 17686 -ne `wc -c <'make.com'`; then
  1066.     echo shar: \"'make.com'\" unpacked with wrong size!
  1067.   fi
  1068.   # end of 'make.com'
  1069. fi
  1070. if test -f 'msdos/netevent.h' -a "${1}" != "-c" ; then 
  1071.   echo shar: Will not clobber existing file \"'msdos/netevent.h'\"
  1072. else
  1073.   echo shar: Extracting \"'msdos/netevent.h'\" \(2703 characters\)
  1074.   sed "s/^X//" >'msdos/netevent.h' <<'END_OF_FILE'
  1075. X/* hfile.inc - placed into all .h files to set up for PVCS 
  1076. X   $Header: /tmp_mnt/com/projects/archie/msdos/RCS/netevent.h,v 1.2 1991/12/13 20:08:56 brendan Exp $
  1077. X   Revision History ----------------------------------------------------
  1078. X   $Log: netevent.h,v $
  1079. X * Revision 1.2  1991/12/13  20:08:56  brendan
  1080. X * entered into RCS
  1081. X *
  1082. X * 
  1083. X *    Rev 1.0   15 Jan 1990 19:29:26   bkc
  1084. X*/
  1085. X
  1086. X
  1087. X/*
  1088. X*  Events for event processing in NCSA Telnet.
  1089. X*  Used for netgetevent().
  1090. X*/
  1091. X
  1092. X
  1093. X#define USERCLASS    1    /* the user program will accept these events */
  1094. X#define ICMPCLASS    2    /* ICMP in netsleep will look for these */
  1095. X#define ERRCLASS    4    /* the user may or may not read these error messages */
  1096. X#define SCLASS        8    /* the background server will take these */
  1097. X#define CONCLASS    0x10    /* the application manages connections with these */
  1098. X
  1099. X#define ERR1    1        /* an error message is waiting, ERRCLASS */
  1100. X
  1101. X#define IREDIR    1        /* ICMP redirect, ICMPCLASS */
  1102. X
  1103. X#define CONOPEN 1        /* connection has opened, CONCLASS */
  1104. X#define CONDATA 2       /* there is data available on this connection */
  1105. X#define CONCLOSE 3        /* the other side has closed its side of the connection */
  1106. X#define CONFAIL 4        /* connection open attempt has failed */
  1107. X
  1108. X#define UDPDATA 1        /* UDP data has arrived on listening port, USERCLASS */
  1109. X#define DOMOK    2        /* domain name ready */
  1110. X#define DOMFAIL 3        /* domain name lookup failed */
  1111. X#define FTPCOPEN 20     /* FTP command connection has opened */
  1112. X#define FTPCLOSE 21     /* FTP command connection has closed */
  1113. X#define FTPBEGIN 22     /* FTP transfer beginning, dat =1 for get, 0 for put */
  1114. X#define FTPEND   23     /* FTP transfer ending */
  1115. X#define FTPLIST  24     /* FTP file listing taking place */
  1116. X#define FTPUSER  25     /* FTP user name has been entered */
  1117. X#define FTPPWOK    26        /* FTP password verified */
  1118. X#define FTPPWNO 27        /* FTP password failed */
  1119. X#define RCPBEGIN 30        /* RCP beginning */
  1120. X#define RCPEND 31        /* RCP ending */
  1121. X
  1122. X#define UDPTO 1            /* UDP request from DOMAIN timed out, SCLASS */
  1123. X#define FTPACT 2        /* FTP transfer is active, keep sending */
  1124. X#define TCPTO  3        /* TCP for DOMAIN timed out */
  1125. X#define RCPACT 4        /* rcp is active, needs CPU time */
  1126. X#define RETRYCON 5        /* retry connection packet, might be lost */
  1127. X#define DOMNEXT 6               /* search next domain list entry */
  1128. X#define E_CLOCK 7
  1129. X#ifdef    SCRIPT
  1130. X#define    SCRIPT_EVENT    1    /* script next step */
  1131. X#define    SCRIPT_DATA    2    /* received some data */
  1132. X#define    SCRIPT_PROC    3    /* just process stuff */
  1133. X#define    SCRIPT_CLOSE    4    /* connection was closed */
  1134. X#define    SCRIPT_FORCE    5    /* user forced connection closed */
  1135. X#define    SCRIPT_DOMAIN    6    /* domain name lookup ok */
  1136. X#define    SCRIPT_FUNC    8
  1137. X/* int Script_Event(int type, void *twin, unsigned int data); */
  1138. X#endif
  1139. END_OF_FILE
  1140.   if test 2703 -ne `wc -c <'msdos/netevent.h'`; then
  1141.     echo shar: \"'msdos/netevent.h'\" unpacked with wrong size!
  1142.   fi
  1143.   # end of 'msdos/netevent.h'
  1144. fi
  1145. if test -f 'regex.c' -a "${1}" != "-c" ; then 
  1146.   echo shar: Will not clobber existing file \"'regex.c'\"
  1147. else
  1148.   echo shar: Extracting \"'regex.c'\" \(16197 characters\)
  1149.   sed "s/^X//" >'regex.c' <<'END_OF_FILE'
  1150. X#include <pmachine.h>
  1151. X
  1152. X#ifdef NOREGEX
  1153. X/*
  1154. X * These routines are BSD regex(3)/ed(1) compatible regular-expression
  1155. X * routines written by Ozan S. Yigit, Computer Science, York University.
  1156. X * Parts of the code that are not needed by Prospero have been removed,
  1157. X * but most of the accompanying information has been left intact. 
  1158. X * This file is to be included on those operating systems that do not
  1159. X * support re_comp and re_exec.
  1160. X */
  1161. X
  1162. X/*
  1163. X * regex - Regular expression pattern matching
  1164. X *         and replacement
  1165. X *
  1166. X * by:  Ozan S. Yigit (oz@nexus.yorku.ca)
  1167. X *    Dept. of Computing Services
  1168. X *      York University
  1169. X *
  1170. X * These routines are the PUBLIC DOMAIN equivalents 
  1171. X * of regex routines as found in 4.nBSD UN*X, with minor
  1172. X * extensions.
  1173. X *
  1174. X * Modification history:
  1175. X *
  1176. X * $Log: regex.c,v $
  1177. X * Revision 1.1  1991/11/20  02:32:13  brendan
  1178. X * entered into RCS
  1179. X *
  1180. X * Revision 1.1  1991/11/20  02:32:13  brendan
  1181. X * entered into RCS
  1182. X *
  1183. X * Revision 1.3  89/04/01  14:18:09  oz
  1184. X * Change all references to a dfa: this is actually an nfa.
  1185. X * 
  1186. X * Revision 1.2  88/08/28  15:36:04  oz
  1187. X * Use a complement bitmap to represent NCL.
  1188. X * This removes the need to have seperate 
  1189. X * code in the pmatch case block - it is 
  1190. X * just CCL code now.
  1191. X * 
  1192. X * Use the actual CCL code in the CLO
  1193. X * section of pmatch. No need for a recursive
  1194. X * pmatch call.
  1195. X * 
  1196. X * Use a bitmap table to set char bits in an
  1197. X * 8-bit chunk.
  1198. X * 
  1199. X * Routines:
  1200. X *      re_comp:        compile a regular expression into
  1201. X *                      a NFA.
  1202. X *
  1203. X *            char *re_comp(s)
  1204. X *            char *s;
  1205. X *
  1206. X *      re_exec:        execute the NFA to match a pattern.
  1207. X *
  1208. X *            int re_exec(s)
  1209. X *            char *s;
  1210. X *
  1211. X * Regular Expressions:
  1212. X *
  1213. X *      [1]     char    matches itself, unless it is a special
  1214. X *                      character (metachar): . \ [ ] * + ^ $
  1215. X *
  1216. X *      [2]     .       matches any character.
  1217. X *
  1218. X *      [3]     \       matches the character following it, except
  1219. X *            when followed by a left or right round bracket,
  1220. X *            a digit 1 to 9 or a left or right angle bracket. 
  1221. X *            (see [7], [8] and [9])
  1222. X *            It is used as an escape character for all 
  1223. X *            other meta-characters, and itself. When used
  1224. X *            in a set ([4]), it is treated as an ordinary
  1225. X *            character.
  1226. X *
  1227. X *      [4]     [set]   matches one of the characters in the set.
  1228. X *                      If the first character in the set is "^",
  1229. X *                      it matches a character NOT in the set, i.e. 
  1230. X *            complements the set. A shorthand S-E is 
  1231. X *            used to specify a set of characters S upto 
  1232. X *            E, inclusive. The special characters "]" and 
  1233. X *            "-" have no special meaning if they appear 
  1234. X *            as the first chars in the set.
  1235. X *                      examples:        match:
  1236. X *
  1237. X *                              [a-z]    any lowercase alpha
  1238. X *
  1239. X *                              [^]-]    any char except ] and -
  1240. X *
  1241. X *                              [^A-Z]   any char except uppercase
  1242. X *                                       alpha
  1243. X *
  1244. X *                              [a-zA-Z] any alpha
  1245. X *
  1246. X *      [5]     *       any regular expression form [1] to [4], followed by
  1247. X *                      closure char (*) matches zero or more matches of
  1248. X *                      that form.
  1249. X *
  1250. X *      [6]     +       same as [5], except it matches one or more.
  1251. X *
  1252. X *      [7]             a regular expression in the form [1] to [10], enclosed
  1253. X *                      as \(form\) matches what form matches. The enclosure
  1254. X *                      creates a set of tags, used for [8] and for
  1255. X *                      pattern substution. The tagged forms are numbered
  1256. X *            starting from 1.
  1257. X *
  1258. X *      [8]             a \ followed by a digit 1 to 9 matches whatever a
  1259. X *                      previously tagged regular expression ([7]) matched.
  1260. X *
  1261. X *    [9]    \<    a regular expression starting with a \< construct
  1262. X *        \>    and/or ending with a \> construct, restricts the
  1263. X *            pattern matching to the beginning of a word, and/or
  1264. X *            the end of a word. A word is defined to be a character
  1265. X *            string beginning and/or ending with the characters
  1266. X *            A-Z a-z 0-9 and _. It must also be preceded and/or
  1267. X *            followed by any character outside those mentioned.
  1268. X *
  1269. X *      [10]            a composite regular expression xy where x and y
  1270. X *                      are in the form [1] to [10] matches the longest
  1271. X *                      match of x followed by a match for y.
  1272. X *
  1273. X *      [11]    ^    a regular expression starting with a ^ character
  1274. X *        $    and/or ending with a $ character, restricts the
  1275. X *                      pattern matching to the beginning of the line,
  1276. X *                      or the end of line. [anchors] Elsewhere in the
  1277. X *            pattern, ^ and $ are treated as ordinary characters.
  1278. X *
  1279. X *
  1280. X * Acknowledgements:
  1281. X *
  1282. X *    HCR's Hugh Redelmeier has been most helpful in various
  1283. X *    stages of development. He convinced me to include BOW
  1284. X *    and EOW constructs, originally invented by Rob Pike at
  1285. X *    the University of Toronto.
  1286. X *
  1287. X * References:
  1288. X *              Software tools            Kernighan & Plauger
  1289. X *              Software tools in Pascal        Kernighan & Plauger
  1290. X *              Grep [rsx-11 C dist]            David Conroy
  1291. X *        ed - text editor        Un*x Programmer's Manual
  1292. X *        Advanced editing on Un*x    B. W. Kernighan
  1293. X *        regexp routines            Henry Spencer
  1294. X *
  1295. X * Notes:
  1296. X *
  1297. X *    This implementation uses a bit-set representation for character
  1298. X *    classes for speed and compactness. Each character is represented 
  1299. X *    by one bit in a 128-bit block. Thus, CCL always takes a 
  1300. X *    constant 16 bytes in the internal nfa, and re_exec does a single
  1301. X *    bit comparison to locate the character in the set.
  1302. X *
  1303. X * Examples:
  1304. X *
  1305. X *    pattern:    foo*.*
  1306. X *    compile:    CHR f CHR o CLO CHR o END CLO ANY END END
  1307. X *    matches:    fo foo fooo foobar fobar foxx ...
  1308. X *
  1309. X *    pattern:    fo[ob]a[rz]    
  1310. X *    compile:    CHR f CHR o CCL bitset CHR a CCL bitset END
  1311. X *    matches:    fobar fooar fobaz fooaz
  1312. X *
  1313. X *    pattern:    foo\\+
  1314. X *    compile:    CHR f CHR o CHR o CHR \ CLO CHR \ END END
  1315. X *    matches:    foo\ foo\\ foo\\\  ...
  1316. X *
  1317. X *    pattern:    \(foo\)[1-3]\1    (same as foo[1-3]foo)
  1318. X *    compile:    BOT 1 CHR f CHR o CHR o EOT 1 CCL bitset REF 1 END
  1319. X *    matches:    foo1foo foo2foo foo3foo
  1320. X *
  1321. X *    pattern:    \(fo.*\)-\1
  1322. X *    compile:    BOT 1 CHR f CHR o CLO ANY END EOT 1 CHR - REF 1 END
  1323. X *    matches:    foo-foo fo-fo fob-fob foobar-foobar ...
  1324. X * 
  1325. X */
  1326. X
  1327. X#define MAXNFA  1024
  1328. X#define MAXTAG  10
  1329. X
  1330. X#define OKP     1
  1331. X#define NOP     0
  1332. X
  1333. X#define CHR     1
  1334. X#define ANY     2
  1335. X#define CCL     3
  1336. X#define BOL     4
  1337. X#define EOL     5
  1338. X#define BOT     6
  1339. X#define EOT     7
  1340. X#define BOW    8
  1341. X#define EOW    9
  1342. X#define REF     10
  1343. X#define CLO     11
  1344. X
  1345. X#define END     0
  1346. X
  1347. X/*
  1348. X * The following defines are not meant
  1349. X * to be changeable. They are for readability
  1350. X * only.
  1351. X *
  1352. X */
  1353. X#define MAXCHR    128
  1354. X#define CHRBIT    8
  1355. X#define BITBLK    MAXCHR/CHRBIT
  1356. X#define BLKIND    0170
  1357. X#define BITIND    07
  1358. X
  1359. X#define ASCIIB    0177
  1360. X
  1361. Xtypedef /*unsigned*/ char CHAR;
  1362. X
  1363. Xstatic int  tagstk[MAXTAG];             /* subpat tag stack..*/
  1364. Xstatic CHAR nfa[MAXNFA];        /* automaton..       */
  1365. Xstatic int  sta = NOP;                   /* status of lastpat */
  1366. X
  1367. Xstatic CHAR bittab[BITBLK];        /* bit table for CCL */
  1368. X                    /* pre-set bits...   */
  1369. Xstatic CHAR bitarr[] = {1,2,4,8,16,32,64,128};
  1370. X
  1371. Xstatic int internal_error;
  1372. X
  1373. Xstatic void
  1374. Xchset(c)
  1375. Xregister CHAR c;
  1376. X{
  1377. X    bittab[((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND];
  1378. X}
  1379. X
  1380. X#define badpat(x)    return (*nfa = END, x)
  1381. X#define store(x)    *mp++ = x
  1382. Xchar *     
  1383. Xre_comp(pat)
  1384. Xchar *pat;
  1385. X{
  1386. X    register char *p;               /* pattern pointer   */
  1387. X    register CHAR *mp = nfa;        /* nfa pointer       */
  1388. X    register CHAR *lp;              /* saved pointer..   */
  1389. X    register CHAR *sp = nfa;        /* another one..     */
  1390. X
  1391. X    register int tagi = 0;          /* tag stack index   */
  1392. X    register int tagc = 1;          /* actual tag count  */
  1393. X
  1394. X    register int n;
  1395. X    register CHAR mask;        /* xor mask -CCL/NCL */
  1396. X    int c1, c2;
  1397. X        
  1398. X    if (!pat || !*pat)
  1399. X        if (sta)
  1400. X            return 0;
  1401. X        else
  1402. X            badpat("No previous regular expression");
  1403. X    sta = NOP;
  1404. X
  1405. X    for (p = pat; *p; p++) {
  1406. X        lp = mp;
  1407. X        switch(*p) {
  1408. X
  1409. X        case '.':               /* match any char..  */
  1410. X            store(ANY);
  1411. X            break;
  1412. X
  1413. X        case '^':               /* match beginning.. */
  1414. X            if (p == pat)
  1415. X                store(BOL);
  1416. X            else {
  1417. X                store(CHR);
  1418. X                store(*p);
  1419. X            }
  1420. X            break;
  1421. X
  1422. X        case '$':               /* match endofline.. */
  1423. X            if (!*(p+1))
  1424. X                store(EOL);
  1425. X            else {
  1426. X                store(CHR);
  1427. X                store(*p);
  1428. X            }
  1429. X            break;
  1430. X
  1431. X        case '[':               /* match char class..*/
  1432. X            store(CCL);
  1433. X
  1434. X            if (*++p == '^') {
  1435. X                mask = 0377;    
  1436. X                p++;
  1437. X            }
  1438. X            else
  1439. X                mask = 0;
  1440. X
  1441. X            if (*p == '-')        /* real dash */
  1442. X                chset(*p++);
  1443. X            if (*p == ']')        /* real brac */
  1444. X                chset(*p++);
  1445. X            while (*p && *p != ']') {
  1446. X                if (*p == '-' && *(p+1) && *(p+1) != ']') {
  1447. X                    p++;
  1448. X                    c1 = *(p-2) + 1;
  1449. X                    c2 = *p++;
  1450. X                    while (c1 <= c2)
  1451. X                        chset(c1++);
  1452. X                }
  1453. X#ifdef EXTEND
  1454. X                else if (*p == '\\' && *(p+1)) {
  1455. X                    p++;
  1456. X                    chset(*p++);
  1457. X                }
  1458. X#endif
  1459. X                else
  1460. X                    chset(*p++);
  1461. X            }
  1462. X            if (!*p)
  1463. X                badpat("Missing ]");
  1464. X
  1465. X            for (n = 0; n < BITBLK; bittab[n++] = (char) 0)
  1466. X                store(mask ^ bittab[n]);
  1467. X    
  1468. X            break;
  1469. X
  1470. X        case '*':               /* match 0 or more.. */
  1471. X        case '+':               /* match 1 or more.. */
  1472. X            if (p == pat)
  1473. X                badpat("Empty closure");
  1474. X            lp = sp;        /* previous opcode */
  1475. X            if (*lp == CLO)        /* equivalence..   */
  1476. X                break;
  1477. X            switch(*lp) {
  1478. X
  1479. X            case BOL:
  1480. X            case BOT:
  1481. X            case EOT:
  1482. X            case BOW:
  1483. X            case EOW:
  1484. X            case REF:
  1485. X                badpat("Illegal closure");
  1486. X            default:
  1487. X                break;
  1488. X            }
  1489. X
  1490. X            if (*p == '+')
  1491. X                for (sp = mp; lp < sp; lp++)
  1492. X                    store(*lp);
  1493. X
  1494. X            store(END);
  1495. X            store(END);
  1496. X            sp = mp;
  1497. X            while (--mp > lp)
  1498. X                *mp = mp[-1];
  1499. X            store(CLO);
  1500. X            mp = sp;
  1501. X            break;
  1502. X
  1503. X        case '\\':              /* tags, backrefs .. */
  1504. X            switch(*++p) {
  1505. X
  1506. X            case '(':
  1507. X                if (tagc < MAXTAG) {
  1508. X                    tagstk[++tagi] = tagc;
  1509. X                    store(BOT);
  1510. X                    store(tagc++);
  1511. X                }
  1512. X                else
  1513. X                    badpat("Too many \\(\\) pairs");
  1514. X                break;
  1515. X            case ')':
  1516. X                if (*sp == BOT)
  1517. X                    badpat("Null pattern inside \\(\\)");
  1518. X                if (tagi > 0) {
  1519. X                    store(EOT);
  1520. X                    store(tagstk[tagi--]);
  1521. X                }
  1522. X                else
  1523. X                    badpat("Unmatched \\)");
  1524. X                break;
  1525. X            case '<':
  1526. X                store(BOW);
  1527. X                break;
  1528. X            case '>':
  1529. X                if (*sp == BOW)
  1530. X                    badpat("Null pattern inside \\<\\>");
  1531. X                store(EOW);
  1532. X                break;
  1533. X            case '1':
  1534. X            case '2':
  1535. X            case '3':
  1536. X            case '4':
  1537. X            case '5':
  1538. X            case '6':
  1539. X            case '7':
  1540. X            case '8':
  1541. X            case '9':
  1542. X                n = *p-'0';
  1543. X                if (tagi > 0 && tagstk[tagi] == n)
  1544. X                    badpat("Cyclical reference");
  1545. X                if (tagc > n) {
  1546. X                    store(REF);
  1547. X                    store(n);
  1548. X                }
  1549. X                else
  1550. X                    badpat("Undetermined reference");
  1551. X                break;
  1552. X#ifdef EXTEND
  1553. X            case 'b':
  1554. X                store(CHR);
  1555. X                store('\b');
  1556. X                break;
  1557. X            case 'n':
  1558. X                store(CHR);
  1559. X                store('\n');
  1560. X                break;
  1561. X            case 'f':
  1562. X                store(CHR);
  1563. X                store('\f');
  1564. X                break;
  1565. X            case 'r':
  1566. X                store(CHR);
  1567. X                store('\r');
  1568. X                break;
  1569. X            case 't':
  1570. X                store(CHR);
  1571. X                store('\t');
  1572. X                break;
  1573. X#endif
  1574. X            default:
  1575. X                store(CHR);
  1576. X                store(*p);
  1577. X            }
  1578. X            break;
  1579. X
  1580. X        default :               /* an ordinary char  */
  1581. X            store(CHR);
  1582. X            store(*p);
  1583. X            break;
  1584. X        }
  1585. X        sp = lp;
  1586. X    }
  1587. X    if (tagi > 0)
  1588. X        badpat("Unmatched \\(");
  1589. X    store(END);
  1590. X    sta = OKP;
  1591. X    return 0;
  1592. X}
  1593. X
  1594. X
  1595. Xstatic char *bol;
  1596. Xstatic char *bopat[MAXTAG];
  1597. Xstatic char *eopat[MAXTAG];
  1598. Xchar *pmatch();
  1599. X
  1600. X/*
  1601. X * re_exec:
  1602. X *     execute nfa to find a match.
  1603. X *
  1604. X *    special cases: (nfa[0])    
  1605. X *        BOL
  1606. X *            Match only once, starting from the
  1607. X *            beginning.
  1608. X *        CHR
  1609. X *            First locate the character without
  1610. X *            calling pmatch, and if found, call
  1611. X *            pmatch for the remaining string.
  1612. X *        END
  1613. X *            re_comp failed, poor luser did not
  1614. X *            check for it. Fail fast.
  1615. X *
  1616. X *    If a match is found, bopat[0] and eopat[0] are set
  1617. X *    to the beginning and the end of the matched fragment,
  1618. X *    respectively.
  1619. X *
  1620. X */
  1621. X
  1622. Xint
  1623. Xre_exec(lp)
  1624. Xregister char *lp;
  1625. X{
  1626. X    register char c;
  1627. X    register char *ep = 0;
  1628. X    register CHAR *ap = nfa;
  1629. X
  1630. X    bol = lp;
  1631. X
  1632. X    bopat[0] = 0;
  1633. X    bopat[1] = 0;
  1634. X    bopat[2] = 0;
  1635. X    bopat[3] = 0;
  1636. X    bopat[4] = 0;
  1637. X    bopat[5] = 0;
  1638. X    bopat[6] = 0;
  1639. X    bopat[7] = 0;
  1640. X    bopat[8] = 0;
  1641. X    bopat[9] = 0;
  1642. X
  1643. X    switch(*ap) {
  1644. X
  1645. X    case BOL:            /* anchored: match from BOL only */
  1646. X        ep = pmatch(lp,ap);
  1647. X        break;
  1648. X    case CHR:            /* ordinary char: locate it fast */
  1649. X        c = *(ap+1);
  1650. X        while (*lp && *lp != c)
  1651. X            lp++;
  1652. X        if (!*lp)        /* if EOS, fail, else fall thru. */
  1653. X            return 0;
  1654. X    default:            /* regular matching all the way. */
  1655. X        while (*lp) {
  1656. X            if ((ep = pmatch(lp,ap)))
  1657. X                break;
  1658. X            lp++;
  1659. X        }
  1660. X        break;
  1661. X    case END:            /* munged automaton. fail always */
  1662. X        return 0;
  1663. X    }
  1664. X    if (!ep)
  1665. X        return 0;
  1666. X
  1667. X    if (internal_error)
  1668. X        return -1;
  1669. X
  1670. X    bopat[0] = lp;
  1671. X    eopat[0] = ep;
  1672. X    return 1;
  1673. X}
  1674. X
  1675. X/* 
  1676. X * pmatch: 
  1677. X *    internal routine for the hard part
  1678. X *
  1679. X *     This code is mostly snarfed from an early
  1680. X *     grep written by David Conroy. The backref and
  1681. X *     tag stuff, and various other mods are by oZ.
  1682. X *
  1683. X *    special cases: (nfa[n], nfa[n+1])
  1684. X *        CLO ANY
  1685. X *            We KNOW ".*" will match ANYTHING
  1686. X *            upto the end of line. Thus, go to
  1687. X *            the end of line straight, without
  1688. X *            calling pmatch recursively. As in
  1689. X *            the other closure cases, the remaining
  1690. X *            pattern must be matched by moving
  1691. X *            backwards on the string recursively,
  1692. X *            to find a match for xy (x is ".*" and 
  1693. X *            y is the remaining pattern) where
  1694. X *            the match satisfies the LONGEST match
  1695. X *            for x followed by a match for y.
  1696. X *        CLO CHR
  1697. X *            We can again scan the string forward
  1698. X *            for the single char without recursion, 
  1699. X *            and at the point of failure, we execute 
  1700. X *            the remaining nfa recursively, as
  1701. X *            described above.
  1702. X *
  1703. X *    At the end of a successful match, bopat[n] and eopat[n]
  1704. X *    are set to the beginning and end of subpatterns matched
  1705. X *    by tagged expressions (n = 1 to 9).    
  1706. X *
  1707. X */
  1708. X
  1709. X/*
  1710. X * character classification table for word boundary
  1711. X * operators BOW and EOW. the reason for not using 
  1712. X * ctype macros is that we can let the user add into 
  1713. X * our own table. see re_modw. This table is not in
  1714. X * the bitset form, since we may wish to extend it
  1715. X * in the future for other character classifications. 
  1716. X *
  1717. X *    TRUE for 0-9 A-Z a-z _
  1718. X */
  1719. Xstatic char chrtyp[MAXCHR] = {
  1720. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
  1721. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
  1722. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
  1723. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
  1724. X    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
  1725. X    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
  1726. X    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
  1727. X    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  1728. X    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  1729. X    1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 
  1730. X    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  1731. X    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  1732. X    1, 1, 1, 0, 0, 0, 0, 0
  1733. X    };
  1734. X
  1735. X#define inascii(x)    (0177&(x))
  1736. X#define iswordc(x)     chrtyp[inascii(x)]
  1737. X#define isinset(x,y)     ((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND])
  1738. X
  1739. X/*
  1740. X * skip values for CLO XXX to skip past the closure
  1741. X *
  1742. X */
  1743. X
  1744. X#define ANYSKIP    2     /* [CLO] ANY END ...         */
  1745. X#define CHRSKIP    3    /* [CLO] CHR chr END ...     */
  1746. X#define CCLSKIP 18    /* [CLO] CCL 16bytes END ... */
  1747. X
  1748. Xstatic char *
  1749. Xpmatch(lp, ap)
  1750. Xregister char *lp;
  1751. Xregister CHAR *ap;
  1752. X{
  1753. X    register int op, c, n;
  1754. X    register char *e;        /* extra pointer for CLO */
  1755. X    register char *bp;        /* beginning of subpat.. */
  1756. X    register char *ep;        /* ending of subpat..     */
  1757. X    char *are;            /* to save the line ptr. */
  1758. X
  1759. X    while ((op = *ap++) != END)
  1760. X        switch(op) {
  1761. X
  1762. X        case CHR:
  1763. X            if (*lp++ != *ap++)
  1764. X                return 0;
  1765. X            break;
  1766. X        case ANY:
  1767. X            if (!*lp++)
  1768. X                return 0;
  1769. X            break;
  1770. X        case CCL:
  1771. X            c = *lp++;
  1772. X            if (!isinset(ap,c))
  1773. X                return 0;
  1774. X            ap += BITBLK;
  1775. X            break;
  1776. X        case BOL:
  1777. X            if (lp != bol)
  1778. X                return 0;
  1779. X            break;
  1780. X        case EOL:
  1781. X            if (*lp)
  1782. X                return 0;
  1783. X            break;
  1784. X        case BOT:
  1785. X            bopat[*ap++] = lp;
  1786. X            break;
  1787. X        case EOT:
  1788. X            eopat[*ap++] = lp;
  1789. X            break;
  1790. X         case BOW:
  1791. X            if (lp!=bol && iswordc(lp[-1]) || !iswordc(*lp))
  1792. X                return 0;
  1793. X            break;
  1794. X        case EOW:
  1795. X            if (lp==bol || !iswordc(lp[-1]) || iswordc(*lp))
  1796. X                return 0;
  1797. X            break;
  1798. X        case REF:
  1799. X            n = *ap++;
  1800. X            bp = bopat[n];
  1801. X            ep = eopat[n];
  1802. X            while (bp < ep)
  1803. X                if (*bp++ != *lp++)
  1804. X                    return 0;
  1805. X            break;
  1806. X        case CLO:
  1807. X            are = lp;
  1808. X            switch(*ap) {
  1809. X
  1810. X            case ANY:
  1811. X                while (*lp)
  1812. X                    lp++;
  1813. X                n = ANYSKIP;
  1814. X                break;
  1815. X            case CHR:
  1816. X                c = *(ap+1);
  1817. X                while (*lp && c == *lp)
  1818. X                    lp++;
  1819. X                n = CHRSKIP;
  1820. X                break;
  1821. X            case CCL:
  1822. X                while ((c = *lp) && isinset(ap+1,c))
  1823. X                    lp++;
  1824. X                n = CCLSKIP;
  1825. X                break;
  1826. X            default:
  1827. X                internal_error++;
  1828. X                return 0;
  1829. X            }
  1830. X
  1831. X            ap += n;
  1832. X
  1833. X            while (lp >= are) {
  1834. X                if (e = pmatch(lp, ap))
  1835. X                    return e;
  1836. X                --lp;
  1837. X            }
  1838. X            return 0;
  1839. X        default:
  1840. X            internal_error++;
  1841. X            return 0;
  1842. X        }
  1843. X    return lp;
  1844. X}
  1845. X#endif /* Need regex libraries? Compile to nothing if not.  */
  1846. END_OF_FILE
  1847.   if test 16197 -ne `wc -c <'regex.c'`; then
  1848.     echo shar: \"'regex.c'\" unpacked with wrong size!
  1849.   fi
  1850.   # end of 'regex.c'
  1851. fi
  1852. echo shar: End of archive 4 \(of 7\).
  1853. cp /dev/null ark4isdone
  1854. MISSING=""
  1855. for I in 1 2 3 4 5 6 7 ; do
  1856.     if test ! -f ark${I}isdone ; then
  1857.     MISSING="${MISSING} ${I}"
  1858.     fi
  1859. done
  1860. if test "${MISSING}" = "" ; then
  1861.     echo You have unpacked all 7 archives.
  1862.     rm -f ark[1-9]isdone
  1863. else
  1864.     echo You still must unpack the following archives:
  1865.     echo "        " ${MISSING}
  1866. fi
  1867. exit 0
  1868. exit 0 # Just in case...
  1869.