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

  1. From: vac@CS.CMU.EDU (Vincent.Cate)
  2. Newsgroups: comp.sources.misc
  3. Subject: v42i048:  alex - NFS/FTP global filesystem, Part10/13
  4. Date: 30 Mar 1994 20:57:40 -0600
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <2nde74$jj4@sparky.sterling.com>
  9. X-Md4-Signature: 2da3bc68446579b01012dbc2598a6db0
  10.  
  11. Submitted-by: vac@CS.CMU.EDU (Vincent.Cate)
  12. Posting-number: Volume 42, Issue 48
  13. Archive-name: alex/part10
  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/src/alex.h alexsrvr/src/cmucs.c
  21. #   alexsrvr/src/defs.c alexsrvr/src/init.c
  22. #   alexsrvr/src/stringtotime.c alexsrvr/src/stringtotime.y
  23. # Wrapped by kent@sparky on Tue Mar 29 21:56:23 1994
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 10 (of 13)."'
  27. if test -f 'alexsrvr/src/alex.h' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'alexsrvr/src/alex.h'\"
  29. else
  30.   echo shar: Extracting \"'alexsrvr/src/alex.h'\" \(17110 characters\)
  31.   sed "s/^X//" >'alexsrvr/src/alex.h' <<'END_OF_FILE'
  32. X
  33. X#include "config.h"
  34. X
  35. X
  36. X#ifndef DEBUGLEVEL
  37. X#define DEBUGLEVEL 1
  38. X#endif
  39. X
  40. X/* The following can be renumbered.  Any that are <= DEBUGLEVEL
  41. X*  end up getting sent to the log.  For example, make DBDOTALEX 0 if you always
  42. X*  want to see the .alex.dir and .alex.info files         
  43. X*
  44. X*                 0      nothing to log - should not do this       */
  45. X#define DBERROR   1   /* errors only - minimal logging             */
  46. X#define DBMAJOR   2   /* only major calls - like to CheckAlexCache */
  47. X#define DBRPC     3   /* a line or two per RPC                     */
  48. X#define DBPERF    4   /* performance monitoring                    */
  49. X#define DBPERF2   5   /* more performance monitoring               */
  50. X#define DBFTP     6   /* all actual FTP details from parent side   */
  51. X#define DBFTPCHILD 7  /* all FTP details in childs own log         */
  52. X#define DBOPEN    9   /* opens and closes of files                 */
  53. X#define DBALL    10   /* log every random thing - lots of stuff    */
  54. X#define DBALLT   11   /* log everything and timestamp it           */
  55. X
  56. X#define DBDOTALEX 1000000  /* show .alex.dir and .alex.info files       */
  57. X
  58. X#define DEFAULTTIMEZONE 300     /* Eastern time if can not get remote timezone info back */
  59. X#define MAXWAITFORTIME  30      /* 30 seconds */
  60. X
  61. Xextern FILE *debugLog;
  62. X
  63. Xextern ToLog_c();
  64. Xextern Logcall_c();
  65. X
  66. X#if (DEBUGLEVEL != 0)
  67. X#define ToLog ToLog_c
  68. X#define Logcall Logcall_c
  69. X#else
  70. X#define ToLog     (void)       
  71. X#define Logcall   (void)
  72. X#endif
  73. X
  74. X
  75. X#define Log2(x, y)     ToLog(10, "%s : %s\n", x, y)
  76. X#define Log3(x, y, z)  ToLog(10, "%s : %s : %s \n", x, y, z)
  77. X#define LogN(x, y)     ToLog(10, "%s : %d \n",   x, y)
  78. X#define LogD(x, y)     ToLog(10, "%s : %f \n",   x, y)
  79. X#define LogT(x, t)     ToLog(10, "%s : %s \n", x, ATypeToString(t))
  80. X#define LogC(x, c)     ToLog(10, "%s : %c \n",   x, c)
  81. X#define Log(x)         ToLog(10, "%s \n",      x)
  82. X#define AlexAssert(x)      if (!(x)) AlexAssertFailed(__FILE__, __LINE__, 1);   /* phone home */
  83. X#define AlexAssertSetup(x) if (!(x)) AlexAssertFailed(__FILE__, __LINE__, 0);   /* just a setup thing */
  84. X
  85. Xextern error1();
  86. Xextern error2();
  87. Xextern double TimeStampLog();
  88. Xextern char *DateStr();
  89. Xextern char *CurrentDateStr();
  90. X
  91. X#define DONOTWAIT       0
  92. X#define DOWAIT          1
  93. X
  94. X#define AMINUTE           60
  95. X#define AHOUR             (60 * AMINUTE)
  96. X#define ADAY              (24 * AHOUR)
  97. X#define AWEEK             ( 7 * ADAY)
  98. X#define AMONTH            (30 * ADAY)
  99. X#define TRUSTTIMEZONE     (6*AMONTH)   /* we catch daylight savings, so no hurry really to recheck timezone */
  100. X#define TRUSTHOSTTYPE     AMONTH           /* if NOANONFTP don't go back for one month   */
  101. X#define SECSTILLRETRY     (10 * AMINUTE)   /* till we retry after major FTP error */
  102. X
  103. X#define MINCONSSLOP       (5 * AMINUTE)    /* minimum consistency promise */
  104. X                                           /* if file changes every minute, you loose */
  105. X
  106. X/* Will force an update off all .alex.info files older than this.  */
  107. X#define MINTIMEOKALEXINFO 690460771
  108. X
  109. X#define AFOPEN(x, t) afopen(x, t, __FILE__, __LINE__)
  110. X#define ALEXINFOINOPEN(m, n, o, p) AlexInfoInOpen(m, n, o, p, __FILE__, __LINE__)
  111. X
  112. X#define AFCLOSE(f) afclose(f, __FILE__, __LINE__)
  113. X
  114. X#define STARTDATA 20
  115. X
  116. X#define ROOTINODE 3                /* also in RootAlexInfo            */
  117. Xextern  char ROOTALEXINFOSTR[];    /* something like /usr2/.alex.info */
  118. Xextern  int  CACHEDIRLEN;          /* strlen(CACHEDIR)                */
  119. Xextern  char CACHEDIRVAR[];        /* alot like CACHEDIR              */
  120. Xextern  int  CACHEDIRPARTS;        /* number of directories           */
  121. Xextern  int  ALEXUIDVAR;
  122. Xextern  int  ALEXGIDVAR;
  123. X
  124. Xextern  int NumFinishedFtps;
  125. X
  126. X#define FTPWRAPPATH     "/usr/vac/alex/bin/ftpwrap"
  127. X#define FTPWRAP         "ftpwrap"
  128. X
  129. X#define ALEXDIR         ".alex.dir"
  130. X#define SLASHALEXDIR   "/.alex.dir"
  131. X
  132. X#define ALEXINFO        ".alex.info"
  133. X#define SLASHALEXINFO  "/.alex.info"
  134. X#define ALEXERROR       ".alex.error"
  135. X#define SLASHALEXERROR "/.alex.error" 
  136. X
  137. X#define ALEXUPDATE      ".alex.update"    /* accessing this file causes server to update dir */
  138. X#define SLASHALEXUPDATE "/.alex.update" 
  139. X
  140. X#define ALEXADDHOST     ".addhost"        /* if NOAUTOADDHOST only check if host if this is */
  141. X                                          /* at end of a path  */
  142. X
  143. X#define MAXPARTSINHOSTNAME 6 /* only a very few this long and never seen longer */
  144. X/* I only know of 2 hosts with 6 part names.  One is:
  145. X * USUHS.UCC.USUHS.NNMC.NAVY.MIL:131.158.4.3 CPU=VAX-8350 OS=VMS 5.0
  146. X */
  147. X
  148. X
  149. X#define MAXFTPSOPEN  10      /* note they also are closed after MAXIDLEFTP */
  150. X#define STRANGEOPENCOUNT 10  /* does not count FTPs - should not be this many files open */ 
  151. X
  152. X#define RemTimeZoneFAIL  24*60          /* unreasonable number of minutes */
  153. X
  154. X#define FILLCHAR '_'         /* what strange chars and spaces are replaced with in error messages */
  155. X
  156. X#define MAXPATH 500
  157. X
  158. X#define MAXTOKENS  11
  159. X#define MAXTOKENLEN   200
  160. X
  161. X#define RECURSIONOK 1
  162. X#define NORECURSION 0
  163. X
  164. X#define NoKillFtps  0
  165. X#define YesKillFtps 1
  166. X
  167. X#define BOGUSINODE  123456
  168. X
  169. X/*  C's enumerated types are not really portable and don't mix well with real ints
  170. X *  so I don't use them.
  171. X *
  172. X *  .alex.info needs AFILE, ADIR, ALINK to not change (can remove all .alex.info if need to)
  173. X */
  174. X#define AOK    0                   /* function did what was asked - we use fact that is zero */
  175. X#define AFAIL  1                   /* function failed */
  176. X#define AFILE  2                   /* type info (no failure implied) */
  177. X#define ADIR   3                   /* type info  "    "      "       */
  178. X#define AERRORMESSAGE    4         /* not a real file just an error message */
  179. X                                   /* 5 no longer used */
  180. X#define ALINK      6               /* a link on a remote host type info  */
  181. X#define NOSUCHFILE 7               /* */
  182. X#define AOLD       8               /* failed because we have old directory data              */
  183. X#define NOPWD      9               /* failed because it does not do PWD but don't know type  */
  184. X#define SOFTERROR  10              /* seems to be the type of error where a retry might work */
  185. X#define AEOF       11              /* were reading a file and got to the end                 */
  186. X#define AHOST      12              /* a directory for a host                                 */
  187. X#define AUPDATE    13              /* we found that directory information is out of date     */
  188. X#define AWORKING   14              /* Alex is working on that job but is not yet done        */
  189. X#define ANFSSTALE  15              /* Stale NFS Handle                                       */
  190. X#define NOSUCHHOST 16              /* even if there used to be such a host, there is not now */
  191. X                                   /* 17 no longer used */
  192. X#define MAKELINKSTOPARENT 18       /* only in dirtoinfo.c                                    */
  193. X#define MAKELINKSTOALEX   19       /* only in dirtoinfo.c                                    */
  194. X#define REMOVEALWAYS 20            /* always remove (unless just seconds old)                */
  195. X#define REMOVEMAYBE  21            /* if old then remove                                     */
  196. X#define REMOVENEVER  22            /* do not remove                                          */
  197. X#define ADOMAIN      23            /* we have something that is part of a hostname */
  198. X         /* XXXXXX UG.  ADOMAIN is in .alex.info as 23 so can not change but is a hosttype   */
  199. X         /* so mst be between MinHostType and MaxHostType.  Ug.                              */
  200. X         /* we use strings for the types below in HostsList so they can change */
  201. X#define MinHostType  ADOMAIN
  202. X#define NOANONFTP    ADOMAIN+1        /* this host does not alow anonymous ftp */
  203. X#define NEVERDOFTP   ADOMAIN+2        /* this host hates ftp attempts - dmscanb.cbr.dms.csiro.au */
  204. X#define UNIX         ADOMAIN+3        /* Unix */
  205. X#define ABSUNIX      ADOMAIN+4        /* Unix with absolute paths like /usr0/anon/pub/README */
  206. X#define CDMODE       ADOMAIN+5        /* unix but must use CDs to get around */
  207. X#define RELMODE      ADOMAIN+6        /* unix but use . as top */
  208. X#define DECVMS       ADOMAIN+7        /* VMS */
  209. X#define IBM          ADOMAIN+8        /* IBM */
  210. X#define TOPS20       ADOMAIN+9        /* TOPS20 */
  211. X#define DECTEN       ADOMAIN+10       /* DECTEN */
  212. X#define HOSTALIAS    ADOMAIN+11       /* need to keep track of these too - very similar to ALINK */
  213. X#define HPUX         ADOMAIN+12       /* only used in dirtoinfo */
  214. X#define DECVMS2      ADOMAIN+13       /* only used in dirtoinfo */
  215. X#define HENSA         ADOMAIN+14          /* uk.ac.hensa.micros */
  216. X#define NOVEL         ADOMAIN+15          /* Novel */
  217. X#define MaxHostType  NOVEL
  218. X#define UNKNOWN      MaxHostType+1   /* can not tell type - always largest type number */
  219. X
  220. X#define ALEXINFOVERSION  4           /* changes .alex.info's format changes  */
  221. X#define OLDVERSIONTOKEN "()"         /* compatibility with older shit    */
  222. X#define METACHAR      '!'             /* non directory info in .alex.info */
  223. X#define VERSCHAR      'V'             /* version number (ALEXINFOVERSION) */
  224. X#define DATECHAR      'D'             /* date last fetched                */
  225. X#define NEWCHAR       'N'             /* date of newest item in directory       */
  226. X#define SIZECHAR      'S'             /* 1 if we could parse the sizes of files */
  227. X#define HOSTPARTSCHAR 'H'             /* number of parts in hostname "cs.cmu.edu" is 3 */
  228. X#define ERRORCHAR     'E'             /* if there then there if a .alex.error type message */
  229. X#define UPDATECHAR    'U'             /* force and update on next use of this file */
  230. X
  231. Xstruct HostEntry {
  232. X    char   *Path;                    /* like /edu/berkeley                                        */
  233. X    int    Type;                     /* ADOMAIN, UNIX...                                          */
  234. X    int    TimeZone;                 /* in minutes from greenwich                                 */
  235. X    int    TimeLastCheck;            /* time we last checked with host about this info            */
  236. X    char   *TopDir;                  /* for places we keep a topdir for                           */
  237. X    char   *SymLink;                 /* if HOSTALIAS                                              */
  238. X                                     /* above is stuff that is saved in file below is dynamic     */
  239. X    int    Status;                   /* AFAIL / AOK / AWORKING                                    */
  240. X    int    NumErrorsSinceOk;         /* 0 add 1 for error clear when worked */
  241. X    unsigned int LastUsed;           /* Time last used                                            */
  242. X    int    PartsInHostName;          /* /edu/berkeley is 2                                        */
  243. X    int    PathLen;                  /* strlen(Path) = strlen("/edu/berkeley") = 13               */
  244. X    float  RespTime;
  245. X    float  KBPSec;
  246. X};
  247. X
  248. Xextern char SERVERHOSTNAME[];        /* name of host running alex  - myhostname  */
  249. X
  250. Xextern struct HostEntry *HostsTable[];    /* mostly just in alex but dirtoinfo uses too */
  251. Xextern int HostsInTable;
  252. X
  253. Xstruct ParsedDir {
  254. X    int          Type;               /* AFILE, ADIR, ALINK, AHOST    */
  255. X#ifdef EXECUTABLE
  256. X        int          Executable;                 /* if the file is trusted as executable */
  257. X#endif
  258. X    unsigned int Date;               /* same as NFS                  */
  259. X    unsigned int Size;               /* same as NFS                  */
  260. X    unsigned int Inode;              /* same as NFS                  */
  261. X    int          CacheStatus;        /* 0=NotThere  1=There          */
  262. X    char Name[MAXPATH];              /* like foo                     */
  263. X    char SymLink[MAXPATH];           /* except for /afs and /alex the link should be relative */
  264. X    int          Stale;              /* 0 if consistent enough 1 if stale */
  265. X    int          SizeTrusted;        /* 1 if sizes come from trusted .alex.dir like UNIX ones */
  266. X    int PartsInHostName;             /* cs.cmu.edu is 3                          */
  267. X};
  268. X
  269. Xstruct ActiveAlexInfo {
  270. X    int  Version;
  271. X    char OpenAlexInfoPath[MAXPATH];  /* path used for open of .alex.info              */
  272. X    int PartsInDirPath;              /* /usr2/alex-cache/edu/berkeley/.alex.info is 2 i.e. after CACHEDIR */
  273. X    unsigned int UpdateDate;         /* date of last fetch of .alex.dir               */
  274. X    unsigned int NewestDate;         /* date of newest item in directory              */
  275. X    int SizeOk;                      /* 1=parsed good sizes,  0=don't know sizes      */
  276. X    FILE *File;
  277. X    int PartsInHostName;             /* cs.cmu.edu is 3                               */
  278. X    int HasAlexError;                /* an .alex.error was included in this           */
  279. X    int NeedAnUpdate;                /* an old .alex.error was included in this - need an update */
  280. X};
  281. X
  282. X
  283. Xextern unsigned int InodeNext;
  284. X
  285. X/* UidToUidStr module */
  286. Xextern char  LastUidStr[];
  287. Xextern char  *UidToUidStr();
  288. Xextern void   ClearKnownUsers();
  289. Xextern int    NumKnownUsers;
  290. Xextern int    NumDiffKnownUids();
  291. X
  292. X
  293. Xextern SetUidGid();
  294. X
  295. X/* Friendly string operations */
  296. X#define streql(x, y)    (!(strcmp(x, y)))
  297. Xextern int WhereString();
  298. Xextern int HasStringNoCase();
  299. Xextern int HasString();
  300. Xextern int HasChar();
  301. Xextern int CountOccurances();
  302. Xextern int StrLastNCmp();
  303. Xextern char *strsave();
  304. X
  305. X/* Destructive string operations  */
  306. Xextern int ChopAtCR();
  307. Xextern int RemoveTrailingSlash();
  308. Xextern int RemoveDot();
  309. Xextern int RemoveDotDot();
  310. Xextern int SimplifyPath();
  311. Xextern int NoTrailingSpaces();
  312. Xextern int RemoveThroughSlash();
  313. Xextern int RemoveTrailingC();
  314. X
  315. Xextern int   afclose();
  316. Xextern FILE *afopen();
  317. X
  318. Xextern char *GetNthToken();
  319. Xextern char *GetNextToken();
  320. Xextern GetLastToken();
  321. X
  322. Xextern int DirToInfo();
  323. Xextern int EmptyToInfo();
  324. Xextern int OneLineIn();
  325. Xextern int OneLineOut();
  326. Xextern CopyParsedDir();
  327. X
  328. Xextern char *ATypeToString();
  329. Xextern int StringToAType();
  330. Xextern int IsAHostType();
  331. X
  332. Xextern int AlexStat();
  333. Xextern int LiteStat();
  334. X
  335. Xextern double TimeInSeconds();
  336. Xextern double RecentTime;
  337. Xextern double GreenTimeInSeconds();
  338. Xextern int StringToTimeb();
  339. Xextern int StringToTimeInt();
  340. Xextern double LastTimeChange;
  341. X
  342. Xextern double MTimeOfFile();
  343. Xextern double SecsSinceWrite();
  344. X
  345. Xextern int AlarmIgnore();
  346. X
  347. Xextern int CheckFileCache();
  348. Xextern int CloseAndDie();
  349. Xextern int HisClockIsOK();
  350. Xextern int RemTimeZone();
  351. Xextern int AlexInit();
  352. Xextern int TouchFile();
  353. X
  354. Xextern int PathToFileName();       /* /foo/bar/baz to baz      */
  355. Xextern int PathToDir();            /* /foo/bar/baz to /foo/bar */
  356. X
  357. X/*  converstion between            /* /edu/berkeley and berkeley.edu */
  358. Xextern int HostNameToPath();
  359. Xextern void PathToHostName();
  360. X
  361. X
  362. Xextern int AlexInfoCompatStat();   /* returns a regular stat buf */
  363. Xextern int AlexInfoLStat();
  364. Xextern int SimpleType();           
  365. X
  366. X
  367. Xextern int LocateHostEntry();
  368. Xextern void ToLower();
  369. X
  370. Xextern int InvalidateStatCache;    /* readinfo should not trust its cache after alex changes world */
  371. X
  372. Xextern int AlexInfoInNext();
  373. Xextern int AlexInfoInClose();
  374. Xextern int AlexInfoInOpen();
  375. Xextern int AlexOpenDir();
  376. Xextern unsigned int AlexInfoMTime();
  377. X
  378. X
  379. Xextern int LineToTokens();         /* string to array of token strings */
  380. X
  381. Xextern SetUsrX();
  382. Xextern int CopyAFile();
  383. X
  384. X
  385. X
  386. X#define Return return
  387. X
  388. Xextern char * strerror();
  389. X
  390. Xextern int StringIntoFile();
  391. Xextern int StringFromFile();
  392. Xextern int StringToUnsigned();
  393. X
  394. Xextern int RecursiveRm();
  395. X
  396. Xextern int SpecialFileName();
  397. X
  398. X/*  doanftp.c */
  399. Xextern int IgnoreSIGPIPE();
  400. Xextern int CloseAllFtpCaches();
  401. Xextern int ClearFtpCacheEntry();
  402. Xextern int DoAnFtp();
  403. Xextern int CheckFileStatus();
  404. Xextern int HaveResultFile();
  405. Xextern int InTransit();
  406. Xextern void KillOldFtps();
  407. X
  408. X/* known stale stuff  */
  409. Xextern void SaveKnownStaleFilePath();
  410. Xextern void ClearKnownStaleFilePath();
  411. Xextern int IsKnownStale();
  412. X
  413. X
  414. Xextern int FilesAreEqual();
  415. X
  416. X
  417. X/* Performance results */
  418. Xextern double InitTime;
  419. X
  420. Xextern double TotalBytesNFSed;
  421. Xextern double TotalBytesFTPed;
  422. Xextern double TotalFTPTime;
  423. Xextern int    NumFinishedFTPs;
  424. X
  425. Xextern int    TotalFilesNFSed;
  426. Xextern int    TotalFilesFTPed;
  427. Xextern double TotalFileBytesNFSed;
  428. Xextern double TotalFileBytesFTPed;
  429. X
  430. Xextern int    TotalFtpsForked;
  431. X
  432. Xextern int    TotalDirsNFSed;
  433. Xextern int    TotalDirsFTPed;
  434. Xextern double TotalDirBytesNFSed;
  435. Xextern double TotalDirBytesFTPed;
  436. X
  437. Xextern int    LookupHits;
  438. Xextern int    LookupMisses;
  439. Xextern int    LookupDrops;
  440. X
  441. Xextern int    ReadHits;
  442. Xextern int    ReadMisses;
  443. Xextern int    ReadDrops;
  444. X
  445. Xextern int    ReadDirHits;
  446. Xextern int    ReadDirMisses;
  447. Xextern int    ReadDirDrops;
  448. X
  449. Xextern int    TotalStaleFiles;
  450. Xextern int    TotalStaleSecs;
  451. X
  452. Xextern double TotalNFSLS;
  453. Xextern double TotalFTPLS;
  454. X
  455. Xextern void   AlexAssertFailed();
  456. Xextern void   PhoneHome();
  457. X
  458. Xextern int    TotalGHBNCalls;
  459. Xextern double TotalGHBNTime;
  460. Xextern double TotalGHBNTimeSQ;
  461. Xextern int    TotalRTZCalls;
  462. Xextern double TotalRTZTime;
  463. Xextern double TotalRTZTimeSQ;
  464. X
  465. Xextern int    NumAlexUpdates;
  466. X
  467. Xextern int    TotalErrorMsg;
  468. Xextern int    TotalUnchangedDirs;
  469. X
  470. X
  471. X
  472. X#ifndef FALSE
  473. X#define FALSE 0                     /* probably only used for AlexAssert(FALSE)  */
  474. X#endif
  475. X
  476. Xextern int h_errno;
  477. X
  478. Xextern int    SortFile();
  479. Xextern int    PrependLineToFile();
  480. X
  481. X#define ALEXVERSION "Tue Mar 29 05:35:43 EST 1994"
  482. END_OF_FILE
  483.   if test 17110 -ne `wc -c <'alexsrvr/src/alex.h'`; then
  484.     echo shar: \"'alexsrvr/src/alex.h'\" unpacked with wrong size!
  485.   fi
  486.   # end of 'alexsrvr/src/alex.h'
  487. fi
  488. if test -f 'alexsrvr/src/cmucs.c' -a "${1}" != "-c" ; then 
  489.   echo shar: Will not clobber existing file \"'alexsrvr/src/cmucs.c'\"
  490. else
  491.   echo shar: Extracting \"'alexsrvr/src/cmucs.c'\" \(15544 characters\)
  492.   sed "s/^X//" >'alexsrvr/src/cmucs.c' <<'END_OF_FILE'
  493. X/*
  494. X * Copyright (c) 1990 Carnegie Mellon University
  495. X * All Rights Reserved.
  496. X * 
  497. X * Permission to use, copy, modify and distribute this software and its
  498. X * documentation is hereby granted, provided that both the copyright
  499. X * notice and this permission notice appear in all copies of the
  500. X * software, derivative works or modified versions, and any portions
  501. X * thereof, and that both notices appear in supporting documentation.
  502. X *
  503. X * THE SOFTWARE IS PROVIDED "AS IS" AND CARNEGIE MELLON UNIVERSITY
  504. X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  505. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT
  506. X * SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, DIRECT,
  507. X * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  508. X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
  509. X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  510. X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  511. X *
  512. X * Users of this software agree to return to Carnegie Mellon any
  513. X * improvements or extensions that they make and grant Carnegie the
  514. X * rights to redistribute these changes.
  515. X *
  516. X * Export of this software is permitted only after complying with the
  517. X * regulations of the U.S. Deptartment of Commerce relating to the
  518. X * Export of Technical Data.
  519. X */
  520. X
  521. X
  522. X#include "alexincs.h"
  523. X
  524. X
  525. X
  526. X/* 
  527. X *  HISTORY
  528. X * $Log:    fdate.c,v $
  529. X * Revision 1.3  92/03/24  14:09:25  mja
  530. X *     For gcc: forward declarations:
  531. X *         static int dofield(), percent(), formfld(), copyword(), casefix();
  532. X *         static char foldc();
  533. X *     [91/11/26            rvb]
  534. X * 
  535. X * Revision 1.2  90/12/11  17:52:25  mja
  536. X *     Add copyright/disclaimer for distribution.
  537. X * 
  538. X * 30-Apr-85  Steven Shafer (sas) at Carnegie-Mellon University
  539. X *    Adapted for 4.2 BSD UNIX:  macro file name changed.
  540. X *
  541. X * 
  542. X *  March 1984 - Leonard Hamey (lgh) at Carnegie-Mellon University
  543. X *     Created.
  544. X */
  545. X
  546. X# define TEXT 1
  547. X# define FAIL 2
  548. X# define OPTIONAL 3
  549. X# define SUCCEED 4
  550. X
  551. X# define YES 1
  552. X# define NO 0
  553. X# define MAYBE 2
  554. X
  555. X# define SMONTHS 0
  556. X# define SWDAYS 12
  557. X# define SNOON 19
  558. X# define SMIDNIGHT 20
  559. X# define SAM 21
  560. X# define SPM 22
  561. X# define STH 23
  562. X# define SST 24
  563. X# define SND 25
  564. X# define SRD 26
  565. X
  566. X# define NOON 0
  567. X# define HOUR 1
  568. X# define AM 2
  569. X# define MINX 3
  570. X# define SEC 4
  571. X# define WDAY 5
  572. X# define DAY 6
  573. X# define TH 7
  574. X# define NMONTH 8
  575. X# define MONTH 9
  576. X# define YEAR 10
  577. X# define YDAY 11
  578. X# define MIDNIGHT 12
  579. X# define TIME 13
  580. X
  581. Xstatic char *strings[] =
  582. X{ "jan*uary", "feb*ruary", "mar*ch", "apr*il", "may", "jun*e",
  583. X  "jul*y", "aug*ust", "sep*tember", "oct*ober", "nov*ember", "dec*ember",
  584. X  "sun*day", "mon*day", "tue*s*day", "wed*nesday", "thu*r*s*day",
  585. X  "fri*day", "sat*urday",
  586. X  "noon", "00:00", "am", "pm", "th", "st", "nd", "rd"
  587. X};
  588. X
  589. Xstatic char *keys[] =
  590. X{ "noon", "hour", "am", "min", "sec",
  591. X  "wday", "day", "th", "nmonth", "month", "year", "yday",
  592. X  "midnight", "time",
  593. X  0
  594. X};
  595. X
  596. X/* The following is a macro definition of %time. */
  597. X
  598. Xstatic char *mactime =
  599. X  "[%midnight|%noon|%0hour:%min:%?sec|{%hour{:%?min}%am}]";
  600. X
  601. Xstatic char *p;
  602. Xstatic int resp;
  603. Xstatic char *result;
  604. Xstatic int dofield(), percent(), formfld(), copyword(), casefix();
  605. Xstatic char foldc();
  606. X
  607. Xchar *fdate (resb, patt, tm)
  608. Xchar *resb, *patt;
  609. Xstruct tm *tm;
  610. X{ result = resb;
  611. X  resp = 0;
  612. X  p = patt;
  613. X  dofield (' ', tm);
  614. X  result[resp] = '\0';
  615. X  return (result);
  616. X}
  617. X
  618. Xstatic dofield (doing, tm)
  619. Xchar doing;
  620. Xstruct tm *tm;
  621. X{ int ndep, s, sresp, sresp2;
  622. X  int fail;
  623. X  char ch;
  624. X  fail = MAYBE;
  625. X  sresp = resp;
  626. X  while (*p)
  627. X  { if (*p == '{' || *p == '[')
  628. X    { ch = *p++;
  629. X      s = dofield (ch, tm);
  630. X      if (s == FAIL && doing == '[')
  631. X    fail = YES;
  632. X      else if (s == SUCCEED && doing == '{')
  633. X    fail = NO;
  634. X    }
  635. X    else if (*p == '}' || *p == ']' || *p == '|')
  636. X    { if (doing == '{' && fail == MAYBE)
  637. X    fail = YES;
  638. X      if (fail == YES)
  639. X      { resp = sresp;
  640. X        if (*p == '|')
  641. X        { p++;
  642. X      fail = MAYBE;                  /* try next */
  643. X      continue;
  644. X        }
  645. X    p++;
  646. X      }
  647. X      else if (*p == '|')
  648. X      { /* Scan to matching bracket/brace */
  649. X    ndep = 1;
  650. X    while (ndep > 0)
  651. X    { if (*p == '{' || *p == '[')
  652. X        ndep++;
  653. X      else if (*p == '}' || *p == ']')
  654. X        ndep--;
  655. X      p++;
  656. X    }
  657. X      }
  658. X      else
  659. X    p++;
  660. X      return (fail == YES ? FAIL : SUCCEED);
  661. X    }
  662. X    else if (*p == '%')
  663. X    { sresp2 = resp;
  664. X      s = percent (tm);
  665. X      if (doing == '{')
  666. X      { if (s == FAIL)             /* Discard failure results */
  667. X      resp = sresp2;
  668. X    else if (s == SUCCEED)
  669. X      fail = NO;
  670. X      }
  671. X      else if (doing == '[')
  672. X      { if (s == FAIL)
  673. X      fail = YES;
  674. X      }
  675. X    }
  676. X    else
  677. X    { result[resp++] = *p;
  678. X      p++;
  679. X    }
  680. X    if (fail == YES)
  681. X    { /* Failure: scan for barline or closing bracket/brace; leave ptr there */
  682. X      resp = sresp;
  683. X      ndep = 1;
  684. X      while (ndep > 0)
  685. X      { if (*p == '|' && ndep == 1)
  686. X      break;
  687. X    if (*p == '[' | *p == '{')
  688. X      ndep++;
  689. X    else if (*p == ']' || *p == '}')
  690. X    { ndep--;
  691. X      if (ndep == 0)
  692. X        return (FAIL);
  693. X    }
  694. X    p++;
  695. X      }
  696. X    }
  697. X  }
  698. X  return (SUCCEED);
  699. X}
  700. X
  701. Xstatic percent (tm)
  702. Xstruct tm *tm;
  703. X{ register char *pp;
  704. X  char *spp;
  705. X  int query, lead0, prec, upcase, sresp, s;
  706. X  char *savep;
  707. X  register int ks;
  708. X  register char *k;
  709. X  char foldc ();
  710. X  int formfld ();
  711. X  char *fldp;
  712. X  pp = p + 1;
  713. X  if (*pp == '%' || *pp == '{' || *pp == '}' || *pp == '|' ||
  714. X    *pp == '[' || *pp == ']')
  715. X  { p += 2;
  716. X    result[resp++] = *pp;
  717. X    return (TEXT);                  /* Was just text */
  718. X  }
  719. X  query = *pp == '?';                  /* Query? */
  720. X  if (query)
  721. X    pp++;
  722. X  lead0 = *pp == '0';                  /* Leading zero? */
  723. X  if (lead0)
  724. X    pp++;
  725. X  if (*pp >= '1' && *pp <= '9')          /* Precision? */
  726. X  { prec = *pp - '0';
  727. X    pp++;
  728. X  }
  729. X  else
  730. X    prec = 0;
  731. X  upcase = 0;                      /* Case? */
  732. X  if (*pp >= 'A' && *pp <= 'Z')
  733. X    upcase = 1;
  734. X  if (pp[1] >= 'A' && pp[1] <= 'Z')
  735. X    upcase = 2;
  736. X
  737. X  spp = pp;
  738. X  for (ks = 0; keys[ks]; ks++)          /* Check for keyword */
  739. X  { for (k = keys[ks], pp = spp; *k; k++, pp++)
  740. X      if (foldc (*k) != foldc (*pp))
  741. X        break;
  742. X    if (! *k)                      /* Match found */
  743. X      break;
  744. X  }
  745. X  if (! keys[ks])                  /* No match */
  746. X  { result[resp++] = '%';              /* Treat as text */
  747. X    p++;
  748. X    return (TEXT);
  749. X  }
  750. X  p = pp;
  751. X  if (ks == TIME)                  /* Macro */
  752. X  { savep = p;
  753. X    sresp = resp;
  754. X    p = mactime + 1;                  /* Skip leading bracket */
  755. X    s = dofield (mactime[0], tm);
  756. X    p = savep;
  757. X    return (s);
  758. X  }
  759. X  /* Match found */
  760. X  s = formfld (tm, ks, lead0, prec, &fldp);
  761. X  sresp = resp;
  762. X  if (s == OPTIONAL)
  763. X  { if (query)
  764. X      s = FAIL;
  765. X    else
  766. X      s = SUCCEED;
  767. X  }
  768. X  if (s == SUCCEED)
  769. X  { for (; *fldp; fldp++)
  770. X      result[resp++] = *fldp;
  771. X    casefix (&result[sresp], upcase);
  772. X  }
  773. X  return (s);
  774. X}
  775. X
  776. Xstatic char foldc (c)
  777. Xchar c;
  778. X{ 
  779. X    return (c < 'a' || c > 'z' ? c : c - 'a' + 'A');
  780. X}
  781. X
  782. Xstatic char nstr[30];
  783. Xstatic char sfield[30];
  784. Xstatic int thmem;
  785. X
  786. Xstatic formfld (tm, field, lead0, prec, result)
  787. Xstruct tm *tm;
  788. Xint field, lead0, prec;
  789. Xchar **result;
  790. X{ int fld, ddiff, s;
  791. X  struct tm ctm;
  792. X  long ctime;
  793. X  sfield[0] = '\0';
  794. X  *result = sfield;
  795. X  if (field != TH)
  796. X    thmem = -1;
  797. X  switch (field)
  798. X  { case NOON:
  799. X      if (tm->tm_hour == 12 && tm->tm_min == 0 && tm->tm_sec == 0)
  800. X      { *result = strings[SNOON];
  801. X    return (SUCCEED);
  802. X      }
  803. X      return (FAIL);
  804. X
  805. X    case HOUR:
  806. X      for (; prec > 2; prec--)
  807. X    strcat (sfield, " ");
  808. X      if (lead0)
  809. X        sprintf (nstr, "%02d", tm->tm_hour);
  810. X      else if (prec < 2)
  811. X    sprintf (nstr, "%d", (tm->tm_hour + 11) % 12 + 1);
  812. X      else
  813. X    sprintf (nstr, "%2d", (tm->tm_hour + 11) % 12 + 1);
  814. X      strcat (sfield, nstr);
  815. X      thmem = tm->tm_hour;
  816. X      return (tm->tm_hour >= 0 ? SUCCEED : FAIL);
  817. X
  818. X    case MINX:
  819. X      fld = tm->tm_min;
  820. X    case SEC:
  821. X      if (field == SEC)
  822. X    fld = tm->tm_sec;
  823. X      if (prec == 0)
  824. X    prec = 2;
  825. X      for (; prec > 2; prec--)
  826. X    strcat (sfield, " ");
  827. X      if (prec < 2)
  828. X    sprintf (nstr, "%d", fld);
  829. X      else
  830. X    sprintf (nstr, "%02d", fld);
  831. X      strcat (sfield, nstr);
  832. X      thmem = fld;
  833. X      return (fld > 0 ? SUCCEED : (fld == 0 ? OPTIONAL : FAIL));
  834. X
  835. X    case AM:
  836. X      if (tm->tm_hour >= 12)
  837. X    *result = strings[SPM];
  838. X      else if (tm->tm_hour >= 0)
  839. X    *result = strings[SAM];
  840. X      return (tm->tm_hour >= 0 ? SUCCEED : FAIL);
  841. X
  842. X    case WDAY:
  843. X      if (tm->tm_wday >= 0 && tm->tm_wday < 7)
  844. X      { copyword (sfield, strings[SWDAYS + tm->tm_wday], prec);
  845. X    return (SUCCEED);
  846. X      }
  847. X      return (FAIL);
  848. X
  849. X    case MONTH:
  850. X      if (tm->tm_mon >= 0 && tm->tm_mon < 12)
  851. X      { copyword (sfield, strings[SMONTHS + tm->tm_mon], prec);
  852. X    return (SUCCEED);
  853. X      }
  854. X      return (FAIL);
  855. X
  856. X    case DAY:
  857. X      fld = tm->tm_mday;
  858. X    case NMONTH:
  859. X    case YDAY:
  860. X      if (field == NMONTH)
  861. X    fld = tm->tm_mon + 1;
  862. X      else if (field == YDAY)
  863. X    fld = tm->tm_yday;
  864. X      if (prec == 0)
  865. X    prec = 1;
  866. X      if (lead0)
  867. X      { strcpy (nstr, "%09d");
  868. X    nstr[2] = prec + '0';
  869. X      }
  870. X      else
  871. X      { strcpy (nstr, "%9d");
  872. X    nstr[1] = prec + '0';
  873. X      }
  874. X      sprintf (sfield, nstr, fld);
  875. X      thmem = fld;
  876. X      return (fld >= 0 ? SUCCEED : FAIL);
  877. X
  878. X    case TH:
  879. X      if (thmem >= 0)
  880. X      { if ((thmem / 10) % 10 == 1)
  881. X      *result = strings[STH];
  882. X    else if (thmem % 10 == 1)
  883. X      *result = strings[SST];
  884. X    else if (thmem % 10 == 2)
  885. X      *result = strings[SND];
  886. X    else if (thmem % 10 == 3)
  887. X      *result = strings[SRD];
  888. X    else
  889. X      *result = strings[STH];
  890. X    return (SUCCEED);
  891. X      }
  892. X      return (FAIL);
  893. X
  894. X    case YEAR:
  895. X      ctime = time (0);
  896. X      ctm = *localtime (&ctime);
  897. X      ddiff = (tm->tm_year - ctm.tm_year) * 366 + tm->tm_yday - ctm.tm_yday;
  898. X      if (tm->tm_year >= -1900)
  899. X      { if (prec == 0 || prec > 3)
  900. X      sprintf (nstr, "%04d", tm->tm_year + 1900);
  901. X    else
  902. X      sprintf (nstr, "%02d", (tm->tm_year + 1900) % 100);
  903. X    *result = nstr;
  904. X    return (ddiff < 0 || ddiff > 300 ? SUCCEED : OPTIONAL);
  905. X      }
  906. X      return (FAIL);
  907. X
  908. X    case MIDNIGHT:
  909. X      if (tm->tm_hour == 0 && tm->tm_min == 0 && tm->tm_sec == 0)
  910. X      { *result = strings[SMIDNIGHT];
  911. X    return (SUCCEED);
  912. X      }
  913. X      return (FAIL);
  914. X  }
  915. X}
  916. X
  917. X/* copyword: Copy <from> to <to> subject to precision <prec>. Asterisks in
  918. X * <from> mark valid truncation points. The longest string no longer than
  919. X * <prec> and broken at a valid truncation point is returned in <to>. Note
  920. X * that the result may exceed <prec> in length only if there are no valid
  921. X * truncation points short enough. The shortest is then taken.
  922. X * 
  923. X * e.g. Tue*s*day.  Precision 1-3 -> Tue,  Precision 4-6 -> Tues,
  924. X *      Precision 0 and 7... -> Tuesday.
  925. X */
  926. X
  927. Xstatic copyword (to, from, prec)
  928. Xchar *to, *from;
  929. Xint prec;
  930. X{ int ast = 0, top = 0;
  931. X  if (prec == 0)
  932. X    prec = 999;
  933. X  for (; *from; from++)
  934. X  { if (*from == '*')
  935. X      ast = top;
  936. X    else
  937. X    { to[top] = *from;
  938. X      top++;
  939. X    }
  940. X    if (top > prec && ast > 0)
  941. X    { /* Required precision exceeded and asterisk found */
  942. X      to[ast] = '\0';                  /* Truncate at asterisk */
  943. X      return;
  944. X    }
  945. X  }
  946. X  to[top] = '\0';
  947. X  return;
  948. X}
  949. X
  950. X
  951. Xvac_foldup(s)
  952. Xchar *s;
  953. X{
  954. X    while (*s != 0) {
  955. X        if (islower(*s)) {
  956. X            *s = toupper(*s);
  957. X        }
  958. X        s++;
  959. X    }  
  960. X}
  961. X
  962. X/* casefix: select case of word. 1: first letter raised. 2: all raised. */
  963. X
  964. Xstatic casefix (text, upcase)
  965. Xchar *text;
  966. Xint upcase;
  967. X{ 
  968. X  if (upcase == 1)
  969. X    *text = foldc (*text);
  970. X  else if (upcase > 0)
  971. X    vac_foldup (text);
  972. X}
  973. X
  974. X
  975. X
  976. X
  977. X/*  filecopy  --  copy a file from here to there
  978. X *
  979. X *  Usage:  i = filecopy (here,there);
  980. X *    int i, here, there;
  981. X *
  982. X *  Filecopy performs a fast copy of the file "here" to the
  983. X *  file "there".  Here and there are both file descriptors of
  984. X *  open files; here is open for input, and there for output.
  985. X *  Filecopy returns 0 if all is OK; -1 on error.
  986. X *
  987. X *  I have performed some tests for possible improvements to filecopy.
  988. X *  Using a buffer size of 10240 provides about a 1.5 times speedup
  989. X *  over 512 for a file of about 200,000 bytes.  Of course, other
  990. X *  buffer sized should also work; this is a rather arbitrary choice.
  991. X *  I have also tried inserting special startup code to attempt
  992. X *  to align either the input or the output file to lie on a
  993. X *  physical (512-byte) block boundary prior to the big loop,
  994. X *  but this presents only a small (about 5% speedup, so I've
  995. X *  canned that code.  The simple thing seems to be good enough.
  996. X *
  997. X *  HISTORY
  998. X * $Log:    filecopy.c,v $
  999. X * Revision 1.2  90/12/11  17:52:57  mja
  1000. X *     Add copyright/disclaimer for distribution.
  1001. X * 
  1002. X * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  1003. X *    Rewritten for VAX; same as "filcopy" on PDP-11.  Bigger buffer
  1004. X *    size (20 physical blocks) seems to be a big win; aligning things
  1005. X *    on block boundaries seems to be a negligible improvement at
  1006. X *    considerable cost in complexity.
  1007. X *
  1008. X */
  1009. X
  1010. X#define BUFFERSIZE 10240
  1011. X
  1012. Xint filecopy (here,there)
  1013. Xint here,there;
  1014. X{
  1015. X    register int kount;
  1016. X    char buffer[BUFFERSIZE];
  1017. X    kount = 0;
  1018. X    while (kount == 0 && (kount=read(here,buffer,BUFFERSIZE)) > 0)
  1019. X        kount -= write (there,buffer,kount);
  1020. X    return (kount ? -1 : 0);
  1021. X}
  1022. X
  1023. X
  1024. X
  1025. X/*  ffilecopy  --  very fast buffered file copy
  1026. X *
  1027. X *  Usage:  i = ffilecopy (here,there)
  1028. X *    int i;
  1029. X *    FILE *here, *there;
  1030. X *
  1031. X *  Ffilecopy is a very fast routine to copy the rest of a buffered
  1032. X *  input file to a buffered output file.  Here and there are open
  1033. X *  buffers for reading and writing (respectively); ffilecopy
  1034. X *  performs a file-copy faster than you should expect to do it
  1035. X *  yourself.  Ffilecopy returns 0 if everything was OK; EOF if
  1036. X *  there was any error.  Normally, the input file will be left in
  1037. X *  EOF state (feof(here) will return TRUE), and the output file will be
  1038. X *  flushed (i.e. all data on the file rather in the core buffer).
  1039. X *  It is not necessary to flush the output file before ffilecopy.
  1040. X *
  1041. X *  HISTORY
  1042. X * $Log:    ffilecopy.c,v $
  1043. X * Revision 1.2  90/12/11  17:52:41  mja
  1044. X *     Add copyright/disclaimer for distribution.
  1045. X * 
  1046. X * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  1047. X *    Created for VAX.
  1048. X *
  1049. X */
  1050. X
  1051. Xint ffilecopy (here,there)
  1052. XFILE *here, *there;
  1053. X{
  1054. X    register int i, herefile, therefile;
  1055. X
  1056. X    herefile = fileno(here);
  1057. X    therefile = fileno(there);
  1058. X
  1059. X    if (fflush (there) == EOF)        /* flush pending output */
  1060. X        return (EOF);
  1061. X
  1062. X#if defined(__386BSD__) || defined(__NetBSD__)
  1063. X    if ((here->_r) > 0) {            /* flush buffered input */
  1064. X        i = write (therefile, here->_p, here->_r);
  1065. X        if (i != here->_r)  return (EOF);
  1066. X        here->_p = here->_bf._base;
  1067. X        here->_r = 0;
  1068. X    }
  1069. X
  1070. X    i = filecopy (herefile, therefile);    /* fast file copy */
  1071. X    if (i < 0)  return (EOF);
  1072. X
  1073. X    (here->_flags) |= __SEOF;        /* indicate EOF */
  1074. X#else
  1075. X#if defined(__linux__)
  1076. X
  1077. X/* 
  1078. X * This is to deal with the new IO stream functions in Linux libc version
  1079. X * 4.5.8 and onwards. It will most definetly not work with libraries before
  1080. X * this. Please report bugs herein to me - Mitch <m.dsouza@mrc-apu.cam.ac.uk>
  1081. X *
  1082. X */
  1083. X       if ((here->_IO_read_end - here->_IO_read_ptr) > 0) { /* flush buffered input */
  1084. X               i = write (therefile, here->_IO_read_ptr,here->_IO_read_end - here->_IO_read_ptr);
  1085. X               if (i != here->_IO_read_end - here->_IO_read_ptr)  return (EOF);
  1086. X               here->_IO_read_ptr = here->_IO_read_end;
  1087. X        }
  1088. X
  1089. X    i = filecopy (herefile, therefile);    /* fast file copy */
  1090. X    if (i < 0)  return (EOF);
  1091. X
  1092. X        (here->_IO_file_flags) |= _IO_EOF_SEEN;                /* indicate EOF */
  1093. X#else
  1094. X       if ((here->_cnt) > 0) {                 /* flush buffered input */
  1095. X               i = write (therefile, here->_ptr, here->_cnt);
  1096. X               if (i != here->_cnt)  return (EOF);
  1097. X               here->_ptr = here->_base;
  1098. X               here->_cnt = 0;
  1099. X        }
  1100. X
  1101. X    i = filecopy (herefile, therefile);    /* fast file copy */
  1102. X    if (i < 0)  return (EOF);
  1103. X
  1104. X        (here->_flag) |= _IOEOF;                /* indicate EOF */
  1105. X#endif
  1106. X#endif
  1107. X
  1108. X    return (0);
  1109. X}
  1110. X
  1111. X
  1112. X
  1113. END_OF_FILE
  1114.   if test 15544 -ne `wc -c <'alexsrvr/src/cmucs.c'`; then
  1115.     echo shar: \"'alexsrvr/src/cmucs.c'\" unpacked with wrong size!
  1116.   fi
  1117.   # end of 'alexsrvr/src/cmucs.c'
  1118. fi
  1119. if test -f 'alexsrvr/src/defs.c' -a "${1}" != "-c" ; then 
  1120.   echo shar: Will not clobber existing file \"'alexsrvr/src/defs.c'\"
  1121. else
  1122.   echo shar: Extracting \"'alexsrvr/src/defs.c'\" \(1678 characters\)
  1123.   sed "s/^X//" >'alexsrvr/src/defs.c' <<'END_OF_FILE'
  1124. X
  1125. X#include "alexincs.h"
  1126. X#include "alex.h"
  1127. X
  1128. XFILE *debugLog;
  1129. X
  1130. Xfh_fdclose()
  1131. X{
  1132. X    printf("ERROR fh_fdclose should not be called\n");
  1133. X    exit(-1);
  1134. X}
  1135. X
  1136. Xmain(argc, argv)
  1137. Xint argc;
  1138. Xchar *argv[];
  1139. X{
  1140. X    FILE *devnull;
  1141. X    char myname[MAXPATH];
  1142. X
  1143. X    PathToFileName(argv[0], myname);
  1144. X    if ((argc > 2) || ((argc==1) && (!streql(myname, "cachedir")))) {
  1145. X        fprintf(stderr, "%s: usage is %s [alexsrvr/home/install/resolver]\n", argv[0], argv[0]);
  1146. X        exit(-1);
  1147. X    }
  1148. X
  1149. X
  1150. X    devnull=fopen("/dev/null", "w");
  1151. X    if (devnull == NULL) {
  1152. X       fprintf(stderr, "ERROR: Can not open /dev/null \n ");
  1153. X       exit(-1);
  1154. X    }
  1155. X
  1156. X    debugLog=devnull;
  1157. X
  1158. X    if (streql(myname, "cachedir") || streql(argv[1], "cachedir")) {
  1159. X        InitReadOnlyVariables();           
  1160. X        printf("%s\n", CACHEDIRVAR);          /* only one that needs Init */
  1161. X
  1162. X    } else if (streql(argv[1], "alexsrvr")) {
  1163. X        printf("%s\n", ALEXSRVR);
  1164. X
  1165. X    } else if (streql(argv[1], "tmpdir")) {
  1166. X        printf("%s\n", TMPDIR);
  1167. X    
  1168. X    } else if (streql(argv[1], "logdir")) {
  1169. X        printf("%s\n", LOGDIR);
  1170. X    
  1171. X    } else if (streql(argv[1], "home")) {
  1172. X        printf("%s\n", ALEXSRVRHOME);
  1173. X    
  1174. X    } else if (streql(argv[1], "debuglevel")) {
  1175. X        printf("%d\n", DEBUGLEVEL);
  1176. X    
  1177. X    } else if (streql(argv[1], "install")) {
  1178. X        printf("%s\n", INSTALLDIR);
  1179. X    
  1180. X    } else if (streql(argv[1], "cacheinfohead")) {
  1181. X        printf("%s\n", CACHEINFOHEAD);
  1182. X    
  1183. X    } else if (streql(argv[1], "at_dir")) {
  1184. X#ifdef AT_DIR
  1185. X        printf("/@");
  1186. X#else
  1187. X        printf("");
  1188. X#endif
  1189. X    } else if (streql(argv[1], "resolver")) {
  1190. X#ifdef USINGRESOLVER
  1191. X        printf("-lresolv\n");
  1192. X#else
  1193. X        printf("");
  1194. X#endif
  1195. X    }
  1196. X}
  1197. X
  1198. END_OF_FILE
  1199.   if test 1678 -ne `wc -c <'alexsrvr/src/defs.c'`; then
  1200.     echo shar: \"'alexsrvr/src/defs.c'\" unpacked with wrong size!
  1201.   fi
  1202.   # end of 'alexsrvr/src/defs.c'
  1203. fi
  1204. if test -f 'alexsrvr/src/init.c' -a "${1}" != "-c" ; then 
  1205.   echo shar: Will not clobber existing file \"'alexsrvr/src/init.c'\"
  1206. else
  1207.   echo shar: Extracting \"'alexsrvr/src/init.c'\" \(15476 characters\)
  1208.   sed "s/^X//" >'alexsrvr/src/init.c' <<'END_OF_FILE'
  1209. X/* Copyright (c) 1992 Vincent Cate
  1210. X * All Rights Reserved.
  1211. X *
  1212. X * Permission to use and modify this software and its documentation
  1213. X * is hereby granted, provided that both the copyright notice and this
  1214. X * permission notice appear in all copies of the software, derivative works
  1215. X * or modified versions, and any portions thereof, and that both notices
  1216. X * appear in supporting documentation.  This software or any derivate works
  1217. X * may not be sold or distributed without prior written approval from
  1218. X * Vincent Cate.
  1219. X *
  1220. X * THE SOFTWARE IS PROVIDED "AS IS" AND VINCENT CATE DISCLAIMS ALL
  1221. X * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  1222. X * WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL
  1223. X * VINCENT CATE BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  1224. X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  1225. X * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  1226. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  1227. X * OR PERFORMANCE OF THIS SOFTWARE.
  1228. X *
  1229. X * Users of this software agree to return to Vincent Cate any improvements
  1230. X * or extensions that they make and grant Vincent Cate the rights to
  1231. X * redistribute these changes.
  1232. X *
  1233. X */
  1234. X
  1235. X
  1236. X
  1237. X
  1238. X/* UNFSD - copyright Mark A Shand, May 1988.
  1239. X * This software maybe be used for any purpose provided
  1240. X * the above copyright notice is retained.  It is supplied
  1241. X * as is, with no warranty expressed or implied.
  1242. X */
  1243. X
  1244. X/*
  1245. X**  Udp socket establishment routine
  1246. X*/
  1247. X
  1248. X
  1249. X#ifndef lint
  1250. Xstatic char sccsid[] = "@(#)init.c  1.2atd  Wed, Jun 07, 1989";
  1251. X#endif  lint
  1252. X
  1253. X#include "alexincs.h"
  1254. X#include "unfsd.h"
  1255. X#include "alex.h"
  1256. X
  1257. X
  1258. X#ifdef EXPORTSFILE
  1259. X#define DEFAULT_EXPORTSFILE EXPORTSFILE
  1260. X#else
  1261. X#define DEFAULT_EXPORTSFILE ALEXEXPORTSFILE 
  1262. X#endif
  1263. X
  1264. X#ifndef SYSERROR
  1265. X#define SYSERROR    (-1)
  1266. X#endif
  1267. X
  1268. X
  1269. Xint init_Log()
  1270. X{
  1271. X    char logbuf[100];
  1272. X    sprintf(logbuf,"%s/alex.log",LOGDIR);
  1273. X    SetLogBaseName(logbuf);
  1274. X    InitReadOnlyVariables();               /* needs to be first before any Logs() */
  1275. X    Log("init_Log  just warming up unfsd Log"); 
  1276. X}
  1277. X
  1278. Xint makesock(port,socksz)
  1279. Xint port;
  1280. Xint socksz;
  1281. X{
  1282. X    struct sockaddr_in  my_sock;
  1283. X    int         s;
  1284. X    extern int      errno;
  1285. X
  1286. X    bzero((char *)&my_sock, sizeof(my_sock));
  1287. X    my_sock.sin_addr.s_addr = INADDR_ANY;
  1288. X    my_sock.sin_family = AF_INET;
  1289. X    my_sock.sin_port = htons(port);
  1290. X
  1291. X    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  1292. X    {
  1293. X        error1("makesock could not make a socket");
  1294. X        return(SYSERROR);
  1295. X    }
  1296. X#ifdef SO_SNDBUF
  1297. X    {
  1298. X        int sblen, rblen;
  1299. X
  1300. X        sblen = rblen = socksz + 1024;
  1301. X        /* 1024 for rpc & transport overheads */
  1302. X        if (
  1303. X        setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sblen, sizeof sblen) < 0
  1304. X        ||
  1305. X        setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rblen, sizeof sblen) < 0
  1306. X        )
  1307. X        error1("makesock  setsockopt failed");
  1308. X    }
  1309. X#endif
  1310. X
  1311. X    if (bind(s, (struct sockaddr *) &my_sock, sizeof(my_sock)) == -1) {
  1312. X        error1("makesock could not bind name to socket");
  1313. X        return(SYSERROR);
  1314. X    }
  1315. X
  1316. X    return s;
  1317. X}
  1318. X
  1319. Xftype ft_map[16];
  1320. Xint svc_euid;
  1321. Xint svc_egid;
  1322. Xint cur_gid;
  1323. Xint svc_ngids;
  1324. Xint svc_gids[NGROUPS+2];
  1325. X
  1326. Xstatic clnt_param   *clients = NULL;
  1327. Xstatic clnt_param   *unknown_clients = NULL;
  1328. Xstatic clnt_param   *default_client = NULL;
  1329. X
  1330. X#define LINE_SIZE   1024
  1331. X
  1332. Xstatic char *
  1333. Xparse_opts(s, terminator, o, client_name)
  1334. Xchar    *s;
  1335. Xchar    terminator;
  1336. Xoptions *o;
  1337. Xchar    *client_name;
  1338. X{
  1339. X    /* parse option string pointed to by s and set o accordingly */
  1340. X    char    kwdbuf[LINE_SIZE];
  1341. X    char    *k;
  1342. X
  1343. X    /* skip white */
  1344. X    while (isspace(*s))
  1345. X        s++;
  1346. X    while (*s != terminator)
  1347. X    {
  1348. X        k = kwdbuf;
  1349. X        while (isalnum(*s) || *s == '_')
  1350. X            *k++ = *s++;
  1351. X        *k = '\0';
  1352. X        /* process keyword */
  1353. X        if (strcmp(kwdbuf, "secure") == 0)
  1354. X            o->secure_port = 1;
  1355. X        else if (strcmp(kwdbuf, "insecure") == 0)
  1356. X            o->secure_port = 0;
  1357. X        else if (strcmp(kwdbuf, "root_squash") == 0)
  1358. X            o->root_squash = 1;
  1359. X        else if (strcmp(kwdbuf, "no_root_squash") == 0)
  1360. X            o->root_squash = 0;
  1361. X        else if (strcmp(kwdbuf, "ro") == 0)
  1362. X            o->read_only = 1;
  1363. X        else if (strcmp(kwdbuf, "rw") == 0)
  1364. X            o->read_only = 0;
  1365. X        else if (strcmp(kwdbuf, "link_relative") == 0)
  1366. X            o->link_relative = 1;
  1367. X        else if (strcmp(kwdbuf, "link_absolute") == 0)
  1368. X            o->link_relative = 0;
  1369. X        else if (strcmp(kwdbuf, "map_daemon") == 0)
  1370. X            o->uidmap = map_daemon;
  1371. X        else if (strcmp(kwdbuf, "map_identity") == 0)
  1372. X            o->uidmap = identity;
  1373. X        else
  1374. X            Log2("parse_opts Unknown keyword ", kwdbuf);
  1375. X        while (isspace(*s))
  1376. X            s++;
  1377. X        if (*s == terminator)
  1378. X            break;
  1379. X        if (*s == ',') {
  1380. X            s++;
  1381. X        } else if (!isalnum(*s) && *s != '_' && *s != '\0') {
  1382. X            if (client_name == NULL) {
  1383. X                LogN("parse_opts Comma expected in option list for default client but got ", (int) *s);
  1384. X            } else {
  1385. X                ToLog(DBERROR, "parse_opts Comma expected in option list for client %s but got %c", 
  1386. X                                                    client_name, *s);
  1387. X            }
  1388. X        }
  1389. X        while (isspace(*s)) {
  1390. X            s++;
  1391. X        }
  1392. X        if (*s == '\0' && *s != terminator) {
  1393. X            LogN("parse_opts   missing terminator on option list", (int) terminator);
  1394. X            return(s);
  1395. X        }
  1396. X    }
  1397. X    if (*s != terminator)
  1398. X        LogC("Internal inconsistency in parse, character '%c'.", *s);
  1399. X    s++;                                        /* Skip past terminator */
  1400. X    while (isspace(*s))
  1401. X        s++;
  1402. X    return s;
  1403. X}
  1404. X
  1405. Xstatic int
  1406. Xfilt_getc(f)
  1407. XFILE    *f;
  1408. X{
  1409. X    int c;
  1410. X
  1411. X    c = getc(f);
  1412. X    if (c == '\\')
  1413. X    {
  1414. X        c = getc(f);
  1415. X        if (c == '\n')
  1416. X            return ' ';
  1417. X        if (c != EOF)
  1418. X            ungetc(c, f);
  1419. X        return '\\';
  1420. X    }
  1421. X    else if (c == '#')
  1422. X    {
  1423. X        int lastc = c;
  1424. X        while ((c = getc(f)) != '\n' && c != EOF)
  1425. X            lastc = c;
  1426. X        if (c == '\n' && lastc == '\\')
  1427. X            c = getc(f);
  1428. X    }
  1429. X    return c;
  1430. X}
  1431. X
  1432. X#define CHUNK_SIZE  132 /* The 'typical' maximum length line */
  1433. X
  1434. Xstatic int getline(lbuf, f)
  1435. Xchar    **lbuf;
  1436. XFILE    *f;
  1437. X{
  1438. X    int    c;
  1439. X    char  *p;
  1440. X    char  *buf;
  1441. X    int    sz;
  1442. X
  1443. X    sz = CHUNK_SIZE;
  1444. X    buf = malloc(sz);
  1445. X    if (buf == NULL) {
  1446. X        MallocDeath("getline");
  1447. X    }
  1448. X    p = buf;
  1449. X    while ((c = filt_getc(f)) != '\n' && c != EOF) {
  1450. X        if (((int) p - (int) buf) == (sz - 2)) {
  1451. X            buf = realloc(buf, sz * 2);
  1452. X            if (buf == NULL) {
  1453. X                MallocDeath("getline 2");
  1454. X            }
  1455. X            p = buf + sz-2;
  1456. X            sz *= 2;
  1457. X        }
  1458. X        *p++ = c;
  1459. X    }
  1460. X    if (c == EOF && p == buf) {
  1461. X        free(buf);
  1462. X        *lbuf = NULL;
  1463. X        return 0;
  1464. X    }
  1465. X    *p++ = '\0';
  1466. X    *lbuf = buf;
  1467. X    return 1;
  1468. X}
  1469. X
  1470. Xunfsd_init(argc, argv, envp)
  1471. Xint argc;
  1472. Xchar    **argv, **envp;
  1473. X{
  1474. X    int i, n;
  1475. X    FILE    *f;
  1476. X    char    *lbuf;
  1477. X    char    *p, *q, *r;
  1478. X    char    *exportsfile = DEFAULT_EXPORTSFILE;
  1479. X    struct hostent  *hent;
  1480. X    clnt_param *tmp;
  1481. X    char    *mount_point;
  1482. X
  1483. X    /* options */
  1484. X    int promiscuous = 0;
  1485. X    char    *o_string = NULL;
  1486. X    options def_opts;
  1487. X
  1488. X
  1489. X    /* setup defaults */
  1490. X    def_opts.uidmap = identity;
  1491. X    def_opts.root_squash = 0;
  1492. X    def_opts.secure_port = 1;
  1493. X    def_opts.read_only = 1;
  1494. X    def_opts.link_relative = 0;      /* vac changed default for Alex world */
  1495. X
  1496. X    (void) AlexInit();
  1497. X
  1498. X#ifdef NAMECHANGE
  1499. X    InitNameChangeVars(argc, argv, envp);
  1500. X#endif
  1501. X
  1502. X    argc--; argv++;
  1503. X    while (argc > 0)
  1504. X    {
  1505. X        if ((*argv)[0] == '-')
  1506. X        {
  1507. X            switch ((*argv)[1])
  1508. X            {
  1509. X                case 'o':
  1510. X                    if ((*argv)[2] == '\0' && argc > 1)
  1511. X                    {
  1512. X                        argc--; argv++;
  1513. X                        o_string = *argv;
  1514. X                    }
  1515. X                    else
  1516. X                        o_string = *argv + 2;
  1517. X                    break;
  1518. X                case 'p':
  1519. X                    promiscuous = 1;
  1520. X                    break;
  1521. X                case 'f':
  1522. X                    if ((*argv)[2] == '\0' && argc > 1)
  1523. X                    {
  1524. X                        argc--; argv++;
  1525. X                        exportsfile = *argv;
  1526. X                    }
  1527. X                    else
  1528. X                        exportsfile = *argv + 2;
  1529. X                    break;
  1530. X                default:
  1531. X                    LogC("unfsd_init Unknown option ", (*argv)[1]);
  1532. X            }
  1533. X        }
  1534. X        else
  1535. X            Log2("unfsd_init Bad argument ", *argv);
  1536. X        argc--; argv++;
  1537. X    }
  1538. X
  1539. X    fh_init();
  1540. X
  1541. X    ft_map[0] = NFNON;
  1542. X    for (i = 1; i < 16; i++)
  1543. X        ft_map[i] = NFBAD;
  1544. X#ifdef S_IFIFO
  1545. X    ft_map[ft_extr(S_IFIFO)] = NFFIFO;
  1546. X#endif
  1547. X    ft_map[ft_extr(S_IFCHR)] = NFCHR;
  1548. X    ft_map[ft_extr(S_IFDIR)] = NFDIR;
  1549. X    ft_map[ft_extr(S_IFBLK)] = NFBLK;
  1550. X    ft_map[ft_extr(S_IFREG)] = NFREG;
  1551. X    ft_map[ft_extr(S_IFLNK)] = NFLNK;
  1552. X    ft_map[ft_extr(S_IFSOCK)] = NFSOCK;
  1553. X
  1554. X    /*  umask(0); */
  1555. X
  1556. X    svc_euid = geteuid();
  1557. X    svc_ngids = getgroups(NGROUPS, svc_gids);
  1558. X    /* Does this always include gid and egid? I don't know. Play it safe */
  1559. X    if (svc_ngids < 0)
  1560. X        svc_ngids = 0;
  1561. X    n = getgid();
  1562. X    for (i = 0; i < svc_ngids; i++)
  1563. X        if (svc_gids[i] == n)
  1564. X            break;
  1565. X    if (i == svc_ngids)
  1566. X        svc_gids[svc_ngids++] = n;
  1567. X    n = svc_egid = getegid();
  1568. X    for (i = 0; i < svc_ngids; i++)
  1569. X        if (svc_gids[i] == n)
  1570. X            break;
  1571. X    if (i == svc_ngids)
  1572. X        svc_gids[svc_ngids++] = n;
  1573. X    cur_gid = svc_gids[0];
  1574. X    if (o_string != NULL)
  1575. X        parse_opts(o_string, '\0', &def_opts, NULL);
  1576. X
  1577. X    if (!promiscuous && (exportsfile != NULL)) {
  1578. X        if ((f = fopen(exportsfile, "r")) == NULL) {
  1579. X            Log2("unfsd_init Could not open ", exportsfile);
  1580. X            exit(1);
  1581. X        }
  1582. X        /* process exports file */
  1583. X        while (getline(&lbuf, f)) {
  1584. X            p = lbuf;
  1585. X            while (isspace(*p))
  1586. X                p++;
  1587. X            q = p;
  1588. X            /* file-system name */
  1589. X            while (*q != '\0' && !isspace(*q)) {
  1590. X                q++;
  1591. X            }
  1592. X            if ((mount_point = malloc(q-p+1)) == NULL) {
  1593. X                MallocDeath("unfsd_init");
  1594. X            }
  1595. X            for (r = mount_point; p < q;) {
  1596. X                *r++ = *p++;
  1597. X            }
  1598. X            *r = '\0';
  1599. X            p = q;
  1600. X            while (isspace(*p)) {
  1601. X                p++;
  1602. X            }
  1603. X            while (*p != '\0') {
  1604. X                q = p;
  1605. X                /* host name */
  1606. X                while (*q != '\0' && !isspace(*q) && *q != '(')
  1607. X                q++;
  1608. X                if ((tmp = (clnt_param *) malloc(sizeof *tmp)) == NULL
  1609. X                || (tmp->clnt_name = malloc(q-p+1)) == NULL)
  1610. X                MallocDeath("unfsd_init");
  1611. X                for (r = tmp->clnt_name; p < q;)
  1612. X                    *r++ = *p++;
  1613. X                *r = '\0';
  1614. X
  1615. X                /* Finish parsing options */
  1616. X                tmp->o = def_opts;
  1617. X                while (isspace(*p))
  1618. X                    p++;
  1619. X                if (*p == '(')
  1620. X                p = parse_opts(p+1, ')', &(tmp->o), tmp->clnt_name);
  1621. X
  1622. X                tmp->mount_point = mount_point;
  1623. X                
  1624. X                if ((hent = gethostbyname(tmp->clnt_name)) == NULL)
  1625. X                {
  1626. X                    char *reason;
  1627. X                    switch (h_errno) {
  1628. X#ifdef HOST_NOT_FOUND                           /* Only on 4.3 systems */
  1629. X                    case HOST_NOT_FOUND:
  1630. X                        reason = "Authoritive -- the host exists only in your imagination.";
  1631. X                        break;
  1632. X                    case TRY_AGAIN:
  1633. X                        reason = "Non-Authoritive -- the host might exist."; break;
  1634. X                    case NO_RECOVERY:
  1635. X                        reason = "Non-recoverable error."; break;
  1636. X                    case NO_ADDRESS:
  1637. X                        reason = "Valid host name, but no address."; break;
  1638. X#endif
  1639. X                    default:
  1640. X                        reason = "Unknown reason.";
  1641. X                    }
  1642. X                    Log3("Unknown host  in  file ", tmp->clnt_name, exportsfile);
  1643. X                    tmp->next = unknown_clients;
  1644. X                    unknown_clients = tmp;
  1645. X                } else {
  1646. X                    /* This should be changed to handle the address list under 4.3 */
  1647. X                    tmp->clnt_addr = *((struct in_addr *)hent->h_addr);
  1648. X                    tmp->next = clients;            /* Add to client list */
  1649. X                    clients = tmp;
  1650. X                }
  1651. X            }
  1652. X            free(lbuf);
  1653. X        }
  1654. X        fclose(f);
  1655. X    }
  1656. X    if (promiscuous) {
  1657. X        if ((tmp = (clnt_param *) malloc(sizeof *tmp)) == NULL)
  1658. X            MallocDeath("unfsd_init");
  1659. X        tmp->clnt_name = NULL;
  1660. X        tmp->mount_point = CACHEDIRVAR;                      /* vac */
  1661. X        default_client = tmp;
  1662. X        tmp->o = def_opts;
  1663. X    }
  1664. X}
  1665. X
  1666. Xint
  1667. X_in_gid_set(gid)
  1668. Xint gid;
  1669. X{
  1670. X    int i;
  1671. X
  1672. X    for (i = 0; i < svc_ngids; i++)
  1673. X        if (svc_gids[i] == gid)
  1674. X        {
  1675. X            cur_gid = gid;
  1676. X            return 1;
  1677. X        }
  1678. X    return 0;
  1679. X}
  1680. X
  1681. Xclnt_param *knownclient(rqstp)
  1682. Xstruct svc_req *rqstp;
  1683. X{
  1684. X    clnt_param  **cpp, *cp;
  1685. X    int IncomingPort;
  1686. X
  1687. X    /* find host parameter struct */
  1688. X    for (cpp = &clients; *cpp != NULL; cpp = &((*cpp)->next))
  1689. X    {
  1690. X        if ((*cpp)->clnt_addr.s_addr == svc_getcaller(rqstp->rq_xprt)->sin_addr.s_addr)
  1691. X        {
  1692. X            cp = *cpp;
  1693. X            if (cp != clients)
  1694. X            {
  1695. X                /* Move to front */
  1696. X                *cpp = cp->next;
  1697. X                cp->next = clients;
  1698. X                clients = cp;
  1699. X            }
  1700. X            goto found_it;
  1701. X        }
  1702. X    }
  1703. X
  1704. X    /* Check the list of clients we didn't know at start-up. */
  1705. X    {
  1706. X        struct hostent  *hent;
  1707. X/*      clnt_param *tmp; */
  1708. X        for (cpp = &unknown_clients; (cp = *cpp) != NULL;
  1709. X             cpp = &((*cpp)->next)) {
  1710. X            if ((hent = gethostbyname(cp->clnt_name)) != NULL) {
  1711. X                ToLog(DBFTP, "clnt_param Found previously unknown host %s\n", cp->clnt_name);
  1712. X                /* First remove from the unknown_clients list. */
  1713. X                *cpp = cp->next;
  1714. X
  1715. X                cp->clnt_addr = *((struct in_addr *)hent->h_addr);
  1716. X                cp->next = clients;         /* Add to front of client list. */
  1717. X                clients = cp;
  1718. X
  1719. X                if (cp->clnt_addr.s_addr == svc_getcaller(rqstp->rq_xprt)->sin_addr.s_addr)
  1720. X                    goto found_it;
  1721. X            }
  1722. X        }
  1723. X    }
  1724. X
  1725. X    if (default_client != NULL)
  1726. X        cp = default_client;
  1727. X    else
  1728. X    {
  1729. X        LogN("clnt_param Access attempt by unknown client ",       /* XXX better as %08X */
  1730. X            ntohl(svc_getcaller(rqstp->rq_xprt)->sin_addr.s_addr));
  1731. X        return NULL;
  1732. X    }
  1733. X    found_it:
  1734. X    /* check request originated on a privileged port */
  1735. X    IncomingPort = ntohs(svc_getcaller(rqstp->rq_xprt)->sin_port);
  1736. X    if (IncomingPort >= IPPORT_RESERVED && cp->o.secure_port) {
  1737. X        ToLog(DBERROR, "clnt_param ERROR NFS request originated on insecure port %d  %d \n",
  1738. X            IncomingPort, ntohl(svc_getcaller(rqstp->rq_xprt)->sin_addr.s_addr)); 
  1739. X
  1740. X        return NULL; 
  1741. X    }
  1742. X    return cp;
  1743. X}
  1744. X
  1745. X/*
  1746. X * Local variables:
  1747. X *  compile-command: "make"
  1748. X *  tab-width: 4
  1749. X *  comment-column: 48
  1750. X *  c-indent-level: 4
  1751. X *  c-continued-statement-offset: 4
  1752. X *  c-continued-brace-offset: -4
  1753. X *  c-brace-offset: 0
  1754. X *  c-brace-imaginary-offset: 0
  1755. X *  c-argdecl-indent: 0
  1756. X *  c-label-offset: -4
  1757. X * End:
  1758. X */
  1759. END_OF_FILE
  1760.   if test 15476 -ne `wc -c <'alexsrvr/src/init.c'`; then
  1761.     echo shar: \"'alexsrvr/src/init.c'\" unpacked with wrong size!
  1762.   fi
  1763.   # end of 'alexsrvr/src/init.c'
  1764. fi
  1765. if test -f 'alexsrvr/src/stringtotime.c' -a "${1}" != "-c" ; then 
  1766.   echo shar: Will not clobber existing file \"'alexsrvr/src/stringtotime.c'\"
  1767. else
  1768.   echo shar: Extracting \"'alexsrvr/src/stringtotime.c'\" \(19965 characters\)
  1769.   sed "s/^X//" >'alexsrvr/src/stringtotime.c' <<'END_OF_FILE'
  1770. X# define ID 257
  1771. X# define MONTH 258
  1772. X# define DAYOFWEEK 259
  1773. X# define MERIDIAN 260
  1774. X# define NUMBER 261
  1775. X# define ZONE 262
  1776. X# define DAYZONE 263
  1777. X
  1778. X# line 3 "stringtotime.y"
  1779. X
  1780. X/*  Vince  Cate  11/9/91  
  1781. X *
  1782. X *  Simplified a bit - no more shift/reduce conflicts.
  1783. X */
  1784. X
  1785. X/*      Steven M. Bellovin (unc!smb)                    */
  1786. X/*      Dept. of Computer Science                       */
  1787. X/*      University of North Carolina at Chapel Hill     */
  1788. X/*      @(#)getdate.y   2.13    9/16/86                 */
  1789. X
  1790. X/*      defining malloc in one of the following can cause problems if you do 
  1791. X *      a "make noyacc" because you do not have yacc  */
  1792. X#include "alexincs.h"
  1793. X#include "alex.h"
  1794. X
  1795. X#define daysec (24L*60L*60L)
  1796. X
  1797. Xstatic int timeflag, zoneflag, dateflag, yearflag;
  1798. Xstatic int hh, mm, ss, merid, daylightsvs;
  1799. Xstatic int month, day, year;
  1800. Xstatic int ourzone;
  1801. X
  1802. X#define AM 1
  1803. X#define PM 2
  1804. X#define DAYLIGHT 1
  1805. X#define STANDARD 2
  1806. X#define MAYBE    3
  1807. X#define yyclearin yychar = -1
  1808. X#define yyerrok yyerrflag = 0
  1809. Xextern int yychar;
  1810. Xextern short yyerrflag;
  1811. X#ifndef YYMAXDEPTH
  1812. X#define YYMAXDEPTH 150
  1813. X#endif
  1814. X#ifndef YYSTYPE
  1815. X#define YYSTYPE int
  1816. X#endif
  1817. XYYSTYPE yylval, yyval;
  1818. X# define YYERRCODE 256
  1819. X
  1820. X# line 86 "stringtotime.y"
  1821. X
  1822. X
  1823. Xstatic int mdays[12] =
  1824. X        {31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
  1825. X
  1826. X#define epoch 1970
  1827. X
  1828. Xextern struct tm *localtime();
  1829. Xtime_t dateconv(mm, dd, yy, h, m, s, mer, zone, daylightsvs)
  1830. Xint mm, dd, yy, h, m, s, mer, zone, daylightsvs;
  1831. X{
  1832. X    time_t tod, jdate;
  1833. X    register int i;
  1834. X    time_t timeconv();
  1835. X
  1836. X    if (yy < 0) yy = -yy;
  1837. X    if (yy < 100) yy += 1900;
  1838. X    mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
  1839. X    if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
  1840. X            dd < 1 || dd > mdays[--mm]) return (-1);
  1841. X    jdate = dd-1;
  1842. X    for (i=0; i<mm; i++) jdate += mdays[i];
  1843. X    for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
  1844. X    jdate *= daysec;
  1845. X    jdate += zone * 60L;
  1846. X    if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
  1847. X    jdate += tod;
  1848. X    if (daylightsvs==DAYLIGHT ||(daylightsvs==MAYBE&&localtime(&jdate)->tm_isdst))
  1849. X        jdate += -1*60*60;
  1850. X    return (jdate);
  1851. X}
  1852. X
  1853. X
  1854. Xtime_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer;
  1855. X{
  1856. X    if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
  1857. X    switch (mer) {
  1858. X        case AM: if (hh < 1 || hh > 12) return(-1);
  1859. X                 return (60L * ((hh%12)*60L + mm)+ss);
  1860. X        case PM: if (hh < 1 || hh > 12) return(-1);
  1861. X                 return (60L * ((hh%12 +12)*60L + mm)+ss);
  1862. X        case 24: if (hh < 0 || hh > 23) return (-1);
  1863. X                 return (60L * (hh*60L + mm)+ss);
  1864. X        default: return (-1);
  1865. X    }
  1866. X}
  1867. X
  1868. X
  1869. Xstatic char *lptr;
  1870. X
  1871. Xyylex()
  1872. X{
  1873. X    extern int yylval;
  1874. X    register char c;
  1875. X    register char *p;
  1876. X    char idbuf[20];
  1877. X    int pcnt;
  1878. X
  1879. X    for (;;) {
  1880. X        while (isspace(*lptr)) lptr++;
  1881. X
  1882. X        if (isdigit(c = *lptr)) {
  1883. X            yylval = 0;
  1884. X            while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
  1885. X                lptr--;
  1886. X            return (NUMBER);
  1887. X
  1888. X        } else if (isalpha(c)) {                      
  1889. X            p = idbuf;
  1890. X            while (isalnum(c = *lptr++) || c=='.' || c=='+' || c=='-') {
  1891. X                if (p < &idbuf[sizeof(idbuf)-1]) {
  1892. X                    *p++ = c;
  1893. X                }
  1894. X            }
  1895. X            *p = '\0';
  1896. X            lptr--;
  1897. X            return (lookup(idbuf));
  1898. X
  1899. X        } else if (c == '(') {                  /* ignore anything in parens */
  1900. X            pcnt = 0;
  1901. X            do {
  1902. X                c = *lptr++;
  1903. X                if (c == '\0') return(c);
  1904. X                else if (c == '(') pcnt++;
  1905. X                else if (c == ')') pcnt--;
  1906. X            } while (pcnt > 0);
  1907. X
  1908. X        } else {
  1909. X            return (*lptr++);
  1910. X        }
  1911. X    }
  1912. X}
  1913. X
  1914. Xstruct table {
  1915. X    char *name;
  1916. X    int type, value;
  1917. X};
  1918. X
  1919. Xstruct table mdtab[] = {       /* user can abreviate with just first 3 chars */
  1920. X        {"January", MONTH, 1},
  1921. X        {"February", MONTH, 2},
  1922. X        {"March", MONTH, 3},
  1923. X        {"April", MONTH, 4},
  1924. X        {"May", MONTH, 5},
  1925. X        {"June", MONTH, 6},
  1926. X        {"July", MONTH, 7},
  1927. X        {"August", MONTH, 8},
  1928. X        {"September", MONTH, 9},
  1929. X        {"October", MONTH, 10},
  1930. X        {"November", MONTH, 11},
  1931. X        {"December", MONTH, 12},
  1932. X
  1933. X        {"Sunday", DAYOFWEEK, 0},
  1934. X        {"Monday", DAYOFWEEK, 1},
  1935. X        {"Tuesday", DAYOFWEEK, 2},
  1936. X        {"Wednesday", DAYOFWEEK, 3},
  1937. X        {"Thursday", DAYOFWEEK, 4},
  1938. X        {"Friday", DAYOFWEEK, 5},
  1939. X        {"Saturday", DAYOFWEEK, 6},
  1940. X        {0, 0, 0}};
  1941. X
  1942. X#define HRS *60
  1943. X#define HALFHR 30
  1944. Xstruct table mztab[] = {           /* meridian and zones - always full length */
  1945. X        {"a.m.", MERIDIAN, AM},
  1946. X        {"am", MERIDIAN, AM},
  1947. X        {"p.m.", MERIDIAN, PM},
  1948. X        {"pm", MERIDIAN, PM},
  1949. X        {"nst", ZONE, 3 HRS + HALFHR},          /* Newfoundland */
  1950. X        {"n.s.t.", ZONE, 3 HRS + HALFHR},
  1951. X        {"ast", ZONE, 4 HRS},           /* Atlantic */
  1952. X        {"a.s.t.", ZONE, 4 HRS},
  1953. X        {"adt", DAYZONE, 4 HRS},
  1954. X        {"a.d.t.", DAYZONE, 4 HRS},
  1955. X        {"est", ZONE, 5 HRS},           /* Eastern */
  1956. X        {"e.s.t.", ZONE, 5 HRS},
  1957. X        {"edt", DAYZONE, 5 HRS},
  1958. X        {"e.d.t.", DAYZONE, 5 HRS},
  1959. X        {"cst", ZONE, 6 HRS},           /* Central */
  1960. X        {"c.s.t.", ZONE, 6 HRS},
  1961. X        {"cdt", DAYZONE, 6 HRS},
  1962. X        {"c.d.t.", DAYZONE, 6 HRS},
  1963. X        {"mst", ZONE, 7 HRS},           /* Mountain */
  1964. X        {"m.s.t.", ZONE, 7 HRS},
  1965. X        {"mdt", DAYZONE, 7 HRS},
  1966. X        {"m.d.t.", DAYZONE, 7 HRS},
  1967. X        {"pst", ZONE, 8 HRS},           /* Pacific */
  1968. X        {"p.s.t.", ZONE, 8 HRS},
  1969. X        {"pdt", DAYZONE, 8 HRS},
  1970. X        {"p.d.t.", DAYZONE, 8 HRS},
  1971. X        {"yst", ZONE, 9 HRS},           /* Yukon */
  1972. X        {"y.s.t.", ZONE, 9 HRS},
  1973. X        {"ydt", DAYZONE, 9 HRS},
  1974. X        {"y.d.t.", DAYZONE, 9 HRS},
  1975. X        {"hst", ZONE, 10 HRS},          /* Hawaii */
  1976. X        {"h.s.t.", ZONE, 10 HRS},
  1977. X        {"hdt", DAYZONE, 10 HRS},
  1978. X        {"h.d.t.", DAYZONE, 10 HRS},
  1979. X
  1980. X        {"gmt",      ZONE,  0 HRS},
  1981. X        {"gmt+000",  ZONE,  0 HRS},
  1982. X        {"gmt+100",  ZONE,  1 HRS},
  1983. X        {"gmt+200",  ZONE,  2 HRS},
  1984. X        {"gmt+300",  ZONE,  3 HRS},
  1985. X        {"gmt+400",  ZONE,  4 HRS},
  1986. X        {"gmt+500",  ZONE,  5 HRS},
  1987. X        {"gmt+600",  ZONE,  6 HRS},
  1988. X        {"gmt+700",  ZONE,  7 HRS},
  1989. X        {"gmt+800",  ZONE,  8 HRS},
  1990. X        {"gmt+900",  ZONE,  9 HRS},
  1991. X        {"gmt+1000", ZONE, 10 HRS},
  1992. X        {"gmt+1100", ZONE, 11 HRS},
  1993. X        {"gmt+1200", ZONE, 12 HRS},
  1994. X        {"gmt-100",  ZONE, -1 HRS},
  1995. X        {"gmt-200",  ZONE, -2 HRS},
  1996. X        {"gmt-300",  ZONE, -3 HRS},
  1997. X        {"gmt-400",  ZONE, -4 HRS},
  1998. X        {"gmt-500",  ZONE, -5 HRS},
  1999. X        {"gmt-600",  ZONE, -6 HRS},
  2000. X        {"gmt-700",  ZONE, -7 HRS},
  2001. X        {"gmt-800",  ZONE, -8 HRS},
  2002. X        {"gmt-900",  ZONE, -9 HRS},
  2003. X        {"gmt-1000", ZONE, -10 HRS},
  2004. X        {"gmt-1100", ZONE, -11 HRS},
  2005. X        {"g.m.t.", ZONE, 0 HRS},
  2006. X        {"bst", DAYZONE, 0 HRS},                /* British Summer Time */
  2007. X        {"b.s.t.", DAYZONE, 0 HRS},
  2008. X        {"eet", ZONE, 0 HRS},           /* European Eastern Time */
  2009. X        {"e.e.t.", ZONE, 0 HRS},
  2010. X        {"eest", DAYZONE, 0 HRS},       /* European Eastern Summer Time */
  2011. X        {"e.e.s.t.", DAYZONE, 0 HRS},
  2012. X        {"met", ZONE, -1 HRS},          /* Middle European Time */
  2013. X        {"m.e.t.", ZONE, -1 HRS},
  2014. X        {"mest", DAYZONE, -1 HRS},      /* Middle European Summer Time */
  2015. X        {"m.e.s.t.", DAYZONE, -1 HRS},
  2016. X        {"wet", ZONE, -2 HRS },         /* Western European Time */
  2017. X        {"w.e.t.", ZONE, -2 HRS },
  2018. X        {"west", DAYZONE, -2 HRS},      /* Western European Summer Time */
  2019. X        {"w.e.s.t.", DAYZONE, -2 HRS},
  2020. X
  2021. X        {"jst", ZONE, -9 HRS},          /* Japan Standard Time */
  2022. X        {"j.s.t.", ZONE, -9 HRS},       /* Japan Standard Time */
  2023. X                                        /* No daylight savings time */
  2024. X
  2025. X        {"aest", ZONE, -10 HRS},        /* Australian Eastern Time */
  2026. X        {"a.e.s.t.", ZONE, -10 HRS},
  2027. X        {"aesst", DAYZONE, -10 HRS},    /* Australian Eastern Summer Time */
  2028. X        {"a.e.s.s.t.", DAYZONE, -10 HRS},
  2029. X        {"acst", ZONE, -(9 HRS + HALFHR)},      /* Australian Central Time */
  2030. X        {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
  2031. X        {"acsst", DAYZONE, -(9 HRS + HALFHR)},  /* Australian Central Summer */
  2032. X        {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
  2033. X        {"awst", ZONE, -8 HRS},         /* Australian Western Time */
  2034. X        {"a.w.s.t.", ZONE, -8 HRS},     /* (no daylight time there, I'm told */
  2035. X        {0, 0, 0}};
  2036. X
  2037. Xstruct table milzone[] = {
  2038. X        {"a", ZONE, 1 HRS},
  2039. X        {"b", ZONE, 2 HRS},
  2040. X        {"c", ZONE, 3 HRS},
  2041. X        {"d", ZONE, 4 HRS},
  2042. X        {"e", ZONE, 5 HRS},
  2043. X        {"f", ZONE, 6 HRS},
  2044. X        {"g", ZONE, 7 HRS},
  2045. X        {"h", ZONE, 8 HRS},
  2046. X        {"i", ZONE, 9 HRS},
  2047. X        {"k", ZONE, 10 HRS},
  2048. X        {"l", ZONE, 11 HRS},
  2049. X        {"m", ZONE, 12 HRS},
  2050. X        {"n", ZONE, -1 HRS},
  2051. X        {"o", ZONE, -2 HRS},
  2052. X        {"p", ZONE, -3 HRS},
  2053. X        {"q", ZONE, -4 HRS},
  2054. X        {"r", ZONE, -5 HRS},
  2055. X        {"s", ZONE, -6 HRS},
  2056. X        {"t", ZONE, -7 HRS},
  2057. X        {"u", ZONE, -8 HRS},
  2058. X        {"v", ZONE, -9 HRS},
  2059. X        {"w", ZONE, -10 HRS},
  2060. X        {"x", ZONE, -11 HRS},
  2061. X        {"y", ZONE, -12 HRS},
  2062. X        {"z", ZONE, 0 HRS},
  2063. X        {0, 0, 0}};
  2064. X
  2065. Xlookup(id) 
  2066. Xchar *id;
  2067. X{
  2068. X#define gotit (yylval=i->value,  i->type)
  2069. X#define getid for(j=idvar, k=id;   *j++ = *k++;      )    /* fresh copy */
  2070. X
  2071. X    char idvar[20];
  2072. X    register char *j, *k;
  2073. X    register struct table *i;
  2074. X
  2075. X    getid;
  2076. X    for (i = mdtab; i->name; i++) {
  2077. X        if (strncasecmp(idvar, i->name, 3) == 0) {
  2078. X            return gotit;
  2079. X        }
  2080. X    }
  2081. X
  2082. X    getid;
  2083. X    for (i = mztab; i->name; i++)
  2084. X        if (strcmp(i->name, idvar) == 0) return gotit;
  2085. X
  2086. X    for (j = idvar; *j; j++)
  2087. X        if (isupper(*j)) *j = tolower(*j);
  2088. X    for (i=mztab; i->name; i++)
  2089. X        if (strcmp(i->name, idvar) == 0) return gotit;
  2090. X
  2091. X    getid;
  2092. X    if (strlen(idvar) == 1 && isalpha(*idvar)) {
  2093. X        if (isupper(*idvar)) *idvar = tolower(*idvar);
  2094. X        for (i = milzone; i->name; i++) {
  2095. X            if (strcmp(i->name, idvar) == 0) return gotit;
  2096. X        }
  2097. X    }
  2098. X
  2099. X    return(ID);
  2100. X}
  2101. X
  2102. X#define mcheck(f)       if (f>1) err++
  2103. X
  2104. Xint StringToTimeb(p, Now, Result) 
  2105. Xchar *p; 
  2106. Xstruct timeb *Now, *Result;
  2107. X{
  2108. X    int err;
  2109. X    struct tm *lt;
  2110. X    struct timeb ftz;
  2111. X    time_t sdate;
  2112. X
  2113. X    lptr = p;
  2114. X    if (Now == ((struct timeb *) NULL)) {
  2115. X        Now = &ftz;
  2116. X        ftime(&ftz);
  2117. X    }
  2118. X    lt = localtime(&Now->time);
  2119. X    year = lt->tm_year;
  2120. X    month = lt->tm_mon+1;
  2121. X    day = lt->tm_mday;
  2122. X    timeflag=zoneflag=dateflag=yearflag=0;
  2123. X    ourzone = Now->timezone;
  2124. X    daylightsvs = MAYBE;
  2125. X    hh = mm = ss = 0;
  2126. X    merid = 24;
  2127. X
  2128. X    err=yyparse();
  2129. X    if (err) {
  2130. X        Log2("StringToTimeb could not parse date ", p);
  2131. X        return(AFAIL);
  2132. X    }
  2133. X
  2134. X    mcheck(timeflag);               /* each of these should be at most 1 */
  2135. X    mcheck(zoneflag);
  2136. X    mcheck(dateflag);
  2137. X    mcheck(yearflag);
  2138. X
  2139. X    if (err) {
  2140. X        Log2("StringToTimeb ERROR parsed some type of field twice", p);
  2141. X        return(AFAIL);
  2142. X    }
  2143. X    if (!dateflag && !timeflag) {   
  2144. X        Log2("StringToTimeb ERROR did not find a major item in string ", p);
  2145. X        return(AFAIL);
  2146. X    }
  2147. X
  2148. X    sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylightsvs);
  2149. X    if (sdate < 0) {
  2150. X        Log2("StringToTimeb ERROR from dateconv", p);
  2151. X        return(AFAIL);
  2152. X    }
  2153. X
  2154. X/*  This is for times of files, so if there is no year we assume it could
  2155. X *  be up to a day ahead but otherwise in the past if no year specified.  
  2156. X */ 
  2157. X    if (!yearflag && (sdate > (Now->time + ADAY))) { 
  2158. X        Log2("StringToTimeb backing up a year since file dates must be in past", p);
  2159. X        year--;                                       
  2160. X        sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylightsvs);
  2161. X        if (sdate < 0) {
  2162. X            Log2("StringToTimeb ERROR from dateconv after backing up a year", p);
  2163. X            return(AFAIL);
  2164. X        }
  2165. X    }
  2166. X
  2167. X
  2168. X    Result->time=sdate;
  2169. X    Result->millitm=0;
  2170. X    Result->timezone=ourzone;
  2171. X    Result->dstflag=daylightsvs; 
  2172. X
  2173. X    Log("StringToTimeb returning AOK");
  2174. X    return(AOK);
  2175. X}
  2176. X
  2177. Xyyerror(s)
  2178. Xchar *s;
  2179. X{
  2180. X    Log2("yyerror", s);
  2181. X}
  2182. X
  2183. Xshort yyexca[] ={
  2184. X-1, 1,
  2185. X    0, -1,
  2186. X    -2, 0,
  2187. X    };
  2188. X# define YYNPROD 22
  2189. X# define YYLAST 212
  2190. Xshort yyact[]={
  2191. X
  2192. X  12,   8,  34,  11,   9,  10,  33,  32,  31,  28,
  2193. X  24,  23,  22,  35,  25,  21,  29,  20,  30,  26,
  2194. X   7,   6,   5,   4,   3,   2,   1,   0,  19,  13,
  2195. X  14,  15,  16,  17,  18,   0,   0,   0,   0,   0,
  2196. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2197. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2198. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2199. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2200. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2201. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2202. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2203. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2204. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2205. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2206. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2207. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2208. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2209. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2210. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2211. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2212. X   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  2213. X   0,  27 };
  2214. Xshort yypact[]={
  2215. X
  2216. X-258,-1000,-258,-258,-258,-258,-258,-258,-1000,-1000,
  2217. X-1000, -30,-249,-1000,-1000,-1000,-1000,-1000,-1000,-250,
  2218. X-251,-244, -25, -49, -31, -27,-253,-1000,-254,-255,
  2219. X-259,-1000,-247,-1000,-1000,-1000 };
  2220. Xshort yypgo[]={
  2221. X
  2222. X   0,  26,  25,  24,  23,  22,  21,  20 };
  2223. Xshort yyr1[]={
  2224. X
  2225. X   0,   1,   1,   1,   1,   1,   1,   1,   2,   7,
  2226. X   4,   4,   4,   4,   3,   3,   5,   5,   5,   6,
  2227. X   6,   6 };
  2228. Xshort yyr2[]={
  2229. X
  2230. X   0,   0,   2,   2,   2,   2,   2,   2,   1,   1,
  2231. X   3,   4,   5,   6,   1,   1,   3,   2,   3,   5,
  2232. X   4,   5 };
  2233. Xshort yychk[]={
  2234. X
  2235. X-1000,  -1,  -2,  -3,  -4,  -5,  -6,  -7, 259, 262,
  2236. X 263, 261, 258,  -1,  -1,  -1,  -1,  -1,  -1,  58,
  2237. X  47,  45, 261, 261, 261, 258,  44, 260,  58,  47,
  2238. X  45, 261, 261, 261, 261, 260 };
  2239. Xshort yydef[]={
  2240. X
  2241. X   1,  -2,   1,   1,   1,   1,   1,   1,   8,  14,
  2242. X  15,   9,   0,   2,   3,   4,   5,   6,   7,   0,
  2243. X   0,   0,  17,  10,  16,  18,   0,  11,   0,   0,
  2244. X   0,  20,  12,  19,  21,  13 };
  2245. X/*
  2246. X **********************************************************************
  2247. X * HISTORY
  2248. X * $Log:    yaccpar,v $
  2249. X * Revision 2.2  89/05/30  11:38:04  gm0w
  2250. X *     Removed unknown preprocessor directive "#".
  2251. X *     [89/05/30            gm0w]
  2252. X * 
  2253. X **********************************************************************
  2254. X */
  2255. X#ifndef lint
  2256. Xstatic char yaccpar_sccsid[] = "@(#)yaccpar    4.1    (Berkeley)    2/11/83";
  2257. X#endif not lint
  2258. X
  2259. X# define YYFLAG -1000
  2260. X# define YYERROR goto yyerrlab
  2261. X# define YYACCEPT return(0)
  2262. X# define YYABORT return(1)
  2263. X
  2264. X/*    parser for yacc output    */
  2265. X
  2266. X#ifdef YYDEBUG
  2267. Xint yydebug = 0; /* 1 for debugging */
  2268. X#endif
  2269. XYYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
  2270. Xint yychar = -1; /* current input token number */
  2271. Xint yynerrs = 0;  /* number of errors */
  2272. Xshort yyerrflag = 0;  /* error recovery flag */
  2273. X
  2274. Xyyparse() {
  2275. X
  2276. X    short yys[YYMAXDEPTH];
  2277. X    short yyj, yym;
  2278. X    register YYSTYPE *yypvt;
  2279. X    register short yystate, *yyps, yyn;
  2280. X    register YYSTYPE *yypv;
  2281. X    register short *yyxi;
  2282. X
  2283. X    yystate = 0;
  2284. X    yychar = -1;
  2285. X    yynerrs = 0;
  2286. X    yyerrflag = 0;
  2287. X    yyps= &yys[-1];
  2288. X    yypv= &yyv[-1];
  2289. X
  2290. X yystack:    /* put a state and value onto the stack */
  2291. X
  2292. X#ifdef YYDEBUG
  2293. X    if( yydebug  ) printf( "state %d, char 0%o\n", yystate, yychar );
  2294. X#endif
  2295. X        if( ++yyps> &yys[YYMAXDEPTH] ) { yyerror( "yacc stack overflow" ); return(1); }
  2296. X        *yyps = yystate;
  2297. X        ++yypv;
  2298. X        *yypv = yyval;
  2299. X
  2300. X yynewstate:
  2301. X
  2302. X    yyn = yypact[yystate];
  2303. X
  2304. X    if( yyn<= YYFLAG ) goto yydefault; /* simple state */
  2305. X
  2306. X    if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0;
  2307. X    if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault;
  2308. X
  2309. X    if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */
  2310. X        yychar = -1;
  2311. X        yyval = yylval;
  2312. X        yystate = yyn;
  2313. X        if( yyerrflag > 0 ) --yyerrflag;
  2314. X        goto yystack;
  2315. X        }
  2316. X
  2317. X yydefault:
  2318. X    /* default state action */
  2319. X
  2320. X    if( (yyn=yydef[yystate]) == -2 ) {
  2321. X        if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0;
  2322. X        /* look through exception table */
  2323. X
  2324. X        for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */
  2325. X
  2326. X        while( *(yyxi+=2) >= 0 ){
  2327. X            if( *yyxi == yychar ) break;
  2328. X            }
  2329. X        if( (yyn = yyxi[1]) < 0 ) return(0);   /* accept */
  2330. X        }
  2331. X
  2332. X    if( yyn == 0 ){ /* error */
  2333. X        /* error ... attempt to resume parsing */
  2334. X
  2335. X        switch( yyerrflag ){
  2336. X
  2337. X        case 0:   /* brand new error */
  2338. X
  2339. X            yyerror( "syntax error" );
  2340. X        yyerrlab:
  2341. X            ++yynerrs;
  2342. X
  2343. X        case 1:
  2344. X        case 2: /* incompletely recovered error ... try again */
  2345. X
  2346. X            yyerrflag = 3;
  2347. X
  2348. X            /* find a state where "error" is a legal shift action */
  2349. X
  2350. X            while ( yyps >= yys ) {
  2351. X               yyn = yypact[*yyps] + YYERRCODE;
  2352. X               if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){
  2353. X                  yystate = yyact[yyn];  /* simulate a shift of "error" */
  2354. X                  goto yystack;
  2355. X                  }
  2356. X               yyn = yypact[*yyps];
  2357. X
  2358. X               /* the current yyps has no shift onn "error", pop stack */
  2359. X
  2360. X#ifdef YYDEBUG
  2361. X               if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] );
  2362. X#endif
  2363. X               --yyps;
  2364. X               --yypv;
  2365. X               }
  2366. X
  2367. X            /* there is no state on the stack with an error shift ... abort */
  2368. X
  2369. X    yyabort:
  2370. X            return(1);
  2371. X
  2372. X
  2373. X        case 3:  /* no shift yet; clobber input char */
  2374. X
  2375. X#ifdef YYDEBUG
  2376. X            if( yydebug ) printf( "error recovery discards char %d\n", yychar );
  2377. X#endif
  2378. X
  2379. X            if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */
  2380. X            yychar = -1;
  2381. X            goto yynewstate;   /* try again in the same state */
  2382. X
  2383. X            }
  2384. X
  2385. X        }
  2386. X
  2387. X    /* reduction by production yyn */
  2388. X
  2389. X#ifdef YYDEBUG
  2390. X        if( yydebug ) printf("reduce %d\n",yyn);
  2391. X#endif
  2392. X        yyps -= yyr2[yyn];
  2393. X        yypvt = yypv;
  2394. X        yypv -= yyr2[yyn];
  2395. X        yyval = yypv[1];
  2396. X        yym=yyn;
  2397. X            /* consult goto table to find next state */
  2398. X        yyn = yyr1[yyn];
  2399. X        yyj = yypgo[yyn] + *yyps + 1;
  2400. X        if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]];
  2401. X        switch(yym){
  2402. X            
  2403. Xcase 2:
  2404. X# line 36 "stringtotime.y"
  2405. X
  2406. X                {;} break;
  2407. Xcase 3:
  2408. X# line 38 "stringtotime.y"
  2409. X
  2410. X                {zoneflag++;} break;
  2411. Xcase 4:
  2412. X# line 40 "stringtotime.y"
  2413. X
  2414. X                {timeflag++;} break;
  2415. Xcase 5:
  2416. X# line 42 "stringtotime.y"
  2417. X
  2418. X                {dateflag++;} break;
  2419. Xcase 6:
  2420. X# line 44 "stringtotime.y"
  2421. X
  2422. X                {dateflag++; yearflag++;} break;
  2423. Xcase 7:
  2424. X# line 46 "stringtotime.y"
  2425. X
  2426. X                {yearflag++;} break;
  2427. Xcase 8:
  2428. X# line 49 "stringtotime.y"
  2429. X
  2430. X                {;} break;
  2431. Xcase 9:
  2432. X# line 53 "stringtotime.y"
  2433. X
  2434. X                {year = yypvt[-0]; } break;
  2435. Xcase 10:
  2436. X# line 56 "stringtotime.y"
  2437. X
  2438. X                {hh = yypvt[-2]; mm = yypvt[-0]; ss=0; merid = 24;} break;
  2439. Xcase 11:
  2440. X# line 58 "stringtotime.y"
  2441. X
  2442. X                {hh = yypvt[-3]; mm = yypvt[-1]; ss=0; merid = yypvt[-0];} break;
  2443. Xcase 12:
  2444. X# line 60 "stringtotime.y"
  2445. X
  2446. X                {hh = yypvt[-4]; mm = yypvt[-2]; ss = yypvt[-0]; merid = 24;} break;
  2447. Xcase 13:
  2448. X# line 62 "stringtotime.y"
  2449. X
  2450. X                {hh = yypvt[-5]; mm = yypvt[-3]; ss = yypvt[-1]; merid = yypvt[-0];} break;
  2451. Xcase 14:
  2452. X# line 66 "stringtotime.y"
  2453. X
  2454. X                {ourzone = yypvt[-0]; daylightsvs = STANDARD;} break;
  2455. Xcase 15:
  2456. X# line 68 "stringtotime.y"
  2457. X
  2458. X                {ourzone = yypvt[-0]; daylightsvs = DAYLIGHT;} break;
  2459. Xcase 16:
  2460. X# line 71 "stringtotime.y"
  2461. X
  2462. X                {month = yypvt[-2]; day = yypvt[-0];} break;
  2463. Xcase 17:
  2464. X# line 73 "stringtotime.y"
  2465. X
  2466. X                {month = yypvt[-1]; day = yypvt[-0];} break;
  2467. Xcase 18:
  2468. X# line 75 "stringtotime.y"
  2469. X
  2470. X                {month = yypvt[-0]; day = yypvt[-2];} break;
  2471. Xcase 19:
  2472. X# line 78 "stringtotime.y"
  2473. X
  2474. X                {month = yypvt[-4]; day = yypvt[-2]; year = yypvt[-0];  } break;
  2475. Xcase 20:
  2476. X# line 80 "stringtotime.y"
  2477. X
  2478. X                {month = yypvt[-3]; day = yypvt[-2]; year = yypvt[-0];  } break;
  2479. Xcase 21:
  2480. X# line 82 "stringtotime.y"
  2481. X
  2482. X                {month = yypvt[-2]; day = yypvt[-4]; year = yypvt[-0];  } break;
  2483. X        }
  2484. X        goto yystack;  /* stack new state and value */
  2485. X
  2486. X    }
  2487. END_OF_FILE
  2488.   if test 19965 -ne `wc -c <'alexsrvr/src/stringtotime.c'`; then
  2489.     echo shar: \"'alexsrvr/src/stringtotime.c'\" unpacked with wrong size!
  2490.   fi
  2491.   # end of 'alexsrvr/src/stringtotime.c'
  2492. fi
  2493. if test -f 'alexsrvr/src/stringtotime.y' -a "${1}" != "-c" ; then 
  2494.   echo shar: Will not clobber existing file \"'alexsrvr/src/stringtotime.y'\"
  2495. else
  2496.   echo shar: Extracting \"'alexsrvr/src/stringtotime.y'\" \(13406 characters\)
  2497.   sed "s/^X//" >'alexsrvr/src/stringtotime.y' <<'END_OF_FILE'
  2498. X%token ID MONTH DAYOFWEEK MERIDIAN NUMBER ZONE DAYZONE 
  2499. X%{
  2500. X
  2501. X/*  Vince  Cate  11/9/91  
  2502. X *
  2503. X *  Simplified a bit - no more shift/reduce conflicts.
  2504. X */
  2505. X
  2506. X/*      Steven M. Bellovin (unc!smb)                    */
  2507. X/*      Dept. of Computer Science                       */
  2508. X/*      University of North Carolina at Chapel Hill     */
  2509. X/*      @(#)getdate.y   2.13    9/16/86                 */
  2510. X
  2511. X/*      defining malloc in one of the following can cause problems if you do 
  2512. X *      a "make noyacc" because you do not have yacc  */
  2513. X#include "alexincs.h"
  2514. X#include "alex.h"
  2515. X
  2516. X#define daysec (24L*60L*60L)
  2517. X
  2518. Xstatic int timeflag, zoneflag, dateflag, yearflag;
  2519. Xstatic int hh, mm, ss, merid, daylightsvs;
  2520. Xstatic int month, day, year;
  2521. Xstatic int ourzone;
  2522. X
  2523. X#define AM 1
  2524. X#define PM 2
  2525. X#define DAYLIGHT 1
  2526. X#define STANDARD 2
  2527. X#define MAYBE    3
  2528. X%}
  2529. X
  2530. X%%
  2531. X
  2532. Xvalidstring:   /* empty */
  2533. X        | dayofweek validstring =
  2534. X                {;}
  2535. X        | zonespec validstring =
  2536. X                {zoneflag++;}
  2537. X        | timespec validstring =
  2538. X                {timeflag++;}
  2539. X        | datespec validstring =
  2540. X                {dateflag++;}
  2541. X        | dateyearspec validstring =
  2542. X                {dateflag++; yearflag++;}
  2543. X        | yearspec validstring =
  2544. X                {yearflag++;};
  2545. X
  2546. Xdayofweek: DAYOFWEEK =
  2547. X                {;};
  2548. X
  2549. X
  2550. Xyearspec:       NUMBER =
  2551. X                {year = $1; };
  2552. X
  2553. Xtimespec: NUMBER ':' NUMBER =
  2554. X                {hh = $1; mm = $3; ss=0; merid = 24;}
  2555. X        | NUMBER ':' NUMBER MERIDIAN =
  2556. X                {hh = $1; mm = $3; ss=0; merid = $4;}
  2557. X        | NUMBER ':' NUMBER ':' NUMBER =
  2558. X                {hh = $1; mm = $3; ss = $5; merid = 24;}
  2559. X        | NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
  2560. X                {hh = $1; mm = $3; ss = $5; merid = $6;};
  2561. X
  2562. X/* note that zone flag means that both ourzone and daylightsvs are set */
  2563. Xzonespec:       ZONE =
  2564. X                {ourzone = $1; daylightsvs = STANDARD;}
  2565. X        | DAYZONE =
  2566. X                {ourzone = $1; daylightsvs = DAYLIGHT;};
  2567. X
  2568. Xdatespec:       NUMBER '/' NUMBER =
  2569. X                {month = $1; day = $3;}
  2570. X        | MONTH NUMBER =
  2571. X                {month = $1; day = $2;}
  2572. X        | NUMBER '-' MONTH =
  2573. X                {month = $3; day = $1;};
  2574. X
  2575. Xdateyearspec:  NUMBER '/' NUMBER '/' NUMBER =
  2576. X                {month = $1; day = $3; year = $5;  }
  2577. X        | MONTH NUMBER ',' NUMBER =
  2578. X                {month = $1; day = $2; year = $4;  }
  2579. X        | NUMBER '-' MONTH '-' NUMBER =
  2580. X                {month = $3; day = $1; year = $5;  };
  2581. X
  2582. X
  2583. X%%
  2584. X
  2585. Xstatic int mdays[12] =
  2586. X        {31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
  2587. X
  2588. X#define epoch 1970
  2589. X
  2590. Xextern struct tm *localtime();
  2591. Xtime_t dateconv(mm, dd, yy, h, m, s, mer, zone, daylightsvs)
  2592. Xint mm, dd, yy, h, m, s, mer, zone, daylightsvs;
  2593. X{
  2594. X    time_t tod, jdate;
  2595. X    register int i;
  2596. X    time_t timeconv();
  2597. X
  2598. X    if (yy < 0) yy = -yy;
  2599. X    if (yy < 100) yy += 1900;
  2600. X    mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
  2601. X    if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
  2602. X            dd < 1 || dd > mdays[--mm]) return (-1);
  2603. X    jdate = dd-1;
  2604. X    for (i=0; i<mm; i++) jdate += mdays[i];
  2605. X    for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
  2606. X    jdate *= daysec;
  2607. X    jdate += zone * 60L;
  2608. X    if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
  2609. X    jdate += tod;
  2610. X    if (daylightsvs==DAYLIGHT ||(daylightsvs==MAYBE&&localtime(&jdate)->tm_isdst))
  2611. X        jdate += -1*60*60;
  2612. X    return (jdate);
  2613. X}
  2614. X
  2615. X
  2616. Xtime_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer;
  2617. X{
  2618. X    if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
  2619. X    switch (mer) {
  2620. X        case AM: if (hh < 1 || hh > 12) return(-1);
  2621. X                 return (60L * ((hh%12)*60L + mm)+ss);
  2622. X        case PM: if (hh < 1 || hh > 12) return(-1);
  2623. X                 return (60L * ((hh%12 +12)*60L + mm)+ss);
  2624. X        case 24: if (hh < 0 || hh > 23) return (-1);
  2625. X                 return (60L * (hh*60L + mm)+ss);
  2626. X        default: return (-1);
  2627. X    }
  2628. X}
  2629. X
  2630. X
  2631. Xstatic char *lptr;
  2632. X
  2633. Xyylex()
  2634. X{
  2635. X    extern int yylval;
  2636. X    register char c;
  2637. X    register char *p;
  2638. X    char idbuf[20];
  2639. X    int pcnt;
  2640. X
  2641. X    for (;;) {
  2642. X        while (isspace(*lptr)) lptr++;
  2643. X
  2644. X        if (isdigit(c = *lptr)) {
  2645. X            yylval = 0;
  2646. X            while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
  2647. X                lptr--;
  2648. X            return (NUMBER);
  2649. X
  2650. X        } else if (isalpha(c)) {                      
  2651. X            p = idbuf;
  2652. X            while (isalnum(c = *lptr++) || c=='.' || c=='+' || c=='-') {
  2653. X                if (p < &idbuf[sizeof(idbuf)-1]) {
  2654. X                    *p++ = c;
  2655. X                }
  2656. X            }
  2657. X            *p = '\0';
  2658. X            lptr--;
  2659. X            return (lookup(idbuf));
  2660. X
  2661. X        } else if (c == '(') {                  /* ignore anything in parens */
  2662. X            pcnt = 0;
  2663. X            do {
  2664. X                c = *lptr++;
  2665. X                if (c == '\0') return(c);
  2666. X                else if (c == '(') pcnt++;
  2667. X                else if (c == ')') pcnt--;
  2668. X            } while (pcnt > 0);
  2669. X
  2670. X        } else {
  2671. X            return (*lptr++);
  2672. X        }
  2673. X    }
  2674. X}
  2675. X
  2676. Xstruct table {
  2677. X    char *name;
  2678. X    int type, value;
  2679. X};
  2680. X
  2681. Xstruct table mdtab[] = {       /* user can abreviate with just first 3 chars */
  2682. X        {"January", MONTH, 1},
  2683. X        {"February", MONTH, 2},
  2684. X        {"March", MONTH, 3},
  2685. X        {"April", MONTH, 4},
  2686. X        {"May", MONTH, 5},
  2687. X        {"June", MONTH, 6},
  2688. X        {"July", MONTH, 7},
  2689. X        {"August", MONTH, 8},
  2690. X        {"September", MONTH, 9},
  2691. X        {"October", MONTH, 10},
  2692. X        {"November", MONTH, 11},
  2693. X        {"December", MONTH, 12},
  2694. X
  2695. X        {"Sunday", DAYOFWEEK, 0},
  2696. X        {"Monday", DAYOFWEEK, 1},
  2697. X        {"Tuesday", DAYOFWEEK, 2},
  2698. X        {"Wednesday", DAYOFWEEK, 3},
  2699. X        {"Thursday", DAYOFWEEK, 4},
  2700. X        {"Friday", DAYOFWEEK, 5},
  2701. X        {"Saturday", DAYOFWEEK, 6},
  2702. X        {0, 0, 0}};
  2703. X
  2704. X#define HRS *60
  2705. X#define HALFHR 30
  2706. Xstruct table mztab[] = {           /* meridian and zones - always full length */
  2707. X        {"a.m.", MERIDIAN, AM},
  2708. X        {"am", MERIDIAN, AM},
  2709. X        {"p.m.", MERIDIAN, PM},
  2710. X        {"pm", MERIDIAN, PM},
  2711. X        {"nst", ZONE, 3 HRS + HALFHR},          /* Newfoundland */
  2712. X        {"n.s.t.", ZONE, 3 HRS + HALFHR},
  2713. X        {"ast", ZONE, 4 HRS},           /* Atlantic */
  2714. X        {"a.s.t.", ZONE, 4 HRS},
  2715. X        {"adt", DAYZONE, 4 HRS},
  2716. X        {"a.d.t.", DAYZONE, 4 HRS},
  2717. X        {"est", ZONE, 5 HRS},           /* Eastern */
  2718. X        {"e.s.t.", ZONE, 5 HRS},
  2719. X        {"edt", DAYZONE, 5 HRS},
  2720. X        {"e.d.t.", DAYZONE, 5 HRS},
  2721. X        {"cst", ZONE, 6 HRS},           /* Central */
  2722. X        {"c.s.t.", ZONE, 6 HRS},
  2723. X        {"cdt", DAYZONE, 6 HRS},
  2724. X        {"c.d.t.", DAYZONE, 6 HRS},
  2725. X        {"mst", ZONE, 7 HRS},           /* Mountain */
  2726. X        {"m.s.t.", ZONE, 7 HRS},
  2727. X        {"mdt", DAYZONE, 7 HRS},
  2728. X        {"m.d.t.", DAYZONE, 7 HRS},
  2729. X        {"pst", ZONE, 8 HRS},           /* Pacific */
  2730. X        {"p.s.t.", ZONE, 8 HRS},
  2731. X        {"pdt", DAYZONE, 8 HRS},
  2732. X        {"p.d.t.", DAYZONE, 8 HRS},
  2733. X        {"yst", ZONE, 9 HRS},           /* Yukon */
  2734. X        {"y.s.t.", ZONE, 9 HRS},
  2735. X        {"ydt", DAYZONE, 9 HRS},
  2736. X        {"y.d.t.", DAYZONE, 9 HRS},
  2737. X        {"hst", ZONE, 10 HRS},          /* Hawaii */
  2738. X        {"h.s.t.", ZONE, 10 HRS},
  2739. X        {"hdt", DAYZONE, 10 HRS},
  2740. X        {"h.d.t.", DAYZONE, 10 HRS},
  2741. X
  2742. X        {"gmt",      ZONE,  0 HRS},
  2743. X        {"gmt+000",  ZONE,  0 HRS},
  2744. X        {"gmt+100",  ZONE,  1 HRS},
  2745. X        {"gmt+200",  ZONE,  2 HRS},
  2746. X        {"gmt+300",  ZONE,  3 HRS},
  2747. X        {"gmt+400",  ZONE,  4 HRS},
  2748. X        {"gmt+500",  ZONE,  5 HRS},
  2749. X        {"gmt+600",  ZONE,  6 HRS},
  2750. X        {"gmt+700",  ZONE,  7 HRS},
  2751. X        {"gmt+800",  ZONE,  8 HRS},
  2752. X        {"gmt+900",  ZONE,  9 HRS},
  2753. X        {"gmt+1000", ZONE, 10 HRS},
  2754. X        {"gmt+1100", ZONE, 11 HRS},
  2755. X        {"gmt+1200", ZONE, 12 HRS},
  2756. X        {"gmt-100",  ZONE, -1 HRS},
  2757. X        {"gmt-200",  ZONE, -2 HRS},
  2758. X        {"gmt-300",  ZONE, -3 HRS},
  2759. X        {"gmt-400",  ZONE, -4 HRS},
  2760. X        {"gmt-500",  ZONE, -5 HRS},
  2761. X        {"gmt-600",  ZONE, -6 HRS},
  2762. X        {"gmt-700",  ZONE, -7 HRS},
  2763. X        {"gmt-800",  ZONE, -8 HRS},
  2764. X        {"gmt-900",  ZONE, -9 HRS},
  2765. X        {"gmt-1000", ZONE, -10 HRS},
  2766. X        {"gmt-1100", ZONE, -11 HRS},
  2767. X        {"g.m.t.", ZONE, 0 HRS},
  2768. X        {"bst", DAYZONE, 0 HRS},                /* British Summer Time */
  2769. X        {"b.s.t.", DAYZONE, 0 HRS},
  2770. X        {"eet", ZONE, 0 HRS},           /* European Eastern Time */
  2771. X        {"e.e.t.", ZONE, 0 HRS},
  2772. X        {"eest", DAYZONE, 0 HRS},       /* European Eastern Summer Time */
  2773. X        {"e.e.s.t.", DAYZONE, 0 HRS},
  2774. X        {"met", ZONE, -1 HRS},          /* Middle European Time */
  2775. X        {"m.e.t.", ZONE, -1 HRS},
  2776. X        {"mest", DAYZONE, -1 HRS},      /* Middle European Summer Time */
  2777. X        {"m.e.s.t.", DAYZONE, -1 HRS},
  2778. X        {"wet", ZONE, -2 HRS },         /* Western European Time */
  2779. X        {"w.e.t.", ZONE, -2 HRS },
  2780. X        {"west", DAYZONE, -2 HRS},      /* Western European Summer Time */
  2781. X        {"w.e.s.t.", DAYZONE, -2 HRS},
  2782. X
  2783. X        {"jst", ZONE, -9 HRS},          /* Japan Standard Time */
  2784. X        {"j.s.t.", ZONE, -9 HRS},       /* Japan Standard Time */
  2785. X                                        /* No daylight savings time */
  2786. X
  2787. X        {"aest", ZONE, -10 HRS},        /* Australian Eastern Time */
  2788. X        {"a.e.s.t.", ZONE, -10 HRS},
  2789. X        {"aesst", DAYZONE, -10 HRS},    /* Australian Eastern Summer Time */
  2790. X        {"a.e.s.s.t.", DAYZONE, -10 HRS},
  2791. X        {"acst", ZONE, -(9 HRS + HALFHR)},      /* Australian Central Time */
  2792. X        {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
  2793. X        {"acsst", DAYZONE, -(9 HRS + HALFHR)},  /* Australian Central Summer */
  2794. X        {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
  2795. X        {"awst", ZONE, -8 HRS},         /* Australian Western Time */
  2796. X        {"a.w.s.t.", ZONE, -8 HRS},     /* (no daylight time there, I'm told */
  2797. X        {0, 0, 0}};
  2798. X
  2799. Xstruct table milzone[] = {
  2800. X        {"a", ZONE, 1 HRS},
  2801. X        {"b", ZONE, 2 HRS},
  2802. X        {"c", ZONE, 3 HRS},
  2803. X        {"d", ZONE, 4 HRS},
  2804. X        {"e", ZONE, 5 HRS},
  2805. X        {"f", ZONE, 6 HRS},
  2806. X        {"g", ZONE, 7 HRS},
  2807. X        {"h", ZONE, 8 HRS},
  2808. X        {"i", ZONE, 9 HRS},
  2809. X        {"k", ZONE, 10 HRS},
  2810. X        {"l", ZONE, 11 HRS},
  2811. X        {"m", ZONE, 12 HRS},
  2812. X        {"n", ZONE, -1 HRS},
  2813. X        {"o", ZONE, -2 HRS},
  2814. X        {"p", ZONE, -3 HRS},
  2815. X        {"q", ZONE, -4 HRS},
  2816. X        {"r", ZONE, -5 HRS},
  2817. X        {"s", ZONE, -6 HRS},
  2818. X        {"t", ZONE, -7 HRS},
  2819. X        {"u", ZONE, -8 HRS},
  2820. X        {"v", ZONE, -9 HRS},
  2821. X        {"w", ZONE, -10 HRS},
  2822. X        {"x", ZONE, -11 HRS},
  2823. X        {"y", ZONE, -12 HRS},
  2824. X        {"z", ZONE, 0 HRS},
  2825. X        {0, 0, 0}};
  2826. X
  2827. Xlookup(id) 
  2828. Xchar *id;
  2829. X{
  2830. X#define gotit (yylval=i->value,  i->type)
  2831. X#define getid for(j=idvar, k=id;   *j++ = *k++;      )    /* fresh copy */
  2832. X
  2833. X    char idvar[20];
  2834. X    register char *j, *k;
  2835. X    register struct table *i;
  2836. X
  2837. X    getid;
  2838. X    for (i = mdtab; i->name; i++) {
  2839. X        if (strncasecmp(idvar, i->name, 3) == 0) {
  2840. X            return gotit;
  2841. X        }
  2842. X    }
  2843. X
  2844. X    getid;
  2845. X    for (i = mztab; i->name; i++)
  2846. X        if (strcmp(i->name, idvar) == 0) return gotit;
  2847. X
  2848. X    for (j = idvar; *j; j++)
  2849. X        if (isupper(*j)) *j = tolower(*j);
  2850. X    for (i=mztab; i->name; i++)
  2851. X        if (strcmp(i->name, idvar) == 0) return gotit;
  2852. X
  2853. X    getid;
  2854. X    if (strlen(idvar) == 1 && isalpha(*idvar)) {
  2855. X        if (isupper(*idvar)) *idvar = tolower(*idvar);
  2856. X        for (i = milzone; i->name; i++) {
  2857. X            if (strcmp(i->name, idvar) == 0) return gotit;
  2858. X        }
  2859. X    }
  2860. X
  2861. X    return(ID);
  2862. X}
  2863. X
  2864. X#define mcheck(f)       if (f>1) err++
  2865. X
  2866. Xint StringToTimeb(p, Now, Result) 
  2867. Xchar *p; 
  2868. Xstruct timeb *Now, *Result;
  2869. X{
  2870. X    int err;
  2871. X    struct tm *lt;
  2872. X    struct timeb ftz;
  2873. X    time_t sdate;
  2874. X
  2875. X    lptr = p;
  2876. X    if (Now == ((struct timeb *) NULL)) {
  2877. X        Now = &ftz;
  2878. X        ftime(&ftz);
  2879. X    }
  2880. X    lt = localtime(&Now->time);
  2881. X    year = lt->tm_year;
  2882. X    month = lt->tm_mon+1;
  2883. X    day = lt->tm_mday;
  2884. X    timeflag=zoneflag=dateflag=yearflag=0;
  2885. X    ourzone = Now->timezone;
  2886. X    daylightsvs = MAYBE;
  2887. X    hh = mm = ss = 0;
  2888. X    merid = 24;
  2889. X
  2890. X    err=yyparse();
  2891. X    if (err) {
  2892. X        Log2("StringToTimeb could not parse date ", p);
  2893. X        return(AFAIL);
  2894. X    }
  2895. X
  2896. X    mcheck(timeflag);               /* each of these should be at most 1 */
  2897. X    mcheck(zoneflag);
  2898. X    mcheck(dateflag);
  2899. X    mcheck(yearflag);
  2900. X
  2901. X    if (err) {
  2902. X        Log2("StringToTimeb ERROR parsed some type of field twice", p);
  2903. X        return(AFAIL);
  2904. X    }
  2905. X    if (!dateflag && !timeflag) {   
  2906. X        Log2("StringToTimeb ERROR did not find a major item in string ", p);
  2907. X        return(AFAIL);
  2908. X    }
  2909. X
  2910. X    sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylightsvs);
  2911. X    if (sdate < 0) {
  2912. X        Log2("StringToTimeb ERROR from dateconv", p);
  2913. X        return(AFAIL);
  2914. X    }
  2915. X
  2916. X/*  This is for times of files, so if there is no year we assume it could
  2917. X *  be up to a day ahead but otherwise in the past if no year specified.  
  2918. X */ 
  2919. X    if (!yearflag && (sdate > (Now->time + ADAY))) { 
  2920. X        Log2("StringToTimeb backing up a year since file dates must be in past", p);
  2921. X        year--;                                       
  2922. X        sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylightsvs);
  2923. X        if (sdate < 0) {
  2924. X            Log2("StringToTimeb ERROR from dateconv after backing up a year", p);
  2925. X            return(AFAIL);
  2926. X        }
  2927. X    }
  2928. X
  2929. X
  2930. X    Result->time=sdate;
  2931. X    Result->millitm=0;
  2932. X    Result->timezone=ourzone;
  2933. X    Result->dstflag=daylightsvs; 
  2934. X
  2935. X    Log("StringToTimeb returning AOK");
  2936. X    return(AOK);
  2937. X}
  2938. X
  2939. Xyyerror(s)
  2940. Xchar *s;
  2941. X{
  2942. X    Log2("yyerror", s);
  2943. X}
  2944. X
  2945. END_OF_FILE
  2946.   if test 13406 -ne `wc -c <'alexsrvr/src/stringtotime.y'`; then
  2947.     echo shar: \"'alexsrvr/src/stringtotime.y'\" unpacked with wrong size!
  2948.   fi
  2949.   # end of 'alexsrvr/src/stringtotime.y'
  2950. fi
  2951. echo shar: End of archive 10 \(of 13\).
  2952. cp /dev/null ark10isdone
  2953. MISSING=""
  2954. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  2955.     if test ! -f ark${I}isdone ; then
  2956.     MISSING="${MISSING} ${I}"
  2957.     fi
  2958. done
  2959. if test "${MISSING}" = "" ; then
  2960.     echo You have unpacked all 13 archives.
  2961.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2962. else
  2963.     echo You still must unpack the following archives:
  2964.     echo "        " ${MISSING}
  2965. fi
  2966. exit 0
  2967. exit 0 # Just in case...
  2968.