home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume42 / alex / part08 < prev    next >
Encoding:
Internet Message Format  |  1994-03-30  |  89.3 KB

  1. From: vac@CS.CMU.EDU (Vincent.Cate)
  2. Newsgroups: comp.sources.misc
  3. Subject: v42i046:  alex - NFS/FTP global filesystem, Part08/13
  4. Date: 30 Mar 1994 20:54:52 -0600
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <2nde1s$j64@sparky.sterling.com>
  9. X-Md4-Signature: 9754477db34f478547a3b6c4f811ae57
  10.  
  11. Submitted-by: vac@CS.CMU.EDU (Vincent.Cate)
  12. Posting-number: Volume 42, Issue 46
  13. Archive-name: alex/part08
  14. Environment: Most Unix machines - with 100 MB to 10 GB of free disk
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  alexsrvr/README alexsrvr/doc/intro.ps.A
  21. #   alexsrvr/src/phonehome.c alexsrvr/src/readinfo.c
  22. # Wrapped by kent@sparky on Tue Mar 29 21:56:21 1994
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 8 (of 13)."'
  26. if test -f 'alexsrvr/README' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'alexsrvr/README'\"
  28. else
  29.   echo shar: Extracting \"'alexsrvr/README'\" \(658 characters\)
  30.   sed "s/^X//" >'alexsrvr/README' <<'END_OF_FILE'
  31. X
  32. XJust go into "src" and read the README there for instructions on
  33. Xbuilding the code.  
  34. X
  35. X
  36. X
  37. XIn general you probably only care about:
  38. X
  39. X  bin/start.alex  -   Must be run as root
  40. X                      Starts up everything 
  41. X                 
  42. X  bin/mountalex   -   Run as root on client machines 
  43. X                      (server machine can also be a client)
  44. X
  45. X  bin/stop.alex   -   Stop everything
  46. X
  47. X
  48. X
  49. X  src/getalex     -   If in src you do a "make new" this will be run.
  50. X                      It will get a new version of Alex and install it.
  51. X                      If it has not been too long since you got a version
  52. X                      you can do "make patch". 
  53. X
  54. X
  55. END_OF_FILE
  56.   if test 658 -ne `wc -c <'alexsrvr/README'`; then
  57.     echo shar: \"'alexsrvr/README'\" unpacked with wrong size!
  58.   fi
  59.   # end of 'alexsrvr/README'
  60. fi
  61. if test -f 'alexsrvr/doc/intro.ps.A' -a "${1}" != "-c" ; then 
  62.   echo shar: Will not clobber existing file \"'alexsrvr/doc/intro.ps.A'\"
  63. else
  64.   echo shar: Extracting \"'alexsrvr/doc/intro.ps.A'\" \(43326 characters\)
  65.   sed "s/^X//" >'alexsrvr/doc/intro.ps.A' <<'END_OF_FILE'
  66. X%!
  67. X%%BoundingBox: (atend)
  68. X%%Pages: (atend)
  69. X%%DocumentFonts: (atend)
  70. X%%EndComments
  71. X%
  72. X% FrameMaker PostScript Prolog 3.0, for use with FrameMaker 3.0
  73. X% Copyright (c) 1986,87,89,90,91 by Frame Technology Corporation.
  74. X% All rights reserved.
  75. X%
  76. X% Known Problems:
  77. X%    Due to bugs in Transcript, the 'PS-Adobe-' is omitted from line 1
  78. X/FMversion (3.0) def 
  79. X% Set up Color vs. Black-and-White
  80. X    /FMPrintInColor systemdict /colorimage known
  81. X        systemdict /currentcolortransfer known or def
  82. X% Uncomment this line to force b&w on color printer
  83. X%   /FMPrintInColor false def
  84. X/FrameDict 195 dict def 
  85. Xsystemdict /errordict known not {/errordict 10 dict def
  86. X        errordict /rangecheck {stop} put} if
  87. X% The readline in 23.0 doesn't recognize cr's as nl's on AppleTalk
  88. XFrameDict /tmprangecheck errordict /rangecheck get put 
  89. Xerrordict /rangecheck {FrameDict /bug true put} put 
  90. XFrameDict /bug false put 
  91. Xmark 
  92. X% Some PS machines read past the CR, so keep the following 3 lines together!
  93. Xcurrentfile 5 string readline
  94. X00
  95. X0000000000
  96. Xcleartomark 
  97. Xerrordict /rangecheck FrameDict /tmprangecheck get put 
  98. XFrameDict /bug get { 
  99. X    /readline {
  100. X        /gstring exch def
  101. X        /gfile exch def
  102. X        /gindex 0 def
  103. X        {
  104. X            gfile read pop 
  105. X            dup 10 eq {exit} if 
  106. X            dup 13 eq {exit} if 
  107. X            gstring exch gindex exch put 
  108. X            /gindex gindex 1 add def 
  109. X        } loop
  110. X        pop 
  111. X        gstring 0 gindex getinterval true 
  112. X        } def
  113. X    } if
  114. X/FMVERSION {
  115. X    FMversion ne {
  116. X        /Times-Roman findfont 18 scalefont setfont
  117. X        100 100 moveto
  118. X        (FrameMaker version does not match postscript_prolog!)
  119. X        dup =
  120. X        show showpage
  121. X        } if
  122. X    } def 
  123. X/FMLOCAL {
  124. X    FrameDict begin
  125. X    0 def 
  126. X    end 
  127. X    } def 
  128. X    /gstring FMLOCAL
  129. X    /gfile FMLOCAL
  130. X    /gindex FMLOCAL
  131. X    /orgxfer FMLOCAL
  132. X    /orgproc FMLOCAL
  133. X    /organgle FMLOCAL
  134. X    /orgfreq FMLOCAL
  135. X    /yscale FMLOCAL
  136. X    /xscale FMLOCAL
  137. X    /manualfeed FMLOCAL
  138. X    /paperheight FMLOCAL
  139. X    /paperwidth FMLOCAL
  140. X/FMDOCUMENT { 
  141. X    array /FMfonts exch def 
  142. X    /#copies exch def
  143. X    FrameDict begin
  144. X    0 ne dup {setmanualfeed} if
  145. X    /manualfeed exch def
  146. X    /paperheight exch def
  147. X    /paperwidth exch def
  148. X    /yscale exch def
  149. X    /xscale exch def
  150. X    currenttransfer cvlit /orgxfer exch def
  151. X    currentscreen cvlit /orgproc exch def
  152. X    /organgle exch def /orgfreq exch def
  153. X    setpapername 
  154. X    desperatepapersize
  155. X    end 
  156. X    } def 
  157. X    /pagesave FMLOCAL
  158. X    /orgmatrix FMLOCAL
  159. X    /landscape FMLOCAL
  160. X/FMBEGINPAGE { 
  161. X    FrameDict begin 
  162. X    /pagesave save def
  163. X    3.86 setmiterlimit
  164. X    /landscape exch 0 ne def
  165. X    landscape { 
  166. X        90 rotate 0 exch neg translate pop 
  167. X        }
  168. X        {pop pop}
  169. X        ifelse
  170. X    xscale yscale scale
  171. X    /orgmatrix matrix def
  172. X    gsave 
  173. X    } def 
  174. X/FMENDPAGE {
  175. X    grestore 
  176. X    pagesave restore
  177. X    end 
  178. X    showpage
  179. X    } def 
  180. X/FMFONTDEFINE { 
  181. X    FrameDict begin
  182. X    findfont 
  183. X    ReEncode 
  184. X    1 index exch 
  185. X    definefont 
  186. X    FMfonts 3 1 roll 
  187. X    put
  188. X    end 
  189. X    } def 
  190. X/FMFILLS {
  191. X    FrameDict begin
  192. X    array /fillvals exch def
  193. X    end 
  194. X    } def 
  195. X/FMFILL {
  196. X    FrameDict begin
  197. X     fillvals 3 1 roll put
  198. X    end 
  199. X    } def 
  200. X/FMNORMALIZEGRAPHICS { 
  201. X    newpath
  202. X    0.0 0.0 moveto
  203. X    1 setlinewidth
  204. X    0 setlinecap
  205. X    0 0 0 sethsbcolor
  206. X    0 setgray 
  207. X    } bind def
  208. X    /fx FMLOCAL
  209. X    /fy FMLOCAL
  210. X    /fh FMLOCAL
  211. X    /fw FMLOCAL
  212. X    /llx FMLOCAL
  213. X    /lly FMLOCAL
  214. X    /urx FMLOCAL
  215. X    /ury FMLOCAL
  216. X/FMBEGINEPSF { 
  217. X    end 
  218. X    /FMEPSF save def 
  219. X    /showpage {} def 
  220. X    FMNORMALIZEGRAPHICS 
  221. X    [/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall 
  222. X    fx fy translate 
  223. X    rotate
  224. X    fw urx llx sub div fh ury lly sub div scale 
  225. X    llx neg lly neg translate 
  226. X    } bind def
  227. X/FMENDEPSF {
  228. X    FMEPSF restore
  229. X    FrameDict begin 
  230. X    } bind def
  231. XFrameDict begin 
  232. X/setmanualfeed {
  233. X%%BeginFeature *ManualFeed True
  234. X     statusdict /manualfeed true put
  235. X%%EndFeature
  236. X    } def
  237. X/max {2 copy lt {exch} if pop} bind def
  238. X/min {2 copy gt {exch} if pop} bind def
  239. X/inch {72 mul} def
  240. X/pagedimen { 
  241. X    paperheight sub abs 16 lt exch 
  242. X    paperwidth sub abs 16 lt and
  243. X    {/papername exch def} {pop} ifelse
  244. X    } def
  245. X    /papersizedict FMLOCAL
  246. X/setpapername { 
  247. X    /papersizedict 14 dict def 
  248. X    papersizedict begin
  249. X    /papername /unknown def 
  250. X        /Letter 8.5 inch 11.0 inch pagedimen
  251. X        /LetterSmall 7.68 inch 10.16 inch pagedimen
  252. X        /Tabloid 11.0 inch 17.0 inch pagedimen
  253. X        /Ledger 17.0 inch 11.0 inch pagedimen
  254. X        /Legal 8.5 inch 14.0 inch pagedimen
  255. X        /Statement 5.5 inch 8.5 inch pagedimen
  256. X        /Executive 7.5 inch 10.0 inch pagedimen
  257. X        /A3 11.69 inch 16.5 inch pagedimen
  258. X        /A4 8.26 inch 11.69 inch pagedimen
  259. X        /A4Small 7.47 inch 10.85 inch pagedimen
  260. X        /B4 10.125 inch 14.33 inch pagedimen
  261. X        /B5 7.16 inch 10.125 inch pagedimen
  262. X    end
  263. X    } def
  264. X/papersize {
  265. X    papersizedict begin
  266. X        /Letter {lettertray letter} def
  267. X        /LetterSmall {lettertray lettersmall} def
  268. X        /Tabloid {11x17tray 11x17} def
  269. X        /Ledger {ledgertray ledger} def
  270. X        /Legal {legaltray legal} def
  271. X        /Statement {statementtray statement} def
  272. X        /Executive {executivetray executive} def
  273. X        /A3 {a3tray a3} def
  274. X        /A4 {a4tray a4} def
  275. X        /A4Small {a4tray a4small} def
  276. X        /B4 {b4tray b4} def
  277. X        /B5 {b5tray b5} def
  278. X        /unknown {unknown} def
  279. X    papersizedict dup papername known {papername} {/unknown} ifelse get
  280. X    end
  281. X    /FMdicttop countdictstack 1 add def 
  282. X    statusdict begin stopped end 
  283. X    countdictstack -1 FMdicttop {pop end} for 
  284. X    } def
  285. X/manualpapersize {
  286. X    papersizedict begin
  287. X        /Letter {letter} def
  288. X        /LetterSmall {lettersmall} def
  289. X        /Tabloid {11x17} def
  290. X        /Ledger {ledger} def
  291. X        /Legal {legal} def
  292. X        /Statement {statement} def
  293. X        /Executive {executive} def
  294. X        /A3 {a3} def
  295. X        /A4 {a4} def
  296. X        /A4Small {a4small} def
  297. X        /B4 {b4} def
  298. X        /B5 {b5} def
  299. X        /unknown {unknown} def
  300. X    papersizedict dup papername known {papername} {/unknown} ifelse get
  301. X    end
  302. X    stopped 
  303. X    } def
  304. X/desperatepapersize {
  305. X    statusdict /setpageparams known
  306. X        {
  307. X        paperwidth paperheight 0 1 
  308. X        statusdict begin
  309. X        {setpageparams} stopped pop 
  310. X        end
  311. X        } if
  312. X    } def
  313. X/savematrix {
  314. X    orgmatrix currentmatrix pop
  315. X    } bind def
  316. X/restorematrix {
  317. X    orgmatrix setmatrix
  318. X    } bind def
  319. X/dmatrix matrix def
  320. X/dpi    72 0 dmatrix defaultmatrix dtransform
  321. X    dup mul exch   dup mul add   sqrt def
  322. X/freq dpi 18.75 div 8 div round dup 0 eq {pop 1} if 8 mul dpi exch div def
  323. X/sangle 1 0 dmatrix defaultmatrix dtransform exch atan def
  324. X/DiacriticEncoding [
  325. X/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
  326. X/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
  327. X/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
  328. X/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
  329. X/.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl
  330. X/numbersign /dollar /percent /ampersand /quotesingle /parenleft
  331. X/parenright /asterisk /plus /comma /hyphen /period /slash /zero /one
  332. X/two /three /four /five /six /seven /eight /nine /colon /semicolon
  333. X/less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K
  334. X/L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash
  335. X/bracketright /asciicircum /underscore /grave /a /b /c /d /e /f /g /h
  336. X/i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar
  337. X/braceright /asciitilde /.notdef /Adieresis /Aring /Ccedilla /Eacute
  338. X/Ntilde /Odieresis /Udieresis /aacute /agrave /acircumflex /adieresis
  339. X/atilde /aring /ccedilla /eacute /egrave /ecircumflex /edieresis
  340. X/iacute /igrave /icircumflex /idieresis /ntilde /oacute /ograve
  341. X/ocircumflex /odieresis /otilde /uacute /ugrave /ucircumflex
  342. X/udieresis /dagger /.notdef /cent /sterling /section /bullet
  343. X/paragraph /germandbls /registered /copyright /trademark /acute
  344. X/dieresis /.notdef /AE /Oslash /.notdef /.notdef /.notdef /.notdef
  345. X/yen /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
  346. X/ordfeminine /ordmasculine /.notdef /ae /oslash /questiondown
  347. X/exclamdown /logicalnot /.notdef /florin /.notdef /.notdef
  348. X/guillemotleft /guillemotright /ellipsis /.notdef /Agrave /Atilde
  349. X/Otilde /OE /oe /endash /emdash /quotedblleft /quotedblright
  350. X/quoteleft /quoteright /.notdef /.notdef /ydieresis /Ydieresis
  351. X/fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl
  352. X/periodcentered /quotesinglbase /quotedblbase /perthousand
  353. X/Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute
  354. X/Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve
  355. X/Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron
  356. X/breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron
  357. X] def
  358. X/ReEncode { 
  359. X    dup 
  360. X    length 
  361. X    dict begin 
  362. X    {
  363. X    1 index /FID ne 
  364. X        {def} 
  365. X        {pop pop} ifelse 
  366. X    } forall 
  367. X    0 eq {/Encoding DiacriticEncoding def} if 
  368. X    currentdict 
  369. X    end 
  370. X    } bind def
  371. X/graymode true def
  372. X    /bwidth FMLOCAL
  373. X    /bpside FMLOCAL
  374. X    /bstring FMLOCAL
  375. X    /onbits FMLOCAL
  376. X    /offbits FMLOCAL
  377. X    /xindex FMLOCAL
  378. X    /yindex FMLOCAL
  379. X    /x FMLOCAL
  380. X    /y FMLOCAL
  381. X/setpattern {
  382. X     /bwidth  exch def
  383. X     /bpside  exch def
  384. X     /bstring exch def
  385. X     /onbits 0 def  /offbits 0 def
  386. X     freq sangle landscape {90 add} if 
  387. X        {/y exch def
  388. X         /x exch def
  389. X         /xindex x 1 add 2 div bpside mul cvi def
  390. X         /yindex y 1 add 2 div bpside mul cvi def
  391. X         bstring yindex bwidth mul xindex 8 idiv add get
  392. X         1 7 xindex 8 mod sub bitshift and 0 ne
  393. X         {/onbits  onbits  1 add def 1}
  394. X         {/offbits offbits 1 add def 0}
  395. X         ifelse
  396. X        }
  397. X        setscreen
  398. X     {} settransfer
  399. X     offbits offbits onbits add div FMsetgray
  400. X    /graymode false def
  401. X    } bind def
  402. X/grayness {
  403. X    FMsetgray
  404. X    graymode not {
  405. X        /graymode true def
  406. X        orgxfer cvx settransfer
  407. X        orgfreq organgle orgproc cvx setscreen
  408. X        } if
  409. X    } bind def
  410. X    /HUE FMLOCAL
  411. X    /SAT FMLOCAL
  412. X    /BRIGHT FMLOCAL
  413. X    /Colors FMLOCAL
  414. XFMPrintInColor 
  415. X    
  416. X    {
  417. X    /HUE 0 def
  418. X    /SAT 0 def
  419. X    /BRIGHT 0 def
  420. X    % array of arrays Hue and Sat values for the separations [HUE BRIGHT]
  421. X    /Colors   
  422. X    [[0    0  ]    % black
  423. X     [0    0  ]    % white
  424. X     [0.00 1.0]    % red
  425. X     [0.37 1.0]    % green
  426. X     [0.60 1.0]    % blue
  427. X     [0.50 1.0]    % cyan
  428. X     [0.83 1.0]    % magenta
  429. X     [0.16 1.0]    % comment / yellow
  430. X     ] def
  431. X      
  432. X    /BEGINBITMAPCOLOR { 
  433. X        BITMAPCOLOR} def
  434. X    /BEGINBITMAPCOLORc { 
  435. X        BITMAPCOLORc} def
  436. X    /BEGINBITMAPTRUECOLOR { 
  437. X        BITMAPTRUECOLOR } def
  438. X    /BEGINBITMAPTRUECOLORc { 
  439. X        BITMAPTRUECOLORc } def
  440. X    /K { 
  441. X        Colors exch get dup
  442. X        0 get /HUE exch store 
  443. X        1 get /BRIGHT exch store
  444. X          HUE 0 eq BRIGHT 0 eq and
  445. X            {1.0 SAT sub setgray}
  446. X            {HUE SAT BRIGHT sethsbcolor} 
  447. X          ifelse
  448. X        } def
  449. X    /FMsetgray { 
  450. X        /SAT exch 1.0 exch sub store 
  451. X          HUE 0 eq BRIGHT 0 eq and
  452. X            {1.0 SAT sub setgray}
  453. X            {HUE SAT BRIGHT sethsbcolor} 
  454. X          ifelse
  455. X        } bind def
  456. X    }
  457. X    
  458. X    {
  459. X    /BEGINBITMAPCOLOR { 
  460. X        BITMAPGRAY} def
  461. X    /BEGINBITMAPCOLORc { 
  462. X        BITMAPGRAYc} def
  463. X    /BEGINBITMAPTRUECOLOR { 
  464. X        BITMAPTRUEGRAY } def
  465. X    /BEGINBITMAPTRUECOLORc { 
  466. X        BITMAPTRUEGRAYc } def
  467. X    /FMsetgray {setgray} bind def
  468. X    /K { 
  469. X        pop
  470. X        } def
  471. X    }
  472. Xifelse
  473. X/normalize {
  474. X    transform round exch round exch itransform
  475. X    } bind def
  476. X/dnormalize {
  477. X    dtransform round exch round exch idtransform
  478. X    } bind def
  479. X/lnormalize { 
  480. X    0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop
  481. X    } bind def
  482. X/H { 
  483. X    lnormalize setlinewidth
  484. X    } bind def
  485. X/Z {
  486. X    setlinecap
  487. X    } bind def
  488. X    /fillvals FMLOCAL
  489. X/X { 
  490. X    fillvals exch get
  491. X    dup type /stringtype eq
  492. X    {8 1 setpattern} 
  493. X    {grayness}
  494. X    ifelse
  495. X    } bind def
  496. X/V { 
  497. X    gsave eofill grestore
  498. X    } bind def
  499. X/N { 
  500. X    stroke
  501. X    } bind def
  502. X/M {newpath moveto} bind def
  503. X/E {lineto} bind def
  504. X/D {curveto} bind def
  505. X/O {closepath} bind def
  506. X    /n FMLOCAL
  507. X/L { 
  508. X     /n exch def
  509. X    newpath
  510. X    normalize
  511. X    moveto 
  512. X    2 1 n {pop normalize lineto} for
  513. X    } bind def
  514. X/Y { 
  515. X    L 
  516. X    closepath
  517. X    } bind def
  518. X    /x1 FMLOCAL
  519. X    /x2 FMLOCAL
  520. X    /y1 FMLOCAL
  521. X    /y2 FMLOCAL
  522. X    /rad FMLOCAL
  523. X/R { 
  524. X    /y2 exch def
  525. X    /x2 exch def
  526. X    /y1 exch def
  527. X    /x1 exch def
  528. X    x1 y1
  529. X    x2 y1
  530. X    x2 y2
  531. X    x1 y2
  532. X    4 Y 
  533. X    } bind def
  534. X/RR { 
  535. X    /rad exch def
  536. X    normalize
  537. X    /y2 exch def
  538. X    /x2 exch def
  539. X    normalize
  540. X    /y1 exch def
  541. X    /x1 exch def
  542. X    newpath
  543. X    x1 y1 rad add moveto
  544. X    x1 y2 x2 y2 rad arcto
  545. X    x2 y2 x2 y1 rad arcto
  546. X    x2 y1 x1 y1 rad arcto
  547. X    x1 y1 x1 y2 rad arcto
  548. X    closepath
  549. X    16 {pop} repeat
  550. X    } bind def
  551. X/C { 
  552. X    grestore
  553. X    gsave
  554. X    R 
  555. X    clip
  556. X    } bind def
  557. X    /FMpointsize FMLOCAL
  558. X/F { 
  559. X    FMfonts exch get
  560. X    FMpointsize scalefont
  561. X    setfont
  562. X    } bind def
  563. X/Q { 
  564. X    /FMpointsize exch def
  565. X    F 
  566. X    } bind def
  567. X/T { 
  568. X    moveto show
  569. X    } bind def
  570. X/RF { 
  571. X    rotate
  572. X    0 ne {-1 1 scale} if
  573. X    } bind def
  574. X/TF { 
  575. X    gsave
  576. X    moveto 
  577. X    RF
  578. X    show
  579. X    grestore
  580. X    } bind def
  581. X/P { 
  582. X    moveto
  583. X    0 32 3 2 roll widthshow
  584. X    } bind def
  585. X/PF { 
  586. X    gsave
  587. X    moveto 
  588. X    RF
  589. X    0 32 3 2 roll widthshow
  590. X    grestore
  591. X    } bind def
  592. X/S { 
  593. X    moveto
  594. X    0 exch ashow
  595. X    } bind def
  596. X/SF { 
  597. X    gsave
  598. X    moveto
  599. X    RF
  600. X    0 exch ashow
  601. X    grestore
  602. X    } bind def
  603. X/B { 
  604. X    moveto
  605. X    0 32 4 2 roll 0 exch awidthshow
  606. X    } bind def
  607. X/BF { 
  608. X    gsave
  609. X    moveto
  610. X    RF
  611. X    0 32 4 2 roll 0 exch awidthshow
  612. X    grestore
  613. X    } bind def
  614. X/G { 
  615. X    gsave
  616. X    newpath
  617. X    normalize translate 0.0 0.0 moveto 
  618. X    dnormalize scale 
  619. X    0.0 0.0 1.0 5 3 roll arc 
  620. X    closepath fill
  621. X    grestore
  622. X    } bind def
  623. X/A { 
  624. X    gsave
  625. X    savematrix
  626. X    newpath
  627. X    2 index 2 div add exch 3 index 2 div sub exch 
  628. X    normalize 2 index 2 div sub exch 3 index 2 div add exch 
  629. X    translate 
  630. X    scale 
  631. X    0.0 0.0 1.0 5 3 roll arc 
  632. X    restorematrix
  633. X    stroke
  634. X    grestore
  635. X    } bind def
  636. X    /x FMLOCAL
  637. X    /y FMLOCAL
  638. X    /w FMLOCAL
  639. X    /h FMLOCAL
  640. X    /xx FMLOCAL
  641. X    /yy FMLOCAL
  642. X    /ww FMLOCAL
  643. X    /hh FMLOCAL
  644. X    /FMsaveobject FMLOCAL
  645. X    /FMoptop FMLOCAL
  646. X    /FMdicttop FMLOCAL
  647. X/BEGINPRINTCODE { 
  648. X    /FMdicttop countdictstack 1 add def 
  649. X    /FMoptop count 4 sub def 
  650. X    /FMsaveobject save def
  651. X    userdict begin 
  652. X    /showpage {} def 
  653. X    FMNORMALIZEGRAPHICS 
  654. X    3 index neg 3 index neg translate
  655. X    } bind def
  656. X/ENDPRINTCODE {
  657. X    count -1 FMoptop {pop pop} for 
  658. X    countdictstack -1 FMdicttop {pop end} for 
  659. X    FMsaveobject restore 
  660. X    } bind def
  661. X/gn { 
  662. X    0 
  663. X    {    46 mul 
  664. X        cf read pop 
  665. X        32 sub 
  666. X        dup 46 lt {exit} if 
  667. X        46 sub add 
  668. X        } loop
  669. X    add 
  670. X    } bind def
  671. X    /str FMLOCAL
  672. X/cfs { 
  673. X    /str sl string def 
  674. X    0 1 sl 1 sub {str exch val put} for 
  675. X    str def 
  676. X    } bind def
  677. X/ic [ 
  678. X    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
  679. X    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
  680. X    0
  681. X    {0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx}
  682. X    {10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx}
  683. X    {19 hx} {gn hx} {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12}
  684. X    {13} {14} {15} {16} {17} {18} {19} {gn} {0 wh} {1 wh} {2 wh} {3 wh}
  685. X    {4 wh} {5 wh} {6 wh} {7 wh} {8 wh} {9 wh} {10 wh} {11 wh} {12 wh}
  686. X    {13 wh} {14 wh} {gn wh} {0 bl} {1 bl} {2 bl} {3 bl} {4 bl} {5 bl} {6 bl}
  687. X    {7 bl} {8 bl} {9 bl} {10 bl} {11 bl} {12 bl} {13 bl} {14 bl} {gn bl}
  688. X    {0 fl} {1 fl} {2 fl} {3 fl} {4 fl} {5 fl} {6 fl} {7 fl} {8 fl} {9 fl}
  689. X    {10 fl} {11 fl} {12 fl} {13 fl} {14 fl} {gn fl}
  690. X    ] def
  691. X    /sl FMLOCAL
  692. X    /val FMLOCAL
  693. X    /ws FMLOCAL
  694. X    /im FMLOCAL
  695. X    /bs FMLOCAL
  696. X    /cs FMLOCAL
  697. X    /len FMLOCAL
  698. X    /pos FMLOCAL
  699. X/ms { 
  700. X    /sl exch def 
  701. X    /val 255 def 
  702. X    /ws cfs 
  703. X    /im cfs 
  704. X    /val 0 def 
  705. X    /bs cfs 
  706. X    /cs cfs 
  707. X    } bind def
  708. X400 ms 
  709. X/ip { 
  710. X    is 
  711. X    0 
  712. X    cf cs readline pop 
  713. X    {    ic exch get exec 
  714. X        add 
  715. X        } forall 
  716. X    pop 
  717. X    
  718. X    } bind def
  719. X/wh { 
  720. X    /len exch def 
  721. X    /pos exch def 
  722. X    ws 0 len getinterval im pos len getinterval copy pop
  723. X    pos len 
  724. X    } bind def
  725. X/bl { 
  726. X    /len exch def 
  727. X    /pos exch def 
  728. X    bs 0 len getinterval im pos len getinterval copy pop
  729. X    pos len 
  730. X    } bind def
  731. X/s1 1 string def
  732. X/fl { 
  733. X    /len exch def 
  734. X    /pos exch def 
  735. X    /val cf s1 readhexstring pop 0 get def
  736. X    pos 1 pos len add 1 sub {im exch val put} for
  737. X    pos len 
  738. X    } bind def
  739. X/hx { 
  740. X    3 copy getinterval 
  741. X    cf exch readhexstring pop pop 
  742. X    } bind def
  743. X    /h FMLOCAL
  744. X    /w FMLOCAL
  745. X    /d FMLOCAL
  746. X    /lb FMLOCAL
  747. X    /bitmapsave FMLOCAL
  748. X    /is FMLOCAL
  749. X    /cf FMLOCAL
  750. X/wbytes { 
  751. X    dup 
  752. X    8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse
  753. X    } bind def
  754. X/BEGINBITMAPBWc { 
  755. X    1 {} COMMONBITMAPc
  756. X    } bind def
  757. X/BEGINBITMAPGRAYc { 
  758. X    8 {} COMMONBITMAPc
  759. X    } bind def
  760. X/BEGINBITMAP2BITc { 
  761. X    2 {} COMMONBITMAPc
  762. X    } bind def
  763. X/COMMONBITMAPc { 
  764. X    /r exch def
  765. X    /d exch def
  766. X    gsave
  767. X    translate rotate scale /h exch def /w exch def
  768. X    /lb w d wbytes def 
  769. X    sl lb lt {lb ms} if 
  770. X    /bitmapsave save def 
  771. X    r                    
  772. X    /is im 0 lb getinterval def 
  773. X    ws 0 lb getinterval is copy pop 
  774. X    /cf currentfile def 
  775. X    w h d [w 0 0 h neg 0 h] 
  776. X    {ip} image 
  777. X    bitmapsave restore 
  778. X    grestore
  779. X    } bind def
  780. X/BEGINBITMAPBW { 
  781. X    1 {} COMMONBITMAP
  782. X    } bind def
  783. X/BEGINBITMAPGRAY { 
  784. X    8 {} COMMONBITMAP
  785. X    } bind def
  786. X/BEGINBITMAP2BIT { 
  787. X    2 {} COMMONBITMAP
  788. X    } bind def
  789. X/COMMONBITMAP { 
  790. X    /r exch def
  791. X    /d exch def
  792. X    gsave
  793. X    translate rotate scale /h exch def /w exch def
  794. X    /bitmapsave save def 
  795. X    r                    
  796. X    /is w d wbytes string def
  797. X    /cf currentfile def 
  798. X    w h d [w 0 0 h neg 0 h] 
  799. X    {cf is readhexstring pop} image
  800. X    bitmapsave restore 
  801. X    grestore
  802. X    } bind def
  803. X    /proc1 FMLOCAL
  804. X    /proc2 FMLOCAL
  805. X    /newproc FMLOCAL
  806. X/Fmcc {
  807. X    /proc2 exch cvlit def
  808. X    /proc1 exch cvlit def
  809. X    /newproc proc1 length proc2 length add array def
  810. X    newproc 0 proc1 putinterval
  811. X    newproc proc1 length proc2 putinterval
  812. X    newproc cvx
  813. X} bind def
  814. X/ngrayt 256 array def
  815. X/nredt 256 array def
  816. X/nbluet 256 array def
  817. X/ngreent 256 array def
  818. X    /gryt FMLOCAL
  819. X    /blut FMLOCAL
  820. X    /grnt FMLOCAL
  821. X    /redt FMLOCAL
  822. X    /indx FMLOCAL
  823. X    /cynu FMLOCAL
  824. X    /magu FMLOCAL
  825. X    /yelu FMLOCAL
  826. X    /k FMLOCAL
  827. X    /u FMLOCAL
  828. X/colorsetup {
  829. X    currentcolortransfer
  830. X    /gryt exch def
  831. X    /blut exch def
  832. X    /grnt exch def
  833. X    /redt exch def
  834. X    0 1 255 {
  835. X        /indx exch def
  836. X        /cynu 1 red indx get 255 div sub def
  837. X        /magu 1 green indx get 255 div sub def
  838. X        /yelu 1 blue indx get 255 div sub def
  839. X        /k cynu magu min yelu min def
  840. X        /u k currentundercolorremoval exec def
  841. X        nredt indx 1 0 cynu u sub max sub redt exec put
  842. X        ngreent indx 1 0 magu u sub max sub grnt exec put
  843. X        nbluet indx 1 0 yelu u sub max sub blut exec put
  844. X        ngrayt indx 1 k currentblackgeneration exec sub gryt exec put
  845. X    } for
  846. X    {255 mul cvi nredt exch get}
  847. X    {255 mul cvi ngreent exch get}
  848. X    {255 mul cvi nbluet exch get}
  849. X    {255 mul cvi ngrayt exch get}
  850. X    setcolortransfer
  851. X    {pop 0} setundercolorremoval
  852. X    {} setblackgeneration
  853. X    } bind def
  854. X    /tran FMLOCAL
  855. X/fakecolorsetup {
  856. X    /tran 256 string def
  857. X    0 1 255 {/indx exch def 
  858. X        tran indx
  859. X        red indx get 77 mul
  860. X        green indx get 151 mul
  861. X        blue indx get 28 mul
  862. X        add add 256 idiv put} for
  863. X    currenttransfer
  864. X    {255 mul cvi tran exch get 255.0 div}
  865. X    exch Fmcc settransfer
  866. X} bind def
  867. X/BITMAPCOLOR { 
  868. X    /d 8 def
  869. X    gsave
  870. X    translate rotate scale /h exch def /w exch def
  871. X    /bitmapsave save def 
  872. X    colorsetup
  873. X    /is w d wbytes string def
  874. X    /cf currentfile def 
  875. X    w h d [w 0 0 h neg 0 h] 
  876. X    {cf is readhexstring pop} {is} {is} true 3 colorimage 
  877. X    bitmapsave restore 
  878. X    grestore
  879. X    } bind def
  880. X/BITMAPCOLORc { 
  881. X    /d 8 def
  882. X    gsave
  883. X    translate rotate scale /h exch def /w exch def
  884. X    /lb w d wbytes def 
  885. X    sl lb lt {lb ms} if 
  886. X    /bitmapsave save def 
  887. X    colorsetup
  888. X    /is im 0 lb getinterval def 
  889. X    ws 0 lb getinterval is copy pop 
  890. X    /cf currentfile def 
  891. X    w h d [w 0 0 h neg 0 h] 
  892. X    {ip} {is} {is} true 3 colorimage
  893. X    bitmapsave restore 
  894. X    grestore
  895. X    } bind def
  896. X/BITMAPTRUECOLORc { 
  897. X        gsave
  898. X        translate rotate scale /h exch def /w exch def
  899. X        /bitmapsave save def 
  900. X        
  901. X        /is w string def
  902. X        
  903. X        ws 0 w getinterval is copy pop 
  904. X        /cf currentfile def 
  905. X        w h 8 [w 0 0 h neg 0 h] 
  906. X        {ip} {gip} {bip} true 3 colorimage
  907. X        bitmapsave restore 
  908. X        grestore
  909. X        } bind def
  910. X/BITMAPTRUECOLOR { 
  911. X        gsave
  912. X        translate rotate scale /h exch def /w exch def
  913. X        /bitmapsave save def 
  914. X        /is w string def
  915. X        /gis w string def
  916. X        /bis w string def
  917. X        /cf currentfile def 
  918. X        w h 8 [w 0 0 h neg 0 h] 
  919. X        { cf is readhexstring pop } 
  920. X        { cf gis readhexstring pop } 
  921. X        { cf bis readhexstring pop } 
  922. X        true 3 colorimage 
  923. X        bitmapsave restore 
  924. X        grestore
  925. X        } bind def
  926. X/BITMAPTRUEGRAYc { 
  927. X        gsave
  928. X        translate rotate scale /h exch def /w exch def
  929. X        /bitmapsave save def 
  930. X        
  931. X        /is w string def
  932. X        
  933. X        ws 0 w getinterval is copy pop 
  934. X        /cf currentfile def 
  935. X        w h 8 [w 0 0 h neg 0 h] 
  936. X        {ip gip bip w gray} image
  937. X        bitmapsave restore 
  938. X        grestore
  939. X        } bind def
  940. X/ww FMLOCAL
  941. X/r FMLOCAL
  942. X/g FMLOCAL
  943. X/b FMLOCAL
  944. X/i FMLOCAL
  945. X/gray { 
  946. X        /ww exch def
  947. X        /b exch def
  948. X        /g exch def
  949. X        /r exch def
  950. X        0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul
  951. X            b i get .114 mul add add r i 3 -1 roll floor cvi put } for
  952. X        r
  953. X        } bind def
  954. X/BITMAPTRUEGRAY { 
  955. X        gsave
  956. X        translate rotate scale /h exch def /w exch def
  957. X        /bitmapsave save def 
  958. X        /is w string def
  959. X        /gis w string def
  960. X        /bis w string def
  961. X        /cf currentfile def 
  962. X        w h 8 [w 0 0 h neg 0 h] 
  963. X        { cf is readhexstring pop 
  964. X          cf gis readhexstring pop 
  965. X          cf bis readhexstring pop w gray}  image
  966. X        bitmapsave restore 
  967. X        grestore
  968. X        } bind def
  969. X/BITMAPGRAY { 
  970. X    8 {fakecolorsetup} COMMONBITMAP
  971. X    } bind def
  972. X/BITMAPGRAYc { 
  973. X    8 {fakecolorsetup} COMMONBITMAPc
  974. X    } bind def
  975. X/ENDBITMAP {
  976. X    } bind def
  977. Xend 
  978. X    /ALDsave FMLOCAL
  979. X    /ALDmatrix matrix def ALDmatrix currentmatrix pop
  980. X/StartALD {
  981. X    /ALDsave save def
  982. X     savematrix
  983. X     ALDmatrix setmatrix
  984. X    } bind def
  985. X/InALD {
  986. X     restorematrix
  987. X    } bind def
  988. X/DoneALD {
  989. X     ALDsave restore
  990. X    } bind def
  991. X%%EndProlog
  992. X%%BeginSetup
  993. X(3.0) FMVERSION
  994. X1 1 612 792 0 1 9 FMDOCUMENT
  995. X0 0 /Times-Italic FMFONTDEFINE
  996. X1 0 /Times-Bold FMFONTDEFINE
  997. X2 0 /Times-Roman FMFONTDEFINE
  998. X3 0 /Helvetica FMFONTDEFINE
  999. X4 0 /Helvetica-Bold FMFONTDEFINE
  1000. X32 FMFILLS
  1001. X0 0 FMFILL
  1002. X1 0.1 FMFILL
  1003. X2 0.3 FMFILL
  1004. X3 0.5 FMFILL
  1005. X4 0.7 FMFILL
  1006. X5 0.9 FMFILL
  1007. X6 0.97 FMFILL
  1008. X7 1 FMFILL
  1009. X8 <0f1e3c78f0e1c387> FMFILL
  1010. X9 <0f87c3e1f0783c1e> FMFILL
  1011. X10 <cccccccccccccccc> FMFILL
  1012. X11 <ffff0000ffff0000> FMFILL
  1013. X12 <8142241818244281> FMFILL
  1014. X13 <03060c183060c081> FMFILL
  1015. X14 <8040201008040201> FMFILL
  1016. X16 1 FMFILL
  1017. X17 0.9 FMFILL
  1018. X18 0.7 FMFILL
  1019. X19 0.5 FMFILL
  1020. X20 0.3 FMFILL
  1021. X21 0.1 FMFILL
  1022. X22 0.03 FMFILL
  1023. X23 0 FMFILL
  1024. X24 <f0e1c3870f1e3c78> FMFILL
  1025. X25 <f0783c1e0f87c3e1> FMFILL
  1026. X26 <3333333333333333> FMFILL
  1027. X27 <0000ffff0000ffff> FMFILL
  1028. X28 <7ebddbe7e7dbbd7e> FMFILL
  1029. X29 <fcf9f3e7cf9f3f7e> FMFILL
  1030. X30 <7fbfdfeff7fbfdfe> FMFILL
  1031. X%%EndSetup
  1032. X%%Page: "1" 1
  1033. X%%BeginPaperSize: Letter
  1034. X%%EndPaperSize
  1035. X612 792 0 FMBEGINPAGE
  1036. X72 63 540 567 R
  1037. X7 X
  1038. X0 K
  1039. XV
  1040. X0 12 Q
  1041. X0 X
  1042. X(School of Computer Science) 238.21 559 T
  1043. X(Carnegie Mellon University) 238.71 545 T
  1044. X(Pittsbur) 215.11 531 T
  1045. X(gh, Pennsylvania 15213-3890) 253.32 531 T
  1046. X1 F
  1047. X(Abstract) 283.69 481 T
  1048. X2 10 Q
  1049. X0.47 (The Alex filesystem provides users and applications transparent read access to files in Internet anony-) 99 456.33 P
  1050. X0.5 (mous FTP sites. Today there are thousands of anonymous FTP sites with a total of a few million files) 99 444.33 P
  1051. X0.01 (and roughly a terabyte of data. The standard approach to accessing these files involves logging in to the) 99 432.33 P
  1052. X0.38 (remote machine. This means that an application can not access remote files and that users do not have) 99 420.33 P
  1053. X0.37 (any of their aliases or local tools available when connected to a remote site. Users who want to use an) 99 408.33 P
  1054. X0.2 (application on a remote file must first manually make a local copy of the file. Not only is this inconve-) 99 396.33 P
  1055. X0.51 (nient, it creates two more problems. First, there is no mechanism for automatically updating this local) 99 384.33 P
  1056. X0.78 (copy when the remote file changes. The users must keep track of where they get their files from and) 99 372.33 P
  1057. X-0.18 (check to see if there are updates, and then fetch these. Second, many different users at the same site may) 99 360.33 P
  1058. X(have made copies of the same remote file, thus wasting disk space.) 99 348.33 T
  1059. X0.08 (Alex addresses the problems with the above approach while maintaining compatibility with the existing) 99 328.33 P
  1060. X0.22 (FTP protocol so that the large collection of currently available files can be accessed. To get reasonable) 99 316.33 P
  1061. X1.27 (performance, long term file caching must be used. Thus consistency must be addressed. Traditional) 99 304.33 P
  1062. X-0.19 (solutions to the cache consistency problem do not work in the Internet FTP domain: callbacks are not an) 99 292.33 P
  1063. X0.05 (option as the FTP protocol has no provisions for this, and polling over the Internet is slow. Fortunately,) 99 280.33 P
  1064. X0.08 (the usage of these files is also not traditional and lends itself to a new approach. Alex relaxes file cache) 99 268.33 P
  1065. X0.08 (consistency semantics, on a per file basis, and uses special caching algorithms that take into account the) 99 256.33 P
  1066. X0.12 (properties of the files and of the network. This approach allows a simple stateless filesystem to scale to) 99 244.33 P
  1067. X(the size of the Internet.) 99 232.33 T
  1068. X2 8 Q
  1069. X0.31 (This research was sponsored in part by The Defense Advanced Research Projects Agency) 99 155.67 P
  1070. X0.31 (, Information Science and T) 389.52 155.67 P
  1071. X0.31 (echnology) 479.69 155.67 P
  1072. X1.46 (Of) 99 145.67 P
  1073. X1.46 (\336ce, under the title \322Research on Parallel Computing\323, ARP) 107.29 145.67 P
  1074. X1.46 (A Order No. 7330, issued by DARP) 310.59 145.67 P
  1075. X1.46 (A/CMO under Contract) 434.12 145.67 P
  1076. X0.19 (MDA972-90-C-0035 and in part by the National Science Foundation under grant number ECD-8907068. The views and conclu-) 99 135.67 P
  1077. X0.24 (sions contained in this document are those of the author and should not be interpreted as representing the of) 99 125.67 P
  1078. X0.24 (\336cial policies, either) 447.44 125.67 P
  1079. X(expressed or implied, of the U.S. Government.) 99 115.67 T
  1080. X117 576 477 720 R
  1081. X7 X
  1082. XV
  1083. X1 14 Q
  1084. X0 X
  1085. X(Alex - a Global Filesystem) 218.88 672.67 T
  1086. X0 12 Q
  1087. X(V) 266.3 646 T
  1088. X(incent Cate) 272.74 646 T
  1089. X(vac@cs.cmu.edu) 256.52 620 T
  1090. XFMENDPAGE
  1091. X%%EndPage: "1" 2
  1092. X%%Page: "2" 2
  1093. X612 792 0 FMBEGINPAGE
  1094. X81 738 522 748.01 R
  1095. X7 X
  1096. X0 K
  1097. XV
  1098. X81 45 522 55.01 R
  1099. XV
  1100. X90 72 522 720 R
  1101. XV
  1102. X1 12 Q
  1103. X0 X
  1104. X(1. Introduction) 267.35 712 T
  1105. X2 10 Q
  1106. X0.71 (T) 90 683.33 P
  1107. X0.71 (oday it is possible to access a tremendous amount of data in FTP archives on the Internet. However) 95.41 683.33 P
  1108. X0.71 (, the) 504.08 683.33 P
  1109. X0.79 (current method of accessing this data is primitive. Users must run the FTP program and then login to the) 90 671.33 P
  1110. X0.2 (remote machine. Once they have done this, they can not use any of their local tools or aliases. Applications) 90 659.33 P
  1111. X0.2 (on a user) 90 647.33 P
  1112. X0.2 (\325) 126.86 647.33 P
  1113. X0.2 (s machine can not access \336les on remote machines, the user must manually copy them \336rst. If the) 129.64 647.33 P
  1114. X0.03 (remote \336le changes the user must \336nd out somehow and make another copy) 90 635.33 P
  1115. X0.03 (. Since each user is making cop-) 392.78 635.33 P
  1116. X0.24 (ies, there may be many copies of a \336le at a given site. Since a user can not easily tell if their own copy of a) 90 623.33 P
  1117. X0.35 (\336le is out of date they may use an old version of a \336le. Thus the existing mechanism is cumbersome, slow) 90 611.33 P
  1118. X0.35 (,) 519.5 611.33 P
  1119. X(inef) 90 599.33 T
  1120. X(\336cient, and provides only limited access to remote data.) 105.36 599.33 T
  1121. X0.29 (T) 90 575.33 P
  1122. X0.29 (o address this problem, and to explore some ideas about wide area \336lesystems, I am designing and imple-) 95.41 575.33 P
  1123. X0.13 (menting a \336lesystem called) 90 563.33 P
  1124. X1 F
  1125. X0.13 (Alex) 202.13 563.33 P
  1126. X2 F
  1127. X0.13 (. The goal of this system is to let users access \336les in FTP sites all over the) 221.56 563.33 P
  1128. X1.05 (world just as they access \336les on their local system. Ideally) 90 551.33 P
  1129. X1.05 (, both the way it is used and its performance) 336.04 551.33 P
  1130. X(should match that of a local \336lesystem.) 90 539.33 T
  1131. X0.05 (Providing transparent access to remote sites requires solutions to the problems of naming, heterogeneity and) 90 515.33 P
  1132. X0.11 (performance. While caching is the key to performance, this leads to the additional problem of cache consis-) 90 503.33 P
  1133. X(tency) 90 491.33 T
  1134. X(. I will describe how these problems are addressed in Alex.) 111 491.33 T
  1135. X2.02 (The name) 90 467.33 P
  1136. X1 F
  1137. X2.02 (Alex) 136.22 467.33 P
  1138. X2 F
  1139. X2.02 ( comes from the ancient Library of Alexandria. Alexandria gathered information from) 155.65 467.33 P
  1140. X(around the world into one easy to access location. Alex does an analogous thing in a very modern way) 90 455.33 T
  1141. X(.) 498.77 455.33 T
  1142. X-0.18 (In this paper) 90 431.33 P
  1143. X-0.18 (, I describe the Alex architecture, how users interact with it, and what they need to understand to) 139.21 431.33 P
  1144. X0.82 (use it. I then describe the current NFS server implementation. After this I discuss related systems. Next I) 90 419.33 P
  1145. X-0.11 (describe some of the useful and novel applications that can be built on top of this \336lesystem. I conclude with) 90 407.33 P
  1146. X(the current status of Alex, some conclusions, and my research agenda.) 90 395.33 T
  1147. X1 12 Q
  1148. X(2. User View of Alex) 253.88 346 T
  1149. X2 10 Q
  1150. X0.41 (One of my goals was to make Alex easy to use and think about. The hope is to provide a tool with a clean) 90 317.33 P
  1151. X(and simple abstraction.) 90 305.33 T
  1152. X1 12 Q
  1153. X(2.1. Standard Filesystem Interface) 90 274 T
  1154. X2 10 Q
  1155. X0.17 (T) 90 245.33 P
  1156. X0.17 (o a user or application, Alex is just a normal \336lesystem. Any command that works on local \336les will work) 95.41 245.33 P
  1157. X0.03 (on Alex \336les. Since Alex is a \336lesystem, nothing needs to be recompiled and no libraries are changed. Thus,) 90 233.33 P
  1158. X(users can apply all of their existing skills and tools for using \336les.) 90 221.33 T
  1159. X1 12 Q
  1160. X(2.2. Naming) 90 190 T
  1161. X2 10 Q
  1162. X0.21 (The user sees a \336lesystem with a hierarchical global name space. At the top level \050) 90 161.33 P
  1163. X1 F
  1164. X0.21 (/alex) 422.85 161.33 P
  1165. X2 F
  1166. X0.21 (\051 there are top-level) 442.84 161.33 P
  1167. X0.17 (Internet domains like \322) 90 149.33 P
  1168. X1 F
  1169. X0.17 (edu) 182.4 149.33 P
  1170. X2 F
  1171. X0.17 (\323, \322) 197.95 149.33 P
  1172. X1 F
  1173. X0.17 (com) 212 149.33 P
  1174. X2 F
  1175. X0.17 (\323, \322) 229.76 149.33 P
  1176. X1 F
  1177. X0.17 (uk) 243.8 149.33 P
  1178. X2 F
  1179. X0.17 (\323, and \322) 254.92 149.33 P
  1180. X1 F
  1181. X0.17 (jp) 286.07 149.33 P
  1182. X2 F
  1183. X0.17 (\323. Each component of the hostname becomes a directory) 294.95 149.33 P
  1184. X0.04 (name as shown in Figure 1. Then the remote path is added at the end. If the user does a \322) 90 137.33 P
  1185. X1 F
  1186. X0.04 (ls /alex/edu/berke-) 444.02 137.33 P
  1187. X0.88 (ley) 90 125.33 P
  1188. X2 F
  1189. X0.88 (\323 he sees some machine names such as \322) 102.21 125.33 P
  1190. X1 F
  1191. X0.88 (ucbvax) 271.31 125.33 P
  1192. X2 F
  1193. X0.88 (\323 and \322) 301.86 125.33 P
  1194. X1 F
  1195. X0.88 (sprite) 331.91 125.33 P
  1196. X2 F
  1197. X0.88 (\323 and some directories on) 356.34 125.33 P
  1198. X1 F
  1199. X0.88 (berkeley) 465.36 125.33 P
  1200. X0.88 (.edu) 501.45 125.33 P
  1201. X2 F
  1202. X0.88 (.) 519.5 125.33 P
  1203. X0.57 (From the \322) 90 113.33 P
  1204. X1 F
  1205. X0.57 (ls) 134.45 113.33 P
  1206. X2 F
  1207. X0.57 (\323 it is not clear what is where. Alex paths do not use any special characters to delineating the) 141.12 113.33 P
  1208. X(host name.) 90 101.33 T
  1209. XFMENDPAGE
  1210. X%%EndPage: "2" 3
  1211. X%%Page: "3" 3
  1212. X612 792 0 FMBEGINPAGE
  1213. X81 738 522 748.01 R
  1214. X7 X
  1215. X0 K
  1216. XV
  1217. X81 45 522 55.01 R
  1218. XV
  1219. X90 72 522 720 R
  1220. XV
  1221. X1 12 Q
  1222. X0 X
  1223. X(2.3. Contr) 90 506 T
  1224. X(ol of Consistency) 141.42 506 T
  1225. X2 10 Q
  1226. X0.03 (By default, the system guarantees to the user that the only updates that might not yet be reflected locally are) 90 477.33 P
  1227. X0.01 (ones that have happened in the last 10% of the reported age of the file. For example, if the user sees a file as) 90 465.33 P
  1228. X0.03 (being 10 hours old the system promises that the data given to the user will be at most 1 hour stale. If a file is) 90 453.33 P
  1229. X0.06 (shown as being last modified 10 days ago, the file may be up to 1 day stale. There is a maximum of 1 month) 90 441.33 P
  1230. X0.05 (and a minimum of 5 minutes. The user can override these rules and ask for an update of any directory at any) 90 429.33 P
  1231. X(time.) 90 417.33 T
  1232. X1 12 Q
  1233. X(3. Alex Implementation) 245.87 368 T
  1234. X2 10 Q
  1235. X0.62 (As shown in Figure 2, Alex is currently implemented as an NFS server) 90 339.33 P
  1236. X0.62 (. Alex uses the FTP protocol [Pos-) 380.31 339.33 P
  1237. X0.09 (tel85] to talk to Internet FTP sites. Machines on the local area net use the NFS protocol [Nowicki89] to talk) 90 327.33 P
  1238. X0.18 (to the Alex server) 90 315.33 P
  1239. X0.18 (. NFS was chosen because it makes it trivial to add Alex to a wide range of machines. On) 161.31 315.33 P
  1240. X0.61 (most machines, adding Alex just involves using a simple command called mount. It is so easy) 90 303.33 P
  1241. X0.61 (, that a user) 474.1 303.33 P
  1242. X1.07 (who has none of my software, and is just talking with me on the phone, can start using Alex in about a) 90 291.33 P
  1243. X1.19 (minute. AFS [Howard87] scales to more clients per server but for the expected number of simultaneous) 90 279.33 P
  1244. X0.38 (users it was felt that NFS would work \336ne. Another motivation for choosing NFS was that it is simple and) 90 267.33 P
  1245. X0.71 (stateless. Because NFS is stateless it is \336ne if Alex dies and restarts \050for example, during installation of a) 90 255.33 P
  1246. X(new version of the server\051. Since this takes only a couple of seconds, none of the clients notice.) 90 243.33 T
  1247. X1 12 Q
  1248. X(3.1. Backgr) 90 212 T
  1249. X(ound) 148.08 212 T
  1250. X2 10 Q
  1251. X0.01 (A few important characteristics of the Alex domain motivated my design choices. Key to the Alex approach) 90 183.33 P
  1252. X0.2 (is using existing FTP sites without any change to the FTP protocol. This determines a number of aspects of) 90 171.33 P
  1253. X(the domain.) 90 159.33 T
  1254. X0.92 (FTP) 90 135.33 P
  1255. X0.92 (, like AFS [Howard87], gives us whole \336le transfer) 106.11 135.33 P
  1256. X0.92 (. The FTP protocol does not do callbacks as does) 317.76 135.33 P
  1257. X0.54 (AFS. Thus, Alex is fully responsible for checking the consistency of its cache with the FTP site. The FTP) 90 123.33 P
  1258. X0.01 (protocol returns directory information as a unit \050not one \336le at a time\051. This, like whole \336le transfer) 90 111.33 P
  1259. X0.01 (, reduces) 486.47 111.33 P
  1260. X0.04 (the number of times you pay the network latency cost. This is a big performance win in a wide area network) 90 99.33 P
  1261. X(as big as the Internet.) 90 87.33 T
  1262. X90 72 522 720 C
  1263. X99.6 558 512.4 710 C
  1264. X99.6 558 512.4 710 R
  1265. X7 X
  1266. X0 K
  1267. XV
  1268. X108.6 583 504.6 691 R
  1269. X5 X
  1270. XV
  1271. X0.5 H
  1272. X2 Z
  1273. X7 X
  1274. XN
  1275. X225.6 610 396.6 637 R
  1276. XV
  1277. X0 X
  1278. XN
  1279. X153.6 655 252.6 682 R
  1280. X7 X
  1281. XV
  1282. X0 X
  1283. XN
  1284. X378.6 655 459.6 682 R
  1285. X7 X
  1286. XV
  1287. X0 X
  1288. XN
  1289. X3 12 Q
  1290. X(ftp.cse.ucsc.edu) 161.34 664.26 T
  1291. X(/alex/edu/ucsc/cse/ftp/pub/tr) 233.34 621.63 T
  1292. X(FTP Host) 135.6 639.63 T
  1293. X(Remote Name) 418.29 639.63 T
  1294. X(Alex Name) 274.95 594.63 T
  1295. X(/pub/tr) 394.01 664.26 T
  1296. X252.82 646.36 260.33 637 249 640.96 250.91 643.66 4 Y
  1297. XV
  1298. X234.6 655 250.92 643.65 2 L
  1299. XN
  1300. X379.74 640.7 368.33 637 376.05 646.19 377.9 643.45 4 Y
  1301. XV
  1302. X395.34 655 377.91 643.44 2 L
  1303. XN
  1304. X1 10 Q
  1305. X(Figure 1. Example Alex Name) 243.6 566 T
  1306. X90 72 522 720 C
  1307. X0 0 612 792 C
  1308. XFMENDPAGE
  1309. X%%EndPage: "3" 4
  1310. X%%Page: "4" 4
  1311. X612 792 0 FMBEGINPAGE
  1312. X81 738 522 748.01 R
  1313. X7 X
  1314. X0 K
  1315. XV
  1316. X81 45 522 55.01 R
  1317. XV
  1318. X90 72 522 720 R
  1319. XV
  1320. X2 10 Q
  1321. X0 X
  1322. X-0.12 (Also important are characteristics of the domain FTP operates in. This domain is truly heterogeneous. While) 90 452.33 P
  1323. X0.15 (FTP hides some of this it also exposes plenty) 90 440.33 P
  1324. X0.15 (. Both the syntax for specifying names and the directory infor-) 270.99 440.33 P
  1325. X0.03 (mation returned varies among the dif) 90 428.33 P
  1326. X0.03 (ferent types of FTP sites. Another problem is that a noticeable percent-) 237.94 428.33 P
  1327. X(age of the FTP sites are either down or inaccessible at any one time.) 90 416.33 T
  1328. X0.65 (The type of data stored in FTP sites and the access patterns for this data are dif) 90 392.33 P
  1329. X0.65 (ferent from that of normal) 415.03 392.33 P
  1330. X0.13 (user \336les. The \336les change much less often than do normal \336les. Another important aspect of this domain is) 90 380.33 P
  1331. X(that users frequently tolerate using stale copies of \336les.) 90 368.33 T
  1332. X1 12 Q
  1333. X(3.2. Naming) 90 337 T
  1334. X2 10 Q
  1335. X0.27 (A path name in Alex has three parts. The \336rst is \322/alex\323. The second part is an Internet host name, with the) 90 308.33 P
  1336. X0.78 (most signi\336cant piece \336rst \050such as \322edu\323\051 and the \322.\323s replaced by \322/\323s. The third part is the path on the) 90 296.33 P
  1337. X0.38 (remote machine relative to the ftp starting directory on that machine. An example path is) 90 284.33 P
  1338. X1 F
  1339. X0.38 (/alex/edu/berke-) 453.15 284.33 P
  1340. X(ley/pub/virus.patch) 90 272.33 T
  1341. X2 F
  1342. X(.) 172.48 272.33 T
  1343. X0.06 (T) 90 248.33 P
  1344. X0.06 (o resolve a name Alex \336rst matches with the longest matching hostname it knows about, in a fashion simi-) 95.41 248.33 P
  1345. X0.04 (lar to Sprite\325) 90 236.33 P
  1346. X0.04 (s pre\336x tables [W) 139.9 236.33 P
  1347. X0.04 (elch86]. Next, it sees if the rest of the path works. If it does not, Alex will cre-) 209.78 236.33 P
  1348. X0.29 (ate a possible hostname and call a nameserver) 90 224.33 P
  1349. X0.29 (. This approach seems to work almost everywhere. However) 275.52 224.33 P
  1350. X0.29 (,) 519.5 224.33 P
  1351. X-0.17 (there is an ambiguity in the above name in that) 90 212.33 P
  1352. X1 F
  1353. X-0.17 (pub) 278.23 212.33 P
  1354. X2 F
  1355. X-0.17 ( is a directory on) 294.9 212.33 P
  1356. X1 F
  1357. X-0.17 (berkeley) 363.75 212.33 P
  1358. X-0.17 (.edu) 399.84 212.33 P
  1359. X2 F
  1360. X-0.17 ( and there is a) 417.89 212.33 P
  1361. X1 F
  1362. X-0.17 (pub.berke-) 475.08 212.33 P
  1363. X0.01 (ley) 90 200.33 P
  1364. X0.01 (.edu) 101.66 200.33 P
  1365. X2 F
  1366. X0.01 ( \050which both map onto the same name in Alex\051. Fortunately this does not happen often, in fact, pub.-) 119.71 200.33 P
  1367. X(berkeley) 90 188.33 T
  1368. X(.edu is the only site found so far for which this does not work \050and it does allow FTP anyway\051.) 123.76 188.33 T
  1369. X-0.25 (One problem with this type of naming is that a user who has set up his account to search the current directory) 90 164.33 P
  1370. X-0.18 (for commands before other places such as \322/bin\323 gets very poor performance at times. For example, if such a) 90 152.33 P
  1371. X0.13 (user wants to run \322ls\323 while in /alex/edu/berkeley the shell will check to see if there is a /alex/edu/berkeley/) 90 140.33 P
  1372. X0.04 (ls. This causes the Alex server to check for a host called \322ls.berkeley) 90 128.33 P
  1373. X0.04 (.edu\323 \050assuming there was no \322ls\323 \336le\051.) 364.64 128.33 P
  1374. X0.12 (Doing this takes a call to a remote nameserver) 90 116.33 P
  1375. X0.12 (, which is expensive. As long as they know this, users can set) 275.43 116.33 P
  1376. X(up their search path to avoid this problem \050they should also change their path for security reasons\051.) 90 104.33 T
  1377. X90 72 522 720 C
  1378. X90 459 522 720 C
  1379. X89.49 459 522.51 720 R
  1380. X7 X
  1381. X0 K
  1382. XV
  1383. X90 450 157.57 90 255.92 602 G
  1384. X4 H
  1385. X2 Z
  1386. X4 X
  1387. X90 450 157.57 90 255.92 602 A
  1388. X1 14 Q
  1389. X0 X
  1390. X(Alex NFS Server) 296.49 583.62 T
  1391. X(Machines on Local Ar) 162.53 541.94 T
  1392. X(ea Net) 294.81 541.94 T
  1393. X( Internet FTP Sites) 389.62 511.62 T
  1394. X270.23 650.01 260.48 657 272.46 656.23 271.34 653.12 4 Y
  1395. X1 X
  1396. XV
  1397. X298.05 647.18 307.79 640.18 295.82 640.95 296.93 644.06 4 Y
  1398. XV
  1399. X271.35 653.12 296.95 644.06 2 L
  1400. X1 H
  1401. X0 Z
  1402. XN
  1403. X380.27 640.24 368.48 638 377.3 646.15 378.78 643.2 4 Y
  1404. XV
  1405. X428.7 671.76 440.48 674 431.67 665.85 430.18 668.81 4 Y
  1406. XV
  1407. X378.79 643.2 430.19 668.81 2 L
  1408. XN
  1409. X278.37 592.12 266.88 588.66 274.78 597.68 276.58 594.9 4 Y
  1410. XV
  1411. X297.7 612.19 309.19 615.65 301.29 606.63 299.49 609.41 4 Y
  1412. XV
  1413. X276.58 594.9 299.5 609.4 2 L
  1414. XN
  1415. X378.18 612.94 368.48 620.01 380.45 619.15 379.31 616.04 4 Y
  1416. XV
  1417. X457.78 591.07 467.48 584.01 455.51 584.86 456.64 587.97 4 Y
  1418. XV
  1419. X379.33 616.04 456.66 587.96 2 L
  1420. XN
  1421. X479.17 653.46 501.4 653.01 501.4 617.4 479.17 619.32 4 Y
  1422. X4 X
  1423. XV
  1424. X0.25 H
  1425. X2 Z
  1426. X0 X
  1427. XN
  1428. X501.4 653.01 512.45 655.9 512.45 627.79 501.4 617.4 4 Y
  1429. X3 X
  1430. XV
  1431. X0 X
  1432. XN
  1433. X512.45 655.9 491.43 656 479.17 653.46 501.4 653.01 4 Y
  1434. XV
  1435. XN
  1436. X480.02 619.24 480.02 618.73 501.22 616.84 512.15 627.03 512.15 627.49 501.4 617.4 6 Y
  1437. XV
  1438. X0.2 H
  1439. XN
  1440. X479.17 652.19 501.4 651.55 512.45 654.81 3 L
  1441. X0.25 H
  1442. XN
  1443. X479.17 642.91 501.4 641.78 512.45 646.88 512.45 646.17 501.4 641.07 479.17 642.2 6 Y
  1444. XV
  1445. XN
  1446. X481.21 642.27 482 642.56 R
  1447. X7 X
  1448. XV
  1449. X0 X
  1450. XN
  1451. X479.17 626.04 501.4 624.35 2 L
  1452. XN
  1453. X479.17 625.4 501.4 623.7 2 L
  1454. XN
  1455. X479.17 624.75 501.4 623.05 2 L
  1456. XN
  1457. X479.17 624.1 501.4 622.4 2 L
  1458. XN
  1459. X479.17 623.46 501.4 621.76 2 L
  1460. XN
  1461. X479.17 622.81 501.4 621.11 2 L
  1462. XN
  1463. X479.17 622.16 501.4 620.46 2 L
  1464. XN
  1465. X479.17 621.52 501.4 619.82 2 L
  1466. XN
  1467. X479.17 620.87 501.4 619.17 2 L
  1468. XN
  1469. X479.17 620.33 501.4 618.42 2 L
  1470. XN
  1471. X479.17 626.69 501.4 624.99 2 L
  1472. XN
  1473. X479.17 627.34 501.4 625.64 2 L
  1474. XN
  1475. X501.4 625.64 512.45 634.13 2 L
  1476. XN
  1477. X501.4 624.93 512.45 633.43 2 L
  1478. XN
  1479. X501.4 624.43 512.45 632.79 2 L
  1480. XN
  1481. X501.4 623.66 512.45 632.29 2 L
  1482. XN
  1483. X501.4 623.02 512.45 631.73 2 L
  1484. XN
  1485. X501.4 622.31 512.45 631.12 2 L
  1486. XN
  1487. X501.4 621.82 512.45 630.49 2 L
  1488. XN
  1489. X501.4 621.11 512.4 629.85 2 L
  1490. XN
  1491. X501.4 620.4 512.45 629.32 2 L
  1492. XN
  1493. X501.4 619.76 512.44 628.93 2 L
  1494. XN
  1495. X501.4 619.2 512.49 628.51 2 L
  1496. XN
  1497. X501.4 618.42 512.44 628.15 2 L
  1498. XN
  1499. X443.18 698.46 465.4 698.01 465.4 662.4 443.18 664.32 4 Y
  1500. X4 X
  1501. XV
  1502. X0 X
  1503. XN
  1504. X465.4 698.01 476.45 700.9 476.45 672.79 465.4 662.4 4 Y
  1505. X3 X
  1506. XV
  1507. X0 X
  1508. XN
  1509. X476.45 700.9 455.43 701 443.18 698.46 465.4 698.01 4 Y
  1510. XV
  1511. XN
  1512. X444.02 664.24 444.02 663.73 465.22 661.84 476.15 672.03 476.15 672.49 465.4 662.4 6 Y
  1513. XV
  1514. X0.2 H
  1515. XN
  1516. X443.18 697.19 465.4 696.55 476.45 699.81 3 L
  1517. X0.25 H
  1518. XN
  1519. X443.18 687.91 465.4 686.78 476.45 691.88 476.45 691.17 465.4 686.07 443.18 687.2 6 Y
  1520. XV
  1521. XN
  1522. X445.21 687.27 446.01 687.56 R
  1523. X7 X
  1524. XV
  1525. X0 X
  1526. XN
  1527. X443.18 671.04 465.4 669.35 2 L
  1528. XN
  1529. X443.18 670.4 465.4 668.7 2 L
  1530. XN
  1531. X443.18 669.75 465.4 668.05 2 L
  1532. XN
  1533. X443.18 669.1 465.4 667.4 2 L
  1534. XN
  1535. X443.18 668.46 465.4 666.76 2 L
  1536. XN
  1537. X443.18 667.81 465.4 666.11 2 L
  1538. XN
  1539. X443.18 667.16 465.4 665.46 2 L
  1540. XN
  1541. X443.18 666.52 465.4 664.82 2 L
  1542. XN
  1543. X443.18 665.87 465.4 664.17 2 L
  1544. XN
  1545. X443.18 665.33 465.4 663.42 2 L
  1546. XN
  1547. X443.18 671.69 465.4 669.99 2 L
  1548. XN
  1549. X443.18 672.34 465.4 670.64 2 L
  1550. XN
  1551. X465.4 670.64 476.45 679.13 2 L
  1552. XN
  1553. X465.4 669.93 476.45 678.43 2 L
  1554. XN
  1555. X465.4 669.43 476.45 677.79 2 L
  1556. XN
  1557. X465.4 668.66 476.45 677.29 2 L
  1558. XN
  1559. X465.4 668.02 476.45 676.73 2 L
  1560. XN
  1561. X465.4 667.31 476.45 676.12 2 L
  1562. XN
  1563. X465.4 666.82 476.45 675.49 2 L
  1564. XN
  1565. X465.4 666.11 476.4 674.85 2 L
  1566. XN
  1567. X465.4 665.4 476.45 674.32 2 L
  1568. XN
  1569. X465.4 664.76 476.45 673.93 2 L
  1570. XN
  1571. X465.4 664.2 476.49 673.51 2 L
  1572. XN
  1573. X465.4 663.42 476.45 673.15 2 L
  1574. XN
  1575. X479.17 599.46 501.4 599.01 501.4 563.4 479.17 565.32 4 Y
  1576. X4 X
  1577. XV
  1578. X0 X
  1579. XN
  1580. X501.4 599.01 512.45 601.9 512.45 573.79 501.4 563.4 4 Y
  1581. X3 X
  1582. XV
  1583. X0 X
  1584. XN
  1585. X512.45 601.9 491.43 602 479.17 599.46 501.4 599.01 4 Y
  1586. XV
  1587. XN
  1588. X480.02 565.24 480.02 564.73 501.22 562.84 512.15 573.03 512.15 573.49 501.4 563.4 6 Y
  1589. XV
  1590. X0.2 H
  1591. XN
  1592. X479.17 598.19 501.4 597.55 512.45 600.81 3 L
  1593. X0.25 H
  1594. XN
  1595. X479.17 588.91 501.4 587.78 512.45 592.88 512.45 592.17 501.4 587.07 479.17 588.2 6 Y
  1596. XV
  1597. XN
  1598. X481.21 588.27 482 588.56 R
  1599. X7 X
  1600. XV
  1601. X0 X
  1602. XN
  1603. X479.17 572.04 501.4 570.35 2 L
  1604. XN
  1605. X479.17 571.4 501.4 569.7 2 L
  1606. XN
  1607. X479.17 570.75 501.4 569.05 2 L
  1608. XN
  1609. X479.17 570.1 501.4 568.4 2 L
  1610. XN
  1611. X479.17 569.46 501.4 567.76 2 L
  1612. XN
  1613. X479.17 568.81 501.4 567.11 2 L
  1614. XN
  1615. X479.17 568.16 501.4 566.46 2 L
  1616. XN
  1617. X479.17 567.52 501.4 565.82 2 L
  1618. XN
  1619. X479.17 566.87 501.4 565.17 2 L
  1620. XN
  1621. X479.17 566.33 501.4 564.42 2 L
  1622. XN
  1623. X479.17 572.69 501.4 570.99 2 L
  1624. XN
  1625. X479.17 573.34 501.4 571.64 2 L
  1626. XN
  1627. X501.4 571.64 512.45 580.13 2 L
  1628. XN
  1629. X501.4 570.93 512.45 579.43 2 L
  1630. XN
  1631. X501.4 570.43 512.45 578.79 2 L
  1632. XN
  1633. X501.4 569.66 512.45 578.29 2 L
  1634. XN
  1635. X501.4 569.02 512.45 577.73 2 L
  1636. XN
  1637. X501.4 568.31 512.45 577.12 2 L
  1638. XN
  1639. X501.4 567.82 512.45 576.49 2 L
  1640. XN
  1641. X501.4 567.11 512.4 575.85 2 L
  1642. XN
  1643. X501.4 566.4 512.45 575.32 2 L
  1644. XN
  1645. X501.4 565.76 512.44 574.93 2 L
  1646. XN
  1647. X501.4 565.2 512.49 574.51 2 L
  1648. XN
  1649. X501.4 564.42 512.44 574.15 2 L
  1650. XN
  1651. X413.49 572.46 435.71 572.01 435.71 536.4 413.49 538.32 4 Y
  1652. X4 X
  1653. XV
  1654. X0 X
  1655. XN
  1656. X435.71 572.01 446.77 574.9 446.77 546.79 435.71 536.4 4 Y
  1657. X3 X
  1658. XV
  1659. X0 X
  1660. XN
  1661. X446.77 574.9 425.74 575 413.49 572.46 435.71 572.01 4 Y
  1662. XV
  1663. XN
  1664. X414.33 538.24 414.33 537.73 435.53 535.84 446.46 546.03 446.46 546.49 435.71 536.4 6 Y
  1665. XV
  1666. X0.2 H
  1667. XN
  1668. X413.49 571.19 435.71 570.55 446.77 573.81 3 L
  1669. X0.25 H
  1670. XN
  1671. X413.49 561.91 435.71 560.78 446.77 565.88 446.77 565.17 435.71 560.07 413.49 561.2 6 Y
  1672. XV
  1673. XN
  1674. X415.52 561.27 416.32 561.56 R
  1675. X7 X
  1676. XV
  1677. X0 X
  1678. XN
  1679. X413.49 545.04 435.71 543.35 2 L
  1680. XN
  1681. X413.49 544.4 435.71 542.7 2 L
  1682. XN
  1683. X413.49 543.75 435.71 542.05 2 L
  1684. XN
  1685. X413.49 543.1 435.71 541.4 2 L
  1686. XN
  1687. X413.49 542.46 435.71 540.76 2 L
  1688. XN
  1689. X413.49 541.81 435.71 540.11 2 L
  1690. XN
  1691. X413.49 541.16 435.71 539.46 2 L
  1692. XN
  1693. X413.49 540.52 435.71 538.82 2 L
  1694. XN
  1695. X413.49 539.87 435.71 538.17 2 L
  1696. XN
  1697. X413.49 539.33 435.71 537.42 2 L
  1698. XN
  1699. X413.49 545.69 435.71 543.99 2 L
  1700. XN
  1701. X413.49 546.34 435.71 544.64 2 L
  1702. XN
  1703. X435.71 544.64 446.77 553.13 2 L
  1704. XN
  1705. X435.71 543.93 446.77 552.43 2 L
  1706. XN
  1707. X435.71 543.43 446.77 551.79 2 L
  1708. XN
  1709. X435.71 542.66 446.77 551.29 2 L
  1710. XN
  1711. X435.71 542.02 446.77 550.73 2 L
  1712. XN
  1713. X435.71 541.31 446.77 550.12 2 L
  1714. XN
  1715. X435.71 540.82 446.77 549.49 2 L
  1716. XN
  1717. X435.71 540.11 446.72 548.85 2 L
  1718. XN
  1719. X435.71 539.4 446.77 548.32 2 L
  1720. XN
  1721. X435.71 538.76 446.76 547.93 2 L
  1722. XN
  1723. X435.71 538.2 446.8 547.51 2 L
  1724. XN
  1725. X435.71 537.42 446.76 547.15 2 L
  1726. XN
  1727. X314.49 652.9 347.86 652.28 347.86 602.78 314.49 605.44 4 Y
  1728. X6 X
  1729. XV
  1730. X0 X
  1731. XN
  1732. X347.86 652.28 364.46 656.3 364.46 617.22 347.86 602.78 4 Y
  1733. X6 X
  1734. XV
  1735. X0 X
  1736. XN
  1737. X364.46 656.3 332.89 656.43 314.49 652.9 347.86 652.28 4 Y
  1738. X6 X
  1739. XV
  1740. X0 X
  1741. XN
  1742. X314.49 650.64 347.86 649.65 350.75 650.36 350.75 651.91 364.46 655.17 5 L
  1743. X6 X
  1744. XV
  1745. X0 X
  1746. XN
  1747. X350.57 650.21 350.57 605.19 2 L
  1748. X6 X
  1749. XV
  1750. X0 X
  1751. XN
  1752. X349.67 650.07 349.67 604.34 2 L
  1753. X6 X
  1754. XV
  1755. X0 X
  1756. XN
  1757. X344.98 649.73 344.98 603.01 2 L
  1758. X6 X
  1759. XV
  1760. X0 X
  1761. XN
  1762. X317.38 650.55 317.38 605.21 2 L
  1763. X6 X
  1764. XV
  1765. X0 X
  1766. END_OF_FILE
  1767.   if test 43326 -ne `wc -c <'alexsrvr/doc/intro.ps.A'`; then
  1768.     echo shar: \"'alexsrvr/doc/intro.ps.A'\" unpacked with wrong size!
  1769.   elif test -f 'alexsrvr/doc/intro.ps.B' ; then
  1770.     echo shar: Combining  \"'alexsrvr/doc/intro.ps'\" \(89781 characters\)
  1771.     cat 'alexsrvr/doc/intro.ps.A' 'alexsrvr/doc/intro.ps.B' > 'alexsrvr/doc/intro.ps'
  1772.     if test 89781 -ne `wc -c <'alexsrvr/doc/intro.ps'`; then
  1773.       echo shar: \"'alexsrvr/doc/intro.ps'\" combined with wrong size!
  1774.     else 
  1775.       rm alexsrvr/doc/intro.ps.A alexsrvr/doc/intro.ps.B 
  1776.     fi 
  1777.   fi
  1778.   # end of 'alexsrvr/doc/intro.ps.A'
  1779. fi
  1780. if test -f 'alexsrvr/src/phonehome.c' -a "${1}" != "-c" ; then 
  1781.   echo shar: Will not clobber existing file \"'alexsrvr/src/phonehome.c'\"
  1782. else
  1783.   echo shar: Extracting \"'alexsrvr/src/phonehome.c'\" \(11298 characters\)
  1784.   sed "s/^X//" >'alexsrvr/src/phonehome.c' <<'END_OF_FILE'
  1785. X/* Copyright (c) 1992 Vincent Cate
  1786. X * All Rights Reserved.
  1787. X *
  1788. X * Permission to use and modify this software and its documentation
  1789. X * is hereby granted, provided that both the copyright notice and this
  1790. X * permission notice appear in all copies of the software, derivative works
  1791. X * or modified versions, and any portions thereof, and that both notices
  1792. X * appear in supporting documentation.  This software or any derivate works
  1793. X * may not be sold or distributed without prior written approval from
  1794. X * Vincent Cate.
  1795. X *
  1796. X * THE SOFTWARE IS PROVIDED "AS IS" AND VINCENT CATE DISCLAIMS ALL
  1797. X * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  1798. X * WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL
  1799. X * VINCENT CATE BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  1800. X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  1801. X * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  1802. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  1803. X * OR PERFORMANCE OF THIS SOFTWARE.
  1804. X *
  1805. X * Users of this software agree to return to Vincent Cate any improvements
  1806. X * or extensions that they make and grant Vincent Cate the rights to
  1807. X * redistribute these changes.
  1808. X *
  1809. X *
  1810. X */
  1811. X
  1812. X#include "alexincs.h"
  1813. X#include "alex.h"
  1814. X
  1815. Xstatic struct sockaddr_in PHremAddr;    /* address of remote host */       /* move to PHConnectTo XXX */
  1816. Xstatic struct sockaddr_in PHlocalAddr;    /* socket name of local host */
  1817. Xstatic FILE *FileToHome;        /* connection as FILE("w") */
  1818. Xstatic FILE *FileFromHome;        /* connection as FILE("r") */
  1819. Xstatic int   FdHome;
  1820. X
  1821. X#define HOMEHOST "cs.cmu.edu"
  1822. X#define HOMEUID "vac+alexphonehome"          /* something we can add # to */
  1823. X
  1824. X#ifndef PROXY_FTP_HOST
  1825. X#define PROXY_FTP_HOST ""
  1826. X#endif
  1827. X
  1828. X/*
  1829. X * send a command to remote host
  1830. X */
  1831. X/*VARARGS*/
  1832. Xstatic void
  1833. XSendHome(va_alist)
  1834. X     va_dcl
  1835. X{
  1836. X  va_list ap;
  1837. X  char *fmt,buf[1024];
  1838. X
  1839. X  usleep((unsigned int) 200000);                   /* 2/10th of a second per line adds ~6 seconds */
  1840. X  ReadInAny();
  1841. X
  1842. X  va_start(ap);
  1843. X  fmt = va_arg(ap,char *);
  1844. X  vsprintf(buf, fmt, ap);
  1845. X  ToLog(DBMAJOR, ">> %s",buf);
  1846. X  fputs(buf, FileToHome);
  1847. X  fflush(FileToHome);
  1848. X}
  1849. X
  1850. X
  1851. X
  1852. X
  1853. X/*
  1854. X * make an connection to an smtp server 
  1855. X */
  1856. X
  1857. Xint PHConnectTo(SmtpHost, PhoneType)
  1858. Xchar *SmtpHost;
  1859. Xint PhoneType;
  1860. X{
  1861. X/*  struct servent *sp; */
  1862. X    struct hostent *hp;
  1863. X    int len;
  1864. X
  1865. X    ToLog(DBMAJOR, "PHConnectTo starting for %s\n", SmtpHost);
  1866. X
  1867. X    if (strlen(SmtpHost) < 5) {
  1868. X        return(AFAIL);
  1869. X    }
  1870. X        
  1871. X/*
  1872. X *   if((sp = getservbyname("smtp", "tcp")) == NULL) {             
  1873. X *       ToLog(DBERROR, "PHConnectTo can not getservbyname");
  1874. X *       return(AFAIL);
  1875. X *   }
  1876. X*/
  1877. X
  1878. X    bzero((char *)&PHremAddr, sizeof(PHremAddr));
  1879. X    PHremAddr.sin_addr.s_addr = inet_addr(SmtpHost);
  1880. X    if(PHremAddr.sin_addr.s_addr != -1){
  1881. X        PHremAddr.sin_family = AF_INET;
  1882. X        hp = NULL;
  1883. X    }else{
  1884. X        if((hp = gethostbyname(SmtpHost)) == NULL){
  1885. X            ToLog(DBERROR, "PHConnectTo can not gethostbyname");
  1886. X            return(AFAIL);
  1887. X        }
  1888. X        PHremAddr.sin_family = hp->h_addrtype;
  1889. X        bcopy(hp->h_addr_list[0],(caddr_t)&PHremAddr.sin_addr,hp->h_length);
  1890. X    }
  1891. X
  1892. X
  1893. X    if((FdHome = socket(PHremAddr.sin_family,SOCK_STREAM,0)) < 0) {
  1894. X        ToLog(DBERROR, "PHConnectTo can not make socket");
  1895. X        return(AFAIL);
  1896. X    }
  1897. X
  1898. X    PHremAddr.sin_port = 25;           /* sp->s_port;    smtp is always 25 */
  1899. X    for(;;){
  1900. X        ToLog(DBMAJOR, "Trying %s ...\n",inet_ntoa(PHremAddr.sin_addr));
  1901. X        if(connect(FdHome,(struct sockaddr *)&PHremAddr, sizeof(PHremAddr)) >= 0) {
  1902. X            break;
  1903. X        }
  1904. X        if(hp && hp->h_addr_list[1]){
  1905. X            hp->h_addr_list++;
  1906. X            bcopy(hp->h_addr_list[0],(caddr_t)&PHremAddr.sin_addr, hp->h_length);
  1907. X            close(FdHome);
  1908. X            if((FdHome = socket(PHremAddr.sin_family,SOCK_STREAM,0)) < 0) {
  1909. X                ToLog(DBERROR, "PHConnectTo can not make socket");
  1910. X              return(AFAIL);
  1911. X            }
  1912. X        } else {
  1913. X            ToLog(DBERROR, "PHConnectTo can not connect to anything");
  1914. X            return(AFAIL);
  1915. X        }
  1916. X    }
  1917. X
  1918. X    ToLog(DBMAJOR, "Connected to %s ...\n",inet_ntoa(PHremAddr.sin_addr));
  1919. X    len = sizeof(PHlocalAddr);
  1920. X    if(getsockname(FdHome,(struct sockaddr *)&PHlocalAddr,&len) < 0) {
  1921. X        ToLog(DBERROR, "PHConnectTo can not getsockname");
  1922. X        return(AFAIL);
  1923. X    }
  1924. X
  1925. X    if((FileFromHome = fdopen(FdHome,"r")) == NULL || (FileToHome = fdopen(FdHome, "w")) == NULL) {
  1926. X        ToLog(DBERROR, "PHConnectTo can not fdopen FdHome ");
  1927. X        (void) fclose(FileFromHome);
  1928. X        (void) fclose(FileToHome);
  1929. X        return(AFAIL);
  1930. X    }
  1931. X
  1932. X    ToLog(DBMAJOR, "PHConnectTo has connected to smtp server AOK\n");
  1933. X
  1934. X    usleep((unsigned int) 5000000);            /* give him 5 seconds to get ready */
  1935. X    SendHome("helo %s\n", SERVERHOSTNAME);
  1936. X    SendHome("mail from:<>\n");
  1937. X    SendHome("rcpt to:<%s%d@%s>\n", HOMEUID, PhoneType, HOMEHOST);
  1938. X    SendHome("data\n");
  1939. X    SendHome("From: <%s@%s>\n", ALEXSRVR, SERVERHOSTNAME);
  1940. X    SendHome("To: <%s%d@%s>\n", HOMEUID, PhoneType, HOMEHOST);
  1941. X    SendHome("Date: %s\n", CurrentDateStr());
  1942. X    SendHome("Message-Id: <%d@%s>\n", InodeNext++, SERVERHOSTNAME);
  1943. X    SendHome("Subject: Alex Phone Home\n");
  1944. X    SendHome(" \n"); 
  1945. X
  1946. X    SendHome("SMTP Host        %s\n", SmtpHost);            /* body of message will follow */
  1947. X
  1948. X    ToLog(DBALL, "PHConnectTo has sent mail headers\n");
  1949. X
  1950. X    return(AOK);
  1951. X}
  1952. X
  1953. X
  1954. Xint TryUCBMail(PhoneType)
  1955. Xint PhoneType;
  1956. X{
  1957. X    char Command[MAXPATH];
  1958. X
  1959. X#ifndef UCBMAILPATH
  1960. X   return(AFAIL);
  1961. X#else
  1962. X    if (strlen(UCBMAILPATH) == 0) {
  1963. X        ToLog(DBMAJOR, "TryUCBMail UCBMAILPATH is null string.\n");
  1964. X        return(AFAIL);
  1965. X    }
  1966. X
  1967. X    if (SizeOfCachedFile(UCBMAILPATH) < 0) {
  1968. X        ToLog(DBERROR, "TryUCBMail ERROR file not found %s\n", UCBMAILPATH);
  1969. X        return(AFAIL);
  1970. X    }
  1971. X
  1972. X    sprintf(Command, "%s -s AlexPhoneHome %s%d@%s", UCBMAILPATH, HOMEUID, PhoneType, HOMEHOST);
  1973. X    FileToHome= popen(Command, "w");
  1974. X    if (FileToHome == NULL) {
  1975. X        ToLog(DBERROR, "TryUCBMail ERROR can not start mail command %s\n", Command);
  1976. X        return(AFAIL);
  1977. X    }
  1978. X
  1979. X    ToLog(DBMAJOR, "TryUCBMail has done popen to do mail using %s\n", UCBMAILPATH);
  1980. X    return(AOK);
  1981. X#endif
  1982. X}
  1983. X
  1984. X
  1985. XReadInAny()
  1986. X{
  1987. X    char buf[1000];
  1988. X    int i, nread;
  1989. X
  1990. X    if (FileFromHome == NULL) {
  1991. X        return;
  1992. X    }
  1993. X
  1994. X    if(ioctl(FileFromHome, FIONREAD, &nread) < 0 || nread < 2){
  1995. X        return;
  1996. X    }
  1997. X
  1998. X    for(i = 0; i < nread; i++){
  1999. X        read(FileFromHome,buf+i,1);
  2000. X        if(buf[i] == '\n')
  2001. X            break;
  2002. X    }
  2003. X    buf[i] = '\0';
  2004. X
  2005. X    ToLog(DBMAJOR, "ReadInAny got %s\n", buf);
  2006. X}
  2007. X
  2008. X
  2009. X#define VERYRECENTLY 60*60
  2010. X
  2011. X/*  If this returns a 1 caller will not phone home, a 0 he will */
  2012. Xint PhonedVeryRecently()
  2013. X{
  2014. X    int Age;
  2015. X    char Version[100];
  2016. X
  2017. X    Age = SecsSinceWrite(PHONEHOMEPATH);
  2018. X
  2019. X    if (((Age >0) && (Age < VERYRECENTLY))                     /* if phoned recently                 */
  2020. X#ifdef ALEXVERSION
  2021. X         && (StringFromFile(PHONEHOMEPATH, Version) == AOK)    /* and can read last version          */
  2022. X         && (streql(Version, ALEXVERSION))                     /* and it is this version             */
  2023. X#endif
  2024. X        ) { 
  2025. X            return(1);                                        /* tell caller NOT to phone home      */
  2026. X    } else {
  2027. X#ifdef ALEXVERSION
  2028. X        StringIntoFile(PHONEHOMEPATH, ALEXVERSION);           /* save current version and set mtime */
  2029. X#endif
  2030. X        return(0);                                            /* tell caller to phone home          */
  2031. X    }
  2032. X}
  2033. X
  2034. XExit()
  2035. X{
  2036. X    exit(-24);
  2037. X}
  2038. X
  2039. X/*   PhoneHome is either for sending mail back to Vince, or for appending information
  2040. X *   to a log that Vince can access through Alex.  We send mail if MAILPERFSTATS is
  2041. X *   defined and if not then append to FTPABLEPERFLOG
  2042. X *
  2043. X *   Could fork() so that mail Alex is not stopped by sending mail.
  2044. X */
  2045. X
  2046. Xextern void PhoneHome(PhoneType, HomeString, SrcFile, SrcLine)
  2047. Xint  PhoneType;
  2048. Xchar *HomeString;
  2049. Xchar *SrcFile;
  2050. Xint  SrcLine;
  2051. X{
  2052. X    int HowSending, i;
  2053. X
  2054. X
  2055. X    FileToHome=NULL;
  2056. X    FileFromHome= NULL;
  2057. X
  2058. X    ToLog(DBMAJOR, "PhoneHome Type= %d  File= %s Line= %d\n", PhoneType, SrcFile, SrcLine);
  2059. X
  2060. X#if !defined(MAILPERFSTATS) && !defined(FTPABLEPERFLOG)
  2061. X    ToLog(DBMAJOR, "PhoneHome neither MAILPERFSTATS nor FTPABLEPERFLOG is defined \n");
  2062. X    return;
  2063. X#else
  2064. X
  2065. X    if (PhonedVeryRecently() && ((PhoneType == 1) || (PhoneType == 2))) {
  2066. X        ToLog(DBMAJOR, "PhoneHome recently phoned home so not going to now\n");
  2067. X        return;
  2068. X    }
  2069. X    
  2070. X    (void) signal(SIGALRM, Exit);
  2071. X    (void) alarm(300);
  2072. X
  2073. X#ifdef MAILPERFSTATS
  2074. X    if (TryUCBMail(PhoneType) == AOK) {
  2075. X        HowSending=2;
  2076. X    } else {
  2077. X        ToLog(DBERROR, "Could not use ucb mail - will try to smtp myself \n");
  2078. X        if ((PHConnectTo(HOMEHOST, PhoneType) != AOK) &&
  2079. X            (PHConnectTo(PROXY_FTP_HOST, PhoneType) != AOK) &&
  2080. X            (PHConnectTo(SERVERHOSTNAME, PhoneType) != AOK)) {
  2081. X                ToLog(DBERROR, "PhoneHome ERROR can NOT use smtp \n");
  2082. X                alarm(0);
  2083. X                return;
  2084. X        }
  2085. X        HowSending=1;
  2086. X    }
  2087. X#else 
  2088. X    FileToHome= AFOPEN(FTPABLEPERFLOG, "a");
  2089. X    if (FileToHome == NULL) {
  2090. X        ToLog(DBERROR, "PhoneHome ERROR can not open FTPABLEPERFLOG %s\n", FTPABLEPERFLOG);
  2091. X        alarm(0);
  2092. X        return;
  2093. X    }
  2094. X    HowSending=3;
  2095. X    ToLog(DBMAJOR, "PhoneHome has done fopen for %s\n", FTPABLEPERFLOG);
  2096. X#endif
  2097. X    
  2098. X#ifdef ALEXVERSION
  2099. X                SendHome("ALEXVERSION      %s\n", ALEXVERSION);
  2100. X#else 
  2101. X                SendHome("ALEXVERSION      Not a release\n");
  2102. X#endif
  2103. X    SendHome("HostName         %s\n", SERVERHOSTNAME); 
  2104. X    
  2105. X    SendHome("PhoneHome Type= %d  File= %s Line= %d\n", PhoneType, SrcFile, SrcLine);
  2106. X
  2107. X    SendHome("PhoneHome HowSending  %d\n", HowSending);
  2108. X
  2109. X    fputs(HomeString, FileToHome);                             /* custom string from caller */
  2110. X    ToLog(DBMAJOR, HomeString);
  2111. X
  2112. X    if (PhoneType < 1) {
  2113. X        ToLog(DBERROR, "PhoneHome ERROR bogus type %d \n", PhoneType);
  2114. X    }
  2115. X
  2116. X    fflush(FileToHome);
  2117. X    if (ferror(FileToHome)) {
  2118. X        ToLog(DBERROR, "PhoneHome ERROR in sending mail\n");
  2119. X    }
  2120. X
  2121. X    switch (HowSending) {
  2122. X         case 1:    SendHome(".\n");
  2123. X                    SendHome("quit\n");
  2124. X                    for (i=0; i<30; i++) {
  2125. X                        sleep(1);              /* Should check for closing info coming back but ... */
  2126. X                        ReadInAny();
  2127. X                    }
  2128. X                    fclose(FileToHome);
  2129. X                    close(FdHome);
  2130. X                    break;
  2131. X         case 2:    pclose(FileToHome);
  2132. X                    break;
  2133. X
  2134. X         case 3:    AFCLOSE(FileToHome);
  2135. X                    break;
  2136. X    
  2137. X         default:   ToLog(DBERROR, "PhoneHome switch\n");
  2138. X                    abort();
  2139. X   }
  2140. X
  2141. X#endif
  2142. X
  2143. X   alarm(0);
  2144. X   ToLog(DBMAJOR, "PhoneHome finished \n");
  2145. X}
  2146. X
  2147. X
  2148. X
  2149. Xextern void AlexAssertFailed(SrcFile, SrcLine, UsePhone)
  2150. Xchar *SrcFile;
  2151. Xint   SrcLine;
  2152. Xint   UsePhone;                    /* We don't phone home about AlexAssertSetup problems */
  2153. X{
  2154. X    char HomeString[1000];
  2155. X    
  2156. X    sprintf(HomeString, "AlexAssertFailed  File= %s Line = %d \n", SrcFile, SrcLine);
  2157. X    ToLog(DBERROR, HomeString);
  2158. X    flushLog();
  2159. X
  2160. X    if (UsePhone) {
  2161. X        PhoneHome(3, HomeString, SrcFile, SrcLine);
  2162. X        flushLog();
  2163. X    } else {
  2164. X        ToLog(DBERROR, "This seems to be a setup problem.\n");
  2165. X    }
  2166. X
  2167. X    abort();
  2168. X}
  2169. X
  2170. X
  2171. END_OF_FILE
  2172.   if test 11298 -ne `wc -c <'alexsrvr/src/phonehome.c'`; then
  2173.     echo shar: \"'alexsrvr/src/phonehome.c'\" unpacked with wrong size!
  2174.   fi
  2175.   # end of 'alexsrvr/src/phonehome.c'
  2176. fi
  2177. if test -f 'alexsrvr/src/readinfo.c' -a "${1}" != "-c" ; then 
  2178.   echo shar: Will not clobber existing file \"'alexsrvr/src/readinfo.c'\"
  2179. else
  2180.   echo shar: Extracting \"'alexsrvr/src/readinfo.c'\" \(29458 characters\)
  2181.   sed "s/^X//" >'alexsrvr/src/readinfo.c' <<'END_OF_FILE'
  2182. X
  2183. X/* Copyright (c) 1992 Vincent Cate
  2184. X * All Rights Reserved.
  2185. X *
  2186. X * Permission to use and modify this software and its documentation
  2187. X * is hereby granted, provided that both the copyright notice and this
  2188. X * permission notice appear in all copies of the software, derivative works
  2189. X * or modified versions, and any portions thereof, and that both notices
  2190. X * appear in supporting documentation.  This software or any derivate works
  2191. X * may not be sold or distributed without prior written approval from
  2192. X * Vincent Cate.
  2193. X *
  2194. X * THE SOFTWARE IS PROVIDED "AS IS" AND VINCENT CATE DISCLAIMS ALL
  2195. X * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  2196. X * WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL
  2197. X * VINCENT CATE BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  2198. X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  2199. X * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  2200. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  2201. X * OR PERFORMANCE OF THIS SOFTWARE.
  2202. X *
  2203. X * Users of this software agree to return to Vincent Cate any improvements
  2204. X * or extensions that they make and grant Vincent Cate the rights to
  2205. X * redistribute these changes.
  2206. X *
  2207. X */
  2208. X
  2209. X
  2210. X
  2211. X/* Exports:
  2212. X *    AlexInfoLStat()      -   sort of like an lstat but uses a .alex.info
  2213. X *    AlexInfoInOpen()     -   Use macro ALEXINFOINOPEN
  2214. X *    AlexInfoInNext()     -   read lines from a .alex.info
  2215. X *    AlexInfoCompatStat() - silly old compatability routine
  2216. X *    AlexInfoMTime()      -   given Inode returns MTime if in cache
  2217. X */
  2218. X
  2219. X#include "alexincs.h"
  2220. X#include "alex.h"
  2221. X
  2222. X#define MAXTOKENS  11
  2223. X#define MAXTLEN   200 
  2224. X
  2225. X
  2226. Xint CallAlexOnDirForFile(FullPath, UidStr)
  2227. Xchar *FullPath, *UidStr;
  2228. X{
  2229. X    char DirPath[MAXPATH];
  2230. X
  2231. X    PathToDir(FullPath, DirPath);
  2232. X    return(CheckFileCache(DirPath, UidStr));
  2233. X}
  2234. X
  2235. Xint ClearActiveAlexInfo(AAIPtr)
  2236. Xstruct ActiveAlexInfo *AAIPtr;
  2237. X{
  2238. X    if (AAIPtr == NULL) {
  2239. X        Log("ClearActiveAlexInfo got a NULL pointer");
  2240. X        return(AFAIL);
  2241. X    }
  2242. X
  2243. X    AAIPtr->File=NULL;                                          /* clear */
  2244. X    AAIPtr->HasAlexError=0;
  2245. X    AAIPtr->NeedAnUpdate=0;
  2246. X    AAIPtr->PartsInHostName=0;
  2247. X    AAIPtr->PartsInDirPath=0;
  2248. X    AAIPtr->SizeOk=0;
  2249. X    AAIPtr->Version=0;
  2250. X    AAIPtr->UpdateDate=0;
  2251. X    AAIPtr->NewestDate=0;
  2252. X
  2253. X    return(AOK);
  2254. X}
  2255. X
  2256. X
  2257. X/* Recursion means calling CheckFileCache
  2258. X */
  2259. Xextern int AlexInfoInOpen(AlexInfoPath, AAIPtr, UidStr, RecursionOk, srcfile, srcline)
  2260. Xchar *AlexInfoPath;
  2261. Xstruct ActiveAlexInfo *AAIPtr;
  2262. Xchar   *UidStr;
  2263. Xint    RecursionOk;
  2264. Xchar   *srcfile;
  2265. Xint    srcline;
  2266. X{
  2267. X    struct stat buf;
  2268. X    int Status;
  2269. X    char *NameOfFileToOpen;
  2270. X
  2271. X    Status=ClearActiveAlexInfo(AAIPtr);
  2272. X    if (Status != AOK) {
  2273. X        return(AFAIL);
  2274. X    }
  2275. X                                        /* /usr2/alex-cache/edu/berkeley/.alex.info is 4 */ 
  2276. X    AAIPtr->PartsInDirPath = CountOccurrences(AlexInfoPath, '/') -CACHEDIRPARTS -1;
  2277. X    if (AAIPtr->PartsInDirPath < 0) {
  2278. X        AAIPtr->PartsInDirPath = 0;
  2279. X    }
  2280. X    LogN("AlexInfoInOpen PartsInDirPath ", AAIPtr->PartsInDirPath);
  2281. X
  2282. X                          /* ROOTALEXINFOSTR could be something like /usr2/.alex.info  */
  2283. X    if (streql(AlexInfoPath, ROOTALEXINFOSTR) || streql(AlexInfoPath,    "/.alex.info")) {
  2284. X        Log2("AlexInfoInOpen had ", AlexInfoPath);
  2285. X        NameOfFileToOpen=ROOTALEXINFO;
  2286. X        AAIPtr->NeedAnUpdate = -1;            /* never try to update root */
  2287. X    } else {
  2288. X        NameOfFileToOpen=AlexInfoPath;
  2289. X    } 
  2290. X
  2291. X    Log2("AlexInfoInOpen with ", NameOfFileToOpen);
  2292. X
  2293. X    (void) strcpy(AAIPtr->OpenAlexInfoPath,  NameOfFileToOpen);
  2294. X
  2295. X
  2296. X#ifdef DEVNULLBROKEN                              /* just define this if /dev/null does not work */
  2297. X    if (streql(AlexInfoPath, "/dev/null")) {
  2298. X        Log("AlexInfoInOpen with /dev/null done ");
  2299. X        return(AOK);                              /* reads will fail which is all we need */
  2300. X    }
  2301. X#endif
  2302. X
  2303. X    if ((lstat(NameOfFileToOpen, &buf) != 0) ||                          /* try lstat */
  2304. X                 (RecursionOk && (buf.st_mtime < MINTIMEOKALEXINFO))) {  /* code to cleanup bad .alex.infos */
  2305. X        Log2("\n\n AlexInfoInOpen did not find this .alex.info ", NameOfFileToOpen);
  2306. X        if (!RecursionOk) {
  2307. X            return(AFAIL);
  2308. X        } else {
  2309. X            Status=CallAlexOnDirForFile(NameOfFileToOpen, UidStr);  /* ends in /.alex.info */
  2310. X            if (Status==AWORKING) {
  2311. X                LogT("AlexInfoInOpen done ", Status);
  2312. X                return(Status);
  2313. X            }
  2314. X            if (lstat(NameOfFileToOpen, &buf) != 0) {           /* try lstat again */
  2315. X                return(AFAIL);
  2316. X            } else {
  2317. X                Log2("\n\n AlexInfoInOpen got Alex to make ", NameOfFileToOpen);
  2318. X            }
  2319. X        }
  2320. X    }
  2321. X
  2322. X    Log2("AlexInfoInOpen has good stat for ", NameOfFileToOpen);
  2323. X
  2324. X    AAIPtr->File=afopen(NameOfFileToOpen,"r", srcfile, srcline);  /* caller resposible for close */
  2325. X    if (AAIPtr->File==NULL) {
  2326. X        Log2("AlexInfoInOpen could not open ", NameOfFileToOpen);
  2327. X        return(AFAIL);
  2328. X    }
  2329. X
  2330. X    AAIPtr->Version=ALEXINFOVERSION;         /* default to current version */
  2331. X    Log("AlexInfoInOpen done AOK");
  2332. X    return(AOK);
  2333. X}
  2334. X
  2335. X/* for unfsd we sort of emulating opendir
  2336. X */
  2337. Xextern int AlexOpenDir(DirPath, AAIPtr, UidStr)
  2338. Xchar *DirPath;
  2339. Xstruct ActiveAlexInfo *AAIPtr;
  2340. Xchar *UidStr;
  2341. X{
  2342. X    int Result;
  2343. X
  2344. X    char AlexInfoPath[MAXPATH];
  2345. X
  2346. X    (void) strcpy(AlexInfoPath, DirPath);
  2347. X    (void) SimplifyPath(AlexInfoPath);
  2348. X    if (streql(AlexInfoPath, "/")) {
  2349. X        (void) strcat(AlexInfoPath, ALEXINFO);
  2350. X    } else {
  2351. X        (void) strcat(AlexInfoPath, SLASHALEXINFO);
  2352. X    }
  2353. X
  2354. X    Result=ALEXINFOINOPEN(AlexInfoPath, AAIPtr, UidStr, RECURSIONOK);
  2355. X
  2356. X    LogT("AlexOpenDir done ", Result); 
  2357. X    return(Result);
  2358. X}
  2359. X
  2360. Xextern int AlexInfoInClose(AAIPtr)
  2361. Xstruct ActiveAlexInfo *AAIPtr;
  2362. X{
  2363. X    int Result;
  2364. X
  2365. X    if (AAIPtr->File == NULL) {
  2366. X        Result=AOK;                       /* might be done by AlexInfoInNext in error cases */
  2367. X    } else {
  2368. X        if (AFCLOSE(AAIPtr->File) == 0) {
  2369. X            Result=AOK;
  2370. X        } else {
  2371. X            Result=AFAIL;
  2372. X        }
  2373. X        AAIPtr->File=NULL;
  2374. X    }
  2375. X   
  2376. X    LogT("AlexInfoInClose returning ", Result); 
  2377. X    return(Result);
  2378. X}
  2379. X
  2380. X
  2381. X
  2382. Xint ParseOneLine(Line, Current, Version)
  2383. Xchar *Line;
  2384. Xstruct ParsedDir *Current;
  2385. Xint Version;
  2386. X{
  2387. X    char Tokens[MAXTOKENS][MAXTLEN];
  2388. X    int NumTokens, NumScanned, NoLinkSize, T;
  2389. X    int Result, GoodType, ShouldHaveSymLink;
  2390. X
  2391. X    NumTokens=LineToTokens(Line, Tokens);
  2392. X
  2393. X#define MAXTOKENINPARSEDLINE 6
  2394. X
  2395. X    if (NumTokens < (MAXTOKENINPARSEDLINE -1)) {
  2396. X        ToLog(DBERROR, "ParseOneLine ERROR BUG not enough tokens %d while working on %s\n", 
  2397. X                        NumTokens, Line);
  2398. X        return(AFAIL);
  2399. X    }
  2400. X
  2401. X    switch (Version) {
  2402. X       case 3:
  2403. X       case 4:                       /* version 3 and 4 are the same in data part */
  2404. X            NumScanned=1;  (void) strcpy(Current->Name, Tokens[0]);
  2405. X            if (StringToUnsigned(Tokens[1],  (unsigned *) &Current->Type) == AOK) NumScanned++;
  2406. X            if (StringToUnsigned(Tokens[2],  &Current->Size) == AOK) NumScanned++;
  2407. X            if (StringToUnsigned(Tokens[3],  &Current->Date) == AOK) NumScanned++;
  2408. X            if (StringToUnsigned(Tokens[4],  &Current->Inode) == AOK) NumScanned++;
  2409. X            if (NumTokens==MAXTOKENINPARSEDLINE) {
  2410. X                 NumScanned ++; (void) strcpy(Current->SymLink, Tokens[MAXTOKENINPARSEDLINE -1]);
  2411. X#ifdef EXECUTABLE
  2412. X                /* if the symlink is "-1", it's faked and we should mark the file executable */
  2413. X                if (streql(Current->SymLink,"-1")) {
  2414. X                     Current->Executable = 1;
  2415. X                     strcpy(Current->SymLink,"");
  2416. X                     --NumScanned;
  2417. X                }
  2418. X#endif
  2419. X            }
  2420. X            NoLinkSize=MAXTOKENINPARSEDLINE -1;
  2421. X            break;
  2422. X
  2423. X       default:
  2424. X            ToLog(DBERROR, "ParseOneLine ERROR BUG unknown Version %d\n", Version);
  2425. X            return(AFAIL);
  2426. X    }
  2427. X
  2428. X    T=Current->Type;
  2429. X    ShouldHaveSymLink = (T==ALINK) && (T=HOSTALIAS);
  2430. X    GoodType = (T==AFILE) || (T==ADIR) || (T==ALINK) || (T==AHOST) || 
  2431. X               (T==HOSTALIAS) || (T==AERRORMESSAGE) || (T==ADOMAIN) ;
  2432. X
  2433. X    if (GoodType &&                                                         /* if type is ok    */
  2434. X        ( ((NumScanned==NoLinkSize)   && (!ShouldHaveSymLink)) ||           /* and right # tokens */
  2435. X          ((NumScanned==NoLinkSize+1) &&  (ShouldHaveSymLink))   )  ) {
  2436. X        Result=AOK;                                                         /* then all is well  */
  2437. X    } else {
  2438. X        ToLog(DBERROR, "ParseOneLine ERROR BUG NumTokens=%d NumScanned= %d, Type= %s\n", 
  2439. X                       NumTokens, NumScanned, ATypeToString(Current->Type));
  2440. X        Result=AFAIL;
  2441. X    }
  2442. X
  2443. X    return(Result);
  2444. X}
  2445. X
  2446. X
  2447. Xstruct DirCacheEntry {
  2448. X    unsigned int Date;           /* MTime */
  2449. X    int    Inode;  
  2450. X};
  2451. X
  2452. X#define DIRINODECACHESIZE 50000
  2453. X
  2454. Xstruct DirCacheEntry DirInodeCache[DIRINODECACHESIZE];
  2455. X
  2456. X
  2457. Xextern unsigned int AlexInfoMTime(Inode)
  2458. Xunsigned int Inode;
  2459. X{
  2460. X   unsigned int MTime;
  2461. X   int Index;
  2462. X
  2463. X   Index = Inode % DIRINODECACHESIZE;
  2464. X
  2465. X   if (DirInodeCache[Index].Inode == Inode) {
  2466. X       MTime = DirInodeCache[Index].Date;
  2467. X       LogN("AlexInfoMTime hit on ", Inode);
  2468. X   } else {
  2469. X       MTime = 0;
  2470. X   }
  2471. X
  2472. X   return(MTime);
  2473. X}
  2474. X
  2475. X
  2476. X
  2477. X/*  Read next directory item from AAIPtr 
  2478. X *  Returns:
  2479. X *        AOK   - fine
  2480. X *        AEOF  - end of file
  2481. X *        AFAIL - did not work.
  2482. X *         
  2483. X */
  2484. Xextern int AlexInfoInNext(AAIPtr, Current)
  2485. Xstruct ActiveAlexInfo *AAIPtr;
  2486. Xstruct ParsedDir *Current;
  2487. X{
  2488. X    char line[MAXPATH+MAXPATH];
  2489. X    int NeedALine, Status, Result, Index;
  2490. X    double Now, Age, OkSlop, SecsSinceCheck;
  2491. X
  2492. X    if (AAIPtr->File == NULL) {
  2493. X        Log("AlexInfoInNext ERROR called with no open file");
  2494. X        return(AFAIL);
  2495. X    }
  2496. X
  2497. X    ClearParsedDirEntry(Current);
  2498. X
  2499. X    NeedALine=1;
  2500. X    Result=AFAIL;
  2501. X    while (NeedALine) {
  2502. X        NeedALine=0;
  2503. X        if(fgets(line, MAXPATH+MAXPATH, AAIPtr->File ) == NULL) {
  2504. X            return(AEOF);                                           /* that all folks */
  2505. X        }
  2506. X
  2507. X        if (line[0] == METACHAR) {
  2508. X            NeedALine=1;                                            /* not a data line */
  2509. X            Status=AOK;
  2510. X            switch (line[1]) {
  2511. X                case VERSCHAR:
  2512. X                    Status=StringToUnsigned(&line[2], (unsigned *) &(AAIPtr->Version)); 
  2513. X                    break; 
  2514. X
  2515. X                case DATECHAR:
  2516. X                    Status=StringToUnsigned(&line[2], (unsigned *) &(AAIPtr->UpdateDate)); 
  2517. X                    break; 
  2518. X
  2519. X                case NEWCHAR:
  2520. X                    Status=StringToUnsigned(&line[2], (unsigned *) &(AAIPtr->NewestDate)); 
  2521. X                    break; 
  2522. X
  2523. X                case SIZECHAR:
  2524. X                    Status=StringToUnsigned(&line[2], (unsigned *) &(AAIPtr->SizeOk)); 
  2525. X                    break; 
  2526. X
  2527. X                case HOSTPARTSCHAR:
  2528. X                    Status=StringToUnsigned(&line[2], (unsigned *) &(AAIPtr->PartsInHostName)); 
  2529. X                    break; 
  2530. X
  2531. X                case ERRORCHAR:
  2532. X                    AAIPtr->HasAlexError = 1; 
  2533. X                    break; 
  2534. X
  2535. X                case UPDATECHAR:
  2536. X                    if (AAIPtr->NeedAnUpdate >= 0) AAIPtr->NeedAnUpdate = 1; 
  2537. X                    break; 
  2538. X
  2539. X                default:
  2540. X                    Status=AFAIL;
  2541. X                    ToLog(DBERROR, "AlexInfoInNext ERROR BUG unknown meta-data type %c\n", line[1]);
  2542. X            }
  2543. X            
  2544. X            if (Status != AOK) {
  2545. X                ToLog(DBERROR, "AlexInfoInNext ERROR BUG meta-data problems Status= %s\n", 
  2546. X                         ATypeToString(Status));
  2547. X            }
  2548. X                
  2549. X        } else if ((strncmp(line, OLDVERSIONTOKEN, strlen(OLDVERSIONTOKEN)) == 0) && 
  2550. X             (CountOccurrences(line, ' ') == 1)) {                   /* one ping only  */
  2551. X            NeedALine=1;                                            /* in either case ignore */
  2552. X            if (StringToUnsigned(&line[strlen(OLDVERSIONTOKEN)], 
  2553. X                                   (unsigned *) &(AAIPtr->Version)) != AOK) {
  2554. X                ToLog(DBERROR, "AlexInfoInNext ERROR BUG StringToUnsigned of version %s\n", line);
  2555. X            }
  2556. X        }
  2557. X    }
  2558. X  
  2559. X
  2560. X    Result=ParseOneLine(line, Current, AAIPtr->Version); 
  2561. X    if (Result != AOK) {
  2562. X        Current->Stale = 1;                            /* all are stale         */
  2563. X        AAIPtr->HasAlexError=1;                        /* there is an error  */   
  2564. X        AAIPtr->NeedAnUpdate=1;                        /* there is an error  */   
  2565. X        ToLog(DBERROR, "AlexInfoInNext ERROR BUG could not read V= %d Name= %s Line= %s\n", 
  2566. X                                AAIPtr->Version, Current->Name, line);
  2567. X        return(Result);
  2568. X    } 
  2569. X
  2570. X    switch (Current->Type) {
  2571. X        case ADIR:    if (Current->Name[0] != '.') {
  2572. X                          Index = Current->Inode % DIRINODECACHESIZE;
  2573. X                          DirInodeCache[Index].Inode = Current->Inode;
  2574. X                          DirInodeCache[Index].Date  = Current->Date;  
  2575. X                      }
  2576. X                      /* fall through - no break */
  2577. X        case AERRORMESSAGE:
  2578. X        case AFILE:   Current->PartsInHostName = AAIPtr->PartsInHostName; 
  2579. X                      break;
  2580. X
  2581. X        case ADOMAIN: Current->PartsInHostName = -1;
  2582. X                      break;
  2583. X
  2584. X        case ALINK:
  2585. X        case HOSTALIAS:
  2586. X        case AHOST:   Current->PartsInHostName = AAIPtr->PartsInDirPath+1;
  2587. X                      break;
  2588. X
  2589. X        default:      LogT("AlexInfoInNext ERROR BUG funny type when getting PartsInHostName", Current->Type);
  2590. X    }
  2591. X
  2592. X    Current->Stale = 0;                            /* not known to be stale so far */
  2593. X    if (AAIPtr->NeedAnUpdate >=0) {
  2594. X        /* Now = TimeInSeconds(); */             /* do not need exact time */
  2595. X        Now = RecentTime;
  2596. X        /* Age = Now - Current->Date; */         /* real for this file */
  2597. X        Age = Now - AAIPtr->NewestDate;          /* but we are doing it on a directory level now XXXX */
  2598. X        if (Age < 60) {
  2599. X            Age=60;
  2600. X        }
  2601. X
  2602. X        SecsSinceCheck= Now - AAIPtr->UpdateDate;   /* time since since we looked */
  2603. X
  2604. X        if (SecsSinceCheck < 0) {
  2605. X            if (SecsSinceCheck > -(5 * AMINUTE)) {     /* overlook a small oddity :-) */
  2606. X                SecsSinceCheck=0;
  2607. X            } else {
  2608. X                ToLog(DBERROR, "AlexInfoInNext ERROR BUG in future SSC= %d Now= %d UD= %d Age= %d", 
  2609. X                         (int) SecsSinceCheck, (int) Now, (int) AAIPtr->UpdateDate, (int) Age);
  2610. X                SecsSinceCheck=1000;
  2611. X                Current->Stale = 1;                       /* an update might help (or loop) */
  2612. X            }
  2613. X        }
  2614. X  
  2615. X        OkSlop = Age / OKINCONSISTENCY;  /* reasonable inconsistency of 10 percent */
  2616. X        if (OkSlop < MINCONSSLOP) {
  2617. X            OkSlop = MINCONSSLOP;
  2618. X        }
  2619. X
  2620. X        if ((Current->Type == AERRORMESSAGE) || (AAIPtr->HasAlexError)) {
  2621. X            AAIPtr->HasAlexError=1;                        /* there is an error      */
  2622. X            if ((SecsSinceCheck > SECSTILLRETRY) &&
  2623. X                ((Current->Stale != 1) || (AAIPtr->NeedAnUpdate != 1)))  {
  2624. X                if (SecsSinceWrite(AAIPtr->OpenAlexInfoPath) > SECSTILLRETRY) {
  2625. X                    Current->Stale = 1;                                /* really astale XXXX  */
  2626. X                    AAIPtr->NeedAnUpdate=1;                         /* time for a retry    */
  2627. X                    ToLog(DBALL, "KnownStaleDir %s\n", AAIPtr->OpenAlexInfoPath);
  2628. X                }
  2629. X            }
  2630. X        } else {
  2631. X            if ((SecsSinceCheck > OkSlop) || (SecsSinceCheck > MAXSECSSINCECHECK)) {
  2632. X                Current->Stale = 1;                            /* not within spec for consistent */
  2633. X                AAIPtr->NeedAnUpdate=1;                        /* directory level now XXXXX */
  2634. X            } 
  2635. X        }
  2636. X    }
  2637. X
  2638. X
  2639. X    if (AAIPtr->NeedAnUpdate > 0) {
  2640. X        Current->Stale = 1;             /* all are stale */
  2641. X    }
  2642. X
  2643. X    if (AAIPtr->UpdateDate == 0) {    /* if "!D 0" in .alex.info never change - for RootAlexInfo */
  2644. X        AAIPtr->NeedAnUpdate = 0;
  2645. X        Current->Stale = 0;            
  2646. X    }
  2647. X
  2648. X    /* LogN("AlexInfoInNext sees SecsSinceCheck ", (int) SecsSinceCheck);
  2649. X     * LogN("AlexInfoInNext sees OkSlop ", (int) OkSlop); 
  2650. X     */
  2651. X
  2652. X                                         /* if Stale we would like to return AUPDATE */
  2653. X                                         /* problem is DirToInfo may be calling us on old things */
  2654. X    return(Result);
  2655. X}
  2656. X
  2657. X
  2658. Xextern int SimpleType(Type)
  2659. Xint Type;
  2660. X{
  2661. X    int Result;
  2662. X
  2663. X    switch(Type) {
  2664. X        case ADOMAIN:
  2665. X        case AHOST:
  2666. X        case ADIR:   Result=ADIR; 
  2667. X                     break;
  2668. X
  2669. X        case AERRORMESSAGE:
  2670. X        case AFILE:  Result= AFILE; 
  2671. X                     break;
  2672. X
  2673. X        case HOSTALIAS:
  2674. X        case ALINK:  Result= ALINK;
  2675. X                     break;
  2676. X
  2677. X        default:     Result=Type;     
  2678. X                     break;
  2679. X   }
  2680. X   return(Result);
  2681. X}
  2682. X
  2683. X#ifdef EXECUTABLE
  2684. Xint ATypeToStatMode(AType,IsExecutable)
  2685. Xint AType;
  2686. Xint IsExecutable;
  2687. X#else
  2688. Xint ATypeToStatMode(AType)
  2689. Xint AType;
  2690. X#endif
  2691. X{
  2692. X    int Result, Type;
  2693. X
  2694. X   /* Log2("ATypeToStatMode is called with ", ATypeToString(AType)); */
  2695. X
  2696. X    Type=SimpleType(AType);
  2697. X
  2698. X    switch (Type) {
  2699. X        case ADIR:   Result= S_IFDIR + 0755;
  2700. X                     break;
  2701. X
  2702. X        case AFILE:
  2703. X#ifdef EXECUTABLE
  2704. X                     if (IsExecutable) {
  2705. X                         Result= S_IFREG + 0755;
  2706. X                     } else {
  2707. X#endif
  2708. X                         Result= S_IFREG + 0644;
  2709. X#ifdef EXECUTABLE
  2710. X                     }
  2711. X#endif
  2712. X                     break;
  2713. X
  2714. X        case ALINK:  Result= S_IFLNK + 0777;
  2715. X                     break;
  2716. X
  2717. X        default:     ToLog(DBERROR, "ATypeToStatMode ERROR BUG %d\n", AType);
  2718. X                     Result= S_IFDIR + 0444;
  2719. X    }
  2720. X
  2721. X    return(Result);
  2722. X}
  2723. X
  2724. XStandardStat(StatBuf)
  2725. Xstruct stat *StatBuf;
  2726. X{
  2727. X    StatBuf->st_dev=1;
  2728. X    StatBuf->st_nlink=1;
  2729. X    StatBuf->st_rdev=1; 
  2730. X    StatBuf->st_uid=ALEXUIDVAR; 
  2731. X    StatBuf->st_gid=ALEXGIDVAR;
  2732. X    StatBuf->st_blksize=1024; 
  2733. X/*    StatBuf->st_spare1=0;
  2734. X    StatBuf->st_spare2=0;
  2735. X    StatBuf->st_spare3=0;
  2736. X    StatBuf->st_spare4[0]=0;
  2737. X    StatBuf->st_spare4[1]=0;
  2738. X */
  2739. X}
  2740. X
  2741. Xint ParsedDirToStat(Current, StatBuf)
  2742. Xstruct ParsedDir *Current;
  2743. Xstruct stat *StatBuf;
  2744. X{
  2745. X
  2746. X
  2747. X    if (Current->Inode != 0) {
  2748. X        StatBuf->st_ino=Current->Inode;
  2749. X    } else {
  2750. X        ToLog(DBERROR, "ParsedDirToStat ERROR BUG why does this happen? %d\n", (int) InodeNext);
  2751. X        StatBuf->st_ino=InodeNext++;
  2752. X    }
  2753. X
  2754. X#ifdef EXECUTABLE
  2755. X    StatBuf->st_mode=ATypeToStatMode(Current->Type,Current->Executable);
  2756. X#else
  2757. X    StatBuf->st_mode=ATypeToStatMode(Current->Type);
  2758. X#endif
  2759. X
  2760. X    StatBuf->st_size=Current->Size; 
  2761. X    StatBuf->st_blocks= 1 + (Current->Size / 512);
  2762. X
  2763. X    StatBuf->st_atime=Current->Date;
  2764. X    StatBuf->st_mtime=Current->Date;
  2765. X    StatBuf->st_ctime=Current->Date;
  2766. X
  2767. X    StandardStat(StatBuf);
  2768. X}
  2769. X
  2770. X
  2771. X
  2772. X/* Currently the StatCache module does not help and is not used.
  2773. X * It causes many copies and strcmp()s.
  2774. X * Wish AlexInfoLStat was given Inode number when known, we could compare 
  2775. X * much faster with that and get rid of the strcmp time at least.        XXXXX  */
  2776. X
  2777. X#ifdef USESTATCACHE
  2778. X/************************* StatCache module  ***************************
  2779. X *   This module only the following entries:
  2780. X *      ClearStatCache()
  2781. X *      AddToStatCache()
  2782. X *      CheckStatCache()
  2783. X */
  2784. X
  2785. X#define STATCACHESIZE 2       /* We need at least 2 */
  2786. X
  2787. Xstruct StatCacheEntry {
  2788. X    struct ParsedDir Current;
  2789. X    char Path[MAXPATH];
  2790. X} StatCache[STATCACHESIZE];
  2791. X
  2792. Xint    StatCacheNextIndex=0;                            /* where next will go */
  2793. Xint    StatCacheNumInCache=0;
  2794. X
  2795. X/*****/
  2796. X
  2797. XClearStatCache()
  2798. X{
  2799. X    StatCacheNumInCache=0;
  2800. X    StatCacheNextIndex=0;
  2801. X}
  2802. X
  2803. XAddToStatCache(Path, PtrCurrent)
  2804. Xchar *Path;
  2805. Xstruct ParsedDir *PtrCurrent;
  2806. X{
  2807. X    (void) strcpy(StatCache[StatCacheNextIndex].Path, Path);
  2808. X    CopyParsedDir(PtrCurrent, &StatCache[StatCacheNextIndex].Current);
  2809. X
  2810. X    StatCacheNextIndex = (StatCacheNextIndex + 1) % STATCACHESIZE;
  2811. X    if (StatCacheNumInCache < STATCACHESIZE) {
  2812. X        StatCacheNumInCache++;
  2813. X    }
  2814. X}
  2815. X
  2816. Xint CheckStatCache(Path, PtrCurrent)
  2817. Xchar *Path;
  2818. Xstruct ParsedDir *PtrCurrent;
  2819. X{
  2820. X    int i, MatchStatus;
  2821. X
  2822. X    MatchStatus = AFAIL;
  2823. X    for (i=0; MatchStatus == AFAIL && i<STATCACHESIZE && i<StatCacheNumInCache; i++) {
  2824. X        if (streql(StatCache[i].Path, Path)) {
  2825. X           MatchStatus = AOK;
  2826. X           CopyParsedDir(&StatCache[i].Current, PtrCurrent);
  2827. X        }
  2828. X    }
  2829. X    return(MatchStatus);
  2830. X}
  2831. X
  2832. X/************************* End of StatCache module  ***************************/
  2833. X#endif
  2834. X
  2835. X
  2836. Xint InvalidateStatCache;                           /* outsiders can change this */
  2837. X
  2838. X/*  It is important that for the case where stats are in order that
  2839. X *  we end up only reading the .alex.info once.  Cache open file
  2840. X *  and position in that file.
  2841. X *
  2842. X *  Recursion means calling Alex
  2843. X *
  2844. X *  Given a "FullPathArg" of /usr2/alexsrvr/alex-cache/edu/cmu/cs
  2845. X *  This looks up "cs" in /usr2/alexsrvr/alex-cache/edu/cmu/.alex.info
  2846. X *
  2847. X *  RecursionOk means we can call CheckFileCache 
  2848. X *
  2849. X */
  2850. Xextern int AlexInfoLStat(FullPathArg, Result, UidStr, RecursionOk)
  2851. Xchar *FullPathArg;
  2852. Xstruct ParsedDir *Result;
  2853. Xchar   *UidStr;
  2854. Xint    RecursionOk;
  2855. X{
  2856. X    char   FullPath[MAXPATH];
  2857. X    static char CurrentOpenAlexInfo[MAXPATH];
  2858. X    static char KnownBadAlexInfo[MAXPATH];
  2859. X    static struct ActiveAlexInfo SAAI;              /* Static AAI           */
  2860. X    struct ActiveAlexInfo AAI;                      /* our own AAI           */
  2861. X    static int SomethingOpen=0;
  2862. X    static struct ParsedDir Current;
  2863. X    static int Status=AFAIL;                        /* status of Current now */
  2864. X    int TmpStatus;
  2865. X    char AlexInfoPath[MAXPATH], FileName[MAXPATH];
  2866. X    struct stat s2;                                 
  2867. X
  2868. X    AlexAssert(FullPathArg != NULL);
  2869. X    AlexAssert(FullPathArg[0] != 0);
  2870. X
  2871. X    strcpy(FullPath, FullPathArg);
  2872. X    (void) SimplifyPath(FullPath);
  2873. X
  2874. X    PathToDir(FullPathArg, AlexInfoPath);
  2875. X    (void) SimplifyPath(AlexInfoPath);
  2876. X    (void) strcat(AlexInfoPath, SLASHALEXINFO);
  2877. X
  2878. X    Log2("AlexInfoLStat with ", AlexInfoPath);
  2879. X    LogN(UidStr, RecursionOk);
  2880. X
  2881. X    (void) PathToFileName(FullPath, FileName);
  2882. X
  2883. X    if ((!InvalidateStatCache) && (streql(AlexInfoPath, KnownBadAlexInfo))) {
  2884. X        Log2("AlexInfoLStat  using info failure cache ", FullPath);
  2885. X        return(AFAIL);
  2886. X    } 
  2887. X
  2888. X    if (!InvalidateStatCache) {
  2889. X#ifdef USESTATCACHE
  2890. X        if (CheckStatCache(FullPath, Result) == AOK) {            /* note copies to Result if AOK */
  2891. X            Log2("AlexInfoLStat got a cache hit ", FullPath);
  2892. X            return(AOK);
  2893. X        }
  2894. X#else   
  2895. X        if ((Status == AOK) &&  streql(AlexInfoPath, CurrentOpenAlexInfo) &&
  2896. X            (streql(FileName, Current.Name)) && SomethingOpen) {    
  2897. X            Log2("AlexInfoLStat cache hit", FullPath);
  2898. X            CopyParsedDir(&Current, Result);
  2899. X            return(Status);
  2900. X        }
  2901. X#endif
  2902. X    } else { /* InvalidateStatCache */
  2903. X#ifdef USESTATCACHE
  2904. X        ClearStatCache();
  2905. X#endif
  2906. X
  2907. X        if (SomethingOpen) {
  2908. X            (void) AlexInfoInClose(&SAAI);
  2909. X            SomethingOpen=0;
  2910. X        }
  2911. X        KnownBadAlexInfo[0]=0;
  2912. X        CurrentOpenAlexInfo[0]=0;
  2913. X
  2914. X        InvalidateStatCache=0;                  /* we are making a new entry not using cache */
  2915. X    }
  2916. X
  2917. X    if (FileName[0] == 0) {
  2918. X        Log("AlexInfoLStat NULL filename - adding .");
  2919. X        strcat(FileName, ".");
  2920. X    }
  2921. X
  2922. X    (void) ClearParsedDirEntry(&Current);
  2923. X
  2924. X    Status=AOK;
  2925. X    if ((!SomethingOpen) || (!streql(AlexInfoPath, CurrentOpenAlexInfo))) {
  2926. X        CurrentOpenAlexInfo[0]=0;
  2927. X        if (Status == AOK) {   
  2928. X            Status=ALEXINFOINOPEN(AlexInfoPath, &AAI, UidStr, RecursionOk);
  2929. X            if (Status == AWORKING) {                                        /* do the open */
  2930. X                return(Status);
  2931. X            }
  2932. X            if (Status != AOK) {                      
  2933. X                (void) strcpy(KnownBadAlexInfo, AlexInfoPath);
  2934. X                (void) AlexInfoInClose(&AAI);                                /* should not need  */
  2935. X                Status=AFAIL;
  2936. X            } else { 
  2937. X                if (SomethingOpen) {
  2938. X                    Status=AlexInfoInClose(&SAAI);                           
  2939. X                    SomethingOpen=0;
  2940. X                }
  2941. X                Status=AOK;
  2942. X                SAAI=AAI;                                                    /* copy to static   */
  2943. X                SomethingOpen=1;                                             /* new active one */
  2944. X                (void) strcpy(CurrentOpenAlexInfo, AlexInfoPath);
  2945. X            }
  2946. X        }
  2947. X    }
  2948. X
  2949. X    if (Status==AOK) {                                   /* if AOK then AAI has right file open */
  2950. X        Status=AlexInfoInNext(&SAAI, &Current);                           /* first try next item */
  2951. X        if ((Status != AOK) || (!streql(Current.Name, FileName))) {
  2952. X            Log2("AlexInfoLStat going back to begining of file looking for ", FileName);
  2953. X            if (fseek(SAAI.File, (long) 0, 0)) {
  2954. X                Log2("AlexInfoLStat ERROR fseek failed", FileName);
  2955. X                (void) AlexInfoInClose(&SAAI);
  2956. X                SomethingOpen=0;
  2957. X                Status=AFAIL;                                              /* going back failed  */
  2958. X            } else {
  2959. X                Status=AOK;
  2960. X                while((Status==AOK) && !streql(Current.Name, FileName)) {  /* goes at least once */
  2961. X                    Status=AlexInfoInNext(&SAAI, &Current);                /* get new Current    */
  2962. X                }
  2963. X            }
  2964. X        }
  2965. X    }
  2966. X
  2967. X    if ((Status != AOK) || !streql(Current.Name, FileName)) {      /* if still not there */
  2968. X        Log2("AlexInfoLStat found No such file as ", FileName);    /* no such file */
  2969. X        Result->PartsInHostName=SAAI.PartsInHostName;              /* what host we checked - alex.c uses */
  2970. X        (void) AlexInfoInClose(&SAAI);
  2971. X        SomethingOpen=0;
  2972. X        Status=NOSUCHFILE;
  2973. X        LogT("AlexInfoLStat ", Status);
  2974. X        CopyParsedDir(&Current, Result);                           /* might want to know if was stale */
  2975. X        return(Status);
  2976. X    }
  2977. X
  2978. X    /* At this point Status == AOK */
  2979. X
  2980. X    if ( ! SAAI.SizeOk) {                                           /* if could not parse sizes */
  2981. X        if (lstat(FullPath, &s2) == 0) {                            /* if we have file in cache */
  2982. X            Current.Size=s2.st_size;                                /* use size of one in cache */
  2983. X        }
  2984. X        Current.SizeTrusted=0;
  2985. X    } else {
  2986. X        Current.SizeTrusted=1;                                 /* size comes from good .alex.dir */
  2987. X    }
  2988. X
  2989. X              
  2990. X
  2991. X    if ((Status==AOK) && (Current.SizeTrusted) && (!Current.Stale)) {
  2992. X#ifdef USESTATCACHE
  2993. X        AddToStatCache(FullPath, &Current);
  2994. X#endif
  2995. X    } else {
  2996. X        if ((Status != AWORKING) && RecursionOk && Current.Stale) {
  2997. X             Status=AFAIL;                  /* really AOK, but just so we don't use Current as cache */
  2998. X             TmpStatus=CallAlexOnDirForFile(FullPath, UidStr);  
  2999. X             Status=AFAIL;                  /* really AOK, but just so we don't use Current as cache */
  3000. X             if ((TmpStatus != NOSUCHFILE) && (TmpStatus != AFAIL)) {
  3001. X                 return(AWORKING);          /* make caller retry later no matter what */
  3002. X             } else {
  3003. X                 return(AFAIL);
  3004. X             }
  3005. X        }
  3006. X        Status=AFAIL;        /* really AOK, but just so we don't use Current as cache */
  3007. X    } 
  3008. X
  3009. X    CopyParsedDir(&Current, Result);       
  3010. X
  3011. X    ToLog(DBALL, "AlexInfoLStat %s %s %d\n", FullPath, ATypeToString(Current.Type), Current.Inode); 
  3012. X    return(AOK);
  3013. X}
  3014. X
  3015. X
  3016. X
  3017. X/* For compatability we fill in a regular stat struct 
  3018. X * For incompatability we use Alex types not regular return codes for lstat 
  3019. X *
  3020. X * Recursion means calling Alex
  3021. X */
  3022. Xextern int AlexInfoCompatStat(FullPath, StatBuf, Current, UidStr, RecursionOk)
  3023. Xchar        *FullPath;
  3024. Xstruct stat *StatBuf;
  3025. Xstruct ParsedDir *Current;
  3026. Xchar          *UidStr;
  3027. Xint          RecursionOk;
  3028. X{
  3029. X    int  Status;
  3030. X    struct ParsedDir CurrentBuf;
  3031. X    char LocalPath[MAXPATH], LastOfPath[MAXPATH];
  3032. X
  3033. X    Log2("AlexInfoCompatStat", FullPath);
  3034. X
  3035. X    if (UidStr==NULL) {
  3036. X        UidStr=LastUidStr;
  3037. X    }
  3038. X
  3039. X    if (Current == NULL) {
  3040. X        Current = &CurrentBuf;
  3041. X    }
  3042. X
  3043. X    (void) strcpy(LocalPath, FullPath);
  3044. X    Status=SimplifyPath(LocalPath);
  3045. X    PathToFileName(LocalPath, LastOfPath);
  3046. X
  3047. X    if (streql(LastOfPath, ALEXUPDATE)) {
  3048. X        if (!RecursionOk) {
  3049. X            ToLog(DBERROR, "AlexInfoCompatStat ERROR BUG recursion needed for .alex.update %s\n",
  3050. X                                                             LocalPath);
  3051. X        }
  3052. X        Status=CheckFileCache(LocalPath, UidStr);            /* don't need DirForFile since .alex.update */
  3053. X        if (Status == AWORKING) {
  3054. X            return(Status);
  3055. X        } else {
  3056. X            return(AFAIL);
  3057. X        }
  3058. X    }
  3059. X
  3060. X    Status=AlexInfoLStat(LocalPath, Current, UidStr, RecursionOk);
  3061. X                 /* if recursion is Ok and helps AlexInfoLStat will do it so we don't need to here */
  3062. X    if (Status == AOK) {
  3063. X        LogN("AlexInfoCompatStat has current inode ", (int) Current->Inode);
  3064. X        if ((debugLog != NULL) && (DEBUGLEVEL >= 10)) {
  3065. X            OneLineOut(debugLog, Current);
  3066. X        }
  3067. X        (void) ParsedDirToStat(Current, StatBuf);
  3068. X        LogN("AlexInfoCompatStat has stat inode ", (int) StatBuf->st_ino);
  3069. X        errno=0;
  3070. X    } else {
  3071. X        ToLog(DBALL, "AlexInfoCompatStat returning %s for %s\n", ATypeToString(Status), FullPath);
  3072. X    }
  3073. X    
  3074. X    return(Status);
  3075. X}
  3076. X
  3077. X
  3078. X
  3079. END_OF_FILE
  3080.   if test 29458 -ne `wc -c <'alexsrvr/src/readinfo.c'`; then
  3081.     echo shar: \"'alexsrvr/src/readinfo.c'\" unpacked with wrong size!
  3082.   fi
  3083.   # end of 'alexsrvr/src/readinfo.c'
  3084. fi
  3085. echo shar: End of archive 8 \(of 13\).
  3086. cp /dev/null ark8isdone
  3087. MISSING=""
  3088. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  3089.     if test ! -f ark${I}isdone ; then
  3090.     MISSING="${MISSING} ${I}"
  3091.     fi
  3092. done
  3093. if test "${MISSING}" = "" ; then
  3094.     echo You have unpacked all 13 archives.
  3095.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3096. else
  3097.     echo You still must unpack the following archives:
  3098.     echo "        " ${MISSING}
  3099. fi
  3100. exit 0
  3101. exit 0 # Just in case...
  3102.