home *** CD-ROM | disk | FTP | other *** search
- From: vac@CS.CMU.EDU (Vincent.Cate)
- Newsgroups: comp.sources.misc
- Subject: v42i043: alex - NFS/FTP global filesystem, Part05/13
- Date: 30 Mar 1994 15:42:09 -0600
- Organization: Sterling Software
- Sender: root@sparky.sterling.com
- Approved: kent@sparky.sterling.com
- Message-ID: <2ncrnh$gp6@sparky.sterling.com>
- X-Md4-Signature: 7ad6967f7a352d3a9110ae1d187f0d50
-
- Submitted-by: vac@CS.CMU.EDU (Vincent.Cate)
- Posting-number: Volume 42, Issue 43
- Archive-name: alex/part05
- Environment: Most Unix machines - with 100 MB to 10 GB of free disk
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: alexsrvr/src/Makefile alexsrvr/src/dirtoinfo.c
- # Wrapped by kent@sparky on Tue Mar 29 21:56:19 1994
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 5 (of 13)."'
- if test -f 'alexsrvr/src/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'alexsrvr/src/Makefile'\"
- else
- echo shar: Extracting \"'alexsrvr/src/Makefile'\" \(7473 characters\)
- sed "s/^X//" >'alexsrvr/src/Makefile' <<'END_OF_FILE'
- X
- X# You probably only want to edit config.h to install Alex.
- X
- X# for prof both CF and LDF need "-p"
- X
- X# CFLAGS= -g -O -p -pg
- XCFLAGS= -O
- X
- X# -g -pg
- XLDFLAGS=
- X
- XRPCGEN= rpcgen
- XCC= cc
- X
- X#------------------------------End of configuration section.
- X
- X
- XNFSOBJS= nfs_prot_svc.o nfs_prot_xdr.o unfsd.o init.o fh.o
- X
- XMOUNTOBJS= mount_svc.o mount_xdr.o unfsmntd.o fh.o alexlib.o phonehome.o \
- X readinfo.o cmucs.o compat.o
- X
- XALEXOBJS= alex.o dirtoinfo.o ftpparent.o ftpchild.o alexlib.o remtimezone.o \
- X stringtotime.o readinfo.o cmucs.o compat.o phonehome.o
- X
- X
- Xall: local.h basic alexfsck evictor printinfo
- X
- Xlocal.h:
- X echo '/* Put local config.h options in here. Use #undef if needed. */' > local.h
- X
- X# Basic is what is needed to get started.
- Xbasic: alexd alexmountd
- X
- Xalexd: ${NFSOBJS} ${ALEXOBJS} defs
- X ${CC} $(LDFLAGS) -o alexd ${NFSOBJS} ${ALEXOBJS} -lm `/bin/csh -f libdefs`
- X
- Xalexmountd: ${MOUNTOBJS}
- X ${CC} $(LDFLAGS) -o alexmountd ${MOUNTOBJS} `/bin/csh -f libdefs`
- X
- X
- X# Non basic
- X#
- Xevictor: evictor.o alexlib.o cmucs.o phonehome.o
- X ${CC} ${LDFLAGS} -o evictor evictor.o alexlib.o cmucs.o compat.o phonehome.o
- X
- Xalexfsck: readinfo.o alexlib.o alexfsck.o cmucs.o compat.o phonehome.o
- X ${CC} -o alexfsck alexfsck.o alexlib.o readinfo.o cmucs.o compat.o phonehome.o
- X
- Xprintinfo: printinfo.c
- X ${CC} ${CFLAGS} -o printinfo printinfo.c
- X
- Xdefs: defs.o alexlib.o cmucs.o compat.o phonehome.o
- X ${CC} ${LDFLAGS} -o defs defs.o alexlib.o cmucs.o compat.o phonehome.o
- X
- X
- X# ----------------- major items above minor things below --------------------
- X
- X# if you do not have yacc just say "make noyacc" and then do "make"
- Xnoyacc:
- X touch stringtotime.c
- X
- Xstringtotime.c: stringtotime.y
- X /bin/rm stringtotime.c
- X yacc -v stringtotime.y
- X mv y.tab.c stringtotime.c
- X
- Xstringtotime.o: stringtotime.c
- X ${CC} ${CFLAGS} -c -DYYDEBUG stringtotime.c
- X
- Xstringtotime: stringtotime.o stringtotimemain.o alexlib.o phonehome.o
- X cc -o stringtotime stringtotime.o stringtotimemain.o alexlib.o phonehome.o
- X
- Xremtimezone: stringtotime.o remtimezonemain.o alexlib.o phonehome.o remtimezone.o
- X cc -o remtimezone stringtotime.o remtimezonemain.o alexlib.o phonehome.o remtimezone.o
- X
- X
- X# Installation stuff -----------------------------------------------------
- X
- Xinstall: all installbasic defs
- X /bin/csh -f install nonbasic
- X
- Xinstallbasic: basic defs
- X /bin/csh -f install basic
- X
- X# NFS Stuff ------------------------------------------------------------------
- X
- Xnorpcgen:
- X touch nfs_prot.h
- X touch nfs_prot_svc.c
- X touch nfs_prot_xdr.c
- X touch mount.h
- X touch mount_svc.c
- X touch mount_xdr.c
- X
- Xnfs_prot.h: nfs_prot.x config.nfs.h
- X ${RPCGEN} -h -o $@ nfs_prot.x
- X
- Xnfs_prot_svc.c: nfs_prot.x config.nfs.h
- X ${RPCGEN} -s udp nfs_prot.x | \
- X sed \
- X -e 's/main()/main(argc,argv,envp) int argc; char **argv, **envp; /' \
- X -e 's/pmap_unset(/init_Log(); pmap_unset(/' \
- X -e 's/RPC_ANYSOCK/makesock(NFS_PORT, NFS_MAXDATA)/' \
- X -e 's/svc_run();/unfsd_init(argc,argv,envp); svc_run();/' \
- X > $@
- X
- Xnfs_prot_xdr.c: nfs_prot.x config.nfs.h
- X ${RPCGEN} -c -o $@ nfs_prot.x
- X
- X
- X
- Xmount.h: mount.x config.nfs.h
- X ${RPCGEN} -h -o $@ mount.x
- X
- Xmount_svc.c: mount.x config.nfs.h
- X ${RPCGEN} -s udp mount.x | \
- X sed \
- X -e 's/main()/main(argc,argv) int argc; char **argv;/' \
- X -e 's/pmap_unset(/init_Log(); pmap_unset(/' \
- X -e 's/svc_run();/unfsmntd_init(argc,argv); svc_run();/' \
- X > $@
- X
- Xmount_xdr.c: mount.x config.nfs.h
- X ${RPCGEN} -c -o $@ mount.x
- X
- X# misc ---------------------------------------------------------------------
- X
- Xclean:
- X rm -rf *.o nfs_prot_svc.c nfs_prot_xdr.c nfs_prot.h y.tab.h \
- X stringtotime.c mount_svc.c mount_xdr.c mount.h alexd alexmountd \
- X printinfo defs alexfsck evictor y.output
- X
- X
- X# could make and install "UidStr" but not needed
- X
- XUidStr:
- X cat /etc/passwd /etc/passwds | awk -f UidStrA.awk | sort -nu | awk -f UidStrB.awk > UidStr
- X
- X
- X# To get and make a new version of the software ------------------------------
- X#
- X# Different people like "getalex", "patchalex", and "updatealex" so
- X# we actually have all of them though they do similar things. The
- X# "srclinks" gives you symlinks to the latest source.
- X#
- X# Except for "alpha" and "new" you need to run "make install" and
- X# then either "grepnkill alexd" to restart or "start.alex" for coldstart.
- X
- X# Recommended - gets latest stuff, compiles, install, and starts things up
- Xalpha:
- X /bin/csh -f getalex alex.alpha.tar.Z
- X
- X# Latest "stable" code.
- Xnew:
- X /bin/csh -f getalex alex.tar.Z
- X
- X# Good for small changes. If whole new files have been added it will miss them.
- X# But as new files are not added very often this usually works.
- Xpatch:
- X /bin/csh -f patchalex
- X
- X# Copies all release files that have changed since last time.
- Xupdate:
- X /bin/csh -f updatealex
- X
- X# Just make symlinks to all of the source files.
- Xsrclinks:
- X mv -f /usr/alexsrvr/src /usr/alexsrvr/src.old
- X sh cp-rs /alex/edu/cmu/cs/sp/alex/src/alexsrvr/src /usr/alexsrvr/src
- X echo "You can go back to real files by doing a make new"
- X echo " "
- X echo "Your current directory has changed"
- X pwd
- X
- X# Only first timers should do this
- X# If there is a running server it will die and this will not finish
- Xalllinks:
- X echo "This should only be run to get Alex the first time."
- X echo "This should only be run as alexsrvr."
- X echo "If either of these is not true, you have 15 seconds to stop this."
- X sleep 15
- X (if [ ! -d /usr/alexsrvr/.old ] ; then mkdir /usr/alexsrvr/.old; fi ;\
- X touch /usr/alexsrvr/tmp ;\
- X mv -f /usr/alexsrvr/* /usr/alexsrvr/.old ;\
- X sh cp-rs /alex/edu/cmu/cs/sp/alex/src/alexsrvr /usr/alexsrvr ;\
- X /bin/rm -f /usr/alexsrvr/bin/* ;\
- X cd /usr/alexsrvr/src ;\
- X make install ;\
- X echo "Run /usr/alexsrvr/bin/start.alex as root" )
- X
- X
- X# Get and compile archie
- Xarchie:
- X /bin/csh -f /alex/edu/cmu/cs/sp/alex/user/bin/getpackage archie
- X
- X# These are sort of development things ----------------------------------------
- X
- XLINTFLAGS = -abchx -DDEBUG
- Xalexlint:
- X lint -u alexlib.c dirtoinfo.c alex.c ftpparent.c ftpchild.c remtimezone.c stringtotime.c \
- X unfsd.c fh.c readinfo.c phonehome.c
- X
- Xmountlint:
- X lint -u alexlib.c unfsmntd.c fh.c readinfo.c
- X
- Xrcs:
- X rcsci -q -l unfsd.c init.c fh.c alex.c ftpparent.c ftpchild.c dirtoinfo.c \
- X alexlib.c phonehome.c remtimezone.c stringtotime.y readinfo.c \
- X remtimezone.c mount.x nfs_prot.x alex.h alexincs.h \
- X config.h config.nfs.h Makefile makerelease printinfo.c \
- X alexfsck.c evictor.c getalex defs.c install scripts/* \
- X updatealex patchalex
- X
- Xbackup:
- X cp *.x backups
- X cp *.c backups
- X cp *.h backups
- X cp *.y backups
- X cp Makefile backups
- X cp getalex updatealex patchalex backups
- X cp makerelease backups
- X
- Xrelease:
- X makerelease
- X
- Xreleaseget:
- X cp getalex /../alex/usr/anon/src
- X
- X
- X# include dependencies -------------------------------------------------------
- X
- Xnfs_prot_svc.o nfs_prot_xdr.o unfsd.o fh.o init.o: nfs_prot.h config.nfs.h
- X
- Xmount_svc.o mount_xdr.o unfsmntd.o: mount.h config.nfs.h
- X
- Xfh.o unfsd.o init.o: unfsd.h fh.h config.nfs.h
- X
- Xftpparent.o ftpchild.o: alexftp.h
- X
- Xinit.o fh.o unfsd.o dirtoinfo.o ftpparent.o ftpchild.o alexlib.o \
- Xremtimezone.o alexmain.o remtimezonemain.o stringtotimemain.o \
- Xstringtotime.o stringtotime.c alex.o readinfo.o unfsmntd.o evictor.o \
- Xphonehome.o defs.o alexfsck.o: alex.h alexincs.h config.h local.h
- X
- X
- X
- X
- END_OF_FILE
- if test 7473 -ne `wc -c <'alexsrvr/src/Makefile'`; then
- echo shar: \"'alexsrvr/src/Makefile'\" unpacked with wrong size!
- fi
- # end of 'alexsrvr/src/Makefile'
- fi
- if test -f 'alexsrvr/src/dirtoinfo.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'alexsrvr/src/dirtoinfo.c'\"
- else
- echo shar: Extracting \"'alexsrvr/src/dirtoinfo.c'\" \(77292 characters\)
- sed "s/^X//" >'alexsrvr/src/dirtoinfo.c' <<'END_OF_FILE'
- X
- X/* Copyright (c) 1992 Vincent Cate
- X * All Rights Reserved.
- X *
- X * Permission to use and modify this software and its documentation
- X * is hereby granted, provided that both the copyright notice and this
- X * permission notice appear in all copies of the software, derivative works
- X * or modified versions, and any portions thereof, and that both notices
- X * appear in supporting documentation. This software or any derivate works
- X * may not be sold or distributed without prior written approval from
- X * Vincent Cate.
- X *
- X * THE SOFTWARE IS PROVIDED "AS IS" AND VINCENT CATE DISCLAIMS ALL
- X * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- X * VINCENT CATE BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- X * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
- X * OR PERFORMANCE OF THIS SOFTWARE.
- X *
- X * Users of this software agree to return to Vincent Cate any improvements
- X * or extensions that they make and grant Vincent Cate the rights to
- X * redistribute these changes.
- X *
- X */
- X
- X/* Todo:
- X *
- X * Does not handle places with filenames with spaces. It would not
- X * be hard to do but then places that put extra stuff on the line would
- X * mess up (but that seems more fair really).
- X
- X *
- X *
- X
- X
- X */
- X
- X
- X/* Exports:
- X * DirToInfo() - reads in a .alex.dir file and writes out a .alex.info
- X */
- X
- X
- X#ifdef EXECUTABLE
- X/*
- XFor security reasons I did not want to have executables show up as executable.
- XHowever, Durand wanted it and I said if he hacked it up I would include
- Xthe patchs. Here are the comments from email from durand alain denis
- X<Alain.Durand@inria.fr> where he sent in EXECUTABLE hack.
- X
- XThe right way to do this is to add another field to .alex.info. Too many
- Xthings to do.
- X
- X>Basically, the idea is to catch the "x" bit when converting from
- X>.alex.dir to .alex.info (in dirtoinfo.c, in XXXTokensToParsedDir),
- X>faking a link with a special "-1" linkname to keep track of the information
- X>(in alexlib.c OneLineOut) and then, when reading the .alex.info file,
- X>(in readinfo.c ParseOneLine) tracking down this fake link,
- X> marking the file executable (Current->Executable) and then giving the
- X>file the correct rights (ATypeToStatMode) according to its executable flag.
- X>
- X>At first, I wanted to add an field in the .alex.info files to store the
- X>executable state of the files, but then I couldn't figure out a way to
- X>restart alex... I tried to modify the HostList, RootAlexInfo,... accordingly
- X>but it didn't work. So I use this trick to fake a link "-1". This have also
- X>the advantage to stay compatible with the original version...
- X>
- X
- XThis is ugly, for sure. XXXX
- X*/
- X#endif
- X
- X#include "alexincs.h"
- X#include "alex.h"
- X
- X#ifdef ONLYSHOWREADABLE
- X#define ONLYSHOWREADABLEINT 1
- X#else
- X#define ONLYSHOWREADABLEINT 0
- X#endif
- X
- X/* returns 1 if not a normal file or directory
- X */
- Xint SpecialFile(Current)
- Xstruct ParsedDir *Current;
- X{
- X int Result;
- X
- X Result=(streql(Current->Name, ".") ||
- X streql(Current->Name, "..") ||
- X streql(Current->Name, ALEXERROR) ||
- X streql(Current->Name, ALEXUPDATE) ||
- X streql(Current->Name, ALEXDIR) ||
- X streql(Current->Name, ALEXINFO));
- X
- X return(Result);
- X}
- X
- Xint SpecialFileOrError(Current)
- Xstruct ParsedDir *Current;
- X{
- X int Result;
- X
- X Result=(SpecialFile(Current) || (Current->Type == AERRORMESSAGE));
- X
- X return(Result);
- X}
- X
- X
- Xint StringToTimeInt(s, Now)
- Xchar *s;
- Xstruct timeb *Now;
- X{
- X struct timeb Then;
- X int status, Result;
- X
- X Log2("StringToTimeInt input is ", s);
- X
- X status=StringToTimeb(s, Now, &Then);
- X
- X if (status != AOK) {
- X LogN("StringToTimeInt got back bad status and time of ", (int) Then.time);
- X Result=Now->time;
- X } else {
- X Result=Then.time;
- X if (Result > Now->time+60) {
- X LogN("StringToTimeInt error future modification time after parsing ", Result);
- X Log2("StringToTimeInt error future ", s);
- X LogN("Zone was ", (int) Then.timezone);
- X if (Result <= (Now->time + (Then.timezone*60))) { /* Could it be Greenwich? */
- X Log("StringToTimeInt XXX fudging timezone to Greenwich ");
- X Result -= Then.timezone*60;
- X } else {
- X Log("StringToTimeInt setting time to Now");
- X Result=Now->time - (Now->time % 60); /* round back an hour */
- X /* otherwise caching fails badly as file */
- X /* looks like it is changing all the time */
- X }
- X }
- X }
- X
- X LogN("StringToTimeInt returning ", Result);
- X return(Result);
- X}
- X
- X
- X
- X
- Xchar Month[12][5] ={"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
- X
- Xint IsAMonth(token)
- Xchar *token;
- X{
- X int i;
- X
- X for (i=0; i<12; i++) {
- X if (strcasecmp(token, Month[i]) == 0) {
- X return(1);
- X }
- X }
- X
- X /* Log2("Was expecting a month but got ", token); */
- X return(0);
- X}
- X
- X
- X
- X
- X
- Xint IsThreeSepNums(token, sep)
- Xchar *token;
- Xchar sep;
- X{
- X int n1, n2, n3, Result;
- X
- X n1=n2=n3=0;
- X Result=1;
- X while((*token != 0) && (isdigit(*token))) {
- X n1=1;
- X token++;
- X }
- X
- X if (*token++ != sep) Result=0;
- X
- X while((*token != 0) && (isdigit(*token))) {
- X n2=1;
- X token++;
- X }
- X
- X if (*token++ != sep) Result=0;
- X
- X while((*token != 0) && (isdigit(*token))) {
- X n3=1;
- X token++;
- X }
- X
- X if (n1 && n2 && n3 && Result) {
- X return(1);
- X } else {
- X return(0);
- X }
- X}
- X
- X/* returns true if token is of the form 7/11/90 */
- Xint IsSlashDate(token)
- Xchar *token;
- X{
- X return(IsThreeSepNums(token, '/'));
- X}
- X
- X/* returns true if token is of the form 11:01:15 */
- Xint IsTimeWithSecs(token)
- Xchar *token;
- X{
- X return(IsThreeSepNums(token, ':'));
- X}
- X
- X/*
- XABCODE FIL V 56 2669 16 7/11/90 11:01:15 PDH515
- XCGRID GIF V 8192 3 5 7/30/91 7:50:27 PDH515
- X
- XFUSION 89-00012 V 80 299 3 5/03/89 14:27:15 FUSION
- XFUSION 89-00013 V 80 2346 28 5/03/89 14:30:35 FUSION
- X
- X/alex/edu/columbia/cc/cuvmb
- X$$READ ME V 73 70 1 12/04/91 15:58:46 TCM301
- X$CUANON DOC V 72 33 1 2/15/89 17:56:46 TCM301
- X
- X */
- X
- Xint IsIBM(Tokens, NumTokens)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- X{
- X return((NumTokens >= 7) && IsSlashDate(Tokens[6]) && IsTimeWithSecs(Tokens[7]));
- X}
- X
- X
- X/*
- X/alex/uk/ac/hensa/micros
- XFiles matching pattern '*' in directory '.' :
- X
- X00contents 719 bytes 4 Feb 1993 16:15
- Xjob.txt 2005 bytes 4 Feb 1993 16:11
- Xnewsfile 1240 bytes 4 Feb 1993 16:15
- X
- X
- XDirectories matching pattern '*':
- X
- Xchest <DIRECTORY> 12 Feb 1993 14:25
- Xcti <DIRECTORY> 3 Nov 1992 12:08
- Xdocs <DIRECTORY> 25 Nov 1992 14:45
- Xtools <DIRECTORY> 3 Nov 1992 23:50
- Xx <DIRECTORY> 3 Nov 1992 23:51
- X*/
- X
- Xint IsHENSA(Tokens, NumTokens)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- X{
- X if (NumTokens<1) return 0;
- X if (streql(Tokens[0],"Files")) return 1;
- X if (streql(Tokens[0],"Directories")) return 1;
- X if (NumTokens>2 && streql(Tokens[1],"<DIRECTORY>")) return 1;
- X if (NumTokens>3 && streql(Tokens[2],"bytes")) return 1;
- X return 0;
- X}
- X
- X/*
- X * Novel. From /alex/edu/usu/netlab2:
- X- [R----F--] jrd 1646 May 07 21:43 index
- Xd [R----F--] jrd 512 Aug 24 20:06 netwire
- Xd [R----F--] jrd 512 Aug 21 18:44 pktdrvr
- X
- X
- X or /alex/com/wordperfect/ftp
- X
- Xd [R----F--] scotteh 512 Aug 24 20:05 msdos
- X- [R----F--] scotteh 74 Jun 29 17:12 read.me
- X0 1 2 3 4 5 6 7
- X*/
- X
- Xint IsNOVEL(Tokens, NumTokens)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- X{
- X if (NumTokens != 8) return(0);
- X if ((Tokens[0][0] != 'd') && (Tokens[0][0] != '-') || Tokens[0][1] != 0) return(0);
- X if (Tokens[1][0] != '[') return(0);
- X Log("IsNovel");
- X return(1);
- X}
- X
- Xint NOVELTokensToParsedDir(Tokens, NumTokens, Current, Now)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xstruct ParsedDir *Current;
- Xstruct timeb *Now;
- X{
- X int Result;
- X char TimeForParsing[200];
- X
- X LogN("NOVELTokensToParsedDir", NumTokens);
- X
- X (void) strcpy(Current->Name, Tokens[7]); /* filename */
- X
- X if (Tokens[0][0] == 'd') {
- X Current->Type=ADIR;
- X } else {
- X Current->Type=AFILE;
- X#ifdef EXECUTABLE
- X Current->Executable = 0; /* Not Yet Implemented */
- X#endif
- X }
- X
- X Current->Size=atoi(Tokens[3]);
- X
- X (void) strcpy(TimeForParsing, Tokens[4]);
- X (void) strcat(TimeForParsing, " ");
- X (void) strcat(TimeForParsing, Tokens[5]);
- X (void) strcat(TimeForParsing, " ");
- X (void) strcat(TimeForParsing, Tokens[6]);
- X Current->Date = (unsigned int) StringToTimeInt(TimeForParsing, Now);
- X LogN("NOVELTokensToParsedDir Date ", Current->Date);
- X
- X if (strlen(Current->Name) > 1) {
- X Result=AOK;
- X } else {
- X Result=AFAIL;
- X }
- X
- X return(Result);
- X}
- X
- X/*
- XPS:<ANONYMOUS>
- X 1752(07) 3-Nov-90 14:49:55 00-README.TXT.2
- X 1298(07) 30-Jun-90 20:18:15 ACCOUNTS.INFO.5
- X 10823(07) 24-Oct-87 17:05:57 BINTNXVMS.C.1
- X */
- X
- Xint IsTOPS20(Tokens, NumTokens)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- X{
- X return((NumTokens >=3) && HasChar(Tokens[0], '(') && IsTimeWithSecs(Tokens[2])); /* had '\(' XXX */
- X}
- X
- X
- X/*
- X
- X/alex/il/ac/tau/vm
- XFUSION 89-00008 V 80 2281 26 5/03/89 14:25:54 FUSION
- XFUSION 89-00009 V 80 2061 24 5/03/89 14:26:18 FUSION
- XFUSION 89-00010 V 80 2025 21 5/03/89 14:26:41 FUSION
- XFUSION 89-00011 V 80 2264 25 5/03/89 14:27:08 FUSION
- XFUSION 89-00012 V 80 299 3 5/03/89 14:27:15 FUSION
- XFUSION 89-00013 V 80 2346 28 5/03/89 14:30:35 FUSION
- X
- X/alex/edu/columbia/cc/cuvmb
- X$$READ ME V 73 70 1 12/04/91 15:58:46 TCM301
- X$CUANON DOC V 72 33 1 2/15/89 17:56:46 TCM301
- X$CULOCAL DOC V 72 36 1 2/06/89 16:58:02 TCM301
- X$CUMXHOS DOC V 73 47 1 9/05/89 13:17:52 TCM301
- X
- X*/
- X
- Xint IBMTokensToParsedDir(Tokens, NumTokens, Current, Now)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xstruct ParsedDir *Current;
- Xstruct timeb *Now;
- X{
- X int Result;
- X char TimeForParsing[200];
- X
- X LogN("IBMTokensToParsedDir", NumTokens);
- X
- X (void) strcpy(Current->Name, Tokens[0]); /* basename */
- X
- X if (streql(Tokens[1], "DISK")) { /* extension */
- X Current->Type=ADIR;
- X } else {
- X Current->Type=AFILE;
- X#ifdef EXECUTABLE
- X Current->Executable = 0; /* Not Yet Implemented */
- X#endif
- X (void) strcat(Current->Name, ".");
- X (void) strcat(Current->Name, Tokens[1]);
- X }
- X
- X ToLower(Current->Name);
- X
- X Current->Size=atoi(Tokens[3]) * atoi(Tokens[4]); /* just a guess */
- X
- X
- X (void) strcpy(TimeForParsing, Tokens[6]);
- X (void) strcat(TimeForParsing, " ");
- X (void) strcat(TimeForParsing, Tokens[7]);
- X Current->Date = (unsigned int) StringToTimeInt(TimeForParsing, Now);
- X
- X
- X if (strlen(Current->Name) > 1) {
- X Result=AOK;
- X } else {
- X Result=AFAIL;
- X }
- X
- X return(Result);
- X}
- X
- X
- X
- Xint UNKNOWNTokensToParsedDir(Tokens, NumTokens, Current)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xstruct ParsedDir *Current;
- X{
- X int wasadir;
- X
- X LogN("UNKNOWNTokensToParsedDir", NumTokens);
- X
- X if (NumTokens < 1) return(AFAIL);
- X
- X if ((strcasecmp(Tokens[0], "Total") == 0) && (NumTokens <= 2)) {
- X Log("UNKNOWNTokensToParsedDir skipping Total ");
- X if (NumTokens == 2) {
- X Log2("UNKNOWNTokensToParsedDir full line was Total ", Tokens[1]);
- X }
- X return(AFAIL);
- X }
- X
- X if ((NumTokens == 2) && (strcasecmp(Tokens[1], "unreadable") == 0)) {
- X Log("UNKNOWNTokensToParsedDir combining unreadable ");
- X (void) strcpy(Current->Name, "ALEX Message: ");
- X (void) strcat(Current->Name, Tokens[0]);
- X (void) strcat(Current->Name, " ");
- X (void) strcat(Current->Name, Tokens[1]);
- X Current->Type=AFILE;
- X Current->Size=0;
- X return(AOK); /* maybe we play with protections someday XXX */
- X }
- X
- X (void) strcpy(Current->Name, Tokens[0]);
- X wasadir=RemoveTrailingSlash(Current->Name);
- X
- X if (wasadir) {
- X Current->Type=ADIR;
- X } else {
- X Current->Type=AFILE;
- X#ifdef EXECUTABLE
- X Current->Executable = 0; /* Not Yet Implemented */
- X#endif
- X }
- X
- X Current->Size=1; /* just one byte to get things started */
- X
- X if (Current->Name[0] != '/') {
- X return(AOK);
- X } else {
- X return(AFAIL);
- X }
- X}
- X
- X/*
- XDECVMS
- XANNOUNCEMENTS.TXT;1 11 2-MAY-1991 15:31 [ANONYMOUS] (RWED,RWED,RE,)
- X00-DIRECTORY.FULL;2 4842 25-NOV-1992 19:21 AUI$TEX (RE,RWED,RE,RE)
- X ^-- 512 byte blocks
- XDECVMS2
- X.NEWSRC;1 10-OCT-1991 11:20:33 23606/47 (RWED,RWED,RE,)
- X ^-- bytes
- X
- X
- X */
- Xint DECVMSTokensToParsedDir(Tokens, NumTokens, Current, Now)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xstruct ParsedDir *Current;
- Xstruct timeb *Now;
- X{
- X char TimeForParsing[MAXTOKENLEN];
- X char *tmp;
- X int loc, j, NumBlocks;
- X
- X LogN("DECVMSTokensToParsedDir", NumTokens);
- X
- X (void) strcpy(Current->Name, Tokens[0]);
- X
- X for (tmp=Current->Name; *tmp != 0; tmp++) {
- X if (isupper(*tmp)) {
- X *tmp=tolower(*tmp);
- X }
- X if (*tmp==';') {
- X *tmp=0; /* we don't need no stinking semicolons */
- X }
- X }
- X
- X loc=WhereString(Current->Name, "]");
- X if (loc>=0) { /* if has directory path get rid of it */
- X for (j=0; j<(loc+1); j++) {
- X Current->Name[j]=Current->Name[j+loc+1];
- X }
- X }
- X
- X loc=WhereString(Current->Name, ".dir"); /* use as type info but get rid of it */
- X if (loc>=0) {
- X Current->Name[loc]=0; /* chop him */
- X Current->Type=ADIR;
- X } else {
- X Current->Type=AFILE;
- X#ifdef EXECUTABLE
- X Current->Executable = 0; /* Not Yet Implemented */
- X#endif
- X
- X }
- X
- X if (HasChar(Tokens[3], '/')) { /* is this DECVMS2 */
- X (void) strcpy(TimeForParsing, Tokens[1]);
- X (void) strcat(TimeForParsing, " ");
- X (void) strcat(TimeForParsing, Tokens[2]);
- X Current->Date = (unsigned int) StringToTimeInt(TimeForParsing, Now);
- X Current->Size= atoi(Tokens[3]); /* sizes almost right - modulo cr/lf -> lf */
- X } else {
- X (void) strcpy(TimeForParsing, Tokens[2]);
- X (void) strcat(TimeForParsing, " ");
- X (void) strcat(TimeForParsing, Tokens[3]);
- X Current->Date = (unsigned int) StringToTimeInt(TimeForParsing, Now);
- X NumBlocks=atoi(Tokens[1]); /* use blocks to estimate size */
- X if (NumBlocks > 1) {
- X Current->Size=512*(NumBlocks-1); /* much better to be low than high with NFS */
- X } else {
- X if (Current->Type==ADIR) {
- X Current->Size=512;
- X } else {
- X Current->Size=1; /* much better to be low than high with NFS */
- X }
- X }
- X }
- X
- X return(AOK);
- X}
- X
- X
- X/* Input: "foo.bar"
- X * Output: "foo"
- X * Destructive
- X */
- XCutAtLastDot(s)
- Xchar *s;
- X{
- X char *LastDot;
- X
- X LastDot = rindex(s, '.');
- X
- X if (LastDot != NULL) {
- X *LastDot = 0;
- X }
- X}
- X
- X
- X/* Input 00README.TXT.1,7
- X * or MAC.DIRECTORY.1
- X *
- X * Output: 00readme.txt return(0)
- X * or mac return(1)
- X */
- Xint DECTENTokensToParsedDir(Tokens, NumTokens, Current)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xstruct ParsedDir *Current;
- X{
- X int i;
- X
- X LogN("DECTENTokensToParsedDir", NumTokens);
- X (void) strcpy(Current->Name, Tokens[0]);
- X
- X ToLower(Current->Name);
- X
- X i=WhereString(Current->Name, ".directory");
- X if (i>=0) {
- X Current->Name[i]=0; /* chop him */
- X Current->Type=ADIR;
- X } else {
- X CutAtLastDot(Current->Name);
- X Current->Type=AFILE;
- X#ifdef EXECUTABLE
- X Current->Executable = 0; /* Not Yet Implemented */
- X#endif
- X }
- X
- X return(AOK);
- X}
- X
- Xint HENSATokensToParsedDir(Tokens, NumTokens, Current, Now)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xstruct ParsedDir *Current;
- Xstruct timeb *Now;
- X{
- X char TimeForParsing[MAXTOKENLEN];
- X int i=0;
- X
- X LogN("HENSATokensToParsedDir", NumTokens);
- X
- X if (NumTokens<6) return (AFAIL);
- X (void) strcpy(Current->Name, Tokens[0]);
- X if (streql(Tokens[1],"<DIRECTORY>")) {
- X Current->Type=ADIR;
- X Current->Size=512;
- X i=2;
- X } else {
- X if (streql(Tokens[2],"bytes")) {
- X Current->Type=AFILE;
- X#ifdef EXECUTABLE
- X Current->Executable = 0; /* Not Yet Implemented */
- X#endif
- X Current->Size=atoi(Tokens[1]);
- X i=3;
- X }
- X }
- X if (i) {
- X sprintf(TimeForParsing,"%s-%s-%s %s",Tokens[i],Tokens[i+1],Tokens[i+2],Tokens[i+3]);
- X Current->Date = (unsigned int) StringToTimeInt(TimeForParsing, Now);
- X return(AOK);
- X }
- X return(AFAIL);
- X}
- X
- X
- X/* Input: 00-README.TXT.2
- X *
- X * Output: 00-readme.txt
- X */
- X
- Xint TOPS20TokensToParsedDir(Tokens, NumTokens, Current)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xstruct ParsedDir *Current;
- X{
- X LogN("TOPS20TokensToParsedDir", NumTokens);
- X
- X (void) strcpy(Current->Name, Tokens[NumTokens+1]);
- X ToLower(Current->Name);
- X CutAtLastDot(Current->Name);
- X Current->Type=AFILE;
- X#ifdef EXECUTABLE
- X Current->Executable = 0; /* Not Yet Implemented */
- X#endif
- X
- X return(AOK);
- X}
- X
- X/* Returns true if s is of the form "drwxr-xr-x"
- X *
- X * Some day I should profile alex and see how slow and silly this is XXXX
- X * d if the entry is a directory;
- X * b if the entry is a block-type special file;
- X * c if the entry is a character-type special file;
- X * l if the entry is a symbolic link;
- X * s if the entry is a socket, or
- X * - if the entry is a plain file.
- X *
- X * r if the file is readable;
- X * w if the file is writable;
- X * x if the file is executable;
- X * - if the indicated permission is not granted.
- X */
- X
- X/* for each character we have 1 integer.
- X * Each integer has more than 10 bits, but we use 10 as 10 booleans
- X * indicating if that character is ok in that position.
- X */
- X
- Xunsigned int BitArrayStd[256];
- Xunsigned int BitArrayReadFile[256];
- Xunsigned int BitArrayReadDir[256];
- X
- X/* AIX needs the DFL if NFS mounted */
- Xchar BitInputStd[10][10]= {"DFLdbcls-", "r-", "w-", "xsS-", "r-", "w-", "xsS-", "r-", "w-", "xstS-"};
- Xchar BitInputReadFile[10][10]={"DFLdbcls-", "r-", "w-", "xsS-", "r", "w-", "xsS-", "r", "w-", "xstS-"};
- Xchar BitInputReadDir[10][10]= {"DFLdbcls-", "r-", "w-", "xsS-", "r", "w-", "xsS", "r", "w-", "xstS"};
- X
- X
- XInitBitArray(Input, BitArray)
- Xchar Input[10][10];
- Xunsigned int BitArray[256];
- X{
- X int i, j, bit, c;
- X
- X for (i=0; i<256; i++) {
- X BitArray[i]=0;
- X }
- X
- X bit = 1;
- X for (i=0; i<10; i++) {
- X for (j=0; Input[i][j] != 0; j++) {
- X c=Input[i][j];
- X BitArray[c] |= bit;
- X }
- X bit = bit << 1;
- X }
- X}
- X
- X/* This should become a fast table lookup XXXX */
- Xint IsUnixProtections(s, OnlyIfReadable)
- Xchar *s;
- Xint OnlyIfReadable;
- X{
- X int IsDir, i;
- X static int NeedInit=1;
- X unsigned int *BitArrayPtr, bit;
- X
- X if (NeedInit) {
- X InitBitArray(BitInputStd, BitArrayStd);
- X InitBitArray(BitInputReadFile, BitArrayReadFile);
- X InitBitArray(BitInputReadDir, BitArrayReadDir);
- X NeedInit=0;
- X }
- X
- X /* if (strlen(s) != 10) return(0); No because it messes up when 2 fields merge as in:
- X * drwxrwsr-x130 root 274 3072 Sep 12 08:37 pub */
- X
- X if (strlen(s) < 10) return(0);
- X
- X IsDir = (*s == 'd');
- X
- X if (OnlyIfReadable) {
- X if (IsDir) {
- X BitArrayPtr=BitArrayReadDir;
- X } else {
- X BitArrayPtr=BitArrayReadFile;
- X }
- X } else {
- X BitArrayPtr=BitArrayStd;
- X }
- X
- X bit = 1;
- X for (i=0; i<10; i++) {
- X if ((BitArrayPtr[*s++] & bit) == 0) return(0);
- X bit = bit << 1;
- X }
- X
- X return(1); /* really looks like Unix */
- X}
- X
- X
- XIsUNIX(Tokens, NumTokens, OnlyIfReadable)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xint OnlyIfReadable;
- X{
- X return((NumTokens > 2) && (IsUnixProtections(Tokens[0], OnlyIfReadable)));
- X}
- X
- XIsHPUX(Tokens, NumTokens, OnlyIfReadable)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xint OnlyIfReadable;
- X{
- X return((NumTokens > 2) && (IsUnixProtections(Tokens[1], OnlyIfReadable)));
- X}
- X
- X
- X
- Xint IsTime(s)
- Xchar *s;
- X{
- X if (isdigit(s[0]) && isdigit(s[1]) && (s[2] == ':') && isdigit(s[3]) && isdigit(s[4])) {
- X return(1);
- X } else {
- X return(0);
- X }
- X}
- X
- X
- X/*
- XCLDATA:[ANONYMOUS_FTP.FILES]
- X
- X00README.TXT;7 6 9-APR-1991 18:14 [ANONYMOUS] (RWED,RE,RE,RE)
- XALEX.DIR;1 8 18-OCT-1990 07:20 [ANONYMOUS] (RWED,RE,RE,RE)
- XANNOUNCEMENTS.TXT;1 11 2-MAY-1991 15:31 [ANONYMOUS] (RWED,RWED,RE,)
- X
- X*/
- X
- XIsDECVMS(Tokens, NumTokens)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- X{
- X return((NumTokens >=4) && HasChar(Tokens[0], ';') && IsTime(Tokens[3]));
- X}
- X
- X/*
- X.NEWSRC;1 10-OCT-1991 11:20:33 23606/47 (RWED,RWED,RE,)
- XFTPD.LOG;2367 22-OCT-1991 21:08:36 0/0 (RWED,RWED,RE,)
- XM51X.GIF;2 29-NOV-1990 12:15:29 118327/232 (RWED,RWED,RE,RE)
- XM57.GIF;1 31-MAR-1991 11:38:21 47425/93 (RWED,RWED,RE,RE)
- X*/
- X
- XIsDECVMS2(Tokens, NumTokens)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- X{
- X return ((NumTokens >= 4) && HasChar(Tokens[0], ';') && IsTime(Tokens[2]) &&
- X HasChar(Tokens[3], '/'));
- X}
- X
- X
- X
- X/*
- X * Returns 1 if is right type
- X */
- Xint IsRightType(Tokens, NumTokens, TypeOfDir)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xint TypeOfDir;
- X{
- X switch(TypeOfDir) {
- X case UNIX: return(IsUNIX(Tokens, NumTokens, ONLYSHOWREADABLEINT));
- X case HPUX: return(IsHPUX(Tokens, NumTokens, ONLYSHOWREADABLEINT));
- X case DECVMS: return(IsDECVMS(Tokens, NumTokens) || IsDECVMS2(Tokens, NumTokens));
- X case HENSA: return(IsHENSA(Tokens,NumTokens));
- X case NOVEL: return(IsNOVEL(Tokens,NumTokens));
- X#ifndef ONLYSAFEPARSE
- X case IBM: return(IsIBM(Tokens, NumTokens));
- X case TOPS20: return(IsTOPS20(Tokens, NumTokens));
- X/* case DECTEN: return(IsDECTEN(Tokens, NumTokens)); */
- X case UNKNOWN: return(NumTokens > 0);
- X#endif
- X default: return(0);
- X }
- X}
- X
- Xint TokensToParsedDir(Tokens, NumTokens, TypeOfDir, Current, Now, DirPath, HostPath)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xint TypeOfDir;
- Xstruct ParsedDir *Current;
- Xstruct timeb *Now;
- Xchar *DirPath;
- Xchar *HostPath;
- X{
- X int Result;
- X char buf[100];
- X
- X switch(TypeOfDir) {
- X case UNIX: Result=UNIXTokensToParsedDir(Tokens, NumTokens, Current, Now,
- X DirPath, HostPath, 0);
- X break;
- X case HPUX: Result=UNIXTokensToParsedDir(Tokens, NumTokens, Current, Now,
- X DirPath, HostPath, 1);
- X break;
- X case DECVMS: Result=DECVMSTokensToParsedDir(Tokens, NumTokens, Current, Now);
- X break;
- X case NOVEL: Result=NOVELTokensToParsedDir(Tokens, NumTokens, Current, Now);
- X break;
- X case HENSA: Result=HENSATokensToParsedDir(Tokens, NumTokens, Current, Now);
- X break;
- X
- X#ifndef ONLYSAFEPARSE
- X case IBM: Result=IBMTokensToParsedDir(Tokens, NumTokens, Current, Now);
- X break;
- X case TOPS20: Result=TOPS20TokensToParsedDir(Tokens, NumTokens, Current);
- X break;
- X case DECTEN: Result=DECTENTokensToParsedDir(Tokens, NumTokens, Current);
- X break;
- X#endif
- X case UNKNOWN: Result=UNKNOWNTokensToParsedDir(Tokens, NumTokens, Current);
- X break;
- X default:
- X AlexAssert(FALSE);
- X }
- X
- X Log2("TokensToParsedDir Date", DateStr((time_t) Current->Date, buf));
- X return(Result);
- X}
- X
- X
- X
- X
- X
- X/* Do this democratically. We vote on it and whoever gets the most votes wins.
- X *
- X */
- X#define NUMVOTES 5
- Xint DetermineTypeOfDir(DirFile)
- XFILE *DirFile;
- X{
- X char line[MAXPATH];
- X int TypeVotes[MaxHostType+3];
- X char Tokens[MAXTOKENS][MAXTOKENLEN];
- X int i, Winner, InputOk, NumTokens, NumLines;
- X
- X for (i=0; i<=UNKNOWN; i++) {
- X TypeVotes[i]=0;
- X }
- X
- X InputOk=1;
- X NumLines=0;
- X for (i=0; i<NUMVOTES && InputOk; i++) {
- X if (fgets(line, MAXPATH, DirFile) == NULL) {
- X InputOk=0;
- X } else {
- X NumLines++;
- X
- X NumTokens=LineToTokens(line, Tokens);
- X if (NumTokens>0) {
- X if (IsUNIX(Tokens, NumTokens, 0)) {
- X TypeVotes[UNIX]++;
- X
- X } else if (IsDECVMS(Tokens, NumTokens)) {
- X TypeVotes[DECVMS]++;
- X
- X } else if (IsDECVMS2(Tokens, NumTokens)) {
- X TypeVotes[DECVMS]++;
- X
- X } else if (IsHPUX(Tokens, NumTokens, 0)) {
- X TypeVotes[HPUX]++;
- X
- X } else if (IsNOVEL(Tokens, NumTokens)) {
- X TypeVotes[NOVEL]++;
- X
- X } else if (IsHENSA(Tokens, NumTokens)) {
- X TypeVotes[HENSA]++;
- X
- X#ifndef ONLYSAFEPARSE
- X } else if (IsTOPS20(Tokens, NumTokens)) {
- X TypeVotes[TOPS20]++;
- X
- X } else if (IsIBM(Tokens, NumTokens)) {
- X TypeVotes[IBM]++;
- X#endif
- X }
- X
- X /* TypeVotes[DECTEN]+=IsDECTEN(Tokens, NumTokens); */
- X }
- X }
- X }
- X
- X Winner=UNKNOWN;
- X for (i=0; i<=UNKNOWN; i++) {
- X if (TypeVotes[i] > TypeVotes[Winner]) {
- X Winner=i;
- X }
- X }
- X
- X LogT("DetermineTypeOfDir returning ", Winner);
- X LogN("DetermineTypeOfDir winner had ", TypeVotes[Winner]);
- X if (Winner==UNKNOWN) {
- X LogN("DetermineTypeOfDir lines checked ", NumLines);
- X }
- X
- X return(Winner);
- X}
- X
- X/*
- X * Input "alexdir" is a path for a file of the form:
- X
- Xdrwxr-xr-x 2 1092 tty 512 Mar 27 01:57 china-related
- X-r--r--r-- 1 root tty 20182 Nov 5 1988 virus.patch
- X-r--r--r--341 root tty 220680 Nov 5 1988 foobar
- Xlrwxr-xr-x 1 50 21 23 Aug 15 16:04 comp.sources.3b1 -> usenet/comp.sources.3b1
- X-rw-r--r-- 2 vac warp 61574 Aug 26 02:59 space-companies
- Xdrwxrwxr-x1693 7 21 39936 Aug 11 23:46 faces
- Xdrwxr-xr-x 2 vac warp 1024 Aug 18 23:51 space-investors.mail
- X-rw-r--r-- 1 1092 tty 28575 May 7 15:54 comm1.c
- Xdrwxrwsr-x 2 27847 101 9216 Jul 24 04:44 gif
- Xdrwxr-sr-x 2 27847 101 512 Nov 30 1990 gray
- Xdr-xr-xr-x 23 ftp daemon 512 Jun 20 15:41 pub
- Xdrwxrwxrwx 2 ftp none 512 May 21 01:37 tmp
- Xlrwxrwxrwx 1 root wheel 1 May 29 11:33 ftp -> .
- Xdrwxrwxrwx 2 3 80 Jul 19 11:33 incomming
- Xdr-xr-xr-x 4 3 240 Oct 10 1990 pub
- Xlrwxrwxrwx 1 root wheel 11 May 29 11:30 news.pub -> .r/news.pub
- X 0 1 2 3 4 5 6 7
- X .
- X 50
- X
- XHPUX:
- Xdir drwxrwxrwx+ 2 librarianftp 1024 Feb 2 16:35 drop_box
- X
- X * "name" is a string like "virus.patch"
- X *
- X */
- X
- XUNIXTokensToParsedDir(Tokens, NumTokens, Current, Now, DirPath, HostPath, ProtIndex)
- Xchar Tokens[MAXTOKENS][MAXTOKENLEN];
- Xint NumTokens;
- Xstruct ParsedDir *Current;
- Xstruct timeb *Now;
- Xchar *DirPath, *HostPath;
- X{
- X int LookingForMonth, MonthIndex, i, Result;
- X char TimeForParsing[MAXTOKENLEN];
- X char FilePath[MAXPATH];
- X
- X LookingForMonth=1;
- X for (i=2; (i<NumTokens) && LookingForMonth; i++) {
- X if (IsAMonth(Tokens[i])) {
- X LookingForMonth=0;
- X MonthIndex=i;
- X }
- X }
- X
- X if (LookingForMonth) {
- X Log2("UNIXTokensToParsedDir ERROR no month", Tokens[0]);
- X return(AFAIL);
- X }
- X
- X if (MonthIndex+3 >= NumTokens) {
- X LogN("UNIXTokensToParsedDir ERROR not enough tokens", NumTokens);
- X return(AFAIL);
- X }
- X
- X Current->Size = atoi(Tokens[MonthIndex-1]); /* on Unix we get a real size */
- X
- X (void) strcpy(TimeForParsing, Tokens[MonthIndex]); /* month */
- X (void) strcat(TimeForParsing, " ");
- X (void) strcat(TimeForParsing, Tokens[MonthIndex+1]); /* day */
- X (void) strcat(TimeForParsing, " ");
- X (void) strcat(TimeForParsing, Tokens[MonthIndex+2]); /* time or year */
- X
- X Current->Date = (unsigned int) StringToTimeInt(TimeForParsing, Now);
- X
- X (void) strcpy(Current->Name, Tokens[MonthIndex+3]); /* name */
- X
- X RemoveThroughSlash(Current->Name); /* "./foo" --> "foo" */
- X
- X Result=AOK;
- X switch(Tokens[ProtIndex][0]) {
- X case 'D':
- X case 'd': Current->Type=ADIR;
- X if (Current->Size < 512) Current->Size=512; /* microsoft.com shows dirs as 0 */
- X#ifdef ONLYSAFEPARSE
- X if (NumTokens > MonthIndex+4) {
- X LogN("UNIXTokensToParsedDir ERROR too many tokens", NumTokens);
- X Result=AFAIL;
- X }
- X#endif
- X break;
- X
- X case 'F':
- X case '-': Current->Type=AFILE;
- X#ifdef EXECUTABLE
- X if (Tokens[ProtIndex][3] == 'x') { /* -rwx */
- X Current->Executable = 1;
- X } else {
- X Current->Executable = 0;
- X }
- X#endif
- X
- X#ifdef ONLYSAFEPARSE
- X if (NumTokens > MonthIndex+4) {
- X LogN("UNIXTokensToParsedDir ERROR too many tokens", NumTokens);
- X Result=AFAIL;
- X }
- X#endif
- X break;
- X
- X case 'L':
- X case 'l': Current->Type=ALINK;
- X if (MonthIndex+5 >= NumTokens) {
- X LogN("UNIXTokensToParsedDir ERROR not enough tokens", NumTokens);
- X Result=AFAIL;
- X } else {
- X (void) strcpy(Current->SymLink, Tokens[MonthIndex+5]);
- X (void) strcpy(FilePath, DirPath);
- X (void) strcat(FilePath, "/");
- X (void) strcat(FilePath, Current->Name);
- X Result=OkSymLink(FilePath, Current->SymLink, HostPath);
- X }
- X break;
- X default:
- X Log("UNIXTokensToParsedDir ERROR did not understand file type");
- X Result=AFAIL;
- X break;
- X }
- X
- X /* should never happen any more XXXX */
- X if (Current->Name[0] == '/') {
- X Log2("UNIXTokensToParsedDir ERROR can not deal with leading / ", Current->Name);
- X Result=AFAIL;
- X }
- X
- X LogT("UNIXTokensToParsedDir returning ", Result);
- X return(Result);
- X}
- X
- X
- X#if defined(__386BSD__) || defined(ALPHAOSF) || defined(__NetBSD__)
- X/* Emulate this.
- X */
- Xvoid ftime(struct timeb *Now)
- X{
- X time_t _now=time(NULL);
- X struct tm *_Now=localtime(&_now);
- X Now->time=_now;
- X Now->millitm=0;
- X Now->timezone=_Now->tm_gmtoff/60;
- X Now->dstflag=_Now->tm_isdst;
- X}
- X#endif
- X
- X/* It is not possible to tell who adjusts for daylight savings and
- X who does not. So after each daylight savings switch we have to
- X check back with each host. This routine is used to check if the
- X date we have on record as our last checking date is prior to the
- X last time change - which would mean it is stale info.
- X*/
- X
- Xdouble LastTimeChange = 0; /* cleared once a day in alex.c */
- X
- Xint PriorToTimeChange(SecsSinceChecked)
- Xdouble SecsSinceChecked;
- X{
- X static double SecsSinceTC = 0;
- X long Spring, Fall;
- X struct timeb Then;
- X int Status, Result;
- X struct timeb Now;
- X
- X if (LastTimeChange == 0) {
- X ftime(&Now);
- X
- X Status = StringToTimeb("October 31", &Now, &Then);
- X if (Status != AOK) {
- X ToLog(DBERROR, "PriorToTimeChange can not parse Fall");
- X flushLog();
- X exit(-1);
- X }
- X Fall = Then.time;
- X LogN("PriorToTimeChange Fall", (int) Fall);
- X
- X Status = StringToTimeb("April 30", &Now, &Then);
- X if (Status != AOK) {
- X ToLog(DBERROR, "PriorToTimeChange can not parse Spring");
- X flushLog();
- X exit(-1);
- X }
- X Spring = Then.time;
- X LogN("PriorToTimeChange Spring", (int) Spring);
- X
- X /* StringToTimeb gets the closest matching date (could be in future). */
- X /* For this we don't want anything in future. */
- X
- X if (((Fall < Now.time) && (Fall > Spring)) || (Spring > Now.time)) {
- X LastTimeChange = Fall;
- X } else {
- X LastTimeChange = Spring;
- X }
- X
- X SecsSinceTC = TimeInSeconds() - LastTimeChange;
- X
- X LogN("PriorToTimeChange SecsSinceTC ", (int) SecsSinceTC);
- X }
- X
- X Result = SecsSinceChecked > SecsSinceTC;
- X
- X LogN("PriorToTimeChange returning ", Result);
- X return(Result);
- X}
- X
- X
- X/* Caller will call at most once per .alex.info even with failure.
- X */
- Xint GetRemoteNow(HostPtr, Now)
- Xstruct HostEntry *HostPtr;
- Xstruct timeb *Now;
- X{
- X char Name[100];
- X int TimeZone;
- X int OldTimeZone;
- X double SecsSinceChecked;
- X double Start, Finish, Elapse;
- X
- X AlexAssert(HostPtr != NULL);
- X
- X ftime(Now);
- X
- X OldTimeZone=HostPtr->TimeZone;
- X TimeZone =HostPtr->TimeZone;
- X
- X Start = TimeInSeconds();
- X SecsSinceChecked = Start - HostPtr->TimeLastCheck;
- X
- X if (((TimeZone >= RemTimeZoneFAIL) && (SecsSinceChecked > ADAY)) ||
- X (SecsSinceChecked > TRUSTTIMEZONE) ||
- X (PriorToTimeChange(SecsSinceChecked) &&
- X (HostPtr->Type != NOANONFTP) && (HostPtr->Type != ADOMAIN)) ||
- X (SecsSinceChecked > TRUSTHOSTTYPE)) {
- X
- X ToLog(DBPERF2, "GetRemoteNow old timezone of %d lastcheck %d ssc %lf \n",
- X OldTimeZone, HostPtr->TimeLastCheck, SecsSinceChecked);
- X
- X PathToHostName(HostPtr->Path, Name);
- X TimeZone=RemTimeZone(Name);
- X Finish = TimeInSeconds();
- X TotalRTZCalls++; /* perf stuff */
- X Elapse = Finish - Start; /* perf stuff */
- X TotalRTZTime += Elapse; /* perf stuff */
- X TotalRTZTimeSQ += Elapse*Elapse ; /* perf stuff */
- X HostPtr->TimeZone = TimeZone; /* Save in cache - could be RemTimeZoneFAIL */
- X HostPtr->TimeLastCheck = (int) Finish;
- X }
- X
- X
- X if (TimeZone < RemTimeZoneFAIL) {
- X Now->timezone=TimeZone; /* return real one */
- X } else { /* failed so can't use TimeZone */
- X Now->timezone=OldTimeZone; /* return old zone */
- X }
- X
- X if (Now->timezone >= RemTimeZoneFAIL) {
- X Now->timezone=DEFAULTTIMEZONE; /* Don't know what it is so use default */
- X }
- X
- X LogN("GetRemoteNow returning ", (int) Now->timezone);
- X return(AOK);
- X}
- X
- X
- X
- Xchar *CopyTillSlash(in, out)
- Xchar *in;
- Xchar *out;
- X{
- X char *tmp;
- X
- X tmp=out;
- X while ((*in != 0) && (*in != '/')) {
- X *tmp++ = *in++;
- X }
- X *tmp=0;
- X
- X return(out);
- X}
- X
- X
- X
- X/* In the case of a HostAlias we need to get the symlink
- X */
- Xint HostToParsedDir(Host, HostName, Current)
- Xstruct HostEntry *Host;
- Xchar *HostName;
- Xstruct ParsedDir *Current;
- X{
- X int Result;
- X
- X ClearParsedDirEntry(Current);
- X (void) strcpy(Current->Name, HostName);
- X
- X Result=AOK;
- X Current->SymLink[0]=0; /* set up defaults */
- X if (Host->Type != HOSTALIAS) {
- X Current->Type=AHOST; /* Any host -> AHOST (mostly ADIR) */
- X } else {
- X Current->Type=ALINK; /* HOSTALIASes are ALINKs */
- X AlexAssert(Host->SymLink != NULL); /* We check when read in file */
- X (void) strcpy(Current->SymLink, Host->SymLink);
- X }
- X
- X Current->Inode=0;
- X Current->Size=512;
- X Current->Date=TimeInSeconds(); /* could make things look like they change */
- X
- X return(Result);
- X}
- X
- X
- X/* This was a terrible linear time algorithm that was just put in place
- X * temporarily, but stayed. This should be fixed. HostsTable needs
- X * to be made into a tree.
- X *
- X * Note that DirPWS is something like /edu/cmu/cs/nectar/furmint/
- X */
- X
- Xint OutputHostsBefore(AIfile, NextHost, DirPWS, DPWSlen, Name)
- XFILE *AIfile;
- Xint NextHost;
- Xchar *DirPWS;
- Xint DPWSlen;
- Xchar *Name;
- X{
- X static char LastHostName[MAXPATH];
- X static int LastNextHost=-1;
- X
- X char HostName[100], FullName[MAXPATH];
- X struct ParsedDir Current;
- X int Status, Done;
- X
- X (void) strcpy(FullName, DirPWS); /* dir path with slash */
- X (void) strcat(FullName, Name);
- X
- X Log2("OutputHostsBefore with ", FullName);
- X
- X if (NextHost != LastNextHost) { /* need to know if continuing or startin over */
- X if ((CountOccurrences(DirPWS, '/') -1) >= MAXPARTSINHOSTNAME) { /* if so then no host in dir */
- X NextHost=HostsInTable;
- X }
- X LastHostName[0]=0;
- X LastNextHost=NextHost;
- X }
- X
- X Done=0;
- X for( ; !Done && NextHost<HostsInTable; ) {
- X Status = strcmp(HostsTable[NextHost]->Path, FullName);
- X if (Status >= 0) {
- X Done=1;
- X } else {
- X Status=strncmp(HostsTable[NextHost]->Path, DirPWS, DPWSlen);
- X if (Status == 0) { /* is in dir */
- X CopyTillSlash(&(HostsTable[NextHost]->Path[DPWSlen]), HostName);
- X
- X if (!streql(HostName, LastHostName)) {
- X Log2("OutputHostsBefore found ", HostName);
- X Status=HostToParsedDir(HostsTable[NextHost], HostName, &Current);
- X if (Status == AOK) {
- X if ((HostsTable[NextHost]->Type == HOSTALIAS) &&
- X (HostsTable[NextHost]->PathLen > DPWSlen+strlen(HostName))) {
- X Current.Type=ADOMAIN;
- X Current.SymLink[0]=0;
- X }
- X OneLineOut(AIfile, &Current);
- X }
- X (void) strcpy(LastHostName,HostName);
- X }
- X
- X }
- X NextHost++;
- X }
- X }
- X
- X LogN("OutputHostsBefore returning ", NextHost);
- X LastNextHost=NextHost;
- X
- X return(NextHost);
- X}
- X
- X
- X
- X
- X/* If there is a .alex.error in DirPath output it to the Sream AIfile
- X * in the correct format for a .alex.info.
- X *
- X * Return:
- X * AOK - no .alex.error file found
- X * AERRORMESSAGE - added an error message to stream
- X * AFAIL - error occurred
- X *
- X */
- Xint AddAnyErrorToStream(AIfile, DirPath)
- XFILE *AIfile;
- Xchar *DirPath;
- X{
- X char AlexErrorPath[MAXPATH];
- X struct ParsedDir Current;
- X int Status;
- X
- X (void) strcpy(AlexErrorPath, DirPath);
- X (void) strcat(AlexErrorPath, SLASHALEXERROR);
- X
- X Status=AOK;
- X if (LiteStat(AlexErrorPath) == AFILE) {
- X ClearParsedDirEntry(&Current);
- X
- X Status=StringFromFile(AlexErrorPath, Current.Name);
- X if (Status != AOK) {
- X ToLog(DBERROR, "AddAnyErrorToStream ERROR BUG .alex.error empty %s\n", AlexErrorPath);
- X } else {
- X Log2("AddAnyErrorToStream got error string ", Current.Name);
- X Current.Inode=InodeNext++; /* allocate a new inode */
- X Current.Size=0;
- X Current.Date=TimeInSeconds();
- X Current.Type=AERRORMESSAGE;
- X Current.CacheStatus=0;
- X Current.SymLink[0]=0;
- X Status=OneLineOut(AIfile, &Current);
- X if (Status == AOK) {
- X Status = AERRORMESSAGE;
- X }
- X if (fprintf(AIfile, "%c%c\n", METACHAR, ERRORCHAR) == EOF) {
- X error1("AddAnyErrorToStream could not write ERRORCHAR");
- X Status=AFAIL;
- X }
- X }
- X }
- X
- X LogT("AddAnyErrorToStream returning ", Status);
- X return(Status);
- X}
- X
- X#ifdef CHECKFORLOOPS
- X/* Returns 0 if none of parents are same,
- X * else number of ../ to have in symlink.
- X */
- Xint NumUpForSameDir(DirPath, ParentDirPath, DirName)
- Xchar *DirPath, *ParentDirPath, *DirName;
- X{
- X char WorkingDirPath[MAXPATH], Tmp[MAXPATH];
- X char ParentDirName[MAXPATH];
- X char ParentAlexDir[MAXPATH], AlexDir[MAXPATH];
- X int Result, NumUp;
- X
- X Result=0;
- X NumUp=1;
- X
- X (void) strcpy(WorkingDirPath, ParentDirPath);
- X
- X while (!Result && strlen(WorkingDirPath) > CACHEDIRLEN && HasString(WorkingDirPath, DirName)) {
- X ToLog(6, "NumUpForSameDir checking for looping %s\n", DirPath);
- X PathToFileName(WorkingDirPath, ParentDirName);
- X if (streql(DirName, ParentDirName)) {
- X ToLog(DBRPC, "NumUpForSameDir checking for looping %s \n", DirPath);
- X (void) strcpy(AlexDir, DirPath);
- X (void) strcat(AlexDir, SLASHALEXDIR);
- X (void) strcpy(ParentAlexDir, WorkingDirPath);
- X (void) strcat(ParentAlexDir, SLASHALEXDIR);
- X if (FilesAreEqual(AlexDir, ParentAlexDir) == AOK) {
- X ToLog(DBMAJOR, "NumUpForSameDir for sure we are looping %s \n", DirPath);
- X Result=NumUp;
- X }
- X }
- X PathToDir(WorkingDirPath, Tmp);
- X (void) strcpy(WorkingDirPath, Tmp);
- X NumUp++;
- X }
- X
- X return(Result);
- X}
- X
- X#endif
- X
- X/* DirPath = path for directory we are updating .alex.info in
- X *
- X * We go to parent of this to get "." and ".."
- X * We also output entries for ".alex.dir" and ".alex.info" (info is fixed up later)
- X */
- Xint OutputExtras(AIfile, DirPath, UidStr, NumUp, PtrNewestDate)
- XFILE *AIfile;
- Xchar *DirPath;
- Xchar *UidStr;
- Xint *NumUp;
- Xunsigned int *PtrNewestDate;
- X{
- X struct ParsedDir Current;
- X#ifdef DOTCHECK
- X struct ParsedDir DotCurrent, DotDotCurrent;
- X#endif
- X char TmpPath[MAXPATH], Name[MAXPATH];
- X char AlexInfoDir[MAXPATH], AlexInfoPath[MAXPATH];
- X struct ActiveAlexInfo AAI;
- X struct stat StatBuf;
- X static char CACHEDIRPARENT[MAXPATH]="";
- X int Result, Status, NeedDot, NeedDotDot, OutputCurrent;
- X
- X Log2("OutputExtras ", DirPath);
- X
- X if (CACHEDIRPARENT[0] == 0) {
- X PathToDir(CACHEDIRVAR, CACHEDIRPARENT);
- X Log2("OutputExtras CACHEDIRPARENT ", CACHEDIRPARENT);
- X }
- X
- X PathToFileName(DirPath, Name); /* name to look for in the .alex.info */
- X PathToDir(DirPath, AlexInfoDir); /* directory .alex.info would be in */
- X
- X if (streql(AlexInfoDir, CACHEDIRPARENT)) {
- X strcpy(AlexInfoPath, ROOTALEXINFO);
- X } else {
- X (void) strcpy(AlexInfoPath, AlexInfoDir);
- X (void) strcat(AlexInfoPath, SLASHALEXINFO);
- X }
- X
- X if (LiteStat(AlexInfoPath) != AFILE) {
- X Log2("OutputExtras ERROR parent had bad .alex.info file ", AlexInfoPath);
- X return(AFAIL);
- X }
- X
- X if (ALEXINFOINOPEN(AlexInfoPath, &AAI, UidStr, NORECURSION) != AOK) {
- X Log2("OutputExtras ERROR could not open .alex.info file ", AlexInfoPath);
- X return(AFAIL);
- X }
- X
- X NeedDot=1; /* we read through our parents .alex.info to get our . and .. */
- X NeedDotDot=1;
- X OutputCurrent=0;
- X /* At one point the idea of having the time on "." be the update time */
- X /* Occured to me, and I set the .Date below, but it does not work. */
- X /* The way lookup_2/readinfo work it ends up that it reads the parents */
- X /* So that the times and sizes on "." and ".." don't matter much. */
- X /* In fact the inode number used for pwd may be all that really matters */
- X while((AlexInfoInNext(&AAI, &Current) == AOK) && (NeedDot || NeedDotDot)) {
- X if (NeedDot && streql(Current.Name, Name)) {
- X Log2("OutputExtras found listing for current in parent ", Name);
- X#ifdef DOTCHECK
- X CopyParsedDir(&Current, &DotCurrent);
- X#endif
- X (void) strcpy(Current.Name, ".");
- X if ((Current.Type == ADIR) && (*PtrNewestDate < Current.Date)) {
- X *PtrNewestDate = Current.Date;
- X }
- X NeedDot=0;
- X OutputCurrent=1;
- X }
- X
- X if (!OutputCurrent && NeedDotDot && streql(Current.Name, ".")) {
- X Log2("OutputExtras found parents info ", Current.Name);
- X#ifdef DOTCHECK
- X CopyParsedDir(&Current, &DotDotCurrent);
- X#endif
- X (void) strcpy(Current.Name, "..");
- X NeedDotDot=0;
- X OutputCurrent=1;
- X }
- X
- X if (OutputCurrent) {
- X Status=OneLineOut(AIfile, &Current);
- X if (Status != AOK) {
- X ToLog(DBERROR, "OutputExtras ERROR BUG can not OneLineOut AIfile");
- X (void) AlexInfoInClose(&AAI);
- X return(AFAIL);
- X }
- X OutputCurrent=0;
- X }
- X }
- X
- X (void) AlexInfoInClose(&AAI); /* done with parent */
- X
- X if (NeedDot || NeedDotDot) {
- X ToLog(DBERROR, "OutputExtras ERROR BUG did not get both . and .. ");
- X return(AOLD); /* update parent */
- X }
- X
- X Result=Status;
- X if ((Result == AOK)
- X#ifdef DOTCHECK
- X /* check for things like sgi.com:sgi sgi.sgi.com sgi.sgi.com:sgi */
- X && (DotCurrent.Type != AHOST)
- X /* && (DotDotCurrent.Date == DotCurrent.Date)
- X * && (DotDotCurrent.Size == DotCurrent.Size) */ /* for now don't filter on date/size */
- X#endif
- X ) {
- X#ifdef CHECKFORLOOPS
- X *NumUp=NumUpForSameDir(DirPath, AlexInfoDir, Name);
- X if (*NumUp > 0) {
- X Result = MAKELINKSTOPARENT;
- X }
- X#endif
- X }
- X
- X if ((Result == AOK) && streql(Name, "alex") && (strlen(DirPath) > CACHEDIRLEN)) {
- X Result = MAKELINKSTOALEX; /* may or may not depending on number of "com" "edu" .. */
- X }
- X
- X if (streql(DirPath, CACHEDIRVAR)) { /* add in README file */
- X Log("Going to add /alex/README");
- X (void) strcpy(TmpPath, DirPath);
- X (void) strcat(TmpPath, "/README");
- X Status=lstat(TmpPath, &StatBuf);
- X if (Status != 0) {
- X (void) CheckAlexReadme(TmpPath);
- X Status=lstat(TmpPath, &StatBuf);
- X }
- X if (Status == 0) {
- X ClearParsedDirEntry(&Current);
- X Current.Inode=InodeNext++;
- X (void) strcpy(Current.Name, "README");
- X Current.Size=StatBuf.st_size;
- X Current.Date=StatBuf.st_mtime; /* will be time of copy but close enough */
- X Current.Type=AFILE;
- X Current.CacheStatus=1;
- X Current.SymLink[0]=0;
- X OneLineOut(AIfile, &Current);
- X if (Status != AOK) {
- X ToLog(DBERROR, "OutputExtras ERROR BUG can not OneLineOut AIfile");
- X return(AFAIL);
- X }
- X }
- X }
- X
- X if (DEBUGLEVEL >= DBDOTALEX) {
- X (void) strcpy(TmpPath, DirPath);
- X (void) strcat(TmpPath, SLASHALEXDIR);
- X Status=lstat(TmpPath, &StatBuf);
- X if (Status == 0) {
- X ClearParsedDirEntry(&Current);
- X Current.Inode=InodeNext++;
- X (void) strcpy(Current.Name, ALEXDIR);
- X Current.Size=StatBuf.st_size;
- X Current.Date=StatBuf.st_mtime;
- X Current.Type=AFILE;
- X Current.CacheStatus=1;
- X Current.SymLink[0]=0;
- X OneLineOut(AIfile, &Current);
- X if (Status != AOK) {
- X ToLog(DBERROR, "OutputExtras ERROR BUG can not OneLineOut AIfile");
- X return(AFAIL);
- X }
- X } else {
- X Log2("OutputExtras - error no .alex.dir for ", TmpPath);
- X }
- X
- X ClearParsedDirEntry(&Current);
- X Current.Inode=BOGUSINODE; /* temporary values - we fix later */
- X (void) strcpy(Current.Name, ALEXINFO);
- X Current.Size=BOGUSINODE;
- X Current.Date=BOGUSINODE;
- X Current.Type=AFILE;
- X Current.CacheStatus=1;
- X Current.SymLink[0]=0;
- X Status=OneLineOut(AIfile, &Current);
- X
- X if (Status != AOK) {
- X ToLog(DBERROR, "OutputExtras ERROR BUG can not OneLineOut AIfile");
- X return(AFAIL);
- X }
- X }
- X
- X
- X LogT("OutputExtras returning ", Result);
- X return(Result);
- X}
- X
- X
- X
- Xint OutputMetaData(AIfile, Version, UpdateDate, NewestDate, TypeOfDir,
- X PartsInHostName, AddAnyErrorStatus)
- XFILE *AIfile;
- Xint Version;
- Xunsigned int UpdateDate, NewestDate;
- Xint TypeOfDir, PartsInHostName, AddAnyErrorStatus;
- X{
- X int Status, SizeOk;
- X
- X Status=AOK;
- X if (TypeOfDir == UNIX) {
- X SizeOk=1;
- X } else {
- X SizeOk=0;
- X }
- X
- X
- X if (fprintf(AIfile, "%c%c %d\n", METACHAR, VERSCHAR, Version) == EOF) {
- X error1("OutputMetaData could not write Version ");
- X Status=AFAIL;
- X
- X } else if (fprintf(AIfile, "%c%c %u\n", METACHAR, DATECHAR, UpdateDate) == EOF) {
- X error1("OutputMetaData could not write UpdateDate ");
- X Status=AFAIL;
- X
- X } else if (fprintf(AIfile, "%c%c %u\n", METACHAR, NEWCHAR, NewestDate) == EOF) {
- X error1("OutputMetaData could not write NewestDate ");
- X Status=AFAIL;
- X
- X } else if (fprintf(AIfile, "%c%c %d\n", METACHAR, SIZECHAR, SizeOk) == EOF) {
- X error1("OutputMetaData could not write SizeOk ");
- X Status=AFAIL;
- X
- X } else if (fprintf(AIfile, "%c%c %d\n", METACHAR, HOSTPARTSCHAR, PartsInHostName) == EOF) {
- X error1("OutputMetaData could not write PartsInHostName ");
- X Status=AFAIL;
- X
- X /* Also can happen in AddAnyErrorToStream() */
- X } else if (AddAnyErrorStatus == AERRORMESSAGE) {
- X if (fprintf(AIfile, "%c%c\n", METACHAR, ERRORCHAR) == EOF) {
- X error1("OutputMetaData could not write ERRORCHAR");
- X Status=AFAIL;
- X }
- X }
- X
- X
- X LogT("OutputMetaData returning ", Status);
- X return(Status);
- X}
- X
- X
- X/* Performance reporting
- X * XXXX YYYY
- X *
- X * Called when old .alex.info entry for a file was out of date.
- X * Input includes directory and the ParsedDir for new entry in .alex.info.
- X *
- X * We only get a reasonable approximation of staleness stats.
- X * File could change, read stale, then change again so looking like read was ok.
- X * Could have read while stale, then been flushed from cache.
- X *
- X * Return
- X * AFAIL if not in cache - (caller removes if is in cache)
- X */
- Xint ReportStaleStats(Dir, CurrentPtr)
- Xchar *Dir;
- Xstruct ParsedDir *CurrentPtr;
- X{
- X char Path[MAXPATH];
- X struct stat StatBuf;
- X int ModTimeMinusATime, ATimeMinusMTime, StaleNess;
- X int Result;
- X
- X (void) strcpy(Path, Dir);
- X (void) strcat(Path, "/");
- X (void) strcat(Path, CurrentPtr->Name);
- X
- X Result=AlexStat(Path, &StatBuf);
- X
- X if (Result == AFAIL) {
- X ToLog(DBPERF, "ReportStaleStats stale but not in cache \n", Path);
- X } else {
- X ToLog(DBPERF, "ReportStaleStats RawData mtime=%d atime=%d modtime=%d %s \n",
- X (int) StatBuf.st_mtime, (int) StatBuf.st_atime, (int) CurrentPtr->Date, Path);
- X
- X ModTimeMinusATime = (int) (CurrentPtr->Date - StatBuf.st_atime);
- X ATimeMinusMTime = (int) StatBuf.st_atime - StatBuf.st_mtime;
- X
- X StaleNess=0;
- X if (ATimeMinusMTime < 0) {
- X ToLog(DBPERF, "ReportStaleStats updated after last read %d\n", ATimeMinusMTime);
- X } else {
- X if (ModTimeMinusATime > 0) {
- X ToLog(DBPERF, "ReportStaleStats changed after we read file\n"); /* StaleNess==0 */
- X } else if (ModTimeMinusATime < 0) {
- X ToLog(DBPERF, "ReportStaleStats should have changed before we read stale data\n");
- X StaleNess= abs(ModTimeMinusATime);
- X if (ATimeMinusMTime < StaleNess) {
- X StaleNess=ATimeMinusMTime;
- X ToLog(DBPERF, "ReportStaleStats StaleData used closer after last update %d\n",
- X StaleNess);
- X } else {
- X ToLog(DBPERF, "ReportStaleStats StaleData used before current update%d \n",
- X StaleNess);
- X }
- X }
- X }
- X
- X if (CurrentPtr->Date < StatBuf.st_mtime) {
- X ToLog(DBPERF, "ReportStaleStats the mod time is before we FTPed it\n");
- X StaleNess=0;
- X }
- X
- X if (StaleNess > 60) {
- X ToLog(DBPERF, "ReportStaleStats StaleDataInfo %d seconds == %f days for %s \n",
- X StaleNess, StaleNess/86400.0, Path);
- X TotalStaleFiles++;
- X TotalStaleSecs += StaleNess;
- X }
- X }
- X return(Result);
- X}
- X
- X
- Xint RmDirNameIfThere(dir, name)
- Xchar *dir, *name;
- X{
- X char tmp[MAXPATH];
- X int Result, Type;
- X
- X (void) strcpy(tmp, dir);
- X (void) strcat(tmp, "/");
- X (void) strcat(tmp, name);
- X
- X
- X Type=LiteStat(tmp); /* not from .alex.info */
- X
- X switch (Type) {
- X case ADIR: Log2("RmDirNameIfThere is RecursiveRming ", tmp);
- X Result=RecursiveRm(tmp, __FILE__, __LINE__, DONOTWAIT);
- X break;
- X
- X case AFILE: Log2("RmDirNameIfThere is unlinking ", tmp);
- X Result=unlink(tmp);
- X break;
- X
- X case AFAIL: Log2("RmDirNameIfThere was not there ", tmp);
- X break;
- X
- X default: Result=AFAIL;
- X LogT("RmDirNameIfThere ERROR bad type ", Type);
- X }
- X
- X if (Result != AOK) {
- X Log2("RmDirNameIfThere did not remove ", tmp);
- X Result=AFAIL;
- X } else {
- X Log2("RmDirNameIfThere removed ", tmp);
- X }
- X
- X return(Result);
- X}
- X
- X
- X
- X/* Assumes files are sorted so we must be sure they are !!!!
- X *
- X * Input: filenames for .alex.info.old, .alex.info.tmp and .alex.info
- X * the .alex.info.old can be /dev/null
- X *
- X * Function:
- X * Remove files and directories that were around but are no longer
- X * Patchs up Inode numbers in cases where files already had inodes
- X *
- X * Algorithm:
- X * work down the 2 sorted lists sort of like a merge
- X * New:
- X * If there is a .alex.error, then there is not a new .alex.info, and we
- X * really want to keep the old info as it is better than the new. So,
- X * we should add an error message, but keep old stuff around.
- X */
- Xint FixInodesAndRemoveOld(AlexInfoOld, AlexInfoTmp, AlexInfo, UidStr,
- X UpdateDate, NewestDate, TypeOfDir, PartsInHostName, AddAnyErrorStatus, HaveAlexDir)
- Xchar *AlexInfoOld, *AlexInfoTmp, *AlexInfo, *UidStr;
- Xunsigned int UpdateDate, NewestDate;
- Xint PartsInHostName;
- Xint TypeOfDir, AddAnyErrorStatus, HaveAlexDir;
- X{
- X struct ActiveAlexInfo OldAIF, TmpAIF;
- X FILE *AIfile;
- X char dir[MAXPATH];
- X int Status, TmpFull, RemovedSomething;
- X struct ParsedDir CurrentOld, CurrentTmp, Current;
- X long AlexInfoLoc, FileLength;
- X struct stat StatBuf;
- X
- X Log2("FixInodesAndRemoveOld ", AlexInfoOld);
- X
- X PathToDir(AlexInfo, dir);
- X
- X if (ALEXINFOINOPEN(AlexInfoOld, &OldAIF, UidStr, NORECURSION) != AOK) {
- X error2("FixInodesAndRemoveOld could not open", AlexInfoOld);
- X return(AFAIL);
- X } else {
- X Log2("FixInodesAndRemoveOld has file open for read ", AlexInfoOld);
- X }
- X
- X if (ALEXINFOINOPEN(AlexInfoTmp, &TmpAIF, UidStr, NORECURSION) != AOK) {
- X Log2("FixInodesAndRemoveOld could not open", AlexInfoTmp);
- X (void) AlexInfoInClose(&OldAIF);
- X (void) AlexInfoInClose(&TmpAIF);
- X return(AFAIL);
- X } else {
- X Log2("FixInodesAndRemoveOld has file open for read ", AlexInfoTmp);
- X }
- X
- X AIfile=AFOPEN(AlexInfo,"w+");
- X if (AIfile==NULL) {
- X error2("FixInodesAndRemoveOld could not open", AlexInfo);
- X (void) AlexInfoInClose(&OldAIF);
- X (void) AlexInfoInClose(&TmpAIF);
- X return(AFAIL);
- X }
- X
- X OutputMetaData(AIfile, ALEXINFOVERSION, UpdateDate, NewestDate, TypeOfDir,
- X PartsInHostName, AddAnyErrorStatus);
- X
- X
- X RemovedSomething=0;
- X CurrentOld.Name[0]=0;
- X CurrentTmp.Name[0]=0;
- X AlexInfoLoc= -1;
- X TmpFull=0;
- X while (1) {
- X if((AlexInfoLoc == -1) && streql(CurrentTmp.Name, ALEXINFO)) {
- X AlexInfoLoc=ftell(AIfile); /* remember this spot we fix later */
- X LogN("FixInodesAndRemoveOld just did ftell ", (int) AlexInfoLoc);
- X }
- X
- X Status=strcmp(CurrentTmp.Name, CurrentOld.Name);
- X ToLog(10, "FixInodesAndRemoveOld : %s : %d : %s t=%d\n", CurrentTmp.Name,
- X Status, CurrentOld.Name, (int) TmpFull);
- X
- X if (Status == 0) { /* matched !!!!!! */
- X if (TmpFull) {
- X if (!SpecialFile(&CurrentTmp)) {
- X CurrentTmp.Inode=CurrentOld.Inode; /* was already around use inode # */
- X
- X if (CurrentTmp.Date != CurrentOld.Date) { /* if has been updated */
- X if ((CurrentTmp.Type == AFILE) || /* and is a file or type has changed */
- X (SimpleType(CurrentTmp.Type) != SimpleType(CurrentOld.Type))) {
- X Log2("FixInodesAndRemoveOld thinks this is old ", CurrentTmp.Name);
- X if (ReportStaleStats(dir, &CurrentTmp) != AFAIL) {
- X (void) RmDirNameIfThere(dir, CurrentOld.Name); /* then remove from cache */
- X RemovedSomething++;
- X }
- X } else {
- X switch (CurrentTmp.Type) {
- X case ADOMAIN:
- X case AHOST:
- X /* CurrentTmp.Date=CurrentOld.Date; */
- X CurrentTmp.Date= 0; /* make hosts old so don't check too often */
- X Log2("FixInodesAndRemoveOld setting date back on ", CurrentTmp.Name);
- X break;
- X
- X case ADIR:
- X Log2("FixInodesAndRemoveOld subdirectory has changed", CurrentTmp.Name);
- X break;
- X
- X case ALINK:
- X Log2("FixInodesAndRemoveOld have a new link value", CurrentTmp.Name);
- X break;
- X case AERRORMESSAGE:
- X Log2("FixInodesAndRemoveOld have an errormessage ", CurrentTmp.Name);
- X break;
- X default:
- X ToLog(DBERROR, "FixInodesAndRemoveOld ERROR BUG %s\n", CurrentTmp.Name);
- X break;
- X }
- X }
- X }
- X }
- X OneLineOut(AIfile, &CurrentTmp);
- X TmpFull=0;
- X }
- X
- X if(AlexInfoInNext(&TmpAIF, &CurrentTmp) != AOK) break; /* check CurrentTmp first */
- X TmpFull=1;
- X if(AlexInfoInNext(&OldAIF, &CurrentOld) != AOK) break;
- X Log2(CurrentTmp.Name, CurrentOld.Name);
- X
- X } else if (Status > 0) {
- X if (!SpecialFileOrError(&CurrentOld)) {
- X if (AddAnyErrorStatus == AERRORMESSAGE) {
- X if (CurrentOld.Type <= ADIR) {
- X OneLineOut(AIfile, &CurrentOld); /* if no new .alex.info copy old */
- X }
- X } else {
- X Log2("FixInodesAndRemoveOld Greater so rming ", CurrentOld.Name);
- X (void) RmDirNameIfThere(dir, CurrentOld.Name); /* gone so remove it */
- X RemovedSomething++;
- X }
- X }
- X
- X if(AlexInfoInNext(&OldAIF, &CurrentOld) != AOK) break;
- X Log2("Just a new old ", CurrentOld.Name);
- X } else {
- X Log2("FixInodesAndRemoveOld less so advancing past ", CurrentTmp.Name);
- X if (TmpFull) {
- X CurrentTmp.Inode=InodeNext++; /* allocate a new inode */
- X OneLineOut(AIfile, &CurrentTmp);
- X TmpFull=0;
- X }
- X if(AlexInfoInNext(&TmpAIF, &CurrentTmp) != AOK) break;
- X Log2("Just a new Tmp ", CurrentTmp.Name);
- X TmpFull=1;
- X }
- X } /* while */
- X
- X
- X while(AlexInfoInNext(&OldAIF, &CurrentOld) == AOK) { /* deal with rest of Old */
- X Log2("FixInodesAndRemoveOld rest-of-old ", CurrentOld.Name);
- X if (!SpecialFileOrError(&CurrentOld)) {
- X if (AddAnyErrorStatus == AERRORMESSAGE) {
- X if (CurrentOld.Type <= ADIR) {
- X OneLineOut(AIfile, &CurrentOld); /* if no new .alex.info copy old */
- X }
- X } else {
- X (void) RmDirNameIfThere(dir, CurrentOld.Name); /* gone so remove it */
- X RemovedSomething++;
- X }
- X }
- X }
- X (void) AlexInfoInClose(&OldAIF);
- X
- X if ((HaveAlexDir || (AddAnyErrorStatus == AERRORMESSAGE)) && (RemovedSomething==0)) {
- X TotalUnchangedDirs++;
- X }
- X
- X do { /* deal with rest Tmp */
- X if (TmpFull) {
- X Log2("FixInodesAndRemoveOld rest-of-tmp ", CurrentTmp.Name);
- X if((AlexInfoLoc == -1) && streql(CurrentTmp.Name, ALEXINFO)) {
- X Log("FixInodesAndRemoveOld about to ftell (2) ");
- X AlexInfoLoc=ftell(AIfile); /* remember this spot we fix later */
- X LogN("FixInodesAndRemoveOld just did ftell (3) ", (int) AlexInfoLoc);
- X } else {
- X if (!SpecialFile(&CurrentTmp)) {
- X CurrentTmp.Inode=InodeNext++; /* allocate a new inode */
- X }
- X }
- X OneLineOut(AIfile, &CurrentTmp);
- X }
- X TmpFull=1; /* if we loop we will have data */
- X } while(AlexInfoInNext(&TmpAIF, &CurrentTmp) == AOK);
- X
- X (void) AlexInfoInClose(&TmpAIF);
- X Status = AOK;
- X
- X fflush(AIfile);
- X if (DEBUGLEVEL >= DBDOTALEX) {
- X Log("FixInodesAndRemoveOld is about to go back and fix AlexInfo");
- X Status=lstat(AlexInfo, &StatBuf);
- X if (Status == 0) {
- X ClearParsedDirEntry(&Current);
- X (void) strcpy(Current.Name, ALEXINFO);
- X Current.Inode=InodeNext++;
- X FileLength = ftell(AIfile); /* we are at the end */
- X Current.Size=FileLength; /* we know the real size now */
- X Current.Date=StatBuf.st_mtime;
- X Current.Type=AFILE;
- X Current.CacheStatus=1;
- X Current.SymLink[0]=0;
- X if ((AlexInfoLoc > 0) && (AlexInfoLoc <FileLength)) {
- X if (fseek(AIfile, AlexInfoLoc, 0)) { /* we saw one go there */
- X LogN("FixInodesAndRemoveOld fseek failed ", (int) AlexInfoLoc);
- X }
- X } else {
- X ToLog(DBERROR, "FixInodesAndRemoveOld ERROR BUG Bogus AlexInfoLoc %d\n ",
- X (int) AlexInfoLoc);
- X Status=AFAIL;
- X }
- X if (Status == AOK) {
- X Status=OneLineOut(AIfile, &Current); /* since size if fixed field this works */
- X }
- X } else {
- X Log2("FixInodesAndRemoveOld ERROR could not update size for ", AlexInfo);
- X Status=AFAIL;
- X }
- X } else {
- X if (AlexInfoLoc > 0) {
- X ToLog(DBERROR, "FixInodesAndRemoveOld ERROR %s has a .alex.info at %d\n", AlexInfo, AlexInfoLoc);
- X }
- X }
- X
- X (void) AFCLOSE(AIfile);
- X
- X LogT("FixInodesAndRemoveOld returning ", Status);
- X return(Status);
- X}
- X
- X
- X
- X
- X
- X/* returns 1 if we have no trouble with this name
- X */
- Xint NotForbiddenName(Name)
- Xchar *Name;
- X{
- X return(!streql(Name, ".") && !streql(Name, "..") &&
- X !streql(Name, ALEXINFO) && !streql(Name, ALEXDIR));
- X}
- X
- X
- X/* WhereTo is either MAKELINKSTOALEX or MAKELINKSTOPARENT
- X * if TOPARENT then NumUp contains number of ../ to add.
- X */
- XModifyCurrentToLink(PtrCurrent, WhereTo, NumUp)
- Xstruct ParsedDir *PtrCurrent;
- Xint WhereTo, NumUp;
- X{
- X int i;
- X
- X PtrCurrent->Type=ALINK;
- X
- X switch (WhereTo) {
- X case MAKELINKSTOALEX: (void) strcpy(PtrCurrent->SymLink, ALEXPATH);
- X (void) strcat(PtrCurrent->SymLink, "/");
- X (void) strcat(PtrCurrent->SymLink, PtrCurrent->Name);
- X break;
- X
- X case MAKELINKSTOPARENT: PtrCurrent->SymLink[0]=0;
- X for (i=0; i<NumUp; i++) {
- X (void) strcat(PtrCurrent->SymLink, "../");
- X }
- X (void) strcat(PtrCurrent->SymLink, PtrCurrent->Name);
- X break;
- X
- X default: ToLog(DBERROR, "ModifyCurrentToLink got bogus argument %d", WhereTo);
- X exit(-1);
- X }
- X}
- X
- Xint ParentHasNewAlexDir(DirPath)
- Xchar *DirPath;
- X{
- X char ParentAlexDir[MAXPATH];
- X
- X PathToDir(DirPath, ParentAlexDir);
- X (void) strcat(ParentAlexDir, SLASHALEXDIR);
- X
- X if (SecsSinceWrite(ParentAlexDir) < SECSTILLRETRY) {
- X return(1);
- X } else {
- X return(0);
- X }
- X}
- X
- Xchar *AlexTops[] = {"ar", "arpa", "at", "au", "be", "br", "ca", "ch", "com", "de", "dk", "ec",
- X "edu", "es", "fi", "fr", "gov", "gr", "hk", "ie", "il", "it", "jp", "kr",
- X "mil", "net", "nl", "no", "nz", "org", "se", "sg", "tw", "uk", "za", NULL };
- X
- X/* return 1 if Name is in above list */
- Xint IsAnAlexTop(Name)
- Xchar *Name;
- X{
- X int i;
- X
- X for (i=0; AlexTops[i] != NULL; i++) {
- X if (streql(AlexTops[i], Name)) {
- X return(1);
- X }
- X }
- X return(0);
- X}
- X
- X/* Input is *directory* to play with and HostPtr to host that is parent of this tree.
- X * If we don't have a HostPtr and there is no .alex.dir we just make a
- X * .alex.info from the known hosts/domains.
- X *
- X * We parse the .alex.dir returned from the ftp dir command once and create
- X * a .alex.info file which is in a standard easy to parse form.
- X *
- X * .alex.dir | conversion | sort > .alex.info.tmp (saving UpdateDate, NewestDate)
- X * FixInodesAndRemoveOld(Old, Tmp, UpdateDate, NewestDate) ==> .alex.info.new
- X * mv .alex.info.new .alex.info
- X *
- X */
- Xextern int DirToInfo(DirPath, HostPtr, UidStr)
- Xchar *DirPath;
- Xstruct HostEntry *HostPtr;
- Xchar *UidStr;
- X{
- X FILE *ADfile, *AITmpFile;
- X char AlexDirPath[MAXPATH], DirPWS[MAXPATH];
- X char AlexInfo[MAXPATH], AlexInfoTmp[MAXPATH], AlexInfoOld[MAXPATH], AlexInfoNew[MAXPATH];
- X char line[MAXPATH];
- X char Tokens[MAXTOKENS][MAXTOKENLEN];
- X int Result, HaveNow, NumTokens, TypeOfDir;
- X int NumLines, NumNotFound;
- X struct ParsedDir Current;
- X struct timeb Now;
- X int Status, DPWSlen, NextHost, AddAnyErrorStatus;
- X unsigned int UpdateDate, NewestDate;
- X int MakeLinksType;
- X int FirstOfTwoPasses, TotalAlexTops, Done, NumUp, HaveAlexDir;
- X#ifdef CAREFULATTOP
- X int AtHostTop;
- X#endif
- X
- X ToLog(DBFTP, "In DirToInfo %s\n", DirPath);
- X
- X if (LiteStat(DirPath) != ADIR) {
- X ToLog(DBERROR, "DirToInfo ERROR BUG did not get a ADIR %s\n", DirPath);
- X return(AFAIL);
- X }
- X
- X if ((HostPtr != NULL) && (HostPtr->Type == ADOMAIN)) { /* ADOMAIN is useless here */
- X HostPtr=NULL;
- X }
- X InvalidateStatCache=1;
- X
- X (void) strcpy(AlexDirPath, DirPath);
- X (void) strcat(AlexDirPath, SLASHALEXDIR);
- X
- X (void) strcpy(AlexInfo, DirPath);
- X (void) strcat(AlexInfo, SLASHALEXINFO);
- X
- X (void) strcpy(DirPWS, &DirPath[CACHEDIRLEN]); /* Dir-Path-With-Slash */
- X (void) strcat(DirPWS, "/");
- X DPWSlen=strlen(DirPWS);
- X
- X (void) strcpy(AlexInfoTmp, AlexInfo);
- X (void) strcat(AlexInfoTmp, ".tmp");
- X
- X (void) strcpy(AlexInfoNew, AlexInfo);
- X (void) strcat(AlexInfoNew, ".new");
- X
- X
- X AITmpFile=AFOPEN(AlexInfoTmp, "w");
- X if (AITmpFile==NULL) {
- X error2("DirToInfo could not open", AlexInfoTmp);
- X return(AFAIL);
- X } else {
- X Log2("DirToInfo has done open for sort into ", AlexInfoTmp);
- X }
- X
- X NewestDate=0;
- X /* do this first since they are all . files */
- X Status=OutputExtras(AITmpFile, DirPath, UidStr, &NumUp, &NewestDate);
- X if ((Status == MAKELINKSTOPARENT) || (Status == MAKELINKSTOALEX)) {
- X MakeLinksType=Status;
- X Status=AOK;
- X } else {
- X MakeLinksType=0;
- X }
- X
- X if (Status == AOK) {
- X AddAnyErrorStatus=AddAnyErrorToStream(AITmpFile, DirPath);
- X }
- X if ((Status != AOK) || (AddAnyErrorStatus == AFAIL)) {
- X ToLog(DBERROR, "DirToInfo ERROR BUG can not OutputExtras/AddAnyError to %s\n", DirPath);
- X AFCLOSE(AITmpFile);
- X LogT("DirToInfo returning ", Status);
- X return(Status);
- X }
- X
- X NextHost=0;
- X Result= AOK;
- X UpdateDate=TimeInSeconds(); /* will use time on .alex.dir if exists */
- X
- X if (HostPtr == NULL) {
- X Log("DirToInfo found NULL HostPtr"); /* skip many lines of code */
- X } else {
- X#ifdef CAREFULATTOP
- X AtHostTop = (HostPtr->PartsInHostName == (CountOccurrences(DirPWS, '/') -1));
- X#endif
- X
- X ADfile=AFOPEN(AlexDirPath,"r");
- X if (ADfile == NULL) {
- X HaveAlexDir=0;
- X Log2("DirToInfo could not open AlexDirPath", AlexDirPath); /* skip many lines of code */
- X } else {
- X HaveAlexDir=1;
- X UpdateDate=MTimeOfFile(AlexDirPath);
- X TypeOfDir=DetermineTypeOfDir(ADfile);
- X if (fseek(ADfile, (long) 0, 0)) { /* go back to start */
- X Log("DirToInfo ERROR fseek failed");
- X (void) AFCLOSE(ADfile);
- X (void) AFCLOSE(AITmpFile);
- X return(AFAIL);
- X }
- X
- X NumLines=0;
- X NumNotFound=0;
- X HaveNow=0;
- X line[0]=0;
- X if (MakeLinksType == MAKELINKSTOALEX) { /* only if name is "alex" */
- X FirstOfTwoPasses=1;
- X } else {
- X FirstOfTwoPasses=0;
- X }
- X TotalAlexTops=0;
- X Done=0;
- X while (!Done && (Result == AOK)) {
- X if (fgets(line, MAXPATH, ADfile) == NULL) {
- X if (FirstOfTwoPasses) {
- X if (TotalAlexTops < 10) {
- X MakeLinksType = 0; /* should be at least 10 of them */
- X }
- X NumLines=0;
- X NumNotFound=0;
- X FirstOfTwoPasses=0; /* done with first pass */
- X (void) rewind(ADfile);
- X continue;
- X } else {
- X Done=1;
- X break;
- X }
- X }
- X
- X NumLines++;
- X if ((TypeOfDir == UNKNOWN) && (HasString(line, "not found"))) {
- X NumNotFound++;
- X continue;
- X }
- X
- X NumTokens=LineToTokens(line, Tokens);
- X
- X if (!IsRightType(Tokens, NumTokens, TypeOfDir)) {
- X Log2("DirToInfo is ignoring this line ", line);
- X continue;
- X }
- X
- X if (!HaveNow) {
- X (void) GetRemoteNow(HostPtr, &Now);
- X HaveNow=1;
- X }
- X
- X ClearParsedDirEntry(&Current);
- X Status=TokensToParsedDir(Tokens, NumTokens, TypeOfDir, &Current, &Now,
- X DirPath, HostPtr->Path);
- X
- X if (FirstOfTwoPasses) {
- X if (IsAnAlexTop(Current.Name)) {
- X TotalAlexTops++;
- X }
- X } else if ((Status==AOK) && NotForbiddenName(Current.Name)){
- X if (MakeLinksType != 0) {
- X ModifyCurrentToLink(&Current, MakeLinksType, NumUp);
- X }
- X#ifndef AT_DIR
- X NextHost=OutputHostsBefore(AITmpFile, NextHost, DirPWS, DPWSlen, Current.Name);
- X#endif
- X TotalFTPLS++;
- X OneLineOut(AITmpFile, &Current);
- X if ((NewestDate < Current.Date) &&
- X ((Current.Type == AFILE) ||
- X#ifdef CAREFULATTOP
- X (AtHostTop && (Current.Type == ADIR)) ||
- X#endif
- X (streql(Current.Name, ".")))) {
- X NewestDate=Current.Date;
- X }
- X }
- X }
- X if ((NumNotFound == 1) && (NumLines==1)) { /* XXXX might be old if NotFound > 1 */
- X if (!ParentHasNewAlexDir(DirPath)) {
- X Result=AOLD;
- X }
- X }
- X if (NumLines==0) {
- X Log2("ERROR Could not read from ", AlexDirPath);
- X }
- X (void) AFCLOSE(ADfile);
- X } /* end of big skip if null ADfile */
- X } /* end of big skip for hosts only */
- X
- X#ifdef AT_DIR
- X if ((HostPtr==NULL) || (ADfile == NULL)) /* AT_DIR only sees hosts when no .alex.dir */
- X#endif
- X {
- X NextHost=OutputHostsBefore(AITmpFile, NextHost, DirPWS, DPWSlen, "~~~~~"); /* large ascii val */
- X }
- X
- X SaveInodeNext(); /* we may have allocated some new ones */
- X
- X Log("DirToInfo about to close tmpfile");
- X if (AFCLOSE(AITmpFile) < 0) {
- X ToLog(DBERROR, "DirToInfo ERROR close of tmpfile failed failed");
- X return(AFAIL);
- X }
- X
- X if (Result != AOK) {
- X LogT("DirToInfo returning early with ", Result);
- X return(Result);
- X }
- X
- X if (LiteStat(AlexInfo) == AFILE) { /* if an old then we will use it but if not */
- X (void) strcpy(AlexInfoOld, AlexInfo); /* careful now with two of same name */
- X } else {
- X (void) strcpy(AlexInfoOld, "/dev/null"); /* then we will use /dev/null */
- X }
- X
- X Log2("DirToInfo AlexInfoOld", AlexInfoOld);
- X LogT("DirToInfo intermediate Result", Result); /* must be AOK */
- X
- X Result=SortFile(AlexInfoTmp);
- X
- X if (Result == AOK) {
- X int PartsInHostName;
- X
- X if (HostPtr == NULL) {
- X PartsInHostName = 0;
- X } else {
- X PartsInHostName = HostPtr->PartsInHostName;
- X }
- X
- X LogN("DirToInfo PartsInHostName= ", PartsInHostName);
- X
- X Status=FixInodesAndRemoveOld(AlexInfoOld, AlexInfoTmp, AlexInfoNew, UidStr,
- X UpdateDate, NewestDate, TypeOfDir, PartsInHostName, AddAnyErrorStatus, HaveAlexDir);
- X if (Status != AOK) {
- X ToLog(DBERROR, "DirToInfo ERROR could not FixInodes %s\n", AlexInfo);
- X (void) unlink(AlexInfoTmp);
- X Result=AFAIL;
- X } else {
- X Log("DirToInfo think we have a good .alex.info.new");
- X Result=AOK;
- X
- X Status=unlink(AlexInfoTmp);
- X if (Status != AOK) {
- X ToLog(DBERROR, "DirToInfo ERROR could not unlink %s\n", AlexInfoTmp);
- X }
- X
- X if(rename(AlexInfoNew, AlexInfo)) { /* last is mv .alex.info.new .alex.info */
- X error2("DirToInfo ERROR could not rename .alex.info.new to ", AlexInfo);
- X Result=AFAIL;
- X }
- X }
- X }
- X
- X InvalidateStatCache=1;
- X
- X ToLog(DBFTP, "DirToInfo is returning %s\n", ATypeToString(Result));
- X return(Result);
- X}
- X
- X
- X
- END_OF_FILE
- if test 77292 -ne `wc -c <'alexsrvr/src/dirtoinfo.c'`; then
- echo shar: \"'alexsrvr/src/dirtoinfo.c'\" unpacked with wrong size!
- fi
- # end of 'alexsrvr/src/dirtoinfo.c'
- fi
- echo shar: End of archive 5 \(of 13\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 13 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-