home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / infoserv / gopher / mvs / old-versions / gopher.ggmvs.distrib.cntl.v2r1.Z / gopher.ggmvs.distrib.cntl.v2r1
Encoding:
Text File  |  1995-04-24  |  1.1 MB  |  13,814 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  2. //*------------------------------------------------------------------*/         
  3. //*                                                                  */         
  4. //* Copyright (c) The Charles Stark Draper Laboratory, Inc.,1992,1993*/         
  5. //*                                                                  */         
  6. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  7. //* including the implied warranties of merchantability and fitness, */         
  8. //* are expressly denied.                                            */         
  9. //*                                                                  */         
  10. //* Provided this copyright notice is included, this software may    */         
  11. //* be freely distributed and not offered for sale.                  */         
  12. //*                                                                  */         
  13. //* Changes or modifications may be made and used only by the maker  */         
  14. //* of same, and not further distributed.  Such modifications should */         
  15. //* be mailed to the author for consideration for addition to the    */         
  16. //* software and incorporation in subsequent releases.               */         
  17. //*                                                                  */         
  18. //*------------------------------------------------------------------*/         
  19. //*                                                                             
  20. //* MVS GOPHER client                                                           
  21. //*                                                                             
  22. //* Author:  Steve Bacher <seb1525@mvs.draper.com>                              
  23. //*                                                                             
  24. //* Date:  April, 1993                                                          
  25. //*                                                                             
  26. //*--------------------------------------------------------------------         
  27. //*                                                                             
  28. //* This job creates the GOPHER distribution libraries (PDS's).                 
  29. //*                                                                             
  30. //* Run this JCL to create the PDS's, after customizing to suit.                
  31. //* (Obviously, put in a good JOB statement first.)                             
  32. //* To customize the JCL, change the defaults on the //GGLOAD PROC              
  33. //* statement to your liking, particularly the PREFIX default.                  
  34. //* You might also want to change the final qualifiers of the PDS's             
  35. //* created - to do this, find the // EXEC GGLOAD statements and                
  36. //* change the value of the TO parameter.                                       
  37. //*                                                                             
  38. //* See the $$README file (of the CNTL PDS, first in this stream)               
  39. //* for the rest of the installation instructions.                              
  40. //*                                                                             
  41. //GGLOAD  PROC CLS='*',BS='6160',U='3380',V='',                                 
  42. //             TRK1='30',TRK2='10',DIR='35',RLSE='RLSE',                        
  43. //             PREFIX='GOPHER.INSTALL.'                                         
  44. //*                                                                             
  45. //IEBUPDTE EXEC PGM=IEBUPDTE,PARM=NEW                                           
  46. //SYSPRINT DD   SYSOUT=&CLS                                                     
  47. //SYSUT2   DD   DISP=(NEW,CATLG,DELETE),DSN=&PREFIX.&TO,                        
  48. //         DCB=(RECFM=FB,LRECL=80,BLKSIZE=&BS),                                 
  49. //         SPACE=(TRK,(&TRK1,&TRK2,&DIR),&RLSE),UNIT=&U,VOL=SER=&V              
  50. //*                                                                             
  51. //         PEND                                                                 
  52. //CNTL     EXEC GGLOAD,TRK1='5',TO='CNTL'                                       
  53. //SYSIN    DD DATA,DLM='?!'                                                     
  54. ./   ADD NAME=$$README,SSI=01100022                                             
  55.                                                                                 
  56. ------------------------------------------------------------------------        
  57.                                                                                 
  58.  Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992, 1993            
  59.                                                                                 
  60.  MVS Gopher Server originally by Shawn Hart (Univ. of Delaware).                
  61.                                                                                 
  62.  This software is provided on an "AS IS" basis.  All warranties,                
  63.  including the implied warranties of merchantability and fitness,               
  64.  are expressly denied.                                                          
  65.                                                                                 
  66.  Provided this copyright notice is included, this software may                  
  67.  be freely distributed and not offered for sale.                                
  68.                                                                                 
  69.  Changes or modifications may be made and used only by the maker                
  70.  of same, and not further distributed.  Such modifications should               
  71.  be mailed to the author for consideration for addition to the                  
  72.  software and incorporation in subsequent releases.                             
  73.                                                                                 
  74. ------------------------------------------------------------------------        
  75.                                                                                 
  76.  MVS Gopher Client - Version 2 Release 1 - March 1993                           
  77.                                                                                 
  78.  Author:          Steve Bacher <seb1525@mvs.draper.com>                         
  79.                                                                                 
  80.  MVS Gopher Server                                                              
  81.                                                                                 
  82.  Author:          Shawn Hart   <shawn.hart@mvs.udel.edu>                        
  83.  Enhancements:    Steve Bacher <seb1525@mvs.draper.com>                         
  84.  Customizations:  Lou Joseph   <CWMY5C@IRISHMVS.CC.ND.EDU>                      
  85.                                                                                 
  86. ------------------------------------------------------------------------        
  87.                                                                                 
  88.  Contents of PDS's belonging to Gopher distribution:                            
  89.                                                                                 
  90.  Member     PDS Type    Description                                             
  91.                                                                                 
  92.  $$README   CNTL        This file                                               
  93.  ACCESS     CNTL        Sample server access file                               
  94.  ALLOAD     CNTL        JCL to allocate GOPHER load library                     
  95.  COMPILEC   CNTL        JCL to compile and link C source for client             
  96.  COMPILES   CNTL        JCL to compile and link C source for server             
  97.  GOPHERD    CNTL        JCL to run the GOPHER server in batch (No TSO)          
  98.  GOPHERT    CNTL        JCL to run the GOPHER server in batch (w. TSO)          
  99.  HELP       CNTL        TSO Help for Gopher client (with XPROC support)         
  100.  HELQ       CNTL        TSO Help for Gopher client (without XPROC)              
  101.  INSTALLC   CNTL        How to install the GOPHER MVS client                    
  102.  INSTALLS   CNTL        How to install the GOPHER MVS server                    
  103.  MENU       CNTL        Initial Gopher server menu                              
  104.  PARMS      CNTL        Sample Gopher startup parameters                        
  105.  GOPHER     CLIST       Exec by which users invoke the Gopher client            
  106.  NNMFIUCV   CLIST       Exec to check for multiple socket applications          
  107.  HOSTNAME   CLIST       Sample "hostname" command for REXX feature              
  108.  TSOHELP    CLIST       Sample REXX exec for Gopher TSO HELP menu hole          
  109.  GGM...     PANEL       ISPF regular panels                                     
  110.  GG...      H           C headers for compilation                               
  111.  GG...      C           C source for compilation                                
  112.  ABOUT...   ABOUT       "About This Gopher" text                                
  113.                                                                                 
  114. --------------------------------------------------------------------            
  115.                                                                                 
  116. Where to Go from Here:                                                          
  117.                                                                                 
  118.  To install the GOPHER MVS client, read member INSTALLC.                        
  119.                                                                                 
  120.  To install the GOPHER MVS server, read member INSTALLS.                        
  121.                                                                                 
  122. Note:                                                                           
  123.                                                                                 
  124.  You may install only the client, only the server, or both the                  
  125.  client and the server.  It is purely up to what your needs are.                
  126.                                                                                 
  127. --------------------------------------------------------------------            
  128.                                                                                 
  129. Changes:                                                                        
  130.                                                                                 
  131.  10/19/92 - Improvements in initial startup and GOPHERRC customization          
  132.  12/07/92 - Customizations to support SNS/TCPAccess                             
  133.  03/20/93 - Version 2:  Improved browse function                                
  134.                         Printing support                                        
  135.                         Bookmark support                                        
  136.                         New commands: PRT, INFO, MENU, BOOKMARK                 
  137.                         Configurable startup parameter file                     
  138.                         Ability to run multiple servers on same MVS             
  139.                                                                                 
  140. --------------------------------------------------------------------            
  141.                                                                                 
  142.  Questions?  Comments?  Suggestions?  Gripes?  Please email to...               
  143.                                                                                 
  144.  Steve Bacher      <seb@draper.com> or <seb1525@mvs.draper.com>                 
  145.                                                                                 
  146. ./   ADD NAME=ACCESS,SSI=01020059                                               
  147. !                                                                               
  148. ! Format of entries:                                                            
  149. !                                                                               
  150. ! filename (fully qualified, all uppercase, no quotes)                          
  151. ! can be "DD:DDNAME" or "EXEC:EXECNAME"                                         
  152. !                                                                               
  153. ! followed by names of hosts which are authorized to access the data.           
  154. ! If no host name list is present, all hosts are authorized                     
  155. !                                                                               
  156. ! You may specify the same file name more than once, if you need                
  157. ! more lines to put host names on.                                              
  158. !                                                                               
  159. ! Individual PDS members must be specified separately.  A PDS without           
  160. ! a member name establishes access only to the PDS directory.                   
  161. !                                                                               
  162. ! Note that the default directory MUST be in this table.                        
  163. !                                                                               
  164. ! Also note that in the case of EXECs, the EXEC must live in the                
  165. ! library allocated to GGEXEC in the Gopher server JCL.                         
  166. !                                                                               
  167. ! *** ANY DATA SET REFERENCED BY ANY EXEC IN THAT LIBRARY IS FULLY              
  168. ! *** ACCESSIBLE TO GOPHER REGARDLESS OF THIS TABLE!  USE THIS TABLE            
  169. ! *** TO GOVERN CONTROL TO THE EXEC ITSELF!!!                                   
  170.                                                                                 
  171. !                                                                               
  172. ! below is default directory spec, which MUST be in this table                  
  173. !                                                                               
  174. DD:GGGOPHER                                                                     
  175.                                                                                 
  176. !                                                                               
  177. ! Use the following for "About This Gopher".                                    
  178. ! (Change the PDS name to match your installation.)                             
  179. ! Free free to specify the name of your MVS client host(s)                      
  180. ! for information pertinent to MVS only.  mvs1 and mvs2 are examples.           
  181. !                                                                               
  182. DD:GGABOUT                                                                      
  183. GOPHER.ABOUT(ABOUT)                                                             
  184. GOPHER.ABOUT(ABOUTC)                              mvs1 mvs2                     
  185. GOPHER.ABOUT(ABOUTCD)                             mvs1 mvs2                     
  186. GOPHER.ABOUT(ABOUTCF)                             mvs1 mvs2                     
  187. GOPHER.ABOUT(ABOUTCO)                             mvs1 mvs2                     
  188. GOPHER.ABOUT(ABOUTCQ)                             mvs1 mvs2                     
  189. GOPHER.ABOUT(ABOUTCS)                             mvs1 mvs2                     
  190. GOPHER.ABOUT(ABOUTCSC)                            mvs1 mvs2                     
  191. GOPHER.ABOUT(ABOUTCSL)                            mvs1 mvs2                     
  192. GOPHER.ABOUT(ABOUTCSM)                            mvs1 mvs2                     
  193. GOPHER.ABOUT(ABOUTCSR)                            mvs1 mvs2                     
  194. GOPHER.ABOUT(ABOUTCSW)                            mvs1 mvs2                     
  195. GOPHER.ABOUT(ABOUTCSX)                            mvs1 mvs2                     
  196. GOPHER.ABOUT(ABOUTCX)                             mvs1 mvs2                     
  197. GOPHER.ABOUT(ABOUTS)                              mvs1 mvs2                     
  198. GOPHER.ABOUT(ABOUTSA)                             mvs1 mvs2                     
  199. GOPHER.ABOUT(ABOUTW)                                                            
  200. GOPHER.ABOUT(FAQ)                                                               
  201.                                                                                 
  202. !                                                                               
  203. ! Here's how to do REXX execs.  Note - no arguments, only exec names            
  204. !                                                                               
  205. EXEC:CHECKLST                     client1 client2 mvs                           
  206. EXEC:WAISDIR                                                                    
  207. EXEC:WAISLIST                                                                   
  208. EXEC:WAISSRCH                                                                   
  209.                                                                                 
  210. ANY.PUBLIC.SEQ.DS                                                               
  211. ANY.SEMI.PUBLIC.SEQ.DS            goodclient1 goodclient2                       
  212. ANY.SEMI.PUBLIC.SEQ.DS            goodclient3 goodclient4                       
  213.                                                                                 
  214. ! PDS without member name provides access to directory only                     
  215. ! All member names must be explicitly listed to be accessible.                  
  216.                                                                                 
  217. ANY.PUBLIC.PDS                                                                  
  218. ANY.PUBLIC.PDS(MEMBER1)                                                         
  219. ANY.PUBLIC.PDS(MEMBER2)                                                         
  220. ANY.PUBLIC.PDS(MEMBER3)                                                         
  221. ANY.PUBLIC.PDS(MEMBER4)                                                         
  222.                                                                                 
  223.                                                                                 
  224. ANY.SEMI.PUBLIC.PDS               goodclient1 goodclient2                       
  225. ANY.SEMI.PUBLIC.PDS               goodclient3 goodclient4                       
  226. ANY.SEMI.PUBLIC.PDS(MEMBER1)      goodclient1                                   
  227. ANY.SEMI.PUBLIC.PDS(MEMBER2)      goodclient2                                   
  228. ANY.SEMI.PUBLIC.PDS(MEMBER3)      goodclient3                                   
  229. ANY.SEMI.PUBLIC.PDS(MEMBER4)      goodclient4                                   
  230.                                                                                 
  231. ./   ADD NAME=ALLOAD,SSI=01010051                                               
  232. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  233. //*                                                                  */         
  234. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  235. //*                                                                  */         
  236. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  237. //* including the implied warranties of merchantability and fitness, */         
  238. //* are expressly denied.                                            */         
  239. //*                                                                  */         
  240. //* Provided this copyright notice is included, this software may    */         
  241. //* be freely distributed and not offered for sale.                  */         
  242. //*                                                                  */         
  243. //* Changes or modifications may be made and used only by the maker  */         
  244. //* of same, and not further distributed.  Such modifications should */         
  245. //* be mailed to the author for consideration for addition to the    */         
  246. //* software and incorporation in subsequent releases.               */         
  247. //*                                                                  */         
  248. //*                                                                             
  249. //* Allocate GOPHER load library before install                                 
  250. //*                                                                             
  251. //GGALLOC PROC BS='6233',U='3380',V='',                                         
  252. //             PRI='100',SEC='100',DIR='35'                                     
  253. //*                                                                             
  254. //IEFBR14  EXEC PGM=IEFBR14                                                     
  255. //ALLOCDD  DD   DISP=(NEW,CATLG,DELETE),DSN=&LIB,                               
  256. //         DCB=(RECFM=U,BLKSIZE=&BS),                                           
  257. //         SPACE=(&BS,(&PRI,&SEC,&DIR)),UNIT=&U,VOL=SER=&V                      
  258. //*                                                                             
  259. //         PEND                                                                 
  260. //*                                                                             
  261. //* The following step allocates the load library from which the                
  262. //* executable program will be run.  If you intend to place the                 
  263. //* executable into an existing library, you can skip this step.                
  264. //* Otherwise, the name must match the name used on the LOADLIB                 
  265. //* parameter of the GGLINK procedure in the COMPILE JCL.                       
  266. //*                                                                             
  267. //* If you want separate libraries for the client and the server,               
  268. //* just dup this step and give 'em different lib names.                        
  269. //*                                                                             
  270. //ALLOC1   EXEC GGALLOC,PRI=50,SEC=50,DIR=35,                                   
  271. //         LIB='GOPHER.LOAD'                                                    
  272. //*                                                                             
  273. ./   ADD NAME=COMPILEC                                                          
  274. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  275. //*                                                                  */         
  276. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  277. //*                                                                  */         
  278. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  279. //* including the implied warranties of merchantability and fitness, */         
  280. //* are expressly denied.                                            */         
  281. //*                                                                  */         
  282. //* Provided this copyright notice is included, this software may    */         
  283. //* be freely distributed and not offered for sale.                  */         
  284. //*                                                                  */         
  285. //* Changes or modifications may be made and used only by the maker  */         
  286. //* of same, and not further distributed.  Such modifications should */         
  287. //* be mailed to the author for consideration for addition to the    */         
  288. //* software and incorporation in subsequent releases.               */         
  289. //*                                                                  */         
  290. //*********************************************************************         
  291. //*                                                                             
  292. //* Compile some or all GOPHER C/370 sources to make the SYSLIN input           
  293. //* to the linkedit of the executable Gopher load module(s).                    
  294. //*                                                                             
  295. //GGCC   PROC MEMBER=,                                                          
  296. //            SRCLIB='GOPHER.C',                 GOPHER C source PDS            
  297. //            HDRLIB='GOPHER.H',                 GOPHER C headers PDS           
  298. //            COMMHDR='TCPIP.COMMMAC',           C/370 TCP/IP headers           
  299. //            C370HDR='SYS1.EDCHDRS',            C/370 standard headers         
  300. //            SYSMSGS='SYS1.EDCMSGS',            C/370 messages file            
  301. //            SYSMSGM='EDCMSGE',                 C/370 message member           
  302. //            VIOUNIT=VIO,                       Temporary disk unit            
  303. //            OUTCLAS='*',                          SYSOUT class                
  304. //            CPARMS='SOURCE EXPMAC NOAGGR NOXREF', Compile parameters          
  305. //            TEST=TEST                             TEST or NOTEST              
  306. //*                                                                             
  307. //CCOMP     EXEC PGM=EDCCOMP,PARM='MARGINS(1,72) &TEST &CPARMS'                 
  308. //SYSMSGS   DD DISP=SHR,DSN=&SYSMSGS(&SYSMSGM)                                  
  309. //SYSIN     DD DISP=SHR,DSN=&SRCLIB(&MEMBER)                                    
  310. //SYSLIB    DD DISP=SHR,DSN=&COMMHDR                                            
  311. //          DD DISP=SHR,DSN=&C370HDR                                            
  312. //USERLIB   DD DISP=SHR,DSN=&HDRLIB                                             
  313. //SYSLIN    DD DSN=&&LOADSET,UNIT=&VIOUNIT,DISP=(MOD,PASS),                     
  314. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  315. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  316. //SYSCPRT   DD SYSOUT=&OUTCLAS                                                  
  317. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  318. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  319. //SYSUT4    DD DSN=&&SYSUT4,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  320. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  321. //SYSUT6    DD DSN=&&SYSUT6,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  322. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  323. //SYSUT7    DD DSN=&&SYSUT7,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  324. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  325. //SYSUT8    DD DSN=&&SYSUT8,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  326. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  327. //SYSUT9    DD DSN=&&SYSUT9,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  328. //   SPACE=(32000,(30,30)),DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)                 
  329. //SYSUT10   DD SYSOUT=&OUTCLAS                                                  
  330. //*                                                                             
  331. //         PEND                                                                 
  332. //*                                                                             
  333. //*********************************************************************         
  334. //*                                                                             
  335. //* Linkedit an executable Gopher load module.                                  
  336. //*                                                                             
  337. //* Note: If C/370 V1R2 or higher, and you have therefore accepted              
  338. //*       the "#define FETCH" in the GG header, you may delete                  
  339. //*       the line that includes the ISPLINK library.                           
  340. //*                                                                             
  341. //* Note: If TCP/IP V2 or higher, remove the PASCAL link libraries              
  342. //*       from the JCL and the AMPZMVSB card from the control deck.             
  343. //*                                                                             
  344. //GGLINK PROC LOADLIB='GOPHER.LOAD',             Executable load library        
  345. //            PLIBASE='SYS1.PLIBASE',            PL/1   link library            
  346. //            EDCBASE='SYS1.SEDCBASE',           C/370  link library            
  347. //            IBMBASE='SYS1.SIBMBASE',           PL/1+C common library          
  348. //            COMMTXT='TCPIP.COMMTXT',           TCP/IP link library            
  349. //            PASRUN3='SYS1.PAS.SAMPRUN3',       PASCAL link library            
  350. //            PASRUN1='SYS1.PAS.SAMPRUN1',       PASCAL link library            
  351. //            PASMSG1='SYS1.PAS.SAMPMSG1',       PASCAL link library            
  352. //            ISPLINK='ISP.V3R2M0.ISPLLIB',      ISPLINK link library           
  353. //            VIOUNIT=VIO,                       Temporary disk unit            
  354. //            OUTCLAS='*',                          SYSOUT class                
  355. //            LPARMS='LIST,LET,MAP',                Linkedit parameters         
  356. //            TEST=TEST                             TEST or NOTEST              
  357. //*                                                                             
  358. //LKED      EXEC PGM=IEWL,PARM='AMODE(31),&TEST,&LPARMS'                        
  359. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  360. //SYSLIB    DD DISP=SHR,DSN=&PLIBASE                                            
  361. //          DD DISP=SHR,DSN=&EDCBASE                                            
  362. //          DD DISP=SHR,DSN=&IBMBASE                                            
  363. //          DD DISP=SHR,DSN=&COMMTXT                                            
  364. //          DD DISP=SHR,DSN=&PASRUN3  if TCP/IP V1 only                         
  365. //          DD DISP=SHR,DSN=&PASRUN1  if TCP/IP V1 only                         
  366. //          DD DISP=SHR,DSN=&PASMSG1  if TCP/IP V1 only                         
  367. //          DD DISP=SHR,DSN=&ISPLINK  if C/370 V1R1 with #undef FETCH           
  368. //SYSLMOD   DD DISP=SHR,DSN=&LOADLIB                                            
  369. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  370. //          SPACE=(32000,(30,30))                                               
  371. //*                                                                             
  372. //         PEND                                                                 
  373. //*                                                                             
  374. //GGCLIENT EXEC GGCC,MEMBER=GGCLIENT                                            
  375. //GGMALLOC EXEC GGCC,MEMBER=GGMALLOC                                            
  376. //GGMCLRTX EXEC GGCC,MEMBER=GGMCLRTX                                            
  377. //GGMCONN  EXEC GGCC,MEMBER=GGMCONN                                             
  378. //GGMCSO   EXEC GGCC,MEMBER=GGMCSO                                              
  379. //GGMDBM   EXEC GGCC,MEMBER=GGMDBM                                              
  380. //GGMDFAIL EXEC GGCC,MEMBER=GGMDFAIL                                            
  381. //GGMDIR   EXEC GGCC,MEMBER=GGMDIR                                              
  382. //GGMDISC  EXEC GGCC,MEMBER=GGMDISC                                             
  383. //GGMDISPL EXEC GGCC,MEMBER=GGMDISPL                                            
  384. //GGMDUMP  EXEC GGCC,MEMBER=GGMDUMP                                             
  385. //GGMESRVR EXEC GGCC,MEMBER=GGMESRVR                                            
  386. //GGMFREEM EXEC GGCC,MEMBER=GGMFREEM                                            
  387. //GGMGETDS EXEC GGCC,MEMBER=GGMGETDS                                            
  388. //GGMGETM  EXEC GGCC,MEMBER=GGMGETM                                             
  389. //GGMGOFOR EXEC GGCC,MEMBER=GGMGOFOR                                            
  390. //GGMGSRVL EXEC GGCC,MEMBER=GGMGSRVL                                            
  391. //GGMIERR  EXEC GGCC,MEMBER=GGMIERR                                             
  392. //GGMIGET  EXEC GGCC,MEMBER=GGMIGET                                             
  393. //GGMINFO  EXEC GGCC,MEMBER=GGMINFO                                             
  394. //GGMISPF  EXEC GGCC,MEMBER=GGMISPF                                             
  395. //GGMIVGET EXEC GGCC,MEMBER=GGMIVGET                                            
  396. //GGMIVPUT EXEC GGCC,MEMBER=GGMIVPUT                                            
  397. //GGMMENU  EXEC GGCC,MEMBER=GGMMENU                                             
  398. //GGMMTFER EXEC GGCC,MEMBER=GGMMTFER                                            
  399. //GGMOUTS  EXEC GGCC,MEMBER=GGMOUTS                                             
  400. //GGMOUTTX EXEC GGCC,MEMBER=GGMOUTTX                                            
  401. //GGMPMSG  EXEC GGCC,MEMBER=GGMPMSG                                             
  402. //GGMPROC  EXEC GGCC,MEMBER=GGMPROC                                             
  403. //GGMSOCKT EXEC GGCC,MEMBER=GGMSOCKT                                            
  404. //GGMSOPT  EXEC GGCC,MEMBER=GGMSOPT                                             
  405. //GGMTNET  EXEC GGCC,MEMBER=GGMTNET                                             
  406. //GGMTSO   EXEC GGCC,MEMBER=GGMTSO                                              
  407. //GGMTYPE  EXEC GGCC,MEMBER=GGMTYPE                                             
  408. //GGMUNALC EXEC GGCC,MEMBER=GGMUNALC                                            
  409. //GGMVIEW  EXEC GGCC,MEMBER=GGMVIEW                                             
  410. //GGMVTX   EXEC GGCC,MEMBER=GGMVTX                                              
  411. //GGMWAIS  EXEC GGCC,MEMBER=GGMWAIS                                             
  412. //GGMWHOIS EXEC GGCC,MEMBER=GGMWHOIS                                            
  413. //GGMXTX   EXEC GGCC,MEMBER=GGMXTX                                              
  414. //*                                                                             
  415. //* Link GOPHER load module. Like SMP/E, expect return code 8 when              
  416. //* doing this from scratch.  Additional one-or-two-module links                
  417. //* will just replace the corresponding parts of the load module.               
  418. //*                                                                             
  419. //GGLINK EXEC GGLINK                                                            
  420. //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET                                
  421. //            DD *                                                              
  422.  INCLUDE SYSLMOD(GGCLIENT)            if included first time, RC = 8            
  423.  INCLUDE SYSLIB(AMPZMVSB)             include if TCP/IP V1 only                 
  424.  ENTRY   CEESTART                                                               
  425.  NAME    GGCLIENT(R)                                                            
  426. /*                                                                              
  427. ./   ADD NAME=COMPILES,SSI=01060050                                             
  428. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  429. //*                                                                  */         
  430. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  431. //*                                                                  */         
  432. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  433. //* including the implied warranties of merchantability and fitness, */         
  434. //* are expressly denied.                                            */         
  435. //*                                                                  */         
  436. //* Provided this copyright notice is included, this software may    */         
  437. //* be freely distributed and not offered for sale.                  */         
  438. //*                                                                  */         
  439. //* Changes or modifications may be made and used only by the maker  */         
  440. //* of same, and not further distributed.  Such modifications should */         
  441. //* be mailed to the author for consideration for addition to the    */         
  442. //* software and incorporation in subsequent releases.               */         
  443. //*                                                                  */         
  444. //*********************************************************************         
  445. //*                                                                             
  446. //* Compile some or all GOPHER C/370 sources to make the SYSLIN input           
  447. //* to the linkedit of the executable Gopher load module.                       
  448. //*                                                                             
  449. //GGCC   PROC MEMBER=,                                                          
  450. //            SRCLIB='GOPHER.C',                 GOPHER C source PDS            
  451. //            HDRLIB='GOPHER.H',                 GOPHER C headers PDS           
  452. //            COMMHDR='TCPIP.COMMMAC',           C/370 TCP/IP headers           
  453. //            C370HDR='SYS1.EDCHDRS',            C/370 standard headers         
  454. //            SYSMSGS='SYS1.EDCMSGS',            C/370 messages file            
  455. //            SYSMSGM='EDCMSGE',                 C/370 message member           
  456. //            VIOUNIT=VIO,                       Temporary disk unit            
  457. //            OUTCLAS='*',                          SYSOUT class                
  458. //            CPARMS='SOURCE EXPMAC NOAGGR NOXREF', Compile parameters          
  459. //            TEST=TEST                             TEST or NOTEST              
  460. //*                                                                             
  461. //CCOMP     EXEC PGM=EDCCOMP,PARM='MARGINS(1,72) &TEST &CPARMS'                 
  462. //SYSMSGS   DD DISP=SHR,DSN=&SYSMSGS(&SYSMSGM)                                  
  463. //SYSIN     DD DISP=SHR,DSN=&SRCLIB(&MEMBER)                                    
  464. //SYSLIB    DD DISP=SHR,DSN=&COMMHDR                                            
  465. //          DD DISP=SHR,DSN=&C370HDR                                            
  466. //USERLIB   DD DISP=SHR,DSN=&HDRLIB                                             
  467. //SYSLIN    DD DSN=&&LOADSET,UNIT=&VIOUNIT,DISP=(MOD,PASS),                     
  468. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  469. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  470. //SYSCPRT   DD SYSOUT=&OUTCLAS                                                  
  471. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  472. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  473. //SYSUT4    DD DSN=&&SYSUT4,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  474. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  475. //SYSUT6    DD DSN=&&SYSUT6,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  476. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  477. //SYSUT7    DD DSN=&&SYSUT7,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  478. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  479. //SYSUT8    DD DSN=&&SYSUT8,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  480. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  481. //SYSUT9    DD DSN=&&SYSUT9,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  482. //   SPACE=(32000,(30,30)),DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)                 
  483. //SYSUT10   DD SYSOUT=&OUTCLAS                                                  
  484. //*                                                                             
  485. //         PEND                                                                 
  486. //*                                                                             
  487. //*********************************************************************         
  488. //*                                                                             
  489. //* Linkedit the executable Gopher load modules.                                
  490. //*                                                                             
  491. //* Note: If TCP/IP V2 or higher, remove the PASCAL link libraries              
  492. //*       from the JCL and the AMPZMVSB card from the control deck.             
  493. //*                                                                             
  494. //GGLINK PROC LOADLIB='GOPHER.LOAD',             Executable load library        
  495. //            EDCBASE='SYS1.SEDCBASE',           C/370  link library            
  496. //            IBMBASE='SYS1.SIBMBASE',           PL/1+C common library          
  497. //            COMMTXT='TCPIP.COMMTXT',           TCP/IP link library            
  498. //            PASRUN3='SYS1.PAS.SAMPRUN3',       PASCAL link library            
  499. //            PASRUN1='SYS1.PAS.SAMPRUN1',       PASCAL link library            
  500. //            PASMSG1='SYS1.PAS.SAMPMSG1',       PASCAL link library            
  501. //            IKJLINK='SYS1.LINKLIB',            IKJEFF18 link library          
  502. //            VIOUNIT=VIO,                       Temporary disk unit            
  503. //            OUTCLAS='*',                          SYSOUT class                
  504. //            LPARMS='LIST,LET,MAP',                Linkedit parameters         
  505. //            TEST=TEST                             TEST or NOTEST              
  506. //*                                                                             
  507. //LKED      EXEC PGM=IEWL,PARM='AMODE(31),&TEST,&LPARMS'                        
  508. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  509. //SYSLIB    DD DISP=SHR,DSN=&EDCBASE                                            
  510. //          DD DISP=SHR,DSN=&IBMBASE                                            
  511. //          DD DISP=SHR,DSN=&COMMTXT                                            
  512. //          DD DISP=SHR,DSN=&PASRUN3  if TCP/IP V1 only                         
  513. //          DD DISP=SHR,DSN=&PASRUN1  if TCP/IP V1 only                         
  514. //          DD DISP=SHR,DSN=&PASMSG1  if TCP/IP V1 only                         
  515. //          DD DISP=SHR,DSN=&IKJLINK  if C/370 V1R1 with #undef FETCH           
  516. //SYSLMOD   DD DISP=SHR,DSN=&LOADLIB                                            
  517. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  518. //          SPACE=(32000,(30,30))                                               
  519. //*                                                                             
  520. //         PEND                                                                 
  521. //*                                                                             
  522. //GGMALLOC EXEC GGCC,MEMBER=GGMALLOC                                            
  523. //GGMDFAIL EXEC GGCC,MEMBER=GGMDFAIL                                            
  524. //GGMUNALC EXEC GGCC,MEMBER=GGMUNALC                                            
  525. //GGMOUTS  EXEC GGCC,MEMBER=GGMOUTS                                             
  526. //GGMPROC  EXEC GGCC,MEMBER=GGMPROC                                             
  527. //GGSTASK  EXEC GGCC,MEMBER=GGSTASK                                             
  528. //*                                                                             
  529. //* Link GOPHER subtask module.  Like SMP/E, expect return code 8               
  530. //* doing this from scratch.  Additional one-or-two-module links                
  531. //* will just replace the corresponding parts of the load module.               
  532. //*                                                                             
  533. //* If recompiling the entire load module, you may want to delete               
  534. //* the previous one from the SYSLMOD library first, or remove the              
  535. //* INCLUDE SYSLMOD card from the JCL below.                                    
  536. //*                                                                             
  537. //GGLINKT EXEC GGLINK                                                           
  538. //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET                                
  539. //            DD *                                                              
  540.  INCLUDE SYSLMOD(GGSTASK)             if included first time, RC = 8            
  541.  INCLUDE SYSLIB(AMPZMVSB)             include if TCP/IP V1 only                 
  542.  INCLUDE SYSLIB(IUCVFORC)                                                       
  543.  INCLUDE SYSLIB(EDCMTFS)                                                        
  544.  ENTRY   CEESTART                                                               
  545.  NAME    GGSTASK(R)                                                             
  546. /*                                                                              
  547. //GGMMTFER EXEC GGCC,MEMBER=GGMMTFER                                            
  548. //GGSERVER EXEC GGCC,MEMBER=GGSERVER                                            
  549. //*                                                                             
  550. //* Link GOPHER server module.  Like SMP/E, expect return code 8                
  551. //* doing this from scratch.  Additional one-or-two-module links                
  552. //* will just replace the corresponding parts of the load module.               
  553. //*                                                                             
  554. //* If recompiling the entire load module, you may want to delete               
  555. //* the previous one from the SYSLMOD library first, or remove the              
  556. //* INCLUDE SYSLMOD card from the JCL below.                                    
  557. //*                                                                             
  558. //GGLINKS EXEC GGLINK                                                           
  559. //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET                                
  560. //            DD *                                                              
  561.  INCLUDE SYSLMOD(GGSERVER)            if included first time, RC = 8            
  562.  INCLUDE SYSLIB(AMPZMVSB)             include if TCP/IP V1 only                 
  563.  ENTRY   CEESTART                                                               
  564.  NAME    GGSERVER(R)                                                            
  565. /*                                                                              
  566. ./   ADD NAME=GOPHERD,SSI=01070018                                              
  567. //GOPHERD  PROC MODULE=GGSERVER,                                        00010000
  568. //         STEPLIB='GOPHER.LOAD',                                       00020000
  569. //         EXECLIB='GOPHER.EXEC',                                       00030000
  570. //         ACCESS='GOPHER.ACCESS',                                      00040000
  571. //         ABOUT='GOPHER.ABOUT',                                        00050000
  572. //         MENU='GOPHER.MENU',                                          00050000
  573. //         PARMS='GOPHER.PARMS',                                                
  574. //         VIO=SYSVIO,                                                          
  575. //         STDERR='*',                                                          
  576. //         STDOUT='*',                                                          
  577. //         GPARM=                                                       00050000
  578. //*                                                                     00060000
  579. //********************************************************************* 00070000
  580. //*                                                                   * 00080000
  581. //* GOPHER daemon, by Shawn Hart (U.Del.) and Steve Bacher (D.Lab.)   * 00090000
  582. //*                                                                   * 00100000
  583. //* Straight batch (no TSO access)                                    * 00100000
  584. //*                                                                   * 00100000
  585. //********************************************************************* 00110000
  586. //*                                                                     00120000
  587. //GOPHERD  EXEC PGM=&MODULE,PARM='&GPARM'                               00150001
  588. //STEPLIB  DD   DISP=SHR,DSN=&STEPLIB                                   00170000
  589. //GGEXEC   DD   DISP=SHR,DSN=&EXECLIB                                   00181002
  590. //SYSTSPRT DD   UNIT=&VIO,SPACE=(TRK,(100,100)),RECFM=VBA,LRECL=255             
  591. //SYSERR   DD   SYSOUT=&STDERR                                                  
  592. //SYSPRINT DD   SYSOUT=&STDOUT                                                  
  593. //SYSTSIN  DD   DUMMY                                                   00210000
  594. //SYSIN    DD   DUMMY                                                   00210000
  595. //GGDEBUG  DD   SYSOUT=*                                                00230000
  596. //GGABOUT  DD   DISP=SHR,DSN=&ABOUT                                     00230000
  597. //GGACCESS DD   DISP=SHR,DSN=&ACCESS                                    00240000
  598. //GGGOPHER DD   DISP=SHR,DSN=&MENU                                      00250000
  599. //GGPARMS  DD   DISP=SHR,DSN=&PARMS                                             
  600. ./   ADD NAME=GOPHERT,SSI=01050012                                              
  601. //GOPHERD  PROC MODULE=GGSERVER,                                        00010000
  602. //         STEPLIB='GOPHER.LOAD',                                       00020000
  603. //         EXECLIB='GOPHER.EXEC',                                       00030000
  604. //         ACCESS='GOPHER.ACCESS',                                      00040000
  605. //         ABOUT='GOPHER.ABOUT',                                        00050000
  606. //         MENU='GOPHER.MENU',                                          00050000
  607. //         PARMS='GOPHER.PARMS',                                                
  608. //         VIO=SYSVIO,                                                          
  609. //         STDERR='*',                                                          
  610. //         STDOUT='*',                                                          
  611. //         GPARM=                                                       00050000
  612. //*                                                                     00060000
  613. //********************************************************************* 00070000
  614. //*                                                                   * 00080000
  615. //* GOPHER daemon, by Shawn Hart (U.Del.) and Steve Bacher (D.Lab.)   * 00090000
  616. //*                                                                   * 00100000
  617. //********************************************************************* 00110000
  618. //*                                                                     00120000
  619. //GOPHERD  EXEC PGM=IKJEFT01,DYNAMNBR=128,REGION=8M,                    00150001
  620. //         PARM='&MODULE &GPARM'                                        00160000
  621. //STEPLIB  DD   DISP=SHR,DSN=&STEPLIB                                   00170000
  622. //GGEXEC   DD   DISP=SHR,DSN=&EXECLIB                                   00181002
  623. //SYSTSPRT DD   UNIT=&VIO,SPACE=(TRK,(100,100)),RECFM=VBA,LRECL=255             
  624. //SYSERR   DD   SYSOUT=&STDERR                                                  
  625. //SYSPRINT DD   SYSOUT=&STDOUT                                                  
  626. //SYSTSIN  DD   DUMMY                                                   00220000
  627. //SYSIN    DD   DUMMY                                                   00230000
  628. //GGDEBUG  DD   SYSOUT=*                                                00230000
  629. //GGABOUT  DD   DISP=SHR,DSN=&ABOUT                                     00230000
  630. //GGACCESS DD   DISP=SHR,DSN=&ACCESS                                    00240000
  631. //GGGOPHER DD   DISP=SHR,DSN=&MENU                                      00250000
  632. //GGPARMS  DD   DISP=SHR,DSN=&PARMS                                             
  633. ./   ADD NAME=HELP,SSI=01010013                                                 
  634. )F Function -                                                                   
  635.                                                                                 
  636.  GOPHER is a distributed document delivery service, or, more generally,         
  637.  a networked information retrieval service.  It allows you to access            
  638.  numerous types of data on various hosts in a transparent fashion.              
  639.  GOPHER presents you with a hierarchical display of information sources         
  640.  which are accessed via a client/server communications link.                    
  641.                                                                                 
  642.  There are GOPHER clients for all common hardware platforms.  The MVS           
  643.  version runs as an ISPF dialog application.                                    
  644.                                                                                 
  645.  When you use the GOPHER client, information about your use of GOPHER           
  646.  is stored in a data set called GOPHERRC.  If you don't have one,               
  647.  GOPHER will create it for you.                                                 
  648.                                                                                 
  649.  You can save Gopher information in bookmark files.  See the                    
  650.  help for operand BOOKMARK for details.                                         
  651.                                                                                 
  652.  For more information on customizing your GOPHER environment, get               
  653.  into Gopher and select "About This GOPHER".                                    
  654.                                                                                 
  655. )I GOPHLOC          - local GOPHER help goes in member GOPHLOC                  
  656.                                                                                 
  657. )X Syntax -                                                                     
  658.                                                                                 
  659.    %GOPHER                                                                      
  660.               LOCAL                                                             
  661.               BOOKMARK(datasetname)                                             
  662.               SERVER(hostname)                                                  
  663.               PATH(pathname)                                                    
  664.               PORT(portnumber)                                                  
  665.               DESCRIPTION(text)                                                 
  666.               FORCE                                                             
  667.               DEBUG                                                             
  668.               TEST                                                              
  669.                                                                                 
  670.    Required:  none                                                              
  671.                                                                                 
  672. )O Operands -                                                                   
  673.                                                                                 
  674. ))LOCAL                                                                         
  675.                                                                                 
  676.               Specify LOCAL if you want to enter GOPHER in "serverless"         
  677.               mode - i.e. start up with your private GOPHER menu.               
  678.               Specifying LOCAL accomplishes two things:                         
  679.                                                                                 
  680.                (1) It sets the server to "-", meaning local access.             
  681.                    Therefore, you must also provide a path, either              
  682.                    via the PATH operand or via a "localmenu:" spec              
  683.                    in your GOPHERRC file.                                       
  684.                                                                                 
  685.                (2) It allows you to use GOPHER even if there are                
  686.                    other TCP/IP socket applications active elsewhere            
  687.                    in your TSO session.  However, it will not allow             
  688.                    you to connect to any GOPHER servers, even if you            
  689.                    have a local menu item that points to one.                   
  690.                                                                                 
  691.               For information on how to set up GOPHER menus, get into           
  692.               GOPHER and select "About This Gopher".                            
  693.                                                                                 
  694. ))BOOKMARK(datasetname)                                                         
  695.                                                                                 
  696.               The name of a data set containing Gopher bookmarks,               
  697.               using normal TSO data set naming conventions.                     
  698.                                                                                 
  699.               You can create bookmarks in GOPHER by using the "B"               
  700.               selection code next to a menu item, or by using the               
  701.               BOOKMARK command while browsing an entry.  GOPHER will            
  702.               append an entry for the selected item to the end of               
  703.               the data set that you specify when asked.                         
  704.                                                                                 
  705.               To access this bookmark in a Gopher session, you can use          
  706.               the MENU command from any Gopher menu display, or you can         
  707.               start Gopher with a specific bookmark file.                       
  708.                                                                                 
  709. ))SERVER(hostname)                                                              
  710.                                                                                 
  711.               The host name (or IP address) of a Gopher server.                 
  712.               If this is not given, GOPHER looks in your GOPHERRC               
  713.               to find what server to connect to.  If it can't find              
  714.               an appropriate specification, you will have to enter              
  715.               a server name on the startup panel.                               
  716.                                                                                 
  717.               A server name of a single minus sign (-) is a special             
  718.               case, signifying local (serverless) access to your                
  719.               own private GOPHER data.  In this case, you must tell             
  720.               GOPHER where your menu is, either via the PATH operand            
  721.               or in the GOPHERRC file.                                          
  722.                                                                                 
  723. ))PATH(pathname)                                                                
  724.                                                                                 
  725.               The path name to be passed to the Gopher server, or               
  726.               used in local access as your initial menu.  Although              
  727.               the exact interpretation of the pathname string varies            
  728.               depending on the server, both the MVS server and the              
  729.               local GOPHER access feature interpret the pathname                
  730.               as the FULLY QUALIFIED WITHOUT QUOTES name of an MVS              
  731.               data set containing a gopher menu.  For information               
  732.               about the format of a gopher menu, see operand MENU.              
  733.                                                                                 
  734. ))PORT(portnumber)                                                              
  735.                                                                                 
  736.               You should never need to specify this field unless                
  737.               someone has set up a special kind of Gopher server that           
  738.               requires a unique port number.  In such a case, you               
  739.               would generally use this along with the SERVER operand.           
  740.                                                                                 
  741. ))DESCRIPTION(text)                                                             
  742.                                                                                 
  743.               A text string giving the heading to be displayed for              
  744.               the initial directory of Gopher goodies.  Normally                
  745.               either the Gopher server or the Gopher client will                
  746.               have a default value for this, or you can specify                 
  747.               a description of your liking in your GOPHERRC file.               
  748.               You can also use this to override the description                 
  749.               generated when you use the BOOKMARK operand to start up.          
  750.                                                                                 
  751. ))FORCE                                                                         
  752.                                                                                 
  753.               GOPHER tries to determine if there is a TCP/IP socket             
  754.               application active elsewhere in your TSO environment              
  755.               before starting up, to prevent TCP/IP errors.  If it              
  756.               tells you that there is another client active but in              
  757.               truth there is none and you know it, you can use the              
  758.               FORCE keyword to make GOPHER proceed whether it finds             
  759.               this to be the case or not.                                       
  760.                                                                                 
  761.               Using the LOCAL operand is one way to avoid this entire           
  762.               scenario.  However, that won't allow you to access any            
  763.               Gopher servers on the network.                                    
  764.                                                                                 
  765. ))DEBUG                                                                         
  766.                                                                                 
  767.               Set debugging mode on.  You must preallocate a file to            
  768.               ddname GGDEBUG for this to work.  This can be allocated           
  769.               to the terminal or a log file.  When debug mode is on,            
  770.               messages describing memory allocation and deallocation            
  771.               and GOPHER queries sent are dumped to the debug file.             
  772.                                                                                 
  773. ))TEST                                                                          
  774.                                                                                 
  775.               Activate C/370 interactive test (INSPECT).  GOPHER must           
  776.               have been compiled with the TEST option for this to be            
  777.               effective.  Note that you can also issue the TEST command         
  778.               inside GOPHER to get to INSPECT, again provided that              
  779.               GOPHER was compiled with the TEST option.                         
  780.                                                                                 
  781. ./   ADD NAME=HELQ,SSI=01000025                                                 
  782. )F Function -                                                                   
  783.                                                                                 
  784.  GOPHER is a distributed document delivery service, or, more generally,         
  785.  a networked information retrieval service.  It allows you to access            
  786.  numerous types of data on various hosts in a transparent fashion.              
  787.  GOPHER presents you with a hierarchical display of information sources         
  788.  which are accessed via a client/server communications link.                    
  789.                                                                                 
  790.  There are GOPHER clients for all common hardware platforms.  The MVS           
  791.  version runs as an ISPF dialog application.                                    
  792.                                                                                 
  793.  When you use the GOPHER client, information about your use of GOPHER           
  794.  is stored in a data set called GOPHERRC.  If you don't have one,               
  795.  GOPHER will create it for you.                                                 
  796.                                                                                 
  797.  For more information on customizing your GOPHER environment, get               
  798.  into Gopher and select "About This GOPHER".                                    
  799.                                                                                 
  800. )I GOPHLOC          - local GOPHER help goes in member GOPHLOC                  
  801.                                                                                 
  802. )X Syntax -                                                                     
  803.                                                                                 
  804.    %GOPHER                                                                      
  805.               LOCAL                                                             
  806.               FORCE                                                             
  807.               DEBUG                                                             
  808.               TEST                                                              
  809.                                                                                 
  810.    Required:  none                                                              
  811.                                                                                 
  812. )O Operands -                                                                   
  813.                                                                                 
  814. ))LOCAL                                                                         
  815.                                                                                 
  816.               Specify LOCAL if you want to enter GOPHER in "serverless"         
  817.               mode - i.e. start up with your private GOPHER menu.               
  818.               Specifying LOCAL accomplishes two things:                         
  819.                                                                                 
  820.                (1) It sets the server to "-", meaning local access.             
  821.                    Therefore, you must also provide a path via a                
  822.                    "localmenu:" spec in your GOPHERRC file.                     
  823.                                                                                 
  824.                (2) It allows you to use GOPHER even if there are                
  825.                    other TCP/IP socket applications active elsewhere            
  826.                    in your TSO session.  However, it will not allow             
  827.                    you to connect to any GOPHER servers, even if you            
  828.                    have a local menu item that points to one.                   
  829.                                                                                 
  830.               For information on how to set up GOPHER menus, get into           
  831.               GOPHER and select "About This Gopher".                            
  832.                                                                                 
  833. ))FORCE                                                                         
  834.                                                                                 
  835.               GOPHER tries to determine if there is a TCP/IP socket             
  836.               application active elsewhere in your TSO environment              
  837.               before starting up, to prevent TCP/IP errors.  If it              
  838.               tells you that there is another client active but in              
  839.               truth there is none and you know it, you can use the              
  840.               FORCE keyword to make GOPHER proceed whether it finds             
  841.               this to be the case or not.                                       
  842.                                                                                 
  843.               Using the LOCAL operand is one way to avoid this entire           
  844.               scenario.  However, that won't allow you to access any            
  845.               Gopher servers on the network.                                    
  846.                                                                                 
  847. ))DEBUG                                                                         
  848.                                                                                 
  849.               Set debugging mode on.  You must preallocate a file to            
  850.               ddname GGDEBUG for this to work.  This can be allocated           
  851.               to the terminal or a log file.  When debug mode is on,            
  852.               messages describing memory allocation and deallocation            
  853.               and GOPHER queries sent are dumped to the debug file.             
  854.                                                                                 
  855. ))TEST                                                                          
  856.                                                                                 
  857.               Activate C/370 interactive test (INSPECT).  GOPHER must           
  858.               have been compiled with the TEST option for this to be            
  859.               effective.  Note that you can also issue the TEST command         
  860.               inside GOPHER to get to INSPECT, again provided that              
  861.               GOPHER was compiled with the TEST option.                         
  862.                                                                                 
  863. ./   ADD NAME=INSTALLC,SSI=01070035                                             
  864.                                                                                 
  865.  Directions for Installing the GOPHER MVS Client                                
  866.                                                                                 
  867.  Assuming the PDS's have been created:                                          
  868.                                                                                 
  869.  1. Customize the ALLOAD and COMPILEC JCL members to reflect your               
  870.  local conventions.  Note:  If you intend to place the executable into          
  871.  an existing library, you can suppress that part of the ALLOAD JCL.             
  872.  The name of the data set created must match across both members.               
  873.                                                                                 
  874.  2. Customize the GGUSER header file as shown by the comments therein.          
  875.  Note in particular the defines for your TCP/IP and your C compiler.            
  876.  There are changes to the linkedit JCL that are related to these.               
  877.                                                                                 
  878.  3.  Customize the GOPHER exec to define the names of the MVS libraries         
  879.  to contain the panel and load library members.  The load library must          
  880.  be the one specified in the ALLOAD JCL, if you are creating it anew.           
  881.  Observe the comments relating to the use of LIBDEF and ISPF APPLIDs.           
  882.                                                                                 
  883.  It is in the GOPHER exec that you will also customize the name of the          
  884.  default Gopher server.  Note that the user's GOPHERRC file gets built          
  885.  from the contents of this exec.                                                
  886.                                                                                 
  887.  Note that if you install one of the REXX execs, you must also install          
  888.  the NNMFIUCV exec in the same library.  This exec implements a rude            
  889.  check for an existing TCP/IP socket application (e.g. another GOPHER)          
  890.  in a different PIE MultiTSO session.  It prevents your users from              
  891.  crashing TCP/IP, so it is highly recommended that you make use of it.          
  892.                                                                                 
  893.  4. If you are running ISPF Version 2 or earlier, edit the GOPHER panels        
  894.  whose names begin "GGMP...".  These are popups, and will not work              
  895.  under ISPF Version 2 unless you change the )BODY line.  Remove the             
  896.  WINDOW(...) parameter from the )BODY line of each panel so that the            
  897.  line just says )BODY or )BODY EXPAND(``), as the case may be.                  
  898.                                                                                 
  899.  Now, to install:                                                               
  900.                                                                                 
  901.  5. Submit the ALLOAD JCL to allocate the load library from which the           
  902.  executable program will be run.  If you intend to place the executable         
  903.  into an existing library, you can skip this step, but you should make          
  904.  sure that there is no previous load module named GGCLIENT in the load          
  905.  library of your choice before you proceed.                                     
  906.                                                                                 
  907.  6. Submit the COMPILEC JCL to compile all the C sources and create             
  908.  the executable Gopher load module.                                             
  909.                                                                                 
  910.  The first time you run this you can expect a return code of 8 from             
  911.  the linkedit.  Like SMP/E, this is OK if the only reason is an IEW0342         
  912.  because the "INCLUDE SYSLMOD(GGCLIENT)" did not find an existing load          
  913.  module.  If you get IEW0132 (unresolved external reference) or                 
  914.  IEW0241 (ESD type definition conflict), your linkedit went awry.               
  915.  Don't use the resultant load module.  Check the libraries you                  
  916.  specified on the link step to see what went wrong.                             
  917.                                                                                 
  918.  In the future, if you have to recompile individual modules, you can use        
  919.  the same JCL to compile only those modules, and the link will include          
  920.  the new modules in the existing executable load module.                        
  921.                                                                                 
  922.  *********************************************************************          
  923.                                                                                 
  924.  IMPORTANT:  If you are running TCP/IP V2R2 or higher on MVS, you must          
  925.  change the following library names in the compile and link JCL:                
  926.                                                                                 
  927.    TCPIP.COMMMAC   should be changed to  TCPIP.SEZACMAC                         
  928.    TCPIP.COMMTXT   should be changed to  TCPIP.SEZACMTX                         
  929.                                                                                 
  930.  If you are using SNS/TCPAccess, use these library names, or                    
  931.  whatever names are defined at your installation:                               
  932.                                                                                 
  933.    TCPIP.COMMMAC   should be changed to  SNSTCP.V110.H                          
  934.    TCPIP.COMMTXT   should be changed to  SNSTCP.V110.CILIB                      
  935.                                                                                 
  936.  *********************************************************************          
  937.                                                                                 
  938.  Note:  If you have defined C370V1 in the GGUSER header file, you must          
  939.  also include the system linklist load library or libraries containing          
  940.  ISPLINK, ISPEXEC and IKJEFF18 when linking.  Otherwise you may delete          
  941.  the lines from the linkedit JCL that reference them.                           
  942.                                                                                 
  943.  Note:  You need not include the PASCAL libraries or the AMPZMVSB               
  944.  module if you are using TCP/IP Version 2 or higher, in which case              
  945.  you must also define TCPIPV2 in the GGUSER headerfile.                         
  946.                                                                                 
  947.  7. Copy all the members of the panel PDS into the ISPF panel library           
  948.  specified in the GOPHER exec.                                                  
  949.                                                                                 
  950.  8. Copy one of the help members (HELP or HELQ) from the CNTL PDS into          
  951.  your local TSO HELP library under the name GOPHER.  You may also               
  952.  create an additional HELP member called GOPHLOC containing                     
  953.  information local to your site, if you wish.                                   
  954.                                                                                 
  955.  Which CNTL member should you use?  If you don't have XPROC, use HELQ.          
  956.  If you do have XPROC, use HELP.  You will have to modify your GOPHER           
  957.  clist either way.  If you don't have XPROC, you should get it,                 
  958.  because you can specify more options on Gopher if you do.  You can             
  959.  get XPROC via USC's "MVS network server" code distribution service.            
  960.  For more information about this, send an email message to                      
  961.  SERVICE@MVSA.USC.EDU - or SERVICE@USCMVSA, which will normally give            
  962.  better results if you have a BITNET (NJE) return address.                      
  963.                                                                                 
  964.  9. Create the "About This Gopher" PDS from the ABOUT PDS.  This has            
  965.  all the text users should see when they select the "About This Gopher"         
  966.  item from the MVS client.  It also contains all the documentation you          
  967.  need about setting up the client and the server, as well as creating           
  968.  menus and REXX execs for use with MVS Gopher.  You may have already            
  969.  done this as part of the server install, but it should also be                 
  970.  available from the client in "local" (serverless) mode, so that is             
  971.  why I mention it here.                                                         
  972.                                                                                 
  973. --------------------------------------------------------------------            
  974.                                                                                 
  975.  Note:  Make sure that the C/370 run time library is available,                 
  976.  either in the system link list or in the ISPLLIB concatenation,                
  977.  before attempting to run GOPHER.                                               
  978.                                                                                 
  979.  If the C/370 runtime library is not in the link list or otherwise              
  980.  available to ISPF at execution time, you may arrange for it to be              
  981.  allocated via LIBDEF in the GOPHER exec (I haven't tried this).                
  982.                                                                                 
  983. ./   ADD NAME=INSTALLS,SSI=010B0042                                             
  984.                                                                                 
  985.  Directions for Installing the GOPHER MVS Server                                
  986.                                                                                 
  987.  Assuming the PDS's have been created:                                          
  988.                                                                                 
  989.  1. Customize the ALLOAD and COMPILES JCL members to reflect your               
  990.  local conventions.  Note:  If you intend to place the executable into          
  991.  an existing library, you can suppress that part of the ALLOAD JCL.             
  992.  The name of the data set created must match across both members.               
  993.                                                                                 
  994.  2. Customize the GGUSER header file as shown by the comments therein.          
  995.  Note in particular the defines for your TCP/IP and your C compiler.            
  996.  There are changes to the linkedit JCL that are related to these.               
  997.                                                                                 
  998.  Now, to install:                                                               
  999.                                                                                 
  1000.  3. Submit the ALLOAD JCL to allocate the load library from which the           
  1001.  executable program will be run.  If you intend to place the executable         
  1002.  into an existing library, you can skip this step, but you should make          
  1003.  sure that there is no previous load module named GGSERVER or GGSTASK           
  1004.  in the load library of your choice before you proceed.                         
  1005.                                                                                 
  1006.  4. Submit the COMPILES JCL to compile all the C sources and create             
  1007.  the executable Gopher load modules.                                            
  1008.                                                                                 
  1009.  The first time you run this you can expect return codes of 8 from              
  1010.  the linkedit.  Like SMP/E, this is OK if the only reason is an IEW0342         
  1011.  because the "INCLUDE SYSLMOD(...)" did not find an existing load               
  1012.  module.  If you get IEW0132 (unresolved external reference) or                 
  1013.  IEW0241 (ESD type definition conflict), your linkedit went awry.               
  1014.  Don't use the resultant load module.  Check the libraries you                  
  1015.  specified on the link step to see what went wrong.                             
  1016.                                                                                 
  1017.  In the future, if you have to recompile individual modules, you can use        
  1018.  the same JCL to compile only those modules, and the link will include          
  1019.  the new modules in the existing executable load module.                        
  1020.                                                                                 
  1021.  *********************************************************************          
  1022.                                                                                 
  1023.  IMPORTANT:  If you are running TCP/IP V2R2 or higher on MVS, you must          
  1024.  change the following library names in the compile and link JCL:                
  1025.                                                                                 
  1026.    TCPIP.COMMMAC   should be changed to  TCPIP.SEZACMAC                         
  1027.    TCPIP.COMMTXT   should be changed to  TCPIP.SEZACMTX                         
  1028.                                                                                 
  1029.  If you are using SNS/TCPAccess, use these library names, or                    
  1030.  whatever names are defined at your installation:                               
  1031.                                                                                 
  1032.    TCPIP.COMMMAC   should be changed to  SNSTCP.V110.H                          
  1033.    TCPIP.COMMTXT   should be changed to  SNSTCP.V110.CILIB                      
  1034.                                                                                 
  1035.  *********************************************************************          
  1036.                                                                                 
  1037.  Note:  If you have defined C370V1 in the GGUSER header file, you must          
  1038.  also include the system linklist load library containing IKJEFF18              
  1039.  when linking.  Otherwise you may delete the line from the linkedit             
  1040.  JCL that references it.                                                        
  1041.                                                                                 
  1042.  Note:  You need not include the PASCAL libraries or the AMPZMVSB               
  1043.  module if you are using TCP/IP Version 2 or higher, in which case              
  1044.  you must also define TCPIPV2 in the GGUSER headerfile.                         
  1045.                                                                                 
  1046.  5. Create the "About This Gopher" PDS from the ABOUT PDS.  This has            
  1047.  all the text users should see when they select the "About This Gopher"         
  1048.  item from the MVS client.  It also contains all the documentation you          
  1049.  need about setting up the client and the server, as well as creating           
  1050.  menus and REXX execs for use with MVS Gopher.  You may have already            
  1051.  done this as part of the client install.                                       
  1052.                                                                                 
  1053.  *** NOTE: In member MENU, you must change the line that reads                  
  1054.  "PATH=GOPHER.ABOUT.PDS(ABOUT)" to reflect the actual name of your              
  1055.  ABOUT PDS.  If you are using an earlier distribution of the MVS                
  1056.  Gopher server that has the line PATH=DD:GGABOUT(ABOUT), then you               
  1057.  must change that as well, because that won't work to get additional            
  1058.  PDS members as the user climbs down the Gopher tree.                           
  1059.                                                                                 
  1060.  6. Create your Gopher access file.  See the instructions in the                
  1061.  "About This Gopher" PDS for the format.                                        
  1062.                                                                                 
  1063.  7. Create your Gopher startup parameter file.  This is not required,           
  1064.  but may be used to change compiled-in defaults.  See the PARMS member          
  1065.  for a default.                                                                 
  1066.                                                                                 
  1067.  8. Allocate a PDS to hold Gopher REXX execs.  This is not required.            
  1068.  See the TSOHELP exec in the clist library of the distribution for a            
  1069.  sample application.                                                            
  1070.                                                                                 
  1071.  9. Create the MVS Gopher started task JCL from either of the samples           
  1072.  given in GOPHERD and GOPHERT.  The GOPHERT is recommended so that you          
  1073.  can use REXX execs that issue TSO commands, but you may not want to            
  1074.  use this for security reasons.  Either way, customize liberally.               
  1075.                                                                                 
  1076.  Started task parameters:                                                       
  1077.                                                                                 
  1078.  MODULE=GGSERVER            the Gopher server load module in STEPLIB            
  1079.  STEPLIB='GOPHER.LOAD'      the load library containing the above               
  1080.  EXECLIB='GOPHER.EXEC'      the PDS containing server REXX execs                
  1081.  ACCESS='GOPHER.ACCESS'     the installation access file (sequential)           
  1082.  ABOUT='GOPHER.ABOUT'       the PDS containing "About This Gopher" info         
  1083.  MENU='GOPHER.MENU'         the initial gopher menu (sequential)                
  1084.  PARMS='GOPHER.PARMS'       the server startup file (sequential)                
  1085.  GPARM=                     the server EXEC parms (e.g. -d for debug)           
  1086.                                                                                 
  1087.  Note: if you specify GPARM='-D', a GGDEBUG DD must be included.                
  1088.                                                                                 
  1089.  You are strongly recommended to create 2 started tasks:  one for               
  1090.  non-REXX requests with MTFTASKS set to 8, and one for REXX requests            
  1091.  with MTFTASKS set to 1 (because of TSO/E multitasking bugs).                   
  1092.  Give each a different port number in the GGPARMS configuration file            
  1093.  allocated to it.  See sample below.                                            
  1094.                                                                                 
  1095.  10. Add the name of the Gopher server started task (the name as it             
  1096.  appears in SYS1.PROCLIB, not necessarily "GOPHER") to the MVS TCPIP            
  1097.  profile data set (or have your MVS TCP/IP system programmer do it).            
  1098.  In the examples below, let's say you've called it GOPHSRV.  Add this           
  1099.  in 2 places:                                                                   
  1100.                                                                                 
  1101.    (a) under AUTOLOG, so that TCP/IP will start the Gopher server               
  1102.        automatically (a la inetd for unix) when a client connects.              
  1103.        Just add the name to the list (e.g. GOPHSRV).                            
  1104.                                                                                 
  1105.    (b) under PORT, so nobody can spoof the Gopher port.  The format             
  1106.        here is:   70 TCP GOPHSRV                                                
  1107.                                                                                 
  1108.  Repeat both for whatever number of Gopher server started tasks you             
  1109.  create (with different port numbers).                                          
  1110.                                                                                 
  1111. --------------------------------------------------------------------            
  1112.                                                                                 
  1113.  Note:  Make sure that the C/370 run time library is available,                 
  1114.  either in the system link list or in the STEPLIB concatenation,                
  1115.  before attempting to run GOPHER.                                               
  1116.                                                                                 
  1117. --------------------------------------------------------------------            
  1118.                                                                                 
  1119. Following is an example of how to define two Gopher servers.                    
  1120.                                                                                 
  1121. 'SYS1.PROCLIB(GOPHSRV)' - the primary gopher server (port 70)                   
  1122.                           will not run any REXX execs                           
  1123.                                                                                 
  1124. //GOPHERD  PROC MODULE=GGSERVER,                                                
  1125. //         STEPLIB='GOPHER.LOAD',                                               
  1126. //         ACCESS='GOPHER.ACCESS(ACCESS)',                                      
  1127. //         PARMS='GOPHER.ACCESS(PARMS)',                                        
  1128. //         MENU='GOPHER.ACCESS(MENU)',                                          
  1129. //         STDERR='*',                                                          
  1130. //         STDOUT='*',                                                          
  1131. //         GPARM=                                                               
  1132. //*                                                                             
  1133. //GOPHERD  EXEC PGM=&MODULE,PARM='&GPARM'                                       
  1134. //STEPLIB  DD   DISP=SHR,DSN=&STEPLIB                                           
  1135. //SYSERR   DD   SYSOUT=&STDERR                                                  
  1136. //SYSPRINT DD   SYSOUT=&STDOUT                                                  
  1137. //SYSIN    DD   DUMMY                                                           
  1138. //GGDEBUG  DD   SYSOUT=*                                                        
  1139. //GGACCESS DD   DISP=SHR,DSN=&ACCESS                                            
  1140. //GGPARMS  DD   DISP=SHR,DSN=&PARMS                                             
  1141. //GGGOPHER DD   DISP=SHR,DSN=&MENU                                              
  1142.                                                                                 
  1143. 'SYS1.PROCLIB(GOPHSRV2)' - the secondary gopher server (port 1570)              
  1144.                            will run REXX execs                                  
  1145.                                                                                 
  1146. //GOPHERD2 PROC MODULE=GGSERVER,                                                
  1147. //         STEPLIB='GOPHER.LOAD',                                               
  1148. //         EXECLIB='GOPHER.EXEC',                                               
  1149. //         ACCESS='GOPHER.ACCESS(ACCESS2)',                                     
  1150. //         PARMS='GOPHER.ACCESS(PARMS2)',                                       
  1151. //         MENU='GOPHER.ACCESS(MENU2)',                                         
  1152. //         VIO=VIO,                                                             
  1153. //         STDERR='*',                                                          
  1154. //         STDOUT='*',                                                          
  1155. //         GPARM=                                                               
  1156. //*                                                                             
  1157. //GOPHERD2 EXEC PGM=IKJEFT01,DYNAMNBR=128, PARM='&MODULE &GPARM'                
  1158. //STEPLIB  DD   DISP=SHR,DSN=&STEPLIB                                           
  1159. //SYSEXEC  DD   DISP=SHR,DSN=&EXECLIB  /* needed for %-invoked execs */         
  1160. //GGEXEC   DD   DISP=SHR,DSN=&EXECLIB                                           
  1161. //SYSTSPRT DD   UNIT=&VIO,SPACE=(TRK,(100,100)),RECFM=VBA,LRECL=255             
  1162. //SYSERR   DD   SYSOUT=&STDERR                                                  
  1163. //SYSPRINT DD   SYSOUT=&STDOUT                                                  
  1164. //SYSTSIN  DD   DUMMY                                                           
  1165. //SYSIN    DD   DUMMY                                                           
  1166. //GGDEBUG  DD   SYSOUT=*                                                        
  1167. //GGACCESS DD   DISP=SHR,DSN=&ACCESS                                            
  1168. //GGPARMS  DD   DISP=SHR,DSN=&PARMS                                             
  1169. //GGGOPHER DD   DISP=SHR,DSN=&MENU                                              
  1170.                                                                                 
  1171. 'GOPHER.ACCESS(PARMS)' - startup parameters used by the primary server          
  1172.                                                                                 
  1173. mtftasks  8    (this is the default)                                            
  1174. port      70   (this is the default too)                                        
  1175.                                                                                 
  1176. 'GOPHER.ACCESS(PARMS2)'- startup parameters used by the secondary server        
  1177.                                                                                 
  1178. mtftasks  1       Force single threading to prevent TSO burpages                
  1179. port      1570    Must be different from primary server's port                  
  1180.                                                                                 
  1181. -----------------------------------------------------------------------         
  1182.                                                                                 
  1183. I have not included members ACCESS, ACCESS2, MENU and MENU2, but you            
  1184. will find samples elsewhere in this distribution.  ACCESS and ACCESS2           
  1185. can be the same, except that you don't need the REXX execs to be in             
  1186. ACCESS since ACCESS can't run REXX execs.  MENU and MENU2 should be             
  1187. the same, since you may want to configure various Gopher clients                
  1188. on other machines to try both MVS servers, but it's up to you.                  
  1189.                                                                                 
  1190. ./   ADD NAME=MENU,SSI=01030021                                                 
  1191. gopher_menu                                                                     
  1192.                                                                                 
  1193. TYPE=FILE                                                                       
  1194. NAME=About This Gopher                                                          
  1195. PATH=GOPHER.ABOUT.PDS(ABOUT)                                                    
  1196. HOST=+                                                                          
  1197. END                                                                             
  1198.                                                                                 
  1199. TYPE=FILE                                                                       
  1200. NAME=TSO HELP (Sample Illustrating the REXX Interface)                          
  1201. PATH=EXEC:TSOHELP                                                               
  1202. HOST=+                                                                          
  1203. END                                                                             
  1204.                                                                                 
  1205. TYPE=DIRECTORY                                                                  
  1206. NAME=Library/Information Services                                               
  1207. PATH=SYS0008.GOPHER.LIBRARY(LIBRS)                                              
  1208. HOST=MVS.UDEL.EDU                                                               
  1209. END                                                                             
  1210.                                                                                 
  1211. TYPE=TELNET                                                                     
  1212. NAME=UDINFO - University of Delaware Information                                
  1213. HOST=UDINFO.UDEL.EDU                                                            
  1214. END                                                                             
  1215.                                                                                 
  1216. TYPE=DIRECTORY                                                                  
  1217. NAME=Network and System Services Computer Systems                               
  1218. PATH=SYS0008.GOPHER.DIR(UDTELNET)                                               
  1219. HOST=MVS.UDEL.EDU                                                               
  1220. END                                                                             
  1221.                                                                                 
  1222. TYPE=DIRECTORY                                                                  
  1223. NAME=Weather Across the Country                                                 
  1224. PATH=1/Weather                                                                  
  1225. HOST=mermaid.micro.umn.edu                                                      
  1226. PORT=150                                                                        
  1227. END                                                                             
  1228.                                                                                 
  1229. TYPE=DIRECTORY                                                                  
  1230. NAME=Other Gopher and Information Servers                                       
  1231. PATH=1/Other Gopher and Information Servers                                     
  1232. HOST=gopher.micro.umn.edu                                                       
  1233. END                                                                             
  1234.                                                                                 
  1235. TYPE=DIRECTORY                                                                  
  1236. NAME=How to use BITNET LISTSERV Servers                                         
  1237. PATH=SYS0008.GOPHER.DIR(LISTSERV)                                               
  1238. HOST=MVS.UDEL.EDU                                                               
  1239. END                                                                             
  1240.                                                                                 
  1241. TYPE=DIRECTORY                                                                  
  1242. NAME=University of Delaware Newspapers                                          
  1243. PATH=SYS0008.GOPHER.DIR(PAPERS)                                                 
  1244. HOST=MVS.UDEL.EDU                                                               
  1245. END                                                                             
  1246.                                                                                 
  1247. /*                                                                              
  1248. ./   ADD NAME=PARMS,SSI=01000028                                                
  1249. !                                                                               
  1250. ! MVS Gopher Sample Startup Parameter File                                      
  1251. !                                                                               
  1252. ! All entries in this file have the format:   variable value comments           
  1253. !                                                                               
  1254. ! These are the possible values and their default settings:                     
  1255. !                                                                               
  1256. ! mtftasks 1    Number of concurrent subtasks to handle client requests         
  1257. ! port     70   The TCP port number by which clients connect                    
  1258. ! qlength  20   Queue length for TCP server listen function                     
  1259. ! timeout  60   Connection timeout specified when socket is closed              
  1260. ! domain   .DRAPER.COM     The suffix to be appende to bald host names          
  1261.                                                                                 
  1262. mtftasks 1    Number of concurrent subtasks to handle client requests           
  1263. port     70   The TCP port number by which clients connect                      
  1264. qlength  20   Queue length for TCP subtask creation                             
  1265. timeout  60   Connection timeout specified when socket is closed                
  1266.                                                                                 
  1267. ./ ENDUP                                                                        
  1268. ?!                                                                              
  1269. //ABOUT    EXEC GGLOAD,TRK1='6',TO='ABOUT'                                      
  1270. //SYSIN    DD DATA,DLM='?!'                                                     
  1271. ./   ADD NAME=ABOUT,SSI=01040045                                                
  1272. gopher_menu                                                                     
  1273.                                                                                 
  1274. TYPE=FILE                                                                       
  1275. NAME=What Is Gopher?                                                            
  1276. PATH=(ABOUTW)                                                                   
  1277. HOST=+                                                                          
  1278. END                                                                             
  1279.                                                                                 
  1280. TYPE=FILE                                                                       
  1281. NAME=Gopher FAQ (Frequently Asked Questions) List                               
  1282. PATH=(FAQ)                                                                      
  1283. HOST=+                                                                          
  1284. END                                                                             
  1285.                                                                                 
  1286. TYPE=DIRECTORY                                                                  
  1287. NAME=Using The Gopher MVS Client                                                
  1288. PATH=(ABOUTC)                                                                   
  1289. HOST=+                                                                          
  1290. END                                                                             
  1291.                                                                                 
  1292. TYPE=DIRECTORY                                                                  
  1293. NAME=Administering the Gopher MVS Server                                        
  1294. PATH=(ABOUTS)                                                                   
  1295. HOST=+                                                                          
  1296. END                                                                             
  1297.                                                                                 
  1298.                                                                                 
  1299. ./   ADD NAME=ABOUTC,SSI=01050028                                               
  1300. gopher_menu                                                                     
  1301.                                                                                 
  1302. TYPE=FILE                                                                       
  1303. NAME=Overview - Using Gopher on MVS                                             
  1304. PATH=(ABOUTCO)                                                                  
  1305. HOST=+                                                                          
  1306. END                                                                             
  1307.                                                                                 
  1308. TYPE=FILE                                                                       
  1309. NAME=Directory Mode - Viewing a Gopher Directory                                
  1310. PATH=(ABOUTCD)                                                                  
  1311. HOST=+                                                                          
  1312. END                                                                             
  1313.                                                                                 
  1314. TYPE=FILE                                                                       
  1315. NAME=File Mode - Browsing a Gopher File                                         
  1316. PATH=(ABOUTCF)                                                                  
  1317. HOST=+                                                                          
  1318. END                                                                             
  1319.                                                                                 
  1320. TYPE=FILE                                                                       
  1321. NAME=Index Mode - Executing a Gopher Query                                      
  1322. PATH=(ABOUTCQ)                                                                  
  1323. HOST=+                                                                          
  1324. END                                                                             
  1325.                                                                                 
  1326. TYPE=DIRECTORY                                                                  
  1327. NAME=Customizing Your Gopher Startup                                            
  1328. PATH=(ABOUTCS)                                                                  
  1329. HOST=+                                                                          
  1330. END                                                                             
  1331.                                                                                 
  1332.                                                                                 
  1333. ./   ADD NAME=ABOUTCD,SSI=01020022                                              
  1334. Directory Mode - Viewing a Gopher Directory                                     
  1335.                                                                                 
  1336. When you are viewing a Gopher directory, you may perform any of the             
  1337. following actions:                                                              
  1338.                                                                                 
  1339.  * Scroll up and down via the normal ISPF UP and DOWN commands or PFK's         
  1340.                                                                                 
  1341.  * Type one of the following letters to the left of a menu item:                
  1342.                                                                                 
  1343.    S - Select the item for viewing or processing                                
  1344.    E - Extract the contents of the item to a file                               
  1345.    P - Print the contents of the item to a system printer                       
  1346.    B - Save the entry as a bookmark (in a bookmark file)                        
  1347.    D - Delete this entry from the bookmark file *** not yet supported **        
  1348.    Q - Display the item as a file, even if it isn't ("Query")                   
  1349.    I - Display the internal Information of the menu item                        
  1350.                                                                                 
  1351.  * Enter one of the following commands on the command line:                     
  1352.                                                                                 
  1353.    MENU - load a data set containing Gopher menu entries (e.g. bookmark)        
  1354.    QUIT - exit Gopher entirely                                                  
  1355.                                                                                 
  1356.    or any standard ISPF command.                                                
  1357.                                                                                 
  1358. Note:  Currently, in order to use the E or P selection code, you must           
  1359.        choose the item via S or Q first.                                        
  1360.                                                                                 
  1361. When you select an item, what happens next depends on the type of the           
  1362. item you have selected.                                                         
  1363.                                                                                 
  1364. For a File type, you are placed in browse mode on the data.                     
  1365.                                                                                 
  1366. For a Directory type, you get another Gopher directory.                         
  1367.                                                                                 
  1368. For an Index type, you see a panel asking you to enter a search string          
  1369. of some kind, after which a Gopher directory of results appears.                
  1370.                                                                                 
  1371. For a TELNET type, a telnet session is started, for which you must              
  1372. enter a login name at the appropriate time.                                     
  1373.                                                                                 
  1374. For a TN3270 type, a tn3270 session is started, for which you must              
  1375. enter a login name at the appropriate time.                                     
  1376.                                                                                 
  1377. For a CSO type, you are placed in a phonebook lookup session.                   
  1378.                                                                                 
  1379. ./   ADD NAME=ABOUTCF,SSI=01020051                                              
  1380. Browse Mode - Viewing a File in Gopher                                          
  1381.                                                                                 
  1382. When you are viewing a Gopher file, you are placed in "browse mode".            
  1383. This is very similar to normal ISPF data set browse, except that:               
  1384.                                                                                 
  1385.  * In addition to most browse commands, you may issue any of the                
  1386.    following commands:                                                          
  1387.                                                                                 
  1388.    EXT or EXTRACT   - copy the current contents to a file                       
  1389.    PRT or PRNT      - print the current data to SYSOUT.                         
  1390.    BOOK or BOOKMARK - Save the entry as a bookmark (in a bookmark file).        
  1391.    INFO             - Display the internal Information for this item            
  1392.    QUIT - terminates Gopher entirely.                                           
  1393.                                                                                 
  1394.    Note that PRT is different from PRINT, which is a built-in ISPF              
  1395.    command that prints the current physical screen image.                       
  1396.                                                                                 
  1397.  * The following ISPF browse commands are the only ones that are                
  1398.    ***not*** supported under GOPHER:                                            
  1399.                                                                                 
  1400.   HEX                                                                           
  1401.   BROWSE                                                                        
  1402.   SUBMIT                                                                        
  1403.   LOCATE .label                                                                 
  1404.   .<string> (to assign a label)                                                 
  1405.   FIND P'generic-string'                                                        
  1406.   DISPLAY CC/NOCC                                                               
  1407.                                                                                 
  1408. ./   ADD NAME=ABOUTCO,SSI=01010039                                              
  1409. The following is modified from Allan Tuchman's XGOPHER help.                    
  1410.                                                                                 
  1411. Gopher on MVS is an ISPF dialog interface to the Gopher                         
  1412. information delivery system from the University of Minnesota.                   
  1413.                                                                                 
  1414. The initial panel asks you to specify the name of the Gopher server             
  1415. host.  Normally you leave the other input fields alone.                         
  1416.                                                                                 
  1417. You may also specify a hostname of "-", which means that you want               
  1418. to use your own private Gopher data without going through a server.             
  1419. When you do this, you must provide the path name to your private                
  1420. top-level menu (data set name, FULLY QUALIFIED, WITHOUT QUOTES).                
  1421.                                                                                 
  1422. Assuming that the top-level path points to a valid Gopher menu,                 
  1423. the initial display will show the top level directory of                        
  1424. gopher information available.  Selecting an item from this                      
  1425. list will fetch the contents of a file, subdirectory, or                        
  1426. other information.  The directory display may be updated to                     
  1427. show the new subdirectory.                                                      
  1428.                                                                                 
  1429. To select an item, type "S" in front of it and press ENTER.                     
  1430. This puts you into ISPF BROWSE mode on the text of the item.                    
  1431. You may also type "Q" in front of an item to see it in text format              
  1432. even if it is a directory.  If you have retrieved an item, you may              
  1433. type "E" in front of it to extract it into a file - but you may                 
  1434. do this more easily via the EXTract command from within BROWSE.                 
  1435.                                                                                 
  1436. Type "I" in front of the item to view the internal menu information.            
  1437. This is sometimes helpful if you are not sure why you are having                
  1438. trouble accessing an item.                                                      
  1439.                                                                                 
  1440. Type "B" in front of the item to save it in a bookmark file.  You will          
  1441. be prompted to supply the name of a bookmark data set; the default is           
  1442. GOPHER.BOOKMARK under your TSO prefix.  You may retrieve bookmarks at a         
  1443. later date by typing "MENU GOPHER.BOOKMARK" - or whatever data set name         
  1444. you used - or you can put a pointer to the bookmark data set in your            
  1445. private Gopher menu (for which you need to learn how to hack your               
  1446. GOPHERRC file).                                                                 
  1447.                                                                                 
  1448. Some gopher file types are not supported by the current client.                 
  1449. These will not appear on your menus.  Furthermore, you may not                  
  1450. be permitted to access some items, depending upon the server                    
  1451. and the host from which you are trying to access them.  These                   
  1452. restrictions do not apply to local mode, where you can access                   
  1453. anything that you have local permission to read.                                
  1454.                                                                                 
  1455. The Gopher MVS client is written by Steve Bacher at Draper Laboratory           
  1456. (copyright 1992).                                                               
  1457.                                                                                 
  1458. ./   ADD NAME=ABOUTCQ,SSI=01020042                                              
  1459. Index Mode - Executing a Gopher Query                                           
  1460.                                                                                 
  1461. When you select a Gopher "index" or "query" option, you are expected            
  1462. to enter some sort of search string.  A typical application is a                
  1463. phone book lookup, or a keyword search of some archive.                         
  1464.                                                                                 
  1465. You will see a popup panel (or just a plain panel if you are running            
  1466. an old version of ISPF) that asks you to enter a search string.  Just           
  1467. type it in and press ENTER.  What format the string needs to be in              
  1468. depends totally on the service that is going to process it.                     
  1469.                                                                                 
  1470. What you get back is a directory with a list of "hits" or whatever              
  1471. is appropriate for the data you requested.  This is just like any               
  1472. other Gopher directory.                                                         
  1473.                                                                                 
  1474. With the original Gopher protocol, there was no mechanism for                   
  1475. defining an index/query that returned file data immediately.                    
  1476. MVS Gopher supports an experimental "whois" type that does this.                
  1477. However, since it was only spottily implemented by other Gophers,               
  1478. and not always the right way (in the humble opinion of the author               
  1479. or the MVS client), it is not likely that you will see such an option           
  1480. on your Gopher screen.                                                          
  1481.                                                                                 
  1482. ./   ADD NAME=ABOUTCS,SSI=01030002                                              
  1483. gopher_menu                                                                     
  1484.                                                                                 
  1485. Type=FILE                                                                       
  1486. Name=Customizing Your Gopher Startup                                            
  1487. Path=(ABOUTCSC)                                                                 
  1488. Host=+                                                                          
  1489. End                                                                             
  1490.                                                                                 
  1491. Type=FILE                                                                       
  1492. Name=What Happens When You Start Up Gopher                                      
  1493. Path=(ABOUTCSW)                                                                 
  1494. Host=+                                                                          
  1495. End                                                                             
  1496.                                                                                 
  1497. Type=FILE                                                                       
  1498. Name=Requesting Local (Serverless) Access                                       
  1499. Path=(ABOUTCSL)                                                                 
  1500. Host=+                                                                          
  1501. End                                                                             
  1502.                                                                                 
  1503. Type=FILE                                                                       
  1504. Name=The GOPHERRC File                                                          
  1505. Path=(ABOUTCSR)                                                                 
  1506. Host=+                                                                          
  1507. End                                                                             
  1508.                                                                                 
  1509. Type=FILE                                                                       
  1510. Name=Defining GOPHER Menus                                                      
  1511. Path=(ABOUTCSM)                                                                 
  1512. Host=+                                                                          
  1513. End                                                                             
  1514.                                                                                 
  1515. Type=FILE                                                                       
  1516. Name=REXX Exec Interface                                                        
  1517. Path=(ABOUTCSX)                                                                 
  1518. Host=+                                                                          
  1519. End                                                                             
  1520.                                                                                 
  1521. ./   ADD NAME=ABOUTCSC,SSI=01030041                                             
  1522.                                                                                 
  1523. =======================================================================         
  1524.                                                                                 
  1525.  Customizing Your Gopher Startup                                                
  1526.                                                                                 
  1527. =======================================================================         
  1528.                                                                                 
  1529.  When you use the GOPHER client, information about your use of GOPHER           
  1530.  is stored in a data set called GOPHERRC.  If you don't have one,               
  1531.  GOPHER will create it for you.                                                 
  1532.                                                                                 
  1533.  Your default startup menu will contain a single item pointing to a             
  1534.  GOPHER server on your MVS system, whether such a server is available           
  1535.  or not.  However, you can ask GOPHER to display a different startup            
  1536.  menu for you.  This startup menu may have entries for the GOPHER               
  1537.  server on the MVS system and one for your own private (local) data,            
  1538.  which the GOPHER client accesses without querying a server.                    
  1539.                                                                                 
  1540.  To get GOPHER to set up a different startup menu, you must edit the            
  1541.  GOPHERRC file.  Note that you may set up the GOPHER startup menu to            
  1542.  include a pointer to your local data - but you have to create that             
  1543.  local data in order to use it.                                                 
  1544.                                                                                 
  1545.  Editing the GOPHERRC file should be easy.  Just follow the                     
  1546.  instructions in the comments of the file itself.  For information              
  1547.  about the contents of GOPHERRC, see "The GOPHERRC File."                       
  1548.                                                                                 
  1549. ./   ADD NAME=ABOUTCSL,SSI=01000056                                             
  1550.                                                                                 
  1551. =======================================================================         
  1552.                                                                                 
  1553.  Requesting Local (Serverless) Access                                           
  1554.                                                                                 
  1555. =======================================================================         
  1556.                                                                                 
  1557.  The LOCAL operand on the GOPHER command is a convenient way of                 
  1558.  requesting "local" serverless mode.  Specify LOCAL on the GOPHER               
  1559.  command if you want to enter GOPHER in "serverless" mode - i.e.                
  1560.  start up with your private GOPHER menu.  Specifying LOCAL                      
  1561.  accomplishes two things:                                                       
  1562.                                                                                 
  1563.   (1) It sets the server to "-", meaning local access.  Therefore, you          
  1564.       must also provide a path, either via the PATH operand on the              
  1565.       GOPHER command or via a "localmenu:" spec in your GOPHERRC file,          
  1566.       so that GOPHER knows where to look for your private data.  The            
  1567.       path is a data set name, FULLY QUALIFIED WITHOUT QUOTES.                  
  1568.                                                                                 
  1569.   (2) It allows you to use GOPHER even if there are other TCP/IP socket         
  1570.       applications active elsewhere in your TSO session.  However, it           
  1571.       will not allow you to connect to any GOPHER servers, even if you          
  1572.       have a local menu item that points to one.                                
  1573.                                                                                 
  1574.  If you do not specify a server and there is no specification in                
  1575.  your GOPHERRC file for one, then GOPHER will display a startup                 
  1576.  ISPF panel asking you to specify a server name and, optionally,                
  1577.  a path name.  (Don't touch the port number!)                                   
  1578. ./   ADD NAME=ABOUTCSM,SSI=01040003                                             
  1579.                                                                                 
  1580. =======================================================================         
  1581.                                                                                 
  1582.  Defining Gopher Menus                                                          
  1583.                                                                                 
  1584. =======================================================================         
  1585.                                                                                 
  1586.  This is a description of how to define GOPHER menus that can be used           
  1587.  either for your own private data or by the GOPHER server administrator         
  1588.  on MVS to define publicly accessible data.                                     
  1589.                                                                                 
  1590.  Bear in mind that the menu may be used to specify data meaningful to           
  1591.  a server other than MVS.  Therefore, the descriptions here should be           
  1592.  interpreted in two ways:                                                       
  1593.                                                                                 
  1594.  (1) how to define MVS-resident information resources                           
  1595.                                                                                 
  1596.  (2) how to request information resources from other GOPHER servers             
  1597.                                                                                 
  1598. ------------------------------------------------------------------------        
  1599.                                                                                 
  1600.  How To Define MVS-Resident Information Resources                               
  1601.                                                                                 
  1602.  The Gopher server (and the Gopher client, in "local" mode) determines          
  1603.  how to return information to the client via menus.  These menus are            
  1604.  plain MVS data sets with a particular structure.                               
  1605.                                                                                 
  1606.  An MVS gopher menu is a sequential data set or PDS member with the             
  1607.  following format:                                                              
  1608.                                                                                 
  1609.  * the first line contains the string GOPHER_MENU                               
  1610.    (in upper, lower or mixed case)                                              
  1611.                                                                                 
  1612.  * the rest of the file contains blocks of information like this:               
  1613.                                                                                 
  1614.    TYPE=type                                                                    
  1615.    NAME=name                                                                    
  1616.    PATH=path                                                                    
  1617.    HOST=host                                                                    
  1618.    PORT=port                                                                    
  1619.    END                                                                          
  1620.                                                                                 
  1621.    For compatibility with earlier versions of the MVS Gopher server,            
  1622.    the following are also accepted:                                             
  1623.                                                                                 
  1624.    DISPLAY=      is equivalent to NAME=                                         
  1625.    SELECTOR=     is equivalent to PATH=                                         
  1626.                                                                                 
  1627.    Explanations                                                                 
  1628.                                                                                 
  1629.    TYPE=type                                                                    
  1630.                                                                                 
  1631.    The type of Gopher entity (FILE, DIRECTORY, INDEX, etc.).                    
  1632.    In other words, one of the following:                                        
  1633.                                                                                 
  1634.    FILE      - the item is an MVS data set with text to be displayed.           
  1635.                The path name is the file name or a REXX exec spec.              
  1636.    DIRECTORY - the item is another Gopher directory.                            
  1637.                The path name is the file name or a REXX exec spec.              
  1638.    INDEX     - the item is a full text search item, which means that            
  1639.                the client will query the user for a search string               
  1640.                which will be passed to the server along with the                
  1641.                pathname.  For the MVS server.  it only makes sense for          
  1642.                the pathname to be a REXX exec specification.  The path          
  1643.                and the user's string are given to the host, which               
  1644.                returns a menu of selections.  See also WHOIS.                   
  1645.    TELNET    - the item is a Telnet server.                                     
  1646.                The path name is ignored.  The port number should be             
  1647.                omitted or set to 0, unless an alternate TELNET port             
  1648.                is required by the server referenced by HOST.                    
  1649.    TN3270    - the item is a TN3270 server.  This is like TELNET                
  1650.                except that it takes you to a full-screen IBM mainframe          
  1651.                terminal session.                                                
  1652.    CSO       - the item is a CSO phonebook server.  This is a campus            
  1653.                information protocol that is not an Internet standard,           
  1654.                but may be available at some universities.                       
  1655.    WHOIS     - the item is a "whois" query.  This is similar to the             
  1656.                INDEX type, except that the server returns a file                
  1657.                rather than a menu.  This is not (yet) an official               
  1658.                part of the Gopher protocol, though it does appear in            
  1659.                certain (patched) versions of other implementations.             
  1660.                                                                                 
  1661.    NAME=name                                                                    
  1662.                                                                                 
  1663.    The descriptive string that will appear in the Gopher client's               
  1664.    display of menu selections for this item.  Make this as human as             
  1665.    possible.  Case is preserved.                                                
  1666.                                                                                 
  1667.    PATH=path                                                                    
  1668.                                                                                 
  1669.    The pathname to be passed to the Gopher server to retrieve the               
  1670.    item.  See below for a fuller description.                                   
  1671.                                                                                 
  1672.    HOST=host                                                                    
  1673.                                                                                 
  1674.    The name of the Gopher server host that will process the request.            
  1675.    See below for a fuller description.                                          
  1676.                                                                                 
  1677.    PORT=port                                                                    
  1678.                                                                                 
  1679.    The TCP/IP port to connect to.  For Gopher, this should always be            
  1680.    port 70 (except for a TELNET or TN3270 type, whose port defaults to          
  1681.    the standard TELNET port if zero or omitted).  If this is omitted,           
  1682.    then the default port number is taken.                                       
  1683.                                                                                 
  1684.    END                                                                          
  1685.                                                                                 
  1686.    Required to keep menu entries separate.                                      
  1687.                                                                                 
  1688.  Comment lines may be freely included, starting with '#' in                     
  1689.  the first column of data.                                                      
  1690.                                                                                 
  1691. More about Path Names                                                           
  1692.                                                                                 
  1693.  Note that the format of a path depends on which Gopher server is               
  1694.  going to be processing the entry, as defined by the HOST= field.               
  1695.  If the entry is going to a different Gopher server, then the                   
  1696.  pathname format depends on that server.  For example, a Unix server            
  1697.  would expect a Unix file name with a slash.                                    
  1698.                                                                                 
  1699.  A path name for the MVS Gopher may be one of the following:                    
  1700.                                                                                 
  1701.  * A fully qualified MVS data set name, without quotes, identifying             
  1702.    a sequential text data set or PDS member.  If TYPE=FILE, this is             
  1703.    text.  If TYPE=DIRECTORY, this is a gopher menu as described above.          
  1704.                                                                                 
  1705.  * A fully qualified MVS data set name, without quotes, identifying a           
  1706.    PDS (no member).  This causes the MVS Gopher server to return a              
  1707.    list of member names of the PDS in Gopher directory format.  This            
  1708.    is valid only with TYPE=DIRECTORY.  Member aliases are included in           
  1709.    the resulting list.                                                          
  1710.                                                                                 
  1711.  * A member name enclosed in parentheses.  This is treated as                   
  1712.    a full PDS member.  In other words, the MVS Gopher server will use           
  1713.    the name of the PDS in which the menu itself was found.                      
  1714.    This allows you to move PDS's full of Gopher menus around without            
  1715.    having to worry about changing all the path names.  This happens             
  1716.    only when the menu itself is a PDS member and the host is the                
  1717.    same as the local host (MVS for the server, - for local mode).               
  1718.    Specifying HOST=+ is recommended for this.                                   
  1719.                                                                                 
  1720.  * A string "DD:ddname" or "DD:ddname(member)", identifying a file by           
  1721.    MVS ddname a la C/370.  Valid with either TYPE=FILE or                       
  1722.    TYPE=DIRECTORY, so the ddname can point to text or a menu.                   
  1723.    However, if the ddname happens to be allocated to a PDS, it does             
  1724.    NOT work like a directory above - it's just illegal and will                 
  1725.    probably cause lossage.                                                      
  1726.                                                                                 
  1727.    Each member is treated as a Gopher FILE.  The NAME field is                  
  1728.    set to the member name.  If you want to do anything fancier                  
  1729.    than this, you will have to construct your own Gopher menu.                  
  1730.                                                                                 
  1731.  * A string "EXEC:execname args", which specifies the name of a                 
  1732.    REXX exec to be executed to return the data.  Valid with any                 
  1733.    and all types.  To learn more about how to make use of this                  
  1734.    feature, please go back to the "About This Gopher" tree and                  
  1735.    read up on using REXX execs with MVS Gopher.                                 
  1736.                                                                                 
  1737.    If you are using your own private GOPHER data via local access               
  1738.    and you want to run REXX execs, you must have a "localexec:"                 
  1739.    line in your GOPHERRC file identifying your REXX exec library.               
  1740.                                                                                 
  1741. More About Host Names                                                           
  1742.                                                                                 
  1743.  You may find that some Gopher servers insist on appending the                  
  1744.  network's domain name to local server hostnames.  You should check             
  1745.  with your network gurus to make sure that this will work with your             
  1746.  TCP/IP host lookup.  The MVS server will accept hostnames either               
  1747.  with or without the domain name appended - this applies to the                 
  1748.  specification of hostnames in the Gopher access table as well -                
  1749.  but other Gopher servers may not.                                              
  1750.                                                                                 
  1751. Two special cases:                                                              
  1752.                                                                                 
  1753.  A plus sign (HOST=+) means that the host is the same host as the one           
  1754.  that is looking at the directory entry - i.e. the server that is               
  1755.  serving up this menu.  The Gopher server simply plugs in its own host          
  1756.  name at that point.  This is NOT part of the Gopher protocol, but              
  1757.  merely a server hack.                                                          
  1758.                                                                                 
  1759.  A minus sign (HOST=-) means that access to this item will be in                
  1760.  "local" (serverless) mode.  This is recognized only by the MVS Gopher          
  1761.  client.  It means that the client will do the retrieval itself,                
  1762.  without asking a server to do it.                                              
  1763.                                                                                 
  1764.  The directory-processing code, when invoked in "local mode", will              
  1765.  treat HOST=+ as HOST=- since the current host is the local mode                
  1766.  operation in that case.  Therefore, using HOST=+ is recommended                
  1767.  so that one can port one's local GOPHER menus to the public server             
  1768.  at some point.                                                                 
  1769.                                                                                 
  1770.  A REXX exec that generates menus dynamically can use - as a hostname,          
  1771.  but not +.                                                                     
  1772.                                                                                 
  1773. ------------------------------------------------------------------------        
  1774.                                                                                 
  1775.  How To Request Information Resources From Other GOPHER Servers                 
  1776.                                                                                 
  1777. Rather than describe the standard format of a Gopher menu here,                 
  1778. I recommend that you go to your nearest Unix box and type                       
  1779.                                                                                 
  1780.   man gopherd                                                                   
  1781.                                                                                 
  1782. That should tell you all you need to know about Unix gopher servers.            
  1783. If your gopher server is on some other kind of machine, then go find            
  1784. the documentation for that machine's Gopher menus.                              
  1785.                                                                                 
  1786. The purpose of the above exercise is primarily to determine the format          
  1787. of a path name understood by a given Gopher server.  Once you know that,        
  1788. you can build a Gopher menu the MVS Gopher will understand, according to        
  1789. the format described in the top section.  Set the host to point to              
  1790. the other Gopher server, who will interpret the other items in the menu.        
  1791.                                                                                 
  1792. ------------------------------------------------------------------------        
  1793.                                                                                 
  1794. Dynamic Generation of GOPHER Menus                                              
  1795.                                                                                 
  1796.  If you want to be able to generate a Gopher menu dynamically,                  
  1797.  you can do this via the REXX interface.  You also must understand              
  1798.  the Gopher protocol.  A Gopher menu is really a text representation            
  1799.  of the actual protocol, which goes like this:                                  
  1800.                                                                                 
  1801.  filetype -tab- name -tab- path -tab- host -tab- port                           
  1802.                                                                                 
  1803.  where -tab- is the EBCDIC (on MVS) or ASCII (on other box) tab                 
  1804.  character, and filetype is a single character.  The filetypes                  
  1805.  supported by the MVS Gopher server are:                                        
  1806.                                                                                 
  1807.  0 - flat file                                                                  
  1808.  1 - directory                                                                  
  1809.  2 - CSO                                                                        
  1810.  3 - error                                                                      
  1811.  7 - index                                                                      
  1812.  8 - TELNET                                                                     
  1813.  T - TN3270                                                                     
  1814.  w - whois (experimental)                                                       
  1815.                                                                                 
  1816.  A REXX exec that wants to generate a Gopher menu must output lines             
  1817.  in this format.  For more information, go back to the Gopher tree              
  1818.  for "About This Gopher" and look up information on the REXX interface.         
  1819.                                                                                 
  1820. ./   ADD NAME=ABOUTCSR,SSI=01020018                                             
  1821.                                                                                 
  1822. =======================================================================         
  1823.                                                                                 
  1824.  The GOPHERRC File                                                              
  1825.                                                                                 
  1826. =======================================================================         
  1827.                                                                                 
  1828.  When you use the GOPHER client, you need a file called GOPHERRC                
  1829.  which stores information about your use of GOPHER.  If you don't               
  1830.  have one, GOPHER will create it for you.  The file initially                   
  1831.  contains:                                                                      
  1832.                                                                                 
  1833.     the initial path/name/host/port specification, which tells                  
  1834.     GOPHER what to display on startup.  By default this is the                  
  1835.     standard GOPHER server info on MVS.  However, you can add                   
  1836.     to your GOPHERRC a specification for local GOPHER by                        
  1837.     editing GOPHERRC and activating one of the following:                       
  1838.                                                                                 
  1839.     - the other "initial:" spec which points to your own startup menu,          
  1840.       overriding the one you'd get otherwise                                    
  1841.                                                                                 
  1842.     - the localmenu: and localexec: lines.                                      
  1843.                                                                                 
  1844.     localmenu: is equivalent to specifying an alternate initial:                
  1845.     spec of host=- (dash) and path=localmenu_name.  When you use                
  1846.     the LOCAL operand of the GOPHER command, localmenu: is what                 
  1847.     GOPHER looks for as the pathname if you don't provide one on                
  1848.     the command.                                                                
  1849.                                                                                 
  1850.     localexec: is required if you want to use your own library of               
  1851.     GOPHER rexx execs.  This is valid for LOCAL access only.                    
  1852.                                                                                 
  1853.     Some option defaults are stored in the GOPHERRC file.                       
  1854.     Note that this is not yet implemented.                                      
  1855.                                                                                 
  1856.     Note that bookmarks are not stored in your GOPHERRC file.                   
  1857.     They are stored in separate bookmark data sets, whose names                 
  1858.     the client user must specify.  Do not attempt to load your                  
  1859.     GOPHERRC file as a bookmark file!                                           
  1860.                                                                                 
  1861.     If you have a newly created GOPHERRC file, you can read the                 
  1862.     comments to guide you in customizing the file.                              
  1863. ./   ADD NAME=ABOUTCSW,SSI=01000034                                             
  1864.                                                                                 
  1865. =======================================================================         
  1866.                                                                                 
  1867.  What Happens When You Start Up GOPHER?                                         
  1868.                                                                                 
  1869. =======================================================================         
  1870.                                                                                 
  1871.  What you see when you start up GOPHER depends on what you have                 
  1872.  specified, either on the command line or in the GOPHERRC file.                 
  1873.  In general, command operands override GOPHERRC specifications.                 
  1874.                                                                                 
  1875.  GOPHER does its thing by connecting to a Gopher server somewhere               
  1876.  on your network.  If you do not specify otherwise, this server is              
  1877.  assumed to be MVS (the host where you are running this client).                
  1878.  The default GOPHERRC file specifies this as the server.                        
  1879.  The startup menu you see is the one defined by the administrator               
  1880.  of that server.                                                                
  1881.                                                                                 
  1882.  You can request a different server or a different startup menu,                
  1883.  either by modifying the GOPHERRC file or by specifying command                 
  1884.  operands.  The SERVER operand tells GOPHER to get a startup menu               
  1885.  from a different server, and the PATH operand tells GOPHER what                
  1886.  startup menu to request (the contents of the path depend on what               
  1887.  server you point to and what it's looking for, but it is typically             
  1888.  the name of a file on that system that contains a Gopher menu).                
  1889.                                                                                 
  1890.  You can also use GOPHER to access your own private data by requesting          
  1891.  "local" (serverless) mode.  A server name of a single dash "-" means           
  1892.  local access.  In this case, you must provide a path name so that              
  1893.  GOPHER knows where to look for your data.  The path name is the name           
  1894.  of a data set containing your GOPHER menu - it must be FULLY QUALIFIED         
  1895.  AND WITHOUT QUOTES.  The path name can be provided either as a command         
  1896.  operand or in the GOPHERRC file.                                               
  1897. ./   ADD NAME=ABOUTCSX,SSI=01040036                                             
  1898. =======================================================================         
  1899.                                                                                 
  1900. REXX Exec Interface                                                             
  1901.                                                                                 
  1902. =======================================================================         
  1903.                                                                                 
  1904. You can request the MVS Gopher server (or the MVS Gopher client, in             
  1905. "local" (serverless) mode) to retrieve information dynamically by               
  1906. executing a REXX exec.  To request this, you define a menu entry                
  1907. with the following PATH= field:                                                 
  1908.                                                                                 
  1909. PATH=EXEC:execname args                                                         
  1910.                                                                                 
  1911. In the case of EXEC:, the REXX exec identified by "execname" is                 
  1912. executed, along with the arguments "args" given.  For example:                  
  1913.                                                                                 
  1914. PATH=EXEC:MYEXEC ANY ARGS                                                       
  1915.                                                                                 
  1916. will cause the MYEXEC exec to be executed with "ANY ARGS" as the                
  1917. single argument string.                                                         
  1918.                                                                                 
  1919. If the TYPE is INDEX, the search string submitted by the user will be           
  1920. appended to the args separated by a blank.  The exec must be able to            
  1921. deal with this.                                                                 
  1922.                                                                                 
  1923. REXX Execs must be in a PDS allocated to DD GGEXEC.  This ddname                
  1924. needs to be allocated in the Gopher server's JCL.  For local mode,              
  1925. the GOPHER command will allocate the GGEXEC file to the REXX exec               
  1926. library specified on the "localexec:" line in your GOPHERRC file,               
  1927. if you have activated it.  Otherwise you will not be able to use                
  1928. REXX execs in local mode.                                                       
  1929.                                                                                 
  1930. Note that you do not need the /* REXX */ comment at the beginning of            
  1931. REXX execs used by gopher (though it does not hurt to include it!)              
  1932. because they are invoked by the IRXEXEC facility and not the standard           
  1933. TSO CLIST/EXEC search.                                                          
  1934.                                                                                 
  1935. Now, how does the REXX exec return data to the Gopher server?                   
  1936.                                                                                 
  1937. First of all, it depends on the TYPE that the exec is expected                  
  1938. to return, which has nothing to do with HOW the returning is done.              
  1939.                                                                                 
  1940. So, first let's talk about how the exec returns data, and then                  
  1941. about what it is expected to return.                                            
  1942.                                                                                 
  1943. How to return data                                                              
  1944.                                                                                 
  1945. The REXX exec must return data by writing it to the SYSTSPRT DD.                
  1946. Note that this is where normal TSO output goes when a REXX exec                 
  1947. is run in TSO batch.  However, since REXX execs are invoked by                  
  1948. the IRXEXEC interface by the Gopher server, to prevent dependency               
  1949. on a TSO environment, this default behavior of REXX/TSO cannot                  
  1950. be relied upon.  Therefore, if you write a REXX exec to return                  
  1951. Gopher data, you must explicitly send the output to the SYSTSPRT                
  1952. ddname.  The Gopher server makes sure that it can read this data.               
  1953.                                                                                 
  1954. A typical approach is to queue all the output to the REXX data stack,           
  1955. queue a final "" and then use EXECIO.  Be careful not to queue null             
  1956. lines in this case.  Be sure to protect the stack in case of lossage.           
  1957. Example:                                                                        
  1958.                                                                                 
  1959.  "NEWSTACK"                                                                     
  1960.  do while more_data_to_get                                                      
  1961.   some_data = get_some_data()                                                   
  1962.   if some_data = "" then queue " "                                              
  1963.   else queue some_data                                                          
  1964.  end                                                                            
  1965.  queue ""                                                                       
  1966.  "EXECIO * DISKW SYSTSPRT (FINIS)"                                              
  1967.  "DELSTACK"                                                                     
  1968.                                                                                 
  1969. You can also create a stem variable to hold the output, if you                  
  1970. want to avoid problems with null lines or nested stacks.  Example:              
  1971.                                                                                 
  1972.  do i = 1 to whatever                                                           
  1973.    foo.i = get_some_data()                                                      
  1974.  end                                                                            
  1975.  foo.0 = i                                                                      
  1976.  "EXECIO * DISKW SYSTSPRT (FINIS STEM FOO.)"                                    
  1977.                                                                                 
  1978. A downside is that if the REXX exec finds anomalous conditions                  
  1979. or executes a TSO command that barfs, standard TSO command output               
  1980. will probably get lost.  Therefore, try to use OUTTRAP to capture               
  1981. command output and test for error codes, and write all captured                 
  1982. output or error messages to SYSTSPRT in such a way as to allow                  
  1983. the client to see them (but not treat them as normal directory                  
  1984. data or whatever).                                                              
  1985.                                                                                 
  1986. A helpful hack is to use an EXECUTE exec to invoke other REXX                   
  1987. code or TSO commands that normally output via PUTLINE.  e.g.:                   
  1988.                                                                                 
  1989. /* REXX. Usage: EXECUTE exec args... */                                         
  1990.                                                                                 
  1991.  parse arg real_exec_command                                                    
  1992.  parse source sourceline                                                        
  1993.  if word(sourceline,7) = "TSO" then do                                          
  1994.   x = outtrap("LINE.")                                                          
  1995.   real_exec_command                                                             
  1996.   arc = rc                                                                      
  1997.   x = outtrap("OFF")                                                            
  1998.   "EXECIO * DISKW SYSTSPRT (FINIS STEM LINE.)"                                  
  1999.  end                                                                            
  2000.  else do                                                                        
  2001.   real_exec_command                                                             
  2002.   arc = rc                                                                      
  2003.  end                                                                            
  2004.                                                                                 
  2005.  return arc                                                                     
  2006.                                                                                 
  2007. I don't recommend this, though, because it's SLOW.                              
  2008.                                                                                 
  2009.                                                                                 
  2010. If the Gopher server is a TSO-in-batch job (i.e. EXEC PGM=IKJEFT01)             
  2011. then you can issue TSO commands from the exec.  To get the output,              
  2012. though, you need to use OUTTRAP around them.  If they issue TPUT's,             
  2013. you are SOL.  If they are PL/1 programs that write to SYSPRINT, or              
  2014. FORTRAN or assembler, etc., allocate the SYSPRINT or FT06F001 or                
  2015. whatever file to a temporary and copy the temporary to SYSTSPRT.  If            
  2016. it is a C/370 program that writes to stdout or stderr, you may be able          
  2017. to use redirection:                                                             
  2018.                                                                                 
  2019.    CALL 'THEIR.LOAD(CPROG)' 'args > DD:SYSTSPRT'                                
  2020.                                                                                 
  2021.  for stdout                                                                     
  2022.                                                                                 
  2023.    CALL 'THEIR.LOAD(CPROG)' 'args 2> DD:SYSTSPRT'                               
  2024.                                                                                 
  2025.  for stderr                                                                     
  2026.                                                                                 
  2027.  (for multiple output, use >> instead of >)                                     
  2028.                                                                                 
  2029.  If gopher server is run straight batch rather than as a TSO job, then          
  2030.  you cannot run REXX execs that require a TSO environment.                      
  2031.                                                                                 
  2032.  One more important word:  Make sure that your SYSTSPRT file has a              
  2033.  large enough LRECL to handle the REXX output.  If it is too short,             
  2034.  the REXX output will get folded.  For TYPE=DIRECTORY in particular,            
  2035.  this is disastrous.  Recommended JCL for executing the Gopher server           
  2036.  may be found elsewhere in the installation materials, or your MVS              
  2037.  system programmer has probably already installed a Gopher server in            
  2038.  'SYS1.PROCLIB' or the equivalent with the correct allocation.                  
  2039.                                                                                 
  2040. What it is expected to return                                                   
  2041.                                                                                 
  2042.  OK - now the good stuff.  This depends on the TYPE on the menu entry           
  2043.  that your exec is trying to fulfill.  Some gopher protocol basics:             
  2044.                                                                                 
  2045.  A Gopher menu is really a text representation of the actual protocol,          
  2046.  which goes like this:                                                          
  2047.                                                                                 
  2048.  filetype -tab- name -tab- path -tab- host -tab- port                           
  2049.                                                                                 
  2050.  where -tab- is the EBCDIC (on MVS) or ASCII (on other box) tab                 
  2051.  character, and filetype is a single character.  The filetypes                  
  2052.  supported by the MVS Gopher server are:                                        
  2053.                                                                                 
  2054.  0 - flat file                                                                  
  2055.  1 - directory                                                                  
  2056.  2 - CSO                                                                        
  2057.  3 - error                                                                      
  2058.  7 - index                                                                      
  2059.  8 - TELNET                                                                     
  2060.  T - TN3270                                                                     
  2061.  w - whois (experimental)                                                       
  2062.                                                                                 
  2063.  To generate the equivalent of a Gopher menu, you must output data              
  2064.  in the above format.  Now for the details...                                   
  2065.                                                                                 
  2066. TYPE=FILE                                                                       
  2067.                                                                                 
  2068. Just return the straight data.  Try to avoid null lines because C/370           
  2069. believes they don't exist and will throw them away.  We hate this, but          
  2070. IBM is so hard to convince of reality sometimes...  Change all null             
  2071. lines to lines containing one blank as you write them out (you need to          
  2072. do this anyway if you are queueing output on the stack for EXECIO) and          
  2073. you will have no problems.                                                      
  2074.                                                                                 
  2075. TYPE=DIRECTORY                                                                  
  2076.                                                                                 
  2077. You must return lines that fit the gopher protocol format as above.             
  2078.                                                                                 
  2079. For example, if you want to generate a Gopher menu on the fly that              
  2080. is equivalent to this:                                                          
  2081.                                                                                 
  2082. type=file                                                                       
  2083. name=This is my description                                                     
  2084. path=some.gopher.path                                                           
  2085. host=sun1.sanjuan.com                                                           
  2086. port=70                                                                         
  2087.                                                                                 
  2088. then you output a line that looks like this:                                    
  2089.                                                                                 
  2090.   0This is my description!some.gopher.path!sun1.sanjuan.com!70                  
  2091.                                                                                 
  2092. (each ! is really a tab (EBCDIC hex 05) character)                              
  2093.                                                                                 
  2094. where "0" is the type (file in this example, but would be "1" for               
  2095. type=directory, "7" for typeindex, etc.)                                        
  2096.                                                                                 
  2097. Here's the REXX code that might do this:                                        
  2098.                                                                                 
  2099. name = "This is my description"                                                 
  2100. path = "some.gopher.path"                                                       
  2101. host = "sun1.sanjuan.com"                                                       
  2102. tab  = '05'x                                                                    
  2103. port = 70                                                                       
  2104.                                                                                 
  2105. queue "0"||name||tab||path||tab||host||tab||port                                
  2106.                                                                                 
  2107. Assuming we write the queued lines to DD SYSTSPRT, as described.                
  2108.                                                                                 
  2109. Specifying the Right Host Name                                                  
  2110.                                                                                 
  2111. Most of the time you will probably want to generate a menu item                 
  2112. that points back to your MVS host, not some other host.  It may                 
  2113. even redrive your selfsame REXX exec with new arguments.  And if                
  2114. the exec was invoked in local (serverless) mode, you want the item              
  2115. to get driven in the same mode, probably.                                       
  2116.                                                                                 
  2117. The question is - what's the easiest way to identify what                       
  2118. the "same server" is?  One way is to hardcode the server name (e.g.             
  2119. "MVS.DRAPER.COM"), but this is not sufficiently general because:                
  2120.                                                                                 
  2121. (1) the server name or location may change                                      
  2122. (2) you can't distribute the exec to other Gopher users                         
  2123. (3) it won't work the same way in "local mode"                                  
  2124.                                                                                 
  2125. So, you need a way to know what the name of your selfsame host is.              
  2126. The MVS Gopher server can use HOST=+, but you can't, as that isn't              
  2127. part of the Gopher protocol.  So what do you do?                                
  2128.                                                                                 
  2129. Recommendation:  call a function hostname() to return the current               
  2130. host name.  So in the above code segment, you might have:                       
  2131.                                                                                 
  2132.  host = hostname()                                                              
  2133.                                                                                 
  2134. What is that hostname() function anyway?                                        
  2135. Well, you create it.                                                            
  2136. Take your Gopher exec library (please) and include an exec                      
  2137. called HOSTNAME, which you set up to return the name                            
  2138. of the host that you want to be the "same host".                                
  2139.                                                                                 
  2140. Note that a plus sign "+" will not work in this context.                        
  2141. The plus sign is a hack interpreted by the Gopher server                        
  2142. when it sees it on a menu.  It is *not* part of the Gopher                      
  2143. protocol and therefore cannot be sent over.                                     
  2144.                                                                                 
  2145. However, the minus sign "-" will work, as the Gopher client                     
  2146. in local mode will interpret it at the protocol level                           
  2147. (which DOES NOT IMPLY THAT IT IS A PART OF THE STANDARD                         
  2148. GOPHER PROTOCOL, PROPOSED OR OTHERWISE - THIS IS JUST A                         
  2149. LOCAL HACK MODIFICATION).                                                       
  2150.                                                                                 
  2151. Anyhow, what you ought to do is to have different Gopher                        
  2152. exec libraries for local (i.e.private) use and public                           
  2153. server use.  The public server will have a HOSTNAME member                      
  2154. that says                                                                       
  2155.                                                                                 
  2156.  return "MVS.DRAPER.COM"                                                        
  2157.                                                                                 
  2158. or whatever the name of *YOUR* gopher server host is.                           
  2159.                                                                                 
  2160. Your private exec library should have a HOSTNAME member                         
  2161. that says                                                                       
  2162.                                                                                 
  2163.   return "-"                                                                    
  2164.                                                                                 
  2165. This is the best I can come up with right now.  A future enhancement            
  2166. may be to pass the hostname as the second arg to the REXX exec using            
  2167. the IRXEXEC interface, e.g.                                                     
  2168.                                                                                 
  2169. parse arg execargs, hostname                                                    
  2170.                                                                                 
  2171. Then we could pass even more such arguments, like port, etc.                    
  2172. But that's all for now...                                                       
  2173.                                                                                 
  2174.                                                                                 
  2175. Oh, one more thing!  The same principle applies to the port number.             
  2176. Yes, it's normally 70 for Gopher.  But if you're running a server               
  2177. off a different port - like the example of running two MVS Gopher               
  2178. servers you saw if you read the installation files - then you will              
  2179. not want to hardcode a port number either.                                      
  2180.                                                                                 
  2181. So in all the above examples, change the statements that read                   
  2182. "port = 70" or the like so that they read                                       
  2183.                                                                                 
  2184. port = port()                                                                   
  2185.                                                                                 
  2186. and define a PORT exec in your library, sort of like the HOSTNAME exec,         
  2187. that reads                                                                      
  2188.                                                                                 
  2189. return "70"            /* if you want to talk to the primary server */          
  2190.                                                                                 
  2191.  or                                                                             
  2192.                                                                                 
  2193. return "1570"          /* use secondary Gopher server */                        
  2194.                                                                                 
  2195. Note that in our recommended scenario, we always use the secondary              
  2196. server for exec requests and the primary server for file requests.              
  2197. So, if you are building a menu item whose path is a file name, use              
  2198. the primary server port; if you are building a menu item whose path             
  2199. is a REXX exec specification, use the secondary server port.                    
  2200.                                                                                 
  2201. ./   ADD NAME=ABOUTS,SSI=01050001                                               
  2202. gopher_menu                                                                     
  2203.                                                                                 
  2204. TYPE=FILE                                                                       
  2205. NAME=Creating MVS Gopher Menus                                                  
  2206. PATH=(ABOUTCSM)                                                                 
  2207. HOST=+                                                                          
  2208. END                                                                             
  2209.                                                                                 
  2210. TYPE=FILE                                                                       
  2211. NAME=MVS Gopher Access Table                                                    
  2212. PATH=(ABOUTSA)                                                                  
  2213. HOST=+                                                                          
  2214. END                                                                             
  2215.                                                                                 
  2216. TYPE=FILE                                                                       
  2217. NAME=MVS Gopher Startup Parameters                                              
  2218. PATH=(ABOUTSP)                                                                  
  2219. HOST=+                                                                          
  2220. END                                                                             
  2221.                                                                                 
  2222. TYPE=FILE                                                                       
  2223. NAME=REXX Exec Interface                                                        
  2224. PATH=(ABOUTCSX)                                                                 
  2225. HOST=+                                                                          
  2226. END                                                                             
  2227.                                                                                 
  2228. ./   ADD NAME=ABOUTSA,SSI=01020004                                              
  2229.                                                                                 
  2230.   Format of entries in the Gopher Access Table:                                 
  2231.                                                                                 
  2232.   filename (fully qualified, all uppercase, no quotes)                          
  2233.   can be "DD:DDNAME" or "EXEC:EXECNAME"                                         
  2234.                                                                                 
  2235.   followed by names of hosts which are authorized to access the data.           
  2236.   If no host name list is present, all hosts are authorized                     
  2237.                                                                                 
  2238.   You may specify the same file name more than once, if you need                
  2239.   more lines to put host names on.                                              
  2240.                                                                                 
  2241.   Individual PDS members must be specified separately.  A PDS without           
  2242.   a member name establishes access only to the PDS directory.                   
  2243.                                                                                 
  2244.   Note that the default directory MUST be in this table.                        
  2245.                                                                                 
  2246.   Also note that in the case of EXECs, the EXEC must live in the                
  2247.   library allocated to GGEXEC in the Gopher server JCL.                         
  2248.                                                                                 
  2249.   *** ANY DATA SET REFERENCED BY ANY EXEC IN THAT LIBRARY IS FULLY              
  2250.   *** ACCESSIBLE TO GOPHER REGARDLESS OF THIS TABLE!  USE THIS TABLE            
  2251.   *** TO GOVERN CONTROL TO THE EXEC ITSELF!!!                                   
  2252.                                                                                 
  2253. ./   ADD NAME=ABOUTSP,SSI=01000044                                              
  2254.                                                                                 
  2255.  MVS Gopher Startup Parameter File                                              
  2256.                                                                                 
  2257.  The Gopher server started task may contain a DD statement pointing             
  2258.  to DDname GGPARMS.  If so, this file contains startup parameters               
  2259.  for that invocation of the server.  If such a file does not exist,             
  2260.  the defaults (as in the header file GGUSER) are used.                          
  2261.                                                                                 
  2262.  One possible use of this feature is to have more than one MVS Gopher           
  2263.  server running, with different port numbers.  This may prevent some            
  2264.  bottlenecking situations.                                                      
  2265.                                                                                 
  2266.  All entries in this file have the format:   variable value comments            
  2267.                                                                                 
  2268.  These are the possible values and their default settings:                      
  2269.                                                                                 
  2270.  mtftasks 1    Number of concurrent subtasks to handle client requests          
  2271.  port     70   The TCP port number by which clients connect                     
  2272.  qlength  20   Queue length for TCP server listen function                      
  2273.  timeout  60   Connection timeout specified when socket is closed               
  2274.  domain   .DRAPER.COM     The suffix to be appende to bald host names           
  2275.                                                                                 
  2276. You may notice that the TELNET command may be set in this file too.             
  2277. That was probably a misunderstanding, as it's the client, not the               
  2278. server, that controls how telnets are to be done.                               
  2279.                                                                                 
  2280. ./   ADD NAME=ABOUTW,SSI=01020053                                               
  2281. What is Gopher?                                                                 
  2282.                                                                                 
  2283. For more information, read the FAQ, posted to USENET newsgroups                 
  2284. comp.infosystems.gopher and news.answers every two weeks.                       
  2285.                                                                                 
  2286. The information contained here is borrowed therefrom in large part.             
  2287.                                                                                 
  2288. Gopher is a client/server protocol for building a distributed                   
  2289. information delivery service.  While providing a delivery vehicle for           
  2290. local information, Gopher also facilitates access to other Gopher and           
  2291. information servers on the Internet.                                            
  2292.                                                                                 
  2293. Gopher servers and clients can be obtained via anonymous ftp to                 
  2294. boombox.micro.umn.edu.  Look in the directory /pub/gopher.                      
  2295.                                                                                 
  2296.      There are clients for the following systems.  For the latest               
  2297.      directory information, see the FAQ.                                        
  2298.                                                                                 
  2299.       Unix Curses & Emacs                                                       
  2300.       Xwindows                                                                  
  2301.       Macintosh Hypercard                                                       
  2302.       Macintosh Application                                                     
  2303.       DOS w/Clarkson Driver                                                     
  2304.       NeXTstep                                                                  
  2305.       VM/CMS                                                                    
  2306.       VMS                                                                       
  2307.       MVS                                                                       
  2308.                                                                                 
  2309.      There are also a number of public telnet login sites available.            
  2310.      See the FAQ for more information.                                          
  2311.                                                                                 
  2312.      There are servers for the following systems.  For the latest               
  2313.      directory information, see the FAQ.                                        
  2314.                                                                                 
  2315.        Unix                                                                     
  2316.        VMS                                                                      
  2317.        Macintosh                                                                
  2318.        VM/CMS                                                                   
  2319.        MVS                                                                      
  2320.                                                                                 
  2321.                                                                                 
  2322. Papers and articles describing Gopher:                                          
  2323.                                                                                 
  2324.      _The_Internet_Gopher_, "ConneXions", July 1992, Interop.                   
  2325.                                                                                 
  2326.      _Exploring_Internet_GopherSpace_ "The Internet Society News", v1n2 1992,   
  2327.                                                                                 
  2328.      _The_Internet_Gopher_Protocol_, Proceedings of the Twenty-Third            
  2329.           IETF, CNRI, Section 5.3                                               
  2330.                                                                                 
  2331.      _Internet_Gopher_, Proceedings of Canadian Networking '92                  
  2332.                                                                                 
  2333.      _The_Internet_Gopher_, INTERNET: Getting Started, SRI                      
  2334.           International, Section 10.5.5                                         
  2335.                                                                                 
  2336.      _Tools_help_Internet_users_discover_on-line_treasures, Computerworld,      
  2337.           July 20, 1992                                                         
  2338.                                                                                 
  2339.      Gopher will also be in two forthcoming O'Reilly Books:                     
  2340.      "Administrating TCP/IP, and The Whole Internet"                            
  2341.                                                                                 
  2342. ./   ADD NAME=FAQ,SSI=01030010                                                  
  2343. Xref: news.draper.com comp.infosystems.gopher:3051 news.answers:5459 comp.answer
  2344. Newsgroups: comp.infosystems.gopher,news.answers,comp.answers                   
  2345. Path: news.draper.com!ns.draper.com!noc.near.net!howland.reston.ans.net!gatech!n
  2346. From: gopher@boombox.micro.umn.edu (UofMN Gopher Team)                          
  2347. Subject: Gopher (comp.infosystems.gopher) Frequently Asked Questions (FAQ)      
  2348. Message-ID: <goher-faq_03-26-93@mudhoney.micro.umn.edu>                         
  2349. Followup-To: comp.infosystems.gopher                                            
  2350. Summary: Common Questions and Answers about the Internet Gopher, a              
  2351.         client/server protocol for making a world wide information              
  2352.         service, with many implementations.                                     
  2353. Sender: news@news.cis.umn.edu (Usenet News Administration)                      
  2354. Supersedes: <gopher-faq_02-19-93@mudhoney.micro.umn.edu>                        
  2355. Nntp-Posting-Host: mudhoney.micro.umn.edu                                       
  2356. Reply-To: gopher@boombox.micro.umn.edu (UofMN Gopher Team)                      
  2357. Organization: University of Minnesota                                           
  2358. Date: Fri, 26 Mar 1993 09:29:40 GMT                                             
  2359. Approved: news-answers-request@MIT.Edu                                          
  2360. Lines: 562                                                                      
  2361.                                                                                 
  2362. Archive-name: gopher-faq                                                        
  2363. Last-modified: 1993/03/11                                                       
  2364.                                                                                 
  2365. Common Questions and Answers about the Internet Gopher, a                       
  2366. client/server protocol for making a world wide information service,             
  2367. with many implementations.  Posted to comp.infosystems.gopher,                  
  2368. comp.answers, and news.answers every two weeks.                                 
  2369.                                                                                 
  2370. The most recent version of this FAQ can be gotten through gopher, or            
  2371. via anonymous ftp:                                                              
  2372.                                                                                 
  2373. pit-manager.mit.edu:/pub/usenet/news.answers/gopher-faq                         
  2374.                                                                                 
  2375. Those without FTP access should send e-mail to mail-server@rtfm.mit.edu         
  2376. with "send usenet/news.answers/finding-sources" in the body to find out         
  2377. how to do FTP by e-mail.                                                        
  2378.                                                                                 
  2379. -------------------------------------------------------------------             
  2380. List of questions in the Gopher FAQ:                                            
  2381.                                                                                 
  2382. Q0:  What is Gopher?                                                            
  2383. Q1:  Where can I get Gopher software?                                           
  2384. Q2:  What do I need to access Gopher?                                           
  2385. Q3:  Where are there publicly available logins for Gopher?                      
  2386. Q4:  How can I add to the information in gopher?                                
  2387. Q5:  Who Develops Gopher Software?                                              
  2388. Q6:  How can I set up a "CSO" phone book server?  Where is the software?        
  2389. Q7:  Why can't I access the University of Minnesota's UPI news?                 
  2390. Q9:  What are the type characters for the different Gopher Objects?             
  2391. Q10: When I do full-text searches I always get every document back, Why?        
  2392. Q11: When I try to build the UNIX software I get an error from make:            
  2393.      "Must be a separator on rules line #. Stop"  Why?                          
  2394. Q12: What is the relationship between Gopher and (WAIS, WWW, ftp)?              
  2395. Q13: Are papers or articles describing Gopher available?                        
  2396. Q14: On a DECstation I get the error message "/etc/svc.conf no such file        
  2397.      or directory" when running the gopherd server, why?                        
  2398. Q15: The boolean searching terms don't work for my full-text index, why?        
  2399. Q16: When linking the Unix gopher server with WAIS I get undefined symbols,     
  2400. Q18: Why don't my WAIS indexes work?  I never get anything back for searches.   
  2401.      or Why do I get "Dangling file" error messages in my logfile?              
  2402. Q19: My gopher server doesn't work under inetd, why?                            
  2403. Q20: This is not a bug report, just a curiousity. I managed to install          
  2404. Q21: Help!  I have PC-NFS and want to use the PC-Gopher client.  How?           
  2405. Q22: How do I nuke a hung TCP connection?  I can't restart my UNIX              
  2406.      gopher server unless I get rid of it, and I don't want to reboot!          
  2407. Q23: Is there somewhere I can retrieve a list of announced gopher               
  2408.      links?  I'd like to keep a local, up-to-date list of available gopher      
  2409.      holes without requiring our users to gopher to umn just to scan            
  2410.      GopherSpace.                                                               
  2411. Q24: Why doesn't my unix gopher client display ISO-Latin-1 characters           
  2412. Q25: What is veronica?                                                          
  2413.                                                                                 
  2414. -------------------------------------------------------------------             
  2415. Q0:  What is Gopher?                                                            
  2416.                                                                                 
  2417. A0:  The Internet Gopher client/server provides a distributed                   
  2418.      information delivery system around which a world/campus-wide               
  2419.      information system (CWIS) can readily be constructed.   While              
  2420.      providing a delivery vehicle for local information,  Gopher                
  2421.      facilitates access to other Gopher and information servers                 
  2422.      throughout the world.                                                      
  2423.                                                                                 
  2424. -------------------------------------------------------------------             
  2425. Q1:  Where can I get Gopher software?                                           
  2426.                                                                                 
  2427. A1:  via anonymous ftp to boombox.micro.umn.edu.  Look in the directory         
  2428.      /pub/gopher                                                                
  2429.                                                                                 
  2430. --------------------------------------------------------------------            
  2431. Q2:  What do I need to access Gopher?                                           
  2432.                                                                                 
  2433. A2:  You will need a gopher "client" program that runs on your local PC         
  2434.      or workstation                                                             
  2435.                                                                                 
  2436.      There are clients for the following systems.  The directory                
  2437.      following the name is the location of the client on the anonymous          
  2438.      ftp site boombox.micro.umn.edu (134.84.132.2) in the directory             
  2439.      /pub/gopher.                                                               
  2440.                                                                                 
  2441.       Unix Curses & Emacs   :  /pub/gopher/Unix/gopher1.12.tar.Z                
  2442.       Xwindows (athena)     :  /pub/gopher/Unix/xgopher1.2.tar.Z                
  2443.       Xwindows (Motif)      :  /pub/gopher/Unix/moog                            
  2444.       Macintosh Hypercard   :  /pub/gopher/Macintosh-TurboGopher/old-versions * 
  2445.       Macintosh Application :  /pub/gopher/Macintosh-TurboGopher *              
  2446.       DOS w/Clarkson Driver :  /pub/gopher/PC_client/                           
  2447.       NeXTstep              :  /pub/gopher/NeXT/                                
  2448.       VM/CMS                :  /pub/gopher/Rice_CMS/ or /pub/gopher/VieGOPHER/  
  2449.       VMS                   :  /pub/gopher/VMS/                                 
  2450.       OS/2 2.0              :  /pub/gopher/os2/                                 
  2451.       MVS/XA                :  /pub/gopher/mvs/                                 
  2452.                                                                                 
  2453.      Many other clients and servers have been developed by others, the          
  2454.      following is an attempt at a comprehensive list.                           
  2455.                                                                                 
  2456.       A Microsoft Windows Winsock client "The Gopher Book"                      
  2457.         sunsite.unc.edu:/pub/micro/pc-stuff/ms-windows/winsock/goph_tbk.zip     
  2458.                                                                                 
  2459.       A Macintosh Application, "MacGopher".                                     
  2460.         ftp.cc.utah.edu:/pub/gopher/Macintosh *                                 
  2461.                                                                                 
  2462.       Another Macintosh application, "GopherApp".                               
  2463.         ftp.bio.indiana.edu:/util/gopher/gopherapp *                            
  2464.                                                                                 
  2465.       A port of the UNIX curses client for DOS with PC/TCP                      
  2466.         oac.hsc.uth.tmc.edu:/public/dos/misc/dosgopher.exe                      
  2467.                                                                                 
  2468.       A port of the UNIX curses client for PC-NFS                               
  2469.          bcm.tmc.edu:/nfs/gopher.exe                                            
  2470.                                                                                 
  2471.       A beta version of the PC Gopher client for Novell's LAN Workplace         
  2472.       for DOS                                                                   
  2473.          lennon.itn.med.umich.edu:/dos/gopher                                   
  2474.                                                                                 
  2475.       A VMS DECwindows client for use with Wollongong or UCX                    
  2476.          job.acs.ohio-state.edu:XGOPHER_CLIENT.SHARE                            
  2477.                                                                                 
  2478.                                                                                 
  2479.      * Note: these Macintosh clients require MacTCP.                            
  2480.                                                                                 
  2481.      Most of the above clients can also be fetched via a gopher client          
  2482.      itself.  Put the following on a gopher server:                             
  2483.                                                                                 
  2484.        Type=1                                                                   
  2485.        Host=boombox.micro.umn.edu                                               
  2486.        Port=70                                                                  
  2487.        Path=                                                                    
  2488.        Name=Gopher Software Distribution.                                       
  2489.                                                                                 
  2490.                                                                                 
  2491.      Or point your gopher client at boombox.micro.umn.edu, port 70 and          
  2492.      look in the gopher directory.                                              
  2493.                                                                                 
  2494.                                                                                 
  2495.      There are also a number of public telnet login sites available.            
  2496.      The University of Minnesota operates one on the machine                    
  2497.      "consultant.micro.umn.edu" (134.84.132.4) See Q3 for more                  
  2498.      information about this.  It is recommended that you run the client         
  2499.      software instead of logging into the public telnet login sites.  A         
  2500.      client uses the custom features of the local machine (mouse,               
  2501.      scroll bars, etc.)  A local client is also faster.                         
  2502.                                                                                 
  2503. ---------------------------------------------------------------------           
  2504. Q3:  Where are there publicly available logins for Gopher?                      
  2505.                                                                                 
  2506. A3:  Here is a short list, use the site closest to you to minimize              
  2507.      network lag.                                                               
  2508.                                                                                 
  2509.      Non-tn3270 Public Logins:                                                  
  2510.                                                                                 
  2511.      Hostname                  IP#              Login   Area                    
  2512.      ------------------------- ---------------  ------  -------------           
  2513.      consultant.micro.umn.edu  134.84.132.4     gopher  North America           
  2514.      gopher.uiuc.edu           128.174.33.160   gopher  North America           
  2515.      panda.uiowa.edu           128.255.40.201   panda   North America           
  2516.      gopher.sunet.se           192.36.125.2     gopher  Europe                  
  2517.      info.anu.edu.au           150.203.84.20    info    Australia               
  2518.      gopher.chalmers.se        129.16.221.40    gopher  Sweden                  
  2519.      tolten.puc.cl             146.155.1.16     gopher  South America           
  2520.      ecnet.ec                  157.100.45.2     gopher  Ecuador                 
  2521.                                                                                 
  2522.      tn3270 Public Logins:                                                      
  2523.                                                                                 
  2524.      Hostname                  IP#              Login   Area                    
  2525.      ------------------------- ---------------  ------  -------------           
  2526.      pubinfo.ais.umn.edu       128.101.109.1    -none-  North America           
  2527.                                                                                 
  2528.                                                                                 
  2529.      It is recommended that you run the client software instead of              
  2530.      logging into the public login sites.  A client uses the                    
  2531.      custom features of the local machine (mouse, scroll bars, etc.)            
  2532.      and gives faster response.                                                 
  2533.                                                                                 
  2534. ---------------------------------------------------------------------           
  2535. Q4:  How can I add to the information in gopher?                                
  2536.                                                                                 
  2537. A4:  You can do this by running a gopher server.  Servers are available         
  2538.      for a number of systems.  Use anonymous ftp to                             
  2539.      boombox.micro.umn.edu (134.84.132.2) and look in /pub/gopher.  The         
  2540.      following servers are available there:                                     
  2541.                                                                                 
  2542.        Unix      : /pub/gopher/Unix/gopherxx.tar.Z                              
  2543.        VMS       : /pub/gopher/VMS/                                             
  2544.        Macintosh : /pub/gopher/Mac_server/                                      
  2545.        VM/CMS    : /pub/gopher/Rice_CMS/ or /pub/gopher/Vienna_CMS/             
  2546.        MVS       : /pub/gopher/mvs/                                             
  2547.        DOS PC    : /pub/gopher/PC_server/                                       
  2548.                                                                                 
  2549.                                                                                 
  2550.      When you have your server ready you can publish it to the world by         
  2551.      sending e-mail to the maintainters of the "Other gophers" list:            
  2552.                                                                                 
  2553.      If your gopher server is in Europe, send mail to:                          
  2554.                                                                                 
  2555.         gopher@ebone.net                                                        
  2556.                                                                                 
  2557.      Otherwise send mail to:                                                    
  2558.                                                                                 
  2559.         gopher@boombox.micro.umn.edu                                            
  2560.                                                                                 
  2561. ---------------------------------------------------------------------           
  2562. Q5:  Who Develops Gopher Software?                                              
  2563.                                                                                 
  2564. A5:  Gopher was originally developed in April 1991 by the University            
  2565.      of Minnesota Microcomputer, Workstation, Networks Center to help           
  2566.      our campus find answers to their computer questions.                       
  2567.                                                                                 
  2568.      It has since grown into a full-fledged World Wide Information              
  2569.      System used by a large number of sites in the world.                       
  2570.                                                                                 
  2571.      Many people have contributed to the project, too numerous to               
  2572.      count.                                                                     
  2573.                                                                                 
  2574.      The people behind the much of the gopher software can be reached           
  2575.      via e-mail at gopher@boombox.micro.umn.edu, or via paper mail:             
  2576.                                                                                 
  2577.       Internet Gopher Developers                                                
  2578.       100 Union St. SE #190                                                     
  2579.       Minneapolis, MN 55455  USA                                                
  2580.                                                                                 
  2581.      Or via FAX at:                                                             
  2582.                                                                                 
  2583.       +1 (612) 625-6817                                                         
  2584.                                                                                 
  2585. ---------------------------------------------------------------------           
  2586. Q6:  How can I set up a "CSO" phone book server?  Where is the software?        
  2587.                                                                                 
  2588. A6:  CSO phone book servers are also known as "qi" servers.  The                
  2589.      software implementation can be gotten via anonymous ftp from               
  2590.      uxc.cso.uiuc.edu (128.174.5.50) as /pub/qi.tar.Z.  You may also            
  2591.      see this referred to as "ph", which is what most of the clients            
  2592.      are called.  A collected set of clients for Macs, PCs, VMS, VM,            
  2593.      etc, are in the /pub/ph.tar.Z file.                                        
  2594.                                                                                 
  2595.      There is also an archive of the mailing list for qi/ph software on         
  2596.      the same machine.  It's in /pub/info-ph.archive. You may join the          
  2597.      list by sending email to info-ph-request@uxc.cso.uiuc.edu.                 
  2598.                                                                                 
  2599.      This software is supported by Paul Pomes <p-pomes@uiuc.edu>                
  2600.      Contact him for more information.                                          
  2601.                                                                                 
  2602. -------------------------------------------------------------------             
  2603. Q7:  Why can't I access the University of Minnesota's UPI news?                 
  2604.                                                                                 
  2605. A7:  The University of Minnesota has a site license for UPI news, we            
  2606.      are not allowed to distribute it off of our campus.  We get our            
  2607.      UPI news from Clarinet.  For more information about getting UPI            
  2608.      news send mail to info@clarinet.com.  For information about                
  2609.      setting up your own gopher-UPI server search the gopher-news               
  2610.      archive for UPI.                                                           
  2611.                                                                                 
  2612. -------------------------------------------------------------------             
  2613. Q9:  What are the type characters for the different Gopher Objects?             
  2614.                                                                                 
  2615. A9:  Normal IDs.                                                                
  2616.                                                                                 
  2617.      0       Item is a file                                                     
  2618.      1       Item is a directory                                                
  2619.      2       Item is a CSO (qi) phone-book server                               
  2620.      3       Error                                                              
  2621.      4       Item is a BinHexed Macintosh file.                                 
  2622.      5       Item is DOS binary archive of some sort.                           
  2623.      6       Item is a UNIX uuencoded file.                                     
  2624.      7       Item is an Index-Search server.                                    
  2625.      8       Item points to a text-based telnet session.                        
  2626.      9       Item is a binary file!  Client must read until the connection      
  2627.                  closes.  Beware.                                               
  2628.      T       TN3270 connection.                                                 
  2629.                                                                                 
  2630.      Experimental IDs.                                                          
  2631.                                                                                 
  2632.      s       Sound type.  Data stream is a mulaw sound.                         
  2633.      g       GIF type.                                                          
  2634.      M       MIME type.  Item contains MIME data.                               
  2635.      h       html type.                                                         
  2636.      I       Image type.                                                        
  2637.      i       "inline" text type (used by panda).                                
  2638.                                                                                 
  2639. -------------------------------------------------------------------             
  2640. Q10: When I do full-text searches I always get every document back, Why?        
  2641.                                                                                 
  2642. A10: This is a problem occasionally encountered with Unix full-text             
  2643.      indexes.  It is caused by setting up the link incorrectly to a             
  2644.      gindexd port.                                                              
  2645.                                                                                 
  2646.      The Path= field should be *blank* when pointing to a gindexd               
  2647.      index.                                                                     
  2648.                                                                                 
  2649.      Otherwise the client will send the path to the gindexd daemon,             
  2650.      which interprets everything as a keyword.  This path is                    
  2651.      likely to contain a pathname that is common to all of the indexed          
  2652.      files.  Thus a search generates hits on everything.                        
  2653.                                                                                 
  2654. -------------------------------------------------------------------             
  2655. Q11: When I try to build the UNIX software I get an error from make:            
  2656.      "Must be a separator on rules line #. Stop"  Why?                          
  2657.                                                                                 
  2658. A11: This is a problem with older makes that don't understand the "include"     
  2659.      keyword.  One easy way to cope with this problem is compiling GNU          
  2660.      make, which does understand the include keyword.                           
  2661.                                                                                 
  2662.      If this is too difficult, remove the line:                                 
  2663.                                                                                 
  2664.       include Makefile.config                                                   
  2665.                                                                                 
  2666.      from all the Makefiles and paste in a copy of Makefile.config at           
  2667.      the top of each Makefile.                                                  
  2668.                                                                                 
  2669.      Or, instead of pasting you can make the client/server by going             
  2670.      into the appropriate directory and typing:                                 
  2671.                                                                                 
  2672.       make -f ../Makefile.config -f Makefile                                    
  2673.                                                                                 
  2674. -------------------------------------------------------------------             
  2675. Q12: What is the relationship between Gopher and (WAIS, WWW, ftp)?              
  2676.                                                                                 
  2677. A12: Gopher is intimately intertwined with these two other systems.             
  2678.      As shipped the Unix gopher server has the capability to:                   
  2679.                                                                                 
  2680.        - Search local WAIS indices.                                             
  2681.        - Query remote WAIS servers and funnel the results to gopher             
  2682.          clients.                                                               
  2683.        - Query remote ftp sites and funnel the results to gopher                
  2684.          clients.                                                               
  2685.        - Be queried by WWW (World Wide Web) clients (either using               
  2686.          built in gopher querying or using native http querying.                
  2687.                                                                                 
  2688. -------------------------------------------------------------------             
  2689. Q13: Are papers or articles describing Gopher available?                        
  2690.                                                                                 
  2691. A13: Gopher has a whole chapter devoted to it in :                              
  2692.                                                                                 
  2693.      _The_Whole_Internet_users_guide_and_catalog by Ed Krol                     
  2694.      (publisher O'Reilley & Associates, Inc; ISBN: 1-56592-025-2).              
  2695.      (Editors note: ...Great book, go out and buy a bunch!)                     
  2696.                                                                                 
  2697.      _The_Internet_Passport: NorthWestNet's Guide to Our World Online"          
  2698.      By Jonathan Kochmer and NorthWestNet. Published by NorthWestNet,           
  2699.      Bellevue, WA. 1993. 516 pp. ISBN 0-9635281-0-6.                            
  2700.      Contact info: passport@nwnet.net, or (206) 562-3000                        
  2701.                                                                                 
  2702.      _A_Students_Guide_to_UNIX by Harley Hahn. (publisher McGraw Hill,          
  2703.      Inc.; 1993 ISBN 0-07-025511-3)                                             
  2704.                                                                                 
  2705.                                                                                 
  2706.      Other references include:                                                  
  2707.                                                                                 
  2708.      _The_Internet_Gopher_, "ConneXions", July 1992, Interop.                   
  2709.                                                                                 
  2710.      _Exploring_Internet_GopherSpace_ "The Internet Society News", v1n2 1992,   
  2711.                                                                                 
  2712.      (You can subscribe to the Internet Society News by sending e-mail to       
  2713.       isoc@nri.reston.va.us)                                                    
  2714.                                                                                 
  2715.      _The_Internet_Gopher_Protocol_, Proceedings of the Twenty-Third            
  2716.           IETF, CNRI, Section 5.3                                               
  2717.                                                                                 
  2718.      _Internet_Gopher_, Proceedings of Canadian Networking '92                  
  2719.                                                                                 
  2720.      _The_Internet_Gopher_, INTERNET: Getting Started, SRI                      
  2721.           International, Section 10.5.5                                         
  2722.                                                                                 
  2723.      _Tools_help_Internet_users_discover_on-line_treasures, Computerworld,      
  2724.           July 20, 1992                                                         
  2725.                                                                                 
  2726.      _TCP/IP_Network_Administration_, O'Reilly.                                 
  2727.                                                                                 
  2728.       Balakrishan, B. (Oct 1992)                                                
  2729.         "SPIGopher: Making SPIRES databases accessible through the              
  2730.       Gopher protocol".  SPIRES Fall '92 Workshop, Chapel Hill, North           
  2731.       Carolina.                                                                 
  2732.                                                                                 
  2733.       Tomer, C.  Information Technology Standards for Libraries,                
  2734.       _Journal of the American Society for Information Science_,                
  2735.       43(8):566-570, Sept 1992.                                                 
  2736.                                                                                 
  2737.                                                                                 
  2738. -------------------------------------------------------------------             
  2739. Q14: On a DECstation I get the error message "/etc/svc.conf no such file        
  2740.      or directory" when running the gopherd server, why?                        
  2741.                                                                                 
  2742. A14: This is caused by the chroot() call in gopherd.  It can be easily          
  2743.      fixed by running gopherd with the -c option.                               
  2744.                                                                                 
  2745.      Alternatively you can copy /etc/svc.conf into a directory named            
  2746.      "etc" inside the gopher-data directory.                                    
  2747. -------------------------------------------------------------------             
  2748. Q15: The boolean searching terms don't work for my full-text index, why?        
  2749.                                                                                 
  2750. A15: This is probably because the searching is being provided by WAIS.          
  2751.      WAIS opts to return all documents that contain a search phrase             
  2752.      within certain limits.  WAIS searches do return the documents with         
  2753.      the highest "score" at the top, those documents will have the              
  2754.      closest relevance.                                                         
  2755.                                                                                 
  2756.      Alternatively you could get a booleanized version of wais from             
  2757.      ftp.bio.indiana.edu.                                                       
  2758. -------------------------------------------------------------------             
  2759. Q16: When linking the Unix gopher server with WAIS I get undefined              
  2760.      symbols,                                                                   
  2761.        such as:                                                                 
  2762.                                                                                 
  2763.          log_file_name                                                          
  2764.          logfile                                                                
  2765.          PrintStatus                                                            
  2766.          find_value                                                             
  2767.          Sources                                                                
  2768.          NumSources                                                             
  2769.                                                                                 
  2770. A17: This happens if you make gopherd before linking in the WAIS ir/ui          
  2771.      directories.  The fix is to "make clean" or remove                         
  2772.      gopherd/{waisgopher.o,Waisindex.o} and then remake gopherd.  Or            
  2773.      link the ir/ui directories first.                                          
  2774. -------------------------------------------------------------------             
  2775. Q18: Why don't my WAIS indexes work?  I never get anything back for searches.   
  2776.      or Why do I get "Dangling file" error messages in my logfile?              
  2777.                                                                                 
  2778. A18: The problem could be in the server.  The server should be run              
  2779.      using the -c option if you want WAIS to work.  Another solution is to      
  2780.      patch the WAIS code so that it doesn't check the files on the disk.        
  2781.      Search the gopher-news archive for "dangling".  This will turn up a        
  2782.      single document with the patch.                                            
  2783.                                                                                 
  2784. -------------------------------------------------------------------             
  2785. Q19: My gopher server doesn't work under inetd, why?                            
  2786.                                                                                 
  2787. A19: It could be that your inetd server only supports a limited amount          
  2788.      of arguments.  For instance, the maximum number of arguments to an         
  2789.      inetd server is 5.  You can get around this by combining arguments: i.e.   
  2790.                                                                                 
  2791.        gopherd -I -c                                                            
  2792.                                                                                 
  2793.      becomes:                                                                   
  2794.                                                                                 
  2795.        gopherd -Ic                                                              
  2796.                                                                                 
  2797.      You may also leave the port specifier off of the command line.             
  2798.      The gopher server automagically finds out the port it's running on.        
  2799.                                                                                 
  2800. -------------------------------------------------------------------             
  2801. Q20: This is not a bug report, just a curiousity. I managed to install          
  2802.      gopher on my PC, more or less by myself, which is a pretty good            
  2803.      accomplishment, for someone who hasn't installed hardly anything on a      
  2804.      PC. I then proceeded to load my PC/TCP kernel, ETHDRV, and try to          
  2805.      start up gopher. It said it couldn't initialize that stack(?). I have      
  2806.      to load this whenever I use PC/TCP. Incredibly, when I did not load        
  2807.      ETHDRV, Gopher came up immediately and telneted to our local server.       
  2808.      How does it know what kernel to load?                                      
  2809.                                                                                 
  2810. A20 Dr. Science says,                                                           
  2811.                                                                                 
  2812.      The Internet Gopher program is not actually computer program at            
  2813.      all, but a collection of magical incantations handed down from Dark        
  2814.      Age conjurors.  It works by sending magical "demons" through the air,      
  2815.      which scour the world for information, and then return to cast             
  2816.      illusions containing the answer.                                           
  2817.                                                                                 
  2818.      When you use the Gopher, your computer isn't actually doing                
  2819.      anything at all.  Instead, these demons have mesmirized you with an        
  2820.      evil magical spell, which was invoked by the pattern of                    
  2821.      finger-movements peculiar to the typing of the letters G-O-P-H-E-R on      
  2822.      your keyboard.  This spell transmits demonic information directly to       
  2823.      your brain.                                                                
  2824.                                                                                 
  2825.      Scientists aren't certain of the long-term effects of demonic              
  2826.      mesmirization, although former presidents have suffered only minor         
  2827.      medical side-effects from it.  Indeed, since Magic and Science are         
  2828.      usually opposed to each other, most Scientists are usually                 
  2829.      close-minded about such issues, and will usually respond with some         
  2830.      vacuous non-answer about "packet drivers", "stacks", and other such        
  2831.      jargon.                                                                    
  2832.                                                                                 
  2833.      Unlike conventional scientists, Dr. Science is very open-minded and        
  2834.      is willing to deal with such issues in a frank and honest manner.          
  2835.      This is why people come to him with questions, and why they've learned     
  2836.      to rely on and live by his answers.                                        
  2837.                                                                                 
  2838.      Dr. Science                                                                
  2839.          "I'm not a real doctor;  I have a Master's Degree....  in SCIENCE!"    
  2840.                                                                                 
  2841. :-) :-) :-) :-)                                                                 
  2842. There's always room for a little humor in a FAQ..                               
  2843. -------------------------------------------------------------------             
  2844. Q21: Help!  I have PC-NFS and want to use the PC-Gopher client.  How?           
  2845.                                                                                 
  2846. A21: Use a piece of software called PKTMUX, available at fine ftp               
  2847.      sites everywhere.  This will let you use any packet driver                 
  2848.      application.                                                               
  2849.                                                                                 
  2850.      Or, aquire a client that supports PC-NFS.  See Q2.                         
  2851. -------------------------------------------------------------------             
  2852. Q22: How do I nuke a hung TCP connection?  I can't restart my UNIX              
  2853.      gopher server unless I get rid of it, and I don't want to reboot!          
  2854.                                                                                 
  2855. A22:                                                                            
  2856.                                                                                 
  2857. Here is an example of using dbx to change a socket from CLOSING to              
  2858. CLOSED.                                                                         
  2859.                                                                                 
  2860.  # netstat -A|grep CLOSING                                                      
  2861.  c4bc5100 tcp        0     11  mymachine.gopher 129.89.8.4.70  CLOSING          
  2862.  # dbx -k /vmunix /dev/mem                                                      
  2863.  ...                                                                            
  2864.  (dbx) 0xc4bc5100+8/1X                  -- display contents of PCB+8            
  2865.  c4bc5108:   00000007                                                           
  2866.  (dbx) assign 0xc4bc5108=0              -- zero it                              
  2867.  0                                                                              
  2868.  (dbx) q                                                                        
  2869.                                                                                 
  2870. After a minute or two, the CLOSED socket should disappear.                      
  2871. -------------------------------------------------------------------             
  2872. Q23: Is there somewhere I can retrieve a list of announced gopher               
  2873.      links?  I'd like to keep a local, up-to-date list of available gopher      
  2874.      holes without requiring our users to gopher to umn just to scan            
  2875.      GopherSpace.                                                               
  2876.                                                                                 
  2877. A23: In the Unix client/server distribution is a perl script called             
  2878.      "gopherdist". Gopherdist can fetch the contents of any point in            
  2879.      GopherSpace.                                                               
  2880.                                                                                 
  2881.      To dump the contents of all the North American links from                  
  2882.      gopher.tc.umn.edu do the following:                                        
  2883.                                                                                 
  2884.      % gopherdist gopher.tc.umn.edu 70 "1/Other Gopher and Information          
  2885.        Servers/North America" > .Links                                          
  2886. -------------------------------------------------------------------             
  2887. Q24: Why doesn't my unix gopher client display ISO-Latin-1 characters           
  2888.      properly?  BTW I'm using a Sun workstation..                               
  2889.                                                                                 
  2890. A24: It is the client's problem, the server is perfectly 8-bit transparent.     
  2891.      The BSD curses library uses bit 8 in order to remember, whether a          
  2892.      character has been displayed reverse. So use just /usr/5bin/cc and         
  2893.      you get the System V curses version which is 8 bit clean.                  
  2894.                                                                                 
  2895.      Note that this may be a problem under other versions of UNIX too...        
  2896.                                                                                 
  2897. -------------------------------------------------------------------             
  2898. Q25: What is veronica?                                                          
  2899.                                                                                 
  2900. A25: veronica:  Very Easy Rodent-Oriented Net-wide Index to                     
  2901.      Computerized Archives.                                                     
  2902.                                                                                 
  2903.      veronica offers a keyword search of most gopher-server menu titles         
  2904.      in the entire gopher web.  As archie is to ftp archives, veronica          
  2905.      is to gopherspace.  A veronica search produces a menu of gopher            
  2906.      items, each of which is a direct pointer to a gopher data source.          
  2907.      Because veronica is accessed through a gopher client, it is easy           
  2908.      to use, and gives access to all types of data supported by the             
  2909.      gopher protocol.                                                           
  2910.                                                                                 
  2911.      To try veronica, select it from the "Other Gophers" menu on                
  2912.      Minnesota's gopher server, or point your gopher at:                        
  2913.                                                                                 
  2914.      Name=veronica (search menu items in most of GopherSpace)                   
  2915.      Type=1                                                                     
  2916.      Port=70                                                                    
  2917.      Path=1/veronica                                                            
  2918.      Host=futique.scs.unr.edu                                                   
  2919. --                                                                              
  2920.  | Paul Lindner | lindner@boombox.micro.umn.edu   | Slipping into madness       
  2921.  |              | Computer & Information Services | is good for the sake        
  2922.  | Gophermaster | University of Minnesota         | of comparison.              
  2923. ///// / / /    /////// / / / /  /  /  /   /      //// / / / /  /  /  /   /      
  2924. ./ ENDUP                                                                        
  2925. ?!                                                                              
  2926. //C        EXEC GGLOAD,TRK1='18',TO='C'                                         
  2927. //SYSIN    DD DATA,DLM='?!'                                                     
  2928. ./   ADD NAME=GGCLIENT,SSI=01070025                                             
  2929.                                                                                 
  2930.  /********************************************************************/         
  2931.  /*                                                                  */         
  2932.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  2933.  /*                                                                  */         
  2934.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  2935.  /*                                                                  */         
  2936.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  2937.  /* including the implied warranties of merchantability and fitness, */         
  2938.  /* are expressly denied.                                            */         
  2939.  /*                                                                  */         
  2940.  /* Provided this copyright notice is included, this software may    */         
  2941.  /* be freely distributed and not offered for sale.                  */         
  2942.  /*                                                                  */         
  2943.  /* Changes or modifications may be made and used only by the maker  */         
  2944.  /* of same, and not further distributed.  Such modifications should */         
  2945.  /* be mailed to the author for consideration for addition to the    */         
  2946.  /* software and incorporation in subsequent releases.               */         
  2947.  /*                                                                  */         
  2948.  /********************************************************************/         
  2949.                                                                                 
  2950. #ifdef SASC                                                                     
  2951. #pragma  runopts(EXECOPS)                                                       
  2952. #else                                                                           
  2953. #pragma  runopts(heap(8k,8k,anywhere,))                                         
  2954. #pragma  runopts(nospie,nostae)                                                 
  2955. #endif                                                                          
  2956.                                                                                 
  2957. #pragma  csect(code,  "GG@LIENT")                                               
  2958. #pragma  csect(static,"GG$LIENT")                                               
  2959. #include "gg.h"                                                                 
  2960.                                                                                 
  2961. /*********************************************************************/         
  2962.                                                                                 
  2963. static char copyright_notice[] =                                                
  2964.    "Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992   \n\         
  2965.                                                                     \n\         
  2966.     GOPHER server due to Shawn Hart at the University of Delaware.  \n\         
  2967.                                                                     \n\         
  2968.     This software is provided on an 'AS IS' basis.  All warranties, \n\         
  2969.     including the implied warranties of merchantability and fitness,\n\         
  2970.     are expressly denied.                                           \n\         
  2971.                                                                     \n\         
  2972.     Provided this copyright notice is included, this software may   \n\         
  2973.     be freely distributed and not offered for sale.                 \n\         
  2974.                                                                     \n\         
  2975.     Changes or modifications may be made and used only by the maker \n\         
  2976.     of same, and not further distributed.  Such modifications should\n\         
  2977.     be mailed to the author for consideration for addition to the   \n\         
  2978.     software and incorporation in subsequent releases.";                        
  2979.                                                                                 
  2980. /*********************************************************************/         
  2981.                                                                                 
  2982. #ifdef I370                                                                     
  2983. char * _style = "tso:";                                                         
  2984. #endif                                                                          
  2985.                                                                                 
  2986. /*********************************************************************/         
  2987.                                                                                 
  2988. static void                                                                     
  2989. trap_ispf_command(gp,verb,action)                                               
  2990. Rstruc ggcb      *gp;                                                           
  2991. char             *verb;                                                         
  2992. char             *action;                                                       
  2993. {                                                                               
  2994.  char             zcttrunc [16];                                                
  2995.  char             zctact   [64];                                                
  2996.  char             zctdesc [128];                                                
  2997.                                                                                 
  2998.  if (!GGMivput(gp,"ZCTVERB ",verb,-1)) return;                                  
  2999.                                                                                 
  3000.  if (!GGMispf(gp,"TBTOP ISPCMDS")) return;                                      
  3001.  if (!GGMispf(gp,"TBSCAN ISPCMDS ARGLIST(ZCTVERB)")) return;                    
  3002.  if (!GGMivget(gp,"ZCTACT ",zctact,sizeof(zctact)))  return;                    
  3003.  if (UNEQUAL(zctact,action)) {                                                  
  3004.    GGMivget(gp,"ZCTTRUNC ",zcttrunc, sizeof(zcttrunc));                         
  3005.    GGMivget(gp,"ZCTDESC  ",zctdesc,sizeof(zctdesc));                            
  3006.    if (!GGMispf(gp,"TBTOP ISPCMDS ")) return;                                   
  3007.    GGMivput(gp,"ZCTACT   ",action   ,-1);                                       
  3008.    GGMivput(gp,"ZCTTRUNC ",zcttrunc ,-1);                                       
  3009.    GGMivput(gp,"ZCTDESC  ",zctdesc  ,-1);                                       
  3010.    if (!GGMispf(gp,"TBADD ISPCMDS ")) return;                                   
  3011.  }                                                                              
  3012.                                                                                 
  3013.  return;                                                                        
  3014. }                                                                               
  3015.                                                                                 
  3016. /*********************************************************************/         
  3017.                                                                                 
  3018. static Bool                                                                     
  3019. go_for_it(gp,ip)                                                                
  3020. struct ggcb            *gp;                                                     
  3021. struct gopherinfo      *ip;                                                     
  3022. {                                                                               
  3023.  char                   temp   [32];                                            
  3024.                                                                                 
  3025.  (void)GGMivget(gp,"GGHOST ",ip->host,sizeof(ip->host));                        
  3026.  (void)GGMivget(gp,"GGPATH ",ip->path,sizeof(ip->path));                        
  3027.  (void)GGMivget(gp,"GGDESC ",ip->desc,sizeof(ip->desc));                        
  3028.  (void)GGMivget(gp,"GGPORT ",temp    ,sizeof(temp)    );                        
  3029.  ip->type = INITIAL_TYPE;                                                       
  3030.  if (!*ip->path) strcpy(ip->path,INITIAL_PATH);                                 
  3031.  if (!*ip->host) strcpy(ip->host,INITIAL_HOST);                                 
  3032.  if (!*ip->desc) strcpy(ip->desc,INITIAL_DESC);                                 
  3033.  ip->port = atoi(temp);                                                         
  3034.  if (ip->port == 0) ip->port = INITIAL_PORT;                                    
  3035.  *ip->bmds = '\0';                                                              
  3036.                                                                                 
  3037.  return GGMgofor(gp,ip,FALSE);                                                  
  3038.                                                                                 
  3039. }                                                                               
  3040.                                                                                 
  3041. /*********************************************************************/         
  3042.                                                                                 
  3043. int                                                                             
  3044. main(argc,argv)                                                                 
  3045. int      argc;                                                                  
  3046. char   **argv;                                                                  
  3047.                                                                                 
  3048. {                                                                               
  3049.  struct ggcb            *gp;                                                    
  3050.  struct gopherinfo      *ip;                                                    
  3051.  struct connection      *sp;                                                    
  3052.  char                   *p;                                                     
  3053.  int                     i;                                                     
  3054.  int                     exit_return_code;                                      
  3055.  Bool                    bypass_startup;                                        
  3056.  struct ggcb             gg;                                                    
  3057.  char                    zerrsm [25];                                           
  3058.  char                    zerrlm [ZERRLM_SIZE];                                  
  3059.                                                                                 
  3060.  exit_return_code = 0;                                                          
  3061.                                                                                 
  3062.  memset(&gg,0,sizeof(struct ggcb));                                             
  3063.                                                                                 
  3064.  gp = ≫                                                                      
  3065.                                                                                 
  3066.  /* set up top-level gopherinfo structure */                                    
  3067.                                                                                 
  3068.  GETMAIN(ip, struct gopherinfo, 1, "top-level gopherinfo struct");              
  3069.  if (!ip) {                                                                     
  3070.    fprintf(stderr,"Not enough memory to start up GOPHER\n");                    
  3071.    exit(16);                                                                    
  3072.  }                                                                              
  3073.                                                                                 
  3074.  memset(ip,0,sizeof(struct gopherinfo));                                        
  3075.                                                                                 
  3076.  gp->ginfo = ip;                                                                
  3077.                                                                                 
  3078.  gp->test_mode  = FALSE;                                                        
  3079.  gp->debug_mode = FALSE;                                                        
  3080.  gp->local_mode = FALSE;                                                        
  3081.  bypass_startup = FALSE;                                                        
  3082.                                                                                 
  3083.  for (i = 1; i < argc; i++) {                                                   
  3084.    p = argv[i];                                                                 
  3085.    if (*p == '-') {                                                             
  3086.      while (*++p) {                                                             
  3087.        switch (toupper(*p)) {                                                   
  3088.          case 'T':  gp->test_mode  = TRUE;    break;                            
  3089.          case 'D':  gp->debug_mode = TRUE;    break;                            
  3090.          case 'L':  gp->local_mode = TRUE;    break;                            
  3091.          case 'Q':  bypass_startup = TRUE;    break;                            
  3092.          default: fprintf(stderr,"GGMVS: Bad parameter flag %c\n", *p);         
  3093.                   exit_return_code = 8;                                         
  3094.        }                                                                        
  3095.      }                                                                          
  3096.    }                                                                            
  3097.    else {                                                                       
  3098.      fprintf(stderr,"GGMVS: Bad parameter string %s\n",p);                      
  3099.      exit_return_code = 8;                                                      
  3100.    }                                                                            
  3101.  }                                                                              
  3102.                                                                                 
  3103.  if (gp->test_mode) __ctest(NULL);                                              
  3104.                                                                                 
  3105.  if (gp->debug_mode) {                                                          
  3106.    if (!(gp->debug_file = fopen(DEBUG_FILE,"w"))) {                             
  3107.      perror(DEBUG_FILE);                                                        
  3108.      exit_return_code = 4;                                                      
  3109.    }                                                                            
  3110.  }                                                                              
  3111.  else gp->debug_file = NULL;                                                    
  3112.                                                                                 
  3113.  gp->thdr.first_text_line = NULL;                                               
  3114.                                                                                 
  3115.  GGMclrtx(gp,NULL);               /* Clear text       */                        
  3116.  GGMclrtx(gp,ip);                 /* Clear text       */                        
  3117.                                                                                 
  3118.  sp = &gp->gopher_connection;                                                   
  3119.                                                                                 
  3120.  /* In the future these will be able to be set from gopherrc. */                
  3121.                                                                                 
  3122.  gp->myport   = SERV_TCP_PORT;                                                  
  3123.  gp->mytelnet = TELNET_COMMAND_NAME;                                            
  3124.  gp->mydomain = MY_DOMAIN_SUFFIX;                                               
  3125.                                                                                 
  3126.  /* Determine the local path name. Done in GGMCONN when needed now */           
  3127.                                                                                 
  3128.  strcpy(gp->ggserver,"");                                                       
  3129.  sp->connected_to_server   = FALSE;                                             
  3130.                                                                                 
  3131.  GETMAIN(sp->server_buf,    char,SERVER_BUF_MSGSIZE+4,"server buffer");         
  3132.  GETMAIN(sp->client_buf,    char,CLIENT_BUF_MSGSIZE+4,"client buffer");         
  3133.  GETMAIN(gp->gopher_command,char,CLIENT_BUF_MSGSIZE+4,"gopher command");        
  3134.                                                                                 
  3135. #ifdef FETCH                                                                    
  3136.                                                                                 
  3137.  gp->isplink_pointer = (int (*) ())fetch("ISPLINK");                            
  3138.  gp->ispexec_pointer = (int (*) ())fetch("ISPEXEC");                            
  3139.                                                                                 
  3140. #endif                                                                          
  3141.                                                                                 
  3142.  if (!GGMispf(gp,"CONTROL ERRORS RETURN")) exit_return_code = 20;               
  3143.                                                                                 
  3144.  else {                                                                         
  3145.                                                                                 
  3146.    exit_return_code = 0;                                                        
  3147.                                                                                 
  3148.    trap_ispf_command(gp,"RFIND","&YRFIND");  /* enable RFIND */                 
  3149.                                                                                 
  3150.    GGMsopt(gp,OPTION_ALL);      /* set options */                               
  3151.                                                                                 
  3152.    if (bypass_startup) {                                                        
  3153.      (void)GGMispf(gp,"VGET (GGHOST GGPATH GGDESC GGPORT) PROFILE");            
  3154.      (void)go_for_it(gp,ip);                                                    
  3155.    }                                                                            
  3156.    else {                                                                       
  3157.      (void)GGMivput(gp,"ZCMD "    ,"",-1);                                      
  3158.      while (GGMdispl(gp,"GGM     ") == 0                                        
  3159.          && !gp->quit                                                           
  3160.          && !go_for_it(gp,ip)) ;                                                
  3161.    }                                                                            
  3162.  }                                                                              
  3163.                                                                                 
  3164.  if (gp->setmsg) {                                                              
  3165.    (void)GGMivget(gp,"ZERRSM ",zerrsm, sizeof(zerrsm));                         
  3166.    (void)GGMivget(gp,"ZERRLM ",zerrlm, sizeof(zerrlm));                         
  3167.    fprintf(stderr,"%s: %s\n",zerrsm,zerrlm);                                    
  3168.    gp->setmsg = FALSE;                                                          
  3169.  }                                                                              
  3170.                                                                                 
  3171.  if (sp->connected_to_server) {                                                 
  3172.    GGMdisc(gp,sp);            /* disconnect from gopher server */               
  3173.  }                                                                              
  3174.                                                                                 
  3175.  FREEMAIN(gp->gopher_command,"gopher command");                                 
  3176.  FREEMAIN(sp->server_buf,    "server buffer");                                  
  3177.  FREEMAIN(sp->client_buf,    "client buffer");                                  
  3178.  FREEMAIN(gp->ginfo,         "top-level gopherinfo struct");                    
  3179.                                                                                 
  3180.  #define FINAL_CLOSE(A,B) \                                                     
  3181.    if (A) { \                                                                   
  3182.             if (fclose(A) < 0) fprintf(stderr,B); \                             
  3183.           }                                                                     
  3184.                                                                                 
  3185.  FINAL_CLOSE(gp->debug_file, "Error closing debug file\n");                     
  3186.                                                                                 
  3187.  exit(exit_return_code);                                                        
  3188. }                                                                               
  3189.                                                                                 
  3190. ./   ADD NAME=GGMALLOC                                                          
  3191.                                                                                 
  3192.  /********************************************************************/         
  3193.  /*                                                                  */         
  3194.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3195.  /*                                                                  */         
  3196.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3197.  /*                                                                  */         
  3198.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3199.  /* including the implied warranties of merchantability and fitness, */         
  3200.  /* are expressly denied.                                            */         
  3201.  /*                                                                  */         
  3202.  /* Provided this copyright notice is included, this software may    */         
  3203.  /* be freely distributed and not offered for sale.                  */         
  3204.  /*                                                                  */         
  3205.  /* Changes or modifications may be made and used only by the maker  */         
  3206.  /* of same, and not further distributed.  Such modifications should */         
  3207.  /* be mailed to the author for consideration for addition to the    */         
  3208.  /* software and incorporation in subsequent releases.               */         
  3209.  /*                                                                  */         
  3210.  /********************************************************************/         
  3211.                                                                                 
  3212. #pragma  csect(code,  "GG@ALLOC")                                               
  3213. #pragma  csect(static,"GG$ALLOC")                                               
  3214. #include "gg.h"                                                                 
  3215.                                                                                 
  3216. /****** Allocate a data set. *****************************************/         
  3217.                                                                                 
  3218. enum data_set_type                                                              
  3219. GGMalloc(dsname,ddname,wanted_type,nitems)                                      
  3220. char                      *dsname;                                              
  3221. char                      *ddname;                                              
  3222. enum data_set_type         wanted_type;                                         
  3223. int                        nitems;                                              
  3224. {                                                                               
  3225.  int                       i;                                                   
  3226.  int                       rc;                                                  
  3227.  char                     *cp;                                                  
  3228.  enum data_set_type        return_type;                                         
  3229.  Bool                      try_new;                                             
  3230.  short                     primary_allocation   ;                               
  3231.  short                     secondary_allocation ;                               
  3232.  short                     directory_blocks     ;                               
  3233.  short                     dsorg                ;                               
  3234.  __S99parms                stuff99; /* No "struct", despite manual */           
  3235.  TEXTUNIT                 *tu [17];                                             
  3236.  TEXTUNIT                  tu_dsn;                                              
  3237.  TEXTUNIT                  tu_ddn;                                              
  3238.  TEXTUNIT                  tu_member;                                           
  3239.  TEXTUNIT                  tu_stat;                                             
  3240.  TEXTUNIT                  tu_disp;                                             
  3241.  TEXTUNIT                  tu_perm;                                             
  3242.  TEXTUNIT                  tu_rtddn;                                            
  3243.  TEXTUNIT                  tu_rtorg;                                            
  3244.  TEXTUNIT                  tu_block;                                            
  3245.  TEXTUNIT                  tu_prime;                                            
  3246.  TEXTUNIT                  tu_sec;                                              
  3247.  TEXTUNIT                  tu_dir;                                              
  3248.  TEXTUNIT                  tu_recfm;                                            
  3249.  TEXTUNIT                  tu_lrecl;                                            
  3250.  TEXTUNIT                  tu_blksz;                                            
  3251.  TEXTUNIT                  tu_dsorg;                                            
  3252.  char                     *lparp;                                               
  3253.  char                     *rparp;                                               
  3254.  char                      dsnseq [81];                                         
  3255.  char                      member [81];                                         
  3256.  char                      what_to_open[81];                                    
  3257.  FILE                     *mfile;                                               
  3258.                                                                                 
  3259.  try_new = FALSE;                                                               
  3260.                                                                                 
  3261.  memset((char *)&stuff99,0,sizeof(__S99parms));                                 
  3262.                                                                                 
  3263.  strcpy(member,"");                                                             
  3264.  strcpy(dsnseq,dsname);                                                         
  3265.  lparp = strchr(dsnseq,'(');                                                    
  3266.  rparp = strchr(dsnseq,')');                                                    
  3267.  if (lparp && rparp && (lparp < rparp) && (*(rparp+1) == '\0')) {               
  3268.    *lparp = '\0';            /* makes dsnseq the seq part only */               
  3269.    *rparp = '\0';            /* turns member into a string     */               
  3270.    strcpy(member, lparp+1);                                                     
  3271.    wanted_type = PDS;                                                           
  3272.  }                                                                              
  3273.                                                                                 
  3274.  for (;;) {                                                                     
  3275.                                                                                 
  3276.    stuff99.__S99RBLN   = 20;                                                    
  3277.    stuff99.__S99VERB   = S99VRBAL;                                              
  3278.    stuff99.__S99FLAG1  = S99NOCNV << 8;                                         
  3279.    stuff99.__S99ERROR  = 0;                                                     
  3280.    stuff99.__S99INFO   = 0;                                                     
  3281.    stuff99.__S99TXTPP  = tu;                                                    
  3282.    stuff99.__S99FLAG2  = 0;                                                     
  3283.                                                                                 
  3284.    i = 0;                                                                       
  3285.                                                                                 
  3286.    tu[i++] = &tu_dsn;                                                           
  3287.                                                                                 
  3288.    tu_dsn.key        = DALDSNAM;                                                
  3289.    tu_dsn.num        = 1;                                                       
  3290.    tu_dsn.ent.len    = strlen(dsnseq);                                          
  3291.    strcpy(tu_dsn.ent.prm,dsnseq);                                               
  3292.    for (cp=tu_dsn.ent.prm; *cp; cp++) *cp = toupper(*cp);                       
  3293.                                                                                 
  3294.    tu[i++] = &tu_stat;                                                          
  3295.                                                                                 
  3296.    tu_stat.key      = DALSTATS;                                                 
  3297.    tu_stat.num      = 1;                                                        
  3298.    tu_stat.ent.len  = 1;                                                        
  3299.    *tu_stat.ent.prm = (try_new ? NEW : SHR);                                    
  3300.                                                                                 
  3301.    tu[i++] = &tu_disp;                                                          
  3302.                                                                                 
  3303.    tu_disp.key      = DALNDISP;                                                 
  3304.    tu_disp.num      = 1;                                                        
  3305.    tu_disp.ent.len  = 1;                                                        
  3306.    *tu_disp.ent.prm = (try_new ? CATLG : KEEP);                                 
  3307.                                                                                 
  3308.    tu[i++] = &tu_rtorg;                                                         
  3309.                                                                                 
  3310.    tu_rtorg.key     = DALRTORG;                                                 
  3311.    tu_rtorg.num     = 1;                                                        
  3312.    tu_rtorg.ent.len = 2;                                                        
  3313.                                                                                 
  3314.    if (*member) {                                                               
  3315.                                                                                 
  3316.      tu[i++] = &tu_member;                                                      
  3317.                                                                                 
  3318.      tu_member.key     = DALMEMBR;                                              
  3319.      tu_member.num     = 1;                                                     
  3320.      tu_member.ent.len = strlen(member);                                        
  3321.      strcpy(tu_member.ent.prm,member);                                          
  3322.      for (cp=tu_member.ent.prm; *cp; cp++) *cp = toupper(*cp);                  
  3323.                                                                                 
  3324.    }                                                                            
  3325.                                                                                 
  3326.    if (ddname && *ddname) {                                                     
  3327.                                                                                 
  3328.      tu[i++] = &tu_ddn;                                                         
  3329.                                                                                 
  3330.      tu_ddn.key     = DALDDNAM;                                                 
  3331.      tu_ddn.num     = 1;                                                        
  3332.      tu_ddn.ent.len = strlen(ddname);                                           
  3333.      strcpy(tu_ddn.ent.prm,ddname);                                             
  3334.      for (cp=tu_ddn.ent.prm; *cp; cp++) *cp = toupper(*cp);                     
  3335.                                                                                 
  3336.      tu[i++] = &tu_perm;                                                        
  3337.                                                                                 
  3338.      tu_perm.key     = DALPERMA;                                                
  3339.      tu_perm.num     = 0;                                                       
  3340.    }                                                                            
  3341.    else {                                                                       
  3342.                                                                                 
  3343.      tu[i++] = &tu_rtddn;                                                       
  3344.                                                                                 
  3345.      tu_rtddn.key     = DALRTDDN;                                               
  3346.      tu_rtddn.num     = 1;                                                      
  3347.      tu_rtddn.ent.len = 8;                                                      
  3348.      memset(tu_rtddn.ent.prm,' ',8);                                            
  3349.                                                                                 
  3350.    }                                                                            
  3351.                                                                                 
  3352.    if (try_new) {                                                               
  3353.                                                                                 
  3354.      switch (wanted_type) {                                                     
  3355.        case PDS:                                                                
  3356.                  primary_allocation   = (short)nitems;                          
  3357.                  secondary_allocation = primary_allocation;                     
  3358.                  directory_blocks     = ((short)nitems/(12*36)+1) * 36;         
  3359.                  dsorg                = DSORG_PO;                               
  3360.                  break;                                                         
  3361.        case SEQ:                                                                
  3362.        default:                                                                 
  3363.                  primary_allocation   = (short)nitems;                          
  3364.                  secondary_allocation = primary_allocation;                     
  3365.                  directory_blocks     = 0;                                      
  3366.                  dsorg                = DSORG_PS;                               
  3367.                  break;                                                         
  3368.      }                                                                          
  3369.                                                                                 
  3370.      tu[i++] = &tu_block;                                                       
  3371.                                                                                 
  3372.      tu_block.key     = DALBLKLN;                                               
  3373.      tu_block.num     = 1;                                                      
  3374.      tu_block.ent.len = 3;                                                      
  3375.      memset(tu_block.ent.prm,0,3);                                              
  3376.      *(short *)(tu_block.ent.prm+1) = 6233;                                     
  3377.                                                                                 
  3378.      tu[i++] = &tu_prime;                                                       
  3379.                                                                                 
  3380.      tu_prime.key     = DALPRIME;                                               
  3381.      tu_prime.num     = 1;                                                      
  3382.      tu_prime.ent.len = 3;                                                      
  3383.      memset(tu_prime.ent.prm,0,3);                                              
  3384.      *(short *)(tu_prime.ent.prm+1) = primary_allocation;                       
  3385.                                                                                 
  3386.      tu[i++] = &tu_sec;                                                         
  3387.                                                                                 
  3388.      tu_sec.key     = DALSECND;                                                 
  3389.      tu_sec.num     = 1;                                                        
  3390.      tu_sec.ent.len = 3;                                                        
  3391.      memset(tu_sec.ent.prm,0,3);                                                
  3392.      *(short *)(tu_sec.ent.prm+1) = secondary_allocation;                       
  3393.                                                                                 
  3394.      tu[i++] = &tu_dir;                                                         
  3395.                                                                                 
  3396.      tu_dir.key     = DALDIR;                                                   
  3397.      tu_dir.num     = 1;                                                        
  3398.      tu_dir.ent.len = 3;                                                        
  3399.      memset(tu_dir.ent.prm,0,3);                                                
  3400.      *(short *)(tu_dir.ent.prm+1) = directory_blocks;                           
  3401.                                                                                 
  3402.      tu[i++] = &tu_recfm;                                                       
  3403.                                                                                 
  3404.      tu_recfm.key        = DALRECFM;                                            
  3405.      tu_recfm.num        = 1;                                                   
  3406.      tu_recfm.ent.len    = 1;                                                   
  3407.      *tu_recfm.ent.prm   = RECFM_VB;                                            
  3408.                                                                                 
  3409.      tu[i++] = &tu_lrecl;                                                       
  3410.                                                                                 
  3411.      tu_lrecl.key        = DALLRECL;                                            
  3412.      tu_lrecl.num        = 1;                                                   
  3413.      tu_lrecl.ent.len    = 2;                                                   
  3414.      *(short *)tu_lrecl.ent.prm   = 259;                                        
  3415.                                                                                 
  3416.      tu[i++] = &tu_blksz;                                                       
  3417.                                                                                 
  3418.      tu_blksz.key        = DALBLKSZ;                                            
  3419.      tu_blksz.num        = 1;                                                   
  3420.      tu_blksz.ent.len    = 2;                                                   
  3421.      *(short *)tu_blksz.ent.prm   = 6233;                                       
  3422.                                                                                 
  3423.      tu[i++] = &tu_dsorg;                                                       
  3424.                                                                                 
  3425.      tu_dsorg.key        = DALDSORG;                                            
  3426.      tu_dsorg.num        = 1;                                                   
  3427.      tu_dsorg.ent.len    = 2;                                                   
  3428.      *(short *)tu_dsorg.ent.prm   = dsorg;                                      
  3429.                                                                                 
  3430.    }                                                                            
  3431.                                                                                 
  3432.    tu[i] = (void *)0x80000000;                                                  
  3433.                                                                                 
  3434.    rc = svc99(&stuff99);                                                        
  3435.                                                                                 
  3436.    if (rc == 0) {                                                               
  3437.      if (!(ddname && *ddname)) {                                                
  3438.        memcpy(ddname,(char *)tu_rtddn.ent.prm,8);                               
  3439.        *(ddname+8) = ' ';                                                       
  3440.        *(strchr(ddname,' ')) = '\0';                                            
  3441.      }                                                                          
  3442.      switch (tu_rtorg.ent.prm[0]) {                                             
  3443.        case 0x40:  return_type = SEQ; break;                                    
  3444.        case 0x02:  return_type = PDS; break;                                    
  3445.        default:    return_type = UNK; break;                                    
  3446.      }                                                                          
  3447.      if (wanted_type == SEQ && return_type != SEQ) {                            
  3448.        fprintf(stderr,"%s: not a sequential data set\n",dsname);                
  3449.      }                                                                          
  3450.      if (wanted_type == PDS && return_type != PDS) {                            
  3451.        fprintf(stderr,"%s: not a partitioned data set\n",dsname);               
  3452.      }                                                                          
  3453.      if (return_type == PDS && *member) return SEQ;                             
  3454.      else return return_type;                                                   
  3455.    }                                                                            
  3456.    else if (!try_new && nitems != 0 && stuff99.__S99ERROR == 0x1708) {          
  3457.     try_new = TRUE;                                                             
  3458.     continue;                                                                   
  3459.    }                                                                            
  3460.    else {                                                                       
  3461.      GGMdfail(rc,&stuff99);                                                     
  3462.      return UNK;                                                                
  3463.    }                                                                            
  3464.  }                                                                              
  3465. }                                                                               
  3466.                                                                                 
  3467. ./   ADD NAME=GGMCLRTX                                                          
  3468.                                                                                 
  3469.  /********************************************************************/         
  3470.  /*                                                                  */         
  3471.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3472.  /*                                                                  */         
  3473.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3474.  /*                                                                  */         
  3475.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3476.  /* including the implied warranties of merchantability and fitness, */         
  3477.  /* are expressly denied.                                            */         
  3478.  /*                                                                  */         
  3479.  /* Provided this copyright notice is included, this software may    */         
  3480.  /* be freely distributed and not offered for sale.                  */         
  3481.  /*                                                                  */         
  3482.  /* Changes or modifications may be made and used only by the maker  */         
  3483.  /* of same, and not further distributed.  Such modifications should */         
  3484.  /* be mailed to the author for consideration for addition to the    */         
  3485.  /* software and incorporation in subsequent releases.               */         
  3486.  /*                                                                  */         
  3487.  /********************************************************************/         
  3488.                                                                                 
  3489. #pragma  csect(code,  "GG@CLRTX")                                               
  3490. #pragma  csect(static,"GG$CLRTX")                                               
  3491. #include "gg.h"                                                                 
  3492.                                                                                 
  3493. /****** Clear text. **************************************************/         
  3494.                                                                                 
  3495. void                                                                            
  3496. GGMclrtx(gp,ip)                                                                 
  3497. Rstruc ggcb           *gp;                                                      
  3498. Rstruc gopherinfo     *ip;                                                      
  3499.                                                                                 
  3500. {                                                                               
  3501.  Rstruc texthdr       *thp;                                                     
  3502.  Rstruc textline      *tp1;                                                     
  3503.  Rstruc textline      *tp2;                                                     
  3504.                                                                                 
  3505.  /* If info is not specified, use main ggcb, else info's text */                
  3506.                                                                                 
  3507.  thp = (ip ? &ip->thdr : &gp->thdr);                                            
  3508.                                                                                 
  3509.  tp1=thp->first_text_line;                                                      
  3510.  while (tp1) {                                                                  
  3511.   tp2 = tp1->next;                                                              
  3512.   FREEMAIN(tp1,"text line");                                                    
  3513.   tp1 = tp2;                                                                    
  3514.  }                                                                              
  3515.                                                                                 
  3516.  thp->text_body_line    = NULL;                                                 
  3517.  thp->first_text_line   = NULL;                                                 
  3518.  thp->current_text_line = NULL;                                                 
  3519.  thp->last_text_line    = NULL;                                                 
  3520.  thp->text_line_count   = 0;                                                    
  3521.  thp->text_max_length   = 0;                                                    
  3522.  thp->text_max_tab_expanded_length   = 0;                                       
  3523.                                                                                 
  3524.  return;                                                                        
  3525.                                                                                 
  3526. }                                                                               
  3527.                                                                                 
  3528. ./   ADD NAME=GGMCONN,SSI=010D0021                                              
  3529.                                                                                 
  3530.  /********************************************************************/         
  3531.  /*                                                                  */         
  3532.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3533.  /*                                                                  */         
  3534.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3535.  /*                                                                  */         
  3536.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3537.  /* including the implied warranties of merchantability and fitness, */         
  3538.  /* are expressly denied.                                            */         
  3539.  /*                                                                  */         
  3540.  /* Provided this copyright notice is included, this software may    */         
  3541.  /* be freely distributed and not offered for sale.                  */         
  3542.  /*                                                                  */         
  3543.  /* Changes or modifications may be made and used only by the maker  */         
  3544.  /* of same, and not further distributed.  Such modifications should */         
  3545.  /* be mailed to the author for consideration for addition to the    */         
  3546.  /* software and incorporation in subsequent releases.               */         
  3547.  /*                                                                  */         
  3548.  /********************************************************************/         
  3549.                                                                                 
  3550. #pragma  csect(code,  "GG@CONN ")                                               
  3551. #pragma  csect(static,"GG$CONN ")                                               
  3552. #include "gg.h"                                                                 
  3553.                                                                                 
  3554. /****** Internet address formatter. **********************************/         
  3555.                                                                                 
  3556. static void                                                                     
  3557. format_ip_address(ia,is)                                                        
  3558. IPADDRESS   ia;                                                                 
  3559. char       *is;                                                                 
  3560. {                                                                               
  3561.  char *cp = (char *)&ia;                                                        
  3562.                                                                                 
  3563.  sprintf(is,"%d.%d.%d.%d",*cp,*(cp+1),*(cp+2),*(cp+3));                         
  3564.  return;                                                                        
  3565. }                                                                               
  3566.                                                                                 
  3567. /****** Get client hostname and IP address. **************************/         
  3568.                                                                                 
  3569. static Bool                                                                     
  3570. get_client_hostname(gp)                                                         
  3571. Rstruc ggcb        *gp;                                                         
  3572. {                                                                               
  3573.  struct hostent    *client_hp;                                                  
  3574.  int                gethostnamerc;                                              
  3575.  int                hostlen;                                                    
  3576.  int                domslen;                                                    
  3577.                                                                                 
  3578.  gethostnamerc = gethostname(gp->client_hostname,MAXHOSTNAMELEN);               
  3579.  if (gethostnamerc < 0) {                                                       
  3580.    fprintf(stderr,"GGMVS: gethostname() failed, don't know my name\n");         
  3581.    return FALSE;                                                                
  3582.  }                                                                              
  3583.                                                                                 
  3584. #ifdef APPEND_DOMAIN_NAME_TO_SELF                                               
  3585.                                                                                 
  3586.  hostlen = strlen(gp->client_hostname);                                         
  3587.  domslen = strlen(gp->mydomain);                                                
  3588.  if (hostlen <= domslen ||                                                      
  3589.     memcmp(gp->client_hostname+hostlen-domslen,gp->mydomain,domslen)) {         
  3590.    strncat(gp->client_hostname,gp->mydomain,domslen);                           
  3591.  }                                                                              
  3592.                                                                                 
  3593. #endif                                                                          
  3594.                                                                                 
  3595.  uppercase_in_place(gp->client_hostname);                                       
  3596.                                                                                 
  3597.  client_hp = gethostbyname(gp->client_hostname);                                
  3598.  if (!client_hp) {                                                              
  3599.    fprintf(stderr,                                                              
  3600.            "GGMCONN: gethostbyname(%s) failed, can't get my name\n",            
  3601.            gp->client_hostname);                                                
  3602.    return FALSE;                                                                
  3603.  }                                                                              
  3604.                                                                                 
  3605.  strcpy(gp->ggclient,gp->client_hostname);                                      
  3606.  strcpy(gp->client_hostname, client_hp->h_name);                                
  3607.  gp->client_ip_address = *(IPADDRESS *)client_hp->h_addr;                       
  3608.                                                                                 
  3609.  return TRUE ;                                                                  
  3610.                                                                                 
  3611. }                                                                               
  3612.                                                                                 
  3613. /****** Connect to news server. **************************************/         
  3614.                                                                                 
  3615. Bool                                                                            
  3616. GGMconn(gp,sp)                                                                  
  3617. Rstruc ggcb        *gp;                                                         
  3618. Rstruc connection  *sp;                                                         
  3619. {                                                                               
  3620.  char              *lp;                                                         
  3621.  char              *cp;                                                         
  3622.  struct recvstruct *R;                                                          
  3623.  struct hostent    *server_hp;                                                  
  3624.  struct sockaddr_in bindsock;       /* socket used by bind           */         
  3625.  struct sockaddr_in consock;        /* socket used by connect        */         
  3626.  int                bindsocklen;    /* size of bind socket           */         
  3627.  int                consocklen;     /* size of connect socket        */         
  3628.  int                bindrc;         /* the return code from bind     */         
  3629.  int                connrc;         /* the return code from connect  */         
  3630.  int                ip_part_1;                                                  
  3631.  int                ip_part_2;                                                  
  3632.  int                ip_part_3;                                                  
  3633.  int                ip_part_4;                                                  
  3634.  char               tempdsn[L_tmpnam];                                          
  3635.                                                                                 
  3636.  if (sp->connected_to_server) {                                                 
  3637.    GGMdisc(gp,sp);         /* Disconnect from gopher server */                  
  3638.  }                                                                              
  3639.                                                                                 
  3640.  sp->closing_connection = FALSE;                                                
  3641.  sp->buf_index          = -1;                                                   
  3642.  sp->bytes_returned     = 0;                                                    
  3643.  sp->receiving_text     = FALSE;                                                
  3644.                                                                                 
  3645.  if (!*gp->ggserver) {                                                          
  3646.    ERR1(                                                                        
  3647.   "No host server defined in Gopher menu,  Cannot make a connection."           
  3648.        );                                                                       
  3649.    return FALSE;                                                                
  3650.  }                                                                              
  3651.                                                                                 
  3652.  uppercase_in_place(gp->ggserver);                                              
  3653.                                                                                 
  3654.  /* If server is "local hack", then establish local mode,                       
  3655.   * open temporary file and return.                                             
  3656.   */                                                                            
  3657.                                                                                 
  3658.  if (!strcmp(gp->ggserver, LOCAL_HOST_FROB)) {                                  
  3659.                                                                                 
  3660.    if (gp->ginfo->port != GOPHER_PORT_NUMBER) {                                 
  3661.      ERR3("Server name %s is permitted only with port number %d.",              
  3662.           LOCAL_HOST_FROB, GOPHER_PORT_NUMBER);                                 
  3663.      return FALSE;                                                              
  3664.    }                                                                            
  3665.                                                                                 
  3666.    GETMAIN(gp->recvp, struct recvstruct, 1, "local recv struct");               
  3667.    if (!gp->recvp) {                                                            
  3668.      CRIT1("Can't get memory for local host struct");                           
  3669.      return FALSE;                                                              
  3670.    }                                                                            
  3671.    R = gp->recvp;                                                               
  3672.    memset(R, 0, sizeof(struct recvstruct));                                     
  3673.                                                                                 
  3674.    R->myport   = gp->myport;                                                    
  3675.    R->mytelnet = gp->mytelnet;                                                  
  3676.    R->mydomain = gp->mydomain;                                                  
  3677.                                                                                 
  3678.    if (!tmpnam(tempdsn)) {                                                      
  3679.      CRIT1("Can't create temporary file for local access");                     
  3680.      return FALSE;                                                              
  3681.    }                                                                            
  3682.                                                                                 
  3683.    /* Create temporary file for writing and reading. */                         
  3684.                                                                                 
  3685.    R->outfp = fopen(tempdsn,"w+,type=memory");                                  
  3686.    if (!R->outfp) {                                                             
  3687.      perror(tempdsn);                                                           
  3688.      CRIT1("Can't open temporary file for local access");                       
  3689.      return FALSE;                                                              
  3690.    }                                                                            
  3691.                                                                                 
  3692.    sp->connected_to_server = TRUE;                                              
  3693.    sp->time_to_go_home     = FALSE;                                             
  3694.    sp->connection_broken   = FALSE;                                             
  3695.                                                                                 
  3696.    GGMesrvr(gp,sp);                                                             
  3697.                                                                                 
  3698.    return TRUE;                                                                 
  3699.  }                                                                              
  3700.                                                                                 
  3701.  /* Disallow network connections if started up in local mode. */                
  3702.                                                                                 
  3703.  if (gp->local_mode) {                                                          
  3704.    ERR1("Network connections are not allowed in local mode.");                  
  3705.    return FALSE;                                                                
  3706.  }                                                                              
  3707.                                                                                 
  3708.  /* Determine the local path name. Do only if making net conn. */               
  3709.                                                                                 
  3710.  if (!*gp->client_hostname) {                                                   
  3711.                                                                                 
  3712.    if (!get_client_hostname(gp)) return FALSE;                                  
  3713.                                                                                 
  3714.  }                                                                              
  3715.                                                                                 
  3716.  /* Get server name and address.  */                                            
  3717.                                                                                 
  3718.  if (strchr(gp->ggserver,'.') &&                                                
  3719.      gp->ggserver[strspn(gp->ggserver,".0123456789")] == '\0') {                
  3720.    ip_part_1 = ip_part_2 = ip_part_3 = ip_part_4 = 32767;                       
  3721.    strcpy(gp->server_hostname, gp->ggserver);                                   
  3722.    sscanf(gp->ggserver,"%d.%d.%d.%d",&ip_part_1,                                
  3723.                                      &ip_part_2,                                
  3724.                                      &ip_part_3,                                
  3725.                                      &ip_part_4);                               
  3726.    if (ip_part_1 > 255 ||                                                       
  3727.        ip_part_2 > 255 ||                                                       
  3728.        ip_part_3 > 255 ||                                                       
  3729.        ip_part_4 > 255) {                                                       
  3730.      ERR2("Syntax error in server network address: %s", gp->ggserver);          
  3731.      return FALSE;                                                              
  3732.    }                                                                            
  3733.    gp->server_ip_address = (IPADDRESS) ((ip_part_1 << 24) +                     
  3734.                                         (ip_part_2 << 16) +                     
  3735.                                         (ip_part_3 <<  8) +                     
  3736.                                         (ip_part_4      ));                     
  3737.  }                                                                              
  3738.  else {                                                                         
  3739.    server_hp = gethostbyname(gp->ggserver);                                     
  3740.    if (!server_hp) {                                                            
  3741.      ERR2(                                                                      
  3742. "Unknown host %s - gethostbyname() could not resolve the server name.",         
  3743.           gp->ggserver);                                                        
  3744.      return FALSE;                                                              
  3745.    }                                                                            
  3746.    strcpy(gp->server_hostname, server_hp->h_name);                              
  3747.    gp->server_ip_address = *(IPADDRESS *)server_hp->h_addr;                     
  3748.  }                                                                              
  3749.                                                                                 
  3750.  format_ip_address(gp->server_ip_address, gp->server_ip_addrstr);               
  3751.  format_ip_address(gp->client_ip_address, gp->client_ip_addrstr);               
  3752.                                                                                 
  3753.  (void)GGMivput(gp,"GGSERVER ",gp->ggserver,-1);                                
  3754.  (void)GGMivput(gp,"GGSERVIP ",gp->server_ip_addrstr,-1);                       
  3755.  (void)GGMivput(gp,"GGCLIENT ",gp->ggclient,-1);                                
  3756.  (void)GGMivput(gp,"GGCLIEIP ",gp->client_ip_addrstr,-1);                       
  3757.                                                                                 
  3758.  consock.sin_family       = AF_INET;                                            
  3759.  consock.sin_port         = htons(gp->ginfo->port);                             
  3760.  consock.sin_addr.s_addr  = gp->server_ip_address;                              
  3761.                                                                                 
  3762.  bindsock.sin_family      = AF_INET;                                            
  3763.  bindsock.sin_port        = 0;                                                  
  3764. #ifdef SNSTCPIP                                                                 
  3765.  bindsock.sin_addr.s_addr = INADDR_ANY;                                         
  3766. #else                                                                           
  3767.  bindsock.sin_addr.s_addr = gp->client_ip_address;                              
  3768. #endif                                                                          
  3769.                                                                                 
  3770.  sp->ns = socket(AF_INET, SOCK_STREAM, 0);                                      
  3771.  if (sp->ns < 0) {                                                              
  3772.    REPORT_TCP_ERROR(gp->ggserver);                                              
  3773.    ERR2("TCP/IP error: socket() failed to make socket for server %s.",          
  3774.         gp->ggserver);                                                          
  3775.    return FALSE;                                                                
  3776.  }                                                                              
  3777.                                                                                 
  3778.  bindsocklen = sizeof(bindsock);                                                
  3779.  bindrc = Bind(sp->ns, &bindsock, bindsocklen);                                 
  3780.  if (bindrc < 0) {                                                              
  3781.    REPORT_TCP_ERROR(gp->ggserver);                                              
  3782.    ERR2("TCP/IP error: bind() failed to bind socket for server %s.",            
  3783.         gp->ggserver);                                                          
  3784.    return FALSE;                                                                
  3785.  }                                                                              
  3786.                                                                                 
  3787.  (void)GGMispf(gp,"CONTROL DISPLAY LOCK");                                      
  3788.  (void)GGMispf(gp,"DISPLAY PANEL(GGMLCONN)");                                   
  3789.                                                                                 
  3790.  if (gp->debug_file) {                                                          
  3791.    fprintf(gp->debug_file,                                                      
  3792.            "Client %s (%s) connecting to GOPHER server on %s (%s)\n",           
  3793.            gp->client_hostname,                                                 
  3794.            gp->client_ip_addrstr,                                               
  3795.            gp->server_hostname,                                                 
  3796.            gp->server_ip_addrstr);                                              
  3797.  }                                                                              
  3798.                                                                                 
  3799.  consocklen = sizeof(consock);                                                  
  3800.  connrc = Connect(sp->ns, &consock, consocklen);                                
  3801.                                                                                 
  3802.  if (connrc < 0) {                                                              
  3803.    REPORT_TCP_ERROR(gp->ggserver);                                              
  3804.    ERR2("TCP/IP failure: connect() failed to connect to server %s.",            
  3805.         gp->ggserver);                                                          
  3806.    return FALSE;                                                                
  3807.  }                                                                              
  3808.                                                                                 
  3809.  sp->connected_to_server = TRUE;                                                
  3810.  sp->time_to_go_home     = FALSE;                                               
  3811.  sp->connection_broken   = FALSE;                                               
  3812.  sp->server_has_something_pending = TRUE;                                       
  3813.  sp->dont_read           = FALSE;                                               
  3814.                                                                                 
  3815.  /* Clean up any stray responses from server. */                                
  3816.                                                                                 
  3817.  GGMesrvr(gp,sp);                         /* End server read */                 
  3818.                                                                                 
  3819.  return TRUE;                                                                   
  3820.                                                                                 
  3821. }                                                                               
  3822.                                                                                 
  3823. ./   ADD NAME=GGMCSO,SSI=01000026                                               
  3824.                                                                                 
  3825.  /********************************************************************/         
  3826.  /*                                                                  */         
  3827.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3828.  /*                                                                  */         
  3829.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3830.  /*                                                                  */         
  3831.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3832.  /* including the implied warranties of merchantability and fitness, */         
  3833.  /* are expressly denied.                                            */         
  3834.  /*                                                                  */         
  3835.  /* Provided this copyright notice is included, this software may    */         
  3836.  /* be freely distributed and not offered for sale.                  */         
  3837.  /*                                                                  */         
  3838.  /* Changes or modifications may be made and used only by the maker  */         
  3839.  /* of same, and not further distributed.  Such modifications should */         
  3840.  /* be mailed to the author for consideration for addition to the    */         
  3841.  /* software and incorporation in subsequent releases.               */         
  3842.  /*                                                                  */         
  3843.  /********************************************************************/         
  3844.                                                                                 
  3845. #pragma  csect(code,  "GG@CSO")                                                 
  3846. #pragma  csect(static,"GG$CSO")                                                 
  3847. #include "gg.h"                                                                 
  3848.                                                                                 
  3849. /****** Gopher CSO interface. ************************************/             
  3850.                                                                                 
  3851. Bool                                                                            
  3852. GGMcso(gp,ip,as_file)                                                           
  3853. Rstruc ggcb        *gp;                                                         
  3854. Rstruc gopherinfo  *ip;                                                         
  3855. Fool                as_file;        /* ignored */                               
  3856. {                                                                               
  3857.  Rstruc connection *sp;                                                         
  3858.  char              *lp;                                                         
  3859.  Bool               got_some;                                                   
  3860.  char               ggcsoq[256];                                                
  3861.  int                e_index_i;                                                  
  3862.  char               e_index_c[10];                                              
  3863.  char               sep[80] = "--------------------";                           
  3864.                                                                                 
  3865.  sp = &gp->gopher_connection;                                                   
  3866.                                                                                 
  3867.  strcpy(gp->ggserver,ip->host);     /* Specify server to connect to */          
  3868.                                                                                 
  3869.  strcpy(ggcsoq,"");                                                             
  3870.                                                                                 
  3871.  GGMispf(gp,"VGET (GGCSOQ) PROFILE");                                           
  3872.                                                                                 
  3873.  if (GGMdispl(gp,"GGMPCSO ") > 0) return FALSE;                                 
  3874.                                                                                 
  3875.  GGMivget(gp,"GGCSOQ ",ggcsoq, sizeof(ggcsoq));                                 
  3876.                                                                                 
  3877.  /***** set up query command to server ****** start ******************/         
  3878.                                                                                 
  3879.  strcpy(gp->gopher_command,"query ");                                           
  3880.  if (!*ip->path)                                                                
  3881.      strcpy(gp->gopher_command + 6, ggcsoq);                                    
  3882.  else                                                                           
  3883.      sprintf(gp->gopher_command + 6,"%s\t%s",ip->path,ggcsoq);                  
  3884.  strcat(gp->gopher_command," return all");                                      
  3885.                                                                                 
  3886.  /***** set up query command to server ****** end   ******************/         
  3887.                                                                                 
  3888.  gp->ginfo = ip;                                                                
  3889.                                                                                 
  3890.  if (!GGMconn(gp,sp)) return FALSE;   /* Connect to CSO server */               
  3891.                                                                                 
  3892.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  3893.                                                                                 
  3894.  GGMclrtx(gp,ip);                  /* Clear text */                             
  3895.                                                                                 
  3896.  sp->receiving_text = TRUE;                                                     
  3897.  got_some = FALSE;                                                              
  3898.  e_index_i = 2;                                                                 
  3899.  sprintf(e_index_c,":%u:",e_index_i);                                           
  3900.  do {                                                                           
  3901.    if (GGMgsrvl(gp,sp,&lp,FALSE)) {        /* Get server line */                
  3902.      if (lp) {                                                                  
  3903.        if (strstr(lp,e_index_c) != NULL) { /* if new entry */                   
  3904.          (void)GGMouttx(gp,sep,ip);        /* Output separator */               
  3905.          ++e_index_i;                      /* Increment index  */               
  3906.          sprintf(e_index_c,":%u:",e_index_i);                                   
  3907.        }                                                                        
  3908.        got_some = TRUE;                                                         
  3909.        (void)GGMouttx(gp,lp,ip);          /* Output text line */                
  3910.        if (lp[0] != '-' && strncmp(lp,"200",3) >= 0) break;                     
  3911.      }                                                                          
  3912.    }                                                                            
  3913.  } while (lp);                            /* until no more lines */             
  3914.                                                                                 
  3915.  if (!got_some) {                                                               
  3916.    WARN2("No data available from server %s.\n",gp->ggserver);                   
  3917.    return FALSE;                                                                
  3918.  }                                                                              
  3919.                                                                                 
  3920.  /* Send quit command        */                                                 
  3921.                                                                                 
  3922.  sp->receiving_text = FALSE;                                                    
  3923.                                                                                 
  3924.  strcpy(gp->gopher_command,"quit");                                             
  3925.                                                                                 
  3926.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  3927.                                                                                 
  3928.  /* Read Bye message         */                                                 
  3929.                                                                                 
  3930.  sp->receiving_text = TRUE;                                                     
  3931.                                                                                 
  3932.  (void)GGMgsrvl(gp,sp,&lp,FALSE);         /* Get server line */                 
  3933.                                                                                 
  3934.  if (sp->connected_to_server) {                                                 
  3935.    (void)GGMdisc(gp,sp);   /* Disconnect from CSO server */                     
  3936.  }                                                                              
  3937.                                                                                 
  3938.  GGMvtx(gp,ip,as_file);  /* display text from CSO server */                     
  3939.                                                                                 
  3940.  return TRUE;                                                                   
  3941.                                                                                 
  3942. }                                                                               
  3943.                                                                                 
  3944. ./   ADD NAME=GGMDBM,SSI=01050050                                               
  3945.                                                                                 
  3946.  /********************************************************************/         
  3947.  /*                                                                  */         
  3948.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3949.  /*                                                                  */         
  3950.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3951.  /*                                                                  */         
  3952.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3953.  /* including the implied warranties of merchantability and fitness, */         
  3954.  /* are expressly denied.                                            */         
  3955.  /*                                                                  */         
  3956.  /* Provided this copyright notice is included, this software may    */         
  3957.  /* be freely distributed and not offered for sale.                  */         
  3958.  /*                                                                  */         
  3959.  /* Changes or modifications may be made and used only by the maker  */         
  3960.  /* of same, and not further distributed.  Such modifications should */         
  3961.  /* be mailed to the author for consideration for addition to the    */         
  3962.  /* software and incorporation in subsequent releases.               */         
  3963.  /*                                                                  */         
  3964.  /********************************************************************/         
  3965.                                                                                 
  3966. #pragma  csect(code,  "GG@DBM  ")                                               
  3967. #pragma  csect(static,"GG$DBM  ")                                               
  3968. #include "gg.h"                                                                 
  3969.                                                                                 
  3970. /****** Delete a bookmark from a bookmark data set. ******************/         
  3971.                                                                                 
  3972. Bool                                                                            
  3973. GGMdbm(gp,ip)                                                                   
  3974. Rstruc ggcb         *gp;                                                        
  3975. Rstruc gopherinfo   *ip;                                                        
  3976. {                                                                               
  3977.  FILE               *xfp;                                                       
  3978.  char               *bufptr;                                                    
  3979.  char                test   [  6];                                              
  3980.  char                dsname [129];                                              
  3981.  char                buffer [RBUFSIZE];                                         
  3982.                                                                                 
  3983.  if (!*ip->bmds) {                                                              
  3984.    WARN1("Delete not possible.  This entry is not from a bookmark.");           
  3985.    return FALSE;                                                                
  3986.  }                                                                              
  3987.                                                                                 
  3988.  GGMivput(gp,"GGMDBMDS ",ip->bmds,-1);                                          
  3989.  GGMivput(gp,"GGMDBMSU ",ip->desc,-1);                                          
  3990.                                                                                 
  3991.  (void)GGMispf(gp,"ADDPOP");                                                    
  3992.                                                                                 
  3993.  if (GGMdispl(gp,"GGMPDBM ") > 0) {                                             
  3994.    WARN1("Deletion cancelled, because you pressed END.");                       
  3995.    (void)GGMispf(gp,"REMPOP");                                                  
  3996.    return FALSE;                                                                
  3997.  }                                                                              
  3998.                                                                                 
  3999.  (void)GGMispf(gp,"REMPOP");                                                    
  4000.                                                                                 
  4001.  sprintf(dsname,"'%s'",ip->bmds);                                               
  4002.  xfp = fopen(dsname,"r");                                                       
  4003.  if (!xfp) {                                                                    
  4004.    perror(dsname);                                                              
  4005.    ERR2("Cannot access bookmark data set %s.",dsname);                          
  4006.    return FALSE;                                                                
  4007.  }                                                                              
  4008.                                                                                 
  4009.                                                                                 
  4010.  for (;;) {                                                                     
  4011.    *buffer = '\0';                                                              
  4012.    fgets(buffer,sizeof(buffer),xfp);                                            
  4013.    if (ferror(xfp)) {                                                           
  4014.      ERR2("Error reading bookmark data set %s.",dsname);                        
  4015.      break;                                                                     
  4016.    }                                                                            
  4017.    if (feof(xfp)) break;                                                        
  4018.    if ((bufptr=strchr(buffer,'\n'))) *bufptr = '\0';                            
  4019.    bufptr = skip_whitespace(buffer);                                            
  4020.    memset(test,0,sizeof(test));                                                 
  4021.    memcpy(test,bufptr,5);                                                       
  4022.    uppercase_in_place(test);                                                    
  4023.                                                                                 
  4024.    /*                                                                           
  4025.    if      (EQUAL(test,"TYPE="))                                                
  4026.    else if (EQUAL(test,"NAME="))                                                
  4027.    else if (EQUAL(test,"PATH="))                                                
  4028.    else if (EQUAL(test,"HOST="))                                                
  4029.    else if (EQUAL(test,"PORT="))                                                
  4030.    else if (EQUAL(test,"END"  ))                                                
  4031.                                                                                 
  4032.    */                                                                           
  4033.                                                                                 
  4034.  }                                                                              
  4035.                                                                                 
  4036.  (void)fclose(xfp);                                                             
  4037.                                                                                 
  4038.  ERR1("Bookmark deletion is not yet supported, sorry.");                        
  4039.  return FALSE;                                                                  
  4040.                                                                                 
  4041. }                                                                               
  4042.                                                                                 
  4043. ./   ADD NAME=GGMDFAIL                                                          
  4044.                                                                                 
  4045.  /********************************************************************/         
  4046.  /*                                                                  */         
  4047.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4048.  /*                                                                  */         
  4049.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4050.  /*                                                                  */         
  4051.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4052.  /* including the implied warranties of merchantability and fitness, */         
  4053.  /* are expressly denied.                                            */         
  4054.  /*                                                                  */         
  4055.  /* Provided this copyright notice is included, this software may    */         
  4056.  /* be freely distributed and not offered for sale.                  */         
  4057.  /*                                                                  */         
  4058.  /* Changes or modifications may be made and used only by the maker  */         
  4059.  /* of same, and not further distributed.  Such modifications should */         
  4060.  /* be mailed to the author for consideration for addition to the    */         
  4061.  /* software and incorporation in subsequent releases.               */         
  4062.  /*                                                                  */         
  4063.  /********************************************************************/         
  4064.                                                                                 
  4065. #pragma  csect(code,  "GG@DFAIL")                                               
  4066. #pragma  csect(static,"GG$DFAIL")                                               
  4067. #include "gg.h"                                                                 
  4068.                                                                                 
  4069. /****** Retrieve allocation failure messages. ************************/         
  4070.                                                                                 
  4071. void                                                                            
  4072. GGMdfail(rc,p99)                                                                
  4073. int            rc;                                                              
  4074. __S99parms    *p99;                                                             
  4075. {                                                                               
  4076.  int           zero = 0;                                                        
  4077.  unsigned int  dfid = 0x40320000;                                               
  4078.  struct {                                                                       
  4079.          short first_level_msg_len;                                             
  4080.          short first_level_msg_offset;                                          
  4081.          char  first_level_msg[251];                                            
  4082.          short second_level_msg_len;                                            
  4083.          short second_level_msg_offset;                                         
  4084.          char  second_level_msg[251];                                           
  4085.         }      dfbuffer;                                                        
  4086.                                                                                 
  4087.  static int (*ikjeff18_pointer)() = NULL;                                       
  4088.                                                                                 
  4089. #ifndef FETCH                                                                   
  4090.  extern int *ikjeff18();                                                        
  4091. #endif                                                                          
  4092.                                                                                 
  4093.  if (!ikjeff18_pointer) {                                                       
  4094. #ifdef FETCH                                                                    
  4095.    ikjeff18_pointer = (int (*)())fetch("IKJEFF18");                             
  4096. #else                                                                           
  4097.    ikjeff18_pointer = (int (*)())ikjeff18;                                      
  4098. #endif                                                                          
  4099.  }                                                                              
  4100.                                                                                 
  4101.  dfbuffer.first_level_msg_len = 4;                                              
  4102.  dfbuffer.second_level_msg_len = 4;                                             
  4103.                                                                                 
  4104.  if (ikjeff18_pointer) {                                                        
  4105.    if ((*ikjeff18_pointer)(p99,&rc,&zero,&dfid,&zero,&dfbuffer)) {              
  4106.      fprintf(stderr,"IKJEFF18 returned a nonzero return code\n");               
  4107.    }                                                                            
  4108.    if (dfbuffer.first_level_msg_len > 0) {                                      
  4109.      fprintf(stderr,"%*.*s\n",                                                  
  4110.                     dfbuffer.first_level_msg_len-4,                             
  4111.                     dfbuffer.first_level_msg_len-4,                             
  4112.                     dfbuffer.first_level_msg);                                  
  4113.    }                                                                            
  4114.    if (dfbuffer.second_level_msg_len > 0) {                                     
  4115.      fprintf(stderr,"%*.*s\n",                                                  
  4116.                     dfbuffer.second_level_msg_len-4,                            
  4117.                     dfbuffer.second_level_msg_len-4,                            
  4118.                     dfbuffer.second_level_msg);                                 
  4119.    }                                                                            
  4120.  }                                                                              
  4121.  else {                                                                         
  4122. #ifdef FETCH                                                                    
  4123.    fprintf(stderr,"GGMVS: Cannot fetch IKJEFF18\n");                            
  4124. #else                                                                           
  4125.    fprintf(stderr,"Cannot call IKJEFF18, not linked with GGMVS\n");             
  4126. #endif                                                                          
  4127.  }                                                                              
  4128.  return;                                                                        
  4129. }                                                                               
  4130.                                                                                 
  4131. ./   ADD NAME=GGMDIR,SSI=010E0028                                               
  4132.                                                                                 
  4133.  /********************************************************************/         
  4134.  /*                                                                  */         
  4135.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4136.  /*                                                                  */         
  4137.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4138.  /*                                                                  */         
  4139.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4140.  /* including the implied warranties of merchantability and fitness, */         
  4141.  /* are expressly denied.                                            */         
  4142.  /*                                                                  */         
  4143.  /* Provided this copyright notice is included, this software may    */         
  4144.  /* be freely distributed and not offered for sale.                  */         
  4145.  /*                                                                  */         
  4146.  /* Changes or modifications may be made and used only by the maker  */         
  4147.  /* of same, and not further distributed.  Such modifications should */         
  4148.  /* be mailed to the author for consideration for addition to the    */         
  4149.  /* software and incorporation in subsequent releases.               */         
  4150.  /*                                                                  */         
  4151.  /********************************************************************/         
  4152.                                                                                 
  4153. #pragma  csect(code,  "GG@DIR  ")                                               
  4154. #pragma  csect(static,"GG$DIR  ")                                               
  4155. #include "gg.h"                                                                 
  4156.                                                                                 
  4157. /*********************************************************************/         
  4158.                                                                                 
  4159. static Bool                                                                     
  4160. valid_code(c)                                                                   
  4161. char       c;                                                                   
  4162. {                                                                               
  4163.                                                                                 
  4164.  switch (c) {                                                                   
  4165.    case GOPHER_FILE:                                                            
  4166.    case GOPHER_DIRECTORY:                                                       
  4167.    case GOPHER_TELNET:                                                          
  4168.    case GOPHER_TN3270:                                                          
  4169.    case GOPHER_WAIS:                                                            
  4170.    case GOPHER_WHOIS:                                                           
  4171.    case GOPHER_CSO:                                                             
  4172.                            return TRUE;                                         
  4173.    default:                return FALSE;                                        
  4174.   }                                                                             
  4175.                                                                                 
  4176. }                                                                               
  4177.                                                                                 
  4178. /*********************************************************************/         
  4179.                                                                                 
  4180. static Bool                                                                     
  4181. process_s_selection(gp,ip)                                                      
  4182. Rstruc ggcb           *gp;                                                      
  4183. Rstruc gopherinfo     *ip;                                                      
  4184. {                                                                               
  4185.                                                                                 
  4186.  GGMgofor(gp,ip,FALSE);                                                         
  4187.                                                                                 
  4188.  return TRUE;                                                                   
  4189. }                                                                               
  4190.                                                                                 
  4191. /*********************************************************************/         
  4192.                                                                                 
  4193. static Bool                                                                     
  4194. process_i_selection(gp,ip)                                                      
  4195. Rstruc ggcb           *gp;                                                      
  4196. Rstruc gopherinfo     *ip;                                                      
  4197. {                                                                               
  4198.                                                                                 
  4199.  if (!GGMinfo(gp,ip)) return FALSE;                                             
  4200.                                                                                 
  4201.  GGMvtx(gp,NULL,TRUE);                                                          
  4202.                                                                                 
  4203.  return TRUE;                                                                   
  4204. }                                                                               
  4205.                                                                                 
  4206. /*********************************************************************/         
  4207.                                                                                 
  4208. static Bool                                                                     
  4209. process_b_selection(gp,ip)                                                      
  4210. Rstruc ggcb           *gp;                                                      
  4211. Rstruc gopherinfo     *ip;                                                      
  4212. {                                                                               
  4213.                                                                                 
  4214.  if (!GGMinfo(gp,ip)) return FALSE;                                             
  4215.                                                                                 
  4216.  gp->extract_file = NULL;                                                       
  4217.                                                                                 
  4218.  GGMxtx(gp,ip,BOOKMARK_IT);                                                     
  4219.                                                                                 
  4220.  return TRUE;                                                                   
  4221. }                                                                               
  4222.                                                                                 
  4223. /*********************************************************************/         
  4224.                                                                                 
  4225. static Bool                                                                     
  4226. process_d_selection(gp,ip)                                                      
  4227. Rstruc ggcb           *gp;                                                      
  4228. Rstruc gopherinfo     *ip;                                                      
  4229. {                                                                               
  4230.                                                                                 
  4231.  return GGMdbm(gp,ip);                                                          
  4232. }                                                                               
  4233.                                                                                 
  4234. /*********************************************************************/         
  4235.                                                                                 
  4236. static Bool                                                                     
  4237. process_e_selection(gp,ip)                                                      
  4238. Rstruc ggcb           *gp;                                                      
  4239. Rstruc gopherinfo     *ip;                                                      
  4240. {                                                                               
  4241.                                                                                 
  4242.  gp->extract_file = NULL;                                                       
  4243.                                                                                 
  4244.  if (ip->thdr.first_text_line) {                                                
  4245.    GGMxtx(gp,ip,EXTRACT_IT);                                                    
  4246.    return TRUE;                                                                 
  4247.  }                                                                              
  4248.  else {                                                                         
  4249.    ERR1("Extract must be preceded by Select.");                                 
  4250.    return FALSE;                                                                
  4251.  }                                                                              
  4252. }                                                                               
  4253.                                                                                 
  4254. /*********************************************************************/         
  4255.                                                                                 
  4256. static Bool                                                                     
  4257. process_p_selection(gp,ip)                                                      
  4258. Rstruc ggcb           *gp;                                                      
  4259. Rstruc gopherinfo     *ip;                                                      
  4260. {                                                                               
  4261.                                                                                 
  4262.  gp->extract_file = NULL;                                                       
  4263.                                                                                 
  4264.  if (ip->thdr.first_text_line) {                                                
  4265.    GGMxtx(gp,ip,PRINT_IT);                                                      
  4266.    return TRUE;                                                                 
  4267.  }                                                                              
  4268.  else {                                                                         
  4269.    ERR1("Print must be preceded by Select.");                                   
  4270.    return FALSE;                                                                
  4271.  }                                                                              
  4272. }                                                                               
  4273.                                                                                 
  4274. /*********************************************************************/         
  4275.                                                                                 
  4276. static Bool                                                                     
  4277. process_q_selection(gp,ip)                                                      
  4278. Rstruc ggcb           *gp;                                                      
  4279. Rstruc gopherinfo     *ip;                                                      
  4280. {                                                                               
  4281.                                                                                 
  4282.  GGMgofor(gp,ip,TRUE);                                                          
  4283.                                                                                 
  4284.  return TRUE;                                                                   
  4285. }                                                                               
  4286.                                                                                 
  4287. /*********************************************************************/         
  4288.                                                                                 
  4289. static Bool                                                                     
  4290. display_dynamic_area(gp,ip,infoarray,entrycount)                                
  4291. Rstruc ggcb           *gp;                                                      
  4292. Rstruc gopherinfo     *ip;                                                      
  4293. Rstruc gopherinfo     *infoarray;                                               
  4294. int                    entrycount;                                              
  4295. {                                                                               
  4296.  struct gopherinfo    *iap;                                                     
  4297.  int                   depth;                                                   
  4298.  int                   ggglvl;                                                  
  4299.  int                   dynsize;                                                 
  4300.  int                   topitem;                                                 
  4301.  int                   bottomitem;                                              
  4302.  int                   last_item_selected;                                      
  4303.  int                   dti;                                                     
  4304.  int                   gii;                                                     
  4305.  int                   l;                                                       
  4306.  int                   prc;                                                     
  4307.  int                   command_index;                                           
  4308.  int                   zscrolln;                                                
  4309.  Bool                  selection_processed_ok;                                  
  4310.  Bool                  command_processed_ok;                                    
  4311.  Bool                  is_max;                                                  
  4312.  char                 *gggdyna;                                                 
  4313.  char                 *rowp;                                                    
  4314.  char                 *cp;                                                      
  4315.  char                  gggcmd     [72];                                         
  4316.  char                  zverb       [9];                                         
  4317.  char                  zscrolla    [9];                                         
  4318.  char                  command    [COMMANDSIZE];                                
  4319.  char                  ggghead    [81];                                         
  4320.  char                  rowmessage [81];                                         
  4321.                                                                                 
  4322.  /* Get depth of dynamic area (number of rows to display on screen) */          
  4323.                                                                                 
  4324.  (void)GGMispf(gp,                                                              
  4325.        "PQUERY PANEL(GGMDIR) AREANAME(GGGDYNA) DEPTH(GGGDEPTH)");               
  4326.  if (gp->ispfrc != 0) return FALSE;                                             
  4327.  depth = GGMiget(gp,"GGGDEPTH ");                                               
  4328.                                                                                 
  4329.  /* Get storage for ISPF dynamic area variable to be constructed. */            
  4330.                                                                                 
  4331.  dynsize = 80*depth;                                                            
  4332.  GETMAIN(gggdyna, char, dynsize+1, "GGGDYNA buffer");                           
  4333.  if (!gggdyna) return FALSE;                                                    
  4334.                                                                                 
  4335.  /* Loop displaying the panel until END pressed. */                             
  4336.                                                                                 
  4337.  topitem = 0;                                                                   
  4338.  last_item_selected = -1;                                                       
  4339.  strcpy(gggcmd,"");                                                             
  4340.                                                                                 
  4341.  do {                                                                           
  4342.                                                                                 
  4343.  /* Fill in the dynamic area with rows, one for each gopher item. */            
  4344.                                                                                 
  4345.    memset(gggdyna,' ',dynsize);                                                 
  4346.                                                                                 
  4347.    for (dti = 0,       gii = topitem,     rowp = gggdyna;                       
  4348.         dti < depth && gii < entrycount;                                        
  4349.         dti++,         gii++,             rowp += 80) {                         
  4350.      iap = &infoarray[gii];                                                     
  4351.      rowp[ 0] = DATAIN_HIGH;             /* selection code attribute */         
  4352.      rowp[ 1] = ' ';                     /* selection code field     */         
  4353.      rowp[ 2] = DATAOUT_GREEN;           /* icon attribute           */         
  4354.      memcpy(&rowp[ 3],GGMtype(iap->type),9);                                    
  4355.      rowp[12] = DATAOUT_HIGH;            /* description attribute    */         
  4356.      l = strlen(iap->desc);                                                     
  4357.      memcpy(&rowp[13],iap->desc,l > 67 ? 67 : l);                               
  4358.    }                                                                            
  4359.                                                                                 
  4360.    if (rowp < gggdyna + dynsize) {                                              
  4361.      rowp[0] = DATAOUT_HIGH;                                                    
  4362.      memset(&rowp[1], '-',79);                                                  
  4363.    }                                                                            
  4364.                                                                                 
  4365.    bottomitem = gii - 1;                                                        
  4366.                                                                                 
  4367.    if (topitem > bottomitem) strcpy(rowmessage,"");                             
  4368.    else sprintf(rowmessage, " %d-%d of %d",                                     
  4369.                        topitem + 1, bottomitem + 1, entrycount);                
  4370.                                                                                 
  4371.    memset(ggghead,' ',79);                                                      
  4372.    ggghead[79] = '\0';                                                          
  4373.    strcpy(ggghead,"GOPHER - ");                                                 
  4374.    strncpy(ggghead+9,ip->desc,70);                                              
  4375.    *strchr(ggghead,'\0') = ' ';                                                 
  4376.    memcpy(ggghead+79-strlen(rowmessage),rowmessage,strlen(rowmessage));         
  4377.                                                                                 
  4378.    (void)GGMivput(gp,"GGGHEAD ",ggghead,79);                                    
  4379.    (void)GGMivput(gp,"GGGDYNA ",gggdyna, dynsize);                              
  4380.    (void)GGMivput(gp,"GGGCMD " ,gggcmd,  -1);                                   
  4381.                                                                                 
  4382.    prc = GGMdispl(gp,"GGMDIR  ");                                               
  4383.    if (prc > 8) break;                                                          
  4384.                                                                                 
  4385.    (void)GGMivget(gp,"GGGDYNA " , gggdyna,  dynsize);                           
  4386.    (void)GGMivget(gp,"ZVERB "   , zverb,    sizeof(zverb));                     
  4387.    (void)GGMivget(gp,"ZSCROLLA ", zscrolla, sizeof(zscrolla));                  
  4388.    zscrolln = GGMiget(gp,"ZSCROLLN ");                                          
  4389.    ggglvl   = GGMiget(gp,"GGGLVL ");                                            
  4390.    last_item_selected = -1;                                                     
  4391.                                                                                 
  4392.    /* Process selections. */                                                    
  4393.                                                                                 
  4394.    for (gii = topitem,         rowp = gggdyna;                                  
  4395.         gii <= bottomitem;                                                      
  4396.         gii++,                 rowp += 80) {                                    
  4397.      iap = &infoarray[gii];                                                     
  4398.      switch (toupper(rowp[1])) {                                                
  4399.        case ' ':  continue;                                                     
  4400.        case 'S':  selection_processed_ok = process_s_selection(gp,iap);         
  4401.                   break;                                                        
  4402.        case 'E':  selection_processed_ok = process_e_selection(gp,iap);         
  4403.                   break;                                                        
  4404.        case 'P':  selection_processed_ok = process_p_selection(gp,iap);         
  4405.                   break;                                                        
  4406.        case 'Q':  selection_processed_ok = process_q_selection(gp,iap);         
  4407.                   break;                                                        
  4408.        case 'I':  selection_processed_ok = process_i_selection(gp,iap);         
  4409.                   break;                                                        
  4410.        case 'B':  selection_processed_ok = process_b_selection(gp,iap);         
  4411.                   break;                                                        
  4412.    /*                                                                           
  4413.     *  case 'D':  selection_processed_ok = process_d_selection(gp,iap);         
  4414.     *             break;                                                        
  4415.     */                                                                          
  4416.        default:                                                                 
  4417.         ERR1("Unknown selection code.  Type one of the listed codes.");         
  4418.                   selection_processed_ok = FALSE;                               
  4419.                   break;                                                        
  4420.      }                                                                          
  4421.      if (selection_processed_ok) last_item_selected = gii;                      
  4422.      if (gp->quit) break;                                                       
  4423.    }                                                                            
  4424.                                                                                 
  4425.    /* Process command if any. */                                                
  4426.                                                                                 
  4427.    strcpy(gggcmd,"");                                                           
  4428.                                                                                 
  4429.    (void)GGMivget(gp,"GGGCMD ",gggcmd,sizeof(gggcmd));                          
  4430.                                                                                 
  4431.    if (*gggcmd) {                                                               
  4432.                                                                                 
  4433.      command_processed_ok = TRUE;                                               
  4434.      memset(command,' ',COMMANDSIZE);                                           
  4435.      command_index = 0;                                                         
  4436.      for (cp = gggcmd; *cp && !isspace(*cp); cp++) {                            
  4437.        if (cp >= gggcmd+COMMANDSIZE) {                                          
  4438.        ERR1("Invalid command.  Try \"MENU bookmarkname\" or \"QUIT\"");         
  4439.          command_processed_ok = FALSE;                                          
  4440.        }                                                                        
  4441.        command[command_index++] = toupper(*cp);                                 
  4442.      }                                                                          
  4443.      while (*cp && isspace(*cp)) cp++;                                          
  4444.                                                                                 
  4445.      if      (!memcmp(command,"QUIT    ",8)) gp->quit = TRUE;                   
  4446.      else if (!memcmp(command,"MENU    ",8)) GGMmenu(gp,cp);                    
  4447.      else {                                                                     
  4448.        ERR1("Unknown command.  Try \"MENU bookmarkname\" or \"QUIT\"");         
  4449.        command_processed_ok = FALSE;                                            
  4450.      }                                                                          
  4451.                                                                                 
  4452.      if (command_processed_ok) strcpy(gggcmd,"");                               
  4453.                                                                                 
  4454.    }                                                                            
  4455.                                                                                 
  4456.    if (gp->quit) break;                                                         
  4457.                                                                                 
  4458.    if (last_item_selected >= 0 && gp->autoscroll) {                             
  4459.      topitem = last_item_selected;                                              
  4460.    }                                                                            
  4461.                                                                                 
  4462.    /* Process scroll request if any. */                                         
  4463.                                                                                 
  4464.    is_max = EQUAL(zscrolla,"MAX");                                              
  4465.    if      (EQUAL(zverb,"DOWN")) {                                              
  4466.      if (is_max) topitem = entrycount - ggglvl;                                 
  4467.      else        topitem += zscrolln;                                           
  4468.    }                                                                            
  4469.    else if (EQUAL(zverb,"UP")) {                                                
  4470.      if (is_max) topitem = 0;                                                   
  4471.      else        topitem -= zscrolln;                                           
  4472.    }                                                                            
  4473.    else if (EQUAL(zverb,"RETURN")) {                                            
  4474.      gp->quit = TRUE;                                                           
  4475.      break;                                                                     
  4476.    }                                                                            
  4477.    if (topitem < 0)                                                             
  4478.        topitem = 0;                                                             
  4479.    if (topitem > entrycount)                                                    
  4480.        topitem = entrycount;                                                    
  4481.                                                                                 
  4482.  } while (prc == 0);                                                            
  4483.                                                                                 
  4484.  return;                                                                        
  4485.                                                                                 
  4486. }                                                                               
  4487.                                                                                 
  4488. /****** Gopher a directory. ******************************************/         
  4489.                                                                                 
  4490. Bool                                                                            
  4491. GGMdir(gp,ip,as_file)                                                           
  4492. Rstruc ggcb        *gp;                                                         
  4493. Rstruc gopherinfo  *ip;                                                         
  4494. Fool                as_file;                                                    
  4495. {                                                                               
  4496.  int                entrycount;                                                 
  4497.  int                i;                                                          
  4498.  int                copysize;                                                   
  4499.  char               typechar;                                                   
  4500.  char               savechar;                                                   
  4501.  char              *p;                                                          
  4502.  char              *q;                                                          
  4503.  char              *r;                                                          
  4504.  struct textline   *tp;                                                         
  4505.  struct gopherinfo *infoarray;                                                  
  4506.  struct gopherinfo *iap;                                                        
  4507.  char               temp[16];                                                   
  4508.                                                                                 
  4509.  if (as_file) {                                                                 
  4510.    GGMvtx(gp,ip,as_file);  /* if as a file, display text as is */               
  4511.    return TRUE;                                                                 
  4512.  }                                                                              
  4513.                                                                                 
  4514.  /* The text chain contains the data from the server, which should be           
  4515.   * in the following format:                                                    
  4516.   *                                                                             
  4517.   * nDescription^Path^foo^bar                                                   
  4518.   *                                                                             
  4519.   * where the "n" in the beginning is a digit and ^ means a tab char.           
  4520.   *                                                                             
  4521.   * Logic:                                                                      
  4522.   *                                                                             
  4523.   * Build an array of gopherinfo structs from the text records.                 
  4524.   *                                                                             
  4525.   * Display them as an ISPF dynamic area pseudotable.                           
  4526.   *                                                                             
  4527.   * Let the user select them, and run GGMgofor on each one                      
  4528.   * with a struct gopherinfo built from the contents.                           
  4529.   *                                                                             
  4530.   */                                                                            
  4531.                                                                                 
  4532.  /* Determine size of array of gopherinfo structs.  This is equal to            
  4533.   * the number of text records with a valid code in the first byte.             
  4534.   */                                                                            
  4535.                                                                                 
  4536.  entrycount = 0;                                                                
  4537.  for (tp = ip->thdr.first_text_line; tp; tp = tp->next) {                       
  4538.    if (valid_code(tp->text[0])) entrycount++;                                   
  4539.  }                                                                              
  4540.                                                                                 
  4541.  if (entrycount == 0) {                                                         
  4542.    ERR1("There seems to be no information in this directory.\n");               
  4543.    return FALSE;                                                                
  4544.  }                                                                              
  4545.                                                                                 
  4546.  /* Allocate an array of structs to hold the stuff. */                          
  4547.                                                                                 
  4548.  GETMAIN(infoarray, struct gopherinfo, entrycount,"gopherinfo array");          
  4549.                                                                                 
  4550.  if (!infoarray) {                                                              
  4551.    ERR2("Not enough memory for %d gopher directory entries\n",                  
  4552.         entrycount);                                                            
  4553.    return FALSE;                                                                
  4554.  }                                                                              
  4555.                                                                                 
  4556.  /* Build the array entries. */                                                 
  4557.                                                                                 
  4558.  iap = infoarray;                                                               
  4559.  for (tp = ip->thdr.first_text_line; tp; tp = tp->next) {                       
  4560.    typechar = tp->text[0];                                                      
  4561.    if (valid_code(typechar)) {                                                  
  4562.      r = &tp->text[tp->text_length];                                            
  4563.      savechar = *r;                                                             
  4564.      *r = '\t';                                                                 
  4565.      memset(iap,0,sizeof(struct gopherinfo));                                   
  4566.      iap->port = GOPHER_PORT_NUMBER;                                            
  4567.      iap->type = (gophertype)typechar;                                          
  4568.      p = &tp->text[1];                                                          
  4569.      q = strchr(p,'\t');                                                        
  4570.      copysize = sizeof(iap->desc)-1;                                            
  4571.      if (copysize > q-p) copysize = q-p;                                        
  4572.      memcpy(iap->desc,p,copysize);                                              
  4573.      if (q < r) {                                                               
  4574.        p = q+1;                                                                 
  4575.        q = strchr(p,'\t');                                                      
  4576.        copysize = sizeof(iap->path)-1;                                          
  4577.        if (copysize > q-p) copysize = q-p;                                      
  4578.        memcpy(iap->path,p,copysize);                                            
  4579.        if (q < r) {                                                             
  4580.          p = q+1;                                                               
  4581.          q = strchr(p,'\t');                                                    
  4582.          copysize = sizeof(iap->host)-1;                                        
  4583.          if (copysize > q-p) copysize = q-p;                                    
  4584.          memcpy(iap->host,p,copysize);                                          
  4585.          if (q < r) {                                                           
  4586.            p = q+1;                                                             
  4587.            q = strchr(p,'\t');                                                  
  4588.            memset(temp,0,sizeof(temp));                                         
  4589.            copysize = sizeof(temp)-1;                                           
  4590.            if (copysize > q-p) copysize = q-p;                                  
  4591.            memcpy(temp,p,copysize);                                             
  4592.            iap->port = atoi(temp);                                              
  4593.          }                                                                      
  4594.        }                                                                        
  4595.      }                                                                          
  4596.                                                                                 
  4597.      strcpy(iap->bmds,gp->current_bookmark_ds);                                 
  4598.                                                                                 
  4599.      *r = savechar;                                                             
  4600.      iap++;                                                                     
  4601.    }                                                                            
  4602.  }                                                                              
  4603.                                                                                 
  4604.  if (gp->debug_mode) {                                                          
  4605.    for (iap = infoarray, i = entrycount; i > 0; iap++, i--) {                   
  4606.      fprintf(gp->debug_file,"GGMdir: type = %d\n",iap->type);                   
  4607.      fprintf(gp->debug_file,"GGMdir: port = %d\n",iap->port);                   
  4608.      fprintf(gp->debug_file,"GGMdir: path = %s\n",iap->path);                   
  4609.      fprintf(gp->debug_file,"GGMdir: host = %s\n",iap->host);                   
  4610.      fprintf(gp->debug_file,"GGMdir: desc = %s\n",iap->desc);                   
  4611.      fprintf(gp->debug_file,"GGMdir: bmds = %s\n",iap->bmds);                   
  4612.      fprintf(gp->debug_file,"\n");                                              
  4613.    }                                                                            
  4614.  }                                                                              
  4615.                                                                                 
  4616.  display_dynamic_area(gp,ip,infoarray,entrycount);                              
  4617.                                                                                 
  4618.  FREEMAIN(infoarray,"gopherinfo array");                                        
  4619.                                                                                 
  4620.  return TRUE;                                                                   
  4621. }                                                                               
  4622.                                                                                 
  4623. ./   ADD NAME=GGMDISC                                                           
  4624.                                                                                 
  4625.  /********************************************************************/         
  4626.  /*                                                                  */         
  4627.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4628.  /*                                                                  */         
  4629.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4630.  /*                                                                  */         
  4631.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4632.  /* including the implied warranties of merchantability and fitness, */         
  4633.  /* are expressly denied.                                            */         
  4634.  /*                                                                  */         
  4635.  /* Provided this copyright notice is included, this software may    */         
  4636.  /* be freely distributed and not offered for sale.                  */         
  4637.  /*                                                                  */         
  4638.  /* Changes or modifications may be made and used only by the maker  */         
  4639.  /* of same, and not further distributed.  Such modifications should */         
  4640.  /* be mailed to the author for consideration for addition to the    */         
  4641.  /* software and incorporation in subsequent releases.               */         
  4642.  /*                                                                  */         
  4643.  /********************************************************************/         
  4644.                                                                                 
  4645. #pragma  csect(code,  "GG@DISC ")                                               
  4646. #pragma  csect(static,"GG$DISC ")                                               
  4647. #include "gg.h"                                                                 
  4648.                                                                                 
  4649. /****** Disconnect from gopher server. ********************************/        
  4650.                                                                                 
  4651. void                                                                            
  4652. GGMdisc(gp,sp)                                                                  
  4653. Rstruc ggcb        *gp;                                                         
  4654. Rstruc connection  *sp;                                                         
  4655. {                                                                               
  4656.  int                closerc;                                                    
  4657.  struct recvstruct *R;                                                          
  4658.                                                                                 
  4659.  /* If local mode, close temporary file and return. */                          
  4660.                                                                                 
  4661.  if ((R=gp->recvp)) {                                                           
  4662.    if (R->outfp) {                                                              
  4663.      if (fclose(R->outfp) < 0) {                                                
  4664.        CRIT1("Error closing local mode temporary file");                        
  4665.      }                                                                          
  4666.      R->outfp = NULL;                                                           
  4667.    }                                                                            
  4668.                                                                                 
  4669.    sp->connected_to_server   = FALSE;                                           
  4670.                                                                                 
  4671.    FREEMAIN(gp->recvp,"local mode recv struct");                                
  4672.    gp->recvp = NULL;                                                            
  4673.    return;                                                                      
  4674.  }                                                                              
  4675.                                                                                 
  4676.  sp->reconnect_in_progress = FALSE;                                             
  4677.  sp->closing_connection    = TRUE;                                              
  4678.                                                                                 
  4679.  if (sp->connection_broken) {                                                   
  4680.    if (gp->debug_file) {                                                        
  4681.      fprintf(gp->debug_file,                                                    
  4682.   "Client %s (%s) connection with gopher server on %s (%s) was lost\n",         
  4683.           gp->client_hostname,                                                  
  4684.           gp->client_ip_addrstr,                                                
  4685.           gp->server_hostname,                                                  
  4686.           gp->server_ip_addrstr);                                               
  4687.    }                                                                            
  4688.    sp->connected_to_server   = FALSE;                                           
  4689.  }                                                                              
  4690.  else {                                                                         
  4691.                                                                                 
  4692.    /* In case of some kind of protocol error, don't let things hang. */         
  4693.                                                                                 
  4694.    GGMesrvr(gp,sp);         /* End server read */                               
  4695.                                                                                 
  4696.    if (gp->debug_file) {                                                        
  4697.      fprintf(gp->debug_file,                                                    
  4698.       "Client %s (%s) disconnecting from gopher server on %s (%s)\n",           
  4699.           gp->client_hostname,                                                  
  4700.           gp->client_ip_addrstr,                                                
  4701.           gp->server_hostname,                                                  
  4702.           gp->server_ip_addrstr);                                               
  4703.    }                                                                            
  4704.                                                                                 
  4705.    (void)GGMivput(gp,"GGSOLDER ",gp->server_hostname,-1);                       
  4706.    (void)GGMivput(gp,"GGSOLDIP ",gp->server_ip_addrstr,-1);                     
  4707.    (void)GGMispf(gp,"CONTROL DISPLAY LOCK");                                    
  4708.    (void)GGMispf(gp,"DISPLAY PANEL(GGMLDISC)");                                 
  4709.                                                                                 
  4710.    /* In case of some kind of protocol error, don't let things hang. */         
  4711.                                                                                 
  4712.    GGMesrvr(gp,sp);                   /* End server read */                     
  4713.                                                                                 
  4714.    sp->connected_to_server   = FALSE;                                           
  4715.                                                                                 
  4716.    TCP_DEBUG_ON;                                                                
  4717.    closerc = close(sp->ns);                                                     
  4718.    TCP_DEBUG_OFF;                                                               
  4719.                                                                                 
  4720.    if (closerc < 0) {                                                           
  4721.      ERR2("TCP/IP error: close() failed to disconnect from server %s.",         
  4722.           gp->ggserver);                                                        
  4723.    }                                                                            
  4724.  }                                                                              
  4725.                                                                                 
  4726.  return;                                                                        
  4727. }                                                                               
  4728.                                                                                 
  4729. ./   ADD NAME=GGMDISPL                                                          
  4730.                                                                                 
  4731.  /********************************************************************/         
  4732.  /*                                                                  */         
  4733.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4734.  /*                                                                  */         
  4735.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4736.  /*                                                                  */         
  4737.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4738.  /* including the implied warranties of merchantability and fitness, */         
  4739.  /* are expressly denied.                                            */         
  4740.  /*                                                                  */         
  4741.  /* Provided this copyright notice is included, this software may    */         
  4742.  /* be freely distributed and not offered for sale.                  */         
  4743.  /*                                                                  */         
  4744.  /* Changes or modifications may be made and used only by the maker  */         
  4745.  /* of same, and not further distributed.  Such modifications should */         
  4746.  /* be mailed to the author for consideration for addition to the    */         
  4747.  /* software and incorporation in subsequent releases.               */         
  4748.  /*                                                                  */         
  4749.  /********************************************************************/         
  4750.                                                                                 
  4751.  /********************************************************************/         
  4752.                                                                                 
  4753. #pragma  csect(code,  "GG@DISPL")                                               
  4754. #pragma  csect(static,"GG$DISPL")                                               
  4755. #include "gg.h"                                                                 
  4756.                                                                                 
  4757. #ifdef FETCH                                                                    
  4758. #define VL_BIT(X) ((unsigned int)(X) | 0x80000000)                              
  4759. #else                                                                           
  4760. #define VL_BIT(X) (X)                                                           
  4761. #endif                                                                          
  4762.                                                                                 
  4763. /****** Display ISPF panel. ******************************************/         
  4764.                                                                                 
  4765. int                                                                             
  4766. GGMdispl(gp,pan8)                                                               
  4767. Rstruc ggcb    *gp;                                                             
  4768. char           *pan8;                                                           
  4769. {                                                                               
  4770.                                                                                 
  4771.  if (gp->setmsg) {                                                              
  4772.    gp->ispfrc = ISPLINK("DISPLAY ", pan8, VL_BIT("ISRZ002 "));                  
  4773.  }                                                                              
  4774.  else {                                                                         
  4775.    gp->ispfrc = ISPLINK("DISPLAY ", VL_BIT(pan8));                              
  4776.  }                                                                              
  4777.                                                                                 
  4778.  if (gp->ispfrc > 8) GGMierr(gp);   /* display ISPF error */                    
  4779.                                                                                 
  4780.  gp->setmsg = FALSE;                                                            
  4781.                                                                                 
  4782.  return gp->ispfrc;                                                             
  4783. }                                                                               
  4784.                                                                                 
  4785. ./   ADD NAME=GGMDUMP                                                           
  4786.                                                                                 
  4787.  /********************************************************************/         
  4788.  /*                                                                  */         
  4789.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4790.  /*                                                                  */         
  4791.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4792.  /*                                                                  */         
  4793.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4794.  /* including the implied warranties of merchantability and fitness, */         
  4795.  /* are expressly denied.                                            */         
  4796.  /*                                                                  */         
  4797.  /* Provided this copyright notice is included, this software may    */         
  4798.  /* be freely distributed and not offered for sale.                  */         
  4799.  /*                                                                  */         
  4800.  /* Changes or modifications may be made and used only by the maker  */         
  4801.  /* of same, and not further distributed.  Such modifications should */         
  4802.  /* be mailed to the author for consideration for addition to the    */         
  4803.  /* software and incorporation in subsequent releases.               */         
  4804.  /*                                                                  */         
  4805.  /********************************************************************/         
  4806.                                                                                 
  4807. #pragma  csect(code,  "GG@DUMP ")                                               
  4808. #pragma  csect(static,"GG$DUMP ")                                               
  4809. #include "gg.h"                                                                 
  4810.                                                                                 
  4811. /****** Dump some data. **********************************************/         
  4812.                                                                                 
  4813. void                                                                            
  4814. GGMdump(struct ggcb *gp, char *label, char *p,int r)                            
  4815. {                                                                               
  4816.  int i;                                                                         
  4817.                                                                                 
  4818.  if (!gp->debug_file) return;                                                   
  4819.                                                                                 
  4820.  if (r == -2) {                                                                 
  4821.    fprintf(gp->debug_file,"%s:  %d\n",label,(int)p);                            
  4822.    return;                                                                      
  4823.  }                                                                              
  4824.                                                                                 
  4825.  if (r == -1) r = strlen(p);                                                    
  4826.                                                                                 
  4827.  fprintf(gp->debug_file,"%s:   (%d characters)\n",label,r);                     
  4828.  for (i=0;i<77;i++) fprintf(gp->debug_file,"-");                                
  4829.  fprintf(gp->debug_file,"\n");                                                  
  4830.  for (i=0;i<r;i++) {                                                            
  4831.    char c = *(p+i);                                                             
  4832.    if (isprint(c))  fprintf(gp->debug_file,"%c",c);                             
  4833.    else             fprintf(gp->debug_file,"<0x%2.2x>",c);                      
  4834.  }                                                                              
  4835.  fprintf(gp->debug_file,"\n");                                                  
  4836.  for (i=0;i<77;i++) fprintf(gp->debug_file,"-");                                
  4837.  fprintf(gp->debug_file,"\n");                                                  
  4838.                                                                                 
  4839.  return;                                                                        
  4840.                                                                                 
  4841. }                                                                               
  4842.                                                                                 
  4843. ./   ADD NAME=GGMESRVR                                                          
  4844.                                                                                 
  4845.  /********************************************************************/         
  4846.  /*                                                                  */         
  4847.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4848.  /*                                                                  */         
  4849.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4850.  /*                                                                  */         
  4851.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4852.  /* including the implied warranties of merchantability and fitness, */         
  4853.  /* are expressly denied.                                            */         
  4854.  /*                                                                  */         
  4855.  /* Provided this copyright notice is included, this software may    */         
  4856.  /* be freely distributed and not offered for sale.                  */         
  4857.  /*                                                                  */         
  4858.  /* Changes or modifications may be made and used only by the maker  */         
  4859.  /* of same, and not further distributed.  Such modifications should */         
  4860.  /* be mailed to the author for consideration for addition to the    */         
  4861.  /* software and incorporation in subsequent releases.               */         
  4862.  /*                                                                  */         
  4863.  /********************************************************************/         
  4864.                                                                                 
  4865. #pragma  csect(code,  "GG@ESRVR")                                               
  4866. #pragma  csect(static,"GG$ESRVR")                                               
  4867. #include "gg.h"                                                                 
  4868.                                                                                 
  4869. /****** End server read. *********************************************/         
  4870.                                                                                 
  4871. void                                                                            
  4872. GGMesrvr(gp,sp)                                                                 
  4873. Rstruc ggcb       *gp;                                                          
  4874. Rstruc connection *sp;                                                          
  4875. {                                                                               
  4876.  char             *lp;                                                          
  4877.  Bool              found_more_server_data = FALSE;                              
  4878.                                                                                 
  4879.  GGMclrtx(gp,NULL);                    /* Clear text */                         
  4880.                                                                                 
  4881.  if (gp->recvp) return;                /* Skip if non-socket */                 
  4882.                                                                                 
  4883.  do {                                                                           
  4884.                                                                                 
  4885.    if (GGMgsrvl(gp,sp,&lp,FALSE)) {    /* Get server line */                    
  4886.      if (lp) {                                                                  
  4887.        found_more_server_data = TRUE;                                           
  4888.        (void)GGMouttx(gp,lp,NULL);     /* Output text line */                   
  4889.      }                                                                          
  4890.    }                                                                            
  4891.                                                                                 
  4892.  } while (lp);                                                                  
  4893.                                                                                 
  4894.  if (found_more_server_data) {                                                  
  4895.    ERR1(                                                                        
  4896. "More data was returned by the GOPHER server than GOPHER expected."             
  4897.        );                                                                       
  4898.    GGMvtx(gp,NULL,TRUE);              /* View text */                           
  4899.  }                                                                              
  4900.                                                                                 
  4901.  return;                                                                        
  4902. }                                                                               
  4903.                                                                                 
  4904. ./   ADD NAME=GGMFREEM                                                          
  4905.                                                                                 
  4906.  /********************************************************************/         
  4907.  /*                                                                  */         
  4908.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4909.  /*                                                                  */         
  4910.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4911.  /*                                                                  */         
  4912.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4913.  /* including the implied warranties of merchantability and fitness, */         
  4914.  /* are expressly denied.                                            */         
  4915.  /*                                                                  */         
  4916.  /* Provided this copyright notice is included, this software may    */         
  4917.  /* be freely distributed and not offered for sale.                  */         
  4918.  /*                                                                  */         
  4919.  /* Changes or modifications may be made and used only by the maker  */         
  4920.  /* of same, and not further distributed.  Such modifications should */         
  4921.  /* be mailed to the author for consideration for addition to the    */         
  4922.  /* software and incorporation in subsequent releases.               */         
  4923.  /*                                                                  */         
  4924.  /********************************************************************/         
  4925.                                                                                 
  4926. #pragma  csect(code,  "GG@FREEM")                                               
  4927. #pragma  csect(static,"GG$FREEM")                                               
  4928. #include "gg.h"                                                                 
  4929.                                                                                 
  4930. /****** Free memory. *************************************************/         
  4931.                                                                                 
  4932. void                                                                            
  4933. GGMfreem(gp,stuff,whatfor)                                                      
  4934. Rstruc ggcb    *gp;                                                             
  4935. char           *stuff;                                                          
  4936. char           *whatfor;                                                        
  4937. {                                                                               
  4938.                                                                                 
  4939.  free(stuff);                                                                   
  4940.                                                                                 
  4941.  if (gp->debug_file) {                                                          
  4942.    fprintf(gp->debug_file,"GGMfreem: freed memory for %s\n", whatfor);          
  4943.  }                                                                              
  4944.  return;                                                                        
  4945.                                                                                 
  4946. }                                                                               
  4947.                                                                                 
  4948. ./   ADD NAME=GGMGETDS,SSI=010C0029                                             
  4949.                                                                                 
  4950.  /********************************************************************/         
  4951.  /*                                                                  */         
  4952.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4953.  /*                                                                  */         
  4954.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4955.  /*                                                                  */         
  4956.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4957.  /* including the implied warranties of merchantability and fitness, */         
  4958.  /* are expressly denied.                                            */         
  4959.  /*                                                                  */         
  4960.  /* Provided this copyright notice is included, this software may    */         
  4961.  /* be freely distributed and not offered for sale.                  */         
  4962.  /*                                                                  */         
  4963.  /* Changes or modifications may be made and used only by the maker  */         
  4964.  /* of same, and not further distributed.  Such modifications should */         
  4965.  /* be mailed to the author for consideration for addition to the    */         
  4966.  /* software and incorporation in subsequent releases.               */         
  4967.  /*                                                                  */         
  4968.  /********************************************************************/         
  4969.                                                                                 
  4970. #pragma  csect(code,  "GG@GETDS")                                               
  4971. #pragma  csect(static,"GG$GETDS")                                               
  4972. #include "gg.h"                                                                 
  4973.                                                                                 
  4974. #define DUMMY_FILE_POINTER_FOR_PDS  (FILE *)(-1)                                
  4975.                                                                                 
  4976. struct sysout    {                                                              
  4977.                   int        copies;                                            
  4978.                   char       class [2];                                         
  4979.                   char       dest  [9];                                         
  4980.                   char       forms [5];                                         
  4981.                   char       ucs   [5];                                         
  4982.                  };                                                             
  4983.                                                                                 
  4984. #define FULLSYSOUT                                                              
  4985.                                                                                 
  4986. /****** Function to close sequential data set after extraction. ******/         
  4987.                                                                                 
  4988. static void                                                                     
  4989. close_seq(gp,ep,xfp,final)                                                      
  4990. Rstruc ggcb         *gp;                                                        
  4991. Rstruc extraction   *ep;                                                        
  4992. FILE                *xfp;                                                       
  4993. Fool                 final;                                                     
  4994. {                                                                               
  4995.                                                                                 
  4996.  if (fclose(xfp) < 0) {                                                         
  4997.    /* perror(ep->dsname); */                                                    
  4998.    ERR2("An error occurred closing %s.", ep->dsname);                           
  4999.    gp->extract_close_error = TRUE;                                              
  5000.  }                                                                              
  5001.                                                                                 
  5002. }                                                                               
  5003.                                                                                 
  5004. /****** Function to close partitioned data set after extraction. *****/         
  5005.                                                                                 
  5006. static void                                                                     
  5007. close_pds(gp,ep,xfp,final)                                                      
  5008. Rstruc ggcb         *gp;                                                        
  5009. Rstruc extraction   *ep;                                                        
  5010. FILE                *xfp;                                                       
  5011. Fool                 final;                                                     
  5012. {                                                                               
  5013.                                                                                 
  5014.  if (final) {                                                                   
  5015.    (void)GGMunalc(ep->ddname);     /* Unallocate the PDS */                     
  5016.  }                                                                              
  5017.  else {                                                                         
  5018.    if (fclose(xfp) < 0) {                                                       
  5019.      /* perror(ep->dsname); */                                                  
  5020.      ERR2("An error occurred closing %s.", ep->dsname);                         
  5021.      gp->extract_close_error = TRUE;                                            
  5022.    }                                                                            
  5023.  }                                                                              
  5024.                                                                                 
  5025. }                                                                               
  5026.                                                                                 
  5027. /****** Function to close SYSOUT print file after printing. **********/         
  5028.                                                                                 
  5029. static void                                                                     
  5030. close_jes(gp,ep,xfp,final)                                                      
  5031. Rstruc ggcb         *gp;                                                        
  5032. Rstruc extraction   *ep;                                                        
  5033. FILE                *xfp;                                                       
  5034. Fool                 final;                                                     
  5035. {                                                                               
  5036.                                                                                 
  5037.  if (fclose(xfp) < 0) {                                                         
  5038.    /* perror(ep->dsname); */                                                    
  5039.    ERR2("An error occurred closing %s.", ep->dsname);                           
  5040.    gp->extract_close_error = TRUE;                                              
  5041.  }                                                                              
  5042.  if (final) {                                                                   
  5043.    (void)GGMunalc(ep->ddname);     /* Unallocate the SYSOUT file */             
  5044.  }                                                                              
  5045.                                                                                 
  5046. }                                                                               
  5047.                                                                                 
  5048. /****** Allocate SYSOUT file. ****************************************/         
  5049.                                                                                 
  5050. static Bool                                                                     
  5051. allocate_sysout(ep,sp)                                                          
  5052. Rstruc extraction   *ep;                                                        
  5053. Rstruc sysout       *sp;                                                        
  5054. {                                                                               
  5055.  int          i;                                                                
  5056.  int          rc;                                                               
  5057.  char        *cp;                                                               
  5058.  __S99parms   stuff99;   /* The manual has it wrong.  No "struct". */           
  5059.  TEXTUNIT    *tu [ 7];                                                          
  5060.  TEXTUNIT     tu_sysout;                                                        
  5061.  TEXTUNIT     tu_copies;                                                        
  5062.  TEXTUNIT     tu_dest;                                                          
  5063.  TEXTUNIT     tu_forms;                                                         
  5064.  TEXTUNIT     tu_ucs;                                                           
  5065.  TEXTUNIT     tu_rtddn;                                                         
  5066.                                                                                 
  5067.  memset((char *)&stuff99,0,sizeof(__S99parms));                                 
  5068.                                                                                 
  5069.  stuff99.__S99RBLN   = 20;                                                      
  5070.  stuff99.__S99VERB   = S99VRBAL;                                                
  5071.  stuff99.__S99FLAG1  = S99NOCNV << 8;                                           
  5072.  stuff99.__S99ERROR  = 0;                                                       
  5073.  stuff99.__S99INFO   = 0;                                                       
  5074.  stuff99.__S99TXTPP  = tu;                                                      
  5075.  stuff99.__S99FLAG2  = 0;                                                       
  5076.                                                                                 
  5077.  i = 0;                                                                         
  5078.                                                                                 
  5079.  tu[i++] = &tu_sysout;                                                          
  5080.                                                                                 
  5081.  tu_sysout.key        = DALSYSOU;                                               
  5082.  tu_sysout.num        = 1;                                                      
  5083.  tu_sysout.ent.len    = 1;                                                      
  5084.  tu_sysout.ent.prm[0] = toupper(sp->class[0]);                                  
  5085.                                                                                 
  5086.  tu[i++] = &tu_copies;                                                          
  5087.                                                                                 
  5088.  tu_copies.key        = DALCOPYS;                                               
  5089.  tu_copies.num        = 1;                                                      
  5090.  tu_copies.ent.len    = 1;                                                      
  5091.  tu_copies.ent.prm[0] = (unsigned char)sp->copies;                              
  5092.                                                                                 
  5093.  if (sp->dest[0] > ' ') {                                                       
  5094.                                                                                 
  5095.   tu[i++] = &tu_dest;                                                           
  5096.                                                                                 
  5097.   tu_dest.key          = DALSUSER;                                              
  5098.   tu_dest.num          = 1;                                                     
  5099.   copy_uppercase_and_strip_trailing(tu_dest.ent.prm,sp->dest,cp);               
  5100.   tu_dest.ent.len      = cp - tu_dest.ent.prm;                                  
  5101.                                                                                 
  5102.  }                                                                              
  5103.                                                                                 
  5104.  if (sp->forms[0] > ' ') {                                                      
  5105.                                                                                 
  5106.   tu[i++] = &tu_forms;                                                          
  5107.                                                                                 
  5108.   tu_forms.key         = DALSFMNO;                                              
  5109.   tu_forms.num         = 1;                                                     
  5110.   copy_uppercase_and_strip_trailing(tu_forms.ent.prm,sp->forms,cp);             
  5111.   tu_forms.ent.len     = cp - tu_forms.ent.prm;                                 
  5112.                                                                                 
  5113.  }                                                                              
  5114.                                                                                 
  5115.  if (sp->ucs[0] > ' ') {                                                        
  5116.                                                                                 
  5117.   tu[i++] = &tu_ucs;                                                            
  5118.                                                                                 
  5119.   tu_ucs.key           = DALUCS;                                                
  5120.   tu_ucs.num           = 1;                                                     
  5121.   copy_uppercase_and_strip_trailing(tu_ucs.ent.prm,sp->ucs,cp);                 
  5122.   tu_ucs.ent.len       = cp - tu_ucs.ent.prm;                                   
  5123.                                                                                 
  5124.  }                                                                              
  5125.                                                                                 
  5126.  tu[i++] = &tu_rtddn;                                                           
  5127.                                                                                 
  5128.  tu_rtddn.key         = DALRTDDN;                                               
  5129.  tu_rtddn.num         = 1;                                                      
  5130.  tu_rtddn.ent.len     = 8;                                                      
  5131.  memset(tu_rtddn.ent.prm,' ',8);                                                
  5132.                                                                                 
  5133.  tu[i] = (void *)0x80000000;                                                    
  5134.                                                                                 
  5135.  rc = svc99(&stuff99);                                                          
  5136.                                                                                 
  5137.  if (rc == 0) {                                                                 
  5138.    memcpy(ep->ddname,(char *)tu_rtddn.ent.prm,8);                               
  5139.    ep->ddname[8] = ' ';                                                         
  5140.    *(strchr(ep->ddname,' ')) = '\0';                                            
  5141.    return TRUE;                                                                 
  5142.  }                                                                              
  5143.  else {                                                                         
  5144.    GGMdfail(rc,&stuff99);                                                       
  5145.    return FALSE;                                                                
  5146.  }                                                                              
  5147. }                                                                               
  5148.                                                                                 
  5149. /****** Prompt user for the name of a data set to extract into. ******/         
  5150.                                                                                 
  5151. FILE *                                                                          
  5152. GGMgetds(gp,ep)                                                                 
  5153. Rstruc ggcb         *gp;                                                        
  5154. Rstruc extraction   *ep;                                                        
  5155. {                                                                               
  5156.  FILE               *xfp;                                                       
  5157.  char               *bufptr;                                                    
  5158.  Bool                asked_for;                                                 
  5159.  Bool                do_warn;                                                   
  5160.  Bool                is_not_gopher_menu;                                        
  5161.  struct sysout       sys;                                                       
  5162.  char                ggexdsn[65];    /* data set name for extraction */         
  5163.  char                ggbmdsn[65];    /* data set name for bookmark   */         
  5164.  char                ggexapp [4];    /* YES or NO for append mode    */         
  5165.  char                ggextab [4];    /* YES or NO for tab expansion  */         
  5166.  char                ggexblk [4];    /* YES or NO for blank after sep*/         
  5167.  char                ggexsep[81];    /* Separator line (optional)    */         
  5168.  char                ggexpmp [9];    /* PDS member name prefix       */         
  5169.  char                ggexscl [2];    /* Print SYSOUT class name      */         
  5170.  char                ggexsco [4];    /* Print SYSOUT copies number   */         
  5171.  char                ggexsde [9];    /* Print SYSOUT destination     */         
  5172.  char                ggexsfo [5];    /* Print SYSOUT forms           */         
  5173.  char                ggexsuc [5];    /* Print SYSOUT UCS             */         
  5174.  char                ddname  [9];                                               
  5175.  char                member  [9];                                               
  5176.  char                pdspec [32];                                               
  5177.  char                quoted_dsname [67];                                        
  5178.  char                formatted_number [11];                                     
  5179.  char                buffer [RBUFSIZE];                                         
  5180.                                                                                 
  5181.                                                                                 
  5182.  /* Display panel asking for data set name into which to extract. */            
  5183.                                                                                 
  5184.  xfp = NULL;                                                                    
  5185.  asked_for = TRUE;                                                              
  5186.                                                                                 
  5187.  (void)GGMispf(gp,"ADDPOP");                                                    
  5188.                                                                                 
  5189.  (void)GGMivput(gp,"GGALLPR ",                                                  
  5190. #ifdef FULLSYSOUT                                                               
  5191.                      "Y",                                                       
  5192. #else                                                                           
  5193.                      "",                                                        
  5194. #endif                                                                          
  5195.                      -1);                                                       
  5196.                                                                                 
  5197.  while (xfp == NULL) {                                                          
  5198.                                                                                 
  5199.    /* Keep asking for a dsname until one works or END pressed. */               
  5200.                                                                                 
  5201.    if (GGMdispl(gp,ep->panelname) > 0) {                                        
  5202.      WARN1("Request cancelled, because you pressed END.");                      
  5203.      asked_for = FALSE;                                                         
  5204.      xfp = NULL;                                                                
  5205.      break;                                                                     
  5206.    }                                                                            
  5207.                                                                                 
  5208.    switch (ep->ex) {                                                            
  5209.      case EXTRACT_IT:                                                           
  5210.           (void)GGMivget(gp,"GGEXDSN ",ggexdsn,sizeof(ggexdsn));                
  5211.           (void)GGMivget(gp,"GGEXTAB ",ggextab,sizeof(ggextab));                
  5212.           if (ep->mode == PDS) {                                                
  5213.             (void)GGMivget(gp,"GGEXPMP ",ggexpmp,sizeof(ggexpmp));              
  5214.           }                                                                     
  5215.           else {                                                                
  5216.             (void)GGMivget(gp,"GGEXAPP ",ggexapp,sizeof(ggexapp));              
  5217.             (void)GGMivget(gp,"GGEXBLK ",ggexblk,sizeof(ggexblk));              
  5218.             (void)GGMivget(gp,"GGEXSEP ",ggexsep,sizeof(ggexsep));              
  5219.           }                                                                     
  5220.           break;                                                                
  5221.      case PRINT_IT:                                                             
  5222.           (void)GGMivget(gp,"GGEXSCL ",ggexscl,sizeof(ggexscl));                
  5223.           (void)GGMivget(gp,"GGEXSCO ",ggexsco,sizeof(ggexsco));                
  5224. #ifdef FULLSYSOUT                                                               
  5225.           (void)GGMivget(gp,"GGEXSDE ",ggexsde,sizeof(ggexsde));                
  5226.           (void)GGMivget(gp,"GGEXSFO ",ggexsfo,sizeof(ggexsfo));                
  5227.           (void)GGMivget(gp,"GGEXSUC ",ggexsuc,sizeof(ggexsuc));                
  5228. #else                                                                           
  5229.           *ggexsde = '\0';                                                      
  5230.           *ggexsfo = '\0';                                                      
  5231.           *ggexsuc = '\0';                                                      
  5232. #endif                                                                          
  5233.           (void)GGMivget(gp,"GGEXBLK ",ggexblk,sizeof(ggexblk));                
  5234.           (void)GGMivget(gp,"GGEXSEP ",ggexsep,sizeof(ggexsep));                
  5235.           break;                                                                
  5236.      case BOOKMARK_IT:                                                          
  5237.           (void)GGMivget(gp,"GGBMDSN ",ggbmdsn,sizeof(ggbmdsn));                
  5238.           break;                                                                
  5239.    }                                                                            
  5240.                                                                                 
  5241.    if (ep->mode == PDS) {                                                       
  5242.                                                                                 
  5243.      ep->closer = close_pds;                                                    
  5244.      ep->appending = FALSE;                                                     
  5245.      ep->blanking  = FALSE;                                                     
  5246.      strcpy(ep->separator,"");                                                  
  5247.      strcpy(ep->ddname,"");                                                     
  5248.      strcpy(ep->member_prefix,ggexpmp);                                         
  5249.                                                                                 
  5250.      /* Note: panel forces fully-qualified name to pass to allocate */          
  5251.                                                                                 
  5252.      if (ggexdsn[0] != '\'') {                                                  
  5253.        strcpy(quoted_dsname,"'");                                               
  5254.        strcat(quoted_dsname,ggexdsn);                                           
  5255.        strcat(quoted_dsname,"'");                                               
  5256.      }                                                                          
  5257.      else strcpy(quoted_dsname,ggexdsn);                                        
  5258.                                                                                 
  5259.      /* Check if PDS already exists. */                                         
  5260.                                                                                 
  5261.      if (gp->warn_overwrite) {                                                  
  5262.        if (TEST_IF_FILE_EXISTS(xfp,quoted_dsname)) {                            
  5263.          CLEANUP_IF_FILE_EXISTS(xfp);                                           
  5264.          xfp = NULL;                                                            
  5265.          if (GGMdispl(gp,"GGMPEXPW") > 0) {                                     
  5266.            WARN1("Operation cancelled, because you pressed END.");              
  5267.            break;                                                               
  5268.          }                                                                      
  5269.        }                                                                        
  5270.      }                                                                          
  5271.                                                                                 
  5272.      if (GGMalloc(ggexdsn,ep->ddname,PDS,ep->count) != PDS) {                   
  5273.        ERR2("Allocation failed for data set %s.", ggexdsn);                     
  5274.        xfp = NULL;                                                              
  5275.        continue;                                                                
  5276.      }                                                                          
  5277.      strcpy(ep->dsname,    ggexdsn);                                            
  5278.      ep->tab_expanding = (ggextab[0] == 'Y');                                   
  5279.      do_warn = (ep->appending ? gp->warn_append : gp->warn_overwrite);          
  5280.    }                                                                            
  5281.    else if (ep->mode == JES) {                                                  
  5282.      ep->closer = close_jes;                                                    
  5283.      strcpy(ep->separator, ggexsep);                                            
  5284.      sprintf(ep->dsname,"SYSOUT class %s",ggexscl);                             
  5285.      strcpy(sys.class, ggexscl);                                                
  5286.      sys.copies = atoi(ggexsco);                                                
  5287.      if (sys.copies < 1) sys.copies = 1;                                        
  5288.      strcpy(sys.dest,  ggexsde);                                                
  5289.      strcpy(sys.forms, ggexsfo);                                                
  5290.      strcpy(sys.ucs,   ggexsuc);                                                
  5291.      ep->appending     = FALSE;                                                 
  5292.      ep->blanking      = (ggexblk[0] == 'Y');                                   
  5293.      ep->tab_expanding = TRUE;                                                  
  5294.      do_warn = FALSE;                                                           
  5295.    }                                                                            
  5296.    else if (ep->ex == BOOKMARK_IT) {                                            
  5297.      ep->closer = close_seq;                                                    
  5298.      strcpy(ep->separator, "");                                                 
  5299.      strcpy(ep->dsname,    ggbmdsn);                                            
  5300.      strcpy(ggexdsn,       ggbmdsn);                                            
  5301.      ep->appending       = TRUE;                                                
  5302.      ep->blanking        = FALSE;                                               
  5303.      ep->tab_expanding   = FALSE;                                               
  5304.      do_warn = FALSE;                                                           
  5305.    }                                                                            
  5306.    else {                                                                       
  5307.      ep->closer = close_seq;                                                    
  5308.      strcpy(ep->separator, ggexsep);                                            
  5309.      strcpy(ep->dsname,    ggexdsn);                                            
  5310.      ep->appending      = (ggexapp[0] == 'Y');                                  
  5311.      ep->blanking       = (ggexblk[0] == 'Y');                                  
  5312.      ep->tab_expanding  = (ggextab[0] == 'Y');                                  
  5313.      do_warn = (ep->appending ? gp->warn_append : gp->warn_overwrite);          
  5314.    }                                                                            
  5315.                                                                                 
  5316.    /* check if the dataset already exists */                                    
  5317.                                                                                 
  5318.    if (ep->ex == BOOKMARK_IT) {                                                 
  5319.      is_not_gopher_menu = FALSE;                                                
  5320.      if (TEST_IF_FILE_EXISTS(xfp,ggexdsn)) {                                    
  5321.        /* check that it is a gopher menu */                                     
  5322.        CLEANUP_IF_FILE_EXISTS(xfp);                                             
  5323.        xfp = fopen(ggexdsn,"r");                                                
  5324.        if (xfp) {                                                               
  5325.          *buffer = '\0';                                                        
  5326.          fgets(buffer,sizeof(buffer),xfp);                                      
  5327.          if (*buffer) {                                                         
  5328.            if ((bufptr=strchr(buffer,'\n'))) *bufptr = '\0';                    
  5329.            uppercase_in_place(buffer);                                          
  5330.            bufptr = skip_whitespace(buffer);                                    
  5331.            if (!EQUAL(bufptr,MENUIDENT)) is_not_gopher_menu = TRUE;             
  5332.          }                                                                      
  5333.          (void)fclose(xfp);                                                     
  5334.          xfp = NULL;                                                            
  5335.        }                                                                        
  5336.        if (is_not_gopher_menu) {                                                
  5337.          WARN2("Not a gopher bookmark or menu file: %s",ep->dsname);            
  5338.          break;                                                                 
  5339.        }                                                                        
  5340.        ep->appending = TRUE;                                                    
  5341.      }                                                                          
  5342.      else {                                                                     
  5343.        ep->appending = FALSE;                                                   
  5344.      }                                                                          
  5345.    }                                                                            
  5346.    else if (ep->mode != JES) {                                                  
  5347.      if (do_warn) {                                                             
  5348.        if (TEST_IF_FILE_EXISTS(xfp,ggexdsn)) {                                  
  5349.          CLEANUP_IF_FILE_EXISTS(xfp);                                           
  5350.          xfp = NULL;                                                            
  5351.          if (GGMdispl(gp,"GGMPEXOW") > 0) {                                     
  5352.            WARN1("Operation cancelled, because you pressed END.");              
  5353.            break;                                                               
  5354.          }                                                                      
  5355.        }                                                                        
  5356.      }                                                                          
  5357.    }                                                                            
  5358.                                                                                 
  5359.    if (ep->mode == JES) {                                                       
  5360.      if (allocate_sysout(ep,&sys)) {                                            
  5361.        sprintf(ggexdsn,"dd:%s",ep->ddname);                                     
  5362.      }                                                                          
  5363.      else *ggexdsn = '\0';                                                      
  5364.    }                                                                            
  5365.                                                                                 
  5366.    if (ep->mode == PDS) {                                                       
  5367.      xfp = DUMMY_FILE_POINTER_FOR_PDS;                                          
  5368.      break;                                                                     
  5369.    }                                                                            
  5370.                                                                                 
  5371.    if (*ggexdsn) {                                                              
  5372.                                                                                 
  5373.      if (ep->mode == JES) {                                                     
  5374.        xfp = OPEN_SYSOUT_FILE(ggexdsn);                                         
  5375.      }                                                                          
  5376.      else {                                                                     
  5377.        xfp = OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(ggexdsn,ep->appending);         
  5378.      }                                                                          
  5379.                                                                                 
  5380.      if (!xfp) {                                                                
  5381. #ifdef SNSTCPIP                                                                 
  5382.        fprintf(stderr,"Open failure: errno=%d\n",GET_ERRNO);                    
  5383. #else                                                                           
  5384.        fprintf(stderr,"Open failure: errno=%d\n",errno);                        
  5385. #endif                                                                          
  5386.        perror(ggexdsn);                                                         
  5387.        ERR2("Cannot open data set %s.", ep->dsname);                            
  5388.      }                                                                          
  5389.    }                                                                            
  5390.  }                                                                              
  5391.                                                                                 
  5392.  (void)GGMispf(gp,"REMPOP");                                                    
  5393.                                                                                 
  5394.  return xfp;                                                                    
  5395.                                                                                 
  5396. }                                                                               
  5397.                                                                                 
  5398. ./   ADD NAME=GGMGETM                                                           
  5399.                                                                                 
  5400.  /********************************************************************/         
  5401.  /*                                                                  */         
  5402.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5403.  /*                                                                  */         
  5404.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5405.  /*                                                                  */         
  5406.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5407.  /* including the implied warranties of merchantability and fitness, */         
  5408.  /* are expressly denied.                                            */         
  5409.  /*                                                                  */         
  5410.  /* Provided this copyright notice is included, this software may    */         
  5411.  /* be freely distributed and not offered for sale.                  */         
  5412.  /*                                                                  */         
  5413.  /* Changes or modifications may be made and used only by the maker  */         
  5414.  /* of same, and not further distributed.  Such modifications should */         
  5415.  /* be mailed to the author for consideration for addition to the    */         
  5416.  /* software and incorporation in subsequent releases.               */         
  5417.  /*                                                                  */         
  5418.  /********************************************************************/         
  5419.                                                                                 
  5420. #pragma  csect(code,  "GG@GETM ")                                               
  5421. #pragma  csect(static,"GG$GETM ")                                               
  5422. #include "gg.h"                                                                 
  5423.                                                                                 
  5424. /****** Get memory. **************************************************/         
  5425.                                                                                 
  5426. void                                                                            
  5427. GGMgetm(gp,pointer,howmuch,whatfor)                                             
  5428. Rstruc ggcb    *gp;                                                             
  5429. char          **pointer;                                                        
  5430. int             howmuch;                                                        
  5431. char           *whatfor;                                                        
  5432. {                                                                               
  5433.                                                                                 
  5434.  *pointer = (char *)malloc(howmuch);                                            
  5435.                                                                                 
  5436.  if (*pointer == NULL) {                                                        
  5437.    fprintf(stderr,"GGMgetm: Cannot obtain %d bytes of memory for %s\n",         
  5438.                   howmuch,whatfor);                                             
  5439.  }                                                                              
  5440.  else if (gp->debug_file) {                                                     
  5441.    fprintf(gp->debug_file,"GGMgetm: got %d bytes of memory for %s\n",           
  5442.                            howmuch,whatfor);                                    
  5443.  }                                                                              
  5444.  return;                                                                        
  5445.                                                                                 
  5446. }                                                                               
  5447.                                                                                 
  5448. ./   ADD NAME=GGMGOFOR,SSI=01020021                                             
  5449.                                                                                 
  5450.  /********************************************************************/         
  5451.  /*                                                                  */         
  5452.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5453.  /*                                                                  */         
  5454.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5455.  /*                                                                  */         
  5456.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5457.  /* including the implied warranties of merchantability and fitness, */         
  5458.  /* are expressly denied.                                            */         
  5459.  /*                                                                  */         
  5460.  /* Provided this copyright notice is included, this software may    */         
  5461.  /* be freely distributed and not offered for sale.                  */         
  5462.  /*                                                                  */         
  5463.  /* Changes or modifications may be made and used only by the maker  */         
  5464.  /* of same, and not further distributed.  Such modifications should */         
  5465.  /* be mailed to the author for consideration for addition to the    */         
  5466.  /* software and incorporation in subsequent releases.               */         
  5467.  /*                                                                  */         
  5468.  /********************************************************************/         
  5469.                                                                                 
  5470. #pragma  csect(code,  "GG@GOFOR")                                               
  5471. #pragma  csect(static,"GG$GOFOR")                                               
  5472. #include "gg.h"                                                                 
  5473.                                                                                 
  5474. /********************************************************************/          
  5475.                                                                                 
  5476. static Bool                                                                     
  5477. connect_to_gopher_server(gp,sp,ip,is_cr_needed)                                 
  5478. Rstruc connection  *sp;                                                         
  5479. Rstruc ggcb        *gp;                                                         
  5480. Rstruc gopherinfo  *ip;                                                         
  5481. Fool                is_cr_needed;                                               
  5482. {                                                                               
  5483.  char              *lp;                                                         
  5484.  Bool               got_some;                                                   
  5485.                                                                                 
  5486.  strcpy(gp->ggserver,ip->host);     /* Specify server to connect to */          
  5487.  strcpy(gp->gopher_command,ip->path);   /* Specify command to issue */          
  5488.  gp->ginfo = ip;                                                                
  5489.  sp->receiving_text = FALSE;                                                    
  5490.                                                                                 
  5491.  if (!GGMconn(gp,sp)) return FALSE;   /* Connect to gopher server */            
  5492.                                                                                 
  5493.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  5494.                                                                                 
  5495.  GGMclrtx(gp,ip);                  /* Clear text */                             
  5496.                                                                                 
  5497.  sp->receiving_text = TRUE;                                                     
  5498.                                                                                 
  5499.  got_some = FALSE;                                                              
  5500.  do {                                                                           
  5501.    if (GGMgsrvl(gp,sp,&lp,is_cr_needed)) {  /* Get server line */               
  5502.      if (lp) {                                                                  
  5503.        got_some = TRUE;                                                         
  5504.        (void)GGMouttx(gp,lp,ip);          /* Output text line */                
  5505.      }                                                                          
  5506.    }                                                                            
  5507.  } while (lp);                            /* until no more lines */             
  5508.                                                                                 
  5509.  if (!got_some) {                                                               
  5510.    WARN2("No data available from server %s.\n",gp->ggserver);                   
  5511.    return FALSE;                                                                
  5512.  }                                                                              
  5513.                                                                                 
  5514.  return TRUE;                                                                   
  5515.                                                                                 
  5516. }                                                                               
  5517.                                                                                 
  5518. /****** Gopher it. ***************************************************/         
  5519.                                                                                 
  5520. Bool                                                                            
  5521. GGMgofor(gp,ip,as_file)                                                         
  5522. Rstruc ggcb        *gp;                                                         
  5523. Rstruc gopherinfo  *ip;                                                         
  5524. Fool                as_file;                                                    
  5525. {                                                                               
  5526.  Rstruc connection *sp;                                                         
  5527.  Bool               con;                                                        
  5528.  Bool               cr;                                                         
  5529.  Bool               rc;                                                         
  5530.  Bool             (*fun)(struct ggcb *,struct gopherinfo *,Fool);               
  5531.  char                    savebook[63];                                          
  5532.  sp = &gp->gopher_connection;                                                   
  5533.                                                                                 
  5534.    /* (1) send initial path string to initial host                              
  5535.     * (2) get back data from host                                               
  5536.     * (3) if it is a gopher directory, then do:                                 
  5537.     *      - display "table" of items                                           
  5538.     *      - for each item selected, call GGMgofor recursively                  
  5539.     *     else browse the file data                                             
  5540.     * (4) bye                                                                   
  5541.     */                                                                          
  5542.                                                                                 
  5543.  if (gp->debug_mode) {                                                          
  5544.    fprintf(gp->debug_file,"GGMgofor: type = %c\n",ip->type);                    
  5545.    fprintf(gp->debug_file,"GGMgofor: port = %d\n",ip->port);                    
  5546.    fprintf(gp->debug_file,"GGMgofor: path = %s\n",ip->path);                    
  5547.    fprintf(gp->debug_file,"GGMgofor: host = %s\n",ip->host);                    
  5548.    fprintf(gp->debug_file,"GGMgofor: desc = %s\n",ip->desc);                    
  5549.    fprintf(gp->debug_file,"GGMgofor: bmds = %s\n",ip->bmds);                    
  5550.  }                                                                              
  5551.                                                                                 
  5552.  switch (ip->type) {                                                            
  5553.    case GOPHER_FILE:     fun = GGMvtx;   con = TRUE;  cr = TRUE; break;         
  5554.    case GOPHER_DIRECTORY:fun = GGMdir;   con = TRUE;  cr = TRUE; break;         
  5555.    case GOPHER_TELNET:   fun = GGMtnet;  con = FALSE; cr = TRUE; break;         
  5556.    case GOPHER_TN3270:   fun = GGMtnet;  con = FALSE; cr = TRUE; break;         
  5557.    case GOPHER_WAIS:     fun = GGMwais;  con = FALSE; cr = TRUE; break;         
  5558.    case GOPHER_WHOIS:    fun = GGMwhois; con = FALSE; cr = TRUE; break;         
  5559.    case GOPHER_CSO:      fun = GGMcso;   con = FALSE; cr = FALSE;break;         
  5560.    default:                                                                     
  5561.         ERR2("Sorry, access via %s not supported", GGMtype(ip->type));          
  5562.         return FALSE;                                                           
  5563.  }                                                                              
  5564.                                                                                 
  5565.  if (con) {                                                                     
  5566.    if (!connect_to_gopher_server(gp,sp,ip,cr)) return FALSE;                    
  5567.  }                                                                              
  5568.                                                                                 
  5569.  /* Insure no connection is active once we do the real thing. */                
  5570.                                                                                 
  5571.  if (sp->connected_to_server) {                                                 
  5572.    (void)GGMdisc(gp,sp);     /* Disconnect from gopher server */                
  5573.  }                                                                              
  5574.                                                                                 
  5575.  strcpy(savebook,gp->current_bookmark_ds);                                      
  5576.  if (EQUAL(ip->host, LOCAL_HOST_FROB)) {                                        
  5577.    strncpy(gp->current_bookmark_ds,ip->path,sizeof(savebook));                  
  5578.  }                                                                              
  5579.  else {                                                                         
  5580.    strcpy(gp->current_bookmark_ds,"");                                          
  5581.  }                                                                              
  5582.                                                                                 
  5583.  rc = (fun)(gp,ip,as_file);                                                     
  5584.                                                                                 
  5585.  strcpy(gp->current_bookmark_ds,savebook);                                      
  5586.                                                                                 
  5587.  return rc;                                                                     
  5588.                                                                                 
  5589. }                                                                               
  5590.                                                                                 
  5591. ./   ADD NAME=GGMGSRVL,SSI=01000040                                             
  5592.                                                                                 
  5593.  /********************************************************************/         
  5594.  /*                                                                  */         
  5595.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5596.  /*                                                                  */         
  5597.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5598.  /*                                                                  */         
  5599.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5600.  /* including the implied warranties of merchantability and fitness, */         
  5601.  /* are expressly denied.                                            */         
  5602.  /*                                                                  */         
  5603.  /* Provided this copyright notice is included, this software may    */         
  5604.  /* be freely distributed and not offered for sale.                  */         
  5605.  /*                                                                  */         
  5606.  /* Changes or modifications may be made and used only by the maker  */         
  5607.  /* of same, and not further distributed.  Such modifications should */         
  5608.  /* be mailed to the author for consideration for addition to the    */         
  5609.  /* software and incorporation in subsequent releases.               */         
  5610.  /*                                                                  */         
  5611.  /********************************************************************/         
  5612.                                                                                 
  5613. #pragma  csect(code,  "GG@GSRVL")                                               
  5614. #pragma  csect(static,"GG$GSRVL")                                               
  5615. #include "gg.h"                                                                 
  5616.                                                                                 
  5617. /****** Input one character from the server. *************************/         
  5618.                                                                                 
  5619. static int                                                                      
  5620. socket_getchar(sp)                                                              
  5621. Rstruc connection *sp;                                                          
  5622. {                                                                               
  5623.  int         readrc;                                                            
  5624.                                                                                 
  5625.  if (sp->buf_index == -1 ||                                                     
  5626.      sp->buf_index >= sp->bytes_returned - 1) {                                 
  5627.    sp->buf_index = -1;                                                          
  5628.    if (sp->dont_read) return(SOCKET_NO_MORE);                                   
  5629.    else {                                                                       
  5630.      TCP_DEBUG_ON;                                                              
  5631.      readrc = read(sp->ns, sp->buf, READ_BYTES);                                
  5632.      TCP_DEBUG_OFF;                                                             
  5633.      if (readrc == -1) {                                                        
  5634.        sp->connection_broken = TRUE;                                            
  5635.        return SOCKET_GETCHAR_ERROR;                                             
  5636.      }                                                                          
  5637.      else if (readrc == 0) {                                                    
  5638.        sp->connection_broken = FALSE;                                           
  5639.        return SOCKET_READ_NOTHING;                                              
  5640.      }                                                                          
  5641.      else {                                                                     
  5642. #ifdef MVS                                                                      
  5643.        ASCII_TO_EBCDIC(sp->buf,readrc);                                         
  5644. #endif                                                                          
  5645.        sp->bytes_returned = readrc;                                             
  5646.      }                                                                          
  5647.    }                                                                            
  5648.  }                                                                              
  5649.  return sp->buf[++sp->buf_index];                                               
  5650. }                                                                               
  5651.                                                                                 
  5652. /****** Input one data line at a time from the server. ***************/         
  5653.                                                                                 
  5654. static enum socket_retval                                                       
  5655. socket_from_server(gp,sp)                                                       
  5656. Rstruc ggcb       *gp;                                                          
  5657. Rstruc connection *sp;                                                          
  5658. {                                                                               
  5659.  char             *s_buf;                                                       
  5660.  int               s_bytes;                                                     
  5661.  int               s_buf_index;                                                 
  5662.  int               character;                                                   
  5663.  int               previous_character;                                          
  5664.                                                                                 
  5665.  s_buf   = sp->server_buf;                                                      
  5666.  s_bytes = SERVER_BUF_MSGSIZE;                                                  
  5667.                                                                                 
  5668.  /* Get characters from the server until CRLF is reached. */                    
  5669.                                                                                 
  5670.  s_buf_index = 0;                                                               
  5671.  previous_character = -1;                                                       
  5672.  for (;;) {                                                                     
  5673.    character = socket_getchar(sp);                                              
  5674.    /*                                                                           
  5675.    if (character == LINE_FEED && previous_character == CARRIAGE_RETURN)         
  5676.       break;                                                                    
  5677.    */                                                                           
  5678.    if (character == LINE_FEED) break;                                           
  5679.    if (character == SOCKET_GETCHAR_ERROR)  return(SERVER_READ_ERROR);           
  5680.    if (character == SOCKET_NO_MORE)        return(SERVER_NO_MORE);              
  5681.    if (character == SOCKET_READ_NOTHING)   return(SERVER_READ_NOTHING);         
  5682.    previous_character = character;                                              
  5683.    if (s_buf_index >= s_bytes) {                                                
  5684.      fprintf(stderr,"Error: sp->server_buf overflowed.\n");                     
  5685.      fprintf(stderr,                                                            
  5686.              "More than %d bytes collected without CR/LF seen.\n",              
  5687.              s_bytes);                                                          
  5688.      if (gp->debug_file) {                                                      
  5689.        GGMdump(gp,"Data collected so far",sp->server_buf,s_bytes);              
  5690.      }                                                                          
  5691.      return(SERVER_BUFFER_ERROR);                                               
  5692.    }                                                                            
  5693.    if (character == '\0') {                                                     
  5694.      fprintf(stderr,                                                            
  5695. "Warning: null character found in data from server, changed to blank\n"         
  5696.             );                                                                  
  5697.      character = ' ';                                                           
  5698.    }                                                                            
  5699.    s_buf[s_buf_index++] = (unsigned char)character;                             
  5700.  }                                                                              
  5701.  s_buf[s_buf_index] = '\0';                                                     
  5702.  return(SERVER_READ_OK);                                                        
  5703. }                                                                               
  5704.                                                                                 
  5705. /****** Get server line. *********************************************/         
  5706.                                                                                 
  5707. Bool                                                                            
  5708. GGMgsrvl(gp,sp,pointer,is_cr_needed)                                            
  5709. Rstruc ggcb        *gp;                                                         
  5710. Rstruc connection  *sp;                                                         
  5711. char              **pointer;                                                    
  5712. Fool                is_cr_needed;                                               
  5713. {                                                                               
  5714.  char              *sbufp;                                                      
  5715.  char              *p;                                                          
  5716.  int                scan_count;                                                 
  5717.  Bool               something_to_print;                                         
  5718.  struct recvstruct *R;                                                          
  5719.                                                                                 
  5720.  *pointer = NULL;                                                               
  5721.                                                                                 
  5722.  /* If local mode, read from temporary file until EOF. */                       
  5723.                                                                                 
  5724.  if ((R=gp->recvp)) {                                                           
  5725.    if (!R->outfp) {                                                             
  5726.      CRIT1("Can't read data locally, non-socket not connected\n");              
  5727.      return FALSE;                                                              
  5728.    }                                                                            
  5729.    fgets(sp->server_buf, SERVER_BUF_MSGSIZE, R->outfp);                         
  5730.    if (ferror(R->outfp)) {                                                      
  5731.      CRIT1("Error reading local non-socket data\n");                            
  5732.      sp->time_to_go_home = TRUE;                                                
  5733.      return FALSE;                                                              
  5734.    }                                                                            
  5735.    if (feof(R->outfp)) return FALSE;                                            
  5736.    if ((p=strchr(sp->server_buf,'\n'))) *p = '\0';                              
  5737.    *pointer = sp->server_buf;                                                   
  5738.    return TRUE;                                                                 
  5739.  }                                                                              
  5740.                                                                                 
  5741.  if (!sp->receiving_text) return TRUE;                                          
  5742.                                                                                 
  5743.  if (sp->server_finished_replying) sp->dont_read = TRUE;                        
  5744.                                                                                 
  5745.  switch (socket_from_server(gp,sp)) {                                           
  5746.    case SERVER_READ_OK:      break;                                             
  5747.    case SERVER_READ_NOTHING: sp->time_to_go_home = TRUE;                        
  5748.                              break;                                             
  5749.    case SERVER_READ_ERROR:   ERR2(                                              
  5750.      "Lost server connection.  Failure reading data from server %s.",           
  5751.                                   gp->ggserver);                                
  5752.                              sp->time_to_go_home = TRUE;                        
  5753.                              break;                                             
  5754.    case SERVER_BUFFER_ERROR: ERR2(                                              
  5755.  "Read error.  No linefeed character found in data from server %s.",            
  5756.                                   gp->ggserver);                                
  5757.                              sp->time_to_go_home = TRUE;                        
  5758.                              break;                                             
  5759.    case SERVER_NO_MORE:      sp->server_has_something_pending = FALSE;          
  5760.                              break;                                             
  5761.  }                                                                              
  5762.                                                                                 
  5763.  if (sp->time_to_go_home) return FALSE;                                         
  5764.  if (sp->dont_read && !sp->server_has_something_pending) return TRUE;           
  5765.                                                                                 
  5766.  something_to_print = TRUE;                                                     
  5767.                                                                                 
  5768.  sbufp = sp->server_buf;                                                        
  5769.                                                                                 
  5770.  if (sp->sending_text) {                                                        
  5771.    if (*sbufp == '.') {                                                         
  5772.      switch (*(sbufp+1)) {                                                      
  5773.         case CARRIAGE_RETURN:                                                   
  5774.         case LINE_FEED:                                                         
  5775.         case '\0':                                                              
  5776.                   sp->server_finished_replying = TRUE;                          
  5777.                   something_to_print = FALSE;                                   
  5778.                   break;                                                        
  5779.         case '.':                                                               
  5780.                   break;                                                        
  5781.         default:                                                                
  5782.                   GGMdump(gp,"Warning, bad period in line from server",         
  5783.                           sbufp,strlen(sbufp));                                 
  5784.                   break;                                                        
  5785.      }                                                                          
  5786.    }                                                                            
  5787.  }                                                                              
  5788.                                                                                 
  5789.  sp->sending_text = TRUE;                                                       
  5790.                                                                                 
  5791.  if (something_to_print) {                                                      
  5792.    /* Last character of output buffer is a CR without LF. */                    
  5793.    p = sbufp + strlen(sbufp)-1;                                                 
  5794.    if (p >= sbufp) {                                                            
  5795.      if (*p == CARRIAGE_RETURN) *p = '\0';                                      
  5796.      else if (is_cr_needed) {                                                   
  5797.        /* Last character of output buffer had better be a LF. */                
  5798.        if (gp->debug_file) {                                                    
  5799.          fprintf(gp->debug_file,                                                
  5800.    "Warning: No carriage return in data from server (%d bytes):\n%s\n",         
  5801.                strlen(sbufp), sbufp);                                           
  5802.        }                                                                        
  5803.        CRIT2(                                                                   
  5804. "Carriage return expected but not seen in data from server %s.",                
  5805.              gp->ggserver);                                                     
  5806.      }                                                                          
  5807.      *(p+1) = '\0';                                                             
  5808.    }                                                                            
  5809.    *pointer = sbufp;                                                            
  5810.  }                                                                              
  5811.                                                                                 
  5812.  if (sp->time_to_go_home) return FALSE;                                         
  5813.  else return TRUE;                                                              
  5814. }                                                                               
  5815.                                                                                 
  5816. ./   ADD NAME=GGMIERR                                                           
  5817.                                                                                 
  5818.  /********************************************************************/         
  5819.  /*                                                                  */         
  5820.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5821.  /*                                                                  */         
  5822.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5823.  /*                                                                  */         
  5824.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5825.  /* including the implied warranties of merchantability and fitness, */         
  5826.  /* are expressly denied.                                            */         
  5827.  /*                                                                  */         
  5828.  /* Provided this copyright notice is included, this software may    */         
  5829.  /* be freely distributed and not offered for sale.                  */         
  5830.  /*                                                                  */         
  5831.  /* Changes or modifications may be made and used only by the maker  */         
  5832.  /* of same, and not further distributed.  Such modifications should */         
  5833.  /* be mailed to the author for consideration for addition to the    */         
  5834.  /* software and incorporation in subsequent releases.               */         
  5835.  /*                                                                  */         
  5836.  /********************************************************************/         
  5837.                                                                                 
  5838. #pragma  csect(code,  "GG@IERR ")                                               
  5839. #pragma  csect(static,"GG$IERR ")                                               
  5840. #include "gg.h"                                                                 
  5841.                                                                                 
  5842. /****** ISPF error handler. ******************************************/         
  5843.                                                                                 
  5844. void                                                                            
  5845. GGMierr(gp)                                                                     
  5846. Rstruc ggcb *gp;                                                                
  5847. {                                                                               
  5848.  char        errbuf[] = "DISPLAY PANEL(ISPTERM)";                               
  5849.  int         errlen;                                                            
  5850.                                                                                 
  5851.  errlen = strlen(errbuf);                                                       
  5852.  switch (ISPEXEC(&errlen,errbuf)) {                                             
  5853.    case  0:                                                                     
  5854.    case  4:                                                                     
  5855.    case  8:                                                                     
  5856.            return;                                                              
  5857.    default:                                                                     
  5858.            fprintf(stderr,                                                      
  5859. "\n*** Severe ISPF error, cannot even display ISPTERM error panel.\n");         
  5860.            fprintf(stderr,                                                      
  5861. "\n*** Return code from ISPF service is %d\n",gp->ispfrc);                      
  5862.            return;                                                              
  5863.  }                                                                              
  5864. }                                                                               
  5865.                                                                                 
  5866. ./   ADD NAME=GGMIGET                                                           
  5867.                                                                                 
  5868.  /********************************************************************/         
  5869.  /*                                                                  */         
  5870.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5871.  /*                                                                  */         
  5872.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5873.  /*                                                                  */         
  5874.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5875.  /* including the implied warranties of merchantability and fitness, */         
  5876.  /* are expressly denied.                                            */         
  5877.  /*                                                                  */         
  5878.  /* Provided this copyright notice is included, this software may    */         
  5879.  /* be freely distributed and not offered for sale.                  */         
  5880.  /*                                                                  */         
  5881.  /* Changes or modifications may be made and used only by the maker  */         
  5882.  /* of same, and not further distributed.  Such modifications should */         
  5883.  /* be mailed to the author for consideration for addition to the    */         
  5884.  /* software and incorporation in subsequent releases.               */         
  5885.  /*                                                                  */         
  5886.  /********************************************************************/         
  5887.                                                                                 
  5888. #pragma  csect(code,  "GG@IGET ")                                               
  5889. #pragma  csect(static,"GG$IGET ")                                               
  5890. #include "gg.h"                                                                 
  5891.                                                                                 
  5892. /****** Retrieve the value of an ISPF variable into an integer. ******/         
  5893.                                                                                 
  5894. int                                                                             
  5895. GGMiget(gp,varname)                                                             
  5896. Rstruc ggcb *gp;                                                                
  5897. char        *varname;                                                           
  5898. {                                                                               
  5899.  char        varbuf[16];                                                        
  5900.  int         vcopy_length;                                                      
  5901.                                                                                 
  5902.  if (!strchr(varname,' ')) {                                                    
  5903.    fprintf(stderr,"GGMiget: no blank passed in var name\n");                    
  5904.    return FALSE;                                                                
  5905.  }                                                                              
  5906.                                                                                 
  5907.  vcopy_length = sizeof(varbuf);                                                 
  5908.                                                                                 
  5909.  gp->ispfrc = ISPLINK("VCOPY",varname,&vcopy_length,varbuf,"MOVE");             
  5910.  switch (gp->ispfrc) {                                                          
  5911.    case  0:                                                                     
  5912.            varbuf[vcopy_length] = '\0';                                         
  5913.            return atoi(varbuf);                                                 
  5914.    case  8:                                                                     
  5915.            return 0;                                                            
  5916.    case 16:                                                                     
  5917.            fprintf(stderr,                                                      
  5918.                    "Error: ISPF variable buffer too short to get %s\n",         
  5919.                    varname);                                                    
  5920.            return 0;                                                            
  5921.    default:                                                                     
  5922.            GGMierr(gp);   /* handle ISPF error */                               
  5923.            return 0;                                                            
  5924.  }                                                                              
  5925. }                                                                               
  5926.                                                                                 
  5927. ./   ADD NAME=GGMINFO,SSI=01050051                                              
  5928.                                                                                 
  5929.  /********************************************************************/         
  5930.  /*                                                                  */         
  5931.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5932.  /*                                                                  */         
  5933.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5934.  /*                                                                  */         
  5935.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5936.  /* including the implied warranties of merchantability and fitness, */         
  5937.  /* are expressly denied.                                            */         
  5938.  /*                                                                  */         
  5939.  /* Provided this copyright notice is included, this software may    */         
  5940.  /* be freely distributed and not offered for sale.                  */         
  5941.  /*                                                                  */         
  5942.  /* Changes or modifications may be made and used only by the maker  */         
  5943.  /* of same, and not further distributed.  Such modifications should */         
  5944.  /* be mailed to the author for consideration for addition to the    */         
  5945.  /* software and incorporation in subsequent releases.               */         
  5946.  /*                                                                  */         
  5947.  /********************************************************************/         
  5948.                                                                                 
  5949. #pragma  csect(code,  "GG@INFO ")                                               
  5950. #pragma  csect(static,"GG$INFO ")                                               
  5951. #include "gg.h"                                                                 
  5952.                                                                                 
  5953.                                                                                 
  5954. /****** Gopher it. ***************************************************/         
  5955.                                                                                 
  5956. Bool                                                                            
  5957. GGMinfo(gp,ip)                                                                  
  5958. Rstruc ggcb        *gp;                                                         
  5959. Rstruc gopherinfo  *ip;                                                         
  5960. {                                                                               
  5961.  char               buf [513];                                                  
  5962.                                                                                 
  5963.  if (!ip) {                                                                     
  5964.    ERR1("Info is not available - this is not a Gopher item.");                  
  5965.    return FALSE;                                                                
  5966.  }                                                                              
  5967.                                                                                 
  5968.  GGMclrtx(gp,NULL);                                                             
  5969.                                                                                 
  5970.  sprintf(buf,"");                        GGMouttx(gp,buf,NULL);                 
  5971.  sprintf(buf,"Type=%c",ip->type);        GGMouttx(gp,buf,NULL);                 
  5972.  sprintf(buf,"Name=%s",ip->desc);        GGMouttx(gp,buf,NULL);                 
  5973.  sprintf(buf,"Path=%s",ip->path);        GGMouttx(gp,buf,NULL);                 
  5974.  sprintf(buf,"Host=%s",ip->host);        GGMouttx(gp,buf,NULL);                 
  5975.  sprintf(buf,"Port=%d",ip->port);        GGMouttx(gp,buf,NULL);                 
  5976.  sprintf(buf,"End");                     GGMouttx(gp,buf,NULL);                 
  5977.                                                                                 
  5978.  return TRUE;                                                                   
  5979. }                                                                               
  5980.                                                                                 
  5981. ./   ADD NAME=GGMISPF                                                           
  5982.                                                                                 
  5983.  /********************************************************************/         
  5984.  /*                                                                  */         
  5985.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5986.  /*                                                                  */         
  5987.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5988.  /*                                                                  */         
  5989.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5990.  /* including the implied warranties of merchantability and fitness, */         
  5991.  /* are expressly denied.                                            */         
  5992.  /*                                                                  */         
  5993.  /* Provided this copyright notice is included, this software may    */         
  5994.  /* be freely distributed and not offered for sale.                  */         
  5995.  /*                                                                  */         
  5996.  /* Changes or modifications may be made and used only by the maker  */         
  5997.  /* of same, and not further distributed.  Such modifications should */         
  5998.  /* be mailed to the author for consideration for addition to the    */         
  5999.  /* software and incorporation in subsequent releases.               */         
  6000.  /*                                                                  */         
  6001.  /********************************************************************/         
  6002.                                                                                 
  6003. #pragma  csect(code,  "GG@ISPF ")                                               
  6004. #pragma  csect(static,"GG$ISPF ")                                               
  6005. #include "gg.h"                                                                 
  6006.                                                                                 
  6007. /****** Call ISPF service. *******************************************/         
  6008.                                                                                 
  6009. Bool                                                                            
  6010. GGMispf(gp,ispfbuf)                                                             
  6011. Rstruc ggcb *gp;                                                                
  6012. char        *ispfbuf;                                                           
  6013. {                                                                               
  6014.  int         ispflen;                                                           
  6015.                                                                                 
  6016. #ifndef ISPFV2                                                                  
  6017.  if (gp->test_mode) {                                                           
  6018. #endif                                                                          
  6019.    if (ispflen >= 6                                                             
  6020.       && (memcmp(ispfbuf,"ADDPOP",6) == 0                                       
  6021.        || memcmp(ispfbuf,"REMPOP",6) == 0)) {                                   
  6022.      gp->ispfrc = 0;                                                            
  6023.      return TRUE;                                                               
  6024.    }                                                                            
  6025. #ifndef ISPFV2                                                                  
  6026.  }                                                                              
  6027. #endif                                                                          
  6028.                                                                                 
  6029.  ispflen = strlen(ispfbuf);                                                     
  6030.  gp->ispfrc = ISPEXEC(&ispflen,ispfbuf);                                        
  6031.  if (gp->ispfrc > 8) {                                                          
  6032.                                                                                 
  6033.    /* Ignore ADDPOP and REMPOP errors, especially if they are due to            
  6034.       ISPF V3 not being active. */                                              
  6035.                                                                                 
  6036.    if (gp->ispfrc == 20                                                         
  6037.     && gp->debug_mode == FALSE                                                  
  6038.     && ispflen >= 6                                                             
  6039.     && (memcmp(ispfbuf,"ADDPOP",6) == 0                                         
  6040.      || memcmp(ispfbuf,"REMPOP",6) == 0)) {                                     
  6041.      return TRUE;                                                               
  6042.    }                                                                            
  6043.                                                                                 
  6044.    GGMierr(gp);             /* handle ISPF error */                             
  6045.    return FALSE;                                                                
  6046.  }                                                                              
  6047.  return TRUE;                                                                   
  6048. }                                                                               
  6049.                                                                                 
  6050. ./   ADD NAME=GGMIVGET                                                          
  6051.                                                                                 
  6052.  /********************************************************************/         
  6053.  /*                                                                  */         
  6054.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6055.  /*                                                                  */         
  6056.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6057.  /*                                                                  */         
  6058.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6059.  /* including the implied warranties of merchantability and fitness, */         
  6060.  /* are expressly denied.                                            */         
  6061.  /*                                                                  */         
  6062.  /* Provided this copyright notice is included, this software may    */         
  6063.  /* be freely distributed and not offered for sale.                  */         
  6064.  /*                                                                  */         
  6065.  /* Changes or modifications may be made and used only by the maker  */         
  6066.  /* of same, and not further distributed.  Such modifications should */         
  6067.  /* be mailed to the author for consideration for addition to the    */         
  6068.  /* software and incorporation in subsequent releases.               */         
  6069.  /*                                                                  */         
  6070.  /********************************************************************/         
  6071.                                                                                 
  6072. #pragma  csect(code,  "GG@IVGET")                                               
  6073. #pragma  csect(static,"GG$IVGET")                                               
  6074. #include "gg.h"                                                                 
  6075.                                                                                 
  6076. /****** Retrieve the value of an ISPF variable. **********************/         
  6077.                                                                                 
  6078. Bool                                                                            
  6079. GGMivget(gp,varname,varbuf,varbuflen)                                           
  6080. Rstruc ggcb *gp;                                                                
  6081. char        *varname;                                                           
  6082. char        *varbuf;                                                            
  6083. int          varbuflen;                                                         
  6084. {                                                                               
  6085.  int         vcopy_length;                                                      
  6086.                                                                                 
  6087.  if (!strchr(varname,' ')) {                                                    
  6088.    fprintf(stderr,"GGMivget: no blank passed in var name\n");                   
  6089.    return FALSE;                                                                
  6090.  }                                                                              
  6091.                                                                                 
  6092.  /*                                                                             
  6093.   * If varbuflen is negative, that means that the value is not to be            
  6094.   * treated as a C string, and the null character is not to be                  
  6095.   * appended to the resulting value.  This is used for hex values               
  6096.   * (like addresses) that are stored in ISPF table row variables.               
  6097.   */                                                                            
  6098.                                                                                 
  6099.  if (varbuflen < 0)  vcopy_length = -varbuflen;                                 
  6100.  else vcopy_length = varbuflen;                                                 
  6101.                                                                                 
  6102.  /* Note that on entry, vcopy_length is an integer that contains                
  6103.     the length of the buffer.  On return it is updated to the length            
  6104.     of the value returned.  Since we have to stick a null character             
  6105.     on the end of it for C, the actual buffer passed must be at least           
  6106.     one character longer than the length as defined to ISPF.                    
  6107.  */                                                                             
  6108.                                                                                 
  6109.  gp->ispfrc = ISPLINK("VCOPY",varname,&vcopy_length,varbuf,"MOVE");             
  6110.  switch (gp->ispfrc) {                                                          
  6111.    case  0:                                                                     
  6112.            if (varbuflen >= 0)                                                  
  6113.               varbuf[vcopy_length] = '\0';                                      
  6114.            return TRUE;                                                         
  6115.    case  8:                                                                     
  6116.            strcpy(varbuf,"");                                                   
  6117.            return TRUE;                                                         
  6118.    case 16:                                                                     
  6119.            fprintf(stderr,                                                      
  6120.                    "Error: ISPF variable buffer too short to get %s\n",         
  6121.                    varname);                                                    
  6122.            return FALSE;                                                        
  6123.    default:                                                                     
  6124.            GGMierr(gp);   /* handle ISPF error */                               
  6125.            return FALSE;                                                        
  6126.  }                                                                              
  6127. }                                                                               
  6128.                                                                                 
  6129. ./   ADD NAME=GGMIVPUT                                                          
  6130.                                                                                 
  6131.  /********************************************************************/         
  6132.  /*                                                                  */         
  6133.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6134.  /*                                                                  */         
  6135.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6136.  /*                                                                  */         
  6137.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6138.  /* including the implied warranties of merchantability and fitness, */         
  6139.  /* are expressly denied.                                            */         
  6140.  /*                                                                  */         
  6141.  /* Provided this copyright notice is included, this software may    */         
  6142.  /* be freely distributed and not offered for sale.                  */         
  6143.  /*                                                                  */         
  6144.  /* Changes or modifications may be made and used only by the maker  */         
  6145.  /* of same, and not further distributed.  Such modifications should */         
  6146.  /* be mailed to the author for consideration for addition to the    */         
  6147.  /* software and incorporation in subsequent releases.               */         
  6148.  /*                                                                  */         
  6149.  /********************************************************************/         
  6150.                                                                                 
  6151. #pragma  csect(code,  "GG@IVPUT")                                               
  6152. #pragma  csect(static,"GG$IVPUT")                                               
  6153. #include "gg.h"                                                                 
  6154.                                                                                 
  6155. /****** Set the value of an ISPF variable. ***************************/         
  6156.                                                                                 
  6157. Bool                                                                            
  6158. GGMivput(gp,varname,varbuf,varlen)                                              
  6159. Rstruc ggcb *gp;                                                                
  6160. char        *varname;                                                           
  6161. char        *varbuf;                                                            
  6162. int          varlen;                                                            
  6163. {                                                                               
  6164.  int         vreplace_length;                                                   
  6165.                                                                                 
  6166.  vreplace_length = (varlen<0 ? strlen(varbuf) : varlen);                        
  6167.                                                                                 
  6168.  gp->ispfrc = ISPLINK("VREPLACE",varname,&vreplace_length,varbuf);              
  6169.  switch (gp->ispfrc) {                                                          
  6170.    case  0:                                                                     
  6171.            return TRUE;                                                         
  6172.    case 16:                                                                     
  6173.            fprintf(stderr,                                                      
  6174.                    "Error: ISPF variable buffer too short to put %s\n",         
  6175.                    varname);                                                    
  6176.            return FALSE;                                                        
  6177.    default:                                                                     
  6178.            GGMierr(gp);   /* handle ISPF error */                               
  6179.            return FALSE;                                                        
  6180.  }                                                                              
  6181. }                                                                               
  6182.                                                                                 
  6183. ./   ADD NAME=GGMMENU,SSI=01080012                                              
  6184.                                                                                 
  6185.  /********************************************************************/         
  6186.  /*                                                                  */         
  6187.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6188.  /*                                                                  */         
  6189.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6190.  /*                                                                  */         
  6191.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6192.  /* including the implied warranties of merchantability and fitness, */         
  6193.  /* are expressly denied.                                            */         
  6194.  /*                                                                  */         
  6195.  /* Provided this copyright notice is included, this software may    */         
  6196.  /* be freely distributed and not offered for sale.                  */         
  6197.  /*                                                                  */         
  6198.  /* Changes or modifications may be made and used only by the maker  */         
  6199.  /* of same, and not further distributed.  Such modifications should */         
  6200.  /* be mailed to the author for consideration for addition to the    */         
  6201.  /* software and incorporation in subsequent releases.               */         
  6202.  /*                                                                  */         
  6203.  /********************************************************************/         
  6204.                                                                                 
  6205. #pragma  csect(code,  "GG@MENU ")                                               
  6206. #pragma  csect(static,"GG$MENU ")                                               
  6207. #include "gg.h"                                                                 
  6208.                                                                                 
  6209. /****** Display Gopher menu in data set. *****************************/         
  6210.                                                                                 
  6211. Bool                                                                            
  6212. GGMmenu(gp,pp)                                                                  
  6213. Rstruc ggcb             *gp;                                                    
  6214. char                    *pp;                                                    
  6215. {                                                                               
  6216.  struct gopherinfo      *ip;                                                    
  6217.  struct gopherinfo      *saveip;                                                
  6218.  char                   *cp;                                                    
  6219.  Bool                    rc;                                                    
  6220.  char                    zprefix[9];                                            
  6221.  char                    temp[129];                                             
  6222.  char                    savebook[63];                                          
  6223.                                                                                 
  6224.  if (!*pp) {                                                                    
  6225.    ERR1("You must supply a data set name for a Gopher menu.");                  
  6226.    return FALSE;                                                                
  6227.  }                                                                              
  6228.                                                                                 
  6229.  if (strlen(pp) >= sizeof(temp)) {                                              
  6230.    ERR1("Gopher menu name too long");                                           
  6231.    return FALSE;                                                                
  6232.  }                                                                              
  6233.                                                                                 
  6234.  GETMAIN(ip, struct gopherinfo, 1, "menu gopherinfo struct");                   
  6235.  if (!ip) {                                                                     
  6236.    ERR2("Not enough memory to load Gopher menu %s",pp);                         
  6237.    return FALSE;                                                                
  6238.  }                                                                              
  6239.                                                                                 
  6240.  memset(ip,0,sizeof(struct gopherinfo));                                        
  6241.                                                                                 
  6242.                                                                                 
  6243.  copy_uppercase(temp,pp);                                                       
  6244.                                                                                 
  6245.  if (temp[0] == '\'') {                                                         
  6246.    strcpy(ip->path, temp+1);                                                    
  6247.    cp = &ip->path[strlen(ip->path)-1];                                          
  6248.    if (*cp == '\'') *cp = '\0';                                                 
  6249.  }                                                                              
  6250.  else {                                                                         
  6251.    GGMivget(gp,"ZPREFIX ",zprefix,sizeof(zprefix));                             
  6252.    if (!*zprefix)  sprintf(ip->path,"'%s'",pp);                                 
  6253.    else sprintf(ip->path,"%s.%s",zprefix,pp);                                   
  6254.  }                                                                              
  6255.                                                                                 
  6256.  ip->type = MENU;                                                               
  6257.  sprintf(ip->desc,"User menu %s",ip->path);                                     
  6258.  strcpy (ip->host, "-");                                                        
  6259.  ip->port = SERV_TCP_PORT;                                                      
  6260.                                                                                 
  6261.  saveip = gp->ginfo;                                                            
  6262.  gp->ginfo = ip;                                                                
  6263.  strcpy(savebook,gp->current_bookmark_ds);                                      
  6264.  strncpy(gp->current_bookmark_ds,ip->path,sizeof(savebook));                    
  6265.                                                                                 
  6266.  rc = GGMgofor(gp,ip,FALSE);                                                    
  6267.                                                                                 
  6268.  gp->ginfo = saveip;                                                            
  6269.  strcpy(gp->current_bookmark_ds,savebook);                                      
  6270.                                                                                 
  6271.  FREEMAIN(ip,"menu gopherinfo struct");                                         
  6272.                                                                                 
  6273.  return rc;                                                                     
  6274. }                                                                               
  6275.                                                                                 
  6276. ./   ADD NAME=GGMMTFER                                                          
  6277.                                                                                 
  6278.  /********************************************************************/         
  6279.  /*                                                                  */         
  6280.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6281.  /*                                                                  */         
  6282.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6283.  /*                                                                  */         
  6284.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6285.  /* including the implied warranties of merchantability and fitness, */         
  6286.  /* are expressly denied.                                            */         
  6287.  /*                                                                  */         
  6288.  /* Provided this copyright notice is included, this software may    */         
  6289.  /* be freely distributed and not offered for sale.                  */         
  6290.  /*                                                                  */         
  6291.  /* Changes or modifications may be made and used only by the maker  */         
  6292.  /* of same, and not further distributed.  Such modifications should */         
  6293.  /* be mailed to the author for consideration for addition to the    */         
  6294.  /* software and incorporation in subsequent releases.               */         
  6295.  /*                                                                  */         
  6296.  /********************************************************************/         
  6297.                                                                                 
  6298. #pragma  csect(code,  "GG@MTFER")                                               
  6299. #pragma  csect(static,"GG$MTFER")                                               
  6300. #include "gg.h"                                                                 
  6301.                                                                                 
  6302. /*********************************************************************/         
  6303.                                                                                 
  6304. void                                                                            
  6305. GGMmtfer(                                                                       
  6306.          int          retcode,                                                  
  6307.          char        *kind)                                                     
  6308. {                                                                               
  6309.  char    *ermsg;                                                                
  6310.                                                                                 
  6311.  switch (retcode) {                                                             
  6312.    case MTF_OK:                                                                 
  6313.         ermsg = NULL;                                                           
  6314.         break;                                                                  
  6315.    case EINACTIVE:                                                              
  6316.         ermsg = "MTF is inactive";                                              
  6317.         break;                                                                  
  6318.    case ESUBCALL:                                                               
  6319.         ermsg = "The MTF call was issued from a subtask";                       
  6320.         break;                                                                  
  6321.    case EWRONGOS:                                                               
  6322.         ermsg = "MTF is not supported under CMS, IMS, CICS, or DB2";            
  6323.         break;                                                                  
  6324.    case EACTIVE:                                                                
  6325.         ermsg = "MTF has already been initialized and is active";               
  6326.         break;                                                                  
  6327.    case ENAME2LNG:                                                              
  6328.         ermsg = "The parallel module name is longer than 8 characters";         
  6329.         break;                                                                  
  6330.    case ETASKNUM:                                                               
  6331.         ermsg = "The number of tasks specified is invalid";                     
  6332.         break;                                                                  
  6333.    case ENOMEM:                                                                 
  6334.         ermsg = "Insufficient storage for MTF internal areas";                  
  6335.         break;                                                                  
  6336.    case EMODFIND:                                                               
  6337.         ermsg = "The parallel load module was not found";                       
  6338.         break;                                                                  
  6339.    case EMODREAD:                                                               
  6340.         ermsg = "The parallel load module was not sucessfully read";            
  6341.         break;                                                                  
  6342.    case EMODFMT:                                                                
  6343.         ermsg = "The parallel load module format is invalid";                   
  6344.         break;                                                                  
  6345.    case EAUTOALC:                                                               
  6346.         ermsg = "Automatic allocation of standard stream DD failed";            
  6347.         break;                                                                  
  6348.    case ETASKFAIL:                                                              
  6349.         ermsg = "The attempt to attach task(s) has failed";                     
  6350.         break;                                                                  
  6351.    case ETASKABND:                                                              
  6352.         ermsg = "One or more subtasks have abnormally terminated";              
  6353.         break;                                                                  
  6354.    case EBADLNKG:                                                               
  6355.         ermsg = "TSCHED has been invoked via invalid linkage";                  
  6356.         break;                                                                  
  6357.    case ETASKID:                                                                
  6358.         ermsg = "The task ID specified is not valid";                           
  6359.         break;                                                                  
  6360.    case EENTRY:                                                                 
  6361.         ermsg = "The parallel function was not in the parallel module";         
  6362.         break;                                                                  
  6363.    default:                                                                     
  6364.         ermsg = "Unknown MTF error";                                            
  6365.         break;                                                                  
  6366.  }                                                                              
  6367.                                                                                 
  6368.  if (ermsg) {                                                                   
  6369.    fprintf(stderr,"GGSERVER: %s error code %d:\n %s\n",                         
  6370.                   kind, retcode, ermsg);                                        
  6371.  }                                                                              
  6372.                                                                                 
  6373.  return;                                                                        
  6374.                                                                                 
  6375. }                                                                               
  6376.                                                                                 
  6377. ./   ADD NAME=GGMOUTS                                                           
  6378.                                                                                 
  6379.  /********************************************************************/         
  6380.  /*                                                                  */         
  6381.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6382.  /*                                                                  */         
  6383.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6384.  /* including the implied warranties of merchantability and fitness, */         
  6385.  /* are expressly denied.                                            */         
  6386.  /*                                                                  */         
  6387.  /* Provided this copyright notice is included, this software may    */         
  6388.  /* be freely distributed and not offered for sale.                  */         
  6389.  /*                                                                  */         
  6390.  /* Changes or modifications may be made and used only by the maker  */         
  6391.  /* of same, and not further distributed.  Such modifications should */         
  6392.  /* be mailed to the author for consideration for addition to the    */         
  6393.  /* software and incorporation in subsequent releases.               */         
  6394.  /*                                                                  */         
  6395.  /********************************************************************/         
  6396.                                                                                 
  6397. #pragma  csect(code,  "GG@MOUTS")                                               
  6398. #pragma  csect(static,"GG$MOUTS")                                               
  6399.                                                                                 
  6400. #include "gg.h"                                                                 
  6401. /*                                                                              
  6402.  ***********************************************************************        
  6403.  *                                                                     *        
  6404.  * This is a Gopher server routine that outputs data to a socket.      *        
  6405.  *                                                                     *        
  6406.  * If the "socket" is actually a file pointer, then output is          *        
  6407.  * written to the file pointer.                                        *        
  6408.  *                                                                     *        
  6409.  ***********************************************************************        
  6410.  */                                                                             
  6411.                                                                                 
  6412. /*=================================================================*/           
  6413.                                                                                 
  6414. Bool                                                                            
  6415. GGMouts(struct recvstruct *R,                                                   
  6416.         char              *text)                                                
  6417. {                                                                               
  6418.  int                len;                                                        
  6419.  int                reallen;                                                    
  6420.  Bool               rc;                                                         
  6421.  char               outbuf[515];  /* hold an output character string */         
  6422.                                                                                 
  6423.  if (R->outfp) {                    /* if using non-socket interface */         
  6424.    if (fputs(text,R->outfp) < 0) {                                              
  6425.      fprintf(stderr,"Error writing to output file\n");                          
  6426.      return FALSE;                                                              
  6427.    }                                                                            
  6428.    if (fputc('\n',R->outfp) < 0) {                                              
  6429.      fprintf(stderr,"Error writing to output file\n");                          
  6430.      return FALSE;                                                              
  6431.    }                                                                            
  6432.    return TRUE;                                                                 
  6433.  }                                                                              
  6434.                                                                                 
  6435.  if (text == NULL) {                                                            
  6436.    outbuf[0] = '.';                                                             
  6437.    len = 1;                                                                     
  6438.  }                                                                              
  6439.  else {                                                                         
  6440.    len = strlen(text);                                                          
  6441.    if (len >= sizeof(outbuf)-3) len = sizeof(outbuf)-3;                         
  6442.    if (text[0] == '.') {                                                        
  6443.      outbuf[0] = '.';                                                           
  6444.      memcpy(outbuf+1,text,len);                                                 
  6445.      len++;                                                                     
  6446.    }                                                                            
  6447.    else {                                                                       
  6448.      memcpy(outbuf,text,len);                                                   
  6449.    }                                                                            
  6450.  }                                                                              
  6451.  outbuf[len  ] = CARRIAGE_RETURN;                                               
  6452.  outbuf[len+1] = LINE_FEED;                                                     
  6453.  outbuf[len+2] = '\0';                                                          
  6454.  reallen = len + 2;                                                             
  6455.                                                                                 
  6456. #ifdef SNSTCPIP                                                                 
  6457.  EBCDIC_TO_ASCII(outbuf,reallen);                                               
  6458. #else                                                                           
  6459.  ebdtoasc(outbuf);                                                              
  6460. #endif                                                                          
  6461.                                                                                 
  6462.  rc = TRUE;                                                                     
  6463.                                                                                 
  6464.  if (R->outlen + reallen > sizeof(R->sockbuf)) {                                
  6465.                                                                                 
  6466.    if (write(R->sockfd,R->sockbuf,R->outlen) < 0) {                             
  6467.      REPORT_TCP_ERROR("SEND");                                                  
  6468.      rc = FALSE;                                                                
  6469.    }                                                                            
  6470.    R->outlen = 0;                                                               
  6471.  }                                                                              
  6472.                                                                                 
  6473.  memcpy(R->sockbuf + R->outlen, outbuf, reallen);                               
  6474.  R->outlen += reallen;                                                          
  6475.                                                                                 
  6476.  if (text == NULL) {  /* flush socket */                                        
  6477.    if (write(R->sockfd,R->sockbuf,R->outlen) < 0) {                             
  6478.      REPORT_TCP_ERROR("SEND");                                                  
  6479.      rc = FALSE;                                                                
  6480.    }                                                                            
  6481.  }                                                                              
  6482.  return rc;                                                                     
  6483. }                                                                               
  6484.                                                                                 
  6485. ./   ADD NAME=GGMOUTTX                                                          
  6486.                                                                                 
  6487.  /********************************************************************/         
  6488.  /*                                                                  */         
  6489.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6490.  /*                                                                  */         
  6491.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6492.  /*                                                                  */         
  6493.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6494.  /* including the implied warranties of merchantability and fitness, */         
  6495.  /* are expressly denied.                                            */         
  6496.  /*                                                                  */         
  6497.  /* Provided this copyright notice is included, this software may    */         
  6498.  /* be freely distributed and not offered for sale.                  */         
  6499.  /*                                                                  */         
  6500.  /* Changes or modifications may be made and used only by the maker  */         
  6501.  /* of same, and not further distributed.  Such modifications should */         
  6502.  /* be mailed to the author for consideration for addition to the    */         
  6503.  /* software and incorporation in subsequent releases.               */         
  6504.  /*                                                                  */         
  6505.  /********************************************************************/         
  6506.                                                                                 
  6507. #pragma  csect(code,  "GG@OUTTX")                                               
  6508. #pragma  csect(static,"GG$OUTTX")                                               
  6509. #include "gg.h"                                                                 
  6510.                                                                                 
  6511. /****** Output a line of text retrieved from the server. *************/         
  6512.                                                                                 
  6513. struct textline *                                                               
  6514. GGMouttx(gp,line,ip)                                                            
  6515. Rstruc ggcb         *gp;                                                        
  6516. char                *line;                                                      
  6517. Rstruc gopherinfo   *ip;                                                        
  6518.                                                                                 
  6519. {                                                                               
  6520.  struct texthdr     *thp;                                                       
  6521.  struct textline    *tp;                                                        
  6522.  short              line_length;                                                
  6523.  short              total_text_length;                                          
  6524.  short              tab_expansion_length;                                       
  6525.  Bool               tabs_present;                                               
  6526.  char              *p;                                                          
  6527.  char              *q;                                                          
  6528.  char              *t;                                                          
  6529.  int                e;                                                          
  6530.  int                u;                                                          
  6531.                                                                                 
  6532.  static char        tab_expansion_buffer[8*TEXT_BYTES];                         
  6533.                                                                                 
  6534.  thp = (ip ? &ip->thdr : &gp->thdr);                                            
  6535.                                                                                 
  6536.  /* If line starts with double period, make it a single period. */              
  6537.                                                                                 
  6538.  if (ip && memcmp(line,"..",2) == 0) line++;                                    
  6539.                                                                                 
  6540.  /* Add this line to the current queue of server text lines. */                 
  6541.                                                                                 
  6542.  /* First, expand tabs in the line. */                                          
  6543.                                                                                 
  6544.  line_length = strlen(line);                                                    
  6545.  t = strchr(line,'\t');                                                         
  6546.  if (t == NULL) {                                                               
  6547.    tabs_present = FALSE;                                                        
  6548.    total_text_length = line_length + 1;                                         
  6549.  }                                                                              
  6550.  else {                                   /* expand tabs */                     
  6551.    tabs_present = TRUE;                                                         
  6552.    p = line;                                                                    
  6553.    q = line + line_length;                                                      
  6554.    e = 0;                                                                       
  6555.    memset(tab_expansion_buffer,' ',sizeof(tab_expansion_buffer));               
  6556.    while (TRUE) {                                                               
  6557.      u = t-p;                                                                   
  6558.      if (u > 0) {                                                               
  6559.        memcpy(tab_expansion_buffer+e,p,u);                                      
  6560.        e += u;                                                                  
  6561.      }                                                                          
  6562.      if (t == q) break;                                                         
  6563.      e = e / 8 * 8 + 8;                                                         
  6564.      p = t+1;                                                                   
  6565.      t = strchr(p,'\t');                                                        
  6566.      if (t == NULL) t = q;                                                      
  6567.    }                                                                            
  6568.    tab_expansion_length = e;                                                    
  6569.    tab_expansion_buffer[tab_expansion_length] = '\0';                           
  6570.    total_text_length = line_length + tab_expansion_length + 1;                  
  6571.  }                                                                              
  6572.                                                                                 
  6573.  GETMAIN(tp, char, offsetof(struct textline, text) + total_text_length,         
  6574.                    "text line");                                                
  6575.                                                                                 
  6576.  if (tp == NULL) {                                                              
  6577.    ERR1("There is not enough virtual storage to process server text.");         
  6578.    return NULL;                                                                 
  6579.  }                                                                              
  6580.                                                                                 
  6581.  tp->next = NULL;                                                               
  6582.  tp->text_length = line_length;                                                 
  6583.  strcpy(tp->text,line);                                                         
  6584.  if (tabs_present) {                                                            
  6585.    tp->tab_expanded_text_length = tab_expansion_length;                         
  6586.    tp->tab_expanded_text = tp->text + line_length;                              
  6587.    strcpy(tp->tab_expanded_text,tab_expansion_buffer);                          
  6588.  }                                                                              
  6589.  else {                                                                         
  6590.    tp->tab_expanded_text_length = line_length;                                  
  6591.    tp->tab_expanded_text = tp->text;                                            
  6592.  }                                                                              
  6593.                                                                                 
  6594.  if (thp->last_text_line == NULL) {                                             
  6595.    thp->first_text_line   = tp;                                                 
  6596.    thp->text_body_line    = tp;                                                 
  6597.    thp->current_text_line = tp;                                                 
  6598.  }                                                                              
  6599.  else thp->last_text_line->next = tp;                                           
  6600.                                                                                 
  6601.  thp->last_text_line = tp;                                                      
  6602.  thp->text_line_count++;                                                        
  6603.                                                                                 
  6604.  if (thp->text_max_length < tp->text_length)                                    
  6605.      thp->text_max_length = tp->text_length;                                    
  6606.  if (thp->text_max_tab_expanded_length < tp->tab_expanded_text_length)          
  6607.      thp->text_max_tab_expanded_length = tp->tab_expanded_text_length;          
  6608.                                                                                 
  6609.  return tp;                                                                     
  6610.                                                                                 
  6611. }                                                                               
  6612.                                                                                 
  6613. ./   ADD NAME=GGMPMSG                                                           
  6614.                                                                                 
  6615.  /********************************************************************/         
  6616.  /*                                                                  */         
  6617.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6618.  /*                                                                  */         
  6619.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6620.  /*                                                                  */         
  6621.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6622.  /* including the implied warranties of merchantability and fitness, */         
  6623.  /* are expressly denied.                                            */         
  6624.  /*                                                                  */         
  6625.  /* Provided this copyright notice is included, this software may    */         
  6626.  /* be freely distributed and not offered for sale.                  */         
  6627.  /*                                                                  */         
  6628.  /* Changes or modifications may be made and used only by the maker  */         
  6629.  /* of same, and not further distributed.  Such modifications should */         
  6630.  /* be mailed to the author for consideration for addition to the    */         
  6631.  /* software and incorporation in subsequent releases.               */         
  6632.  /*                                                                  */         
  6633.  /********************************************************************/         
  6634.                                                                                 
  6635. #define  SUPPRESS_V_DECLARATION                                                 
  6636. #pragma  csect(code,  "GG@PMSG ")                                               
  6637. #pragma  csect(static,"GG$PMSG ")                                               
  6638. #include "gg.h"                                                                 
  6639.                                                                                 
  6640. /****** Set an ISPF message, or write to SYSOUT if batch mode. *******/         
  6641.                                                                                 
  6642. void                                                                            
  6643. GGMpmsg(gp,msgtype,msghelp,msgformat) /* also ... for sprintf args */           
  6644. Rstruc ggcb *gp;                                                                
  6645. int          msgtype;                                                           
  6646. char        *msghelp;                                                           
  6647. char        *msgformat;                                                         
  6648. {                                                                               
  6649.  va_list     argp;                                                              
  6650.  char       *cp;                                                                
  6651.  char        zerrsm    [25];                                                    
  6652.  char        zerrhm     [9];                                                    
  6653.  char        zerralrm   [4];                                                    
  6654.  char        zerrlm   [ZERRLM_SIZE];                                            
  6655.  char        buf      [257];                                                    
  6656.                                                                                 
  6657.  va_start(argp,msgformat);                                                      
  6658.  vsprintf(buf,msgformat,argp);                                                  
  6659.  va_end(argp);                                                                  
  6660.                                                                                 
  6661.  cp = strchr(buf,';');                                                          
  6662.  if (cp) {                                                                      
  6663.   *cp = '\0';                                                                   
  6664.   strncpy(zerrsm,buf, sizeof(zerrsm));                                          
  6665.   strncpy(zerrlm,cp+1,sizeof(zerrlm));                                          
  6666.  }                                                                              
  6667.  else {                                                                         
  6668.   strcpy(zerrsm,"");                                                            
  6669.   strncpy(zerrlm,buf,sizeof(zerrlm));                                           
  6670.  }                                                                              
  6671.                                                                                 
  6672.  zerrsm[sizeof(zerrsm)-1] = '\0';                                               
  6673.  zerrlm[sizeof(zerrlm)-1] = '\0';                                               
  6674.                                                                                 
  6675.  if (msghelp) strcpy(zerrhm, msghelp);                                          
  6676.  else         strcpy(zerrhm, "*"    );                                          
  6677.                                                                                 
  6678.  switch (msgtype) {                                                             
  6679.    case NOTIFY_MSG:    strcpy(zerralrm,"NO "); break;                           
  6680.    case WARNING_MSG:                                                            
  6681.    case CRITICAL_MSG:                                                           
  6682.    default:            strcpy(zerralrm,"YES"); break;                           
  6683.  }                                                                              
  6684.                                                                                 
  6685.  (void)GGMivput(gp,"ZERRSM ",  zerrsm,   -1);                                   
  6686.  (void)GGMivput(gp,"ZERRLM ",  zerrlm,   -1);                                   
  6687.  (void)GGMivput(gp,"ZERRHM ",  zerrhm,   -1);                                   
  6688.  (void)GGMivput(gp,"ZERRALRM ",zerralrm, -1);                                   
  6689.                                                                                 
  6690.  gp->setmsg = TRUE;                                                             
  6691.                                                                                 
  6692.  return;                                                                        
  6693. }                                                                               
  6694.                                                                                 
  6695. ./   ADD NAME=GGMPROC,SSI=01030021                                              
  6696.                                                                                 
  6697.  /********************************************************************/         
  6698.  /*                                                                  */         
  6699.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6700.  /*                                                                  */         
  6701.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6702.  /* including the implied warranties of merchantability and fitness, */         
  6703.  /* are expressly denied.                                            */         
  6704.  /*                                                                  */         
  6705.  /* Provided this copyright notice is included, this software may    */         
  6706.  /* be freely distributed and not offered for sale.                  */         
  6707.  /*                                                                  */         
  6708.  /* Changes or modifications may be made and used only by the maker  */         
  6709.  /* of same, and not further distributed.  Such modifications should */         
  6710.  /* be mailed to the author for consideration for addition to the    */         
  6711.  /* software and incorporation in subsequent releases.               */         
  6712.  /*                                                                  */         
  6713.  /********************************************************************/         
  6714.                                                                                 
  6715. #pragma  csect(code,  "GG@MPROC")                                               
  6716. #pragma  csect(static,"GG$MPROC")                                               
  6717.                                                                                 
  6718. #pragma  linkage(IRXEXEC,OS)                                                    
  6719.                                                                                 
  6720. #include "gg.h"                                                                 
  6721.                                                                                 
  6722. /**********************************************************************         
  6723.  *                                                                    *         
  6724.  * Changes: 02/17/93 Fixed memcmp logic in append-domain-name code.   *         
  6725.  *                                                                    *         
  6726.  **********************************************************************/        
  6727.                                                                                 
  6728. /*=================================================================*/           
  6729.                                                                                 
  6730. /*******************************************************************/           
  6731. /*   This routine cleans up a token.  It converts all chars to     */           
  6732. /*   upper case and removes any leading spaces. Note that the      */           
  6733. /*   string is assumed to be null terminated.                      */           
  6734. /*                                                                 */           
  6735. /*       INPUT    token          pointer to token string.          */           
  6736. /*       OUTPUT   *token         string upcased, blanks removed.   */           
  6737. /*******************************************************************/           
  6738.                                                                                 
  6739. static char *                                                                   
  6740. uppercase_and_trim_leading_space(char *token)                                   
  6741. {                                                                               
  6742.                                                                                 
  6743.  uppercase_in_place(token);                                                     
  6744.                                                                                 
  6745.  return token + strspn(token," ");                                              
  6746. };                                                                              
  6747.                                                                                 
  6748. /*=================================================================*/           
  6749.                                                                                 
  6750. /****************************************************/                          
  6751. /* This routine "cleans" a string by removing the   */                          
  6752. /* leading spaces and trailing spaces+non-printable */                          
  6753. /* characters.                                      */                          
  6754. /****************************************************/                          
  6755.                                                                                 
  6756. static char *                                                                   
  6757. trim_leading_and_trailing_space(char *string)                                   
  6758. {                                                                               
  6759. char *str;                                                                      
  6760. char *ptr;                                                                      
  6761.                                                                                 
  6762.  /*  first clean up the beginning of the string... */                           
  6763.                                                                                 
  6764.  str = string + strspn(string," \t");                                           
  6765.                                                                                 
  6766.  /*    now look at the end of the string... */                                  
  6767.                                                                                 
  6768.  ptr = str+strlen(str)-1;                                                       
  6769.  while (!isgraph(*ptr) && ptr >=str) ptr--;                                     
  6770.  *(ptr+1)=0;                                                                    
  6771.                                                                                 
  6772.  return str;                                                                    
  6773. }                                                                               
  6774.                                                                                 
  6775. /*=================================================================*/           
  6776.                                                                                 
  6777. /****************************************************/                          
  6778. /* This routine "cleans" an output line by removing */                          
  6779. /* trailing spaces and non-printable characters.    */                          
  6780. /****************************************************/                          
  6781.                                                                                 
  6782. static void                                                                     
  6783. trim_trailing_space(char *string)                                               
  6784. {                                                                               
  6785.  char *ptr;                                                                     
  6786.                                                                                 
  6787.  ptr = string;                                                                  
  6788.                                                                                 
  6789.  /*  look at the end of the string... */                                        
  6790.                                                                                 
  6791.  ptr = string+strlen(string)-1;                                                 
  6792.  while (isgraph(*ptr)==0 && ptr >=string) ptr--;                                
  6793.  *(ptr+1)=0;                                                                    
  6794. }                                                                               
  6795.                                                                                 
  6796. /*=================================================================*/           
  6797.                                                                                 
  6798. static void                                                                     
  6799. gbarf(struct recvstruct *R,                                                     
  6800.       char              *message)                                               
  6801. {                                                                               
  6802.  char        temp[257];                                                         
  6803.                                                                                 
  6804.  /* the number should be 3 (ERROR) but some clients may not show it             
  6805.   *             |                                                               
  6806.   *             |                                                               
  6807.   *             |                                                               
  6808.   *             V                                                               
  6809.   */                                                                            
  6810.  sprintf(temp, "1Sorry, %s.\t0\t0\t0", message);                                
  6811.                                                                                 
  6812.  (void)GGMouts(R,temp);                                                         
  6813.                                                                                 
  6814.  return;                                                                        
  6815. }                                                                               
  6816.                                                                                 
  6817. /*=================================================================*/           
  6818.                                                                                 
  6819. static Bool                                                                     
  6820. insure_my_name(struct recvstruct *R)                                            
  6821. {                                                                               
  6822.  int                hostlen;                                                    
  6823.  int                domslen;                                                    
  6824.                                                                                 
  6825.  /* Determine the local path name, if not already set. */                       
  6826.                                                                                 
  6827.  if (!*R->myname) {                                                             
  6828.    if (gethostname(R->myname,MAXHOSTNAMELEN) < 0) {                             
  6829.      fprintf(stderr,"GOPHER:gethostname() failed, can't get my name\n");        
  6830.      gbarf(R,"the GOPHER server had an attack of amnesia");                     
  6831.      return FALSE;                                                              
  6832.    }                                                                            
  6833.                                                                                 
  6834. #ifdef APPEND_DOMAIN_NAME_TO_SELF                                               
  6835.                                                                                 
  6836.    hostlen = strlen(R->myname);                                                 
  6837.    domslen = strlen(R->mydomain);                                               
  6838.    if (hostlen <= domslen ||                                                    
  6839.       memcmp(R->myname+hostlen-domslen, R->mydomain, domslen)) {                
  6840.      strncat(R->myname, R->mydomain, domslen);                                  
  6841.    }                                                                            
  6842.                                                                                 
  6843. #endif                                                                          
  6844.                                                                                 
  6845.    uppercase_in_place(R->myname);                                               
  6846.                                                                                 
  6847.    /* fprintf(stderr,"Local hostname set to '%s'\n",R->myname); */              
  6848.                                                                                 
  6849.  }                                                                              
  6850.                                                                                 
  6851.  return TRUE;                                                                   
  6852.                                                                                 
  6853. }                                                                               
  6854.                                                                                 
  6855. /*=================================================================*/           
  6856.                                                                                 
  6857. static Bool                                                                     
  6858. authorized_file(struct recvstruct *R)                                           
  6859. {                                                                               
  6860.  char    *cp;                                                                   
  6861.  FILE    *afp;                                                                  
  6862.  int      n;                                                                    
  6863.  int      hostcount;                                                            
  6864.  Bool     rc;                                                                   
  6865.  char     filetest[RBUFSIZE];                                                   
  6866.  char     accline [RBUFSIZE];                                                   
  6867.  char     accfile [RBUFSIZE];                                                   
  6868.  char     acchost [RBUFSIZE];                                                   
  6869.                                                                                 
  6870.  /* If non-socket interface, bypass the authorization check. */                 
  6871.                                                                                 
  6872.  if (R->outfp) return TRUE;                                                     
  6873.                                                                                 
  6874.  /* Check that the server is allowed to return data from the file               
  6875.   * specified in R->fileptr.  Note that this could be the name of               
  6876.   * an exec.  The name will be (dataset), EXEC:execname, or DD:file             
  6877.   * - we look at only the first part, whitespace-delimited.                     
  6878.   * Entries in the file authorization table look as above.                      
  6879.   */                                                                            
  6880.                                                                                 
  6881.  rc = FALSE;                                                                    
  6882.  filetest[0] = '\0';                                                            
  6883.  sscanf(R->fileptr,"%s",filetest);                                              
  6884.                                                                                 
  6885.  /* Read authorization file. */                                                 
  6886.                                                                                 
  6887.  afp = fopen(ACCESS_TABLE,"r");                                                 
  6888.  if (!afp) {                                                                    
  6889.    perror(ACCESS_TABLE);                                                        
  6890.    fflush(stderr);                                                              
  6891.    return FALSE;                                                                
  6892.  }                                                                              
  6893.                                                                                 
  6894.  for (;;) {                                                                     
  6895.    fgets(accline, sizeof(accline), afp);                                        
  6896.    if (ferror(afp)) {                                                           
  6897.      fprintf(stderr,"Error reading access table %s\n",ACCESS_TABLE);            
  6898.      fflush(stderr);                                                            
  6899.      break;                                                                     
  6900.    }                                                                            
  6901.    if (feof(afp)) break;                                                        
  6902.    /* format of line is: filename machine(s) */                                 
  6903.    uppercase_in_place(accline);                                                 
  6904.    cp = accline;                      /* Start scan pointer         */          
  6905.    *accfile = '\0';                   /* Clear access file name     */          
  6906.    sscanf(cp,"%s %n",accfile,&n);     /* Get file name, bump scan   */          
  6907.    if (!strcmp(filetest,accfile)) {   /* If file name matches       */          
  6908.      hostcount = 0;                   /* Clear access host count    */          
  6909.      for (;;) {                       /* Loop over access host ids  */          
  6910.        cp += n;                       /* Bump to next word in file  */          
  6911.        *acchost = '\0';               /* Clear word before scanf    */          
  6912.        sscanf(cp,"%s %n",acchost,&n); /* Get next word, bump scan   */          
  6913.        if (!*acchost) break;          /* exit loop if no more hosts */          
  6914.        hostcount++;                   /* increment access host count*/          
  6915.        if (!strcmp(R->hostname,acchost)                                         
  6916.         || !strcmp(R->hosttest,acchost)) { /* if hostname matches */            
  6917.          rc = TRUE;                        /* access is allowed   */            
  6918.          break;                                                                 
  6919.        }                                                                        
  6920.      }                                                                          
  6921.      if (!rc) {                       /* If no matching host found  */          
  6922.        if (hostcount == 0) rc = TRUE; /* if no access hosts, say OK */          
  6923.      }                                                                          
  6924.      if (rc) break;                   /* if access OK, finished     */          
  6925.                                                                                 
  6926.      /* If access is not permitted, we keep checking because                    
  6927.       * there may be more than one entry in the access table                    
  6928.       * for this file, so that many host names can be given.                    
  6929.       */                                                                        
  6930.                                                                                 
  6931.    }                                                                            
  6932.  }                                                                              
  6933.                                                                                 
  6934.  (void)fclose(afp);                                                             
  6935.                                                                                 
  6936.  if (!rc) {                                                                     
  6937.    fprintf(stderr,"Not authorized from %s: '%s'\n",                             
  6938.                   R->hosttest, filetest);                                       
  6939.  }                                                                              
  6940.                                                                                 
  6941.  fflush(stderr);                                                                
  6942.                                                                                 
  6943.  return rc;                                                                     
  6944. }                                                                               
  6945.                                                                                 
  6946. /*=================================================================*/           
  6947.                                                                                 
  6948. /*******************************************************************/           
  6949. /*            This routine determines what type of gopher file     */           
  6950. /*            we've opened.  We'll return the file type to the     */           
  6951. /*            caller.                                              */           
  6952. /*                                                                 */           
  6953. /*            INPUT:   ident   pointer to first line of file       */           
  6954. /*                                                                 */           
  6955. /*            OUTPUT:   MENU   file type is a menu                 */           
  6956. /*                      FILE   file type is a file                 */           
  6957. /*                      INDEX  file type is an INDEX (not done)    */           
  6958. /*******************************************************************/           
  6959.                                                                                 
  6960. static char                                                                     
  6961. getftype(char *ident)                                                           
  6962. {                                                                               
  6963.  int   x;                              /* loop counter */                       
  6964.  char  buffer[RBUFSIZE];                                                        
  6965.  char *bufptr;                                                                  
  6966.                                                                                 
  6967.  /**********/                                                                   
  6968.  /*   first, convert the string to upper case...   */                           
  6969.  /*********/                                                                    
  6970.  strcpy(buffer,ident);                                                          
  6971.  bufptr = uppercase_and_trim_leading_space(buffer);                             
  6972.                                                                                 
  6973.  /**********/                                                                   
  6974.  /*   return the type of file.                     */                           
  6975.  /*********/                                                                    
  6976.                                                                                 
  6977.  if(strcmp(bufptr,MENUIDENT)==0) return(MENU);                                  
  6978.  if(strcmp(bufptr,INDEXIDENT)==0) return(INDEX);                                
  6979.                                                                                 
  6980.  /**********/                                                                   
  6981.  /*   don't know, so assume it's a "file" file...    */                         
  6982.  /*********/                                                                    
  6983.                                                                                 
  6984.  return(GFILE);                                                                 
  6985.                                                                                 
  6986. }                                                                               
  6987.                                                                                 
  6988. /*=================================================================*/           
  6989.                                                                                 
  6990. /*******************************************************************/           
  6991. /*            This routine figures out what type of parm line      */           
  6992. /*            the current line is.  We'll return the token         */           
  6993. /*            type to the caller.                                  */           
  6994. /*                                                                 */           
  6995. /*            INPUT:   buffer  pointer to first line of file       */           
  6996. /*                       (Note: string must be null terminated!    */           
  6997. /*            OUTPUT:   Type of token.  (See in include file...)   */           
  6998. /*******************************************************************/           
  6999.                                                                                 
  7000. static int                                                                      
  7001. menukeywd(char  *buffer,                                                        
  7002.           char  *token,                                                         
  7003.           char  *operand)                                                       
  7004. {                                                                               
  7005.  int             x;                              /* loop counter */             
  7006.  char           *tokval;                                                        
  7007.  char           *oprval;                                                        
  7008.  char           *tokptr;                                                        
  7009.  char            tokstr[256];                                                   
  7010.                                                                                 
  7011.  strcpy(tokstr,buffer);                                                         
  7012.  tokval=strtok(tokstr,"=");                                                     
  7013.  oprval=strtok(NULL,"");                                                        
  7014.  strcpy(token,tokval);                                                          
  7015.  strcpy(operand,oprval);                                                        
  7016.  tokptr = uppercase_and_trim_leading_space(token);                              
  7017.                                                                                 
  7018.  /*********/                                                                    
  7019.  /*  now look at the tokens to see if we have a weener... */                    
  7020.  /*********/                                                                    
  7021.                                                                                 
  7022.  if(strcmp(tokptr,TOKTYPE)==0) return(TYPETOK);                                 
  7023.  if(strcmp(tokptr,TOKNAME)==0) return(NAMETOK);                                 
  7024.  if(strcmp(tokptr,TOKPATH)==0) return(PATHTOK);                                 
  7025.  if(strcmp(tokptr,TOKHOST)==0) return(HOSTTOK);                                 
  7026.  if(strcmp(tokptr,TOKPORT)==0) return(PORTTOK);                                 
  7027.  if(strcmp(tokptr,TOKEND)==0) return(ENDTOK);                                   
  7028.                                                                                 
  7029.  /* for back compatibility with the old MVS GOPHER server */                    
  7030.                                                                                 
  7031.  if(strcmp(tokptr,TOKDISPLAY)==0) return(DISPLAYTOK);                           
  7032.  if(strcmp(tokptr,TOKSELECT)==0) return(SELECTTOK);                             
  7033.                                                                                 
  7034.  return(COMMENTTOK);                                                            
  7035.                                                                                 
  7036. }                                                                               
  7037.                                                                                 
  7038. /*=================================================================*/           
  7039.                                                                                 
  7040. /*******************************************************************/           
  7041. /*       This routine reads a line from the specified file.        */           
  7042. /*       if a read error occurs, an error message is printed and   */           
  7043. /*       FALSE is returned.                                        */           
  7044. /*                                                                 */           
  7045. /*       INPUT   buffer      pointer to buffer to place line       */           
  7046. /*               readfile    file structure to read from           */           
  7047. /*                                                                 */           
  7048. /*       OUTPUT  buffer      line that was read from the file      */           
  7049. /*               TRUE        read worked ok                        */           
  7050. /*               FALSE       read failed!                          */           
  7051. /*******************************************************************/           
  7052.                                                                                 
  7053. static Bool                                                                     
  7054. readaline(struct recvstruct *R)                                                 
  7055. {                                                                               
  7056.                                                                                 
  7057.  memset(R->buffer,0,RBUFSIZE);                                                  
  7058.  fread(R->buffer,RBUFSIZE,1,R->readfile);                                       
  7059.  if (ferror(R->readfile)) {                                                     
  7060.    /* perror("FREAD"); */                                                       
  7061.    fprintf(stderr,"GGSTASK: Error reading file\n");                             
  7062.    return(FALSE);                                                               
  7063.  }                                                                              
  7064.  trim_trailing_space(R->buffer); /* Remove trailing whitespace */               
  7065.  return(TRUE);                                                                  
  7066. }                                                                               
  7067.                                                                                 
  7068. /*=================================================================*/           
  7069.                                                                                 
  7070. /*******************************************************************/           
  7071. /*   This routine sends a file to the calling client.              */           
  7072. /*   It assumes the file is a text formatted file.                 */           
  7073. /*   INPUT:   buffer    pointer to the already read line...        */           
  7074. /*            readfile  file we're going to read from..            */           
  7075. /*            maxlen    size of the buffer.                        */           
  7076. /*            sockfd    socket descriptor for client.              */           
  7077. /*                                                                 */           
  7078. /*   OUTPUT:   send the file to the client                         */           
  7079. /*******************************************************************/           
  7080. static void                                                                     
  7081. sendafile(struct recvstruct *R)                                                 
  7082. {                                                                               
  7083.  int            x;                                                              
  7084.  char          *moveit;                                                         
  7085.                                                                                 
  7086.  /*******/                                                                      
  7087.  /*   send the first line (cause we already read it) */                         
  7088.  /*******/                                                                      
  7089.                                                                                 
  7090.  if (!GGMouts(R,R->buffer)) return;                                             
  7091.                                                                                 
  7092.  /*******/                                                                      
  7093.  /*   get the rest of the lines of the file and send them... */                 
  7094.  /*******/                                                                      
  7095.                                                                                 
  7096.  for (;;) {                                                                     
  7097.    if (!readaline(R)) {                                                         
  7098.      (void)GGMouts(R,"<<<*** I/O ERROR ON MVS FILE ***>>>");                    
  7099.      return;                                                                    
  7100.    }                                                                            
  7101.    if (feof(R->readfile)) break;                                                
  7102.    if (!GGMouts(R,R->buffer)) return;                                           
  7103.  }                                                                              
  7104. }                                                                               
  7105.                                                                                 
  7106. /*=================================================================*/           
  7107.                                                                                 
  7108. /*******************************************************************/           
  7109. /*   This routine formats a menu file into gopher data & sends it  */           
  7110. /*   to the client.                                                */           
  7111. /*   INPUT:   buffer    pointer to the already read line...        */           
  7112. /*            readfile  file we're going to read from..            */           
  7113. /*            maxlen    size of the buffer.                        */           
  7114. /*            sockfd    socket descriptor for client               */           
  7115. /*                                                                 */           
  7116. /*   OUTPUT:   send the menu to the client                         */           
  7117. /*******************************************************************/           
  7118.                                                                                 
  7119. #define MENU_STUFF_SIZE GOPHER_DESC_LENGTH + \                                  
  7120.                         GOPHER_PATH_LENGTH + \                                  
  7121.                         GOPHER_HOST_LENGTH + 20                                 
  7122.                                                                                 
  7123. static void                                                                     
  7124. sendamenu(struct recvstruct *R)                                                 
  7125. {                                                                               
  7126.  char           *moveit;                                                        
  7127.  char           *operptr;                                                       
  7128.  char           *typeoftype;             /*pointer for strtok   */              
  7129.  char           *cp;                                                            
  7130.  int             kindotoken;                                                    
  7131.  int             x;                         /* loop counter */                  
  7132.  char            token   [133];                                                 
  7133.  char            operand [133];                                                 
  7134.  char            outbuf  [MENU_STUFF_SIZE];                                     
  7135.  struct menuitem menu;                                                          
  7136.                                                                                 
  7137.  memset(&menu,0,sizeof menu );                                                  
  7138.  for (;;) {                                                                     
  7139.    if (!readaline(R)) break;                                                    
  7140.    if (feof(R->readfile)) break;                                                
  7141.    if (!*R->buffer) continue;                                                   
  7142.    kindotoken = menukeywd(R->buffer,token,operand);                             
  7143.    switch(kindotoken) {                                                         
  7144.      case TYPETOK:                                                              
  7145.           operptr = uppercase_and_trim_leading_space(operand);                  
  7146.           typeoftype = strtok(operptr," ");                                     
  7147.           if (strlen(typeoftype) == 1)      menu.type = *typeoftype;            
  7148.           else                                                                  
  7149.           if (EQUAL(typeoftype,TYPEFILE))   menu.type = GFILE;                  
  7150.           else                                                                  
  7151.           if (EQUAL(typeoftype,TYPEMENU))   menu.type = MENU;                   
  7152.           else                                                                  
  7153.           if (EQUAL(typeoftype,TYPEINDEX))  menu.type = INDEX;                  
  7154.           else                                                                  
  7155.           if (EQUAL(typeoftype,TYPETELNET)) menu.type = TELNET;                 
  7156.           else                                                                  
  7157.           if (EQUAL(typeoftype,TYPETN3270)) menu.type = TN3270;                 
  7158.           else                                                                  
  7159.           if (EQUAL(typeoftype,TYPEWHOIS))  menu.type = WHOIS;                  
  7160.           else                              menu.type = ERROR;                  
  7161.           break;                                                                
  7162.      case NAMETOK:                                                              
  7163.      case DISPLAYTOK:                                                           
  7164.           strncpy(menu.desc,     operptr, sizeof(menu.desc));                   
  7165.           break;                                                                
  7166.      case PATHTOK:                                                              
  7167.      case SELECTTOK:                                                            
  7168.           strncpy(menu.select,   operptr, sizeof(menu.select));                 
  7169.           break;                                                                
  7170.      case HOSTTOK:                                                              
  7171.           if (EQUAL(operptr,IDENT_HOST_FROB)) {  /* HOST=+  */                  
  7172.             if (insure_my_name(R)) {                                            
  7173.               strncpy(menu.hostname, R->myname, sizeof(menu.hostname));         
  7174.             }                                                                   
  7175.           }                                                                     
  7176.           else {                                                                
  7177.             strncpy(menu.hostname, operptr, sizeof(menu.hostname));             
  7178.           }                                                                     
  7179.           break;                                                                
  7180.      case PORTTOK:                                                              
  7181.           if (EQUAL(operptr,IDENT_HOST_FROB)) {  /* PORT=+  */                  
  7182.             menu.port = R->myport;                                              
  7183.           }                                                                     
  7184.           else {                                                                
  7185.             menu.port=atoi(operptr);                                            
  7186.           }                                                                     
  7187.           break;                                                                
  7188.      case ENDTOK:                                                               
  7189.           if (menu.port == 0) {                                                 
  7190.             switch (menu.type) {                                                
  7191.               case TELNET: break;                                               
  7192.               case TN3270: break;                                               
  7193.               default:     menu.port = GOPHER_PORT_NUMBER; break;               
  7194.             }                                                                   
  7195.           }                                                                     
  7196.           /* If host is local and path is in the form "(member)",               
  7197.            * and current dsname is a PDS, then use same PDS:                    
  7198.            * i.e. turn PATH=(FOOBAR) into PATH=AA.BB.CC(FOOBAR)                 
  7199.            */                                                                   
  7200.           if (*R->myname                                                        
  7201.            && EQUAL(menu.hostname,R->myname)                                    
  7202.            && *menu.select == '('        /* ) */                                
  7203.            && (cp = strchr(R->dsname,'(' /* ) */ ))) {                          
  7204.             memcpy(outbuf, R->dsname, (cp-R->dsname));                          
  7205.             strcpy(outbuf+(cp-R->dsname), menu.select);                         
  7206.             strncpy(menu.select, outbuf, sizeof(menu.select));                  
  7207.           }                                                                     
  7208.           if (*menu.desc && *menu.hostname) {                                   
  7209.             sprintf(outbuf,"%c%s\t%s\t%s\t%d",                                  
  7210.                            menu.type,menu.desc,                                 
  7211.                            menu.select,menu.hostname,menu.port);                
  7212.             if (!GGMouts(R,outbuf)) return;                                     
  7213.           }                                                                     
  7214.           fflush(stdout);                                                       
  7215.           memset(&menu,0,sizeof menu );                                         
  7216.           break;                                                                
  7217.      default:                                                                   
  7218.           break;                                                                
  7219.        }                                                                        
  7220.    }                                                                            
  7221. }                                                                               
  7222.                                                                                 
  7223. /*=================================================================*/           
  7224.                                                                                 
  7225. static Bool                                                                     
  7226. get_directory(struct recvstruct *R)                                             
  7227. {                                                                               
  7228.  FILE              *dirfile;                                                    
  7229.  int                i;                                                          
  7230.  short              block_count;                                                
  7231.  short              bump_amount;                                                
  7232.  Bool               reject;                                                     
  7233.  Bool               no_more;                                                    
  7234.  char              *cp;                                                         
  7235.  char              *mp;                                                         
  7236.  char               dirblk  [256];                                              
  7237.  char               pdsspec [256];                                              
  7238.  char               entry   [256];                                              
  7239.                                                                                 
  7240.  /* The local path name is required for this function. */                       
  7241.                                                                                 
  7242.  if (!insure_my_name(R)) return FALSE;                                          
  7243.                                                                                 
  7244.  if ((dirfile=fopen(R->buffer,"rb,recfm=u,lrecl=256")) == NULL) {               
  7245.    perror(R->buffer);                                                           
  7246.    printf("Can't open PDS directory:%s\n",R->dsname);                           
  7247.    gbarf(R,"the GOPHER server can't open the directory");                       
  7248.    return(FALSE);                                                               
  7249.  }                                                                              
  7250.                                                                                 
  7251.  while (!feof(dirfile)) {                                                       
  7252.                                                                                 
  7253.    no_more = FALSE;                                                             
  7254.                                                                                 
  7255.    do {                                                                         
  7256.      memset(dirblk,0x00,256);                                                   
  7257.      fread(dirblk,256,1,dirfile);                                               
  7258.      if (feof(dirfile)) break;                                                  
  7259.      if (ferror(dirfile)) {                                                     
  7260.        printf("Can't read PDS directory:%s\n", R->fileptr);                     
  7261.        gbarf(R,"the GOPHER server can't read the directory");                   
  7262.        fclose(dirfile);                                                         
  7263.        return FALSE;                                                            
  7264.      }                                                                          
  7265.      mp = dirblk;                                                               
  7266.      block_count = *(short *)mp - 2;   /* # bytes in dir block */               
  7267.      mp += 2;                        /* addr of dir block data */               
  7268.      while (block_count > 0) {                                                  
  7269.        if (memcmp(mp,"\xff\xff\xff\xff\xff\xff\xff\xff",8)==0) break;           
  7270.        reject = FALSE;                                                          
  7271.        /*                                                                       
  7272.         * Uncomment this if you want to skip aliases.                           
  7273.         * It is recommended that you let aliases through, since                 
  7274.         * they often have better names (e.g. TSO HELP files)                    
  7275.         *                                                                       
  7276.         * if ((mp[11] & 0x80) != 0) {                                           
  7277.         *   fprintf(stderr,"Skipping alias:  %-8.8s\n",mp);                     
  7278.         *   reject = TRUE;                                                      
  7279.         * }                                                                     
  7280.         */                                                                      
  7281.        if (!reject) {                                                           
  7282.          strcpy(pdsspec, R->dsname);                                            
  7283.          cp = strchr(pdsspec, '\0');                                            
  7284.          *(cp++) = '(';                                                         
  7285.          for (i = 0; i < 8 && mp[i] != ' '; cp++, i++) *cp = mp[i];             
  7286.          *(cp++) = ')';                                                         
  7287.          *cp = '\0';                                                            
  7288.          sprintf(entry,"0%8.8s\t%s\t%s\t%d",                                    
  7289.                        mp, pdsspec, R->myname, SERV_TCP_PORT);                  
  7290.          (void)GGMouts(R,entry);                                                
  7291.        }                                                                        
  7292.        bump_amount = 12 + ((mp[11] & 0x1f) * 2);                                
  7293.        mp += bump_amount;                                                       
  7294.        block_count -= bump_amount;                                              
  7295.      }                                                                          
  7296.    } while(!no_more);                                                           
  7297.                                                                                 
  7298.  }                                                                              
  7299.                                                                                 
  7300.  fclose(dirfile);                                                               
  7301.  return TRUE;                                                                   
  7302. }                                                                               
  7303.                                                                                 
  7304. /*=================================================================*/           
  7305.                                                                                 
  7306. static Bool                                                                     
  7307. get_flat_file(struct recvstruct *R)                                             
  7308. {                                                                               
  7309.  int                x;            /* loop counter*/                             
  7310.  int                numread;      /* number of items read... */                 
  7311.  char               filetype;     /* type of file we're dealing with*/          
  7312.                                                                                 
  7313.  if ((R->readfile=fopen(R->buffer,"rb,type=record")) == NULL) {                 
  7314.    perror(R->buffer);                                                           
  7315.    printf("INVALID! requested:%s\n",R->fileptr);                                
  7316.    gbarf(R,"the GOPHER server couldn't open the file");                         
  7317.    return(FALSE);                                                               
  7318.  }                                                                              
  7319.                                                                                 
  7320.  /************/                                                                 
  7321.  /*  get the first line and see what type of file we've got.      */            
  7322.  /************/                                                                 
  7323.                                                                                 
  7324.  if (readaline(R) && !feof(R->readfile)) {                                      
  7325.                                                                                 
  7326.    filetype=getftype(R->buffer);                                                
  7327.                                                                                 
  7328.   /************/                                                                
  7329.   /*  Now let's go do whatever we need to for this file type.    */             
  7330.   /************/                                                                
  7331.                                                                                 
  7332.    switch(filetype) {                                                           
  7333.      case MENU:                                                                 
  7334.                  sendamenu(R);                                                  
  7335.                  break;                                                         
  7336.      case GFILE:                                                                
  7337.      default:                                                                   
  7338.                  sendafile(R);                                                  
  7339.                  break;                                                         
  7340.    }                                                                            
  7341.                                                                                 
  7342.  }                                                                              
  7343.                                                                                 
  7344.  if(fclose(R->readfile) < 0) {                                                  
  7345.    /* perror("PROCESS CLOSE"); */                                               
  7346.    fprintf(stderr,"GGSTASK: Error closing file %s\n",R->fileptr);               
  7347.    gbarf(R,"the GOPHER server couldn't close the file");                        
  7348.    return FALSE;                                                                
  7349.  }                                                                              
  7350.                                                                                 
  7351.  return TRUE;                                                                   
  7352.                                                                                 
  7353. }                                                                               
  7354.                                                                                 
  7355. /*=================================================================*/           
  7356.                                                                                 
  7357. #define PARAMETER   unsigned int                                                
  7358. #define LASTPARM(X) ((unsigned int)(X) | 0x80000000)                            
  7359.                                                                                 
  7360.                                                                                 
  7361. static Bool                                                                     
  7362. get_exec_data(struct recvstruct *R)                                             
  7363. {                                                                               
  7364.  char              *command;                                                    
  7365.  char              *commandargs;                                                
  7366.  unsigned int       bitflags;                                                   
  7367.  int                rexxrc;                                                     
  7368.  int                irxexecrc;                                                  
  7369.  int                commandlength;                                              
  7370.  int                scan_count;                                                 
  7371.  int                i;                                                          
  7372.  Bool               rc;                                                         
  7373.  int              (*irxexec)();                                                 
  7374.  FILE              *fp;                                                         
  7375.  char               exectest[RBUFSIZE];                                         
  7376.  PARAMETER          parameter[11];                                              
  7377.  struct {                                                                       
  7378.                          /* repeat this block for each argument */              
  7379.          char      *argstring_ptr;                                              
  7380.          int        argstring_length;                                           
  7381.                          /* end repeat this block for each argument */          
  7382.          int        argstring_end;                                              
  7383.         }           arguments;                                                  
  7384.                                                                                 
  7385.  struct {                                                                       
  7386.          char       acryn[8];       /* "IRXEXECB" */                            
  7387.          int        length;                                                     
  7388.          int        reserved1;                                                  
  7389.          char       member[8];                                                  
  7390.          char       ddname[8];                                                  
  7391.          char       subcom[8];                                                  
  7392.          char      *dsnptr;                                                     
  7393.          int        dsnlen;                                                     
  7394.         }           execblk;                                                    
  7395.                                                                                 
  7396.   /*                                                                            
  7397.    * Menu item should look like this:                                           
  7398.    *                                                                            
  7399.    * exec:rexxname any args                                                     
  7400.    *                                                                            
  7401.    * The exec should write output to SYSTSPRT.  Normal TSO command              
  7402.    * output will be captured by the SYSTSPRT allocation only if                 
  7403.    * the Gopher server is run as a batch job.                                   
  7404.    *                                                                            
  7405.    * If this was sent by the client with a type 7 or type w, then               
  7406.    * additional args will appear at the end delimited by a space.               
  7407.    */                                                                           
  7408.                                                                                 
  7409.  irxexec = NULL;                                                                
  7410.  rc = TRUE;                                                                     
  7411.  scan_count = 0;                                                                
  7412.                                                                                 
  7413.  if (R->wargptr) {                                                              
  7414.    commandlength = strlen(R->fileptr) + strlen(R->wargptr) + 4;                 
  7415.    command = (char *)malloc(commandlength);                                     
  7416.    if (!command) {                                                              
  7417.      printf("Cannot allocate %d bytes of memory for exec\n",                    
  7418.             commandlength);                                                     
  7419.      gbarf(R,"the GOPHER server ran out of memory");                            
  7420.      return FALSE;                                                              
  7421.    }                                                                            
  7422.    else sprintf(command,"%s %s",R->fileptr,R->wargptr);                         
  7423.  }                                                                              
  7424.  else {                                                                         
  7425.    commandlength = 0;                                                           
  7426.    command = R->fileptr;                                                        
  7427.  }                                                                              
  7428.                                                                                 
  7429.  *exectest = '\0';                                                              
  7430.  sscanf(command, "%s %n", exectest, &scan_count);                               
  7431.  if (strlen(exectest) > 8) {                                                    
  7432.    gbarf(R,"name of exec is too long");                                         
  7433.    return FALSE;                                                                
  7434.  }                                                                              
  7435.  commandargs = command + scan_count;                                            
  7436.                                                                                 
  7437.  if (rc) {                                                                      
  7438.    irxexec = (int(*)())fetch("IRXEXEC");                                        
  7439.    if (!irxexec) {                                                              
  7440.      printf("Cannot fetch IRXEXEC\n");                                          
  7441.      rc = FALSE;                                                                
  7442.    }                                                                            
  7443.  }                                                                              
  7444.                                                                                 
  7445.  /* Give the exec an empty SYSTSPRT file to write into.                         
  7446.   * Then when we read it we can see only what was added.                        
  7447.   * Since IRXEXEC doesn't close SYSTSPRT, we can't remove it                    
  7448.   * and reallocate it.                                                          
  7449.   */                                                                            
  7450.                                                                                 
  7451.  if (rc) {                                                                      
  7452.    fp = fopen("DD:SYSTSPRT","w");                                               
  7453.    if (!fp) {                                                                   
  7454.      perror("DD:SYSTSPRT");                                                     
  7455.      printf("Cannot open SYSTSPRT to prepare for REXX exec\n");                 
  7456.      rc = FALSE;                                                                
  7457.    }                                                                            
  7458.                                                                                 
  7459.    /* Open for write + close = clear it out */                                  
  7460.                                                                                 
  7461.    else if (fclose(fp) < 0) {                                                   
  7462.      printf("Cannot close SYSTSPRT to prepare for REXX exec\n");                
  7463.      rc = FALSE;                                                                
  7464.    }                                                                            
  7465.  }                                                                              
  7466.                                                                                 
  7467.  /* Set up parameters for IRXEXEC:                                              
  7468.   *                                                                             
  7469.   * Param 1  -  address of EXECBLK                                              
  7470.   * Param 2  -  address of arguments                                            
  7471.   * Param 3  -  bitflags                                                        
  7472.   * Param 4  -  address of INSTBLK                                              
  7473.   * Param 5  -  address of CPPL                                                 
  7474.   * Param 6  -  address of EVALBLOCK                                            
  7475.   * Param 7  -  address of 8-byte work area                                     
  7476.   * Param 8  -  address of user field                                           
  7477.   * Param 9  -  address of environment block                                    
  7478.   * Param 10 -  return code                                                     
  7479.   *                                                                             
  7480.   */                                                                            
  7481.                                                                                 
  7482.  if (rc) {                                                                      
  7483.                                                                                 
  7484.    /* set up exec block */                                                      
  7485.                                                                                 
  7486.    memset (&execblk, 0, sizeof(execblk));                                       
  7487.    execblk.length = sizeof(execblk);                                            
  7488.    memcpy (execblk.acryn, "IRXEXECB", 8);                                       
  7489.    strncpy(execblk.member,exectest,8);                                          
  7490.    for (i=0;i<8;i++) {                                                          
  7491.      if (execblk.member[i] == '\0')                                             
  7492.          execblk.member[i] = ' ';                                               
  7493.    }                                                                            
  7494.    /* We may have just clobbered this, so do this after... */                   
  7495.                                                                                 
  7496.    memcpy (execblk.ddname, REXX_EXEC_LIBRARY_DDNAME, 8);                        
  7497.    memcpy (execblk.subcom, REXX_EXEC_SUBCOM,     8);                            
  7498.                                                                                 
  7499.    /* set up arguments  */                                                      
  7500.                                                                                 
  7501.    arguments.argstring_ptr    = commandargs;                                    
  7502.    arguments.argstring_length = strlen(commandargs);                            
  7503.    arguments.argstring_end    = 0xffffffff;                                     
  7504.                                                                                 
  7505.    /* Invoke the rexx exec */                                                   
  7506.                                                                                 
  7507.    if (!R->outfp) printf("Executing:%s\n", command);                            
  7508.                                                                                 
  7509. #define INVOKE_EXEC_AS_COMMAND            (unsigned int)0x80000000              
  7510. #define INVOKE_EXEC_AS_EXTERNAL_FUNCTION  (unsigned int)0x40000000              
  7511. #define INVOKE_EXEC_AS_SUBROUTINE         (unsigned int)0x20000000              
  7512. #define RETURN_EXTENDED_RETURN_CODES      (unsigned int)0x10000000              
  7513.                                                                                 
  7514.    rexxrc = 0;                                                                  
  7515.    bitflags = (unsigned int)(INVOKE_EXEC_AS_COMMAND +                           
  7516.                              RETURN_EXTENDED_RETURN_CODES);                     
  7517.                                                                                 
  7518.    parameter[ 1] =   (PARAMETER)&execblk;                                       
  7519.    parameter[ 2] =   (PARAMETER)&arguments;                                     
  7520.    parameter[ 3] =   (PARAMETER)bitflags;                                       
  7521.    parameter[ 4] =   (PARAMETER)NULL;  /* no INSTBLK */                         
  7522.    parameter[ 5] =   (PARAMETER)NULL;  /* no CPPL    */                         
  7523.    parameter[ 6] =   (PARAMETER)NULL;  /* no eval block */                      
  7524.    parameter[ 7] =   (PARAMETER)NULL;  /* no work area */                       
  7525.    parameter[ 8] =   (PARAMETER)NULL;  /* no user field, last parm */           
  7526.    parameter[ 9] =   (PARAMETER)NULL;  /* no environment block */               
  7527.    parameter[10] =   (PARAMETER)0;     /* return code */                        
  7528.                                                                                 
  7529.    irxexecrc = (*irxexec) (                                                     
  7530.                            ¶meter[1],                                       
  7531.                            ¶meter[2],                                       
  7532.                            ¶meter[3],                                       
  7533.                            ¶meter[4],                                       
  7534.                            ¶meter[5],                                       
  7535.                            ¶meter[6],                                       
  7536.                            ¶meter[7],                                       
  7537.                            LASTPARM(¶meter[8]), /* old REXX */              
  7538.                            ¶meter[9],                                       
  7539.                            LASTPARM(¶meter[10]) /* new REXX */              
  7540.                           );                                                    
  7541.                                                                                 
  7542.    if (irxexecrc != 0) {                                                        
  7543.      fprintf(stderr,"Return code from IRXEXEC is %d\n", irxexecrc);             
  7544.      gbarf(R,"the Gopher server was unable to run the exec");                   
  7545.      rc = FALSE;                                                                
  7546.    }                                                                            
  7547.    else {                                                                       
  7548.                                                                                 
  7549.      rexxrc = parameter[10];                                                    
  7550.                                                                                 
  7551.      if (!R->outfp) printf("Return code from exec is %d\n", rexxrc);            
  7552.                                                                                 
  7553.      /* Read what the exec wrote. */                                            
  7554.                                                                                 
  7555.      strcpy(R->buffer,"DD:SYSTSPRT");                                           
  7556.      R->fileptr = R->buffer;                                                    
  7557.      rc = get_flat_file(R);                                                     
  7558.                                                                                 
  7559.    }                                                                            
  7560.                                                                                 
  7561.  }                                                                              
  7562.                                                                                 
  7563.  else {                                                                         
  7564.      gbarf(R,"the GOPHER server had a problem with the exec");                  
  7565.  }                                                                              
  7566.                                                                                 
  7567.  if (irxexec) release((void (*)())irxexec);                                     
  7568.                                                                                 
  7569.  if (commandlength > 0) free(command);                                          
  7570.                                                                                 
  7571.  return rc;                                                                     
  7572.                                                                                 
  7573. }                                                                               
  7574.                                                                                 
  7575. /*=================================================================*/           
  7576.                                                                                 
  7577. /*******************************************************************/           
  7578. /*   This routine Processes the file the user requested.           */           
  7579. /*   If it's a menu, we'll form a menu line, if it's a             */           
  7580. /*   file, we'll just send it as is.                               */           
  7581. /*                                                                 */           
  7582. /*   INPUT:   filename  pointer to the file name to open           */           
  7583. /*            sockfd    socket descriptor for the client           */           
  7584. /*                                                                 */           
  7585. /*   OUTPUT:   print "gopher" lines.                               */           
  7586. /*             TRUE  - file printed ok.                            */           
  7587. /*             FALSE - Error reading or writing                    */           
  7588. /*******************************************************************/           
  7589.                                                                                 
  7590. Bool                                                                            
  7591. GGMproc(struct recvstruct *R)                                                   
  7592. {                                                                               
  7593.  int                x;            /* loop counter*/                             
  7594.  int                numread;      /* number of items read... */                 
  7595.  int                hacksize;     /* length of hack prefix before : */          
  7596.  Bool               rc;           /* return value */                            
  7597.  enum data_set_type dstype;       /* SEQ, PDS or UNK */                         
  7598.  char              *p;                                                          
  7599.  char              *q;                                                          
  7600.  char              *tabptr;                                                     
  7601.  char              *colonptr;                                                   
  7602.  char               ddname    [  9];                                            
  7603.  char               hackprefix[ 17];                                            
  7604.                                                                                 
  7605.  *ddname     = '\0';                                                            
  7606.  *hackprefix = '\0';                                                            
  7607.                                                                                 
  7608.  /************/                                                                 
  7609.  /*  First, strip off any "bad" characters from the arguments. */               
  7610.  /************/                                                                 
  7611.                                                                                 
  7612.  /*                                                                             
  7613.   * Break the argument up into one or two pieces delimited by tab.              
  7614.   */                                                                            
  7615.                                                                                 
  7616.  R->fileptr = R->buffer;        /* filename passed in buffer */                 
  7617.                                                                                 
  7618.  tabptr = strchr(R->fileptr,'\t');                                              
  7619.  if (tabptr) {                                                                  
  7620.    *tabptr = '\0';                                                              
  7621.    R->fileptr = trim_leading_and_trailing_space(R->fileptr);                    
  7622.    R->wargptr = trim_leading_and_trailing_space(tabptr+1);                      
  7623.  }                                                                              
  7624.  else {                                                                         
  7625.    R->fileptr = trim_leading_and_trailing_space(R->fileptr);                    
  7626.    R->wargptr = NULL;                                                           
  7627.  }                                                                              
  7628.                                                                                 
  7629.  if (!*R->fileptr) {                                                            
  7630.    R->fileptr = DEFAULT_DIRECTORY;                                              
  7631.  }                                                                              
  7632.                                                                                 
  7633.  /* If first character is numeric, assume it's a gopher type.                   
  7634.   * Later we will actually support different types...                           
  7635.   */                                                                            
  7636.                                                                                 
  7637.  switch (*R->fileptr) {                                                         
  7638.    case '0':                                                                    
  7639.    case '1':                                                                    
  7640.    case '2':                                                                    
  7641.    case '3':                                                                    
  7642.    case '4':                                                                    
  7643.    case '5':                                                                    
  7644.    case '6':                                                                    
  7645.    case '7':                                                                    
  7646.    case '8':                                                                    
  7647.    case '9':  R->fileptr++; break;                                              
  7648.    default:                 break;                                              
  7649.  }                                                                              
  7650.                                                                                 
  7651.  if (!R->outfp) printf("%s: requested:%s;\n",R->hostname,R->fileptr);           
  7652.                                                                                 
  7653.  /*                                                                             
  7654.   * Process special hacks here.                                                 
  7655.   *                                                                             
  7656.   * For example, if the file name begins with "exec:", then                     
  7657.   * execute the specified REXX exec.                                            
  7658.   *                                                                             
  7659.   * Hackless names are processed as files.  "dd:" is not a                      
  7660.   * special hack but the normal C/370 DDname reference.                         
  7661.   *                                                                             
  7662.   */                                                                            
  7663.                                                                                 
  7664.  colonptr = strchr(R->fileptr,':');                                             
  7665.  if (colonptr) {                                                                
  7666.    hacksize = colonptr - R->fileptr;                                            
  7667.    if (hacksize > 0 && hacksize < sizeof(hackprefix)) {                         
  7668.      for (p = hackprefix, q = R->fileptr;                                       
  7669.           hacksize > 0;                                                         
  7670.           p++, q++, hacksize--) *p = toupper(*q);                               
  7671.      *p = '\0';                                                                 
  7672.    }                                                                            
  7673.  }                                                                              
  7674.                                                                                 
  7675.  if (EQUAL(hackprefix,"EXEC")) {                                                
  7676.   /*                                                                            
  7677.    * REXX exec, which must reside in SYSEXEC DD.                                
  7678.    */                                                                           
  7679.    if (!authorized_file(R)) {                                                   
  7680.      gbarf(R,"the GOPHER server won't run the exec for you");                   
  7681.      rc = FALSE;                                                                
  7682.    }                                                                            
  7683.    else {                                                                       
  7684.      R->fileptr = colonptr + 1;  /* point to exec itself */                     
  7685.      rc = get_exec_data(R);                                                     
  7686.    }                                                                            
  7687.  }                                                                              
  7688.  else                                                                           
  7689.  if (EQUAL(hackprefix,"DD")) {                                                  
  7690.   /*                                                                            
  7691.    * C/370 style ddname.  Assume sequential file - cannot be a PDS              
  7692.    * because I don't feel like trying to determine that right now.              
  7693.    */                                                                           
  7694.    if (!authorized_file(R)) {                                                   
  7695.      gbarf(R,"the GOPHER server won't read the DD for you");                    
  7696.      rc = FALSE;                                                                
  7697.    }                                                                            
  7698.    else {                                                                       
  7699.      strcpy(R->buffer,R->fileptr); /* still points to "DD:xxxxxxxx" */          
  7700.      dstype = SEQ;                                                              
  7701.      rc = get_flat_file(R);                                                     
  7702.    }                                                                            
  7703.  }                                                                              
  7704.  else {                                                                         
  7705.    /* Regular file name without ":" hack, or with invalid ":" hack.             
  7706.     * Check to see that the file name is on our "official" list.                
  7707.     */                                                                          
  7708.    if (!authorized_file(R)) {                                                   
  7709.      gbarf(R,"the GOPHER server won't let you see the file");                   
  7710.      rc = FALSE;                                                                
  7711.    }                                                                            
  7712.    else {                                                                       
  7713.                                                                                 
  7714.    /* Dynamically allocate data set and use generated ddname.                   
  7715.     * Note that we have to allocate the data set name to a ddname and           
  7716.     * then open the ddname to prevent C/370 from barfing on otherwise           
  7717.     * valid data set names like those with hyphens in them.  But this           
  7718.     * also lets us determine if the data set is sequential or a PDS.            
  7719.     */                                                                          
  7720.      strcpy(R->dsname,R->fileptr);                                              
  7721.      dstype = GGMalloc(R->dsname,ddname,UNK,0);                                 
  7722.      sprintf(R->buffer,"DD:%s",ddname);                                         
  7723.      switch (dstype) {                                                          
  7724.        case SEQ: rc = get_flat_file(R); break;                                  
  7725.        case PDS: rc = get_directory(R); break;                                  
  7726.        default:                                                                 
  7727.                printf("INVALID! requested:%s\n",R->fileptr);                    
  7728.                gbarf(R,"the GOPHER server couldn't allocate the file");         
  7729.                rc = FALSE;                                                      
  7730.      }                                                                          
  7731.    }                                                                            
  7732.  }                                                                              
  7733.                                                                                 
  7734.  GGMunalc(ddname);  /* free the ddname if set */                                
  7735.                                                                                 
  7736.  if (!rc) {                                                                     
  7737.    fflush(stdout);                                                              
  7738.    fflush(stderr);                                                              
  7739.  }                                                                              
  7740.                                                                                 
  7741.  return rc;                                                                     
  7742.                                                                                 
  7743. }                                                                               
  7744.                                                                                 
  7745. ./   ADD NAME=GGMSOCKT                                                          
  7746.                                                                                 
  7747.  /********************************************************************/         
  7748.  /*                                                                  */         
  7749.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7750.  /*                                                                  */         
  7751.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  7752.  /*                                                                  */         
  7753.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7754.  /* including the implied warranties of merchantability and fitness, */         
  7755.  /* are expressly denied.                                            */         
  7756.  /*                                                                  */         
  7757.  /* Provided this copyright notice is included, this software may    */         
  7758.  /* be freely distributed and not offered for sale.                  */         
  7759.  /*                                                                  */         
  7760.  /* Changes or modifications may be made and used only by the maker  */         
  7761.  /* of same, and not further distributed.  Such modifications should */         
  7762.  /* be mailed to the author for consideration for addition to the    */         
  7763.  /* software and incorporation in subsequent releases.               */         
  7764.  /*                                                                  */         
  7765.  /********************************************************************/         
  7766.                                                                                 
  7767. #pragma  csect(code,  "GG@SOCKT")                                               
  7768. #pragma  csect(static,"GG$SOCKT")                                               
  7769. #include "gg.h"                                                                 
  7770.                                                                                 
  7771. /****** Output one data line for the server. *************************/         
  7772.                                                                                 
  7773. Bool                                                                            
  7774. GGMsockt(gp,sp)                                                                 
  7775. Rstruc ggcb        *gp;                                                         
  7776. Rstruc connection  *sp;                                                         
  7777. {                                                                               
  7778.  int                gopher_bytes;                                               
  7779.  int                writrc;                                                     
  7780.  char              *s_buf;                                                      
  7781.  Bool               procok;                                                     
  7782.  struct recvstruct *R;                                                          
  7783.                                                                                 
  7784.  /* Before sending a request to the server, do a cleanup operation              
  7785.   * to make sure that no more responses are coming from the server.             
  7786.   */                                                                            
  7787.                                                                                 
  7788.  GGMesrvr(gp,sp);           /* End server read */                               
  7789.                                                                                 
  7790.  /* If local mode, call server subtask processor with command. */               
  7791.                                                                                 
  7792.  if ((R=gp->recvp)) {                                                           
  7793.    if (!R->outfp) {                                                             
  7794.      CRIT1("Can't send data locally, non-socket not connected");                
  7795.      return FALSE;                                                              
  7796.    }                                                                            
  7797.    strncpy(R->buffer, gp->gopher_command, sizeof(R->buffer)-1);                 
  7798.    strcpy(R->myname, LOCAL_HOST_FROB);  /* used by PDS feature */               
  7799.                                                                                 
  7800.    /* allocate SYSTSPRT file, used by REXX EXEC interface */                    
  7801.                                                                                 
  7802.    if (GGMtso(                                                                  
  7803.      "ALLOC FI(SYSTSPRT) T SP(100 100) REL REU DEL"                             
  7804.      " RECFM(V B) LRECL(1024) BLKSIZE(32760)"                                   
  7805.              ) != 0) {                                                          
  7806.      fprintf(stderr,                                                            
  7807.        "Warning: Cannot allocate temporary SYSTSPRT file.\n");                  
  7808.      fprintf(stderr,                                                            
  7809.        "         Some interfaces may not work properly.\n");                    
  7810.    }                                                                            
  7811.                                                                                 
  7812.    procok = GGMproc(R);                                                         
  7813.                                                                                 
  7814.    /* free SYSTSPRT file, used by REXX EXEC interface */                        
  7815.                                                                                 
  7816.    (void)GGMunalc("SYSTSPRT");                                                  
  7817.                                                                                 
  7818.    /* Prepare to read from the beginning of the file */                         
  7819.                                                                                 
  7820.    if (fseek(R->outfp, 0, SEEK_SET) != 0) {                                     
  7821.      CRIT1("Can't reposition to start of local file");                          
  7822.      return FALSE;                                                              
  7823.    }                                                                            
  7824.    return procok;                                                               
  7825.  }                                                                              
  7826.                                                                                 
  7827.  gopher_bytes = strlen(gp->gopher_command);                                     
  7828.                                                                                 
  7829.  memcpy(sp->client_buf,gp->gopher_command,gopher_bytes);                        
  7830.  sp->client_buf[gopher_bytes]   = CARRIAGE_RETURN;                              
  7831.  sp->client_buf[gopher_bytes+1] = LINE_FEED;                                    
  7832.                                                                                 
  7833.  if (sp->receiving_text &&                                                      
  7834.      gopher_bytes == 1  &&                                                      
  7835.      sp->client_buf[0] == '.') {                                                
  7836.    sp->receiving_text = FALSE;                                                  
  7837.  }                                                                              
  7838.                                                                                 
  7839.  if (gp->debug_mode)                                                            
  7840.     GGMdump(gp,"Writing to server",sp->client_buf,gopher_bytes+2);              
  7841.                                                                                 
  7842. #ifdef MVS                                                                      
  7843.  EBCDIC_TO_ASCII(sp->client_buf,gopher_bytes+2);                                
  7844. #endif                                                                          
  7845.                                                                                 
  7846.  writrc = write(sp->ns, sp->client_buf, gopher_bytes+2);                        
  7847.  if (writrc < 0) {                                                              
  7848.    sp->connection_broken = TRUE;                                                
  7849.    CRIT2("TCP/IP error: write() failed to send data to server %s.",             
  7850.          gp->ggserver);                                                         
  7851.    return FALSE;                                                                
  7852.  }                                                                              
  7853.                                                                                 
  7854.  /* Prepare server for read. */                                                 
  7855.                                                                                 
  7856.  sp->server_has_something_pending = TRUE;                                       
  7857.  sp->server_finished_replying     = FALSE;                                      
  7858.  sp->sending_text                 = FALSE;                                      
  7859.  sp->dont_read                    = FALSE;                                      
  7860.                                                                                 
  7861.  (void)GGMispf(gp,"CONTROL DISPLAY LOCK");                                      
  7862.  (void)GGMispf(gp,"DISPLAY PANEL(GGMLSOCK)");                                   
  7863.                                                                                 
  7864.  return TRUE;                                                                   
  7865. }                                                                               
  7866.                                                                                 
  7867. ./   ADD NAME=GGMSOPT                                                           
  7868.                                                                                 
  7869.  /********************************************************************/         
  7870.  /*                                                                  */         
  7871.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7872.  /*                                                                  */         
  7873.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  7874.  /*                                                                  */         
  7875.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7876.  /* including the implied warranties of merchantability and fitness, */         
  7877.  /* are expressly denied.                                            */         
  7878.  /*                                                                  */         
  7879.  /* Provided this copyright notice is included, this software may    */         
  7880.  /* be freely distributed and not offered for sale.                  */         
  7881.  /*                                                                  */         
  7882.  /* Changes or modifications may be made and used only by the maker  */         
  7883.  /* of same, and not further distributed.  Such modifications should */         
  7884.  /* be mailed to the author for consideration for addition to the    */         
  7885.  /* software and incorporation in subsequent releases.               */         
  7886.  /*                                                                  */         
  7887.  /********************************************************************/         
  7888.                                                                                 
  7889. #pragma  csect(code,  "GG@SOPT ")                                               
  7890. #pragma  csect(static,"GG$SOPT ")                                               
  7891. #include "gg.h"                                                                 
  7892.                                                                                 
  7893. #define BOOLOPTSET(A,B,C) \                                                     
  7894.    switch (A[0]) { \                                                            
  7895.      case  'n': \                                                               
  7896.      case  'N':   B = FALSE; break; \                                           
  7897.      case  'y': \                                                               
  7898.      case  'Y':   B = TRUE; break; \                                            
  7899.      case '\0': \                                                               
  7900.      default:     B = C; break; \                                               
  7901.    }                                                                            
  7902.                                                                                 
  7903. /****** Set options that are stored in ISPF profile. *****************/         
  7904.                                                                                 
  7905. void                                                                            
  7906. GGMsopt(gp,which)                                                               
  7907. Rstruc ggcb        *gp;                                                         
  7908. enum user_option    which;                                                      
  7909. {                                                                               
  7910.  int                arrows;                                                     
  7911.  char               ggextpow[  4];                                              
  7912.  char               ggextpap[  4];                                              
  7913.  char               ggscroll[  4];                                              
  7914.                                                                                 
  7915.  if (which == OPTION_ALL) {                                                     
  7916.    GGMispf(gp, "VGET (GGMUPDTF GGEXTPOW GGEXTPOP GGSCROLL) PROFILE");           
  7917.  }                                                                              
  7918.                                                                                 
  7919.  if (which == OPTION_ALL || which == OPTION_OTHER) {                            
  7920.                                                                                 
  7921.    (void)GGMivget(gp,"GGEXTPOW ", ggextpow, sizeof(ggextpow));                  
  7922.    (void)GGMivget(gp,"GGEXTPAP ", ggextpap, sizeof(ggextpap));                  
  7923.                                                                                 
  7924.    BOOLOPTSET(ggextpow, gp->warn_overwrite,              TRUE);                 
  7925.    BOOLOPTSET(ggextpap, gp->warn_append,                 TRUE);                 
  7926.                                                                                 
  7927.  }                                                                              
  7928.                                                                                 
  7929.  if (which == OPTION_ALL || which == OPTION_VIEW) {                             
  7930.                                                                                 
  7931.    (void)GGMivget(gp,"GGSCROLL ", ggscroll, sizeof(ggscroll));                  
  7932.                                                                                 
  7933.    BOOLOPTSET(ggscroll, gp->autoscroll, TRUE);                                  
  7934.                                                                                 
  7935.  }                                                                              
  7936.                                                                                 
  7937.  return;                                                                        
  7938. }                                                                               
  7939.                                                                                 
  7940. ./   ADD NAME=GGMTNET,SSI=01010055                                              
  7941.                                                                                 
  7942.  /********************************************************************/         
  7943.  /*                                                                  */         
  7944.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7945.  /*                                                                  */         
  7946.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  7947.  /*                                                                  */         
  7948.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7949.  /* including the implied warranties of merchantability and fitness, */         
  7950.  /* are expressly denied.                                            */         
  7951.  /*                                                                  */         
  7952.  /* Provided this copyright notice is included, this software may    */         
  7953.  /* be freely distributed and not offered for sale.                  */         
  7954.  /*                                                                  */         
  7955.  /* Changes or modifications may be made and used only by the maker  */         
  7956.  /* of same, and not further distributed.  Such modifications should */         
  7957.  /* be mailed to the author for consideration for addition to the    */         
  7958.  /* software and incorporation in subsequent releases.               */         
  7959.  /*                                                                  */         
  7960.  /********************************************************************/         
  7961.                                                                                 
  7962. #pragma  csect(code,  "GG@TNET ")                                               
  7963. #pragma  csect(static,"GG$TNET ")                                               
  7964. #include "gg.h"                                                                 
  7965.                                                                                 
  7966. /****** Gopher TELNET interface. *************************************/         
  7967.                                                                                 
  7968. Bool                                                                            
  7969. GGMtnet(gp,ip,as_file)                                                          
  7970. Rstruc ggcb        *gp;                                                         
  7971. Rstruc gopherinfo  *ip;                                                         
  7972. Fool                as_file;                                                    
  7973. {                                                                               
  7974.  int                tsorc;                                                      
  7975.  char               tsocmd[256];                                                
  7976.                                                                                 
  7977.  if (as_file) {                                                                 
  7978.    ERR1("TELNET interface cannot be viewed as a file.");                        
  7979.    return FALSE;                                                                
  7980.  }                                                                              
  7981.                                                                                 
  7982.  GGMispf(gp,"CONTROL DISPLAY LINE");                                            
  7983.                                                                                 
  7984.  fprintf(stderr,"Note: Login as user: %s\n\n", ip->path);                       
  7985.                                                                                 
  7986.  if (ip->port==0) sprintf(tsocmd,"%s %s",gp->mytelnet,ip->host);                
  7987.  else sprintf(tsocmd,"%s %s %d",gp->mytelnet,ip->host,ip->port);                
  7988.                                                                                 
  7989.  if ((tsorc = GGMtso(tsocmd)) != 0) {                                           
  7990.    ERR3("Command \"%s\" returned code %d", tsocmd, tsorc);                      
  7991.  }                                                                              
  7992.                                                                                 
  7993.  GGMispf(gp,"CONTROL DISPLAY REFRESH");                                         
  7994.                                                                                 
  7995.  return TRUE;                                                                   
  7996. }                                                                               
  7997.                                                                                 
  7998. ./   ADD NAME=GGMTSO                                                            
  7999.                                                                                 
  8000.  /********************************************************************/         
  8001.  /*                                                                  */         
  8002.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8003.  /*                                                                  */         
  8004.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8005.  /*                                                                  */         
  8006.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8007.  /* including the implied warranties of merchantability and fitness, */         
  8008.  /* are expressly denied.                                            */         
  8009.  /*                                                                  */         
  8010.  /* Provided this copyright notice is included, this software may    */         
  8011.  /* be freely distributed and not offered for sale.                  */         
  8012.  /*                                                                  */         
  8013.  /* Changes or modifications may be made and used only by the maker  */         
  8014.  /* of same, and not further distributed.  Such modifications should */         
  8015.  /* be mailed to the author for consideration for addition to the    */         
  8016.  /* software and incorporation in subsequent releases.               */         
  8017.  /*                                                                  */         
  8018.  /********************************************************************/         
  8019.                                                                                 
  8020.  /********************************************************************/         
  8021.  /*                                                                  */         
  8022.  /* Thanks to Michael Van Norman for this code.                      */         
  8023.  /*                                                                  */         
  8024.  /********************************************************************/         
  8025.                                                                                 
  8026. #pragma  csect(code,  "GG@TSO  ")                                               
  8027. #pragma  csect(static,"GG$TSO  ")                                               
  8028. #include "gg.h"                                                                 
  8029.                                                                                 
  8030. #pragma linkage(ikjeftsr,OS)                                                    
  8031.                                                                                 
  8032. #define _IKJEFTSR_FLAGS_AUTH        0x00000000                                  
  8033. #define _IKJEFTSR_FLAGS_COMMAND     0x00000001                                  
  8034. #define _IKJEFTSR_FLAGS_DUMP        0x00000100                                  
  8035. #define _IKJEFTSR_FLAGS_NODUMP      0x00000000                                  
  8036. #define _IKJEFTSR_FLAGS_PROGRAM     0x00000002                                  
  8037. #define _IKJEFTSR_FLAGS_UNAUTH      0x00010000                                  
  8038.                                                                                 
  8039. /****** Issue TSO command. *******************************************/         
  8040.                                                                                 
  8041. int                                                                             
  8042. GGMtso(command)                                                                 
  8043. char        *command;                                                           
  8044. {                                                                               
  8045.  int         flags         = _IKJEFTSR_FLAGS_COMMAND +                          
  8046.                              _IKJEFTSR_FLAGS_UNAUTH;                            
  8047.  int         commandLength = strlen(command);                                   
  8048.  int         rc            = 0;                                                 
  8049.  int         returnCode    = 0;                                                 
  8050.  int         reasonCode    = 0;                                                 
  8051.  int         abendCode     = 0;                                                 
  8052.                                                                                 
  8053.  static int (*ikjeftsr)() = NULL;                                               
  8054.                                                                                 
  8055.  if (!ikjeftsr) {                                                               
  8056.    int tsoEntryAddress;                                                         
  8057.                                                                                 
  8058.    tsoEntryAddress = 0x00000010;    /* Address of CVT */                        
  8059.    tsoEntryAddress = *(int *)(tsoEntryAddress);                                 
  8060.    tsoEntryAddress += 0x9C;/*       /* Offset of TVT in CVT */                  
  8061.    tsoEntryAddress = *(int *)(tsoEntryAddress);                                 
  8062.    tsoEntryAddress += 0x10;/*       /* TSVTASF-TSVT (from IKJTSVT) */           
  8063.    tsoEntryAddress = *(int *)(tsoEntryAddress);                                 
  8064.    ikjeftsr = (int (*)())(tsoEntryAddress);                                     
  8065.  }                                                                              
  8066.                                                                                 
  8067.  if (!ikjeftsr) {                                                               
  8068.    fprintf(stderr,                                                              
  8069.            "Cannot execute TSO commands, can't fetch IKJEFTSR.\n");             
  8070.    return -2;                                                                   
  8071.  }                                                                              
  8072.                                                                                 
  8073.  rc = (*ikjeftsr)(&flags, command, &commandLength,                              
  8074.                           &returnCode, &reasonCode,                             
  8075.                           (int *)((int)(&abendCode) | 0x80000000));             
  8076.                                                                                 
  8077.  if (rc != 0) {                                                                 
  8078.    if (rc > 4) {                                                                
  8079.      fprintf(stderr,"Command failed:%s\n",command);                             
  8080.      if (rc == 20 && reasonCode == 40)                                          
  8081.           fprintf(stderr,"Command was not found.\n");                           
  8082.      else fprintf(stderr,                                                       
  8083.              "rc=%d,returncode=%d,reasoncode=%d,abendcode=%8.8x\n",             
  8084.              rc, returnCode, reasonCode, abendCode);                            
  8085.    }                                                                            
  8086.    if (abendCode != 0) rc = -1;                                                 
  8087.    else rc = returnCode;                                                        
  8088.  }                                                                              
  8089.                                                                                 
  8090.  return rc;                                                                     
  8091. }                                                                               
  8092.                                                                                 
  8093. ./   ADD NAME=GGMTYPE                                                           
  8094.                                                                                 
  8095.  /********************************************************************/         
  8096.  /*                                                                  */         
  8097.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8098.  /*                                                                  */         
  8099.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8100.  /*                                                                  */         
  8101.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8102.  /* including the implied warranties of merchantability and fitness, */         
  8103.  /* are expressly denied.                                            */         
  8104.  /*                                                                  */         
  8105.  /* Provided this copyright notice is included, this software may    */         
  8106.  /* be freely distributed and not offered for sale.                  */         
  8107.  /*                                                                  */         
  8108.  /* Changes or modifications may be made and used only by the maker  */         
  8109.  /* of same, and not further distributed.  Such modifications should */         
  8110.  /* be mailed to the author for consideration for addition to the    */         
  8111.  /* software and incorporation in subsequent releases.               */         
  8112.  /*                                                                  */         
  8113.  /********************************************************************/         
  8114.                                                                                 
  8115. #pragma  csect(code,  "GG@TYPE ")                                               
  8116. #pragma  csect(static,"GG$TYPE ")                                               
  8117. #include "gg.h"                                                                 
  8118.                                                                                 
  8119. /*********************************************************************/         
  8120.                                                                                 
  8121. char *                                                                          
  8122. GGMtype(gophertype t)                                                           
  8123. {                                                                               
  8124.                                                                                 
  8125.  switch (t) {                                                                   
  8126.    case GOPHER_FILE:        return "File     ";                                 
  8127.    case GOPHER_DIRECTORY:   return "Directory";                                 
  8128.    case GOPHER_CSO:         return "Cso      ";                                 
  8129.    case GOPHER_ERROR:       return "Error    ";                                 
  8130.    case GOPHER_MAC_BINHEX:  return "Binhex   ";                                 
  8131.    case GOPHER_DOS_BINARCH: return "Binarch  ";                                 
  8132.    case GOPHER_UUENCODE:    return "Uuencode ";                                 
  8133.    case GOPHER_WAIS:        return "Index    ";                                 
  8134.    case GOPHER_TELNET:      return "Telnet   ";                                 
  8135.    case GOPHER_TN3270:      return "TN3270   ";                                 
  8136.    case GOPHER_BINARY:      return "Binary   ";                                 
  8137.    case GOPHER_REDUNDANT:   return "Redundant";                                 
  8138.    case GOPHER_WHOIS:       return "Whois    ";                                 
  8139.    default:                 return "Unknown  ";                                 
  8140.  }                                                                              
  8141. }                                                                               
  8142.                                                                                 
  8143. ./   ADD NAME=GGMUNALC                                                          
  8144.                                                                                 
  8145.  /********************************************************************/         
  8146.  /*                                                                  */         
  8147.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8148.  /*                                                                  */         
  8149.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8150.  /*                                                                  */         
  8151.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8152.  /* including the implied warranties of merchantability and fitness, */         
  8153.  /* are expressly denied.                                            */         
  8154.  /*                                                                  */         
  8155.  /* Provided this copyright notice is included, this software may    */         
  8156.  /* be freely distributed and not offered for sale.                  */         
  8157.  /*                                                                  */         
  8158.  /* Changes or modifications may be made and used only by the maker  */         
  8159.  /* of same, and not further distributed.  Such modifications should */         
  8160.  /* be mailed to the author for consideration for addition to the    */         
  8161.  /* software and incorporation in subsequent releases.               */         
  8162.  /*                                                                  */         
  8163.  /********************************************************************/         
  8164.                                                                                 
  8165. #pragma  csect(code,  "GG@UNALC")                                               
  8166. #pragma  csect(static,"GG$UNALC")                                               
  8167. #include "gg.h"                                                                 
  8168.                                                                                 
  8169. /****** Unallocate a data set. ***************************************/         
  8170.                                                                                 
  8171. Bool                                                                            
  8172. GGMunalc(ddname)                                                                
  8173. char         *ddname;                                                           
  8174. {                                                                               
  8175.  __S99parms   stuff99;   /* The manual has it wrong.  No "struct". */           
  8176.  int          rc;                                                               
  8177.  char        *cp;                                                               
  8178.  TEXTUNIT    *tu [2];                                                           
  8179.  TEXTUNIT     tu_ddn;                                                           
  8180.  TEXTUNIT     tu_una;                                                           
  8181.                                                                                 
  8182.  if (!ddname ||                                                                 
  8183.      !*ddname) return TRUE;   /* if no ddname to free, do nothing */            
  8184.                                                                                 
  8185.  memset((char *)&stuff99,0,sizeof(__S99parms));                                 
  8186.                                                                                 
  8187.  stuff99.__S99RBLN   = 20;                                                      
  8188.  stuff99.__S99VERB   = S99VRBUN;                                                
  8189.  stuff99.__S99FLAG1  = 0;                                                       
  8190.  stuff99.__S99ERROR  = 0;                                                       
  8191.  stuff99.__S99INFO   = 0;                                                       
  8192.  stuff99.__S99TXTPP  = tu;                                                      
  8193.  stuff99.__S99FLAG2  = 0;                                                       
  8194.                                                                                 
  8195.  tu[0] = &tu_ddn;                                                               
  8196.  tu[1] = &tu_una;                                                               
  8197.  *(int *)&tu[1] |= 0x80000000;                                                  
  8198.                                                                                 
  8199.  tu_ddn.key     = DUNDDNAM;                                                     
  8200.  tu_ddn.num     = 1;                                                            
  8201.  tu_ddn.ent.len = strlen(ddname);                                               
  8202.  strcpy(tu_ddn.ent.prm,ddname);                                                 
  8203.                                                                                 
  8204.  tu_una.key     = DUNUNALC;                                                     
  8205.  tu_una.num     = 0;                                                            
  8206.                                                                                 
  8207.  for (cp=tu_ddn.ent.prm; *cp; cp++) *cp = toupper(*cp);                         
  8208.                                                                                 
  8209.  rc = svc99(&stuff99);                                                          
  8210.                                                                                 
  8211.  if (rc == 0) return TRUE;                                                      
  8212.  else if (stuff99.__S99ERROR == 0x0438) /* not freed, is not allocated*/        
  8213.          return TRUE;                                                           
  8214.  else {                                                                         
  8215.    GGMdfail(rc,&stuff99);                                                       
  8216.    return FALSE;                                                                
  8217.  }                                                                              
  8218. }                                                                               
  8219.                                                                                 
  8220. ./   ADD NAME=GGMVIEW,SSI=01070056                                              
  8221.                                                                                 
  8222.  /********************************************************************/         
  8223.  /*                                                                  */         
  8224.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1993    */         
  8225.  /*                                                                  */         
  8226.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8227.  /*                                                                  */         
  8228.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8229.  /* including the implied warranties of merchantability and fitness, */         
  8230.  /* are expressly denied.                                            */         
  8231.  /*                                                                  */         
  8232.  /* Provided this copyright notice is included, this software may    */         
  8233.  /* be freely distributed and not offered for sale.                  */         
  8234.  /*                                                                  */         
  8235.  /* Changes or modifications may be made and used only by the maker  */         
  8236.  /* of same, and not further distributed.  Such modifications should */         
  8237.  /* be mailed to the author for consideration for addition to the    */         
  8238.  /* software and incorporation in subsequent releases.               */         
  8239.  /*                                                                  */         
  8240.  /********************************************************************/         
  8241.                                                                                 
  8242. #pragma  csect(code,  "GG@VIEW ")                                               
  8243. #pragma  csect(static,"GG$VIEW ")                                               
  8244. #include "gg.h"                                                                 
  8245.                                                                                 
  8246. struct browser {                                                                
  8247.    struct gopherinfo    *ip;                                                    
  8248.    struct texthdr       *thp;            /* text header pointer      */         
  8249.    struct textline     **tv;             /* text vector              */         
  8250.                char     *bda;            /* dynamic area address     */         
  8251.                char     *work;           /* find work area address   */         
  8252.                char     *firstpos;       /* beginning of actual data */         
  8253.                char     *lastpos;        /* end of actual data       */         
  8254.                int       depth;          /* dynamic area depth       */         
  8255.                int       lvl;            /* last visible line        */         
  8256.                int       size;           /* dynamic area size        */         
  8257.                int       more_rows;      /* Scroll request row count */         
  8258.                int       rowfactor;      /* # physical rows per line */         
  8259.                int       screenbump;     /* # physical rows * width  */         
  8260.                int       top;            /* top row number           */         
  8261.                int       total;          /* total number of rows     */         
  8262.                int       coloff;         /* offset from LEFT/RIGHT   */         
  8263.                int       cols;           /* 1 if COLS done, else 0   */         
  8264.                int       maxlen;         /* maximum text length      */         
  8265.                int       maxcoloff;      /* maximum right scroll     */         
  8266.                Bool      override_scroll;/* set by some commands     */         
  8267.                Bool      highlighted;    /* set if FIND highlights   */         
  8268.                Bool      reinit_browse;  /* set if text changed      */         
  8269.                Bool      exit_browse;    /* set if browse must exit  */         
  8270.                Bool      find_hit_end;   /* top/bottom of data reach */         
  8271.                int       find_count;     /* used by FIND ALL         */         
  8272.                int       find_row;       /* row where last found     */         
  8273.                int       find_col;       /* col where last found     */         
  8274.                int       found_row;      /* row where last found     */         
  8275.                int       found_col;      /* col where last found     */         
  8276.                int       csrpos;         /* cursor position          */         
  8277.                int       find_csrpos;    /* col where last found     */         
  8278.                int       found_left;     /* pos left of found string */         
  8279.                int       found_right;    /* pos right of found string*/         
  8280.                char      cursor     [9]; /* cursor field name        */         
  8281.                char      find_cursor[9]; /* row where last found     */         
  8282.                char      title     [81]; /* title                    */         
  8283.                char      cols_line [81]; /* cols line                */         
  8284.                char      zcmd      [81]; /* command input            */         
  8285.               };                                                                
  8286.                                                                                 
  8287. /******* EXTRACT command **********************************************/        
  8288.                                                                                 
  8289. static Bool                                                                     
  8290. process_extract_command(gp,bp,operands)                                         
  8291. Rstruc ggcb         *gp;                                                        
  8292. Rstruc browser      *bp;                                                        
  8293. char                *operands;                                                  
  8294. {                                                                               
  8295.  Rstruc gopherinfo  *ip = bp->ip;                                               
  8296.                                                                                 
  8297.  gp->extract_file = NULL;                                                       
  8298.                                                                                 
  8299.  (void)GGMispf(gp,"CONTROL DISPLAY SAVE");                                      
  8300.  (void)GGMxtx(gp,ip,EXTRACT_IT);                   /* Extract text */           
  8301.  (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");                                   
  8302.                                                                                 
  8303.  return TRUE;                                                                   
  8304. }                                                                               
  8305.                                                                                 
  8306. /******* PRINT command ************************************************/        
  8307.                                                                                 
  8308. static Bool                                                                     
  8309. process_print_command(gp,bp,operands)                                           
  8310. Rstruc ggcb         *gp;                                                        
  8311. Rstruc browser      *bp;                                                        
  8312. char                *operands;                                                  
  8313. {                                                                               
  8314.  Rstruc gopherinfo  *ip = bp->ip;                                               
  8315.                                                                                 
  8316.  gp->extract_file = NULL;                                                       
  8317.                                                                                 
  8318.  (void)GGMispf(gp,"CONTROL DISPLAY SAVE");                                      
  8319.  (void)GGMxtx(gp,ip,PRINT_IT);                   /* Print text */               
  8320.  (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");                                   
  8321.                                                                                 
  8322.  return TRUE;                                                                   
  8323. }                                                                               
  8324.                                                                                 
  8325. /******* INFO command. ************************************************/        
  8326.                                                                                 
  8327. static Bool                                                                     
  8328. process_info_command(gp,bp,operands)                                            
  8329. Rstruc ggcb         *gp;                                                        
  8330. Rstruc browser      *bp;                                                        
  8331. char                *operands;                                                  
  8332. {                                                                               
  8333.  Rstruc gopherinfo  *ip = bp->ip;                                               
  8334.                                                                                 
  8335.  if (!GGMinfo(gp,ip)) return FALSE;                                             
  8336.                                                                                 
  8337.  (void)GGMispf(gp,"CONTROL DISPLAY SAVE");                                      
  8338.  (void)GGMvtx(gp,NULL,TRUE);              /* View text */                       
  8339.  (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");                                   
  8340.                                                                                 
  8341.  return TRUE;                                                                   
  8342. }                                                                               
  8343.                                                                                 
  8344. /******* BOOKMARK command. ********************************************/        
  8345.                                                                                 
  8346. static Bool                                                                     
  8347. process_bookmark_command(gp,bp,operands)                                        
  8348. Rstruc ggcb         *gp;                                                        
  8349. Rstruc browser      *bp;                                                        
  8350. char                *operands;                                                  
  8351. {                                                                               
  8352.  Rstruc gopherinfo  *ip = bp->ip;                                               
  8353.                                                                                 
  8354.  if (!GGMinfo(gp,ip)) return FALSE;                                             
  8355.                                                                                 
  8356.  gp->extract_file = NULL;                                                       
  8357.                                                                                 
  8358.  (void)GGMispf(gp,"CONTROL DISPLAY SAVE");                                      
  8359.  (void)GGMxtx(gp,ip,BOOKMARK_IT);       /* save as bookmark */                  
  8360.  (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");                                   
  8361.                                                                                 
  8362.  return TRUE;                                                                   
  8363. }                                                                               
  8364.                                                                                 
  8365. /******* QUIT command *************************************************/        
  8366.                                                                                 
  8367. static Bool                                                                     
  8368. process_quit_command(gp,bp,operands)                                            
  8369. Rstruc ggcb         *gp;                                                        
  8370. Rstruc browser      *bp;                                                        
  8371. char                *operands;                                                  
  8372. {                                                                               
  8373.                                                                                 
  8374.  gp->quit = TRUE;                                                               
  8375.                                                                                 
  8376.  return TRUE;                                                                   
  8377. }                                                                               
  8378.                                                                                 
  8379. /******* COLS command *************************************************/        
  8380.                                                                                 
  8381. static Bool                                                                     
  8382. process_cols_command(gp,bp,operands)                                            
  8383. Rstruc ggcb         *gp;                                                        
  8384. Rstruc browser      *bp;                                                        
  8385. char                *operands;                                                  
  8386. {                                                                               
  8387.                                                                                 
  8388.  bp->cols = 1;                                                                  
  8389.  *bp->cols_line = '\0';                                                         
  8390.  bp->reinit_browse = TRUE;                                                      
  8391.  return TRUE;                                                                   
  8392. }                                                                               
  8393.                                                                                 
  8394. /******* RESET command ************************************************/        
  8395.                                                                                 
  8396. static Bool                                                                     
  8397. process_reset_command(gp,bp,operands)                                           
  8398. Rstruc ggcb         *gp;                                                        
  8399. Rstruc browser      *bp;                                                        
  8400. char                *operands;                                                  
  8401. {                                                                               
  8402.                                                                                 
  8403.  bp->cols = 0;                                                                  
  8404.  *bp->cols_line = '\0';                                                         
  8405.  bp->reinit_browse = TRUE;                                                      
  8406.  return TRUE;                                                                   
  8407. }                                                                               
  8408.                                                                                 
  8409. /******* DISPLAY command **********************************************/        
  8410.                                                                                 
  8411. static Bool                                                                     
  8412. process_display_command(gp,bp,operands)                                         
  8413. Rstruc ggcb         *gp;                                                        
  8414. Rstruc browser      *bp;                                                        
  8415. char                *operands;                                                  
  8416. {                                                                               
  8417.  unsigned int        u;                                                         
  8418.                                                                                 
  8419.  switch (strlen(operands)) {                                                    
  8420.    case 1: gp->text_dispchar = operands[0];                                     
  8421.            break;                                                               
  8422.    case 2: if (1 != sscanf(operands,"%x",&u)) {                                 
  8423.              ERR1("Invalid hex character representation.");                     
  8424.              return FALSE;                                                      
  8425.            }                                                                    
  8426.            gp->text_dispchar = u;                                               
  8427.            break;                                                               
  8428.    default:                                                                     
  8429.            ERR1("A single character must be specified.");                       
  8430.            return FALSE;                                                        
  8431.  }                                                                              
  8432.  bp->reinit_browse = TRUE;                                                      
  8433.  return TRUE;                                                                   
  8434. }                                                                               
  8435.                                                                                 
  8436. /******* LOCATE command ***********************************************/        
  8437.                                                                                 
  8438. static Bool                                                                     
  8439. process_locate_command(gp,bp,operands)                                          
  8440. Rstruc ggcb         *gp;                                                        
  8441. Rstruc browser      *bp;                                                        
  8442. char                *operands;                                                  
  8443. {                                                                               
  8444.  int                 locnum;                                                    
  8445.  char                junk[72];                                                  
  8446.                                                                                 
  8447.  if (1 != sscanf(operands, "%d %s", &locnum, junk)) {                           
  8448.    ERR1("The LOCATE command requires a line number.");                          
  8449.    return FALSE;                                                                
  8450.  }                                                                              
  8451.                                                                                 
  8452.  bp->top = locnum;                                                              
  8453.  bp->more_rows = 0;                                                             
  8454.  bp->override_scroll = TRUE;                                                    
  8455.  bp->reinit_browse = TRUE;                                                      
  8456.  return TRUE;                                                                   
  8457. }                                                                               
  8458.                                                                                 
  8459. /***** Helper functions for FIND **************************************/        
  8460.                                                                                 
  8461. /*--------------------------------------------------------------------*         
  8462.  * Get quoted FIND string.                                            *         
  8463.  *--------------------------------------------------------------------*/        
  8464.                                                                                 
  8465. static char *                                                                   
  8466. get_quoted_find_string(gp,cp,qform)                                             
  8467. Rstruc ggcb         *gp;                                                        
  8468. char                *cp;                                                        
  8469. char                *qform;                                                     
  8470. {                                                                               
  8471.  char                quote     = *cp;                                           
  8472.  char                termchar  = '\0';                                          
  8473.                                                                                 
  8474.  for (cp++;;cp++) {                                                             
  8475.    if (*cp == quote) {                                                          
  8476.      switch (*(cp+1)) {                                                         
  8477.        case '\0':                                                               
  8478.        case ' ':  termchar = '\0'; break;                                       
  8479.        case 'c':                                                                
  8480.        case 'C':  termchar = 'C' ; break;                                       
  8481.        case 't':                                                                
  8482.        case 'T':  termchar = 'T' ; break;                                       
  8483.        case 'x':                                                                
  8484.        case 'X':  termchar = 'X' ; break;                                       
  8485.        case 'p':                                                                
  8486.        case 'P':  termchar = 'P' ; break;                                       
  8487.        default:   continue;                                                     
  8488.      }                                                                          
  8489.      if (termchar) {                                                            
  8490.        switch (*(cp+2)) {                                                       
  8491.          case '\0':                                                             
  8492.          case ' ':  break;                                                      
  8493.          default:   continue;                                                   
  8494.        }                                                                        
  8495.        if (*qform != FIND_QUOTED) {                                             
  8496.          ERR1(                                                                  
  8497.       "Invalid string; Do not surround a quoted string with letters.");         
  8498.          *qform = FIND_BADFORM;                                                 
  8499.          return NULL;                                                           
  8500.        }                                                                        
  8501.        else {                                                                   
  8502.          switch (termchar) {                                                    
  8503.            case 'C': *qform = FIND_C; break;                                    
  8504.            case 'T': *qform = FIND_T; break;                                    
  8505.            case 'X': *qform = FIND_X; break;                                    
  8506.            case 'P': *qform = FIND_P; break;                                    
  8507.          }                                                                      
  8508.          *cp = '\0'; /* kill the quote because it's the character */            
  8509.          cp++;       /* that the caller will kill, not the quote */             
  8510.        }                                                                        
  8511.      }                                                                          
  8512.      break;                                                                     
  8513.    }                                                                            
  8514.    else if (!*cp) {                                                             
  8515.      ERR1(                                                                      
  8516.      "Missing quote; The FIND command requires balanced quote marks.");         
  8517.      *qform = FIND_BADFORM;                                                     
  8518.      return NULL;                                                               
  8519.    }                                                                            
  8520.  }                                                                              
  8521.  return cp;                                                                     
  8522. }                                                                               
  8523.                                                                                 
  8524. /*--------------------------------------------------------------------*         
  8525.  * Get FIND operand.                                                  *         
  8526.  *--------------------------------------------------------------------*/        
  8527.                                                                                 
  8528. static char *                                                                   
  8529. get_find_operand(gp,opp,qform)                                                  
  8530. Rstruc ggcb     *gp;                                                            
  8531. char           **opp;                                                           
  8532. char            *qform;                                                         
  8533. {                                                                               
  8534.  char           *cp    = *opp;                                                  
  8535.  char           *start = NULL;                                                  
  8536.                                                                                 
  8537.  cp = skip_ISPF_whitespace(cp);                                                 
  8538.                                                                                 
  8539.  if (!*cp) return NULL;                                                         
  8540.  if (*cp == '\'' || *cp == '"') {                                               
  8541.    start = cp+1;                                                                
  8542.    *qform = FIND_QUOTED;                                                        
  8543.    if (!(cp = get_quoted_find_string(gp,cp,qform))) return NULL;                
  8544.  }                                                                              
  8545.  else if ((*(cp+1) == '\'' || *(cp+1) == '"')) {                                
  8546.    switch (*cp) {                                                               
  8547.      case 'c':                                                                  
  8548.      case 'C': *qform = FIND_C; break;                                          
  8549.      case 't':                                                                  
  8550.      case 'T': *qform = FIND_T; break;                                          
  8551.      case 'x':                                                                  
  8552.      case 'X': *qform = FIND_X; break;                                          
  8553.      case 'p':                                                                  
  8554.      case 'P': *qform = FIND_P; break;                                          
  8555.      default:  *qform = FIND_UNQUOTED; break;                                   
  8556.    }                                                                            
  8557.    if (*qform != FIND_UNQUOTED) {                                               
  8558.      cp++;                                                                      
  8559.      start = cp+1;                                                              
  8560.      if (!(cp = get_quoted_find_string(gp,cp,qform))) return NULL;              
  8561.    }                                                                            
  8562.    else {                                                                       
  8563.      start = cp;                                                                
  8564.      find_ISPF_whitespace(cp,start);                                            
  8565.    }                                                                            
  8566.  }                                                                              
  8567.  else {                                                                         
  8568.    start = cp;                                                                  
  8569.    *qform = FIND_UNQUOTED;                                                      
  8570.    find_ISPF_whitespace(cp,start);                                              
  8571.  }                                                                              
  8572.  if (*cp) {                                                                     
  8573.    *cp  = '\0';                                                                 
  8574.    *opp = cp+1;                                                                 
  8575.  }                                                                              
  8576.  else {                                                                         
  8577.    *opp = cp;                                                                   
  8578.  }                                                                              
  8579.  return start;                                                                  
  8580. }                                                                               
  8581.                                                                                 
  8582. /*--------------------------------------------------------------------*         
  8583.  * Find it.                                                           *         
  8584.  *--------------------------------------------------------------------*/        
  8585.                                                                                 
  8586. #define REND                 (r+(*tpp)->tab_expanded_text_length)               
  8587. #define PRECEDED_BY_VERBIAGE (q>r && isalnum(*(q-1)))                           
  8588. #define FOLLOWED_BY_VERBIAGE (q+findlen<REND && isalnum(*(q+findlen)))          
  8589.                                                                                 
  8590. static Bool                                                                     
  8591. find_it(gp,bp,find_string,findlen,                                              
  8592.                           find_type,find_what,find_trans,                       
  8593.                           find_left_bound,find_right_bound)                     
  8594. Rstruc ggcb       *gp;                                                          
  8595. Rstruc browser    *bp;                                                          
  8596. char              *find_string;                                                 
  8597. int                findlen;                                                     
  8598. char               find_type;      /* chars word prefix suffix */               
  8599. char               find_what;      /* next prev first last all */               
  8600. char               find_trans;     /* caps asis generic        */               
  8601. int                find_left_bound;                                             
  8602. int                find_right_bound;                                            
  8603. {                                                                               
  8604.  struct textline **tpp;                                                         
  8605.  char             *p;                                                           
  8606.  char             *q;                                                           
  8607.  char             *r;                                                           
  8608.  int               row;                                                         
  8609.  int               col;                                                         
  8610.  int               complen;                                                     
  8611.  int               lcol;                                                        
  8612.  int               rcol;                                                        
  8613.  int               ecol;                                                        
  8614.  Bool              backward_find;                                               
  8615.                                                                                 
  8616.  lcol = find_left_bound - 1;                                                    
  8617.  rcol = find_right_bound - 1;                                                   
  8618.  row  = bp->find_row;                                                           
  8619.  col  = bp->find_col;                                                           
  8620.                                                                                 
  8621.  switch (find_what) {                                                           
  8622.    case FIND_NEXT:                                                              
  8623.                     if (bp->find_hit_end) {                                     
  8624.                       bp->find_hit_end = FALSE;                                 
  8625.                       row = 0;                                                  
  8626.                       col = lcol;                                               
  8627.                     }                                                           
  8628.                     else if (EQUAL(bp->find_cursor,"GGBDYNA")) {                
  8629.                       row = bp->top+((bp->find_csrpos-1)/80)-bp->cols-1;        
  8630.                       col = (bp->find_csrpos-1) % 80 + bp->coloff;              
  8631.                       if (++col >= bp->maxlen) {                                
  8632.                         row++;                                                  
  8633.                         col = lcol;                                             
  8634.                       }                                                         
  8635.                     }                                                           
  8636.                     else {                                                      
  8637.                       row = bp->top - 1;                                        
  8638.                       if (row < 0) row = 0;                                     
  8639.                       col = lcol;                                               
  8640.                     }                                                           
  8641.                     backward_find = FALSE;                                      
  8642.                     break;                                                      
  8643.    case FIND_PREV:                                                              
  8644.                     if (bp->find_hit_end) {                                     
  8645.                       bp->find_hit_end = FALSE;                                 
  8646.                       row = bp->total - 1;                                      
  8647.                       col = rcol;                                               
  8648.                     }                                                           
  8649.                     else if (EQUAL(bp->find_cursor,"GGBDYNA")) {                
  8650.                       row = bp->top+((bp->find_csrpos-1)/80)-bp->cols-1;        
  8651.                       col = (bp->find_csrpos-1) % 80 + bp->coloff;              
  8652.                       if (--col < 0) {                                          
  8653.                         row--;                                                  
  8654.                         col = rcol;                                             
  8655.                       }                                                         
  8656.                     }                                                           
  8657.                     else {                                                      
  8658.                       row = bp->total - 1;                                      
  8659.                       col = rcol;                                               
  8660.                     }                                                           
  8661.                     backward_find = TRUE;                                       
  8662.                     break;                                                      
  8663.    case FIND_FIRST:                                                             
  8664.                     if (bp->find_hit_end) {                                     
  8665.                       bp->find_hit_end = FALSE;                                 
  8666.                     }                                                           
  8667.                     row = 0;                                                    
  8668.                     col = lcol;                                                 
  8669.                     backward_find = FALSE;                                      
  8670.                     break;                                                      
  8671.    case FIND_LAST:                                                              
  8672.                     if (bp->find_hit_end) {                                     
  8673.                       bp->find_hit_end = FALSE;                                 
  8674.                     }                                                           
  8675.                     row = bp->total - 1;                                        
  8676.                     col = rcol;                                                 
  8677.                     backward_find = TRUE;                                       
  8678.                     break;                                                      
  8679.    case FIND_ALL:                                                               
  8680.                     col++;                                                      
  8681.                     backward_find = FALSE;                                      
  8682.                     break;                                                      
  8683.  }                                                                              
  8684.                                                                                 
  8685.  if (backward_find == FALSE) {                                                  
  8686.    /* forward find */                                                           
  8687.    if (col < lcol) col = lcol;                                                  
  8688.    else if (col > rcol) {                                                       
  8689.      col = lcol;                                                                
  8690.      row++;                                                                     
  8691.    }                                                                            
  8692.    for (tpp = &bp->tv[row]; row < bp->total; tpp++, col=lcol, row++) {          
  8693.      ecol = (*tpp)->tab_expanded_text_length - 1;                               
  8694.      if (ecol > rcol) ecol = rcol;                                              
  8695.      if (col > ecol) continue;                                                  
  8696.      p = (*tpp)->tab_expanded_text;                                             
  8697.      if (find_trans == FIND_CAPS) {                                             
  8698.        copy_uppercase(bp->work,p);                                              
  8699.        r = bp->work;                                                            
  8700.      }                                                                          
  8701.      else r = p;                                                                
  8702.      complen = ecol-col+1;                                                      
  8703.      for (q = r + col;;q++) {                                                   
  8704.        q = memchr(q,find_string[0],complen);                                    
  8705.        if (!q) break;                                                           
  8706.        col = q - r;                                                             
  8707.        complen = ecol-col+1;                                                    
  8708.        if (complen < findlen) break;                                            
  8709.        if (!memcmp(q,find_string,findlen)) {                                    
  8710.          switch (find_type) {                                                   
  8711.            case FIND_CHARS:  break;                                             
  8712.            case FIND_WORD:                                                      
  8713.                 if (PRECEDED_BY_VERBIAGE || FOLLOWED_BY_VERBIAGE)               
  8714.                     continue;                                                   
  8715.                 break;                                                          
  8716.            case FIND_PREFIX:                                                    
  8717.                 if (PRECEDED_BY_VERBIAGE || !FOLLOWED_BY_VERBIAGE)              
  8718.                     continue;                                                   
  8719.                 break;                                                          
  8720.            case FIND_SUFFIX:                                                    
  8721.                 if (!PRECEDED_BY_VERBIAGE || FOLLOWED_BY_VERBIAGE)              
  8722.                    continue;                                                    
  8723.                 break;                                                          
  8724.          }                                                                      
  8725.          bp->find_row = row;                                                    
  8726.          bp->find_col = col;                                                    
  8727.          return TRUE;                                                           
  8728.        }                                                                        
  8729.      }                                                                          
  8730.    }                                                                            
  8731.    bp->find_row = 0;                                                            
  8732.    bp->find_col = 0;                                                            
  8733.    bp->find_hit_end = TRUE;                                                     
  8734.    return FALSE;                                                                
  8735.  }                                                                              
  8736.  else {                                                                         
  8737.    /* backward find */                                                          
  8738.    if (row >= bp->total) row = bp->total - 1;                                   
  8739.    if (col > rcol-findlen+1) col = rcol-findlen+1;                              
  8740.    else if (col < lcol) {                                                       
  8741.      col = rcol-findlen+1;                                                      
  8742.      row--;                                                                     
  8743.    }                                                                            
  8744.    for (tpp=&bp->tv[row]; row >= 0; tpp--, col=rcol-findlen+1, row--) {         
  8745.      ecol = (*tpp)->tab_expanded_text_length - 1;                               
  8746.      if (ecol > rcol) ecol = rcol;                                              
  8747.      if (col > ecol) col = ecol;                                                
  8748.      p = (*tpp)->tab_expanded_text;                                             
  8749.      if (find_trans == FIND_CAPS) {                                             
  8750.        copy_uppercase(bp->work,p);                                              
  8751.        r = bp->work;                                                            
  8752.      }                                                                          
  8753.      else r = p;                                                                
  8754.      for (q = r + col; q >= r; q--) {                                           
  8755.        if (!memcmp(q,find_string,findlen)) {                                    
  8756.          switch (find_type) {                                                   
  8757.            case FIND_CHARS:  break;                                             
  8758.            case FIND_WORD:                                                      
  8759.                 if (PRECEDED_BY_VERBIAGE || FOLLOWED_BY_VERBIAGE)               
  8760.                     continue;                                                   
  8761.                 break;                                                          
  8762.            case FIND_PREFIX:                                                    
  8763.                 if (PRECEDED_BY_VERBIAGE || !FOLLOWED_BY_VERBIAGE)              
  8764.                     continue;                                                   
  8765.                 break;                                                          
  8766.            case FIND_SUFFIX:                                                    
  8767.                 if (!PRECEDED_BY_VERBIAGE || FOLLOWED_BY_VERBIAGE)              
  8768.                    continue;                                                    
  8769.                 break;                                                          
  8770.          }                                                                      
  8771.          col = q - r;                                                           
  8772.          bp->find_row = row;                                                    
  8773.          bp->find_col = col;                                                    
  8774.          return TRUE;                                                           
  8775.        }                                                                        
  8776.      }                                                                          
  8777.    }                                                                            
  8778.    bp->find_row = bp->total - 1;                                                
  8779.    bp->find_col = bp->maxlen;                                                   
  8780.    bp->find_hit_end = TRUE;                                                     
  8781.    return FALSE;                                                                
  8782.  }                                                                              
  8783.                                                                                 
  8784. }                                                                               
  8785.                                                                                 
  8786. /********* FIND command ***********************************************/        
  8787.                                                                                 
  8788. static Bool                                                                     
  8789. process_find_command(gp,bp,operands)                                            
  8790. Rstruc ggcb         *gp;                                                        
  8791. Rstruc browser      *bp;                                                        
  8792. char                *operands;                                                  
  8793. {                                                                               
  8794.  char        *find_operand [64];                                                
  8795.  char        *show_type;                                                        
  8796.  char        *cp;                                                               
  8797.  char        *opcopy;                                                           
  8798.  char        *op;                                                               
  8799.  char        *p;                                                                
  8800.  char        *q;                                                                
  8801.  char         find_qform   [64];                                                
  8802.  Bool         finderror = FALSE;                                                
  8803.  Bool         out_of_bounds = FALSE;                                            
  8804.  int          find_operand_count;                                               
  8805.  int          ox;                                                               
  8806.  int          find_left_bound;                                                  
  8807.  int          find_right_bound;                                                 
  8808.  int          n;                                                                
  8809.  int          len;                                                              
  8810.  int          findlen;                                                          
  8811.  char         find_what;      /* next prev first last all */                    
  8812.  char         find_type;      /* chars word prefix suffix */                    
  8813.  char         find_trans;     /* caps asis generic        */                    
  8814.  char         find_form;      /* unquoted quoted c x t p  */                    
  8815.  char         ff;             /* unquoted quoted c x t p  */                    
  8816.  Bool         hit_end                = FALSE;                                   
  8817.  Bool         find_string_given      = FALSE;                                   
  8818.  Bool         find_what_given        = FALSE;                                   
  8819.  Bool         find_type_given        = FALSE;                                   
  8820.  Bool         find_left_bound_given  = FALSE;                                   
  8821.  Bool         find_right_bound_given = FALSE;                                   
  8822.  char         operand_copy [81];                                                
  8823.  char         find_string  [81];                                                
  8824.  char         temp         [81];                                                
  8825.  char         show_string [129];                                                
  8826.  char         shortmsg    [129];                                                
  8827.  char         longmsg     [129];                                                
  8828.                                                                                 
  8829.  strcpy(operand_copy,operands);                                                 
  8830.                                                                                 
  8831.  find_operand_count = 0;                                                        
  8832.  for (ox = 0, opcopy = operand_copy; ox < 64; ox++) {                           
  8833.    ff = FIND_UNQUOTED;                                                          
  8834.    op = get_find_operand(gp,&opcopy,&ff);                                       
  8835.    if (ff == FIND_BADFORM) return FALSE;                                        
  8836.    if (!op) break;                                                              
  8837.    find_operand[ox] = op;                                                       
  8838.    find_qform[ox] = ff;                                                         
  8839.    find_operand_count++;                                                        
  8840.  }                                                                              
  8841.                                                                                 
  8842.  if (find_operand_count == 0) {                                                 
  8843.    if (!*gp->text_find_string) {                                                
  8844.      ERR1("The first FIND command requires an operand.");                       
  8845.      return FALSE;                                                              
  8846.    }                                                                            
  8847.    strcpy(find_string,gp->text_find_string);                                    
  8848.    find_what        = gp->text_find_what;                                       
  8849.    find_type        = gp->text_find_type;                                       
  8850.    find_trans       = gp->text_find_trans;                                      
  8851.    find_left_bound  = gp->text_find_left_bound;                                 
  8852.    find_right_bound = gp->text_find_right_bound;                                
  8853.  }                                                                              
  8854.  else {                                                                         
  8855.    find_what        = FIND_NEXT;                                                
  8856.    find_type        = FIND_CHARS;                                               
  8857.    find_trans       = FIND_CAPS;                                                
  8858.    find_left_bound  = 1;                                                        
  8859.    find_right_bound = bp->maxlen;                                               
  8860.    for (ox = 0; ox < find_operand_count; ox++) {                                
  8861.      op = find_operand[ox];                                                     
  8862.      ff = find_qform[ox];                                                       
  8863.      if (ff != FIND_UNQUOTED) {                                                 
  8864.        if (find_string_given) finderror = TRUE;                                 
  8865.        else {                                                                   
  8866.          strcpy(find_string,op);                                                
  8867.          find_form = ff;                                                        
  8868.          find_string_given = TRUE;                                              
  8869.        }                                                                        
  8870.      }                                                                          
  8871.      else {                                                                     
  8872.        copy_uppercase(temp,op);                                                 
  8873.        if (EQUAL(temp,"*")) {                                                   
  8874.          if (find_string_given) finderror = TRUE;                               
  8875.          else {                                                                 
  8876.            strcpy(find_string,gp->text_find_string);                            
  8877.            find_form = ff;                                                      
  8878.            find_string_given = TRUE;                                            
  8879.          }                                                                      
  8880.        }                                                                        
  8881.        else if (find_operand_count == 1) {                                      
  8882.          strcpy(find_string,op);                                                
  8883.          find_form = ff;                                                        
  8884.          find_string_given = TRUE;                                              
  8885.        }                                                                        
  8886.        else if (EQUAL(temp,"NEXT")) {                                           
  8887.          if (find_what_given) finderror = TRUE;                                 
  8888.          else {                                                                 
  8889.            find_what = FIND_NEXT;                                               
  8890.            find_what_given = TRUE;                                              
  8891.          }                                                                      
  8892.        }                                                                        
  8893.        else if (EQUAL(temp,"PREV")) {                                           
  8894.          if (find_what_given) finderror = TRUE;                                 
  8895.          else {                                                                 
  8896.            find_what = FIND_PREV;                                               
  8897.            find_what_given = TRUE;                                              
  8898.          }                                                                      
  8899.        }                                                                        
  8900.        else if (EQUAL(temp,"FIRST")) {                                          
  8901.          if (find_what_given) finderror = TRUE;                                 
  8902.          else {                                                                 
  8903.            find_what = FIND_FIRST;                                              
  8904.            find_what_given = TRUE;                                              
  8905.          }                                                                      
  8906.        }                                                                        
  8907.        else if (EQUAL(temp,"LAST")) {                                           
  8908.          if (find_what_given) finderror = TRUE;                                 
  8909.          else {                                                                 
  8910.            find_what = FIND_LAST;                                               
  8911.            find_what_given = TRUE;                                              
  8912.          }                                                                      
  8913.        }                                                                        
  8914.        else if (EQUAL(temp,"ALL")) {                                            
  8915.          if (find_what_given) finderror = TRUE;                                 
  8916.          else {                                                                 
  8917.            find_what = FIND_ALL;                                                
  8918.            find_what_given = TRUE;                                              
  8919.          }                                                                      
  8920.        }                                                                        
  8921.        else if (EQUAL(temp,"CHARS")) {                                          
  8922.          if (find_type_given) finderror = TRUE;                                 
  8923.          else {                                                                 
  8924.            find_type = FIND_CHARS;                                              
  8925.            find_type_given = TRUE;                                              
  8926.          }                                                                      
  8927.        }                                                                        
  8928.        else if (EQUAL(temp,"WORD")) {                                           
  8929.          if (find_type_given) finderror = TRUE;                                 
  8930.          else {                                                                 
  8931.            find_type = FIND_WORD;                                               
  8932.            find_type_given = TRUE;                                              
  8933.          }                                                                      
  8934.        }                                                                        
  8935.        else if (EQUAL(temp,"PREFIX") || EQUAL(temp,"PRE")) {                    
  8936.          if (find_type_given) finderror = TRUE;                                 
  8937.          else {                                                                 
  8938.            find_type = FIND_PREFIX;                                             
  8939.            find_type_given = TRUE;                                              
  8940.          }                                                                      
  8941.        }                                                                        
  8942.        else if (EQUAL(temp,"SUFFIX") || EQUAL(temp,"SUF")) {                    
  8943.          if (find_type_given) finderror = TRUE;                                 
  8944.          else {                                                                 
  8945.            find_type = FIND_SUFFIX;                                             
  8946.            find_type_given = TRUE;                                              
  8947.          }                                                                      
  8948.        }                                                                        
  8949.        else if (*(temp+strspn(temp,"0123456789")) == '\0') {                    
  8950.          if (find_left_bound_given) {                                           
  8951.            if (find_right_bound_given) finderror = TRUE;                        
  8952.            else {                                                               
  8953.              find_right_bound = atoi(temp);                                     
  8954.              if (find_right_bound > bp->maxlen) out_of_bounds = TRUE;           
  8955.              find_right_bound_given = TRUE;                                     
  8956.            }                                                                    
  8957.          }                                                                      
  8958.          else {                                                                 
  8959.            find_left_bound  = atoi(temp);                                       
  8960.              if (find_right_bound < 1) out_of_bounds = TRUE;                    
  8961.            find_left_bound_given = TRUE;                                        
  8962.          }                                                                      
  8963.        }                                                                        
  8964.        else {                                                                   
  8965.          if (find_string_given) finderror = TRUE;                               
  8966.          else {                                                                 
  8967.            strcpy(find_string,op);                                              
  8968.            find_form = ff;                                                      
  8969.            find_string_given = TRUE;                                            
  8970.          }                                                                      
  8971.        }                                                                        
  8972.      }                                                                          
  8973.    }                                                                            
  8974.  }                                                                              
  8975.                                                                                 
  8976.  if (out_of_bounds) {                                                           
  8977.    ERR2("Invalid bound; Bounds must lie between 1 and %d", bp->maxlen);         
  8978.    return FALSE;                                                                
  8979.  }                                                                              
  8980.                                                                                 
  8981.  if (finderror) {                                                               
  8982.    ERR1("Put string in quotes; Conflicting or unknown parameter.");             
  8983.    return FALSE;                                                                
  8984.  }                                                                              
  8985.                                                                                 
  8986.  len = strlen(find_string);                                                     
  8987.                                                                                 
  8988.  if (find_string_given) bp->find_hit_end = FALSE;                               
  8989.                                                                                 
  8990.  if (find_left_bound_given && find_right_bound_given                            
  8991.      && find_left_bound > find_right_bound) {                                   
  8992.    n = find_left_bound;                                                         
  8993.    find_left_bound = find_right_bound;                                          
  8994.    find_right_bound = n;                                                        
  8995.  }                                                                              
  8996.  else if (find_left_bound_given && !find_right_bound_given) {                   
  8997.    find_right_bound = find_left_bound + len - 1;                                
  8998.  }                                                                              
  8999.                                                                                 
  9000.  if (find_string_given) {                                                       
  9001.    switch (find_form) {                                                         
  9002.      case FIND_UNQUOTED:  find_trans = FIND_CAPS;    break;                     
  9003.      case FIND_QUOTED:    find_trans = FIND_CAPS;    break;                     
  9004.      case FIND_C:         find_trans = FIND_ASIS;    break;                     
  9005.      case FIND_T:         find_trans = FIND_CAPS;    break;                     
  9006.      case FIND_P:         find_trans = FIND_GENERIC; break;                     
  9007.      case FIND_X:         find_trans = FIND_HEX;                                
  9008.         if (len % 2 != 0) {                                                     
  9009.           ERR1("Odd number of characters in hex string.");                      
  9010.           return FALSE;                                                         
  9011.         }                                                                       
  9012.         if (len != strspn(find_string,"0123456789abcdefABCDEF")) {              
  9013.           ERR1("Invalid (non-hex) characters in hex string.");                  
  9014.           return FALSE;                                                         
  9015.         }                                                                       
  9016.         for (p = find_string, q = find_string; *p; p += 2, *q++) {              
  9017.           sprintf(temp,"0x%2.2s",p);                                            
  9018.           sscanf(temp,"%x",&n);                                                 
  9019.           *q = (char)n;                                                         
  9020.         }                                                                       
  9021.         *q = '\0';                                                              
  9022.         len = strlen(find_string);                                              
  9023.         break;                                                                  
  9024.    }                                                                            
  9025.  }                                                                              
  9026.                                                                                 
  9027.  /* Store parameters for next Repeat Find operation. */                         
  9028.                                                                                 
  9029.  strcpy(gp->text_find_string,find_string);                                      
  9030.  switch (find_what) {                                                           
  9031.    case FIND_PREV:                                                              
  9032.    case FIND_LAST:  gp->text_find_what = FIND_PREV; break;                      
  9033.    default:         gp->text_find_what = FIND_NEXT; break;                      
  9034.  }                                                                              
  9035.  gp->text_find_type        = find_type;                                         
  9036.  gp->text_find_trans       = find_trans;                                        
  9037.  gp->text_find_left_bound  = find_left_bound;                                   
  9038.  gp->text_find_right_bound = find_right_bound;                                  
  9039.                                                                                 
  9040.  if (!*find_string) {                                                           
  9041.    ERR1("A null string is not allowed for the FIND command.");                  
  9042.    return FALSE;                                                                
  9043.  }                                                                              
  9044.                                                                                 
  9045.  if (bp->total == 0) {                                                          
  9046.    ERR1("There is no text to search.");                                         
  9047.    return FALSE;                                                                
  9048.  }                                                                              
  9049.                                                                                 
  9050.  strcpy(bp->zcmd,"");                                                           
  9051.                                                                                 
  9052.  switch (find_type) {                                                           
  9053.    case FIND_CHARS:   show_type = "Chars";  break;                              
  9054.    case FIND_WORD:    show_type = "Word";   break;                              
  9055.    case FIND_PREFIX:  show_type = "Prefix"; break;                              
  9056.    case FIND_SUFFIX:  show_type = "Suffix"; break;                              
  9057.    default:           show_type = "Text";   break;                              
  9058.  }                                                                              
  9059.                                                                                 
  9060.  switch (find_trans) {                                                          
  9061.    case FIND_ASIS:    strcpy(show_string+0,"C'");                               
  9062.                       strcpy(show_string+2,find_string);                        
  9063.                       strcat(show_string,"'");                                  
  9064.                       break;                                                    
  9065.    case FIND_GENERIC: strcpy(show_string+0,"P'");                               
  9066.                       strcpy(show_string+2,find_string);                        
  9067.                       strcat(show_string,"'");                                  
  9068.                       break;                                                    
  9069.    case FIND_HEX:     strcpy(show_string+0,"X'");                               
  9070.                       for (p=find_string,q=show_string+2;*p;p++,q+=2) {         
  9071.                         sprintf(q,"%2.2X",*p);                                  
  9072.                       }                                                         
  9073.                       strcat(show_string,"'");                                  
  9074.                       break;                                                    
  9075.    case FIND_CAPS:                                                              
  9076.    default:           strcpy(show_string+0,"'");                                
  9077.                       strcpy(show_string+1,find_string);                        
  9078.                       strcat(show_string,"'");                                  
  9079.                       break;                                                    
  9080.  }                                                                              
  9081.                                                                                 
  9082.  switch (find_trans) {                                                          
  9083.    case FIND_CAPS:                                                              
  9084.         uppercase_in_place(find_string);                                        
  9085.         break;                                                                  
  9086.    case FIND_GENERIC:                                                           
  9087.         ERR1("The P'string' generic format is not supported.");                 
  9088.         return FALSE;                                                           
  9089.  }                                                                              
  9090.                                                                                 
  9091.  hit_end = bp->find_hit_end;                                                    
  9092.  findlen = strlen(find_string);                                                 
  9093.                                                                                 
  9094.  if (find_what == FIND_ALL) {                                                   
  9095.    bp->find_count = 0;                                                          
  9096.    if (!find_it(gp,bp,find_string,findlen,                                      
  9097.                                   find_type,FIND_FIRST,find_trans,              
  9098.                                   find_left_bound, find_right_bound)) {         
  9099.      sprintf(shortmsg,"No %s %s found",show_type,show_string);                  
  9100.      sprintf(longmsg,                                                           
  9101.              "%s %s - not found within columns %d to %d",                       
  9102.              show_type,show_string,find_left_bound,find_right_bound);           
  9103.      ERR3("%24s;%s",shortmsg,longmsg);                                          
  9104.      return FALSE;                                                              
  9105.    }                                                                            
  9106.    bp->found_row = bp->find_row;                                                
  9107.    bp->found_col = bp->find_col;                                                
  9108.    bp->find_count = 1;                                                          
  9109.    while (find_it(gp,bp,find_string,findlen,                                    
  9110.                         find_type,FIND_ALL,find_trans,                          
  9111.                         find_left_bound, find_right_bound)) {                   
  9112.          bp->find_count++;                                                      
  9113.    }                                                                            
  9114.    bp->find_hit_end = FALSE;                                                    
  9115.  }                                                                              
  9116.  else {                                                                         
  9117.    if (!find_it(gp,bp,find_string,findlen,                                      
  9118.                                   find_type,find_what,find_trans,               
  9119.                                   find_left_bound, find_right_bound)) {         
  9120.      if (hit_end) {                                                             
  9121.        sprintf(shortmsg,"No %s %s found",show_type,show_string);                
  9122.        sprintf(longmsg,                                                         
  9123.                "%s %s - not found within columns %d to %d",                     
  9124.                show_type,show_string,find_left_bound,find_right_bound);         
  9125.        ERR3("%24s;%s",shortmsg,longmsg);                                        
  9126.        return FALSE;                                                            
  9127.      }                                                                          
  9128.      else if (gp->text_find_what == FIND_PREV) {                                
  9129.        sprintf(shortmsg,"Top of data reached");                                 
  9130.        sprintf(longmsg,                                                         
  9131.             "%s %s not found.  Use RFIND to continue from bottom.",             
  9132.              show_type, show_string);                                           
  9133.        ERR3("%24s;%s",shortmsg,longmsg);                                        
  9134.      }                                                                          
  9135.      else {                                                                     
  9136.        sprintf(shortmsg,"Bottom of data reached");                              
  9137.        sprintf(longmsg,                                                         
  9138.                "%s %s not found.  Use RFIND to continue from top.",             
  9139.              show_type, show_string);                                           
  9140.        ERR3("%24s;%s",shortmsg,longmsg);                                        
  9141.      }                                                                          
  9142.      return FALSE;                                                              
  9143.    }                                                                            
  9144.    bp->found_row = bp->find_row;                                                
  9145.    bp->found_col = bp->find_col;                                                
  9146.  }                                                                              
  9147.                                                                                 
  9148.  if (bp->found_row + 1 < bp->top                                                
  9149.   || bp->found_row + 1 >= bp->top + bp->lvl - bp->cols) {                       
  9150.    bp->top = bp->found_row + 1 - 1;                                             
  9151.    if (bp->top < 0) bp->top = 0;                                                
  9152.  }                                                                              
  9153.                                                                                 
  9154.  if (bp->found_col < bp->coloff) {                                              
  9155.    bp->coloff = bp->found_col;                                                  
  9156.    *bp->cols_line = '\0';                                                       
  9157.  }                                                                              
  9158.  else if (bp->found_col+len > bp->coloff+80) {                                  
  9159.    bp->coloff = bp->found_col + len - 80;                                       
  9160.    if (bp->coloff < 0) bp->coloff = 0;                                          
  9161.    *bp->cols_line = '\0';                                                       
  9162.  }                                                                              
  9163.                                                                                 
  9164.  strcpy(bp->cursor, "GGBDYNA");                                                 
  9165.  bp->csrpos = 80 * (bp->found_row - bp->top+bp->cols + 1)                       
  9166.               + bp->found_col - bp->coloff + 1;                                 
  9167.                                                                                 
  9168.  bp->found_left = bp->csrpos;                                                   
  9169.  bp->found_right = bp->found_left + len;                                        
  9170.  bp->reinit_browse = TRUE;                                                      
  9171.                                                                                 
  9172.  if (find_what == FIND_ALL) {                                                   
  9173.    sprintf(shortmsg,"%d %s %s",bp->find_count,show_type,show_string);           
  9174.    sprintf(longmsg,                                                             
  9175.            "%s %s found %d times within columns %d to %d",                      
  9176.            show_type,show_string,bp->find_count,                                
  9177.            find_left_bound,find_right_bound);                                   
  9178.    WARN3("%24s;%s",shortmsg,longmsg);                                           
  9179.  }                                                                              
  9180.  else {                                                                         
  9181.    sprintf(shortmsg,"%s %s found",show_type,show_string);                       
  9182.    sprintf(longmsg,                                                             
  9183.            "Search for %s %s within columns %d to %d was successful",           
  9184.            show_type,show_string, find_left_bound,find_right_bound);            
  9185.    WARN3("%24s;%s",shortmsg,longmsg);                                           
  9186.  }                                                                              
  9187.                                                                                 
  9188.  bp->find_row = bp->found_row;                                                  
  9189.  bp->find_col = bp->found_col;                                                  
  9190.  return TRUE;                                                                   
  9191. }                                                                               
  9192.                                                                                 
  9193. /************ Fill browse dynamic area. *******************************/        
  9194.                                                                                 
  9195. static void                                                                     
  9196. fill_browse_dynamic_area(gp,bp)                                                 
  9197. Rstruc ggcb        *gp;                                                         
  9198. Rstruc browser     *bp;                                                         
  9199. {                                                                               
  9200.  struct textline  **tpp  = NULL;                                                
  9201.  register char     *cp   = NULL;                                                
  9202.  register char     *p;                                                          
  9203.  char              *q;                                                          
  9204.  char              *r;                                                          
  9205.  int                i;                                                          
  9206.  int                j;                                                          
  9207.  char               temp[12];                                                   
  9208.                                                                                 
  9209.  static char  top_of_data_line[81] = "\                                         
  9210. ********************************* Top of data \                                 
  9211. **********************************";                                            
  9212.                                                                                 
  9213.  static char  bottom_of_data_line[81] = "\                                      
  9214. ******************************** Bottom of data \                               
  9215. ********************************";                                              
  9216.                                                                                 
  9217.  bp->lastpos = bp->bda + bp->size;                                              
  9218.  bp->total = bp->thp->text_line_count;                                          
  9219.                                                                                 
  9220.  memset(bp->bda,' ',bp->size);                                                  
  9221.                                                                                 
  9222.  if      (bp->more_rows == -MAX_INT)                                            
  9223.          bp->top = 0;                                                           
  9224.  else if (bp->more_rows == MAX_INT)                                             
  9225.          bp->top = bp->total + 2 - bp->lvl + bp->cols;                          
  9226.  else    bp->top += bp->more_rows;                                              
  9227.                                                                                 
  9228.  if (bp->top < 0) bp->top = 0;                                                  
  9229.  if (bp->top > bp->total) bp->top = bp->total + 1;                              
  9230.                                                                                 
  9231.  i  = bp->top;                                                                  
  9232.  p  = bp->bda;                                                                  
  9233.                                                                                 
  9234.  if (bp->cols > 0) {                                                            
  9235.    if (!*bp->cols_line) {                                                       
  9236.      for (j=bp->coloff+1,r=bp->cols_line; j<=bp->coloff+80; j++,r++) {          
  9237.        if (j%10 == 0) {                                                         
  9238.          sprintf(temp,"%d",j%100);                                              
  9239.          *r = temp[0];                                                          
  9240.        }                                                                        
  9241.        else if (j%5 == 0) *r = '+';                                             
  9242.        else *r = '-';                                                           
  9243.      }                                                                          
  9244.    }                                                                            
  9245.    memcpy(p,bp->cols_line,80);                                                  
  9246.    p += 80;                                                                     
  9247.  }                                                                              
  9248.                                                                                 
  9249.  if (i == 0) {                                                                  
  9250.    memcpy(p,top_of_data_line,80);                                               
  9251.    p += 80;                                                                     
  9252.    i++;                                                                         
  9253.  }                                                                              
  9254.                                                                                 
  9255.  bp->firstpos = p;                                                              
  9256.                                                                                 
  9257.  for (tpp=&bp->tv[i-1];i<=bp->total && p<bp->lastpos;i++,tpp++,p+=80) {         
  9258.    if ((*tpp)->tab_expanded_text_length > bp->coloff) {                         
  9259.      cp = (*tpp)->tab_expanded_text + bp->coloff;                               
  9260.      for (j = 0, q = p; *cp && j < 80; j++, q++, cp++) {                        
  9261.        if (*cp > 0xf9 || *cp < 0x40) *q = gp->text_dispchar;                    
  9262.        else *q = *cp;                                                           
  9263.      }                                                                          
  9264.    }                                                                            
  9265.  }                                                                              
  9266.                                                                                 
  9267.  if (p < bp->lastpos) {                                                         
  9268.    memcpy(p,bottom_of_data_line,80);                                            
  9269.  }                                                                              
  9270.                                                                                 
  9271.  return;                                                                        
  9272. }                                                                               
  9273.                                                                                 
  9274. /************ Highlight browse text. **********************************/        
  9275.                                                                                 
  9276. static void                                                                     
  9277. highlight_browse_text(gp,bp)                                                    
  9278. Rstruc ggcb        *gp;                                                         
  9279. Rstruc browser     *bp;                                                         
  9280. {                                                                               
  9281.  char              *p;                                                          
  9282.                                                                                 
  9283.  bp->highlighted = FALSE;                                                       
  9284.                                                                                 
  9285.  if (bp->found_left) {                                                          
  9286.    if (EQUAL(bp->cursor,"GGBDYNA")) {                                           
  9287.      for (p = bp->bda + bp->found_left - 1; p >= bp->firstpos; p--) {           
  9288.        if (*p == ' ') {                                                         
  9289.          *p = DATAOUT_HIGH;                                                     
  9290.          bp->highlighted = TRUE;                                                
  9291.          break;                                                                 
  9292.        }                                                                        
  9293.      }                                                                          
  9294.      for (p = bp->bda + bp->found_right - 1; p <= bp->lastpos; p++) {           
  9295.       if (*p == ' ') {                                                          
  9296.         *p = DATAOUT_LOW;                                                       
  9297.          bp->highlighted = TRUE;                                                
  9298.          break;                                                                 
  9299.        }                                                                        
  9300.      }                                                                          
  9301.    }                                                                            
  9302.  }                                                                              
  9303.                                                                                 
  9304.  bp->found_left = 0;                                                            
  9305.  bp->found_right = 0;                                                           
  9306.                                                                                 
  9307.  return;                                                                        
  9308. }                                                                               
  9309.                                                                                 
  9310. /************ Display browse data. ************************************/        
  9311.                                                                                 
  9312. static void                                                                     
  9313. display_browse_data(gp,bp)                                                      
  9314. Rstruc ggcb        *gp;                                                         
  9315. Rstruc browser     *bp;                                                         
  9316. {                                                                               
  9317.  Rstruc cmddesc    *cdp;                                                        
  9318.  char              *cp;                                                         
  9319.  char              *operands;                                                   
  9320.  int                displayrc;                                                  
  9321.  int                zscrolln;                                                   
  9322.  int                leftcol;                                                    
  9323.  int                rightcol;                                                   
  9324.  int                command_index;                                              
  9325.  Bool               command_processed_ok;                                       
  9326.  Bool               is_max;                                                     
  9327.  Bool               is_scroll_word;                                             
  9328.  Bool               is_scroll_cursor;                                           
  9329.  SCROLL             scroll_amount;                                              
  9330.  char               command    [COMMANDSIZE+1];                                 
  9331.  char               zverb      [16];                                            
  9332.  char               zscrolla   [16];                                            
  9333.  char               longmsg    [73];                                            
  9334.  char               ggbtitle  [129];                                            
  9335.  char               ggbmsg     [81];                                            
  9336.  char               temp1      [81];                                            
  9337.  char               temp2      [81];                                            
  9338.                                                                                 
  9339. static struct cmddesc browse_commands[] = {                                     
  9340.                           {"L          ",process_locate_command   },            
  9341.                           {"LOC        ",process_locate_command   },            
  9342.                           {"LOCATE     ",process_locate_command   },            
  9343.                           {"F          ",process_find_command     },            
  9344.                           {"FIND       ",process_find_command     },            
  9345.                           {"RFIND      ",process_find_command     },            
  9346.                           {"YRFIND     ",process_find_command     },            
  9347.                           {"COL        ",process_cols_command     },            
  9348.                           {"COLS       ",process_cols_command     },            
  9349.                           {"RES        ",process_reset_command    },            
  9350.                           {"RESET      ",process_reset_command    },            
  9351.                           {"NOCOL      ",process_reset_command    },            
  9352.                           {"NOCOLS     ",process_reset_command    },            
  9353.                           {"DISP       ",process_display_command  },            
  9354.                           {"DISPL      ",process_display_command  },            
  9355.                           {"DISPLAY    ",process_display_command  },            
  9356.                           {"EXT        ",process_extract_command  },            
  9357.                           {"EXTR       ",process_extract_command  },            
  9358.                           {"EXTRACT    ",process_extract_command  },            
  9359.                           {"PRT        ",process_print_command    },            
  9360.                           {"PRNT       ",process_print_command    },            
  9361.                           {"PRINT      ",process_print_command    },            
  9362.                           {"INFO       ",process_info_command     },            
  9363.                           {"BOOK       ",process_bookmark_command },            
  9364.                           {"BOOKMARK   ",process_bookmark_command },            
  9365.                           {"QUIT       ",process_quit_command     },            
  9366.                           {"           ",NULL}                                  
  9367.                          };                                                     
  9368.                                                                                 
  9369.  bp->more_rows = 0;                                                             
  9370.  bp->override_scroll = FALSE;                                                   
  9371.  bp->exit_browse     = FALSE;                                                   
  9372.                                                                                 
  9373.  memset (ggbtitle, '-', 80);                                                    
  9374.  strcpy (ggbtitle, "Browse - ");                                                
  9375.  memcpy (ggbtitle + 9, bp->title, strlen(bp->title));                           
  9376.  *(ggbtitle + 9 + strlen(bp->title)) = ' ';                                     
  9377.                                                                                 
  9378.                                                                                 
  9379.  if (!gp->setmsg) {                                                             
  9380.    leftcol = bp->coloff + 1;                                                    
  9381.    rightcol = bp->coloff + 80;                                                  
  9382.    if (bp->top > bp->total) strcpy(temp1,"");                                   
  9383.    else sprintf(temp1, " Line %d of %d,", bp->top, bp->total);                  
  9384.    if (bp->maxlen <= 80)                                                        
  9385.         sprintf(temp2," Cols %d-%d",leftcol,rightcol);                          
  9386.    else sprintf(temp2," Cols %d-%d of %d",leftcol,rightcol,bp->maxlen);         
  9387.    strcpy(ggbmsg,temp1);                                                        
  9388.    strcat(ggbmsg,temp2);                                                        
  9389.    strcpy (ggbtitle + 79 - strlen(ggbmsg), ggbmsg);                             
  9390.  }                                                                              
  9391.                                                                                 
  9392.  (void)GGMivput(gp,"GGBTITLE ",ggbtitle    ,-1);                                
  9393.  (void)GGMivput(gp,"ZCMD "    ,bp->zcmd    ,-1);                                
  9394.  (void)GGMivput(gp,"GGBDYNA " ,bp->bda     ,bp->size);                          
  9395.  (void)GGMivput(gp,"GGBCUR "  ,bp->cursor  ,-1);                                
  9396.  sprintf(temp1,"%d",bp->csrpos);                                                
  9397.  (void)GGMivput(gp,"GGBPOS  " ,temp1       ,-1);                                
  9398.  (void)GGMivput(gp,"YRFIND "  ,"ALIAS FIND",-1);                                
  9399.                                                                                 
  9400.  displayrc = GGMdispl(gp,"GGMVIEW ");                                           
  9401.                                                                                 
  9402.  if (displayrc > 0) bp->exit_browse = TRUE;                                     
  9403.                                                                                 
  9404.  (void)GGMivput(gp,"YRFIND "  ,"",-1);                                          
  9405.  (void)GGMivget(gp,"GGBCUR  " ,bp->cursor  , 8);                                
  9406.  (void)GGMivget(gp,"ZCMD    " ,bp->zcmd     ,sizeof(bp->zcmd));                 
  9407.  bp->lvl    = GGMiget(gp,"GGBLVL  ");                                           
  9408.  bp->csrpos = GGMiget(gp,"GGBPOS  ");                                           
  9409.                                                                                 
  9410.  strcpy(bp->find_cursor, bp->cursor);                                           
  9411.  bp->find_csrpos = bp->csrpos;                                                  
  9412.  strcpy(bp->cursor,"");                                                         
  9413.  bp->csrpos = 1;                                                                
  9414.  if (bp->highlighted) bp->reinit_browse = TRUE;                                 
  9415.  else                 bp->reinit_browse = FALSE;                                
  9416.                                                                                 
  9417.  if (*bp->zcmd) {                                                               
  9418.                                                                                 
  9419.    memset(command,' ',COMMANDSIZE);                                             
  9420.    command_index = 0;                                                           
  9421.    for (cp = bp->zcmd; *cp && !isspace(*cp); cp++) {                            
  9422.      if (cp >= bp->zcmd+COMMANDSIZE) {                                          
  9423.        ERR1("Enter EXTract, PRT, BOOKmark, INFO, or a browse command.");        
  9424.        command_processed_ok = FALSE;                                            
  9425.      }                                                                          
  9426.      command[command_index++] = toupper(*cp);                                   
  9427.    }                                                                            
  9428.    while (*cp && isspace(*cp)) cp++;                                            
  9429.                                                                                 
  9430.    for (cdp=browse_commands; *cdp->command_name != ' '; cdp++) {                
  9431.      if (!memcmp(command,cdp->command_name,COMMANDSIZE-1)) {                    
  9432.        command_processed_ok = (cdp->command_processor)(gp,bp,cp);               
  9433.        cdp = NULL;                                                              
  9434.        break;                                                                   
  9435.      }                                                                          
  9436.    }                                                                            
  9437.    if (cdp) {                                                                   
  9438.      ERR1("Enter EXTract, PRT, BOOKmark, INFO, or a browse command.");          
  9439.      command_processed_ok = FALSE;                                              
  9440.    }                                                                            
  9441.                                                                                 
  9442.    if (command_processed_ok) strcpy(bp->zcmd,"");                               
  9443.                                                                                 
  9444.  }                                                                              
  9445.                                                                                 
  9446.  if (gp->quit || bp->exit_browse) return;                                       
  9447.                                                                                 
  9448.  /* Check scroll request (ZSCROLLA direction, ZSCROLLN number).                 
  9449.   * Skip this if something was done by a command which causes                   
  9450.   * its own pseudo-scrolling to happen (like LOCATE).                           
  9451.   */                                                                            
  9452.                                                                                 
  9453.  if (!bp->override_scroll) {                                                    
  9454.                                                                                 
  9455.    zscrolln = 0;                                                                
  9456.                                                                                 
  9457.    (void)GGMivget(gp,"ZVERB    " ,  zverb    ,sizeof(zverb));                   
  9458.    (void)GGMivget(gp,"ZSCROLLA " ,  zscrolla ,sizeof(zscrolla));                
  9459.    zscrolln = GGMiget(gp,"ZSCROLLN ");                                          
  9460.                                                                                 
  9461.    is_max = FALSE;                                                              
  9462.    is_scroll_word = FALSE;                                                      
  9463.    is_scroll_cursor = FALSE;                                                    
  9464.                                                                                 
  9465.    switch (zscrolla[0]) {                                                       
  9466.      case 'P':                                                                  
  9467.      case 'H':                                                                  
  9468.      case 'D':  is_scroll_word = TRUE;                                          
  9469.                 break;                                                          
  9470.      case 'C':  is_scroll_word = TRUE;                                          
  9471.                 is_scroll_cursor = TRUE;                                        
  9472.                 break;                                                          
  9473.      case 'M':  is_max = TRUE;                                                  
  9474.                 break;                                                          
  9475.    }                                                                            
  9476.                                                                                 
  9477.    if      (EQUAL(zverb,"DOWN"))  scroll_amount = DOWN;                         
  9478.    else if (EQUAL(zverb,"UP"))    scroll_amount = UP;                           
  9479.    else if (EQUAL(zverb,"LEFT"))  scroll_amount = LEFT;                         
  9480.    else if (EQUAL(zverb,"RIGHT")) scroll_amount = RIGHT;                        
  9481.    else                           scroll_amount = NO_SCROLL;                    
  9482.                                                                                 
  9483.                                                                                 
  9484.    switch (scroll_amount) {                                                     
  9485.      case NO_SCROLL:                                                            
  9486.           bp->more_rows = 0;                                                    
  9487.           break;                                                                
  9488.      case DOWN:                                                                 
  9489.           if (is_max) bp->more_rows = MAX_INT;                                  
  9490.           else if (is_scroll_word)                                              
  9491.                       bp->more_rows = zscrolln - bp->cols;                      
  9492.           else        bp->more_rows = zscrolln;                                 
  9493.           bp->reinit_browse = TRUE;                                             
  9494.           break;                                                                
  9495.      case UP:                                                                   
  9496.           if (is_max) bp->more_rows = -MAX_INT;                                 
  9497.           else if (is_scroll_cursor)                                            
  9498.                       bp->more_rows = -zscrolln;                                
  9499.           else if (is_scroll_word)                                              
  9500.                       bp->more_rows = -zscrolln - bp->cols;                     
  9501.           else        bp->more_rows = -zscrolln;                                
  9502.           bp->reinit_browse = TRUE;                                             
  9503.           break;                                                                
  9504.      case LEFT:                                                                 
  9505.           if (is_max) bp->coloff = 0;                                           
  9506.           else        bp->coloff -= zscrolln;                                   
  9507.           if (bp->coloff < 0) bp->coloff = 0;                                   
  9508.           *bp->cols_line = '\0';                                                
  9509.           bp->more_rows = 0;                                                    
  9510.           bp->reinit_browse = TRUE;                                             
  9511.           break;                                                                
  9512.      case RIGHT:                                                                
  9513.           if (is_max) bp->coloff = bp->maxcoloff;                               
  9514.           else        bp->coloff += zscrolln;                                   
  9515.           if (bp->coloff > bp->maxcoloff) bp->coloff = bp->maxcoloff;           
  9516.           *bp->cols_line = '\0';                                                
  9517.           bp->more_rows = 0;                                                    
  9518.           bp->reinit_browse = TRUE;                                             
  9519.           break;                                                                
  9520.    }                                                                            
  9521.  }                                                                              
  9522.                                                                                 
  9523.  return;                                                                        
  9524. }                                                                               
  9525.                                                                                 
  9526. /****** View text in full screen mode (BROWSE replacement) ***********/         
  9527.                                                                                 
  9528. void                                                                            
  9529. GGMview(gp,ip,texthdrp,title)                                                   
  9530. Rstruc ggcb         *gp;                                                        
  9531. Rstruc gopherinfo   *ip;                                                        
  9532. struct texthdr      *texthdrp;                                                  
  9533. char                *title;                                                     
  9534. {                                                                               
  9535.  struct textline    *tp;                                                        
  9536.  struct textline   **tv;                                                        
  9537.  struct textline   **textvector;                                                
  9538.  struct browser     *bp;                                                        
  9539.  struct browser      browserstruct;                                             
  9540.                                                                                 
  9541.  GETMAIN(textvector, struct textline *,                                         
  9542.          texthdrp->text_line_count, "text vector");                             
  9543.  if (!textvector) {                                                             
  9544.    ERR1("Not enough memory to display text.");                                  
  9545.    return;                                                                      
  9546.  }                                                                              
  9547.                                                                                 
  9548.  bp = &browserstruct;                                                           
  9549.  memset(bp,0,sizeof(struct browser));                                           
  9550.  bp->ip = ip;                                                                   
  9551.  bp->thp = texthdrp;                                                            
  9552.  bp->tv = textvector;                                                           
  9553.  strcpy(bp->title,title);                                                       
  9554.  bp->more_rows = -MAX_INT;   /* set initial request to scroll up max */         
  9555.  bp->top       = 0;                                                             
  9556.  bp->find_row  = -1;                                                            
  9557.  bp->find_col  = -1;                                                            
  9558.  bp->csrpos    = 1;                                                             
  9559.  strcpy(bp->cursor,"");                                                         
  9560.  bp->reinit_browse = TRUE;                                                      
  9561.                                                                                 
  9562.  /* Collect text line pointers, skipping suppressed lines. */                   
  9563.                                                                                 
  9564.  bp->maxlen = 0;                                                                
  9565.  for (tp=texthdrp->first_text_line, tv=textvector; tp; tp=tp->next) {           
  9566.    if (tp->text_length >= 0) {                                                  
  9567.      *(tv++) = tp;                                                              
  9568.      if (bp->maxlen < tp->tab_expanded_text_length)                             
  9569.          bp->maxlen = tp->tab_expanded_text_length;                             
  9570.    }                                                                            
  9571.  }                                                                              
  9572.  bp->maxcoloff = bp->maxlen - 80;                                               
  9573.  if (bp->maxcoloff < 0) bp->maxcoloff = 0;                                      
  9574.                                                                                 
  9575.  GETMAIN(bp->work, char *, bp->maxlen+1, "browse work string");                 
  9576.  if (!bp->work) return;                                                         
  9577.                                                                                 
  9578.  (void)GGMispf(gp,                                                              
  9579.          "PQUERY PANEL(GGMVIEW) AREANAME(GGBDYNA) DEPTH(GGBDEPTH)");            
  9580.  if (gp->ispfrc != 0) return;                                                   
  9581.  bp->depth = GGMiget(gp,"GGBDEPTH ");                                           
  9582.  bp->size = bp->depth * 80;                                                     
  9583.  GETMAIN(bp->bda, char *, bp->size+1, "browse dynamic area");                   
  9584.  if (!bp->bda) return;                                                          
  9585.                                                                                 
  9586.  if (!gp->text_dispchar) gp->text_dispchar = '.';                               
  9587.                                                                                 
  9588.  for (;;) {                                                                     
  9589.    if (bp->reinit_browse) {                                                     
  9590.      fill_browse_dynamic_area(gp,bp);                                           
  9591.      highlight_browse_text(gp,bp);                                              
  9592.    }                                                                            
  9593.    display_browse_data(gp,bp);                                                  
  9594.    if (gp->quit || bp->exit_browse) break;                                      
  9595.  }                                                                              
  9596.                                                                                 
  9597.  FREEMAIN(bp->work,"browse work string");                                       
  9598.  FREEMAIN(bp->bda,"browse dynamic area");                                       
  9599.  FREEMAIN(textvector, "text vector");                                           
  9600.                                                                                 
  9601.  return;                                                                        
  9602. }                                                                               
  9603.                                                                                 
  9604. ./   ADD NAME=GGMVTX                                                            
  9605.                                                                                 
  9606.  /********************************************************************/         
  9607.  /*                                                                  */         
  9608.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9609.  /*                                                                  */         
  9610.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  9611.  /*                                                                  */         
  9612.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9613.  /* including the implied warranties of merchantability and fitness, */         
  9614.  /* are expressly denied.                                            */         
  9615.  /*                                                                  */         
  9616.  /* Provided this copyright notice is included, this software may    */         
  9617.  /* be freely distributed and not offered for sale.                  */         
  9618.  /*                                                                  */         
  9619.  /* Changes or modifications may be made and used only by the maker  */         
  9620.  /* of same, and not further distributed.  Such modifications should */         
  9621.  /* be mailed to the author for consideration for addition to the    */         
  9622.  /* software and incorporation in subsequent releases.               */         
  9623.  /*                                                                  */         
  9624.  /********************************************************************/         
  9625.                                                                                 
  9626. #pragma  csect(code,  "GG@VTX  ")                                               
  9627. #pragma  csect(static,"GG$VTX  ")                                               
  9628. #include "gg.h"                                                                 
  9629.                                                                                 
  9630. /****** View the lines of text retrieved from the server. ************/         
  9631.                                                                                 
  9632. Bool                                                                            
  9633. GGMvtx(gp,ip,as_file)                                                           
  9634. Rstruc ggcb         *gp;                                                        
  9635. Rstruc gopherinfo   *ip;                                                        
  9636. Fool                 as_file;  /* ignored */                                    
  9637. {                                                                               
  9638.  struct texthdr     *texthdrp;                                                  
  9639.  char                title     [81];                                            
  9640.                                                                                 
  9641.  texthdrp = (ip ? &ip->thdr : &gp->thdr);                                       
  9642.                                                                                 
  9643.  if (!ip) sprintf(title, "GopherServer:%s ",gp->ggserver);                      
  9644.  else     strncpy(title, ip->desc, sizeof(title));                              
  9645.                                                                                 
  9646.  GGMview(gp,ip,texthdrp,title);                                                 
  9647.                                                                                 
  9648.  return;                                                                        
  9649. }                                                                               
  9650.                                                                                 
  9651. ./   ADD NAME=GGMWAIS                                                           
  9652.                                                                                 
  9653.  /********************************************************************/         
  9654.  /*                                                                  */         
  9655.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9656.  /*                                                                  */         
  9657.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  9658.  /*                                                                  */         
  9659.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9660.  /* including the implied warranties of merchantability and fitness, */         
  9661.  /* are expressly denied.                                            */         
  9662.  /*                                                                  */         
  9663.  /* Provided this copyright notice is included, this software may    */         
  9664.  /* be freely distributed and not offered for sale.                  */         
  9665.  /*                                                                  */         
  9666.  /* Changes or modifications may be made and used only by the maker  */         
  9667.  /* of same, and not further distributed.  Such modifications should */         
  9668.  /* be mailed to the author for consideration for addition to the    */         
  9669.  /* software and incorporation in subsequent releases.               */         
  9670.  /*                                                                  */         
  9671.  /********************************************************************/         
  9672.                                                                                 
  9673. #pragma  csect(code,  "GG@WAIS ")                                               
  9674. #pragma  csect(static,"GG$WAIS ")                                               
  9675. #include "gg.h"                                                                 
  9676.                                                                                 
  9677. /****** Gopher WAIS interface. *************************************/           
  9678.                                                                                 
  9679. Bool                                                                            
  9680. GGMwais(gp,ip,as_file)                                                          
  9681. Rstruc ggcb        *gp;                                                         
  9682. Rstruc gopherinfo  *ip;                                                         
  9683. Fool                as_file;                                                    
  9684. {                                                                               
  9685.  Rstruc connection *sp;                                                         
  9686.  char              *lp;                                                         
  9687.  char               ggwaisq[256];                                               
  9688.                                                                                 
  9689.  sp = &gp->gopher_connection;                                                   
  9690.                                                                                 
  9691.  strcpy(gp->ggserver,ip->host);     /* Specify server to connect to */          
  9692.                                                                                 
  9693.  strcpy(ggwaisq,"");                                                            
  9694.                                                                                 
  9695.  GGMispf(gp,"VGET (GGWAISQ) PROFILE");                                          
  9696.                                                                                 
  9697.  if (GGMdispl(gp,"GGMPWAIS") > 0) return FALSE;                                 
  9698.                                                                                 
  9699.  GGMivget(gp,"GGWAISQ ",ggwaisq, sizeof(ggwaisq));                              
  9700.                                                                                 
  9701.  if (!*ip->path) strcpy(gp->gopher_command, ggwaisq);                           
  9702.  else            sprintf(gp->gopher_command,"%s\t%s",ip->path,ggwaisq);         
  9703.                                                                                 
  9704.  gp->ginfo = ip;                                                                
  9705.                                                                                 
  9706.  if (!GGMconn(gp,sp)) return FALSE; /* Connect to gopher server */              
  9707.                                                                                 
  9708.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  9709.                                                                                 
  9710.  GGMclrtx(gp,ip);                  /* Clear text */                             
  9711.                                                                                 
  9712.  sp->receiving_text = TRUE;                                                     
  9713.                                                                                 
  9714.  do {                                                                           
  9715.    if (GGMgsrvl(gp,sp,&lp,TRUE)) {         /* Get server line */                
  9716.      if (lp) {                                                                  
  9717.        (void)GGMouttx(gp,lp,ip);          /* Output text line */                
  9718.      }                                                                          
  9719.    }                                                                            
  9720.  } while (lp);                            /* until no more lines */             
  9721.                                                                                 
  9722.  if (sp->time_to_go_home) {                                                     
  9723.    WARN2("No data available from server %s.\n",gp->ggserver);                   
  9724.    return FALSE;                                                                
  9725.  }                                                                              
  9726.                                                                                 
  9727.  if (sp->connected_to_server) {                                                 
  9728.    (void)GGMdisc(gp,sp);           /* Disconnect from gopher server */          
  9729.  }                                                                              
  9730.                                                                                 
  9731.  GGMdir(gp,ip,as_file); /* display entries returned from WAIS server */         
  9732.                                                                                 
  9733.  return TRUE;                                                                   
  9734.                                                                                 
  9735. }                                                                               
  9736.                                                                                 
  9737. ./   ADD NAME=GGMWHOIS                                                          
  9738.                                                                                 
  9739.  /********************************************************************/         
  9740.  /*                                                                  */         
  9741.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9742.  /*                                                                  */         
  9743.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  9744.  /*                                                                  */         
  9745.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9746.  /* including the implied warranties of merchantability and fitness, */         
  9747.  /* are expressly denied.                                            */         
  9748.  /*                                                                  */         
  9749.  /* Provided this copyright notice is included, this software may    */         
  9750.  /* be freely distributed and not offered for sale.                  */         
  9751.  /*                                                                  */         
  9752.  /* Changes or modifications may be made and used only by the maker  */         
  9753.  /* of same, and not further distributed.  Such modifications should */         
  9754.  /* be mailed to the author for consideration for addition to the    */         
  9755.  /* software and incorporation in subsequent releases.               */         
  9756.  /*                                                                  */         
  9757.  /********************************************************************/         
  9758.                                                                                 
  9759. #pragma  csect(code,  "GG@WHOIS")                                               
  9760. #pragma  csect(static,"GG$WHOIS")                                               
  9761. #include "gg.h"                                                                 
  9762.                                                                                 
  9763. /****** Gopher WHOIS/FINGER interface. *****************************/           
  9764.                                                                                 
  9765. Bool                                                                            
  9766. GGMwhois(gp,ip,as_file)                                                         
  9767. Rstruc ggcb        *gp;                                                         
  9768. Rstruc gopherinfo  *ip;                                                         
  9769. Fool                as_file;        /* ignored */                               
  9770. {                                                                               
  9771.  Rstruc connection *sp;                                                         
  9772.  char              *lp;                                                         
  9773.  Bool               got_some;                                                   
  9774.  char               ggwhoisq[256];                                              
  9775.                                                                                 
  9776.  sp = &gp->gopher_connection;                                                   
  9777.                                                                                 
  9778.  strcpy(gp->ggserver,ip->host);     /* Specify server to connect to */          
  9779.                                                                                 
  9780.  strcpy(ggwhoisq,"");                                                           
  9781.                                                                                 
  9782.  GGMispf(gp,"VGET (GGWHOISQ) PROFILE");                                         
  9783.                                                                                 
  9784.  if (GGMdispl(gp,"GGMPWHOI") > 0) return FALSE;                                 
  9785.                                                                                 
  9786.  GGMivget(gp,"GGWHOISQ ",ggwhoisq, sizeof(ggwhoisq));                           
  9787.                                                                                 
  9788.  if (!*ip->path) strcpy(gp->gopher_command, ggwhoisq);                          
  9789.  else            sprintf(gp->gopher_command,"%s\t%s",ip->path,ggwhoisq);        
  9790.                                                                                 
  9791.  gp->ginfo = ip;                                                                
  9792.                                                                                 
  9793.  if (!GGMconn(gp,sp)) return FALSE;   /* Connect to gopher server */            
  9794.                                                                                 
  9795.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  9796.                                                                                 
  9797.  GGMclrtx(gp,ip);                  /* Clear text */                             
  9798.                                                                                 
  9799.  sp->receiving_text = TRUE;                                                     
  9800.  got_some = FALSE;                                                              
  9801.  do {                                                                           
  9802.    if (GGMgsrvl(gp,sp,&lp,TRUE)) {         /* Get server line */                
  9803.      if (lp) {                                                                  
  9804.        got_some = TRUE;                                                         
  9805.        (void)GGMouttx(gp,lp,ip);          /* Output text line */                
  9806.      }                                                                          
  9807.    }                                                                            
  9808.  } while (lp);                            /* until no more lines */             
  9809.                                                                                 
  9810.  if (!got_some) {                                                               
  9811.    WARN2("No data available from server %s.\n",gp->ggserver);                   
  9812.    return FALSE;                                                                
  9813.  }                                                                              
  9814.                                                                                 
  9815.  if (sp->connected_to_server) {                                                 
  9816.    (void)GGMdisc(gp,sp);         /* Disconnect from gopher server */            
  9817.  }                                                                              
  9818.                                                                                 
  9819.  GGMvtx(gp,ip,as_file);  /* display text from WHOIS/FINGER server */            
  9820.                                                                                 
  9821.  return TRUE;                                                                   
  9822.                                                                                 
  9823. }                                                                               
  9824.                                                                                 
  9825. ./   ADD NAME=GGMXTX,SSI=01030034                                               
  9826.                                                                                 
  9827.  /********************************************************************/         
  9828.  /*                                                                  */         
  9829.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9830.  /*                                                                  */         
  9831.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  9832.  /*                                                                  */         
  9833.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9834.  /* including the implied warranties of merchantability and fitness, */         
  9835.  /* are expressly denied.                                            */         
  9836.  /*                                                                  */         
  9837.  /* Provided this copyright notice is included, this software may    */         
  9838.  /* be freely distributed and not offered for sale.                  */         
  9839.  /*                                                                  */         
  9840.  /* Changes or modifications may be made and used only by the maker  */         
  9841.  /* of same, and not further distributed.  Such modifications should */         
  9842.  /* be mailed to the author for consideration for addition to the    */         
  9843.  /* software and incorporation in subsequent releases.               */         
  9844.  /*                                                                  */         
  9845.  /********************************************************************/         
  9846.                                                                                 
  9847. #pragma  csect(code,  "GG@XTX  ")                                               
  9848. #pragma  csect(static,"GG$XTX  ")                                               
  9849. #include "gg.h"                                                                 
  9850.                                                                                 
  9851. #define XFPUTC(A)     gp->extract_write_error = (fputc((A),xfp) == EOF)         
  9852.                                                                                 
  9853. #define XFWRITE(A,B)  fwrite((A),(B),1,xfp), \                                  
  9854.                       gp->extract_write_error = (ferror(xfp) != 0)              
  9855.                                                                                 
  9856. /****** Extract the lines of server text into a data set. ************/         
  9857.                                                                                 
  9858. Bool                                                                            
  9859. GGMxtx(gp,ip,ex)                                                                
  9860. Rstruc ggcb         *gp;                                                        
  9861. Rstruc gopherinfo   *ip;                                                        
  9862. EXTREQ               ex;                                                        
  9863. {                                                                               
  9864.  FILE               *xfp;                                                       
  9865.  struct texthdr     *thp;                                                       
  9866.  struct textline    *tp;                                                        
  9867.  struct extraction  *ep;                                                        
  9868.  char               *cp;                                                        
  9869.  int                 l;                                                         
  9870.  int                 linelen;                                                   
  9871.  Bool                final;                                                     
  9872.  char                formatted_number [11];                                     
  9873.  struct extraction   the_extraction;                                            
  9874.                                                                                 
  9875.  thp = (ip && ex != BOOKMARK_IT ? &ip->thdr : &gp->thdr);                       
  9876.                                                                                 
  9877.  /* Set article data for message. */                                            
  9878.                                                                                 
  9879.  if (ip) {                                                                      
  9880.    sprintf(formatted_number,"%d",ip->type);                                     
  9881.    (void)GGMivput(gp,"GGTNUM ",  formatted_number, -1);                         
  9882.    (void)GGMivput(gp,"GGTSUBJ ", ip->desc,         -1);                         
  9883.  }                                                                              
  9884.                                                                                 
  9885.  if (gp->extract_file) {                                                        
  9886.    (void)GGMispf(gp,"CONTROL DISPLAY LOCK");                                    
  9887.      switch (ex) {                                                              
  9888.        case PRINT_IT: GGMispf(gp,"DISPLAY PANEL(GGMLPRN2)"); break;             
  9889.        default:       GGMispf(gp,"DISPLAY PANEL(GGMLEXN2)"); break;             
  9890.      }                                                                          
  9891.    xfp = gp->extract_file;                                                      
  9892.    ep = gp->extractionp;                                                        
  9893.  }                                                                              
  9894.  else {                                                                         
  9895.                                                                                 
  9896.    ep = &the_extraction;                                                        
  9897.    memset(ep,0,sizeof(struct extraction));                                      
  9898.    switch (ex) {                                                                
  9899.      case EXTRACT_IT:  ep->mode = SEQ;                                          
  9900.                        strcpy(ep->panelname,"GGMPEXDS");                        
  9901.                        break;                                                   
  9902.      case PRINT_IT:    ep->mode = JES;                                          
  9903.                        strcpy(ep->panelname,"GGMPPRDS");                        
  9904.                        break;                                                   
  9905.      case BOOKMARK_IT: ep->mode = SEQ;                                          
  9906.                        strcpy(ep->panelname,"GGMPBMDS");                        
  9907.                        break;                                                   
  9908.    }                                                                            
  9909.    ep->ex = ex;                                                                 
  9910.                                                                                 
  9911.    if (ip) GGMivput(gp,"GGTSUBJ ",ip->desc,-1);                                 
  9912.    else    GGMivput(gp,"GGTSUBJ ",""      ,-1);                                 
  9913.                                                                                 
  9914.    if (!((xfp=GGMgetds(gp,ep)))) return FALSE;                                  
  9915.                                                                                 
  9916.    gp->extract_tab_expanding          = ep->tab_expanding;                      
  9917.    gp->extract_appending              = ep->appending;                          
  9918.    gp->extract_blank_before_separator = ep->blanking;                           
  9919.    gp->extract_separator_line         = ep->separator;                          
  9920.  }                                                                              
  9921.                                                                                 
  9922.  gp->extract_write_error = FALSE;                                               
  9923.  gp->extract_close_error = FALSE;                                               
  9924.                                                                                 
  9925.  /* If a bookmark, then write gopher menu header only if this is                
  9926.   * a new data set (not appending).                                             
  9927.   */                                                                            
  9928.                                                                                 
  9929.  if (ep->ex == BOOKMARK_IT && !ep->appending) {                                 
  9930.    XFWRITE(MENUIDENT,strlen(MENUIDENT));                                        
  9931.    XFPUTC('\n');                                                                
  9932.  }                                                                              
  9933.                                                                                 
  9934.  /* If append mode, and a separator line was specified, use it. */              
  9935.                                                                                 
  9936.  if (gp->extract_appending) {                                                   
  9937.    XFPUTC('\n');                                                                
  9938.    if (gp->extract_separator_line && *gp->extract_separator_line) {             
  9939.      XFWRITE(gp->extract_separator_line,                                        
  9940.              strlen(gp->extract_separator_line));                               
  9941.      XFPUTC('\n');                                                              
  9942.      if (gp->extract_blank_before_separator) XFPUTC('\n');                      
  9943.    }                                                                            
  9944.  }                                                                              
  9945.                                                                                 
  9946.  linelen = (ex == PRINT_IT ? 120 : 251);                                        
  9947.                                                                                 
  9948.  for (tp = thp->first_text_line;                                                
  9949.       tp && !gp->extract_write_error;                                           
  9950.       tp = tp->next) {                                                          
  9951.    if (tp->text_length == 0) {                                                  
  9952.      XFPUTC('\n');                                                              
  9953.    }                                                                            
  9954.    else if (tp->text_length > 0) {                                              
  9955.      if (gp->extract_tab_expanding) {                                           
  9956.        cp = tp->tab_expanded_text;                                              
  9957.        l  = tp->tab_expanded_text_length;                                       
  9958.      }                                                                          
  9959.      else {                                                                     
  9960.        cp = tp->text;                                                           
  9961.        l  = tp->text_length;                                                    
  9962.      }                                                                          
  9963.      for (; l>0 && !gp->extract_write_error; cp+=linelen, l-=linelen) {         
  9964.        XFWRITE(cp,(l > linelen ? linelen : l));                                 
  9965.        XFPUTC('\n');                                                            
  9966.      }                                                                          
  9967.    }                                                                            
  9968.  }                                                                              
  9969.                                                                                 
  9970.  if (!gp->extract_write_error && ferror(xfp))                                   
  9971.     gp->extract_write_error = TRUE;                                             
  9972.                                                                                 
  9973.  if (!gp->extract_appending || !gp->extract_file) {                             
  9974.    switch (ex) {                                                                
  9975.      case EXTRACT_IT:   final = FALSE; break;                                   
  9976.      case PRINT_IT:     final = TRUE;  break;                                   
  9977.      default:           final = FALSE; break;                                   
  9978.    }                                                                            
  9979.    (ep->closer)(gp,ep,xfp,final);   /* Close the file */                        
  9980.    if (gp->extract_close_error) return FALSE;                                   
  9981.  }                                                                              
  9982.                                                                                 
  9983.  if (!gp->extract_file) {                                                       
  9984.    if (gp->extract_write_error) {                                               
  9985.      ERR2("An error occurred writing to %s.", ep->dsname);                      
  9986.      gp->extract_write_error = TRUE;                                            
  9987.    }                                                                            
  9988.    else switch (ex) {                                                           
  9989.      case EXTRACT_IT:                                                           
  9990.           WARN2("Current text extracted into %s.", ep->dsname);                 
  9991.           break;                                                                
  9992.      case PRINT_IT:                                                             
  9993.           WARN2("Current text printed to %s.", ep->dsname);                     
  9994.           break;                                                                
  9995.      case BOOKMARK_IT:                                                          
  9996.           WARN2("Item stored as bookmark in %s.", ep->dsname);                  
  9997.           break;                                                                
  9998.    }                                                                            
  9999.  }                                                                              
  10000.  if (gp->extract_write_error) return FALSE;                                     
  10001.  else return TRUE;                                                              
  10002. }                                                                               
  10003.                                                                                 
  10004. ./   ADD NAME=GGSERVER,SSI=010E0033                                             
  10005. /*                                                                              
  10006.  ***********************************************************************        
  10007.  *                                                                     *        
  10008.  * GOPHER server, based on the simple TCP/IP server from Shawn Hart at *        
  10009.  * the University of Delaware.                                         *        
  10010.  *                                                                     *        
  10011.  ***********************************************************************        
  10012.  *                                                                              
  10013.  *  This server follows the GOPHER protocols defined by UMN.                    
  10014.  *  For more information, see the ANONYMOUS FTP site at                         
  10015.  *  BOOMBOX.MICRO.UMN.EDU.                                                      
  10016.  *                                                                              
  10017.  ***********************************************************************        
  10018.  *                                                                              
  10019.  * November 1992 - parameters may be passed to the server:                      
  10020.  *                                                                              
  10021.  * -d              run in debug mode                                            
  10022.  *                                                                              
  10023.  ***********************************************************************        
  10024.  *                                                                              
  10025.  * December 1992 - support for SNS/TCPAccess compilation                        
  10026.  *                                                                              
  10027.  ***********************************************************************        
  10028.  */                                                                             
  10029.                                                                                 
  10030. #pragma  csect(code,  "GG@ERVER")                                               
  10031. #pragma  csect(static,"GG$ERVER")                                               
  10032. #include "gg.h"                 /* All system file includes needed. */          
  10033.                                                                                 
  10034. /********************************************************************/          
  10035.                                                                                 
  10036. static int                                                                      
  10037. tcpsetup(int          port,                                                     
  10038.          int          qlen,                                                     
  10039.          int          mtftasks,                                                 
  10040.          FILE        *debugfp)                                                  
  10041. {                                                                               
  10042.  int                  tinitrc;             /* loop counter*/                    
  10043.  int                  sockfd;              /* loop counter*/                    
  10044.  int                  x;                   /* loop counter*/                    
  10045.  struct linger        l;                   /* linger for setsockopt */          
  10046.  struct sockaddr_in   server;          /*server address information */          
  10047.                                                                                 
  10048.  /*    initialize the MTF  environment.                   */                    
  10049.                                                                                 
  10050.  if (debugfp) {                                                                 
  10051.    fprintf(debugfp,"tinit...\n");                                               
  10052.    fflush(debugfp);                                                             
  10053.  }                                                                              
  10054.                                                                                 
  10055.  tinitrc = tinit("GGSTASK", mtftasks);                                          
  10056.                                                                                 
  10057.  if (tinitrc != MTF_OK) {                                                       
  10058.    GGMmtfer(tinitrc, "TINIT");                                                  
  10059.    return -1;                                                                   
  10060.  }                                                                              
  10061.                                                                                 
  10062.  /*       open a TCP socket...                            */                    
  10063.                                                                                 
  10064.  if (debugfp) {                                                                 
  10065.    fprintf(debugfp,"socket...\n");                                              
  10066.    fflush(debugfp);                                                             
  10067.  }                                                                              
  10068.                                                                                 
  10069.  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {                          
  10070.    REPORT_TCP_ERROR("SOCKET - ");                                               
  10071.    return -1;                                                                   
  10072.  };                                                                             
  10073.                                                                                 
  10074.  /*  set the linger option on so we wait for data to be sent... */              
  10075.                                                                                 
  10076.  l.l_onoff  =  1;                                                               
  10077.  l.l_linger =100;           /* wait 100 seconds before giving up */             
  10078.                                                                                 
  10079.  if (debugfp) {                                                                 
  10080.    fprintf(debugfp,"setsockopt (%d, SO_LINGER)...\n",sockfd);                   
  10081.    fflush(debugfp);                                                             
  10082.  }                                                                              
  10083.                                                                                 
  10084.  if (setsockopt(sockfd,SOL_SOCKET,SO_LINGER,(char *)&l,sizeof(l))               
  10085.      < 0) {                                                                     
  10086.    REPORT_TCP_ERROR("SETSOCKOPT - ");                                           
  10087.    return -1;                                                                   
  10088.  }                                                                              
  10089.                                                                                 
  10090.  /*    now bind our local address so that the client can send to us */          
  10091.                                                                                 
  10092.  memset((char *)&server, 0, sizeof(server));                                    
  10093.  server.sin_family           =   AF_INET;                                       
  10094.  server.sin_addr.s_addr      =   INADDR_ANY;                                    
  10095.  server.sin_port             =   htons(port);                                   
  10096.                                                                                 
  10097.  if (debugfp) {                                                                 
  10098.    fprintf(debugfp,"bind (%d)...\n",sockfd);                                    
  10099.    fflush(debugfp);                                                             
  10100.  }                                                                              
  10101.                                                                                 
  10102.  if (Bind(sockfd, &server, sizeof(server)) < 0) {                               
  10103.    REPORT_TCP_ERROR("BIND - ");                                                 
  10104.    return -1;                                                                   
  10105.  }                                                                              
  10106.                                                                                 
  10107.  /*    now set length of the connection queue... */                             
  10108.                                                                                 
  10109.  if (debugfp) {                                                                 
  10110.    fprintf(debugfp,"listen (sockfd=%d, qlen=%d)...\n",sockfd,qlen);             
  10111.    fflush(debugfp);                                                             
  10112.  }                                                                              
  10113.                                                                                 
  10114.  if (listen(sockfd,qlen) != 0) {                                                
  10115.    REPORT_TCP_ERROR("LISTEN -");                                                
  10116.    return -1;                                                                   
  10117.  }                                                                              
  10118.                                                                                 
  10119.  return sockfd;                                                                 
  10120.                                                                                 
  10121. }                                                                               
  10122.                                                                                 
  10123.                                                                                 
  10124. /********************************************************************/          
  10125. /*                                                                              
  10126. *   This routine waits for an exception on the socket.  When one                
  10127. *   occurs (by a subtask's "TAKESOCKET"!) we'll close our (the main             
  10128. *   task's) connection to it.                                                   
  10129. *                                                                               
  10130. *               INPUT   s   pointer to socket descripter.                       
  10131. *               OUTPUT  rc  -1 = connection timed out...                        
  10132. *                            0 = an excption occured!                           
  10133. */                                                                              
  10134. /********************************************************************/          
  10135.                                                                                 
  10136. #ifdef SNSTCPIP                                                                 
  10137.                                                                                 
  10138. static int                                                                      
  10139. closesock(int              newsockfd,                                           
  10140.           int              timeout,                                             
  10141.           FILE            *debugfp)                                             
  10142. {                                                                               
  10143.  if (debugfp) {                                                                 
  10144.    fprintf(debugfp,"close (%d)...\n",newsockfd);                                
  10145.    fflush(debugfp);                                                             
  10146.  }                                                                              
  10147.                                                                                 
  10148.  if (close(newsockfd) < 0) REPORT_TCP_ERROR("CLOSE -");                         
  10149.  return 0;                                                                      
  10150. }                                                                               
  10151.                                                                                 
  10152. #else                                                                           
  10153.                                                                                 
  10154. static int                                                                      
  10155. closesock(int              newsockfd,                                           
  10156.           int              timeout,                                             
  10157.           FILE            *debugfp)                                             
  10158. {                                                                               
  10159.  int                       temps;                                               
  10160.  struct sockaddr           clientaddress;                                       
  10161.  int                       addrlen;                                             
  10162.  int                       maxfdpl;                                             
  10163.  struct fd_set             readmask;                                            
  10164.  struct fd_set             writmask;                                            
  10165.  struct fd_set             exepmask;                                            
  10166.  int                       rc;                                                  
  10167.  struct timeval            time;                                                
  10168.                                                                                 
  10169.  temps = newsockfd;                                                             
  10170.  time.tv_sec = timeout;                                                         
  10171.  time.tv_usec = 0;                                                              
  10172.  maxfdpl = temps + 1;                                                           
  10173.                                                                                 
  10174.  FD_ZERO(&readmask);                                                            
  10175.  FD_ZERO(&writmask);                                                            
  10176.  FD_ZERO(&exepmask);                                                            
  10177.  FD_SET(temps, &exepmask);                                                      
  10178.                                                                                 
  10179.  if (debugfp) {                                                                 
  10180.    fprintf(debugfp,"select (maxfdpl=%d)...\n",maxfdpl);                         
  10181.    fflush(debugfp);                                                             
  10182.  }                                                                              
  10183.                                                                                 
  10184.  rc = select(maxfdpl, &readmask, &writmask, &exepmask, &time);                  
  10185.                                                                                 
  10186.  if (rc < 0) {                                                                  
  10187.    REPORT_TCP_ERROR("SELECT - ");                                               
  10188.    return rc;                                                                   
  10189.  }                                                                              
  10190.  else {                                                                         
  10191.    if (rc == 0) fprintf(stdout,"The GIVESOCKET timed out!\n");                  
  10192.                                                                                 
  10193.    if (debugfp) {                                                               
  10194.      fprintf(debugfp,"close (%d)...\n",newsockfd);                              
  10195.      fflush(debugfp);                                                           
  10196.    }                                                                            
  10197.                                                                                 
  10198.    if (close(newsockfd) < 0) REPORT_TCP_ERROR("CLOSE -");                       
  10199.    return rc;                                                                   
  10200.  }                                                                              
  10201. }                                                                               
  10202.                                                                                 
  10203. #endif                                                                          
  10204.                                                                                 
  10205. /********************************************************************/          
  10206. /*                                                                              
  10207. *       This routine starts a subtask, passing control of a socket              
  10208. *       to it.  It then waits for the subtask to take the socket and            
  10209. *       then closes the socket.                                                 
  10210. *                                                                               
  10211. *       INPUT: newsockfd - socket descriptor to give to subtask.                
  10212. */                                                                              
  10213. /********************************************************************/          
  10214.                                                                                 
  10215. static Bool                                                                     
  10216. spawn(                                                                          
  10217.       int           newsockfd,                                                  
  10218.       int           timeout,                                                    
  10219.  struct recvstruct *recvp,                                                      
  10220.       FILE         *debugfp)                                                    
  10221. {                                                                               
  10222.  int                tschedrc;                                                   
  10223. #ifdef SNSTCPIP                                                                 
  10224.  unsigned long      token;                                                      
  10225. #else                                                                           
  10226.  struct clientid    clid;                                                       
  10227.  char               mysname[8];                                                 
  10228. #endif                                                                          
  10229.                                                                                 
  10230.  if (debugfp) {                                                                 
  10231.    fprintf(debugfp,"getclientid...\n");                                         
  10232.    fflush(debugfp);                                                             
  10233.  }                                                                              
  10234.                                                                                 
  10235. #ifdef SNSTCPIP                                                                 
  10236.                                                                                 
  10237.  token = closepass(newsockfd);                                                  
  10238.  if (debugfp) {                                                                 
  10239.    fprintf(debugfp,"token = %X\n",token);                                       
  10240.    fflush(debugfp);                                                             
  10241.  }                                                                              
  10242.                                                                                 
  10243. #else                                                                           
  10244.                                                                                 
  10245.  memset(&clid,0,sizeof(clid));                                                  
  10246.  if(getclientid(AF_INET,&clid) < 0) {                                           
  10247.    REPORT_TCP_ERROR("GETCLIENTID");                                             
  10248.    return FALSE;                                                                
  10249.  }                                                                              
  10250.                                                                                 
  10251.  if (debugfp) {                                                                 
  10252.    fprintf(debugfp,"client name = %8.8s, subtaskname = %8.8s\n",                
  10253.                    clid.name, clid.subtaskname);                                
  10254.    fflush(debugfp);                                                             
  10255.  }                                                                              
  10256.                                                                                 
  10257.  clid.domain = AF_INET;                                                         
  10258.  memcpy(mysname,clid.subtaskname,8);                                            
  10259.  memcpy(clid.subtaskname,"        ",8);                                         
  10260.                                                                                 
  10261.  if (debugfp) {                                                                 
  10262.    fprintf(debugfp,"givesocket (%d)...\n",newsockfd);                           
  10263.    fflush(debugfp);                                                             
  10264.  }                                                                              
  10265.                                                                                 
  10266.  if(givesocket(newsockfd,&clid) != 0) {                                         
  10267.    REPORT_TCP_ERROR("GIVESOCKET");                                              
  10268.    return FALSE;                                                                
  10269.  }                                                                              
  10270.  memcpy(clid.subtaskname,mysname,8);                                            
  10271.                                                                                 
  10272.  if (debugfp) {                                                                 
  10273.    fprintf(debugfp,"client name = %8.8s, subtaskname = %8.8s\n",                
  10274.                    clid.name, clid.subtaskname);                                
  10275.    fflush(debugfp);                                                             
  10276.  }                                                                              
  10277.                                                                                 
  10278. #endif                                                                          
  10279.                                                                                 
  10280.  if (debugfp) {                                                                 
  10281.    fprintf(debugfp,"tsched...\n");                                              
  10282.    fflush(debugfp);                                                             
  10283.  }                                                                              
  10284.                                                                                 
  10285.  tschedrc = tsched(MTF_ANY,"GGSRECV",                                           
  10286. #ifdef SNSTCPIP                                                                 
  10287.                            token,                                               
  10288. #else                                                                           
  10289.                            newsockfd,                                           
  10290.                            clid,                                                
  10291. #endif                                                                          
  10292.                            recvp,                                               
  10293.                            (debugfp ? 1 : 0));                                  
  10294.                                                                                 
  10295.  if (debugfp) {                                                                 
  10296.    fprintf(debugfp,"tsched completed...rc=%d\n",tschedrc);                      
  10297.    fflush(debugfp);                                                             
  10298.  }                                                                              
  10299.                                                                                 
  10300.  if (tschedrc != 0) {                                                           
  10301.    GGMmtfer(tschedrc,"TSCHED");                                                 
  10302.    return FALSE;                                                                
  10303.  }                                                                              
  10304.                                                                                 
  10305.  if (closesock(newsockfd,timeout,debugfp) < 0) {                                
  10306.    REPORT_TCP_ERROR("close socket");                                            
  10307.    return FALSE;                                                                
  10308.  }                                                                              
  10309.                                                                                 
  10310.  return TRUE;                                                                   
  10311.                                                                                 
  10312. }                                                                               
  10313.                                                                                 
  10314. /******************************************************************/            
  10315.                                                                                 
  10316. static Bool                                                                     
  10317. numparm(                                                                        
  10318.         char *pvar,                                                             
  10319.         char *pval,                                                             
  10320.         int  *ivalp                                                             
  10321.        )                                                                        
  10322. {                                                                               
  10323.  if (*(pval + strspn(pval,"0123456789"))) {                                     
  10324.    fprintf(stdout,"Non-numeric value given for %s: %s\n",                       
  10325.                   pvar, pval);                                                  
  10326.    return FALSE;                                                                
  10327.  }                                                                              
  10328.  else {                                                                         
  10329.   *ivalp = atoi(pval);                                                          
  10330.   return TRUE;                                                                  
  10331.  }                                                                              
  10332. }                                                                               
  10333.                                                                                 
  10334. /******************************************************************/            
  10335.                                                                                 
  10336. int                                                                             
  10337. main(int            argc,                                                       
  10338.          char     **argv)                                                       
  10339. {                                                                               
  10340.  int                trc;               /* return code */                        
  10341.  int                x;                 /* loop counter*/                        
  10342.  int                sockfd;            /* connection socket...*/                
  10343.  int                newsockfd;         /* new connection socket...*/            
  10344.  int                clientlen;         /* new connection socket...*/            
  10345.  int                i;                                                          
  10346.  int                n;                                                          
  10347.  int                ival;                                                       
  10348.  char               cval;                                                       
  10349.  char              *p;                                                          
  10350.  char              *cp;                                                         
  10351.  FILE              *debugfp;                                                    
  10352.  FILE              *pfp;                                                        
  10353.  struct sockaddr_in client;            /* client address information */         
  10354. #ifndef SNSTCPIP                                                                
  10355.  struct clientid    clid;              /* client info for givesocket */         
  10356. #endif                                                                          
  10357.  struct recvstruct  recvtemplate;                                               
  10358.  int                mtftasks;                                                   
  10359.  int                port;                                                       
  10360.  int                qlength;                                                    
  10361.  int                timeout;                                                    
  10362.  char               telnet   [257];                                             
  10363.  char               domain   [257];                                             
  10364.  char                  pline    [RBUFSIZE];                                        
  10365.  char                  pvar     [RBUFSIZE];                                        
  10366.  char               pval     [RBUFSIZE];                                        
  10367.  char               buffer   [255];      /* buffer for input/output*/           
  10368.                                                                                 
  10369. /******************************************************************/            
  10370. /* Set parameter defaults.                                        */            
  10371. /******************************************************************/            
  10372.                                                                                 
  10373.  mtftasks     = MTF_TASKS;                                                      
  10374.  port         = SERV_TCP_PORT;                                                  
  10375.  qlength      = TCP_QUEUE_LENGTH;                                               
  10376.  timeout      = CONNECT_TIME_OUT;                                               
  10377.  COPY(telnet,   TELNET_COMMAND_NAME);                                           
  10378.  COPY(domain,   MY_DOMAIN_SUFFIX);                                              
  10379.                                                                                 
  10380. /******************************************************************/            
  10381. /* Process server parameters.                                     */            
  10382. /******************************************************************/            
  10383.                                                                                 
  10384.  debugfp = NULL;                                                                
  10385.                                                                                 
  10386.  for (i = 1; i < argc; i++) {                                                   
  10387.    p = argv[i];                                                                 
  10388.    if (*p == '-') {                                                             
  10389.      while (*++p) {                                                             
  10390.        switch (toupper(*p)) {                                                   
  10391.          case 'D':  debugfp = fopen(DEBUG_FILE,"w");                            
  10392.                     break;                                                      
  10393.          default:   break;                                                      
  10394.        }                                                                        
  10395.      }                                                                          
  10396.    }                                                                            
  10397.  }                                                                              
  10398.                                                                                 
  10399. /******************************************************************/            
  10400. /*         Read startup parameters from parameter file.           */            
  10401. /******************************************************************/            
  10402.                                                                                 
  10403. /*                                                                              
  10404.  * If dd:GGPARMS is present, then read parameters therefrom.                    
  10405.  * If not, then use defaults.  In any case, defaults will be                    
  10406.  * assigned where a corresponding parameter file line isn't found,              
  10407.  *                                                                              
  10408.  * Syntax of parameter file lines:                                              
  10409.  *                                                                              
  10410.  * VARIABLE value   comments                                                    
  10411.  *                                                                              
  10412.  * e.g.                                                                         
  10413.  *                                                                              
  10414.  * MTFTASKS    8    the number of tasks                                         
  10415.  *                                                                              
  10416.  * Comments are indicated by "!" in col 1.                                      
  10417.  *                                                                              
  10418.  */                                                                             
  10419.                                                                                 
  10420.  pfp = fopen(PARAMETER_FILE,"r");                                               
  10421.  if (!pfp) {                                                                    
  10422.    perror(PARAMETER_FILE);                                                      
  10423.    fprintf(stdout,                                                              
  10424.            "No parameter file.  Using all installed defaults.\n");              
  10425.    fflush(stderr);                                                              
  10426.  }                                                                              
  10427.  else {                                                                         
  10428.    for (;;) {                                                                   
  10429.      fgets(pline, sizeof(pline), pfp);                                          
  10430.      if (ferror(pfp)) {                                                         
  10431.        fprintf(stderr,"Error reading parameters from %s\n",                     
  10432.                       PARAMETER_FILE);                                          
  10433.        fflush(stderr);                                                          
  10434.        break;                                                                   
  10435.      }                                                                          
  10436.      if (feof(pfp)) break;                                                      
  10437.      cp = pline;                     /* Start parameter scan       */           
  10438.      if (*cp == '!') continue;       /* Skip comment               */           
  10439.      *pvar = '\0';                   /* Clear parameter variable   */           
  10440.      sscanf(cp,"%s %n",pvar,&n);     /* Get parameter, bump scan   */           
  10441.      if (!*pvar) continue;           /* If nothing on line, skip   */           
  10442.      uppercase_in_place(pvar);       /* Fold variable name         */           
  10443.      cp += n;                        /* Bump to next word in file  */           
  10444.      *pval = '\0';                   /* Clear parameter value      */           
  10445.      sscanf(cp,"%s %n",pval,&n);     /* Get next word, bump scan   */           
  10446.      if (!*pval) {                                                              
  10447.        fprintf(stdout,"Parameter error: value missing for %s\n",                
  10448.                       pvar);                                                    
  10449.        continue;                                                                
  10450.      }                                                                          
  10451.      fprintf(stderr,"Setting %s to '%s' (%d)\n",pvar,pval,ival);                
  10452.      if      (EQUAL(pvar,"MTFTASKS" )) {                                        
  10453.                                         if (numparm(pvar,pval,&ival))           
  10454.                                            mtftasks = ival;                     
  10455.                                        }                                        
  10456.      else if (EQUAL(pvar,"PORT"     )) {                                        
  10457.                                         if (numparm(pvar,pval,&ival))           
  10458.                                            port     = ival;                     
  10459.                                        }                                        
  10460.      else if (EQUAL(pvar,"QLENGTH"  )) {                                        
  10461.                                         if (numparm(pvar,pval,&ival))           
  10462.                                            qlength  = ival;                     
  10463.                                        }                                        
  10464.      else if (EQUAL(pvar,"TIMEOUT"  )) {                                        
  10465.                                         if (numparm(pvar,pval,&ival))           
  10466.                                            timeout  = ival;                     
  10467.                                        }                                        
  10468.      else if (EQUAL(pvar,"TELNET"   )) {                                        
  10469.                                         uppercase_in_place(pval);               
  10470.                                         COPY(telnet,pval);                      
  10471.                                        }                                        
  10472.      else if (EQUAL(pvar,"DOMAIN"   )) {                                        
  10473.                                         uppercase_in_place(pval);               
  10474.                                         COPY(domain,pval);                      
  10475.                                        }                                        
  10476.      else {                                                                     
  10477.        fprintf(stdout,"Unknown parameter, %s.  Skipping.\n",pvar);              
  10478.      }                                                                          
  10479.    }                                                                            
  10480.    (void)fclose(pfp);                                                           
  10481.  }                                                                              
  10482.                                                                                 
  10483. /******************************************************************/            
  10484. /*         display parameter values in effect                     */            
  10485. /******************************************************************/            
  10486.                                                                                 
  10487.  /* Set defaults to pass to the subtask. */                                     
  10488.                                                                                 
  10489.  memset(&recvtemplate,0,sizeof(struct recvstruct));                             
  10490.                                                                                 
  10491.  recvtemplate.myport       = port;                                              
  10492.  recvtemplate.mytelnet     = telnet;                                            
  10493.  recvtemplate.mydomain     = domain;                                            
  10494.                                                                                 
  10495.  fprintf(stdout,"Parameter values in effect:\n\n");                             
  10496.  fprintf(stdout,"MTFTASKS = %d\n", mtftasks);                                   
  10497.  fprintf(stdout,"QLENGTH  = %d\n", qlength);                                    
  10498.  fprintf(stdout,"TIMEOUT  = %d\n", timeout);                                    
  10499.  fprintf(stdout,"PORT     = %d\n", recvtemplate.myport);                        
  10500.  fprintf(stdout,"TELNET   = %s\n", recvtemplate.mytelnet);                      
  10501.  fprintf(stdout,"DOMAIN   = %s\n", recvtemplate.mydomain);                      
  10502.  fprintf(stdout,"\n");                                                          
  10503.                                                                                 
  10504.  fflush(stdout);                                                                
  10505.                                                                                 
  10506. /******************************************************************/            
  10507. /*         set up the connection to the socket...                 */            
  10508. /******************************************************************/            
  10509.                                                                                 
  10510.  sockfd = tcpsetup(port,qlength,mtftasks,debugfp);                              
  10511.  if (sockfd < 0) {                                                              
  10512.    fprintf(stdout,"Could not set up the TCP/IP environment!\n");                
  10513.    exit(16);                                                                    
  10514.  }                                                                              
  10515.                                                                                 
  10516. /******************************************************************/            
  10517. /*         Now loop, waiting for a connection request.            */            
  10518. /******************************************************************/            
  10519.                                                                                 
  10520.  clientlen = sizeof(client);                                                    
  10521.  x = 0;                                                                         
  10522.  for (;;) {                                                                     
  10523.                                                                                 
  10524.    if (debugfp) {                                                               
  10525.      fprintf(debugfp,"accept (%d)...\n",sockfd);                                
  10526.      fflush(debugfp);                                                           
  10527.    }                                                                            
  10528.                                                                                 
  10529.    if ((newsockfd=Accept(sockfd,&client,&clientlen)) == -1) {                   
  10530.      REPORT_TCP_ERROR("ACCEPT - ");                                             
  10531.      exit(8);                                                                   
  10532.    }                                                                            
  10533.    if (debugfp) {                                                               
  10534.      fprintf(debugfp,"newsockfd=%d...\n",newsockfd);                            
  10535.      fflush(debugfp);                                                           
  10536.    }                                                                            
  10537.                                                                                 
  10538.    x++;                                                                         
  10539.    if (!spawn(newsockfd,timeout,&recvtemplate,debugfp)) {                       
  10540.      fprintf(stdout,"spawn failed for socket %d\n",newsockfd);                  
  10541.      exit(8);                                                                   
  10542.    }                                                                            
  10543.    else {                                                                       
  10544.      if (debugfp) {                                                             
  10545.        fprintf(debugfp,"spawn OK for socket %d\n",newsockfd);                   
  10546.        fflush(debugfp);                                                         
  10547.      }                                                                          
  10548.    }                                                                            
  10549.  }                                                                              
  10550.                                                                                 
  10551. /******************************************************************/            
  10552. /*         Wait for all pending tasks to complete (should never   */            
  10553. /*         run, since I haven't added PURGE support yet...)       */            
  10554. /*         then shut down subtasks.                               */            
  10555. /******************************************************************/            
  10556.                                                                                 
  10557.  if (debugfp) {                                                                 
  10558.    fprintf(debugfp,"tsyncro...\n");                                             
  10559.    fflush(debugfp);                                                             
  10560.  }                                                                              
  10561.                                                                                 
  10562.  trc = tsyncro(MTF_ALL);                                                        
  10563.  if (trc != 0) {                                                                
  10564.    GGMmtfer(trc,"TSYNCRO");                                                     
  10565.  }                                                                              
  10566.                                                                                 
  10567.  if (debugfp) {                                                                 
  10568.    fprintf(debugfp,"tterm...\n");                                               
  10569.    fflush(debugfp);                                                             
  10570.  }                                                                              
  10571.                                                                                 
  10572.  trc = tterm();                                                                 
  10573.  if (trc != 4) {                                                                
  10574.    GGMmtfer(trc,"TTERM");                                                       
  10575.    exit(8);                                                                     
  10576.  }                                                                              
  10577.                                                                                 
  10578.  if (debugfp) fclose(debugfp);                                                  
  10579.                                                                                 
  10580.  exit(0);                                                                       
  10581.                                                                                 
  10582. }                                                                               
  10583. ./   ADD NAME=GGSTASK,SSI=01010047                                              
  10584.                                                                                 
  10585.  /********************************************************************/         
  10586.  /*                                                                  */         
  10587.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  10588.  /*                                                                  */         
  10589.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10590.  /* including the implied warranties of merchantability and fitness, */         
  10591.  /* are expressly denied.                                            */         
  10592.  /*                                                                  */         
  10593.  /* Provided this copyright notice is included, this software may    */         
  10594.  /* be freely distributed and not offered for sale.                  */         
  10595.  /*                                                                  */         
  10596.  /* Changes or modifications may be made and used only by the maker  */         
  10597.  /* of same, and not further distributed.  Such modifications should */         
  10598.  /* be mailed to the author for consideration for addition to the    */         
  10599.  /* software and incorporation in subsequent releases.               */         
  10600.  /*                                                                  */         
  10601.  /********************************************************************/         
  10602.                                                                                 
  10603. #pragma  csect(code,  "GGSTASK ")                                               
  10604. #pragma  csect(static,"GG$TASK ")                                               
  10605.                                                                                 
  10606. #include "gg.h"                                                                 
  10607.                                                                                 
  10608. /*=================================================================*/           
  10609.                                                                                 
  10610. /*******************************************************************/           
  10611. /*                                                                 */           
  10612. /*    this is a debugging routine;  it looks at the status of a    */           
  10613. /*    socket.                                                      */           
  10614. /*******************************************************************/           
  10615.                                                                                 
  10616. static void                                                                     
  10617. lookatsocket(int sockfd)                                                        
  10618. {                                                                               
  10619.  int             rc;                       /* return code */                    
  10620.  int             length;                   /* length variable */                
  10621.  int             option;                                                        
  10622.  int             x;                                                             
  10623.  struct linger   l;                        /* linger structure */               
  10624.  char            buffer[RBUFSIZE];                                              
  10625.                                                                                 
  10626.  length = sizeof(l);                                                            
  10627.  if (Getsockopt(sockfd,SOL_SOCKET, SO_LINGER,&l,&length)==0) {                  
  10628.    printf("l_onoff=%d\n",l.l_onoff);                                            
  10629.    printf("l_linger=%d\n",l.l_linger);                                          
  10630.  }                                                                              
  10631.  else REPORT_TCP_ERROR("GETSOCKOPT");                                           
  10632.                                                                                 
  10633.  length = sizeof(option);                                                       
  10634.  if (Getsockopt(sockfd,SOL_SOCKET, SO_ERROR,&option,&length)==0) {              
  10635.    printf("so_error=%d\n",option);                                              
  10636.  }                                                                              
  10637.  else REPORT_TCP_ERROR("GETSOCKOPT");                                           
  10638.                                                                                 
  10639.  if (fcntl(sockfd,F_SETFL,FNDELAY)!=0) REPORT_TCP_ERROR("FCNTL");               
  10640.                                                                                 
  10641.  length = recv(sockfd,buffer,sizeof(buffer)-1,0);                               
  10642.  if (length == -1) {                                                            
  10643.    if (errno != EWOULDBLOCK) REPORT_TCP_ERROR("recv");                          
  10644.  }                                                                              
  10645.  else {                                                                         
  10646.    buffer[sizeof(buffer)-1] = 0;                                                
  10647.    printf("buffer =%s\n",buffer);                                               
  10648.    for (x=0;x<length;x++) printf("%x ",buffer[x]);                              
  10649.    printf("\n");                                                                
  10650.  }                                                                              
  10651.                                                                                 
  10652. }                                                                               
  10653.                                                                                 
  10654. /*******************************************************************/           
  10655.                                                                                 
  10656. /**************************************************************/                
  10657. /*    this routine processes the data once a connection       */                
  10658. /*    has been accepted.  It just takes the data sent by the  */                
  10659. /*    client and prints it to sysprint, then sends it back    */                
  10660. /*    to the client.                                          */                
  10661. /*                                                            */                
  10662. /*             INPUT:   newsockfd  - socket descriptor        */                
  10663. /*                      clid       - takesocket structure...  */                
  10664. /**************************************************************/                
  10665.                                                                                 
  10666. void                                                                            
  10667. GGSrecv(                                                                        
  10668. #ifdef SNSTCPIP                                                                 
  10669.  unsigned long      token,                                                      
  10670. #else                                                                           
  10671.  int                newsockfd,                                                  
  10672.  struct clientid    clid,                                                       
  10673. #endif                                                                          
  10674.  struct recvstruct *recvtp,                                                     
  10675.  int                is_debug                                                    
  10676.        )                                                                        
  10677. {                                                                               
  10678.  struct recvstruct *R;                                                          
  10679.  struct hostent    *hostentp;                                                   
  10680.  char              *bufptr;   /* pointer into buffer strings         */         
  10681.  char              *hp;                                                         
  10682.  char             **halias;                                                     
  10683.  int                retcode;  /* return code                         */         
  10684.  int                len;      /* length of the buffer we're sent     */         
  10685.  int                x;        /* loop counter                        */         
  10686.  int                addrlen;  /* length of client address socket     */         
  10687.  int                hostlen;                                                    
  10688.  int                domslen;                                                    
  10689.  struct sockaddr_in clientaddress; /* address of client              */         
  10690.  struct recvstruct  r;                                                          
  10691.  time_t             timeval;                                                    
  10692.  struct tm         *tmp;                                                        
  10693.  char               outbuf[RBUFSIZE];  /* hold an output string */              
  10694.  char               timestamp[20];                                              
  10695.                                                                                 
  10696.  /* Initialize recv struct with values passed from main task. */                
  10697.                                                                                 
  10698.  memcpy(&r, recvtp, sizeof(struct recvstruct));                                 
  10699.  R = &r;                                                                        
  10700.                                                                                 
  10701. #ifdef SNSTCPIP                                                                 
  10702.                                                                                 
  10703.  if (is_debug) {                                                                
  10704.    fprintf(stdout,"openold (token=%X)...\n",token);                             
  10705.    fflush(stdout);                                                              
  10706.  }                                                                              
  10707.  s0skcfg.exitfunc = NULL; /* Set exit address to NULL */                        
  10708.  R->sockfd = openold(token);                                                    
  10709.  if (is_debug) {                                                                
  10710.    fprintf(stdout,"sockfd from openold is %d\n", R->sockfd);                    
  10711.    fflush(stdout);                                                              
  10712.  }                                                                              
  10713.  if(R->sockfd < 0) {                                                            
  10714.    REPORT_TCP_ERROR("OPENOLD");                                                 
  10715.    fflush(stderr);                                                              
  10716.    return;                                                                      
  10717.  }                                                                              
  10718.                                                                                 
  10719. #else                                                                           
  10720.                                                                                 
  10721.  if (is_debug) {                                                                
  10722.    fprintf(stdout,"takesocket (newsockfd=%d)...\n",newsockfd);                  
  10723.    fprintf(stdout,"name is %8.8s, subtaskname is %8.8s\n",                      
  10724.                   clid.name,clid.subtaskname);                                  
  10725.    fflush(stdout);                                                              
  10726.  }                                                                              
  10727.                                                                                 
  10728.  R->sockfd = takesocket(&clid,newsockfd);                                       
  10729.  if (is_debug) {                                                                
  10730.    fprintf(stdout,"sockfd from takesocket is %d\n", R->sockfd);                 
  10731.    fflush(stdout);                                                              
  10732.  }                                                                              
  10733.  if(R->sockfd < 0) {                                                            
  10734.    REPORT_TCP_ERROR("TAKESOCKET");                                              
  10735.    return;                                                                      
  10736.  }                                                                              
  10737.                                                                                 
  10738. #endif                                                                          
  10739.                                                                                 
  10740.  time(&timeval);                                                                
  10741.  tmp = localtime(&timeval);                                                     
  10742.  sprintf(timestamp,"%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d",                       
  10743.          tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_year,                           
  10744.          tmp->tm_hour, tmp->tm_min, tmp->tm_sec);                               
  10745.                                                                                 
  10746.  if (is_debug) {                                                                
  10747.    fprintf(stdout,"getpeername...\n");                                          
  10748.    fflush(stdout);                                                              
  10749.  }                                                                              
  10750.                                                                                 
  10751.  addrlen = sizeof(clientaddress);                                               
  10752.  if(Getpeername(R->sockfd,&clientaddress,&addrlen)!=0) {                        
  10753.    REPORT_TCP_ERROR("GETPEERNAME");                                             
  10754.    printf("could not determine client address for socket %d\n",                 
  10755.           R->sockfd);                                                           
  10756.  }                                                                              
  10757.                                                                                 
  10758.  /* Try to get the name of the client host. */                                  
  10759.                                                                                 
  10760.  strcpy(R->hostname,"{UNKNOWN HOST NAME}");                                     
  10761.                                                                                 
  10762.  if (is_debug) {                                                                
  10763.    fprintf(stdout,"gethostbyaddr...\n");                                        
  10764.    fflush(stdout);                                                              
  10765.  }                                                                              
  10766.                                                                                 
  10767.  hostentp = Gethostbyaddr(&clientaddress.sin_addr,                              
  10768.                           sizeof(clientaddress.sin_addr),                       
  10769.                           AF_INET);                                             
  10770.                                                                                 
  10771.  if (hostentp && hostentp->h_name) {                                            
  10772.    memcpy(&R->clienthostent, hostentp, sizeof(struct hostent));                 
  10773.    strcpy(R->hostname,hostentp->h_name);                                        
  10774.    uppercase_in_place(R->hostname);                                             
  10775.  }                                                                              
  10776.                                                                                 
  10777.  strcpy(R->hosttest,R->hostname);                                               
  10778.                                                                                 
  10779.  hostlen = strlen(R->hosttest);                                                 
  10780.  domslen = strlen(R->mydomain);                                                 
  10781.  if (hostlen > domslen) {                                                       
  10782.    hp = R->hosttest + hostlen - domslen;                                        
  10783.    if (!memcmp(hp, R->mydomain, domslen)) {                                     
  10784.      *hp = '\0';                                                                
  10785.    }                                                                            
  10786.  }                                                                              
  10787.                                                                                 
  10788.  printf("%s Connection from %s (%s, aka %s).  Socket %d\n",                     
  10789.         timestamp,                                                              
  10790.         inet_ntoa(clientaddress.sin_addr), R->hostname, R->hosttest,            
  10791.         R->sockfd);                                                             
  10792.                                                                                 
  10793.  /* This still doesn't do anything.                                             
  10794.   *                                                                             
  10795.   * if (hostentp && hostentp->h_name) {                                         
  10796.   *   memcpy(&R->clienthostent, hostentp, sizeof(struct hostent));              
  10797.   *   for (halias = R->clienthostent.h_aliases; *halias; halias++) {            
  10798.   *     printf("  Host alias:'%s'\n",*halias);                                  
  10799.   *   }                                                                         
  10800.   * }                                                                           
  10801.   */                                                                            
  10802.                                                                                 
  10803.  R->buffer[0] = '\0';                                                           
  10804.  bufptr = R->buffer;                                                            
  10805.                                                                                 
  10806. /***********************/                                                       
  10807. /*  NOTE:  sometimes, if timing is right, RECV can return a 0 length */         
  10808. /* record when a connection is closed by the client!!  below is a   */          
  10809. /* hack to check for a 0 length record, and then terminate this     */          
  10810. /* connection if we got one.                                        */          
  10811. /***********************/                                                       
  10812.                                                                                 
  10813. #define RECV_SIZE       (sizeof(R->buffer)-1)                                   
  10814.                                                                                 
  10815.  for (;;) {                                                                     
  10816.                                                                                 
  10817.    if (is_debug) {                                                              
  10818.      fprintf(stdout,"recv (sock=%d,size=%d)...\n",R->sockfd,RECV_SIZE);         
  10819.      fflush(stdout);                                                            
  10820.    }                                                                            
  10821.                                                                                 
  10822.    if ((len=recv(R->sockfd,outbuf,RECV_SIZE,0)) <= 0) {                         
  10823.      REPORT_TCP_ERROR("RECV - ");                                               
  10824.      printf("%s tcp error! len=%d\n",R->hostname, len);                         
  10825.      break;                                                                     
  10826.    }                                                                            
  10827.                                                                                 
  10828.    *(outbuf+(len))=0;    /*make sure it's null terminated...*/                  
  10829.    /* printf("len=%d;",len); */                                                 
  10830.    ASCII_TO_EBCDIC(outbuf,len);                                                 
  10831.    if (strlen(R->buffer) + strlen(outbuf) >= sizeof(R->buffer)) {               
  10832.      printf("\nError: More than %d bytes seen without CRLF\n",                  
  10833.             sizeof(R->buffer)-1);                                               
  10834.      len = 0;                                                                   
  10835.      break;                                                                     
  10836.    }                                                                            
  10837.    strcat(R->buffer,outbuf);                                                    
  10838.    bufptr=R->buffer+(strlen(R->buffer)-2);                                      
  10839.    if (*bufptr == CARRIAGE_RETURN && *(bufptr+1) == LINE_FEED) break;           
  10840.  }                                                                              
  10841.                                                                                 
  10842.  /* Note: no \n required, data line already has CRLF in it */                   
  10843.  fprintf(stderr,"%s %s Client data:%s",                                         
  10844.                 timestamp, R->hostname, R->buffer);                             
  10845.                                                                                 
  10846.  if (len < 0) return;                                                           
  10847.  else if (len == 0) {                                                           
  10848.    (void)GGMouts(R,                                                             
  10849.   "1Sorry, the GOPHER server couldn't hear you.  Try again.\t0\t0\t0");         
  10850.  }                                                                              
  10851.  else (void)GGMproc(R);                                                         
  10852.                                                                                 
  10853.  (void)GGMouts(R,NULL);          /* send terminating dot */                     
  10854.                                                                                 
  10855.  fflush(stdout);                                                                
  10856.  fflush(stderr);                                                                
  10857.                                                                                 
  10858. #ifdef DEBUGMTF                                                                 
  10859.  lookatsocket(R->sockfd);                                                       
  10860. #endif                                                                          
  10861.                                                                                 
  10862.  if (is_debug) {                                                                
  10863.    fprintf(stdout,"close (%d)...\n",R->sockfd);                                 
  10864.    fflush(stdout);                                                              
  10865.  }                                                                              
  10866.                                                                                 
  10867.  if(close(R->sockfd)<0) REPORT_TCP_ERROR("CLOSE - ");                           
  10868.                                                                                 
  10869. }                                                                               
  10870. ./ ENDUP                                                                        
  10871. ?!                                                                              
  10872. //CLIST    EXEC GGLOAD,TRK1='4',TO='CLIST'                                      
  10873. //SYSIN    DD DATA,DLM='?!'                                                     
  10874. ./   ADD NAME=GOPHER,SSI=01100012                                               
  10875. /* REXX. GOPHER client.  */                                                     
  10876.                                                                                 
  10877. /* *** Customize the following lines for your installation.                     
  10878.  * If ggmpanel is set to "", it will not be LIBDEF'd.                           
  10879.  */                                                                             
  10880.                                                                                 
  10881. ggmprefix      = "GOPHER"                                                       
  10882. ggmpanelsuffix = "PANELS"                                                       
  10883. ggmloadsuffix  = "LOAD"                                                         
  10884. ggmlmod        = "GGCLIENT"                                                     
  10885. ggmpanel       = ggmprefix"."ggmpanelsuffix                                     
  10886. ggmload        = ggmprefix"."ggmloadsuffix                                      
  10887. ggmappl        = ""                     /* ISPF applid (e.g. ISR)  */           
  10888. ggmdefaulthost = "gopher.micro.umn.edu" /* to initialize GOPHERRC  */           
  10889. gophermeister  = ""              /* TSOid of Gopher's Big Brother  */           
  10890. xprocavailable = 0               /* set to 1 if XPROC is available */           
  10891.                                                                                 
  10892. trace off                                                                       
  10893. signal on novalue                                                               
  10894. stacked   = 0                                                                   
  10895. libdeffed = 0                                                                   
  10896. parse arg args                                                                  
  10897. "ISPQRY"                                                                        
  10898. if rc > 0 then do                                                               
  10899.  parse source . . execname . execds .                                           
  10900.  if execds = "?" then                                                           
  10901.   icmd = "%"execname args                                                       
  10902.  else                                                                           
  10903.   icmd = "EX '"execds"("execname")'" quote(args)                                
  10904.  call startispf ggmappl, icmd                                                   
  10905.  exit                                                                           
  10906. end                                                                             
  10907.                                                                                 
  10908. if xprocavailable then do                                                       
  10909.                                                                                 
  10910.  save_prompt = prompt("ON")                                                     
  10911.  "XPROC 0 TEST DEBUG FORCE LOCAL                                                
  10912.           BOOKMARK() SERVER() PORT() PATH() DESCRIPTION()"                      
  10913.  if rc <> 0 then exit rc                                                        
  10914.  call prompt save_prompt                                                        
  10915.                                                                                 
  10916. end                                                                             
  10917.                                                                                 
  10918. else do /* XPROC not available */                                               
  10919.                                                                                 
  10920.  bookmark = ""                                                                  
  10921.  server = ""                                                                    
  10922.  port = 70                                                                      
  10923.  path  =                                                                        
  10924.  description =                                                                  
  10925.  local =                                                                        
  10926.  force =                                                                        
  10927.  test  =                                                                        
  10928.  debug =                                                                        
  10929.  uargs = translate(args)                                                        
  10930.  if wordpos("LOCAL",uargs) > 0 then local = "LOCAL"                             
  10931.  if wordpos("FORCE",uargs) > 0 then force = "FORCE"                             
  10932.  if wordpos("TEST" ,uargs) > 0 then test  = "TEST"                              
  10933.  if wordpos("DEBUG",uargs) > 0 then debug = "DEBUG"                             
  10934.                                                                                 
  10935. end                                                                             
  10936.                                                                                 
  10937. signal on failure                                                               
  10938. signal on halt                                                                  
  10939.                                                                                 
  10940. call check_for_other_socket_app                                                 
  10941. call read_gopherrc                                                              
  10942. call validate_operands                                                          
  10943. call libdef                                                                     
  10944. call let_me_know                                                                
  10945. call ggm_dialog                                                                 
  10946. call unlibdef                                                                   
  10947.                                                                                 
  10948. cleanup:                                                                        
  10949. if libdeffed then call unlibdef                                                 
  10950. if stacked then "DELSTACK"                                                      
  10951. exit                                                                            
  10952. error:failure:halt:say "GOPHER: Severe lossage."                                
  10953. say "Statement:" sourceline(sigl)                                               
  10954. exit                                                                            
  10955.                                                                                 
  10956. /*********************************************************************/         
  10957.                                                                                 
  10958. validate_operands:                                                              
  10959.                                                                                 
  10960. /*                                                                              
  10961.  * Logic that determines what to display on startup:                            
  10962.  * If gopherrc file does not exist, create it from default                      
  10963.  * (default has everything commented out except for a                           
  10964.  *  one-item "initial" menu pointing to the MVS server)                         
  10965.  * Read gopherrc (in case operands need fields therein)                         
  10966.  * Command operands override gopherrc specs:                                    
  10967.  * if LOCAL given then server = "-", see below for SERVER(-)                    
  10968.  * if SERVER(host) given then startup host=SERVER, path=PATH, etc.              
  10969.  *  (no gopherrc referenced)                                                    
  10970.  * if SERVER(-) given then either PATH must be given or                         
  10971.  *  the gopherrc's localmenu: must be given,                                    
  10972.  *  otherwise look at gopherrc                                                  
  10973.  *   if LOCAL given and initial: present then extract startup menu              
  10974.  *    but remember that there will be no server access possible                 
  10975.  *   else nothing given, this is an error, barf                                 
  10976.  * if no SERVER, look at gopherrc:                                              
  10977.  *   if initial: given then extract startup menu from there                     
  10978.  *   else if localmenu: given then use that menu (SERVER=-)                     
  10979.  *   else nothing given, display ISPF panel asking for host/path                
  10980.  */                                                                             
  10981.                                                                                 
  10982. if local = "LOCAL" then do                                                      
  10983.  if server <> "" then do                                                        
  10984.   say "GOPHER: SERVER cannot be specified when LOCAL is specified."             
  10985.   exit 12                                                                       
  10986.  end                                                                            
  10987.  server = "-"                                                                   
  10988. end                                                                             
  10989.                                                                                 
  10990. if bookmark <> "" then do                                                       
  10991.  if server <> "" & local = "" then do                                           
  10992.   say "GOPHER: SERVER cannot be specified when BOOKMARK is specified."          
  10993.   exit 12                                                                       
  10994.  end                                                                            
  10995.  if path <> "" then do                                                          
  10996.   say "GOPHER: PATH cannot be specified when BOOKMARK is specified."            
  10997.   exit 12                                                                       
  10998.  end                                                                            
  10999.  server = "-"                                                                   
  11000.  if left(bookmark,1) = "'" then path = strip(bookmark,"B","'")                  
  11001.  else do                                                                        
  11002.   tsoprefix = sysvar("SYSPREF")                                                 
  11003.   if tsoprefix = "" then path = bookmark                                        
  11004.   else path = tsoprefix"."bookmark                                              
  11005.  end                                                                            
  11006.  if description = "" then description = "Bookmark" path                         
  11007. end                                                                             
  11008.                                                                                 
  11009. ggpath = ""                                                                     
  11010. gghost = ""                                                                     
  11011. ggport = port                                                                   
  11012. ggdesc = description                                                            
  11013.                                                                                 
  11014. if server <> "" then do                                                         
  11015.  if server = "-" then do                                                        
  11016.   gghost = server                                                               
  11017.   if path <> "" then do                                                         
  11018.    ggpath = path                                                                
  11019.   end                                                                           
  11020.   else if localmenu <> "" then do                                               
  11021.    ggpath = localmenu                                                           
  11022.    if ggdesc = "" then ggdesc = "Local Private Gopher Menu"                     
  11023.   end                                                                           
  11024.   else if local = "LOCAL" & initial <> "" then do                               
  11025.    gghost = ""                                                                  
  11026.    call use_initial_spec                                                        
  11027.    if gghost <> "-" then do                                                     
  11028.     say "Gopher: Cannot determine path for local access."                       
  11029.     say "        Either specify PATH(pathname), activate"                       
  11030.     say "        the localmenu: line in GOPHERRC, or set"                       
  11031.     say "        the initial: line in GOPHERRC for local access."               
  11032.     exit 12                                                                     
  11033.    end                                                                          
  11034.   end                                                                           
  11035.   else do                                                                       
  11036.    say "Gopher: Cannot determine path for local access."                        
  11037.    say "        Either specify PATH(pathname) or activate"                      
  11038.    say "        the localmenu: or initial: line in GOPHERRC."                   
  11039.    exit 12                                                                      
  11040.   end                                                                           
  11041.  end                                                                            
  11042.  else do                                                                        
  11043.   gghost = server                                                               
  11044.   ggpath = path                                                                 
  11045.   ggdesc = description                                                          
  11046.   ggport = port                                                                 
  11047.   nop  /* use provided server, host, path, etc. */                              
  11048.  end                                                                            
  11049. end                                                                             
  11050. else do       /* no server given on command */                                  
  11051.  if localmenu <> "" then do                                                     
  11052.   gghost = "-"                                                                  
  11053.   ggpath = localmenu                                                            
  11054.   if ggdesc = "" then ggdesc = "Local Private Gopher Menu"                      
  11055.  end                                                                            
  11056.  else if initial <> "" then do                                                  
  11057.   call use_initial_spec                                                         
  11058.  end                                                                            
  11059.  else do                                                                        
  11060.   /* this is nominally illegal, but should cause gopher to                      
  11061.      display the hackish startup menu */                                        
  11062.   gghost = ""                                                                   
  11063.   ggpath = ""                                                                   
  11064.  end                                                                            
  11065. end                                                                             
  11066.                                                                                 
  11067. return                                                                          
  11068.                                                                                 
  11069. /*********************************************************************/         
  11070.                                                                                 
  11071. use_initial_spec:                                                               
  11072.                                                                                 
  11073.  if initial = "*temp*" then do                                                  
  11074.   /* we're eventually not going to do it this way really */                     
  11075.   /* initial_type is ignored - only "DIRECTORY" is valid anyway */              
  11076.   if initial_name <> "" & ggdesc = "" then ggdesc = initial_name                
  11077.   if initial_host <> "" & gghost = "" then gghost = initial_host                
  11078.   if initial_path <> "" & ggpath = "" then ggpath = initial_path                
  11079.   if initial_port <> "" & ggport = "" then ggport = initial_port                
  11080.  end                                                                            
  11081.  else do                                                                        
  11082.   ggpath = initial                                                              
  11083.   if ggdesc = "" then ggdesc = "Local Private Gopher Menu"                      
  11084.  end                                                                            
  11085.                                                                                 
  11086. return                                                                          
  11087.                                                                                 
  11088. /*********************************************************************/         
  11089.                                                                                 
  11090. read_gopherrc:                                                                  
  11091.                                                                                 
  11092. localmenu = ""                                                                  
  11093. localexec = ""                                                                  
  11094. initial   = ""                                                                  
  11095. initial_type = ""                                                               
  11096. initial_name = ""                                                               
  11097. initial_host = ""                                                               
  11098. initial_path = ""                                                               
  11099. initial_port = ""                                                               
  11100. new_gopherrc = 0                                                                
  11101. gopherrc = "'"userid()".GOPHERRC'"                                              
  11102. gopherdcb = "RECFM(V B) LRECL(255) BLKSIZE(6233) DSORG(PS)"                     
  11103. gopherrc_status = sysdsn(gopherrc)                                              
  11104. select                                                                          
  11105.  when gopherrc_status = "OK" then nop                                           
  11106.  when gopherrc_status = "DATASET NOT FOUND" then do                             
  11107.   address TSO "ALLOC DA("gopherrc") T SP(1 1)" gopherdcb                        
  11108.   if rc <> 0 then do                                                            
  11109.    say "Error: Cannot create" gopherrc                                          
  11110.    exit rc                                                                      
  11111.   end                                                                           
  11112.   new_gopherrc = 1                                                              
  11113.  end                                                                            
  11114.  otherwise do                                                                   
  11115.   say "Error: Cannot access" gopherrc":" gopherrc_status                        
  11116.   exit 16                                                                       
  11117.  end                                                                            
  11118. end                                                                             
  11119.                                                                                 
  11120. address TSO "ALLOC FI(GOPHERRC) DA("gopherrc") OLD REU"                         
  11121. if rc <> 0 then exit rc                                                         
  11122.                                                                                 
  11123. if new_gopherrc = 0 then do                                                     
  11124.  "EXECIO * DISKR GOPHERRC (FINIS STEM GOPHERRC.)"                               
  11125.  execiorc = rc                                                                  
  11126.  if execiorc <> 0 then do                                                       
  11127.   say "Error: Cannot read" gopherrc                                             
  11128.   address TSO "FREE FI(GOPHERRC)"                                               
  11129.   exit execiorc                                                                 
  11130.  end                                                                            
  11131.  if gopherrc.0 = 0 then new_gopherrc = 1                                        
  11132. end                                                                             
  11133.                                                                                 
  11134. if new_gopherrc then call initialize_gopherrc                                   
  11135.                                                                                 
  11136. address TSO "FREE FI(GOPHERRC)"                                                 
  11137.                                                                                 
  11138. collecting_initial = 0                                                          
  11139. do i = 1 to gopherrc.0                                                          
  11140.  gline = gopherrc.i                                                             
  11141.  if gline = "" then iterate                                                     
  11142.  if left(gline,1) = '#' then iterate                                            
  11143.  parse var gline ghead ":" gtext                                                
  11144.  ghead = translate(strip(ghead,"B"))                                            
  11145.  gtext = strip(gtext,"B")                                                       
  11146.  if collecting_initial then do                                                  
  11147.   parse var gline ghead "=" gtext                                               
  11148.   ghead = translate(strip(ghead,"B"))                                           
  11149.   gtext = strip(gtext,"B")                                                      
  11150.   select                                                                        
  11151.    when ghead = "TYPE" then initial_type = gtext                                
  11152.    when ghead = "NAME" then initial_name = gtext                                
  11153.    when ghead = "PATH" then initial_path = gtext                                
  11154.    when ghead = "HOST" then initial_host = gtext                                
  11155.    when ghead = "PORT" then initial_port = gtext                                
  11156.    when ghead = "END"  then do                                                  
  11157.     collecting_initial = 0                                                      
  11158.     initial = "*temp*"                                                          
  11159.    end                                                                          
  11160.    otherwise do                                                                 
  11161.     say "Error in "gopherrc": INITIAL: not terminated by END"                   
  11162.     say "Line where error was detected:"                                        
  11163.     say gline                                                                   
  11164.     exit 8                                                                      
  11165.    end                                                                          
  11166.   end                                                                           
  11167.  end                                                                            
  11168.  else select                                                                    
  11169.   when ghead = "LOCALMENU" then localmenu = gtext                               
  11170.   when ghead = "LOCALEXEC" then localexec = gtext                               
  11171.   when ghead = "INITIAL"   then do                                              
  11172.    if gtext = "" then collecting_initial = 1                                    
  11173.    else initial = gtext                                                         
  11174.   end                                                                           
  11175.   otherwise do                                                                  
  11176.    say "Warning, gopherrc field ignored:" ghead                                 
  11177.   end                                                                           
  11178.  end                                                                            
  11179. end                                                                             
  11180.                                                                                 
  11181. return                                                                          
  11182.                                                                                 
  11183. /*********************************************************************/         
  11184.                                                                                 
  11185. ggm_dialog:                                                                     
  11186.                                                                                 
  11187. vputvars = "GGHOST GGPORT GGPATH GGDESC"                                        
  11188.                                                                                 
  11189. if vputvars <> "" then do                                                       
  11190.  address ISPEXEC "VPUT ("vputvars") PROFILE"                                    
  11191.  if rc <> 0 then do; call ispf_error rc; exit rc; end                           
  11192. end                                                                             
  11193.                                                                                 
  11194. parm = ""                                                                       
  11195. if test  = "TEST"  then parm = parm "-t"                                        
  11196. if debug = "DEBUG" then parm = parm "-d"                                        
  11197. if local = "LOCAL" then parm = parm "-l"                                        
  11198. if gghost <> ""    then parm = parm "-q"                                        
  11199.                                                                                 
  11200. zerrmsg = ""                                                                    
  11201. zerrsm  = ""                                                                    
  11202. zerrlm  = ""                                                                    
  11203.                                                                                 
  11204. if ggmappl = "" then applsource = ""                                            
  11205. else applsource = "NEWAPPL("ggmappl") PASSLIB"                                  
  11206.                                                                                 
  11207. if ggmload = "" then selstring = "PGM("ggmlmod") PARM("parm")"                  
  11208. else selstring = "CMD(CALL '"ggmload"("ggmlmod")'" quote(parm)")"               
  11209.                                                                                 
  11210. address ISPEXEC "SELECT" applsource selstring                                   
  11211.                                                                                 
  11212. if rc <> 0 then say "Return code from" ggmlmod "program is" rc                  
  11213.                                                                                 
  11214. address ISPEXEC "VGET (ZERRSM ZERRLM)"                                          
  11215. if zerrsm <> "" then do                                                         
  11216.  say zerrmsg":" zerrsm                                                          
  11217.  say zerrlm                                                                     
  11218. end                                                                             
  11219.                                                                                 
  11220. return                                                                          
  11221.                                                                                 
  11222. /*********************************************************************/         
  11223.                                                                                 
  11224. libdef:                                                                         
  11225. if ggmpanel <> "" then do                                                       
  11226.  address ISPEXEC "LIBDEF ISPPLIB DATASET ID('"ggmpanel"')"                      
  11227.  if rc <> 0 then do; call ispf_error rc; exit rc; end                           
  11228. end                                                                             
  11229. if localexec <> "" then do                                                      
  11230.  address TSO "ALLOC FI(GGEXEC) SHR REU DA('"localexec"')"                       
  11231.  if rc <> 0 then exit rc                                                        
  11232. end                                                                             
  11233. libdeffed = 1                                                                   
  11234. return                                                                          
  11235.                                                                                 
  11236. /*********************************************************************/         
  11237.                                                                                 
  11238. unlibdef:                                                                       
  11239. if localexec <> "" then do                                                      
  11240.  address TSO "FREE FI(GGEXEC)"                                                  
  11241. end                                                                             
  11242. if ggmpanel <> "" then do                                                       
  11243.  address ISPEXEC "LIBDEF ISPPLIB DATASET"                                       
  11244.  if rc <> 0 then call ispf_error rc                                             
  11245. end                                                                             
  11246. libdeffed = 0                                                                   
  11247. return                                                                          
  11248.                                                                                 
  11249. /*********************************************************************/         
  11250.                                                                                 
  11251. initialize_gopherrc:                                                            
  11252.                                                                                 
  11253.  say "Initializing new GOPHERRC file..."                                        
  11254.  do i = sigl while sourceline(i) <> "_BEGIN_"                                   
  11255.  end                                                                            
  11256.  gx = 0                                                                         
  11257.  do i = i+1 by 1                                                                
  11258.   gline = sourceline(i)                                                         
  11259.   if gline = "_END_" then leave                                                 
  11260.   gpos = pos("ggmdefaulthost",gline)                                            
  11261.   if gpos > 0 then do                                                           
  11262.    gline = substr(gline,1,gpos-1) || ggmdefaulthost                             
  11263.   end                                                                           
  11264.   gx = gx + 1                                                                   
  11265.   gopherrc.gx = gline                                                           
  11266.  end                                                                            
  11267.  gopherrc.0 = gx                                                                
  11268.  "EXECIO * DISKW GOPHERRC (FINIS STEM GOPHERRC.)"                               
  11269.  say "New GOPHERRC file initialized."                                           
  11270.                                                                                 
  11271. return                                                                          
  11272.                                                                                 
  11273. /*                                                                              
  11274.                                                                                 
  11275. _BEGIN_                                                                         
  11276. #                                                                               
  11277. #                                                                               
  11278. # Default "gopherrc" file, created by the MVS Gopher client.                    
  11279. #                                                                               
  11280. # Uncomment desired fields by removing the initial "# " from them.              
  11281. #                                                                               
  11282. # Beware - the Gopher client may update this file with bookmarks.               
  11283. #          You can delete it at any time and it will be recreated               
  11284. #          from the default settings, but you'll lose your bookmarks.           
  11285. #                                                                               
  11286. ######################################################################          
  11287. #                                                                               
  11288. # If you want local (serverless) gopher access, then use the following          
  11289. # lines, specifying full qualified (no quotes) data set names:                  
  11290. #                                                                               
  11291. # localmenu: name_of_initial_gopher_menu                                        
  11292. # localexec: name_of_pds_of_rexx_execs                                          
  11293. #                                                                               
  11294. # Specifying localmenu: is equivalent to specifying an initial: section         
  11295. # with host set to "-" and path set to the value of localmenu.                  
  11296. #                                                                               
  11297. # You cannot use your own REXX execs, however, unless you specify               
  11298. # localexec: as above.  You don't need one to use the other, though.            
  11299. #                                                                               
  11300. ######################################################################          
  11301. #                                                                               
  11302. # The following is used by the Gopher client at startup to determine            
  11303. # how the initial menu will appear.                                             
  11304. #                                                                               
  11305. # You may want to change the host to the one appropriate for your site.         
  11306. #                                                                               
  11307. initial:                                                                        
  11308. #                                                                               
  11309. Type=DIRECTORY                                                                  
  11310. Name=Primary (Root) Gopher Menu                                                 
  11311. Path=                                                                           
  11312. Host=ggmdefaulthost                                                             
  11313. Port=70                                                                         
  11314. End                                                                             
  11315. #                                                                               
  11316. # Alternatively, if you want your own private Gopher data:                      
  11317. #                                                                               
  11318. # initial:                                                                      
  11319. #                                                                               
  11320. # Type=0                                                                        
  11321. # Name=My Own Private Gopherhole                                                
  11322. # Path=userid.GOPHER.MENU                                                       
  11323. # Host=-                                                                        
  11324. # End                                                                           
  11325. #                                                                               
  11326. # In which case you should create a data set called userid.GOPHER.MENU          
  11327. # (or whatever name you choose that appears in the "Path=" line above)          
  11328. # that looks like this.  (NOT in the gopherrc file!)                            
  11329. #                                                                               
  11330. #                                                                               
  11331. # gopher_menu                                                                   
  11332. #                                                                               
  11333. # TYPE=DIRECTORY                                                                
  11334. # NAME=Public GOPHER Server at ggmdefaulthost                                   
  11335. # PATH=                                                                         
  11336. # HOST=ggmdefaulthost                                                           
  11337. # END                                                                           
  11338. #                                                                               
  11339. # TYPE=DIRECTORY                                                                
  11340. # NAME=Private GOPHER                                                           
  11341. # PATH=userid.ANOTHER.GOPHER.MENU                                               
  11342. # HOST=-                                                                        
  11343. # END                                                                           
  11344. #                                                                               
  11345. # and then you need yet another menu, similar in format to this one,            
  11346. # in userid.ANOTHER.GOPHER.MENU.  Get the idea?                                 
  11347. #                                                                               
  11348. ######################################################################          
  11349. #                                                                               
  11350. # These fields may be used by the Gopher client for local purposes              
  11351. # in the future.  Currently they are ignored.                                   
  11352. #                                                                               
  11353. # Printercmd: lpr                                                               
  11354. # Telnetcmd: telnet                                                             
  11355. # Mailcmd: mail                                                                 
  11356. # Playcmd: play -v 40 -                                                         
  11357. # TN3270cmd: tn3270                                                             
  11358. # MIMEcmd: metamail -p                                                          
  11359. #                                                                               
  11360. ######################################################################          
  11361. _END_                                                                           
  11362.                                                                                 
  11363. */                                                                              
  11364.                                                                                 
  11365. /*********************************************************************/         
  11366.                                                                                 
  11367. check_for_other_socket_app:                                                     
  11368.                                                                                 
  11369.  if local = "LOCAL" then return                                                 
  11370.                                                                                 
  11371.  call nnmfiucv      /* FIND IUCVMULT in another PIE MultiTSO session */         
  11372.                                                                                 
  11373.  if result = 0 then return                                                      
  11374.                                                                                 
  11375.  say,                                                                           
  11376.  "A TCP/IP socket application appears active in another PIE session."           
  11377.  if force = "FORCE" then do                                                     
  11378.   say "Proceeding anyhow, because you said FORCE."                              
  11379.   return                                                                        
  11380.  end                                                                            
  11381.  say "To proceed at this point would be potentially disastrous."                
  11382.  say "If you want to use GOPHER anyway, use one of these operands:"             
  11383.  say "  FORCE  -  if I'm mistaken and it's really safe to make a"               
  11384.  say "            TCP/IP connection."                                           
  11385.  say "  LOCAL  -  if you just want local (serverless) access."                  
  11386.  say "Terminating."                                                             
  11387.                                                                                 
  11388. exit 16                                                                         
  11389.                                                                                 
  11390. /*********************************************************************/         
  11391.                                                                                 
  11392. ispf_error: parse arg ispfrc                                                    
  11393.                                                                                 
  11394. say "GOPHER: ISPF dialog service error detected on line" sigl                   
  11395. say sourceline(sigl)                                                            
  11396. say                                                                             
  11397. say zerrmsg":" zerrsm                                                           
  11398. say zerrlm                                                                      
  11399. say                                                                             
  11400.                                                                                 
  11401. return ispfrc                                                                   
  11402.                                                                                 
  11403. /*********************************************************************/         
  11404.                                                                                 
  11405. /*                                                                              
  11406.  * The following function starts ISPF from READY mode.                          
  11407.  * Beware:  splitting the screen starts up an identical copy of the             
  11408.  *          application, which may not be desirable.                            
  11409.  */                                                                             
  11410.                                                                                 
  11411. startispf: parse arg startappl, startcmd                                        
  11412. if startappl = "" then,                                                         
  11413.  "ISPSTART CMD("startcmd")"                                                     
  11414. else,                                                                           
  11415.  "ISPSTART NEWAPPL("startappl") CMD("startcmd")"                                
  11416. return                                                                          
  11417.                                                                                 
  11418. /* The following function implements Big Brother mode. */                       
  11419.                                                                                 
  11420. let_me_know:                                                                    
  11421. if gophermeister = "" | gophermeister = userid() then return                    
  11422. parse source . . execname . execds .                                            
  11423. call outtrap "X."                                                               
  11424. address TSO,                                                                    
  11425.  "SEND" quote(execds"("execname")" date("U") time()" "),                        
  11426.         "U("gophermeister") LOGON"                                              
  11427. call outtrap "OFF"                                                              
  11428. return                                                                          
  11429.                                                                                 
  11430. /* The following function enquotes a string. */                                 
  11431.                                                                                 
  11432. quote: parse arg string                                                         
  11433. ix = 1                                                                          
  11434. do forever                                                                      
  11435.  ix = pos("'",string,ix)                                                        
  11436.  if ix = 0 then return "'"string"'"                                             
  11437.  string = insert("'",string,ix)                                                 
  11438.  ix=ix+2                                                                        
  11439. end                                                                             
  11440.                                                                                 
  11441. ./   ADD NAME=HOSTNAME,SSI=01000048                                             
  11442. /* REXX */                                                                      
  11443.                                                                                 
  11444. return "MVS.DRAPER.COM"   /* or your hostname, in production */                 
  11445. /* return "-" */          /* for local private testing */                       
  11446.                                                                                 
  11447. ./   ADD NAME=NNMFIUCV,SSI=01000017                                             
  11448. /* REXX.  This exec scans the job pack queues for IUCVMULT and returns          
  11449.  * with an error code if IUCVMULT is already loaded under a                     
  11450.  * different TCB. This can only happen under PIE MultiTSO or a                  
  11451.  * similar product that makes multiple job step TCB's.                          
  11452.  */                                                                             
  11453.                                                                                 
  11454. trace off                                                                       
  11455. signal on novalue                                                               
  11456.                                                                                 
  11457. search_name = "IUCVMULT"                                                        
  11458. count = 0                                                                       
  11459. foundtcb. = ""                                                                  
  11460. current_tcb  = getword24("21C")                                                 
  11461. current_job_step_tcb = getword24(current_tcb,"7C")                              
  11462. current_ascb = getword24("224")                                                 
  11463. current_asxb = getword31(current_ascb,"6C")                                     
  11464. first_tcb    = getword24(current_asxb,"4")                                      
  11465. tcb = first_tcb                                                                 
  11466. motherflag = 0                                                                  
  11467. do forever                                                                      
  11468.  if motherflag = 0 then do                                                      
  11469.   call process                                                                  
  11470.   daughter_tcb = getword24(tcb,"88")                                            
  11471.   if daughter_tcb \= "00000000" then do                                         
  11472.    tcb = daughter_tcb                                                           
  11473.    iterate                                                                      
  11474.   end                                                                           
  11475.  end                                                                            
  11476.  motherflag = 0                                                                 
  11477.  sister_tcb = getword24(tcb, "80")                                              
  11478.  if sister_tcb \= "00000000" then do                                            
  11479.   tcb = sister_tcb                                                              
  11480.   iterate                                                                       
  11481.  end                                                                            
  11482.  mother_tcb = getword24(tcb, "84")                                              
  11483.  if mother_tcb \= "00000000" then do                                            
  11484.   tcb = mother_tcb                                                              
  11485.   motherflag = 1                                                                
  11486.   iterate                                                                       
  11487.  end                                                                            
  11488.  leave                                                                          
  11489. end                                                                             
  11490.                                                                                 
  11491. if count = 0 then return 0                                                      
  11492. problem = 0                                                                     
  11493. do i = 1 to count                                                               
  11494.  if foundtcb.i = current_job_step_tcb then do                                   
  11495.   /*                                                                            
  11496.   say search_name "is already loaded under current TCB at "foundtcb.i"."        
  11497.   */                                                                            
  11498.  end                                                                            
  11499.  else do                                                                        
  11500.   /*                                                                            
  11501.   say search_name "is loaded under different TCB at "foundtcb.i"."              
  11502.   */                                                                            
  11503.   problem = 1                                                                   
  11504.  end                                                                            
  11505. end                                                                             
  11506.                                                                                 
  11507. if problem = 1 then return 1                                                    
  11508.                                                                                 
  11509. else return 0                                                                   
  11510.                                                                                 
  11511. process:                                                                        
  11512.                                                                                 
  11513.  jpq = getword31(tcb,"2C")                                                      
  11514.  cde = jpq                                                                      
  11515.  do while cde \= "00000000"                                                     
  11516.   cde_contents = storage(cde,32)                                                
  11517.   cde_name = substr(cde_contents,9,8)                                           
  11518.   cde_epa  = substr(cde_contents,9,8)                                           
  11519.   if search_name = cde_name then do                                             
  11520.    count = count + 1                                                            
  11521.    foundtcb.count = tcb                                                         
  11522.   end                                                                           
  11523.   cde = getword31(cde,"0")                                                      
  11524.  end                                                                            
  11525.                                                                                 
  11526. return                                                                          
  11527.                                                                                 
  11528. getword31: parse arg addr, offset                                               
  11529. temp1 = x2d(addr)                                                               
  11530. if offset = "" then temp2 = 0                                                   
  11531. else temp2 = x2d(offset)                                                        
  11532. return c2x(storage(d2x(temp1+temp2),4))                                         
  11533.                                                                                 
  11534. getword24: parse arg addr, offset                                               
  11535. temp1 = x2d(addr)                                                               
  11536. if offset = "" then temp2 = 0                                                   
  11537. else temp2 = x2d(offset)                                                        
  11538. return "00"c2x(storage(d2x(temp1+temp2+1),3))                                   
  11539.                                                                                 
  11540. ./   ADD NAME=TSOHELP,SSI=01020035                                              
  11541. /* REXX */                                                                      
  11542.                                                                                 
  11543. /* This exec provides a sample TSO HELP application.                            
  11544.    The gopher menu item will look something like this:                          
  11545.                                                                                 
  11546. TYPE=DIRECTORY                                                                  
  11547. NAME=TSO HELP                                                                   
  11548. PATH=EXEC:TSOHELP                                                               
  11549. HOST=+                                                                          
  11550. END                                                                             
  11551.                                                                                 
  11552. where "TSOHELP" is the name of this exec.                                       
  11553.                                                                                 
  11554. This exec generates a series of lower-level menus, giving the user              
  11555. a choice of how much help data to search (IBM only, local installation          
  11556. help, etc.).  This particular sample is Draper Lab's own, so you will           
  11557. need to change it.                                                              
  11558.                                                                                 
  11559.  */                                                                             
  11560.                                                                                 
  11561. trace off                                                                       
  11562. signal on novalue                                                               
  11563.                                                                                 
  11564. host = hostname()                                                               
  11565. port = "70"                                                                     
  11566. tab  = '05'x                                                                    
  11567.                                                                                 
  11568. helpfiles.        = "'SYS1.HELP'"                                               
  11569. helpfiles.sys1    = "'SYS1.HELP'"                                               
  11570. helpfiles.draper  = "'CSD.CMD.HELP' 'CSD.PP.HELP' 'SYS1.HELP'"                  
  11571. helpfiles.proglib = "'PROGLIB.CMD.HELP'"                                        
  11572.                                                                                 
  11573. parse arg helplib command type extra                                            
  11574.                                                                                 
  11575. if helplib = "" then,                                                           
  11576.      call display_top_menus                                                     
  11577. else call set_up_help helplib,command,type,extra                                
  11578.                                                                                 
  11579. return 0                                                                        
  11580.                                                                                 
  11581. /*------------------------------------------------------------------*/          
  11582.                                                                                 
  11583. display_top_menus:                                                              
  11584.                                                                                 
  11585.  call start_output                                                              
  11586.  call menu_out "SYS1",  "COMMANDS","DIRECTORY","Regular IBM TSO Help"           
  11587.  call menu_out "DRAPER","COMMANDS","DIRECTORY","IBM and Draper TSO Help"        
  11588.  call menu_out "PROGLIB","PROGLIB" ,"DIRECTORY","PROGLIB TSO Help"              
  11589.  call end_output                                                                
  11590.                                                                                 
  11591. return                                                                          
  11592.                                                                                 
  11593. /*------------------------------------------------------------------*/          
  11594.                                                                                 
  11595. set_up_help:  parse arg helplib,command,type,extra                              
  11596.                                                                                 
  11597.  call outtrap "TSO."                                                            
  11598.  "ALLOC FI(SYSHELP) SHR REU DA("helpfiles.helplib")"                            
  11599.  allocrc = rc                                                                   
  11600.  call outtrap "OFF"                                                             
  11601.  if allocrc <> 0 then do                                                        
  11602.   call start_output                                                             
  11603.   do i = 1 to tso.0                                                             
  11604.    call menu_out "ERROR","ERROR","DIRECTORY",tso.i                              
  11605.   end                                                                           
  11606.   call end_output                                                               
  11607.  end                                                                            
  11608.  else do                                                                        
  11609.   select                                                                        
  11610.    when type = "FILE"      then call specific_help command,extra                
  11611.    when type = "DIRECTORY" then call general_help  command,extra                
  11612.    when type = "INDEX"     then call index_help    extra                        
  11613.    otherwise                    call specific_help command                      
  11614.  end                                                                            
  11615.                                                                                 
  11616. return                                                                          
  11617.                                                                                 
  11618. /*------------------------------------------------------------------*/          
  11619.                                                                                 
  11620. index_help:                                                                     
  11621.                                                                                 
  11622.  /* This intermediate one-element directory is necessary because                
  11623.   * the Gopher INDEX format only returns directories, not files.                
  11624.   */                                                                            
  11625.                                                                                 
  11626.  parse upper arg commands                                                       
  11627.  call start_output                                                              
  11628.  do while commands <> ""                                                        
  11629.   parse var commands command commands                                           
  11630.   call menu_out helplib,command,"FILE","Complete help for" command              
  11631.   call menu_out helplib,command,"FILE","Function help only","FUNCTION"          
  11632.   call menu_out helplib,command,"FILE","Syntax help only","SYNTAX"              
  11633.   call menu_out helplib,command,"FILE","Operands help only","OPERANDS"          
  11634.  end                                                                            
  11635.  call end_output                                                                
  11636.                                                                                 
  11637. return                                                                          
  11638.                                                                                 
  11639. /*------------------------------------------------------------------*/          
  11640.                                                                                 
  11641. general_help:                                                                   
  11642.                                                                                 
  11643. parse arg command,extra                                                         
  11644.                                                                                 
  11645. call get_help_text command,extra                                                
  11646.                                                                                 
  11647. call start_output                                                               
  11648.                                                                                 
  11649. call menu_out helplib,"*","INDEX","Help for a specific TSO command"             
  11650.                                                                                 
  11651. do i = 1 to help.0                                                              
  11652.  parse var help.i helpname helpdesc                                             
  11653.  if helpdesc <> "" & ,                                                          
  11654.     length(helpname) <= 8 & ,                                                   
  11655.     helpname < "0" & ,                                                          
  11656.     verify(helpname,"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789W#$") = 0 ,            
  11657.     then do                                                                     
  11658.                                                                                 
  11659.   /*                                                                            
  11660.    * Draper help has a series of "$..." members which are like                  
  11661.    * sublevel COMMANDS members.  This hack supports that.                       
  11662.    */                                                                           
  11663.                                                                                 
  11664.   if left(helpname,1) = "$" then do                                             
  11665.    call menu_out helplib,helpname,"DIRECTORY",helpdesc                          
  11666.   end                                                                           
  11667.   else do                                                                       
  11668.    call menu_out helplib,helpname,"FILE",helpdesc                               
  11669.   end                                                                           
  11670.  end                                                                            
  11671. end                                                                             
  11672.                                                                                 
  11673. call end_output                                                                 
  11674.                                                                                 
  11675. return                                                                          
  11676.                                                                                 
  11677. /*------------------------------------------------------------------*/          
  11678.                                                                                 
  11679. specific_help:                                                                  
  11680.                                                                                 
  11681. parse arg command,extra                                                         
  11682.                                                                                 
  11683. call get_help_text command,extra                                                
  11684.                                                                                 
  11685. call start_output                                                               
  11686.                                                                                 
  11687. do i = 1 to help.0                                                              
  11688.  call text_output help.i                                                        
  11689. end                                                                             
  11690.                                                                                 
  11691. call end_output                                                                 
  11692.                                                                                 
  11693. return                                                                          
  11694.                                                                                 
  11695. /*------------------------------------------------------------------*/          
  11696.                                                                                 
  11697. get_help_text:                                                                  
  11698.                                                                                 
  11699. parse arg helpcmd,helpargs                                                      
  11700.                                                                                 
  11701. help. =                                                                         
  11702.                                                                                 
  11703. call outtrap "HELP."                                                            
  11704.                                                                                 
  11705. address TSO "HELP" helpcmd helpargs                                             
  11706.                                                                                 
  11707. call outtrap "OFF"                                                              
  11708.                                                                                 
  11709. return                                                                          
  11710.                                                                                 
  11711. /*------------------------------------------------------------------*/          
  11712.                                                                                 
  11713. menu_out: parse arg mlib,mname,mtype,mdesc,mops                                 
  11714.                                                                                 
  11715.  select                                                                         
  11716.   when mtype = "FILE"      then gtype = "0"                                     
  11717.   when mtype = "DIRECTORY" then gtype = "1"                                     
  11718.   when mtype = "INDEX"     then gtype = "7"                                     
  11719.   otherwise do                                                                  
  11720.    call menu_out "ERROR","ERROR","DIRECTORY", "Unknown type:" mtype             
  11721.   end                                                                           
  11722.  end                                                                            
  11723.                                                                                 
  11724.  gname = left(mname,9)"--" mdesc                                                
  11725.  gpath = "EXEC:TSOHELP" mlib mname mtype mops                                   
  11726.  out = gtype || gname || tab || gpath || tab || host || tab || port             
  11727.  queue out                                                                      
  11728.                                                                                 
  11729. return                                                                          
  11730.                                                                                 
  11731. /*------------------------------------------------------------------*/          
  11732.                                                                                 
  11733. text_output: parse arg text                                                     
  11734.                                                                                 
  11735.  if text = "" then queue " "                                                    
  11736.  else queue text                                                                
  11737.                                                                                 
  11738. return                                                                          
  11739.                                                                                 
  11740. /*------------------------------------------------------------------*/          
  11741.                                                                                 
  11742. start_output:                                                                   
  11743.                                                                                 
  11744. "newstack"                                                                      
  11745.                                                                                 
  11746. return                                                                          
  11747.                                                                                 
  11748. /*------------------------------------------------------------------*/          
  11749.                                                                                 
  11750. end_output:                                                                     
  11751.                                                                                 
  11752. queue ""                                                                        
  11753.                                                                                 
  11754. "EXECIO * DISKW SYSTSPRT (FINIS)"                                               
  11755.                                                                                 
  11756. "delstack"                                                                      
  11757.                                                                                 
  11758. return                                                                          
  11759.                                                                                 
  11760. ./ ENDUP                                                                        
  11761. ?!                                                                              
  11762. //H        EXEC GGLOAD,TRK1='4',TO='H'                                          
  11763. //SYSIN    DD DATA,DLM='?!'                                                     
  11764. ./   ADD NAME=GG,SSI=01160032                                                   
  11765.                                                                                 
  11766.  /********************************************************************/         
  11767.  /*                                                                  */         
  11768.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  11769.  /*                                                                  */         
  11770.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  11771.  /*                                                                  */         
  11772.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  11773.  /* including the implied warranties of merchantability and fitness, */         
  11774.  /* are expressly denied.                                            */         
  11775.  /*                                                                  */         
  11776.  /* Provided this copyright notice is included, this software may    */         
  11777.  /* be freely distributed and not offered for sale.                  */         
  11778.  /*                                                                  */         
  11779.  /* Changes or modifications may be made and used only by the maker  */         
  11780.  /* of same, and not further distributed.  Such modifications should */         
  11781.  /* be mailed to the author for consideration for addition to the    */         
  11782.  /* software and incorporation in subsequent releases.               */         
  11783.  /*                                                                  */         
  11784.  /********************************************************************/         
  11785.                                                                                 
  11786. /* --------------------- "gg.h" include member --------------------- */         
  11787.                                                                                 
  11788. #pragma linkage(ispexec,OS)                                                     
  11789. #pragma linkage(isplink,OS)                                                     
  11790. #pragma linkage(ikjeff18,OS)                                                    
  11791.                                                                                 
  11792. /****** Installation-customized defines. *****************************/         
  11793.                                                                                 
  11794. #include "gguser.h"                                                             
  11795.                                                                                 
  11796. #ifndef  C370V1                                                                 
  11797. #ifndef  C370V2                                                                 
  11798. #ifndef  SASC                                                                   
  11799.  install_error_neither_C370V1_C370V2_nor_SASC_was_defined;                      
  11800. #endif                                                                          
  11801. #endif                                                                          
  11802. #endif                                                                          
  11803.                                                                                 
  11804. #ifndef  TCPIPV1                                                                
  11805. #ifndef  TCPIPV2                                                                
  11806. #ifndef  SNSTCPIP                                                               
  11807.  install_error_neither_TCPIPV1_TCPIPV2_nor_SNSTCPIP_was_defined;                
  11808. #endif                                                                          
  11809. #endif                                                                          
  11810. #endif                                                                          
  11811.                                                                                 
  11812. #ifndef  ISPFV2                                                                 
  11813. #ifndef  ISPFV3                                                                 
  11814.  install_error_neither_ISPFV2_nor_ISPFV3_was_defined;                           
  11815. #endif                                                                          
  11816. #endif                                                                          
  11817.                                                                                 
  11818. #define  MVS                                                                    
  11819.                                                                                 
  11820. /****** Clean up compiler warnings BEFORE time.h gets 'em ************/         
  11821.                                                                                 
  11822. #ifndef  SASC                                                                   
  11823. #define  localtime            LOCALTIM                                          
  11824. #endif                                                                          
  11825.                                                                                 
  11826. /****** Include all header files that are necessary. *****************/         
  11827.                                                                                 
  11828. #ifndef SNSTCPIP                                                                
  11829. #include <manifest.h>                                                           
  11830. #include <sys/types.h>                                                          
  11831. #include <netinet/in.h>                                                         
  11832. #include <sys/ioctl.h>                                                          
  11833. #include <tcperrno.h>                                                           
  11834. #include <fcntl.h>                                                              
  11835. #endif                                                                          
  11836.                                                                                 
  11837. #include <sys/socket.h>                                                         
  11838. #include <netdb.h>                                                              
  11839. #include <sys/uio.h>                                                            
  11840. #include <ctype.h>                                                              
  11841. #include <errno.h>                                                              
  11842. #include <limits.h>                                                             
  11843. #include <setjmp.h>                                                             
  11844. #include <stdio.h>                                                              
  11845. #include <stdarg.h>                                                             
  11846. #include <stdlib.h>                                                             
  11847. #include <string.h>                                                             
  11848. #include <stddef.h>                                                             
  11849. #include <time.h>                                                               
  11850.                                                                                 
  11851. #ifdef SNSTCPIP                                                                 
  11852. #include <acs.h>                                                                
  11853. #include <inet.h>                                                               
  11854. #include <sockcfg.h>                                                            
  11855. #include <serrno.h>                                                             
  11856. #endif                                                                          
  11857.                                                                                 
  11858. #ifndef  SASC                                                                   
  11859. #include <ctest.h>                                                              
  11860. #endif                                                                          
  11861.                                                                                 
  11862. #ifdef   SASC                                                                   
  11863. #include "ggsasc.h"                                                             
  11864. #endif                                                                          
  11865.                                                                                 
  11866. #undef ENOMEM                                                                   
  11867.                                                                                 
  11868. #include <mtf.h>                                                                
  11869.                                                                                 
  11870. /****** Version-dependent stuff **************************************/         
  11871.                                                                                 
  11872. #ifdef   C370V1                                                                 
  11873. #undef   FETCH                                                                  
  11874. #endif                                                                          
  11875.                                                                                 
  11876. #ifdef   C370V2                                                                 
  11877. #define  FETCH                                                                  
  11878. #endif                                                                          
  11879.                                                                                 
  11880. #ifdef   TCPIPV1                                                                
  11881. #define  TCP_DEBUG            tcp_debug                                         
  11882. #endif                                                                          
  11883.                                                                                 
  11884. #ifdef   TCPIPV2                                                                
  11885. #define  TCP_DEBUG            sock_debug                                        
  11886. #endif                                                                          
  11887.                                                                                 
  11888. #ifdef   SNSTCPIP                                                               
  11889. #define  TCP_DEBUG            /* I don't know how to debug in SNS */            
  11890. #undef   DEBUG                                                                  
  11891. #endif                                                                          
  11892.                                                                                 
  11893. #ifdef   DEBUG                                                                  
  11894. #define  TCP_DEBUG_ON         TCP_DEBUG(1)                                      
  11895. #define  TCP_DEBUG_OFF        TCP_DEBUG(0)                                      
  11896. #else                                                                           
  11897. #define  TCP_DEBUG_ON         /* */                                             
  11898. #define  TCP_DEBUG_OFF        /* */                                             
  11899. #endif                                                                          
  11900.                                                                                 
  11901. /****** Preprocessor bookkeeping *************************************/         
  11902.                                                                                 
  11903. #define  Bool                 char                                              
  11904. #define  Fool                 unsigned int /* for function arguments */         
  11905. #ifndef  TRUE                                                                   
  11906. #define  TRUE                 1                                                 
  11907. #endif                                                                          
  11908. #ifndef  FALSE                                                                  
  11909. #define  FALSE                0                                                 
  11910. #endif                                                                          
  11911.                                                                                 
  11912. #define  COMMANDSIZE          12                                                
  11913.                                                                                 
  11914. #define  GOPHER_FILE          '0'                                               
  11915. #define  GOPHER_DIRECTORY     '1'                                               
  11916. #define  GOPHER_CSO           '2'                                               
  11917. #define  GOPHER_ERROR         '3'                                               
  11918. #define  GOPHER_MAC_BINHEX    '4'                                               
  11919. #define  GOPHER_DOS_BINARCH   '5'                                               
  11920. #define  GOPHER_UUENCODE      '6'                                               
  11921. #define  GOPHER_WAIS          '7'                                               
  11922. #define  GOPHER_TELNET        '8'                                               
  11923. #define  GOPHER_TN3270        'T'                                               
  11924. #define  GOPHER_BINARY        '9'                                               
  11925. #define  GOPHER_REDUNDANT     '+'                                               
  11926. #define  GOPHER_WHOIS         'w'                                               
  11927.                                                                                 
  11928. #define  READ_BYTES           1024                                              
  11929. #define  SERVER_BUF_MSGSIZE   1024                                              
  11930. #define  CLIENT_BUF_MSGSIZE   1024                                              
  11931. #define  TEXT_BYTES           1024                                              
  11932. #define  INTERNET_SIZE        256                                               
  11933. #define  RBUFSIZE             256                                               
  11934. #define  OUTBUFSIZE           1024                                              
  11935.                                                                                 
  11936. #define  GOPHER_PORT_NUMBER   70                                                
  11937. #define  GOPHER_HOST_LENGTH   MAXHOSTNAMELEN                                    
  11938. #define  GOPHER_PATH_LENGTH   512                                               
  11939. #define  GOPHER_DESC_LENGTH   256                                               
  11940.                                                                                 
  11941. #define  SOCKET_GETCHAR_ERROR (-1)                                              
  11942. #define  SOCKET_NO_MORE       (-2)                                              
  11943. #define  SOCKET_READ_NOTHING  (-3)                                              
  11944.                                                                                 
  11945. #define  NO_VALUE             (-1)                                              
  11946.                                                                                 
  11947. #define  Rstruc               register struct                                   
  11948.                                                                                 
  11949. #define  EQUAL                !strcmp                                           
  11950. #define  UNEQUAL              strcmp                                            
  11951. #define  COPY(A,B)            strncpy((A),(B),sizeof(A)-1)                      
  11952.                                                                                 
  11953. #define  FIND_NEXT            'N'                                               
  11954. #define  FIND_FIRST           'F'                                               
  11955. #define  FIND_LAST            'L'                                               
  11956. #define  FIND_PREV            'P'                                               
  11957. #define  FIND_ALL             'A'                                               
  11958. #define  FIND_CHARS           '\0'                                              
  11959. #define  FIND_WORD            'W'                                               
  11960. #define  FIND_PREFIX          'P'                                               
  11961. #define  FIND_SUFFIX          'S'                                               
  11962. #define  FIND_CAPS            '\0'                                              
  11963. #define  FIND_ASIS            'A'                                               
  11964. #define  FIND_HEX             'X'                                               
  11965. #define  FIND_GENERIC         'P'                                               
  11966. #define  FIND_BADFORM         '\0'                                              
  11967. #define  FIND_UNQUOTED        'U'                                               
  11968. #define  FIND_QUOTED          'Q'                                               
  11969. #define  FIND_C               'C'                                               
  11970. #define  FIND_X               'X'                                               
  11971. #define  FIND_T               'T'                                               
  11972. #define  FIND_P               'P'                                               
  11973.                                                                                 
  11974. #define  MAX_INT               (int)0x7fffffff                                  
  11975. #define  LOCATE_INT            (int)0x7ffffffe                                  
  11976.                                                                                 
  11977. enum     scroll    {NO_SCROLL, UP, DOWN, LEFT, RIGHT, LOCATE};                  
  11978. enum     extreq    {EXTRACT_IT, PRINT_IT, BOOKMARK_IT};                         
  11979.                                                                                 
  11980. #define  CARRIAGE_RETURN      ('\r')                                            
  11981.                                                                                 
  11982. #ifdef   MVS                                                                    
  11983. #ifdef   I370                                                                   
  11984. #define  LINE_FEED            (0x15)                                            
  11985. #else                                                                           
  11986. #define  LINE_FEED            (0x25)                                            
  11987. #endif                                                                          
  11988. #else                                                                           
  11989. #define  LINE_FEED            (0x0a)                                            
  11990. #endif                                                                          
  11991.                                                                                 
  11992. #ifdef   MVS                                                                    
  11993. #ifdef   SNSTCPIP                                                               
  11994. #define  EtoA                 etoa                                              
  11995. #define  AtoE                 atoe                                              
  11996. #else                                                                           
  11997. #ifdef   I370                                                                   
  11998. #define  EtoA                 htoncs                                            
  11999. #define  AtoE                 ntohcs                                            
  12000. #else                                                                           
  12001. #define  EtoA(x)              ebcdictoascii[x]                                  
  12002. #define  AtoE(x)              asciitoebcdic[x]                                  
  12003. #define  ebcdictoascii        ebcdicto                                          
  12004. #define  asciitoebcdic        asciitoe                                          
  12005. #endif                                                                          
  12006. #endif                                                                          
  12007. #endif                                                                          
  12008.                                                                                 
  12009. #ifdef SNSTCPIP                                                                 
  12010. #define EBCDIC_TO_ASCII(A,B) EtoA(A,B)                                          
  12011. #define ASCII_TO_EBCDIC(A,B) AtoE(A,B)                                          
  12012. #else                                                                           
  12013. #define EBCDIC_TO_ASCII(A,B) {int _i; \                                         
  12014.                               for (_i=0; _i<(B); ++_i) \                        
  12015.                                   (A)[_i] = EtoA((A)[_i]); \                    
  12016.                              }                                                  
  12017. #define ASCII_TO_EBCDIC(A,B) {int _i; \                                         
  12018.                               for (_i=0; _i<(B); ++_i) \                        
  12019.                                   (A)[_i] = AtoE((A)[_i]); \                    
  12020.                              }                                                  
  12021. #endif                                                                          
  12022.                                                                                 
  12023. #ifdef TCPIPV1                                                                  
  12024. #define REPORT_TCP_ERROR(A)  /* */                                              
  12025. #endif                                                                          
  12026.                                                                                 
  12027. #ifdef TCPIPV2                                                                  
  12028. #define REPORT_TCP_ERROR(A)  tcperror(A)                                        
  12029. #endif                                                                          
  12030.                                                                                 
  12031. #ifdef SNSTCPIP                                                                 
  12032. #define REPORT_TCP_ERROR(A)  fprintf(stderr,\                                   
  12033.                                     "\nTCP error on %s: errno = %d\n",\         
  12034.                                     A,GET_ERRNO)                                
  12035. #endif                                                                          
  12036.                                                                                 
  12037. #ifdef SNSTCPIP                                                                 
  12038. #define Accept(A,B,C)        accept((A),(struct sockaddr *)(B),(C))             
  12039. #define Bind(A,B,C)          bind((A),(struct sockaddr *)(B),(C))               
  12040. #define Connect(A,B,C)       connect((A),(struct sockaddr *)(B),(C))            
  12041. #define Gethostbyaddr(A,B,C) gethostbyaddr((char *)(A),(B),(C))                 
  12042. #define Getpeername(A,B,C)   getpeername((A),(struct sockaddr *)(B),(C))        
  12043. #define Getsockopt(A,B,C,D,E) getsockopt((A),(B),(C),(char *)(D),(E))           
  12044. #define EWOULDBLOCK          (ESWOULDBLOCK+s0skcfg.errnobase)                   
  12045. #else                                                                           
  12046. #define Accept               accept                                             
  12047. #define Bind                 bind                                               
  12048. #define Connect              connect                                            
  12049. #define Gethostbyaddr        gethostbyaddr                                      
  12050. #define Getpeername          getpeername                                        
  12051. #define Getsockopt           getsockopt                                         
  12052. #endif                                                                          
  12053.                                                                                 
  12054. #ifdef   FETCH                                                                  
  12055. #define  ISPLINK              (gp->isplink_pointer)                             
  12056. #define  ISPEXEC              (gp->ispexec_pointer)                             
  12057. #else                                                                           
  12058. #define  ISPLINK              isplink                                           
  12059. #define  ISPEXEC              ispexec                                           
  12060. #endif                                                                          
  12061.                                                                                 
  12062. #define  DATAOUT_LOW          0x01                                              
  12063. #define  DATAOUT_HIGH         0x02                                              
  12064. #define  DATAIN_LOW           0x03                                              
  12065. #define  DATAIN_HIGH          0x04                                              
  12066. #define  DATAOUT_BLUE         DATAOUT_LOW                                       
  12067. #define  DATAOUT_GREEN        0x05                                              
  12068. #define  DATAOUT_PINK         0x06                                              
  12069. #define  DATAOUT_RED          0x07                                              
  12070. #define  DATAOUT_TURQ         0x08                                              
  12071. #define  DATAOUT_WHITE        DATAOUT_HIGH                                      
  12072. #define  DATAOUT_YELLOW       0x09                                              
  12073. #define  DATAIN_BLUE          0x0a                                              
  12074. #define  DATAIN_GREEN         DATAIN_LOW                                        
  12075. #define  DATAIN_PINK          0x0b                                              
  12076. #define  DATAIN_RED           DATAIN_HIGH                                       
  12077. #define  DATAIN_TURQ          0x0c                                              
  12078. #define  DATAIN_WHITE         0x0d                                              
  12079. #define  DATAIN_YELLOW        0x0e                                              
  12080.                                                                                 
  12081. #define  S99VRBAL  0x01             /* ALLOCATION                    */         
  12082. #define  S99VRBUN  0x02             /* UNALLOCATION                  */         
  12083. #define  S99VRBCC  0x03             /* CONCATENATION                 */         
  12084. #define  S99VRBDC  0x04             /* DECONCATENATION               */         
  12085. #define  S99VRBRI  0x05             /* REMOVE IN-USE                 */         
  12086. #define  S99VRBDN  0x06             /* DDNAME ALLOCATION             */         
  12087. #define  S99VRBIN  0x07             /* INFORMATION RETRIEVAL         */         
  12088. #define  S99NOCNV  0x40             /* ALLOC FUNCTION-DO NOT USE AN  */         
  12089.                                     /* EXISTING ALLOCATION TO SATISFY*/         
  12090.                                     /* THE REQUEST                   */         
  12091. #define  DALDDNAM   0x0001          /* DDNAME                        */         
  12092. #define  DALDSNAM   0x0002          /* DSNAME                        */         
  12093. #define  DALMEMBR   0x0003          /* MEMBER NAME                   */         
  12094. #define  DALSTATS   0x0004          /* DATA SET STATUS               */         
  12095. #define  DALNDISP   0x0005          /* DATA SET DISPOSITION          */         
  12096. #define  DALTRK     0x0007          /* TRACK SPACE TYPE              */         
  12097. #define  DALBLKLN   0x0009          /* BLOCK LENGTH                  */         
  12098. #define  DALPRIME   0x000a          /* PRIMARY SPACE ALLOCATION      */         
  12099. #define  DALSECND   0x000b          /* SECONDARY SPACE ALLOCATION    */         
  12100. #define  DALDIR     0x000c          /* DIRECTORY BLOCK ALLOCATION    */         
  12101. #define  DALSYSOU   0x0018          /* SYSOUT                        */         
  12102. #define  DALSFMNO   0x001a          /* SYSOUT FORMS NUMBER           */         
  12103. #define  DALCOPYS   0x001d          /* SYSOUT COPIES                 */         
  12104. #define  DALUCS     0x0029          /* UNIVERSAL CHARACTER SET       */         
  12105. #define  DALBLKSZ   0x0030          /* DCB BLOCKSIZE                 */         
  12106. #define  DALDSORG   0x003c          /* DATA SET ORGANIZATION         */         
  12107. #define  DALLRECL   0x0042          /* DCB LOGICAL RECORD LENGTH     */         
  12108. #define  DALRECFM   0x0049          /* DCB RECORD FORMAT             */         
  12109. #define  DALPERMA   0x0052          /* PERMANENTLY ALLOCATED ATTRIB  */         
  12110. #define  DALRTDDN   0x0055          /* RETURN DDNAME                 */         
  12111. #define  DALRTDSN   0x0056          /* RETURN DSNAME                 */         
  12112. #define  DALRTORG   0x0057          /* RETURN D.S. ORGANIZATION      */         
  12113. #define  DALSUSER   0x0058          /* SYSOUT REMOTE WORKSTATION     */         
  12114. #define  DUNDDNAM   0x0001          /* DDNAME                        */         
  12115. #define  DUNDSNAM   0x0002          /* DSNAME                        */         
  12116. #define  DUNUNALC   0x0007          /* UNALLOC OPTION                */         
  12117.                                                                                 
  12118. #define  SHR        0x08                                                        
  12119. #define  NEW        0x04                                                        
  12120. #define  MOD        0x02                                                        
  12121. #define  OLD        0x01                                                        
  12122. #define  KEEP       0x08                                                        
  12123. #define  DELETE     0x04                                                        
  12124. #define  CATLG      0x02                                                        
  12125. #define  UNCATLG    0x01                                                        
  12126. #define  RECFM_F    0x80                                                        
  12127. #define  RECFM_V    0x40                                                        
  12128. #define  RECFM_U    0xc0                                                        
  12129. #define  RECFM_D    0x20                                                        
  12130. #define  RECFM_T    0x20                                                        
  12131. #define  RECFM_B    0x10                                                        
  12132. #define  RECFM_S    0x08                                                        
  12133. #define  RECFM_A    0x04                                                        
  12134. #define  RECFM_M    0x02                                                        
  12135. #define  RECFM_FB   (RECFM_F | RECFM_B)                                         
  12136. #define  RECFM_VB   (RECFM_V | RECFM_B)                                         
  12137. #define  DSORG_PS   0x4000                                                      
  12138. #define  DSORG_PO   0x0200                                                      
  12139.                                                                                 
  12140.                                                                                 
  12141. /****** Data and structure definitions. ******************************/         
  12142.                                                                                 
  12143. typedef struct _textunit     TEXTUNIT;                                          
  12144. typedef unsigned int         IPADDRESS;                                         
  12145. typedef int                  SOCKETNO;                                          
  12146. typedef char                 gophertype;                                        
  12147. typedef enum     scroll      SCROLL;                                            
  12148. typedef enum     extreq      EXTREQ;                                            
  12149.                                                                                 
  12150. enum socket_retval  {                                                           
  12151.                      SERVER_READ_OK,                                            
  12152.                      SERVER_READ_ERROR,                                         
  12153.                      SERVER_BUFFER_ERROR,                                       
  12154.                      SERVER_NO_MORE,                                            
  12155.                      SERVER_READ_NOTHING                                        
  12156.                     };                                                          
  12157.                                                                                 
  12158. enum data_set_type  {                                                           
  12159.                      PDS,                                                       
  12160.                      SEQ,                                                       
  12161.                      UNK,                                                       
  12162.                      JES                                                        
  12163.                     };                                                          
  12164.                                                                                 
  12165. enum user_option    {                                                           
  12166.                      OPTION_ALL,                                                
  12167.                      OPTION_VIEW,                                               
  12168.                      OPTION_OTHER                                               
  12169.                     };                                                          
  12170.                                                                                 
  12171. struct textline    {                                                            
  12172.                     struct textline    *next;                                   
  12173.                     short               text_length;                            
  12174.                     short               tab_expanded_text_length;               
  12175.                     char               *tab_expanded_text;                      
  12176.                     char                text[1];  /* dummy */                   
  12177.                    };                                                           
  12178.                                                                                 
  12179. struct texthdr     {                                                            
  12180.                     int                   text_line_count;                      
  12181.                     struct textline      *text_body_line;                       
  12182.                     short                 text_max_length;                      
  12183.                     short                 text_max_tab_expanded_length;         
  12184.                     struct textline      *first_text_line;                      
  12185.                     struct textline      *current_text_line;                    
  12186.                     struct textline      *last_text_line;                       
  12187.                    };                                                           
  12188.                                                                                 
  12189. struct cmddesc   {                                                              
  12190.                   char    command_name[COMMANDSIZE];                            
  12191.                   Bool    (*command_processor)();                               
  12192.                  };                                                             
  12193.                                                                                 
  12194. struct seldesc   {                                                              
  12195.                   char    selection_code;                                       
  12196.                   Bool    (*selection_processor)();                             
  12197.                  };                                                             
  12198.                                                                                 
  12199. struct tabledesc {                                                              
  12200.                   char   *command_variable;                                     
  12201.         struct cmddesc   *first_cmddesc;                                        
  12202.         struct seldesc   *first_seldesc;                                        
  12203.                  };                                                             
  12204.                                                                                 
  12205. struct _textunit {                                                              
  12206.                   unsigned short         key;                                   
  12207.                   unsigned short         num;                                   
  12208.                   struct {                                                      
  12209.                           unsigned short len;                                   
  12210.                           char           prm[80];                               
  12211.                          }               ent;                                   
  12212.                  };                                                             
  12213.                                                                                 
  12214. struct extraction {                                                             
  12215.                    int                   from_number;                           
  12216.                    int                   to_number;                             
  12217.                    int                   count;                                 
  12218.                    enum data_set_type    mode;                                  
  12219.                    void               *(*closer)();                             
  12220.                    Bool                  appending;                             
  12221.                    Bool                  blanking;                              
  12222.                    Bool                  tab_expanding;                         
  12223.                    EXTREQ                ex;                                    
  12224.                    char                  panelname     [9];                     
  12225.                    char                  dsname       [65];                     
  12226.                    char                  separator    [81];                     
  12227.                    char                  member_prefix [9];                     
  12228.                    char                  ddname        [9];                     
  12229.                    char                  member        [9];                     
  12230.                   };                                                            
  12231.                                                                                 
  12232. struct gopherinfo {                                                             
  12233.                    gophertype            type;                                  
  12234.                    int                   port;                                  
  12235.                    struct texthdr        thdr;                                  
  12236.                    char                  path [GOPHER_PATH_LENGTH+1];           
  12237.                    char                  host [GOPHER_HOST_LENGTH+1];           
  12238.                    char                  desc [GOPHER_DESC_LENGTH+1];           
  12239.                    char                  bmds [65]; /* bookmark file */         
  12240.                   };                                                            
  12241.                                                                                 
  12242. struct recvstruct {                                                             
  12243.     int             sockfd;   /* socket descriptor for socket call */           
  12244.     int             outlen;                                                     
  12245.     int             myport;                                                     
  12246.     FILE           *outfp;    /* used by local (non-socket) interface*/         
  12247.     FILE           *readfile;                 /* declare the file... */         
  12248.     char           *fileptr;                                                    
  12249.     char           *wargptr;                                                    
  12250.     char           *mytelnet;                                                   
  12251.     char           *mydomain;                                                   
  12252.     struct hostent  clienthostent;                                              
  12253.     char            myname  [MAXHOSTNAMELEN+1];                                 
  12254.     char            hostname[MAXHOSTNAMELEN+1];  /* client host name */         
  12255.     char            hosttest[MAXHOSTNAMELEN+1];  /* client host name */         
  12256.     char            buffer  [RBUFSIZE]; /* client's character string */         
  12257.     char            dsname  [RBUFSIZE];                                         
  12258.     char            sockbuf [OUTBUFSIZE];    /* socket output buffer */         
  12259.    };                                                                           
  12260.                                                                                 
  12261. struct menuitem {                                                               
  12262.     char          type;                  /* type of record to send   */         
  12263.     char          desc     [GOPHER_DESC_LENGTH+1];                              
  12264.     char          select   [GOPHER_PATH_LENGTH+1];                              
  12265.     char          hostname [GOPHER_HOST_LENGTH+1];                              
  12266.     int           port;                  /* host port to connect to  */         
  12267.    };                                                                           
  12268.                                                                                 
  12269. struct connection  {                                                            
  12270.              char   *server_buf;                                                
  12271.              char   *client_buf;                                                
  12272.               int    mybufl;                                                    
  12273.               int    nbytes;                                                    
  12274.               int    ibuflen;                                                   
  12275.               int    bytes_returned;                                            
  12276.               int    buf_index;                                                 
  12277.          SOCKETNO    ns;                                                        
  12278.              Bool    time_to_go_home;                                           
  12279.              Bool    server_has_something_pending;                              
  12280.              Bool    server_finished_replying;                                  
  12281.              Bool    sending_text;                                              
  12282.              Bool    receiving_text;                                            
  12283.              Bool    dont_read;                                                 
  12284.              Bool    connected_to_server;                                       
  12285.              Bool    connection_broken;                                         
  12286.              Bool    closing_connection;                                        
  12287.              Bool    reconnect_in_progress;                                     
  12288.              char    buf [READ_BYTES];                                          
  12289.                    };                                                           
  12290.                                                                                 
  12291.                                                                                 
  12292. struct ggcb {                                                                   
  12293.              char    *gopher_command;                                           
  12294.              char    *extract_separator_line;                                   
  12295.              char    *mytelnet;                                                 
  12296.              char    *mydomain;                                                 
  12297.              FILE    *debug_file;                                               
  12298.              FILE    *extract_file;                                             
  12299.   struct recvstruct  *recvp;                                                    
  12300.   struct extraction  *extractionp;                                              
  12301.   struct gopherinfo  *ginfo;                                                    
  12302. #ifdef FETCH                                                                    
  12303.               int   (*isplink_pointer)();                                       
  12304.               int   (*ispexec_pointer)();                                       
  12305. #endif                                                                          
  12306.               int     ispfrc;                                                   
  12307.               int     text_find_left_bound;                                     
  12308.               int     text_find_right_bound;                                    
  12309.               int     myport;                                                   
  12310.              Bool     test_mode;                                                
  12311.              Bool     debug_mode;                                               
  12312.              Bool     quit;                                                     
  12313.              Bool     local_mode;                                               
  12314.              Bool     extract_tab_expanding;                                    
  12315.              Bool     extract_appending;                                        
  12316.              Bool     extract_blank_before_separator;                           
  12317.              Bool     extract_write_error;                                      
  12318.              Bool     extract_close_error;                                      
  12319.              Bool     warn_overwrite;                                           
  12320.              Bool     warn_append;                                              
  12321.              Bool     setmsg;                                                   
  12322.              Bool     autoscroll;                                               
  12323.              Bool     autocursor;                                               
  12324.              Bool     setcursor;                                                
  12325.              Bool     printing;                                                 
  12326.         IPADDRESS     client_ip_address;                                        
  12327.         IPADDRESS     server_ip_address;                                        
  12328.    struct texthdr     thdr;                                                     
  12329.    struct connection  gopher_connection;                                        
  12330.              char     client_ip_addrstr   [16];                                 
  12331.              char     server_ip_addrstr   [16];                                 
  12332.              char     ggserver            [MAXHOSTNAMELEN+1];                   
  12333.              char     ggclient            [MAXHOSTNAMELEN+1];                   
  12334.              char     client_hostname     [MAXHOSTNAMELEN+1];                   
  12335.              char     server_hostname     [MAXHOSTNAMELEN+1];                   
  12336.              char     text_find_string    [81];                                 
  12337.              char     text_dispchar;                                            
  12338.              char     text_find_what;                                           
  12339.              char     text_find_type;                                           
  12340.              char     text_find_trans;                                          
  12341.              char     current_bookmark_ds [65];                                 
  12342.             };                                                                  
  12343.                                                                                 
  12344. #ifdef MVS                                                                      
  12345. #ifndef I370                                                                    
  12346. extern char                 ebcdictoascii[];                                    
  12347. extern char                 asciitoebcdic[];                                    
  12348. #endif                                                                          
  12349. #endif                                                                          
  12350.                                                                                 
  12351. #ifndef FETCH                                                                   
  12352. extern int                  isplink();                                          
  12353. extern int                  ispexec();                                          
  12354. #endif                                                                          
  12355.                                                                                 
  12356. #ifdef   ISPFV3                                                                 
  12357. #define  ZERRLM_SIZE          513                                               
  12358. #else                                                                           
  12359. #define  ZERRLM_SIZE          73                                                
  12360. #endif                                                                          
  12361.                                                                                 
  12362. #define  NOTIFY_MSG   1                                                         
  12363. #define  WARNING_MSG  2                                                         
  12364. #define  CRITICAL_MSG 3                                                         
  12365.                                                                                 
  12366. #define  WARN1(X)           GGMpmsg(gp,NOTIFY_MSG,NULL,X)                       
  12367. #define  WARN2(X,Y)         GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y)                     
  12368. #define  WARN3(X,Y,Z)       GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y,Z)                   
  12369. #define  WARN4(X,Y,Z,W)     GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y,Z,W)                 
  12370. #define  ERR1(X)            GGMpmsg(gp,WARNING_MSG,NULL,X)                      
  12371. #define  ERR2(X,Y)          GGMpmsg(gp,WARNING_MSG,NULL,X,Y)                    
  12372. #define  ERR3(X,Y,Z)        GGMpmsg(gp,WARNING_MSG,NULL,X,Y,Z)                  
  12373. #define  ERR4(X,Y,Z,W)      GGMpmsg(gp,WARNING_MSG,NULL,X,Y,Z,W)                
  12374. #define  CRIT1(X)           GGMpmsg(gp,CRITICAL_MSG,NULL,X)                     
  12375. #define  CRIT2(X,Y)         GGMpmsg(gp,CRITICAL_MSG,NULL,X,Y)                   
  12376. #define  CRIT3(X,Y,Z)       GGMpmsg(gp,CRITICAL_MSG,NULL,X,Y,Z)                 
  12377.                                                                                 
  12378. #define  GETMAIN(Ptr,Typ,Siz,For) \                                             
  12379.          GGMgetm(gp,(char **)&(Ptr),(sizeof(Typ))*(Siz),For)                    
  12380.                                                                                 
  12381. #define  FREEMAIN(Ptr,For)    if (Ptr) {GGMfreem(gp,(char *)Ptr,For);}          
  12382.                                                                                 
  12383. #ifndef I370                                                                    
  12384.                                                                                 
  12385. #define  WRITE_FILEMODE     "w,recfm=vb,lrecl=259,blksize=6233"                 
  12386. #define  APPEND_FILEMODE    "a,recfm=vb,lrecl=259,blksize=6233"                 
  12387. #define  SYSOUT_FILEMODE    "w,recfm=vba,lrecl=133"                             
  12388. #define  FILEMODE             "recfm=vb,lrecl=259,blksize=6233"                 
  12389. #define  FILEMODE_A           "recfm=vba,lrecl=133"                             
  12390.                                                                                 
  12391. #define  OPEN_TEXT_FILE_FOR_WRITE(F)  \                                         
  12392.          fopen((F),WRITE_FILEMODE)                                              
  12393.                                                                                 
  12394. #define  OPEN_TEXT_FILE_FOR_APPEND(F)  \                                        
  12395.          fopen((F),APPEND_FILEMODE)                                             
  12396.                                                                                 
  12397. #define  OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                             
  12398.          fopen((F),(B) ? APPEND_FILEMODE : WRITE_FILEMODE)                      
  12399.                                                                                 
  12400. #define  OPEN_OUTPUT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                           
  12401.          fopen((F),(B) ? "a" : WRITE_FILEMODE)                                  
  12402.                                                                                 
  12403. #define  OPEN_SYSOUT_FILE(F)  \                                                 
  12404.          fopen((F),SYSOUT_FILEMODE)                                             
  12405.                                                                                 
  12406. #define  TEST_IF_FILE_EXISTS(P,F)  (P=fopen((F),"r"))                           
  12407. #define  CLEANUP_IF_FILE_EXISTS(P) (void)fclose(P)                              
  12408.                                                                                 
  12409. #else                                                                           
  12410.                                                                                 
  12411. #define  WRITE_FILEMODE     "w,recfm=v,lrecl=255,blksize=6233"                  
  12412. #define  APPEND_FILEMODE    "a,recfm=v,lrecl=255,blksize=6233"                  
  12413. #define  SYSOUT_FILEMODE    "w,recfm=va,lrecl=133"                              
  12414. #define  FILEMODE             "recfm=v,lrecl=255,blksize=6233"                  
  12415. #define  FILEMODE_A           "recfm=va,lrecl=133"                              
  12416.                                                                                 
  12417. #define  OPEN_TEXT_FILE_FOR_WRITE(F)  \                                         
  12418.          afopen((F),"w","seq",FILEMODE)                                         
  12419.                                                                                 
  12420. #define  OPEN_TEXT_FILE_FOR_APPEND(F)  \                                        
  12421.          afopen((F),"a","seq",FILEMODE)                                         
  12422.                                                                                 
  12423. #define  OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                             
  12424.          afopen((F),(B)?"a":"w","seq",FILEMODE)                                 
  12425.                                                                                 
  12426. #define  OPEN_OUTPUT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                           
  12427.          afopen((F),(B)?"a":"w","seq",FILEMODE)                                 
  12428.                                                                                 
  12429. #define  OPEN_SYSOUT_FILE(F)  \                                                 
  12430.          afopen((F),"w","seq",FILEMODE_A)                                       
  12431.                                                                                 
  12432. #define  TEST_IF_FILE_EXISTS(F,P)  (access((F),0) == 0)                         
  12433. #define  CLEANUP_IF_FILE_EXISTS(P) /* */                                        
  12434.                                                                                 
  12435. #endif                                                                          
  12436.                                                                                 
  12437. #define ebdtoasc(C) {char *__cp;\                                               
  12438.                      for(__cp = C;*__cp;__cp++) *__cp = EtoA(*__cp);}           
  12439.                                                                                 
  12440. #define asctoebd(C) {char *__cp;\                                               
  12441.                      for(__cp = C;*__cp;__cp++) *__cp = AtoE(*__cp);}           
  12442.                                                                                 
  12443. #define uppercase_in_place(C) {char *__cp;\                                     
  12444.                      for(__cp=C;*__cp;__cp++) *__cp = toupper(*__cp);}          
  12445.                                                                                 
  12446. #define lowercase_in_place(C) {char *__cp;\                                     
  12447.                      for(__cp=C;*__cp;__cp++) *__cp = tolower(*__cp);}          
  12448.                                                                                 
  12449. #define copy_uppercase(A,B) {char *__cA,*__cB;\                                 
  12450.                      for (__cA=A,__cB=B; *__cB;__cA++,__cB++)\                  
  12451.                          *__cA = toupper(*__cB);\                               
  12452.                      *__cA='\0';}                                               
  12453.                                                                                 
  12454. #define copy_lowercase(A,B) {char *__cA,*__cB;\                                 
  12455.                      for (__cA=A,__cB=B; *__cB;__cA++,__cB++)\                  
  12456.                          *__cA = tolower(*__cB);\                               
  12457.                      *__cA='\0';}                                               
  12458.                                                                                 
  12459. #define copy_uppercase_and_strip_trailing(A,B,C) {char *__cA,*__cB;\            
  12460.                      for (__cA=A,__cB=B; *__cB;__cA++,__cB++)\                  
  12461.                          *__cA = toupper(*__cB);\                               
  12462.                      for (; __cA>A && isspace(*(__cA-1)); __cA--);\             
  12463.                      *__cA='\0';C=__cA;}                                        
  12464.                                                                                 
  12465. #define copy_lowercase_and_strip_trailing(A,B,C) {char *__cA,*__cB;\            
  12466.                      for (__cA=A,__cB=B; *__cB;__cA++,__cB++)\                  
  12467.                          *__cA = tolower(*__cB);\                               
  12468.                      for (; __cA>A && isspace(*(__cA-1)); __cA--);\             
  12469.                      *__cA='\0';C=__cA;}                                        
  12470.                                                                                 
  12471. #define skip_whitespace(C)        (C) + strspn((C)," \t")                       
  12472. #define skip_ISPF_whitespace(C)   (C) + strspn((C)," ,\t")                      
  12473. #define find_whitespace(A,B)      if (!(A=strpbrk((B)," \t")))\                 
  12474.                                      A = strchr((B),'\0');                      
  12475. #define find_ISPF_whitespace(A,B) if (!(A=strpbrk((B)," ,\t")))\                
  12476.                                      A = strchr((B),'\0');                      
  12477.                                                                                 
  12478.                                                                                 
  12479. /****** Procedure and function declarations. *************************/         
  12480.                                                                                 
  12481. extern enum data_set_type  GGMalloc(char *, char *, enum data_set_type,         
  12482.                                                                   int);         
  12483. extern void                GGMbtext(struct ggcb *, struct texthdr *,            
  12484.                                                                FILE *);         
  12485. extern void                GGMclrtx(struct ggcb *,struct gopherinfo *);         
  12486. extern Bool                GGMconn (struct ggcb *,struct connection *);         
  12487. extern char               *GGMcopy (struct ggcb *, char *);                     
  12488. extern Bool                GGMcso  (struct ggcb *,struct gopherinfo *,          
  12489.                                                                  Fool);         
  12490. extern Bool                GGMdbm  (struct ggcb *,struct gopherinfo *);         
  12491. extern void                GGMdfail(int,__S99parms *);                          
  12492. extern Bool                GGMdir  (struct ggcb *,struct gopherinfo *,          
  12493.                                                                  Fool);         
  12494. extern void                GGMdisc (struct ggcb *,struct connection *);         
  12495. extern int                 GGMdispl(struct ggcb *, char *);                     
  12496. extern void                GGMdump (struct ggcb *,char *, char *, int);         
  12497. extern void                GGMesrvr(struct ggcb *,struct connection *);         
  12498. extern void                GGMfreem(struct ggcb *,char *,char *);               
  12499. extern FILE               *GGMgetds(struct ggcb *,struct extraction *);         
  12500. extern void                GGMgetm (struct ggcb *,char **,int,char *);          
  12501. extern Bool                GGMgofor(struct ggcb *,struct gopherinfo *,          
  12502.                                                                 Fool);          
  12503. extern Bool                GGMgsrvl(struct ggcb *,struct connection *,          
  12504.                                                         char **, Fool);         
  12505. extern void                GGMierr (struct ggcb *);                             
  12506. extern int                 GGMiget (struct ggcb *, char *);                     
  12507. extern void                GGMimsg (struct ggcb *, char *);                     
  12508. extern Bool                GGMinfo (struct ggcb *, struct gopherinfo *);        
  12509. extern Bool                GGMispf (struct ggcb *, char *);                     
  12510. extern Bool                GGMivget(struct ggcb *, char *, char *,int);         
  12511. extern Bool                GGMivput(struct ggcb *, char *, char *,int);         
  12512. extern Bool                GGMmenu (struct ggcb *, char *);                     
  12513. extern void                GGMmtfer(int, char*);                                
  12514. extern struct textline    *GGMouttx(struct ggcb *, char *,                      
  12515.                                                   struct gopherinfo *);         
  12516. extern Bool                GGMouts (struct recvstruct *, char *);               
  12517. extern Bool                GGMproc (struct recvstruct *);                       
  12518. extern void                GGMrbfm (struct ggcb *);                             
  12519. extern void                GGMrperr(struct ggcb *);                             
  12520. extern Bool                GGMsockt(struct ggcb *,struct connection *);         
  12521. extern void                GGMsopt (struct ggcb *,enum user_option);            
  12522. extern char               *GGMstrlc(char *, char *);                            
  12523. extern Bool                GGMtnet (struct ggcb *,struct gopherinfo *,          
  12524.                                                                  Fool);         
  12525. extern int                 GGMtso  (char *);                                    
  12526. extern char               *GGMtype (gophertype);                                
  12527. extern Bool                GGMunalc(char *);                                    
  12528. extern Bool                GGMvtx  (struct ggcb *,struct gopherinfo *,          
  12529.                                                                  Fool);         
  12530. extern Bool                GGMwais (struct ggcb *,struct gopherinfo *,          
  12531.                                                                  Fool);         
  12532. extern Bool                GGMwhois(struct ggcb *,struct gopherinfo *,          
  12533.                                                                  Fool);         
  12534. extern Bool                GGMxlist(struct ggcb *,char *);                      
  12535. extern Bool                GGMxtx  (struct ggcb *,struct gopherinfo *,          
  12536.                                                                EXTREQ);         
  12537.                                                                                 
  12538. #ifndef SUPPRESS_V_DECLARATION                                                  
  12539. extern void                GGMpmsg (struct ggcb *,int,char *,char *,            
  12540.                                                                   ...);         
  12541. #endif                                                                          
  12542.                                                                                 
  12543. ./   ADD NAME=GGSASC                                                            
  12544.                                                                                 
  12545.  /********************************************************************/         
  12546.  /*                                                                  */         
  12547.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12548.  /*                                                                  */         
  12549.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  12550.  /*                                                                  */         
  12551.  /* SAS modifications due to Dale Ingold at SAS Institute, Inc.      */         
  12552.  /*                                                                  */         
  12553.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12554.  /* including the implied warranties of merchantability and fitness, */         
  12555.  /* are expressly denied.                                            */         
  12556.  /*                                                                  */         
  12557.  /* Provided this copyright notice is included, this software may    */         
  12558.  /* be freely distributed and not offered for sale.                  */         
  12559.  /*                                                                  */         
  12560.  /* Changes or modifications may be made and used only by the maker  */         
  12561.  /* of same, and not further distributed.  Such modifications should */         
  12562.  /* be mailed to the author for consideration for addition to the    */         
  12563.  /* software and incorporation in subsequent releases.               */         
  12564.  /*                                                                  */         
  12565.  /********************************************************************/         
  12566.                                                                                 
  12567. /* ------------------- "ggsasc.h" include member ------------------- */         
  12568.                                                                                 
  12569. #ifdef SASC                                                                     
  12570.                                                                                 
  12571. #define I370                                                                    
  12572.                                                                                 
  12573. #include <dynam.h>                                                              
  12574.                                                                                 
  12575. #define FETCH                                                                   
  12576.                                                                                 
  12577.  __inline void (*fetch( const char *modname ))()                                
  12578.  {                                                                              
  12579.    void (*fpp)();                                                               
  12580.                                                                                 
  12581.    loadm( modname, &fpp );                                                      
  12582.    return( fpp );                                                               
  12583.  }                                                                              
  12584.                                                                                 
  12585.  __inline int (*release( void (*fpp)() ))                                       
  12586.  {                                                                              
  12587.    unloadm( fpp );                                                              
  12588.    return( 0 );                                                                 
  12589.  }                                                                              
  12590.                                                                                 
  12591.                                                                                 
  12592. #ifndef __SVC99                                                                 
  12593.                                                                                 
  12594.   #define __SVC99  1                                                            
  12595.                                                                                 
  12596.   #include <code.h>                                                             
  12597.                                                                                 
  12598.   struct __S99struc                                                             
  12599.     {                                                                           
  12600.       unsigned char   __S99RBLN;  /* length of request block..20      */        
  12601.       unsigned char   __S99VERB;  /* verb code                        */        
  12602.       unsigned short  __S99FLAG1; /* FLAGS1 field of SVC99 Req Block  */        
  12603.       unsigned short  __S99ERROR; /* error code field                 */        
  12604.       unsigned short  __S99INFO;  /* information reason code          */        
  12605.       void           *__S99TXTPP; /* address of text unit pointer list*/        
  12606.       int             __reserved; /* reserved..will always be 0       */        
  12607.       unsigned int    __S99FLAG2; /* FLAGS2 field..can only be filled */        
  12608.                                   /* in by APF authorized programs    */        
  12609.     };                                                                          
  12610.                                                                                 
  12611.   typedef struct __S99struc __S99parms;                                         
  12612.                                                                                 
  12613.   __inline int svc99(__S99parms* svc99parmlist)                                 
  12614.     { return( (_ldregs(R1, &svc99parmlist),                                     
  12615.                _code(0, 0x0a63),                                                
  12616.                _stregs(R15) ) );                                                
  12617.     }                                                                           
  12618.                                                                                 
  12619. #endif                                                                          
  12620.                                                                                 
  12621. #define FALSE 0                                                                 
  12622. #define TRUE  1                                                                 
  12623.                                                                                 
  12624. #include <lcio.h>                                                               
  12625.                                                                                 
  12626. #define  MAXHOSTNAMELEN     64                                                  
  12627.                                                                                 
  12628. #define  __ctest(X)  fprintf(stderr,\                                           
  12629.                      "GGMVS: CTEST is not supported by this compiler.")         
  12630.                                                                                 
  12631. #endif                                                                          
  12632.                                                                                 
  12633. ./   ADD NAME=GGUSER,SSI=01020033                                               
  12634.                                                                                 
  12635.  /********************************************************************/         
  12636.  /*                                                                  */         
  12637.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12638.  /*                                                                  */         
  12639.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  12640.  /*                                                                  */         
  12641.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12642.  /* including the implied warranties of merchantability and fitness, */         
  12643.  /* are expressly denied.                                            */         
  12644.  /*                                                                  */         
  12645.  /* Provided this copyright notice is included, this software may    */         
  12646.  /* be freely distributed and not offered for sale.                  */         
  12647.  /*                                                                  */         
  12648.  /* Changes or modifications may be made and used only by the maker  */         
  12649.  /* of same, and not further distributed.  Such modifications should */         
  12650.  /* be mailed to the author for consideration for addition to the    */         
  12651.  /* software and incorporation in subsequent releases.               */         
  12652.  /*                                                                  */         
  12653.  /********************************************************************/         
  12654.                                                                                 
  12655. /* ------------------- "gguser.h" include member ------------------- */         
  12656.                                                                                 
  12657. /* Include file for locally customized values. */                               
  12658.                                                                                 
  12659. /* Define levels of C/370 and TCP/IP.  This controls support for                
  12660.  * fetching of non-C load modules and socket error reporting.                   
  12661.  */                                                                             
  12662.                                                                                 
  12663. /* #define  C370V1    /* define this if C/370 Version 1 */                      
  12664.    #define  C370V2    /* define this if C/370 Version 2 or higher */            
  12665. /* #define  SASC      /* define this if SAS/C compiler */                       
  12666.                                                                                 
  12667. /* #define  TCPIPV1   /* define this if TCP/IP Version 1 */                     
  12668.    #define  TCPIPV2   /* define this if TCP/IP Version 2 or higher */           
  12669. /* #define  SNSTCPIP  /* define this if SNS/TCPAccess    */                     
  12670.                                                                                 
  12671. /* #define  ISPFV2    /* define this if ISPF Version 2 or earlier */            
  12672.    #define  ISPFV3    /* define this if ISPF Version 3 or later                 
  12673.                                                                                 
  12674. /*                                                                              
  12675.  * Define this if you want DEST, FORMS and UCB for print requests.              
  12676.  * Undefine it if you don't (you get just CLASS and COPIES).                    
  12677.  */                                                                             
  12678.                                                                                 
  12679.    #define FULLSYSOUT                                                           
  12680. /* #undef  FULLSYSOUT */                                                        
  12681.                                                                                 
  12682. /* Define the following defaults for your installation. */                      
  12683. /* Use XTELNET if you like the CSOCK package from UCLA. */                      
  12684.                                                                                 
  12685.    #define  TELNET_COMMAND_NAME     "TELNET"                                    
  12686. /* #define  TELNET_COMMAND_NAME     "XTELNET" */                                
  12687.                                                                                 
  12688. /* Define this if the server host name set by the "+" frob                      
  12689.  * should have the domain name appended.  Note that this will                   
  12690.  * affect how the hostname needs to be specified for a                          
  12691.  * Path=(pdsmember) specification - it must match the local host                
  12692.  * the way it is generated here.  Of course, host=+ will do it anyway.          
  12693.  */                                                                             
  12694.                                                                                 
  12695.    #define  APPEND_DOMAIN_NAME_TO_SELF                                          
  12696. /* #undef   APPEND_DOMAIN_NAME_TO_SELF */                                       
  12697.                                                                                 
  12698. /*                                                                              
  12699.  * Turn on for TCP-level debugging output (you probably don't want to           
  12700.  * unless your TCP/IP stuff is really broken and I can't help you).             
  12701.  */                                                                             
  12702.                                                                                 
  12703. /* #define DEBUG       */                                                       
  12704.    #undef  DEBUG                                                                
  12705.                                                                                 
  12706. /*                                                                              
  12707.  * Turn on for MTF-level debugging output.                                      
  12708.  */                                                                             
  12709.                                                                                 
  12710. /* #define DEBUGMTF    */                                                       
  12711.    #undef  DEBUGMTF                                                             
  12712.                                                                                 
  12713. /* Server and MTF stuff. */                                                     
  12714.                                                                                 
  12715. /* #define  MTF_TASKS           8 */                                            
  12716. #define  MTF_TASKS           1  /* lest REXX multitasking lossage */            
  12717. #define  TCP_QUEUE_LENGTH   20                                                  
  12718. #define  SERV_TCP_PORT      70                                                  
  12719. #define  CONNECT_TIME_OUT   60                                                  
  12720. #define  DEFAULT_DIRECTORY  "DD:GGGOPHER"                                       
  12721. #define  ACCESS_TABLE       "DD:GGACCESS"                                       
  12722. #define  DEBUG_FILE         "DD:GGDEBUG"                                        
  12723. #define  PARAMETER_FILE     "DD:GGPARMS"                                        
  12724. #define  MY_DOMAIN_SUFFIX   ".DRAPER.COM"                                       
  12725.                                                                                 
  12726. /* note: could get MY_DOMAIN_SUFFIX from TCPIP startup - what call? */          
  12727.                                                                                 
  12728. /* Client stuff. */                                                             
  12729.                                                                                 
  12730. #define  INITIAL_TYPE   GOPHER_DIRECTORY                                        
  12731. #define  INITIAL_PORT   GOPHER_PORT_NUMBER                                      
  12732. #define  INITIAL_PATH   ""                                                      
  12733. #define  INITIAL_HOST   "MVS.DRAPER.COM"                                        
  12734. #define  INITIAL_DESC   "Root"                                                  
  12735.                                                                                 
  12736. /* Server and client stuff. */                                                  
  12737.                                                                                 
  12738. #define  IDENT_HOST_FROB    "+"                                                 
  12739. #define  LOCAL_HOST_FROB    "-"                                                 
  12740.                                                                                 
  12741. /********************************************************************/          
  12742. /*  following are "gopher" record types.   */                                   
  12743. /********************************************************************/          
  12744.                                                                                 
  12745. #define  GFILE    '0'                                                           
  12746. #define  MENU     '1'                                                           
  12747. #define  ERROR    '2'                                                           
  12748. #define  INDEX    '7'                                                           
  12749. #define  TELNET   '8'                                                           
  12750. #define  TN3270   'T'                                                           
  12751. #define  WHOIS    'w'                                                           
  12752.                                                                                 
  12753. /********************************************************************/          
  12754. /* following are MVS file type identifiers.  They must appear at the            
  12755.    beginning of the file they're identifying.                        */         
  12756. /********************************************************************/          
  12757.                                                                                 
  12758. #define  MENUIDENT    "GOPHER_MENU"                                             
  12759. #define  INDEXIDENT   "GOPHER_INDEX"                                            
  12760.                                                                                 
  12761. /********************************************************************/          
  12762. /*  following are tokens for menu GOPHER identifiers.    */                     
  12763. /********************************************************************/          
  12764.                                                                                 
  12765. #define  TOKTYPE      "TYPE"                                                    
  12766. #define  TYPETOK      0                                                         
  12767. #define  TOKNAME      "NAME"                                                    
  12768. #define  NAMETOK      1                                                         
  12769. #define  TOKPATH      "PATH"                                                    
  12770. #define  PATHTOK      2                                                         
  12771. #define  TOKHOST      "HOST"                                                    
  12772. #define  HOSTTOK      3                                                         
  12773. #define  TOKPORT      "PORT"                                                    
  12774. #define  PORTTOK      4                                                         
  12775. #define  TOKEND       "END"                                                     
  12776. #define  ENDTOK       5                                                         
  12777. #define  TOKCOMMENT   "*"                                                       
  12778. #define  COMMENTTOK   6                                                         
  12779.                                                                                 
  12780. #define  TOKDISPLAY   "DISPLAY"                                                 
  12781. #define  DISPLAYTOK   7                                                         
  12782. #define  TOKSELECT    "SELECTOR"                                                
  12783. #define  SELECTTOK    8                                                         
  12784.                                                                                 
  12785. /********************************************************************/          
  12786. /*  types of   "types" - operands of the TYPE keyword in directories.*/         
  12787. /********************************************************************/          
  12788.                                                                                 
  12789. #define  TYPEFILE    "FILE"                                                     
  12790. #define  TYPEMENU    "DIRECTORY"                                                
  12791. #define  TYPEINDEX   "INDEX"                                                    
  12792. #define  TYPETELNET  "TELNET"                                                   
  12793. #define  TYPETN3270  "TN3270"                                                   
  12794. #define  TYPEWHOIS   "WHOIS"                                                    
  12795.                                                                                 
  12796. /********************************************************************/          
  12797. /*  used by the REXX Interface                                      */          
  12798. /********************************************************************/          
  12799.                                                                                 
  12800.   /* Be sure to include all 8 bytes, including blanks, in below */              
  12801.                                                                                 
  12802. #define  REXX_EXEC_LIBRARY_DDNAME   "GGEXEC  "                                  
  12803. #define  REXX_EXEC_SUBCOM           "        "                                  
  12804.                                                                                 
  12805. ./ ENDUP                                                                        
  12806. ?!                                                                              
  12807. //PANELS   EXEC GGLOAD,TRK1='5',TO='PANELS'                                     
  12808. //SYSIN    DD DATA,DLM='?!'                                                     
  12809. ./   ADD NAME=GGM,SSI=01060053                                                  
  12810. )ATTR                                                                           
  12811. /*                                                                   /*         
  12812. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  12813. /*                                                                   /*         
  12814. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  12815. /* including the implied warranties of merchantability and fitness,  /*         
  12816. /* are expressly denied.                                             /*         
  12817. /*                                                                   /*         
  12818. /* Provided this copyright notice is included, this software may     /*         
  12819. /* be freely distributed and not offered for sale.                   /*         
  12820. /*                                                                   /*         
  12821. /* Changes or modifications may be made and used only by the maker   /*         
  12822. /* of same, and not further distributed.  Such modifications should  /*         
  12823. /* be mailed to the author for consideration for addition to the     /*         
  12824. /* software and incorporation in subsequent releases.                /*         
  12825. /*                                                                   /*         
  12826.  ^ TYPE(INPUT) INTENS(HIGH) COLOR(GREEN) CAPS(OFF)                              
  12827.  ! TYPE(TEXT)  INTENS(HIGH) COLOR(RED)                                          
  12828. )BODY EXPAND(``)                                                                
  12829. %-`-`-  MVS Gopher Client -`-`-                                                 
  12830. %COMMAND ===>_ZCMD                                                              
  12831. +                                                                               
  12832. %Gopher server host name+(or IP address) %===>_GGHOST                           
  12833. +                                                                               
  12834. %Initial path%===>^GGPATH                                                       
  12835. %Port number %===>_GGPORT                                                       
  12836. +                                                                               
  12837. +Note:  You may specify a dash%-+as the Gopher server host name if              
  12838.         you want to use your own private Gopher data without making             
  12839.         a connection to a server.  If you do, you must specify the              
  12840.         name of your private Gopher menu in the initial path.                   
  12841.         This name must be UNQUOTED AND FULLY QUALIFIED.                         
  12842.         Alternatively, you may allocate your initial Gopher menu                
  12843.         to file GGGOPHER.                                                       
  12844.                                                                                 
  12845.         Any menu entries must also specify a dash in the host field;            
  12846.         otherwise they will require server access, as usual.                    
  12847.                                                                                 
  12848.         To use the REXX interface, you must allocate file GGEXEC to             
  12849.         your library of Gopherable REXX execs.                                  
  12850.                                                                                 
  12851. +Press!END+key to leave this menu.                                              
  12852. )INIT                                                                           
  12853.  &ZCMD = &Z                                                                     
  12854.  IF (&GGPORT = &Z) &GGPORT = 70                                                 
  12855. )PROC                                                                           
  12856.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  12857.  VER (&GGHOST,NB)                                                               
  12858.  VER (&GGPORT,NUM)                                                              
  12859.  VPUT (GGHOST GGPATH GGPORT) PROFILE                                            
  12860. )END                                                                            
  12861. ./   ADD NAME=GGMDIR,SSI=01040015                                               
  12862. )ATTR                                                                           
  12863. /*                                                                   /*         
  12864. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  12865. /*                                                                   /*         
  12866. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  12867. /* including the implied warranties of merchantability and fitness,  /*         
  12868. /* are expressly denied.                                             /*         
  12869. /*                                                                   /*         
  12870. /* Provided this copyright notice is included, this software may     /*         
  12871. /* be freely distributed and not offered for sale.                   /*         
  12872. /*                                                                   /*         
  12873. /* Changes or modifications may be made and used only by the maker   /*         
  12874. /* of same, and not further distributed.  Such modifications should  /*         
  12875. /* be mailed to the author for consideration for addition to the     /*         
  12876. /* software and incorporation in subsequent releases.                /*         
  12877. /*                                                                   /*         
  12878.  ~ TYPE(INPUT) INTENS(HIGH)  CAPS(OFF) JUST(LEFT)                               
  12879.  ^ TYPE(INPUT) INTENS(HIGH)  CAPS(OFF) JUST(LEFT)                               
  12880.  ! TYPE(OUTPUT) INTENS(LOW)  CAPS(OFF) JUST(RIGHT) COLOR(YELLOW)                
  12881.  # TYPE(OUTPUT) INTENS(LOW)  CAPS(OFF) JUST(RIGHT) COLOR(BLUE)                  
  12882.  @ TYPE(OUTPUT) INTENS(HIGH) CAPS(OFF) JUST(RIGHT) COLOR(PINK)                  
  12883.  ? TYPE(OUTPUT) INTENS(LOW)  CAPS(OFF) JUST(LEFT)  COLOR(TURQ) PAD('.')         
  12884.  |  AREA(DYNAMIC) EXTEND(ON) SCROLL(ON)                                         
  12885.  \  AREA(DYNAMIC) EXTEND(OFF) SCROLL(OFF)                                       
  12886.  01 TYPE(DATAOUT) INTENS(LOW)                                                   
  12887.  02 TYPE(DATAOUT) INTENS(HIGH)                                                  
  12888.  03 TYPE(DATAIN)  INTENS(LOW)                                                   
  12889.  04 TYPE(DATAIN)  INTENS(HIGH)                                                  
  12890.  05 TYPE(DATAOUT) COLOR(GREEN)                                                  
  12891.  06 TYPE(DATAOUT) COLOR(PINK)                                                   
  12892.  07 TYPE(DATAOUT) COLOR(RED)                                                    
  12893.  08 TYPE(DATAOUT) COLOR(TURQ)                                                   
  12894.  09 TYPE(DATAOUT) COLOR(YELLOW)                                                 
  12895.  0A TYPE(DATAIN)  COLOR(BLUE)                                                   
  12896.  0B TYPE(DATAIN)  COLOR(PINK)                                                   
  12897.  0C TYPE(DATAIN)  COLOR(TURQ)                                                   
  12898.  0D TYPE(DATAIN)  COLOR(WHITE)                                                  
  12899.  0E TYPE(DATAIN)  COLOR(YELLOW)                                                 
  12900. )BODY EXPAND(``)                                                                
  12901. %&GGGHEAD                                                                       
  12902. %COMMAND ===>~GGGCMD                                          %SCROLL ===>^GAMT+
  12903. +                                                                               
  12904. +%S+Select%Q+Query%E+Extract%P+Print%B+Bookmark%I+Info                          
  12905.  -------------------------------------------------------------------------------
  12906. |GGGDYNA                                                                       |
  12907. )INIT                                                                           
  12908.  IF (&GAMT = &Z) &GAMT = CSR                                                    
  12909. )PROC                                                                           
  12910.  &GGGLVL = LVLINE(GGGDYNA)                                                      
  12911.  VPUT (GAMT) PROFILE                                                            
  12912. )END                                                                            
  12913. ./   ADD NAME=GGMLCONN,SSI=01010026                                             
  12914. )ATTR                                                                           
  12915. /*                                                                   /*         
  12916. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  12917. /*                                                                   /*         
  12918. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  12919. /* including the implied warranties of merchantability and fitness,  /*         
  12920. /* are expressly denied.                                             /*         
  12921. /*                                                                   /*         
  12922. /* Provided this copyright notice is included, this software may     /*         
  12923. /* be freely distributed and not offered for sale.                   /*         
  12924. /*                                                                   /*         
  12925. /* Changes or modifications may be made and used only by the maker   /*         
  12926. /* of same, and not further distributed.  Such modifications should  /*         
  12927. /* be mailed to the author for consideration for addition to the     /*         
  12928. /* software and incorporation in subsequent releases.                /*         
  12929. /*                                                                   /*         
  12930.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  12931.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  12932.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  12933.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  12934.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  12935.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  12936.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  12937. )BODY EXPAND(``)                                                                
  12938. %-`-`-  MVS Gopher Server Connection -`-`-                                      
  12939. +                                                                               
  12940. +             Client name: &CLIENT                                              
  12941. +                                                                               
  12942. +                                                                               
  12943. +             Connection is in progress for Gopher server at:                   
  12944.               &SERVER                                                           
  12945. +                                                                               
  12946. +