home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / sources / misc / 4058 < prev    next >
Encoding:
Text File  |  1992-11-05  |  54.3 KB  |  1,876 lines

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