Patch #: 197 Type: operational change Priority: none Modification: add support for fixed directory and file IDs Submitted: John Forrest Submitted: Scooter Morris Modification: add support for Digital UNIX enhanced security Submitted: Andrew Greer Submitted: Richard Rogers Modification: add support for Digital UNIX FDDI interface Submitted: Conrad Huang Modification: yet more minor fixes for Solaris 2.N Submitted: Andy Polyakov Submitted: Doug Scoular Submitted: Marc Boucher Submitted: Stephen Cliffe Submitted: Stephen Campbell Modification: make lwsrv -s option handling consistent Submitted: Dave Alden Modification: protect lwsrv spool files - set mode 0600 Submitted: Einar Indridason Modification: fix missing variable initialization in lwsrv Submitted: Ed Keizer Modification: rationalise check for multiple NBP tuples Submitted: Yoshiaki Irino Modification: fix for magic length range lock in MicroSoft apps Submitted: Norbert Hanke Submitted: Marc Boucher Modification: fix for papif argument handling Submitted: David Nyman Modification: minor fixes for ISO_TRANSLATE Submitted: Andy Polyakov Modification: minor fix for NONLXLATE Submitted: George V. Bouriakov Modification: fix portability bug in NCS code (affects DEC Alpha) Submitted: Salvatore Valente Modification: add PKillGetReq() equivalent for ATP Submitted: Rob Burrowes Modification: documentation fix Submitted: David Hornsby Submitted: Peter Torkelson Archived: munnari.OZ.AU mac/cap.patches/cap60.patch197 Application: 'cd cap60; patch -p < cap60.patches/cap60.patch197' File: cap60/Configure File: cap60/conf.func.lst File: cap60/netat/afp.h File: cap60/netat/afpcmd.h File: cap60/man/AUFS.1 File: cap60/man/AUFS.8 File: cap60/man/getzones.1 File: cap60/contrib/Makefile.m4 File: cap60/contrib/printqueue.c File: cap60/etc/start-cap-servers File: cap60/applications/aufs/Makefile.m4 File: cap60/applications/aufs/afps.h File: cap60/applications/aufs/afpntoh.h File: cap60/applications/aufs/afpfile.c File: cap60/applications/aufs/afpfid.c File: cap60/applications/aufs/afpdid.c File: cap60/applications/aufs/afpdir.c File: cap60/applications/aufs/afposncs.c File: cap60/applications/aufs/afpserver.c File: cap60/applications/aufs/afpos.c File: cap60/applications/aufs/aufs.c File: cap60/applications/aufs/afpid.notes File: cap60/applications/aufs/afpidlist.c File: cap60/applications/aufs/afpidsrvr.c File: cap60/applications/aufs/afpidtool.c File: cap60/applications/papif/papif.c File: cap60/applications/lwsrv/lwsrv.c File: cap60/lib/cap/abatp.h File: cap60/lib/cap/abatp.c File: cap60/lib/cap/abnbp.c File: cap60/lib/cap/abmisc.c File: cap60/lib/cap/abpapc.c File: cap60/lib/afp/Makefile.m4 File: cap60/lib/afp/afposlock.c File: cap60/lib/afp/afppacks.c File: cap60/lib/afp/afpidaufs.h File: cap60/lib/afp/afpidaufs.c File: cap60/lib/afp/afpidclnt.c File: cap60/lib/afp/afpidgnrl.c File: cap60/lib/afp/afpidnames.h File: cap60/lib/afpc/afpc.c File: cap60/lib/afpc/afpcc.c File: cap60/samples/ash.c File: cap60/samples/getzones.c File: cap60/support/ethertalk/aarpd.c File: cap60/support/ethertalk/abelap.c File: cap60/support/ethertalk/spfiltp.c *** Configure.orig Wed Aug 30 22:52:28 1995 --- Configure Tue Apr 30 14:20:19 1996 *************** *** 1,7 **** #!/bin/sh ! # $Author: djh $ $Date: 1995/08/30 12:52:13 $ ! # $Header: /mac/src/cap60/RCS/Configure,v 2.100 1995/08/30 12:52:13 djh Rel djh $ ! # $Revision: 2.100 $ # CAP configuration shell script. This ain't perfect, but it's a start. # Execute with /bin/sh Configure if your system won't run it (ksh is okay too) # --- 1,7 ---- #!/bin/sh ! # $Author: djh $ $Date: 1996/04/30 04:20:05 $ ! # $Header: /mac/src/cap60/RCS/Configure,v 2.105 1996/04/30 04:20:05 djh Rel djh $ ! # $Revision: 2.105 $ # CAP configuration shell script. This ain't perfect, but it's a start. # Execute with /bin/sh Configure if your system won't run it (ksh is okay too) # *************** *** 87,95 **** # sunos if [ -z "${osdefault}" ]; then echo "Checking for SunOS/Solaris" ! if [ -f /bin/sun ]; then ! /bin/sun 2>/dev/null >/dev/null ! if [ $? -eq 0 ]; then if [ -f /bin/uname ]; then if [ `uname -r` -ge "5.0" ]; then echo "Solaris" --- 87,94 ---- # sunos if [ -z "${osdefault}" ]; then echo "Checking for SunOS/Solaris" ! if [ -f /bin/uname ]; then ! if [ `uname -s` = "SunOS" ]; then if [ -f /bin/uname ]; then if [ `uname -r` -ge "5.0" ]; then echo "Solaris" *************** *** 917,922 **** --- 916,927 ---- # + ULTRIX_SECURITY adds ULTRIX enhanced security to aufs # define(`specialcflags',concat(specialcflags,` -DULTRIX_SECURITY')) # + # + DIGITAL_UNIX_SECURITY adds OSF/1 enhanced security to aufs + # define(`specialcflags',concat(specialcflags,` -DDIGITAL_UNIX_SECURITY')) + # + # + USING_FDDI_NET adds support for FDDI networks (Digital UNIX/Ultrix only) + # define(`specialcflags',concat(specialcflags,` -DUSING_FDDI_NET')) + # # + USE_MAC_DATES maintains Mac Create/Modify dates on file copy # define(`specialcflags',concat(specialcflags,` -DUSE_MAC_DATES')) # *************** *** 983,988 **** --- 988,996 ---- # # AUFS definable options (previously required editing m4.setup) # + # + FIXED_DIRIDS compile server and AUFS code for fixed directory & file IDs + # define(`specialcflags',concat(specialcflags,` -DFIXED_DIRIDS')) + # # + DISTRIB_PASSWDS use ~/.afppass for encrypted passwords (see CAP60.README) # define(`specialcflags',concat(specialcflags,` -DDISTRIB_PASSWDS')) # *************** *** 995,1000 **** --- 1003,1014 ---- # + DEBUG_AFP_CMD write detailed AUFS AFP debugging info to -Z specified file # define(`specialcflags',concat(specialcflags,` -DDEBUG_AFP_CMD')) # + # + PID_FILE write an aufs process-ID file + # define(`specialcflags',concat(specialcflags,` -DPID_FILE=\"aufs.pid\"')) + # + # + CLOSE_LOG_SIG close and reopen the aufs log on signal -USR2 + # define(`specialcflags',concat(specialcflags,` -DCLOSE_LOG_SIG=SIGUSR2')) + # # + LOG_WTMP add entry to the 'wtmp' file for each AUFS connection (not IRIX4) # define(`aufsosflags',concat(aufsosflags,` -DLOG_WTMP')) # *************** *** 1556,1561 **** --- 1570,1577 ---- define([libspecial],[]) ifelse(os,[ultrix40],[ define([libspecial],concat(libspecial,[ -lauth]))]) + ifelse(os,[osf1],[ + define([libspecial],concat(libspecial,[ -lsecurity]))]) ifelse(os,[xenix5],[ define([libspecial],concat(libspecial,[ -lsocket]))]) ifelse(os,[drsnx],[ *************** *** 1610,1616 **** # # lib/cap/authenticate.c: configuration file # ! define([authconfig],[[\"/etc/cap.auth\"]]) # # lwsrv: see applications/lwsrv/README --- 1626,1632 ---- # # lib/cap/authenticate.c: configuration file # ! define([authconfig],concat([\"],etcdest,[/],[cap.auth],[\"])) # # lwsrv: see applications/lwsrv/README *** conf.func.lst.orig Mon Oct 10 18:54:22 1994 --- conf.func.lst Mon Mar 11 14:59:10 1996 *************** *** 1,6 **** ! # $Author: djh $ $Date: 1994/10/10 08:54:05 $ ! # $Header: /mac/src/cap60/RCS/conf.func.lst,v 2.8 1994/10/10 08:54:05 djh Rel djh $ ! # $Revision: 2.8 $ # # see Conf.func.sh for format of file # --- 1,6 ---- ! # $Author: djh $ $Date: 1996/03/11 03:58:55 $ ! # $Header: /mac/src/cap60/RCS/conf.func.lst,v 2.9 1996/03/11 03:58:55 djh Rel djh $ ! # $Revision: 2.9 $ # # see Conf.func.sh for format of file # *************** *** 14,19 **** --- 14,20 ---- N+-,STATFS,/usr/include/sys/mount.h,statfs,"aufs: info on file systems (bsd44)" E,STATFS,x,x,"aufs: no space information on volumes will be available" N+-,QUOTA,/usr/include/sys/quota.h,quota,"aufs: info on user quota" + N+-,QUOTA,/usr/include/sys/fs/ufs_quota.h,quota,"aufs: info on user quota (solaris)" E,QUOTA,x,x,"aufs: no information on user quotas" A+,SUNQUOTA,/usr/include/ufs/quota.h,quotactl,"aufs: info on user quota" N+-,SUNQUOTA,/usr/include/mntent.h,getmntent,"aufs: used by sunquota" *** netat/afp.h.orig Mon Jan 31 10:20:38 1994 --- netat/afp.h Thu Apr 25 11:06:42 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1994/01/30 23:20:31 $ ! * $Header: /mac/src/cap60/netat/RCS/afp.h,v 2.4 1994/01/30 23:20:31 djh Rel djh $ ! * $Revision: 2.4 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 01:06:27 $ ! * $Header: /mac/src/cap60/netat/RCS/afp.h,v 2.5 1996/04/25 01:06:27 djh Rel djh $ ! * $Revision: 2.5 $ * */ *************** *** 111,117 **** --- 111,121 ---- #define AFPChgPasswd 36 /* AFP2.0: Change Password */ #define AFPGetUserInfo 37 /* AFP2.0: Get User Information */ #define AFPGetSrvrMsg 38 /* AFP2.1: Get Server Message */ + #define AFPCreateID 39 /* AFP2.1: Create a File ID */ + #define AFPDeleteID 40 /* AFP2.1: Invalidate a File ID */ + #define AFPResolveID 41 /* AFP2.1: Get params for a file by File ID */ #define AFPExchangeFiles 42 /* AFP2.1: Exchange 2 files Data/Resource */ + #define AFPCatSearch 43 /* AFP2.1: Search volume for files */ #define AFPOpenDT 48 /* Open the volume's desktop database */ #define AFPCloseDT 49 /* Close the volume's desktop database */ #define AFPGetIcon 51 /* Get an icon from the dt database */ *** netat/afpcmd.h.orig Mon Jun 19 11:33:21 1995 --- netat/afpcmd.h Thu Apr 25 11:25:20 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/06/19 01:33:09 $ ! * $Header: /mac/src/cap60/netat/RCS/afpcmd.h,v 2.5 1995/06/19 01:33:09 djh Rel djh $ ! * $Revision: 2.5 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 01:24:27 $ ! * $Header: /mac/src/cap60/netat/RCS/afpcmd.h,v 2.6 1996/04/25 01:24:27 djh Rel djh $ ! * $Revision: 2.6 $ * */ *************** *** 633,638 **** --- 633,668 ---- word msgr_bitmap; /* bitmap */ byte msgr_data[SRVRMSGLEN]; /* message string */ } SrvrMsgReplyPkt, *SrvrMsgReplyPtr; + + typedef struct { /* FPCreateID */ + byte crid_cmd; /* command */ + byte crid_zero; /* always zero */ + word crid_volid; /* volume ID */ + sdword crid_dirid; /* directory ID */ + byte crid_ptype; /* path type */ + byte crid_path[MAXPATH]; /* path */ + } CreateIDPkt, *CreateIDPtr; + + typedef struct { /* FPDeleteID */ + byte did_cmd; /* command */ + byte did_zero; /* always zero */ + word did_volid; /* volume ID */ + sdword did_fileid; /* file ID */ + } DeleteIDPkt, *DeleteIDPtr; + + typedef struct { /* FPResolveID */ + byte rid_cmd; /* command */ + byte rid_zero; /* always zero */ + word rid_volid; /* volume ID */ + sdword rid_fileid; /* file id */ + word rid_fbitmap; /* result bitmap */ + } ResolveIDPkt, *ResolveIDPtr; + + typedef struct { /* FPResolveID Reply */ + word ridr_fbitmap; /* result bitmap */ + /* followed by packed parms */ + } ResolveIDReplyPkt, *ResolveIDRPtr; + typedef struct { int pe_typ; /* type of data */ *** man/AUFS.1.orig Mon Jun 19 11:33:51 1995 --- man/AUFS.1 Tue Apr 30 20:24:24 1996 *************** *** 42,47 **** --- 42,48 ---- subdirectory and make the same subdirectories again. For example: .br + .sp .I % mkdir mac .br *************** *** 54,59 **** --- 55,61 ---- .I % mkdir .finderinfo .resource .br + .sp The top level .finderinfo directory is used to store information about the volume window size, position and layout. You can do without the top level .finderinfo and .resource *************** *** 67,75 **** --- 69,79 ---- in your home directory to designate your Macintosh directory, with a line like: .br + .sp .I ~/mac:UNIX_mac_files: .br + .sp where the part before the colon is the UNIX pathname (here relative to my home directory) and the part after is the volume name that the Macintosh will use and display. *************** *** 183,204 **** --- 187,213 ---- AUFS volume "mac", it could be seen in the UNIX file system as the three files: .br + .sp ~/mac/MacWrite .br ~/mac/.resource/MacWrite .br ~/mac/.finderinfo/MacWrite + .br + .sp .PP Macintosh folders are simply mapped to UNIX subdirectories. For example, if the AUFS volume "mac" contained the folder "paintings", the UNIX directory ~/mac would contain additional subdirectories .br + .sp ~/mac/paintings .br ~/mac/paintings/.resource .br ~/mac/paintings/.finderinfo .br + .sp Finder information for the folder itself is stored in the parent UNIX directory .finderinfo subdirectory, but folders have no resource fork. *************** *** 215,221 **** periodically delete them with the UNIX .I rm command (when the volume is not mounted) and rebuild your desktop ! the next time the volume is mounted. .PP The AFP protocol does not handle file protections. Instead, it implements a limited set of directory protections. --- 224,230 ---- periodically delete them with the UNIX .I rm command (when the volume is not mounted) and rebuild your desktop ! with the 'builddt' command in the contrib/DeskTop directory. .PP The AFP protocol does not handle file protections. Instead, it implements a limited set of directory protections. *************** *** 259,271 **** --- 268,284 ---- Each directory that is to be mountable by AUFS is represented in this file by a single line with the following format: .br + .sp UNIX_path_name:Macintosh_volume_name[:optional_password] .br + .sp For example, I could create the subdirectory "mac" in my UNIX home directory and then include this line in my "afpvols" file: .br + .sp ~/mac:UNIX_mac_files .br + .sp If you do not have an afpvols file in your home directory, your home directory will be made available for mounting by default. .PP *************** *** 383,407 **** systems, stick to file names of 31 characters or less, using only letters, numbers, period, underscore, and hyphen. .SH LOCAL CONFIGURATION ! .SH KNOWN BUGS DeskTop files grow without bounds. The only way to prune them is to delete them from the UNIX side ! and rebuild the desktop from the Macintosh. .PP Applications mappings in the DeskTop files can quickly get out of sync with reality. Not enough information is stored to keep everything in sync, and it would be costly to recover anyway if available. Problems may occur when you move around directories holding applications. ! A work-around is to delete and rebuild the DeskTop files. .PP The file creator "unix" and the file type "TEXT" are not registered with Apple. .PP - Deny read/write interlocking is not implemented. - This is generally not necessary with UNIX file protections. - .PP You cannot change the owner of a file; thus drop folders do not work well. .PP --- 396,420 ---- systems, stick to file names of 31 characters or less, using only letters, numbers, period, underscore, and hyphen. .SH LOCAL CONFIGURATION ! .br ! .sp .SH KNOWN BUGS DeskTop files grow without bounds. The only way to prune them is to delete them from the UNIX side ! and rebuild the desktop using the 'builddt' command in the contrib/DeskTop ! directory. .PP Applications mappings in the DeskTop files can quickly get out of sync with reality. Not enough information is stored to keep everything in sync, and it would be costly to recover anyway if available. Problems may occur when you move around directories holding applications. ! A work-around is to delete and rebuild the DeskTop files as described ! above. .PP The file creator "unix" and the file type "TEXT" are not registered with Apple. .PP You cannot change the owner of a file; thus drop folders do not work well. .PP *************** *** 425,435 **** .PP Specifications for the Macintosh Hierarchical Filing System and AppleShare require that directory ids be fixed across the lifetime of a volume, and ! not be reused. ! AUFS breaks this rule; directory ids are unique only for a particular ! session. ! Some programs store away directory ids; unexpected things (probably not ! fatal) may happen when you use such programs with AUFS. .PP In a directory used as an AUFS volume, path names can get very long. Some implementations of the UNIX --- 438,445 ---- .PP Specifications for the Macintosh Hierarchical Filing System and AppleShare require that directory ids be fixed across the lifetime of a volume, and ! not be reused. Code to implement fixed directory ids is only included by ! setting the FIXED_DIRIDS flag in the features file at Configure time. .PP In a directory used as an AUFS volume, path names can get very long. Some implementations of the UNIX *** man/AUFS.8.orig Fri Jun 30 14:46:47 1995 --- man/AUFS.8 Tue Apr 30 20:41:05 1996 *************** *** 322,329 **** If the parent process receives SIGUSR1, it will re-read the global afpvols volume configuration file (this option requires that REREAD_AFPVOLS be defined at configuration time). .SH LOCAL CONFIGURATION ! .SH BUGS AND NOTES There are no known bugs in the code, but it is recognized that the DeskTop management is less than optimial. --- 322,336 ---- If the parent process receives SIGUSR1, it will re-read the global afpvols volume configuration file (this option requires that REREAD_AFPVOLS be defined at configuration time). + .TP 15 + .B SIGUSR2 + Sending a SIGUSR2 signal to the AUFS parent process causes it to close and + then reopen the specified log file. This allows log files to be truncated + at intervals (this option requires that CLOSE_LOG_SIG be used to define + the signal name - default SIGUSR2 - at configuration time). .SH LOCAL CONFIGURATION ! .br ! .sp .SH BUGS AND NOTES There are no known bugs in the code, but it is recognized that the DeskTop management is less than optimial. *** man/getzones.1.orig Mon Aug 9 00:09:17 1993 --- man/getzones.1 Tue Apr 30 19:14:22 1996 *************** *** 10,15 **** --- 10,17 ---- ] [ .BI \-m ] [ + .BI \-s + ] [ .BI \-v ] .SH DESCRIPTION *************** *** 35,40 **** --- 37,45 ---- .TP .BI \-m print the zone name for this host (myZone). + .TP + .BI \-s + sort the zones list. .TP .BI \-v produces a more verbose output including a zone count and *** contrib/Makefile.m4.orig Tue Jun 20 18:57:11 1995 --- contrib/Makefile.m4 Mon Mar 11 15:10:15 1996 *************** *** 38,44 **** ${CC} ${CFLAGS} ${RENAMEFLAG} -c lwrename.c printqueue: printqueue.o ! ${CC} ${LFLAGS} -o printqueue printqueue.o ${O} ${CAPLIB} ${SLIB} aufsmkusr: aufsmkusr.o ${CC} ${LFLAGS} -o aufsmkusr aufsmkusr.o ${O} ${AFPLIB} ${SLIB} --- 38,44 ---- ${CC} ${CFLAGS} ${RENAMEFLAG} -c lwrename.c printqueue: printqueue.o ! ${CC} ${LFLAGS} -o printqueue printqueue.o ${O} ${CAPLIB} ${AFPLIB} ${SLIB} aufsmkusr: aufsmkusr.o ${CC} ${LFLAGS} -o aufsmkusr aufsmkusr.o ${O} ${AFPLIB} ${SLIB} *** contrib/printqueue.c.orig Wed Jun 28 12:15:10 1995 --- contrib/printqueue.c Mon Mar 11 15:17:22 1996 *************** *** 299,310 **** tobds("Warning: \"%s\" is down: ", printer); fd = open(status, O_RDONLY); if (fd >= 0) { ! #if !(defined(SOLARIS) || defined(hpux)) ! (void) flock(fd, LOCK_SH); ! #endif /* SOLARIS || hpux */ while ((i = read(fd, line, BUFSIZ)) > 0) writebds(line, i); ! (void) close(fd); /* unlocks as well */ } else writebds("\n", 1); } --- 299,309 ---- tobds("Warning: \"%s\" is down: ", printer); fd = open(status, O_RDONLY); if (fd >= 0) { ! OSLockFileforRead(fd); while ((i = read(fd, line, BUFSIZ)) > 0) writebds(line, i); ! OSUnlockFile(fd); ! (void) close(fd); } else writebds("\n", 1); } *************** *** 338,349 **** */ fd = open(status, O_RDONLY); if (fd >= 0) { ! #if !(defined(SOLARIS) || defined(hpux)) ! (void) flock(fd, LOCK_SH); ! #endif /* SOLARIS || hpux */ while ((i = read(fd, line, BUFSIZ)) > 0) writebds(line, i); ! (void) close(fd); /* unlocks as well */ } else writebds("\n", 1); } --- 337,347 ---- */ fd = open(status, O_RDONLY); if (fd >= 0) { ! OSLockFileforRead(fd); while ((i = read(fd, line, BUFSIZ)) > 0) writebds(line, i); ! OSUnlockFile(fd); ! (void) close(fd); } else writebds("\n", 1); } *** etc/start-cap-servers.orig Thu Feb 28 23:43:52 1991 --- etc/start-cap-servers Tue Apr 30 18:58:30 1996 *************** *** 11,25 **** LWARGS="-a ${LIB}/procsets -f ${LIB}/LW+Fonts" # ! # Start UAB first if used # ! # /usr/local/cap/uab # sleep 10 # # Otherwise start aarpd first for Native EtherTalk # ! # /usr/local/cap/aarpd "interface" "zone" # # allow atis to startup before other CAP programs --- 11,25 ---- LWARGS="-a ${LIB}/procsets -f ${LIB}/LW+Fonts" # ! # Start UAR first if used # ! # ${CAP}/uar -C "interface" # sleep 10 # # Otherwise start aarpd first for Native EtherTalk # ! # ${CAP}/aarpd "interface" "zone" # # allow atis to startup before other CAP programs *************** *** 32,36 **** sleep 5 ${CAP}/snitch -S -f "SUN 4 SunOS 4.0 UNIX" -l lwsrv - ${CAP}/aufs -U 20 -V ${LIB}/afpvols -l ${LOGf} -n `hostname` ${CAP}/lwsrv -n "Technical Services Spool" -p lw.tsa ${LWARGS} --- 32,40 ---- sleep 5 ${CAP}/snitch -S -f "SUN 4 SunOS 4.0 UNIX" -l lwsrv ${CAP}/lwsrv -n "Technical Services Spool" -p lw.tsa ${LWARGS} + + # if CAP compiled with FIXED_DIRIDS then start AFP ID server first + # ${CAP}/afpidsrvr -l ${LOGd}/afpidsrvr.log + + ${CAP}/aufs -U 20 -V ${LIB}/afpvols -l ${LOGf} -n `hostname` *** applications/aufs/Makefile.m4.orig Tue Oct 11 16:56:05 1994 --- applications/aufs/Makefile.m4 Sat Apr 27 23:12:01 1996 *************** *** 48,62 **** afpmisc.c afpserver.c aufsicon.c abmisc2.c \ afpdt.c afpdid.c afposenum.c afpavl.c \ afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \ ! afpudb.c afposncs.c afpspd.c OBJS=afpos.o afpvols.o afpfile.o \ afpmisc.o afpserver.o aufsicon.o abmisc2.o \ afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \ afposfi.o afpgc.o afppasswd.o aufsv.o \ ! afpudb.o afposncs.o afpspd.o SYMLINKS=att_getopt.c ! all: aufs sizeserver aufs: aufs.o $(OBJS) $(CAPFILES) ${RENAME} $(GETOPT) ${CC} $(LFLAGS) -o aufs aufs.o $(OBJS) $(CAPFILES) ${RENAME} \ --- 48,62 ---- afpmisc.c afpserver.c aufsicon.c abmisc2.c \ afpdt.c afpdid.c afposenum.c afpavl.c \ afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \ ! afpudb.c afposncs.c afpspd.c afpfid.c OBJS=afpos.o afpvols.o afpfile.o \ afpmisc.o afpserver.o aufsicon.o abmisc2.o \ afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \ afposfi.o afpgc.o afppasswd.o aufsv.o \ ! afpudb.o afposncs.o afpspd.o afpfid.o SYMLINKS=att_getopt.c ! all: aufs sizeserver afpidsrvr afpidlist afpidtool aufs: aufs.o $(OBJS) $(CAPFILES) ${RENAME} $(GETOPT) ${CC} $(LFLAGS) -o aufs aufs.o $(OBJS) $(CAPFILES) ${RENAME} \ *************** *** 68,73 **** --- 68,85 ---- sizeserver.o: sizeserver.c sizeserver.h ${CC} ${OSDEFS} ${CFLAGS} -c sizeserver.c + afpidsrvr: afpidsrvr.c ../../lib/afp/afpidaufs.h + ${CC} ${OSDEFS} ${CFLAGS} -o afpidsrvr afpidsrvr.c \ + ${GETOPT} ${AFPLIB} ${SLIB} + + afpidlist: afpidlist.c ../../lib/afp/afpidaufs.h + ${CC} ${OSDEFS} ${CFLAGS} -o afpidlist afpidlist.c \ + ${GETOPT} ${AFPLIB} ${SLIB} + + afpidtool: afpidtool.c ../../lib/afp/afpidaufs.h + ${CC} ${OSDEFS} ${CFLAGS} -o afpidtool afpidtool.c \ + ${GETOPT} ${AFPLIB} ${SLIB} + newver: /bin/sh aufs_vers.sh `cat aufs_vers` aufs_vers aufsv.c make all *************** *** 76,85 **** /bin/sh aufs_vers.sh `cat aufs_vers` useold aufsv.c clean: ! -rm -f *.o aufs sizeserver ${SYMLINKS} spotless: ! -rm -f *.o *.orig aufs sizeserver ${SYMLINKS} Makefile makefile lint: aufs.c $(SRCS) lint aufs.c $(SRCS) --- 88,98 ---- /bin/sh aufs_vers.sh `cat aufs_vers` useold aufsv.c clean: ! -rm -f *.o aufs sizeserver afpidsrvr afpidlist afpidtool ${SYMLINKS} spotless: ! -rm -f *.o *.orig aufs sizeserver afpidsrvr afpidlist afpidtool \ ! ${SYMLINKS} Makefile makefile lint: aufs.c $(SRCS) lint aufs.c $(SRCS) *************** *** 91,96 **** --- 104,112 ---- -strip sizeserver ifdef([sysvinstall],[install -f $(DESTDIR) sizeserver], [${INSTALLER} sizeserver $(DESTDIR)]) + -strip afpidsrvr afpidlist afpidtool + ifdef([sysvinstall],[install -f $(DESTDIR) afpidsrvr afpidlist afpidtool], + [${INSTALLER} afpidsrvr afpidlist afpidtool $(DESTDIR)]) dist: @cat todist *** applications/aufs/afps.h.orig Mon Oct 10 19:02:25 1994 --- applications/aufs/afps.h Wed May 1 00:41:30 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1994/10/10 09:02:04 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afps.h,v 2.8 1994/10/10 09:02:04 djh Rel djh $ ! * $Revision: 2.8 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/30 14:41:04 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afps.h,v 2.10 1996/04/30 14:41:04 djh Rel djh $ ! * $Revision: 2.10 $ * */ *************** *** 45,50 **** --- 45,51 ---- OSErr FPChgPasswd(), FPGetUserInfo(); /* afp2.1 */ OSErr FPExchangeFiles(), FPGetSrvrMsg(); + OSErr FPCreateID(), FPDeleteID(), FPResolveID(); /* abafpserver.c */ *************** *** 192,200 **** /* Portable library functions */ ! #ifndef AIX char *malloc(),*strcpy(),*strcat(),*realloc(); ! #endif AIX /* defined here so that enumerate can skip these entries when reading dirs */ --- 193,201 ---- /* Portable library functions */ ! #if (!(defined(AIX) || defined(hpux))) char *malloc(),*strcpy(),*strcat(),*realloc(); ! #endif /* AIX || hpux */ /* defined here so that enumerate can skip these entries when reading dirs */ *** applications/aufs/afpntoh.h.orig Mon Jun 19 11:32:29 1995 --- applications/aufs/afpntoh.h Thu Apr 25 13:16:13 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/06/19 01:32:20 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpntoh.h,v 2.4 1995/06/19 01:32:20 djh Rel djh $ ! * $Revision: 2.4 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 03:15:24 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpntoh.h,v 2.5 1996/04/25 03:15:24 djh Rel djh $ ! * $Revision: 2.5 $ * */ *************** *** 87,92 **** --- 87,98 ---- #define PsSetFileDirParms ProtoSFDPP extern PackEntry ProtoMsgP[]; /* 38 GetSrvrMsg */ #define PsGetSrvrMsg ProtoMsgP + extern PackEntry ProtoCreateID[]; /* 39 CreateID */ + #define PsCreateID ProtoCreateID + extern PackEntry ProtoDelID[]; /* 40 DeleteID */ + #define PsDelID ProtoDelID + extern PackEntry ProtoRslvID[]; /* 41 ResolveID */ + #define PsRslvID ProtoRslvID extern PackEntry ProtoExP[]; /* 42 ExchangeFiles */ #define PsExchange ProtoExP extern PackEntry ProtoODT[]; /* 48 OpenDT */ *** applications/aufs/afpfile.c.orig Mon Jun 12 16:58:51 1995 --- applications/aufs/afpfile.c Mon Apr 29 18:22:25 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/06/12 06:58:18 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpfile.c,v 2.5 1995/06/12 06:58:18 djh Rel djh $ ! * $Revision: 2.5 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/29 08:21:55 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpfile.c,v 2.9 1996/04/29 08:21:55 djh Rel djh $ ! * $Revision: 2.9 $ * */ *************** *** 158,163 **** --- 158,340 ---- return(err); } + #ifdef FIXED_DIRIDS + /* + * OSErr FPCreateID(byte *p,byte *r,int *rl) + * + * This call is used to create a file ID. + * + */ + + + /*ARGSUSED*/ + OSErr + FPCreateID(p,l,r,rl) + byte *p,*r; + int l,*rl; + { + CreateIDPkt crid; + int ivol,delf,err; + IDirP idir,ipdir; + char file[MAXUFLEN]; + sdword fileID; + + ntohPackX(PsCreateID,p,l,(byte *) &crid); + + err = EtoIfile(file,&idir,&ipdir,&ivol,crid.crid_dirid, + crid.crid_volid,crid.crid_ptype,crid.crid_path); + + if (err == noErr) + fileID = aufsExtEFileId(ipdir->edirid, file); + #ifdef DEBUG_AFP_CMD + if (dbg != NULL) { + void dbg_print_path(); + fprintf(dbg, "\tVolID: %04x\n", crid.crid_volid); + fprintf(dbg, "\tDirID: %08x\n", crid.crid_dirid); + fprintf(dbg, "\tPType: %d\t(%s Names)\n", crid.crid_ptype, + (crid.crid_ptype == 1) ? "Short" : "Long"); + dbg_print_path(crid.crid_path); + if (err == noErr) + fprintf(dbg, "\tUPath: \"%s/%s\"\n", pathstr(ipdir), file); + else + fprintf(dbg, "\tUPath: \n", err); + fprintf(dbg, "\tFileID: %08x\n", fileID); + fflush(dbg); + } + #endif /* DEBUG_AFP_CMD */ + + + if ((err != noErr) && (DBFIL)) + printf("error returned from EtoIfile\n"); + PackDWord(fileID,r); + *rl = 4; + return(noErr); + } + + /* + * OSErr FPResolveID(byte *p,byte *r,int *rl) + * + * This call is used to resolve a file ID. + * + */ + + + /*ARGSUSED*/ + OSErr + FPResolveID(p,l,r,rl) + byte *p,*r; + int l,*rl; + { + ResolveIDPkt rid; + int ivol,delf,err; + IDirP idir,ipdir; + FileDirParm fdp; + char file[MAXUFLEN]; + sdword fileID; + char *path, *filep; + extern char *strrchr(); + extern char *aufsExtPath(); + + idir = NULL; + + ntohPackX(PsRslvID,p,l,(byte *) &rid); + + #ifdef DEBUG_AFP_CMD + if (dbg != NULL) { + fprintf(dbg, "\tVolID: %04x\n", rid.rid_volid); + fprintf(dbg, "\tFilID: %04x\n", rid.rid_fileid); + fprintf(dbg, "\tFBMap: %04x\t", rid.rid_fbitmap); + dbg_print_bmap(rid.rid_fbitmap, 0); + fflush(dbg); + } + #endif /* DEBUG_AFP_CMD */ + + /* + * get the path from the database + */ + if ((path = aufsExtPath(rid.rid_fileid)) == NULL) + return(aeIDNotFound); + + #ifdef DEBUG_AFP_CMD + if (dbg != NULL) { + fprintf(dbg, "\tFName: %s\n", path); + fflush(dbg); + } + #endif /* DEBUG_AFP_CMD */ + + /* + * devide into file and dir + */ + filep = strrchr(path, '/'); + if (filep) + *filep++ = '\0'; + + /* + * get the Volume ID + */ + ivol = EtoIVolid(rid.rid_volid); /* set internal volid */ + + /* + * get the directory ID + */ + ipdir = Idirid(path); + + /* + * call OSFileDirInfo + */ + fdp.fdp_pdirid = ItoEdirid(ipdir,ivol); + fdp.fdp_dbitmap = 0; + fdp.fdp_fbitmap = rid.rid_fbitmap; + fdp.fdp_zero = 0; + err = OSFileDirInfo(ipdir,idir,filep,&fdp,ivol); /* fill in information */ + if (err != noErr) { + if (DBFIL) + printf("FPResolveID: OSFileDirInfo returns %d on %s/%s\n", + err,pathstr(ipdir),file); + return(err); + } + PackWord(rid.rid_fbitmap,r); + *rl = 2; + *rl += htonPackX(FilePackR,(byte *) &fdp,r+(*rl)); + + #ifdef DEBUG_AFP_CMD + if (dbg != NULL) { + void dbg_print_parm(); + void dbg_print_bmap(); + fprintf(dbg, " Return Parameters:\n"); + fprintf(dbg, "\tFBMap: %04x\t", fdp.fdp_fbitmap); + dbg_print_bmap(fdp.fdp_fbitmap, 0); + fprintf(dbg, "\tFDFlg: %02x\t(%s)\n", fdp.fdp_flg, + FDP_ISDIR(fdp.fdp_flg) ? "Directory" : "File"); + if (*rl == 2) + fprintf(dbg, "\t\n"); + else + dbg_print_parm(fdp.fdp_fbitmap, r+2, (*rl)-2, 0); + fflush(dbg); + } + #endif /* DEBUG_AFP_CMD */ + + return(noErr); + } + + + /* + * OSErr FPDeleteID(byte *p,byte *r,int *rl) + * + * This call is used to delete a file ID. + * + */ + + + /*ARGSUSED*/ + OSErr + FPDeleteID(p,l,r,rl) + byte *p,*r; + int l,*rl; + { + return(aeParamErr); + } + #endif /* FIXED_DIRIDS */ /* * FPCopyFile(byte *p,byte *r,int *rl) [NOP] *************** *** 532,539 **** err = OSExchangeFiles(aipdir,afile,bipdir,bfile); ! if (err == noErr) /* if success */ VolModified(ivol); /* then volume modified */ return(err); } --- 709,725 ---- err = OSExchangeFiles(aipdir,afile,bipdir,bfile); ! if (err == noErr) { /* if success */ VolModified(ivol); /* then volume modified */ + #ifdef FIXED_DIRIDS + { + char a_path[MAXPATHLEN], b_path[MAXPATHLEN]; + sprintf(a_path, "%s/%s", pathstr(aipdir),afile); + sprintf(b_path, "%s/%s", pathstr(bipdir),bfile); + aufsExtExchange(a_path, b_path); + } + #endif /* FIXED_DIRIDS */ + } return(err); } *** applications/aufs/afpfid.c.orig Thu Apr 25 11:36:50 1996 --- applications/aufs/afpfid.c Sat Apr 27 22:03:24 1996 *************** *** 0 **** --- 1,99 ---- + /* + * $Author: djh $ $Date: 1996/04/27 12:03:04 $ + * $Header: /mac/src/cap60/applications/aufs/RCS/afpfid.c,v 2.2 1996/04/27 12:03:04 djh Rel djh $ + * $Revision: 2.2 $ + * + */ + + /* + * afpfid.c - File ID routines + * + * AppleTalk package for UNIX (4.2 BSD). + * + * Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University in the + * City of New York. + * + * Edit History: + * + * September 1995 scooter Created + * + */ + + #include + #include + #include + #ifndef _TYPES + /* assume included by param.h */ + # include + #endif _TYPES + #include + #include + #include + #include "afps.h" + + #ifdef FIXED_DIRIDS + #include "../../lib/afp/afpidaufs.h" + #endif /* FIXED_DIRIDS */ + + /* + * FIdmove(IDirP fpdir, char *from, IDirP tpdir, char *to) + * + * Maintains consistency in database structures when a file + * is renamed or moved. + * + * The file "from" in parent fpdir is being renamed to be + * "to" in the parent tpdir. Because file ids may not + * change we must modify the tree instead of recreating nodes. + * + */ + + #ifndef FIXED_DIRIDS + void + FIdmove(fpdir,from,tpdir,to) + IDirP fpdir,tpdir; + char *from,*to; + { + return; + } + #else /* FIXED_DIRIDS */ + void + FIdmove(fpdir,from,tpdir,to) + IDirP fpdir,tpdir; + char *from,*to; + { + IDirP fdir; + sdword toEid, fileID; + char path[MAXUFLEN]; + + #ifdef SHORT_NAMES + if (DBFIL && fpdir != NULL) + printf("FIdmove fpdir->name %s, tpdir->name %s, from %s, to %s\n",fpdir->name, tpdir->name, from, to); + #endif SHORT_NAMES + + if (DBFIL) { + printf("FIdmove: changing path=%s, file=%s",pathstr(fpdir),from); + if (tpdir == fpdir) + printf(" to new name %s\n",to); + else + printf(" to path=%s, file=%s\n",pathstr(tpdir),to); + } + + sprintf(path, "%s/%s", pathstr(fpdir), from); + + /* Look up from to see if we have a FileID */ + if ((fileID = aufsExtFindId(path)) < 0) { + if (DBFIL) + printf("FIdmove: no ID for %s/%s",pathstr(fpdir),from); + return; /* Nope, we're done */ + } + + /* We've got one, now rename it! */ + + if (fpdir != tpdir) { /* if different parents then... */ + toEid = Edirid(tpdir); + aufsExtMoveIds(fileID, toEid, to); + } else { /* effectively a rename */ + aufsExtRenameId(fileID, to); + } + } + #endif FIXED_DIRIDS *** applications/aufs/afpdid.c.orig Mon Oct 10 19:02:14 1994 --- applications/aufs/afpdid.c Sat Apr 27 22:03:22 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1994/10/10 09:02:04 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpdid.c,v 2.11 1994/10/10 09:02:04 djh Rel djh $ ! * $Revision: 2.11 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/27 12:03:04 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpdid.c,v 2.13 1996/04/27 12:03:04 djh Rel djh $ ! * $Revision: 2.13 $ * */ *************** *** 76,81 **** --- 76,100 ---- private IDirP rootd; + #ifdef FIXED_DIRIDS + /* + * We use a separate database and server to provide persistant + * external numbers. This allows the external ids to be + * common accross several instances of aufs - coincidental ones + * as well as repeated calls by the same user. The database + * is read-only from this program - a separate aufsExt server + * is used to create new entries etc. Some backup functions in + * the library allow for when the server or database are (for + * some reason) absent or not responding. However, these should + * not be used normally. The scheme below is preferable if you + * don't wish to have the server running. + * + */ + + #include "../../lib/afp/afpidaufs.h" + + #else FIXED_DIRIDS + /* * ExtDir structure maps external directory numbers into internal (IDir) * pointers. It is not a good idea to simply pass back the IDir pointer *************** *** 97,102 **** --- 116,123 ---- int xd_idsize; /* size of idirs array */ } ExtDir; + #endif FIXED_DIRIDS + private char *ipathstr(); private sdword NewEDirid(); *************** *** 241,246 **** --- 262,291 ---- return(p); } + #ifdef FIXED_DIRIDS + /* + * dir path and filename concatanated + * + */ + + private char * + filpathstr(cd, name) + IDirP cd; + char *name; + { + char *p; + int len; + + p = pathstr(cd); /* get dir path */ + len = strlen(p); + if (p[len-1] != '/') /* add / if needs */ + p[len++] = '/'; + strcpy(p+len, name); /* add given name */ + lastcd = NILDIR; /* have corrupted cd area */ + return p; + } + #endif FIXED_DIRIDS + /* * return a path relative to vroot * *************** *** 296,305 **** --- 341,354 ---- void InitDID() { + #ifdef FIXED_DIRIDS + aufsExtInit(); + #else FIXED_DIRIDS ExtDir.xd_count = 0; /* no known external dirs */ ExtDir.xd_base = 320; /* anything will do above EROOTD */ ExtDir.xd_idsize = 100; /* inital size of table */ ExtDir.xd_idirs = (IDirP *) malloc(sizeof(IDirP)*100); + #endif FIXED_DIRIDS rootd = mkdirset(NILDIR,""); /* allocate root directory */ } *************** *** 436,463 **** * */ private sdword NewEDirid(idir) IDirP idir; { - sdword edir; - #ifdef SHORT_NAMES if (DBDIR && idir != NULL) printf("NewEDirid idir->name %s\n",idir->name); #endif SHORT_NAMES ! if (ExtDir.xd_count >= ExtDir.xd_idsize) { ! ExtDir.xd_idirs = (IDirP *) /* realloc larger table */ ! realloc((char *) ExtDir.xd_idirs, ! sizeof(IDirP)*((unsigned) ExtDir.xd_idsize+100)); ! ExtDir.xd_idsize += 100; /* larger table now */ ! if (DBDIR) ! printf("NewEDirid: Realloc occured.\n"); } ! edir = ExtDir.xd_count; /* current counter is idx */ ! ExtDir.xd_count++; /* increment count */ ! ExtDir.xd_idirs[edir] = idir; /* save new handle */ ! return(ExtDir.xd_base+edir); /* return base + idx */ } /* --- 485,535 ---- * */ + #ifdef FIXED_DIRIDS + sdword + Edirid(idir) + IDirP idir; + { + if (idir == rootd) /* shortcut */ + return(rootEid); + else { + if (idir->edirid == -1) + idir->edirid = NewEDirid(idir); + return(idir->edirid); + } + } + #endif FIXED_DIRIDS + private sdword NewEDirid(idir) IDirP idir; { #ifdef SHORT_NAMES if (DBDIR && idir != NULL) printf("NewEDirid idir->name %s\n",idir->name); #endif SHORT_NAMES ! #ifdef FIXED_DIRIDS ! if (idir == rootd) ! return(rootEid); /* root has no parent! */ ! return(aufsExtEDirId(Edirid(idir->pdir), idir->name)); ! #else FIXED_DIRIDS ! { ! sdword edir; ! ! if (ExtDir.xd_count >= ExtDir.xd_idsize) { ! ExtDir.xd_idirs = (IDirP *) /* realloc larger table */ ! realloc((char *) ExtDir.xd_idirs, ! sizeof(IDirP)*((unsigned) ExtDir.xd_idsize+100)); ! ExtDir.xd_idsize += 100; /* larger table now */ ! if (DBDIR) ! printf("NewEDirid: Realloc occured.\n"); ! } ! edir = ExtDir.xd_count; /* current counter is idx */ ! ExtDir.xd_count++; /* increment count */ ! ExtDir.xd_idirs[edir] = idir; /* save new handle */ ! return(ExtDir.xd_base+edir); /* return base + idx */ } ! #endif FIXED_DIRIDS } /* *************** *** 478,483 **** --- 550,569 ---- if (DBDIR) printf("GetIDirid: edir:%d\n",edir); #endif SHORT_NAMES + #ifdef FIXED_DIRIDS + { + char *path; + + path = aufsExtPath(edir); + if (DBDIR) + printf("GetIDirid gave '%s' for %d\n", path, edir); + if (path) + return(Idirid(path)); + if (DBDIR) + printf("GetIDirid: Bad directory idx %d\n", edir); + return(NILDIR); + } + #else FIXED_DIRIDS edir -= ExtDir.xd_base; /* subtract base */ if (edir < 0 || /* below base? */ edir > ExtDir.xd_count-1) { /* or above count? */ *************** *** 487,492 **** --- 573,579 ---- return(NILDIR); /* yes... not allocated */ } return(ExtDir.xd_idirs[edir]); /* return handle */ + #endif FIXED_DIRIDS } *************** *** 518,527 **** { IDirP VolRootD(),idir; - #ifdef SHORT_NAMES if (DBDIR) printf("EtoIdirid: volid %d dirid:%d \n",volid,dirid); - #endif SHORT_NAMES if (dirid == EROOTD) /* check for root id */ return(VolRootD(volid)); /* yes, so return volumes root */ if (dirid == EPROOTD) /* check for parent of root */ --- 605,612 ---- *************** *** 562,569 **** if (DBDIR && !V_BITTST(dirid->volbm,volid)) /* know this ownership? */ printf("ItoEdirid: bad volid for %s\n",pathstr(dirid)); ! if (dirid->edirid == -1) dirid->edirid = NewEDirid(dirid); if ((dirid->flags & DID_VALID) == 0) /* validate info if invalid */ OSValidateDIDDirInfo(dirid); --- 647,659 ---- if (DBDIR && !V_BITTST(dirid->volbm,volid)) /* know this ownership? */ printf("ItoEdirid: bad volid for %s\n",pathstr(dirid)); ! if (dirid->edirid == -1) { ! if (DBDIR) ! printf("ItoEdirid: calling NewEDirid\n"); dirid->edirid = NewEDirid(dirid); + if (DBDIR) + printf("ItoEdirid: NewEDirid returns %d\n", dirid->edirid); + } if ((dirid->flags & DID_VALID) == 0) /* validate info if invalid */ OSValidateDIDDirInfo(dirid); *************** *** 617,622 **** --- 707,723 ---- IDirP id; IDirP iprootd, irootd; /* has parent of root and root respectively */ + if (DBDIR) { + int i = 1; + pl = *epath; + printf("EtoIfile: ivol = %d, epath = ", *ivol); + while (pl--) { + printf("(%c)", *(epath+i)); + i++; + } + printf("\n"); + } + *ivol = EtoIVolid(evol); /* set internal volid */ if (*ivol < 0) return(*ivol); /* error */ *************** *** 801,807 **** --- 902,915 ---- /* prevent returnning "bad" info anyway. Basically, the whole */ /* point is to prevent mac side from getting to entries which aren't */ /* valid - this will simply eliminate work */ + #ifdef FIXED_DIRIDS + if (idir->edirid == -1) + aufsExtDel(pathstr(idir)); + else + aufsExtDelId(idir->edirid); + #else FIXED_DIRIDS ExtDir.xd_idirs[idir->edirid - ExtDir.xd_base] = NILDIR; + #endif FIXED_DIRIDS idir->edirid = -1; idir->flags &= ~DID_VALID; #ifdef SHORT_NAMES *************** *** 817,823 **** /* would like to delete space, but bad thing to do */ idir->flags &= ~DID_VALID; /* mark as not valid */ idir->subs = NILDIR; /* make sure not valid (shouldn't be) */ ! #endif } /* --- 925,931 ---- /* would like to delete space, but bad thing to do */ idir->flags &= ~DID_VALID; /* mark as not valid */ idir->subs = NILDIR; /* make sure not valid (shouldn't be) */ ! #endif notdef } /* *************** *** 837,842 **** --- 945,954 ---- char *from,*to; { IDirP fdir; + #ifdef FIXED_DIRIDS + sdword toEid; + char *orig_name = NULL; + #endif FIXED_DIRIDS #ifdef SHORT_NAMES if (DBFIL && fpdir != NULL) *************** *** 857,862 **** --- 969,979 ---- return; } + #ifdef FIXED_DIRIDS + if (fdir->edirid == -1) /* will need full name later */ + orig_name = string_copy(pathstr(fdir)); + #endif FIXED_DIRIDS + if (strcmp(from,to) != 0) { /* if different names then... */ register long hash; register char *p, *t; *************** *** 874,886 **** } if (fpdir != tpdir) { /* if different parents then... */ ! if (nfind(tpdir->subs,to) != NILDIR) { printf("Idmove: name already exists %s\n",to); ! return; } - dir_unlink(fpdir,fdir); /* unlink from old parent */ - dir_link(tpdir,fdir); /* relink into new parent */ } lastcd = NILDIR; /* names have changed */ } --- 991,1020 ---- } if (fpdir != tpdir) { /* if different parents then... */ ! if (nfind(tpdir->subs,to) != NILDIR) printf("Idmove: name already exists %s\n",to); ! else { ! dir_unlink(fpdir,fdir); /* unlink from old parent */ ! dir_link(tpdir,fdir); /* relink into new parent */ ! #ifdef FIXED_DIRIDS ! toEid = Edirid(tpdir); ! if (fdir->edirid == -1) ! aufsExtMoveId(orig_name, toEid, to); ! else ! aufsExtMoveIds(fdir->edirid, toEid, to); ! #endif FIXED_DIRIDS } } + #ifdef FIXED_DIRIDS + else { /* effectively a rename */ + if (fdir->edirid == -1) + aufsExtRename(orig_name, to); + else + aufsExtRenameId(fdir->edirid, to); + } + if (orig_name != NULL) + free(orig_name); + #endif FIXED_DIRIDS lastcd = NILDIR; /* names have changed */ } *** applications/aufs/afpdir.c.orig Mon Jun 12 23:13:45 1995 --- applications/aufs/afpdir.c Thu Apr 25 11:32:10 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/06/12 13:13:08 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpdir.c,v 2.6 1995/06/12 13:13:08 djh Rel djh $ ! * $Revision: 2.6 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 01:32:00 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpdir.c,v 2.7 1996/04/25 01:32:00 djh Rel djh $ ! * $Revision: 2.7 $ * */ *************** *** 516,521 **** --- 516,524 ---- printf("FPCreateDir: create path=%s name=%s\n",pathstr(ipdir),file); if ((err = OSCreateDir(ipdir,file, &idir)) == noErr) { + if (DBFIL) + printf("FPCreateDir: create path=%s name=%s edirID=%d\n", + pathstr(ipdir),file,idir->edirid); PackDWord(ItoEdirid(idir,ivol),r); *rl = 4; } *** applications/aufs/afpserver.c.orig Fri Jun 30 08:43:01 1995 --- applications/aufs/afpserver.c Wed May 1 02:21:13 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/06/29 22:42:37 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpserver.c,v 2.13 1995/06/29 22:42:37 djh Rel djh $ ! * $Revision: 2.13 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/30 16:20:46 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpserver.c,v 2.16 1996/04/30 16:20:46 djh Rel djh $ ! * $Revision: 2.16 $ * */ *************** *** 36,41 **** --- 36,42 ---- * FPGetSrvrMsg() * FPMapID() * FPMapName() + * FPCreateID() * */ *************** *** 142,147 **** --- 143,153 ---- {AFPChgPasswd, FPChgPasswd, "ChangePassword", 0, 0}, /* AFP2.0 */ {AFPGetUserInfo, FPGetUserInfo, "GetUserInfo", 0, 0}, /* AFP2.0 */ {AFPGetSrvrMsg, FPGetSrvrMsg, "GetSrvrMsg", 0, 0}, /* AFP2.1 */ + #ifdef FIXED_DIRIDS + {AFPCreateID, FPCreateID, "CreateID", 0, 0}, /* AFP2.1 */ + {AFPDeleteID, FPDeleteID, "DeleteID", 0, 0}, /* AFP2.1 */ + {AFPResolveID, FPResolveID, "ResolveID", 0, 0}, /* AFP2.1 */ + #endif /* FIXED_DIRIDS */ {AFPCloseVol,FPCloseVol,"CloseVol",0,0}, {AFPCloseDir,FPCloseDir,"CloseDir",0,0}, {AFPCreateDir,FPCreateDir,"CreateDir",0,0}, *************** *** 242,248 **** --- 248,256 ---- InitOSFI(); /* init finder file info */ ECacheInit(); /* init afposenum cache */ InitIconCache(); /* init afpdt cache */ + #ifndef FIXED_DIRIDS InitDID(); /* init directory stuff */ + #endif FIXED_DIRIDS #ifdef STAT_CACHE OSStatInit(); /* init stat cache */ #endif STAT_CACHE *** applications/aufs/afposncs.c.orig Tue Nov 30 00:10:17 1993 --- applications/aufs/afposncs.c Mon Mar 11 23:35:27 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1993/11/29 13:09:45 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afposncs.c,v 2.7 1993/11/29 13:09:45 djh Rel djh $ ! * $Revision: 2.7 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/03/11 12:34:09 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afposncs.c,v 2.9 1996/03/11 12:34:09 djh Rel djh $ ! * $Revision: 2.9 $ */ /* *************** *** 32,39 **** * */ - /* PATCH: PC.aufs/afposncs.c.diffs, djh@munnari.OZ.AU, 15/11/90 */ - #include #include #include --- 32,37 ---- *************** *** 377,384 **** #endif /* FULL_NCS_SUPPORT */ #define NCS_entry(name, suf, conj, creator, type, totable, fromtable) \ ! { name, suf, sizeof(suf)-1, conj, creator, sizeof(creator)-1, \ ! type, sizeof(type)-1, totable, fromtable } /* * NCS_entry: --- 375,382 ---- #endif /* FULL_NCS_SUPPORT */ #define NCS_entry(name, suf, conj, creator, type, totable, fromtable) \ ! { name, suf, sizeof(suf)-1, conj, (byte *) creator, sizeof(creator)-1, \ ! (byte *) type, sizeof(type)-1, totable, fromtable } /* * NCS_entry: *************** *** 407,433 **** #if defined (ISO_TRANSLATE) & defined (ISO_FILE_TRANS) #ifdef NCS_ALL_TEXT /* ISO 8859-1 latin1 translation for all TEXT files */ ! NCS_entry("ISO 8859-1 Latin 1", NULL, NCS_AND, NULL, (byte *)"TEXT", Mac2ISO, ISO2Mac), #else NCS_ALL_TEXT /* ISO 8859-1 latin1 translation for unix/TEXT files */ ! NCS_entry("ISO 8859-1 Latin 1", NULL, NCS_AND, (byte *)"unix", (byte *)"TEXT", Mac2ISO, ISO2Mac), #endif NCS_ALL_TEXT #endif ISO_TRANSLATE & ISO_FILE_TRANS #ifdef NCS_ALL_TEXT /* ASCII translation for all TEXT files */ ! NCS_entry("ascii", NULL, NCS_AND, NULL, (byte *)"TEXT", to_ascii, from_ascii), #else NCS_ALL_TEXT /* ASCII translation for unix/TEXT files */ ! NCS_entry("ascii", NULL, NCS_AND, (byte *)"unix", (byte *)"TEXT", to_ascii, from_ascii), #endif NCS_ALL_TEXT #ifdef SHORT_NAMES ! NCS_entry("pc-ascii", NULL, NCS_AND, (byte *)"unix", (byte *)"TEXT", pc_to_ascii, pc_from_ascii), #endif SHORT_NAMES {NULL} --- 405,431 ---- #if defined (ISO_TRANSLATE) & defined (ISO_FILE_TRANS) #ifdef NCS_ALL_TEXT /* ISO 8859-1 latin1 translation for all TEXT files */ ! NCS_entry("ISO 8859-1 Latin 1", NULL, NCS_AND, NULL, "TEXT", Mac2ISO, ISO2Mac), #else NCS_ALL_TEXT /* ISO 8859-1 latin1 translation for unix/TEXT files */ ! NCS_entry("ISO 8859-1 Latin 1", NULL, NCS_AND, "unix", "TEXT", Mac2ISO, ISO2Mac), #endif NCS_ALL_TEXT #endif ISO_TRANSLATE & ISO_FILE_TRANS #ifdef NCS_ALL_TEXT /* ASCII translation for all TEXT files */ ! NCS_entry("ascii", NULL, NCS_AND, NULL, "TEXT", to_ascii, from_ascii), #else NCS_ALL_TEXT /* ASCII translation for unix/TEXT files */ ! NCS_entry("ascii", NULL, NCS_AND, "unix", "TEXT", to_ascii, from_ascii), #endif NCS_ALL_TEXT #ifdef SHORT_NAMES ! NCS_entry("pc-ascii", NULL, NCS_AND, "unix", "TEXT", pc_to_ascii, pc_from_ascii), #endif SHORT_NAMES {NULL} *************** *** 605,612 **** --- 603,612 ---- } } #endif USR_FILE_TYPES + #ifndef NONLXLATE if (*bp == fc) *bp = tc; + #endif NONLXLATE bp++; } #ifdef SHORT_NAMES *** applications/aufs/afpos.c.orig Mon Aug 28 08:24:19 1995 --- applications/aufs/afpos.c Fri Apr 26 01:05:35 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/08/27 22:23:51 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpos.c,v 2.74 1995/08/27 22:23:51 djh Rel djh $ ! * $Revision: 2.74 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 15:05:22 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/afpos.c,v 2.78 1996/04/25 15:05:22 djh Rel djh $ ! * $Revision: 2.78 $ * */ *************** *** 252,257 **** --- 252,263 ---- #include #endif ULTRIX_SECURITY + #ifdef DIGITAL_UNIX_SECURITY + #include + #include + #include + #endif DIGITAL_UNIX_SECURITY + #ifdef LOG_WTMP # if defined(sgi) || defined(SOLARIS) # define LOG_WTMPX *************** *** 1125,1130 **** --- 1131,1138 ---- if (S_ISDIR(stb.st_mode)) /* if a directory then need to */ Idmove(fpdir,from,tpdir,to); /* change internal structure */ + else + FIdmove(fpdir,from,tpdir,to); FModified(fpdir, from); /* does an emodified */ /* EModified(fpdir); */ *************** *** 2483,2489 **** #elif defined(encore) if (equota(Q_GETDLIM, usruid, buf.st_dev, &dqblk) == 0 && #elif defined(SOLARIS) ! if (solaris_quota(Q_GETDLIM, usruid, buf.st_dev, &dqblk) == 0 && #else /* gould || encore || SOLARIS */ if (quota(Q_GETDLIM, usruid, buf.st_dev, &dqblk) == 0 && #endif /* gould || encore || SOLARIS */ --- 2491,2497 ---- #elif defined(encore) if (equota(Q_GETDLIM, usruid, buf.st_dev, &dqblk) == 0 && #elif defined(SOLARIS) ! if (solaris_quota(Q_GETDLIM, usruid, path, &dqblk) == 0 && #else /* gould || encore || SOLARIS */ if (quota(Q_GETDLIM, usruid, buf.st_dev, &dqblk) == 0 && #endif /* gould || encore || SOLARIS */ *************** *** 3502,3508 **** setpwent(); while ((pw = getpwent()) != 0) { ptm = pw->pw_gecos; ! for (i = 0 ; *ptm ; ptm++, i++) { if (isupper(*ptm)) nomi[i] = tolower(*ptm); else --- 3510,3516 ---- setpwent(); while ((pw = getpwent()) != 0) { ptm = pw->pw_gecos; ! for (i = 0 ; ptm && *ptm && (*ptm != ','); ptm++, i++) { if (isupper(*ptm)) nomi[i] = tolower(*ptm); else *************** *** 3559,3564 **** --- 3567,3576 ---- char *ultrix_crypt(); char *crypted_password; #endif ULTRIX_SECURITY + #ifdef DIGITAL_UNIX_SECURITY + char *bigcrypt(); + struct pr_passwd *pr; + #endif DIGITAL_UNIX_SECURITY #ifdef LWSRV_AUFS_SECURITY extern char *userlogindir; int namlen; *************** *** 3737,3742 **** --- 3749,3755 ---- } else { logit(0, "Login: user %s found in shadow password file", p->pw_name); } + endspent(); } #else SHADOW_PASSWD /* cope with some adjunct password file schemes */ *************** *** 3750,3773 **** crypted_password = ultrix_crypt(pwd, p); if (strcmp(crypted_password, p->pw_passwd) != 0) { #else ULTRIX_SECURITY ! # ifndef SHADOW_PASSWD ! # ifdef RUTGERS if (strcmp(ru_crypt(pwd,p->pw_passwd,p->pw_uid,p->pw_name), p->pw_passwd) != 0) { ! # else RUTGERS if (strcmp(crypt(pwd,p->pw_passwd),p->pw_passwd) != 0) { ! # endif RUTGERS ! # else SHADOW_PASSWD pw_check = (shadow_flag) ? ! # ifdef RUTGERS strcmp(ru_crypt(pwd,sp->sp_pwdp,p->pw_uid,p->pw_name),sp->sp_pwdp) : strcmp(ru_crypt(pwd,p->pw_passwd,p->pw_uid,p->pw_name),p->pw_passwd); ! # else RUTGERS strcmp(crypt(pwd,sp->sp_pwdp),sp->sp_pwdp) : strcmp(crypt(pwd,p->pw_passwd),p->pw_passwd); ! # endif RUTGERS if (pw_check) { ! # endif SHADOW_PASSWD #endif ULTRIX_SECURITY logit(0, "Login: Incorrect password for user %s", nam); if (!safedebug) --- 3763,3792 ---- crypted_password = ultrix_crypt(pwd, p); if (strcmp(crypted_password, p->pw_passwd) != 0) { #else ULTRIX_SECURITY ! # ifdef DIGITAL_UNIX_SECURITY ! pr = getprpwnam(nam); ! if (pr == NULL || strcmp(bigcrypt(pwd, pr->ufld.fd_encrypt), ! pr->ufld.fd_encrypt) != 0) { ! # else DIGITAL_UNIX_SECURITY ! # ifndef SHADOW_PASSWD ! # ifdef RUTGERS if (strcmp(ru_crypt(pwd,p->pw_passwd,p->pw_uid,p->pw_name), p->pw_passwd) != 0) { ! # else RUTGERS if (strcmp(crypt(pwd,p->pw_passwd),p->pw_passwd) != 0) { ! # endif RUTGERS ! # else SHADOW_PASSWD pw_check = (shadow_flag) ? ! # ifdef RUTGERS strcmp(ru_crypt(pwd,sp->sp_pwdp,p->pw_uid,p->pw_name),sp->sp_pwdp) : strcmp(ru_crypt(pwd,p->pw_passwd,p->pw_uid,p->pw_name),p->pw_passwd); ! # else RUTGERS strcmp(crypt(pwd,sp->sp_pwdp),sp->sp_pwdp) : strcmp(crypt(pwd,p->pw_passwd),p->pw_passwd); ! # endif RUTGERS if (pw_check) { ! # endif SHADOW_PASSWD ! # endif DIGITAL_UNIX_SECURITY #endif ULTRIX_SECURITY logit(0, "Login: Incorrect password for user %s", nam); if (!safedebug) *** applications/aufs/aufs.c.orig Mon Jun 19 11:32:30 1995 --- applications/aufs/aufs.c Tue Apr 30 23:59:28 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/06/19 01:32:20 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/aufs.c,v 2.27 1995/06/19 01:32:20 djh Rel djh $ ! * $Revision: 2.27 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/30 13:59:00 $ ! * $Header: /mac/src/cap60/applications/aufs/RCS/aufs.c,v 2.33 1996/04/30 13:59:00 djh Rel djh $ ! * $Revision: 2.33 $ * */ *************** *** 137,142 **** --- 137,145 ---- private EntityName srvr_entity_name; /* our entity name */ private char zonetorun[34]; /* zone to run in if different than std. */ private char logfile[MAXPATHLEN]; /* log file name if any */ + #ifdef PID_FILE + private char pid_file[MAXPATHLEN]; /* pid file name if any */ + #endif /* PID_FILE */ private int parent_pid; /* pid of main server */ private int mypid; /* pid of running process */ private int nomoresessions = FALSE; /* set true of out of asp sessions */ *************** *** 243,248 **** --- 246,254 ---- fprintf(stderr,"\t-c directory to specify a directory to coredump to\n"); #endif STAT_CACHE fprintf(stderr,"\t-l file to send logfile to other than .log\n"); + #ifdef PID_FILE + fprintf(stderr,"\t-w file to write pid to other than ./%s\n", PID_FILE); + #endif /* PID_FILE */ fprintf(stderr,"\t-S limit responses to packets\n"); fprintf(stderr,"\t-R limit remote to sending packets\n"); #ifdef LWSRV_AUFS_SECURITY *************** *** 318,326 **** #ifdef LOGIN_AUTH_PROG strcat(optlist, "L:"); #endif LOGIN_AUTH_PROG ! #ifdef DEBUG_AFP strcat(optlist, "Z:"); ! #endif DEBUG_AFP while ((c = getopt(argc,argv,optlist)) != EOF) { switch (c) { --- 324,336 ---- #ifdef LOGIN_AUTH_PROG strcat(optlist, "L:"); #endif LOGIN_AUTH_PROG ! #ifdef PID_FILE ! pid_file[0] = '\0'; ! strcat(optlist, "w:"); ! #endif /* PID_FILE */ ! #ifdef DEBUG_AFP strcat(optlist, "Z:"); ! #endif /* DEBUG_AFP */ while ((c = getopt(argc,argv,optlist)) != EOF) { switch (c) { *************** *** 456,466 **** } break; #endif LOGIN_AUTH_PROG ! #ifdef DEBUG_AFP ! case 'Z': /* AFP command debugging */ debugAFPFile = optarg; break; ! #endif /* DEBUG_AFP */ default: usage(argv[0]); break; --- 466,481 ---- } break; #endif LOGIN_AUTH_PROG ! #ifdef PID_FILE ! case 'w': /* pid file */ ! strncpy(pid_file, optarg, sizeof(pid_file)-1); ! break; ! #endif /* PID_FILE */ ! #ifdef DEBUG_AFP ! case 'Z': /* command debug file */ debugAFPFile = optarg; break; ! #endif /* DEBUG_AFP */ default: usage(argv[0]); break; *************** *** 498,503 **** --- 513,521 ---- void setreadafpvols(); void dorereadafpvols(); #endif REREAD_AFPVOLS + #ifdef CLOSE_LOG_SIG + void closelog(); + #endif /* CLOSE_LOG_SIG */ #ifndef NOSHUTDOWNCODE void killnow(), killin5(), diein5(); void msgnotify(), msgavail(); *************** *** 520,526 **** void cISO2Mac(); #endif ISO_TRANSLATE ! /* initial os dependent items first */ OSEnable(); /* enable OS dependent items */ IniServer(); --- 538,547 ---- void cISO2Mac(); #endif ISO_TRANSLATE ! #ifdef DIGITAL_UNIX_SECURITY ! set_auth_parameters(argc, argv); ! #endif DIGITAL_UNIX_SECURITY ! OSEnable(); /* enable OS dependent items */ IniServer(); *************** *** 602,613 **** } #ifdef DEBUG_AFP ! if (debugAFPFile != NULL) ! if ((dbg = fopen(debugAFPFile, "w")) != NULL) ! fprintf(dbg, "AUFS Debug Session\n"); #endif /* DEBUG_AFP */ mypid = parent_pid = getpid(); /* remember who we are */ if (logfile[0] == '\0') { #ifdef ISO_TRANSLATE sprintf(logfile, "%s.log", (char *)isoSrvrName); --- 623,652 ---- } #ifdef DEBUG_AFP ! if (debugAFPFile != NULL) ! if ((dbg = fopen(debugAFPFile, "w")) != NULL) ! fprintf(dbg, "AUFS Debug Session\n"); #endif /* DEBUG_AFP */ + #ifdef FIXED_DIRIDS + InitDID(); /* init directory stuff */ + #endif FIXED_DIRIDS + mypid = parent_pid = getpid(); /* remember who we are */ + + #ifdef PID_FILE + { FILE *pidfd; + if (pid_file[0] == '\0') + strncpy(pid_file, PID_FILE, sizeof(pid_file)-1); + if( (pidfd = fopen(pid_file, "w")) == NULL ) { + logit(0,"Can't open pid file %s", pid_file); + exit(-1); + } + fprintf(pidfd, "%d\n", mypid); + fclose(pidfd); + } + #endif /* PID_FILE */ + if (logfile[0] == '\0') { #ifdef ISO_TRANSLATE sprintf(logfile, "%s.log", (char *)isoSrvrName); *************** *** 771,776 **** --- 810,818 ---- #ifdef REREAD_AFPVOLS signal(SIGUSR1, setreadafpvols); /* kill -USR1 -- force afpvols re-read */ #endif REREAD_AFPVOLS + #ifdef CLOSE_LOG_SIG + signal(CLOSE_LOG_SIG, closelog); /* kill -USR2 -- force close/reopen log */ + #endif /* CLOSE_LOG_SIG */ do { pid = -1; /* make sure zero at start */ *************** *** 1525,1530 **** --- 1567,1590 ---- } } #endif REREAD_AFPVOLS + + #ifdef CLOSE_LOG_SIG + /* + * A SIGUSR2 requests that the log be closed and reopened. This is + * important if you wish to rotate your logs on a regular basis. + * + */ + + void + closelog() + { + signal(CLOSE_LOG_SIG, SIG_IGN); + nologitfile(); + logitfileis(logfile, "a+"); + signal(CLOSE_LOG_SIG, closelog); + return; + } + #endif /* CLOSE_LOG_SIG */ #ifdef notdef /* *** applications/aufs/afpid.notes.orig Sat Apr 27 22:50:50 1996 --- applications/aufs/afpid.notes Sat Apr 27 22:50:43 1996 *************** *** 0 **** --- 1,160 ---- + afpidsrvr + --------- + + This provides aufs with permanent external directory and file id's. + + Rather than remembering pathnames, Mac's often store a number for + the directory and the name of the file. These id's must be mapped + by aufs onto the Unix file system - thus the term "external id's". + External id's are used extensively by the alias manager, and also + affect QuickTime. aufs's problem is that it forgets the id's after + each session. This causes many problems, the greatest being that + aliases do not work properly. + + The previous, and still default, version created external id's as + required in a linear manner. These are mapped onto pointers - + internally aufs holds the directory picture as a tree. An array of + these pointers, indexed by the external id, was used to perform the + external to internal mapping. The reverse mapping was achieved + primarily by a field in the internal directory records. + + This new version uses a central database to hold the external id's. + Various schemes were examined, including the use of inode numbers. + Most were rejected on the realisation that a single scheme had to + cover the whole file system: you cannot assign numbers by volumes. + The database is single-writer/multi-reader. aufs processes read + id/path pairs from the database, but if they want to add entries they + send a request to the 'afpidsrvr'. The use of a server at least + ensures consistency is maintained, gets around the basic problem of + the lack of locks, and preserves some security. So far, at least, the + system has worked without locks - aufs does re-open databases after + it detects change, to avoid some problems. Security is not + particularly strict - the server will not create entries if + directories don't exist, and will not remove entries for existing + directories. The system is not foolproof, and can have problems if + the database gets corrupted, but there we are. + + The current version (1.1) of the database is the second go. The first + version contained two sets of entries: fullpath->id and id->fullpath. + This worked fine until the system tried to delete or move directory + trees - it just moved the top one, and left the children in their + original places. The second version mirrors the directory structure + in providing a tree. Moving and deleting now alters the tree + structure. This means that many more accesses are required, but the + records themselves are on average smaller. Each record, looked up by + key N, consists of: + + + + There is also an initial record consisting of the databased version + and the root id. + + As well as a the afpidsrvr server there is an afpidtool, which can + send messages directly to the server, and afpidlist, which will + list the database. + + The system is by no means foolproof. Expect problems if different + people are working on the same area - aufs still cannot detect + automatically that other processes have changed the Unix + filestructure. Since the server routines pass a fullpath back to + aufs itself, and let it then decode that into the internal aufs + directory tree, if the name is changed by another process, then aufs + may see a whole new path. If this proves a problem, a mechanism will + be required to pass back the information to aufs - it is essentially + a problem with the aufs/afpidsrvr interface, rather than with afpidsrvr + itself. One possibility would be to passback a list of extId/name + pairs, rather than a path. If the names changed than aufs would + realise that, and could change its internal record. I've no idea how + it would tell the Mac though! + + Another area of concern is in the integrity of the database. The + current database should not get corrupted, but if it does the + programs are not very resiliant to it - the contents of a record are + believed. It is not particularly clear how this will workout in + practice - my experience with corruptions is limited to problems + during testing, when bugs caused process crashes. If corruptions turn + out to be a problem, then some extra checks will be required. To be + worth while, adding CRC checks to the database records is probably + required. For the moment the simple scheme seems preferable. Do note + that, in the extreme case, you may have to delete the database in + /usr/local/lib/cap and start again. If you do this, ensure you stop both + afpidsrvr and aufs first - neither like this event! This will obviously + cause problems to users. The previous version of afpidsrvr had a clean + function, which was intended to remove unused and faulty entries. + This is currently non-operative, but may be re-instated in the + future. + + In will be noted that afpidsrvr is optional. Why might you not wish to + use this: + + * There is a performance penalty, and you might not wish to pay it. + In practice, there is a slight penalty on startup, and in opening + folders for the first time - especially new ones. The only "bad case" + scenario that actually occurs is the reverse lookup of an id to a + pathname, which is then converted to an internal pointer by a second + tree semi-traversal. My experience with a Sun II server suggests that + this delay is negligable. + + * Reliability. The system has, currently, only been tested on a Sun + II server. There may be minor problems elsewhere, but there is + nothing to suggest that there should be huge problems. I'm still not + sure about the big-endian/little-endian situation, but I believe that + providing the database is not moved from one machine to another there + should be no problem. + + * NFS. We do not use NFS much, and I have little experience of it. I + would only expect problems if the aufs server for the same area ran + on serveral machines, but there are several suspect areas. + + * Portability. The system runs under SunOS4.1. I have not tested it + on other systems - not even Solaris. The chief problem areas may be + in named sockets, which are used to send the information between + client processes and the server. On other systems you my have to use + equivalents. + + On a final point, the modified server does contain emergency code for + use if the server ceases to function. This should never happen in + normal running, but may if errors are hit. This backup mechanism + actually reflects v1.0 if the database, and just records name/id + pairs. It is anything but efficient, and is merely intended to avoid + having to crash the server. Really there ought to be a few bells + ringing if this happens, but there are not! [Perhaps in a future + version, if something thinks of a good interface.] It is suggested + that this should not be used routinely - not least it has problems + still with moving and deleting sub-trees of directories - and is very + inefficient. In case you wonder why not just fall back on the default + scheme, the assumption is that the existing database is fine, but + cannot be modified. + + Installation and Use + -------------------- + + To use the file/directory ID server, select the FIXED_DIRIDS option in + the m4.features file. Re-run gen.makes, 'make clean' and rebuild CAP. + + When compiled and installed, you will get the additional tools afpidsrvr, + afpidlist and afpidtool in your cap bin directory - along with the + modified aufs. + + To bring them into operation, you must: + + * Modify /etc/rc.local or your start-cap-servers file to place the + following lines, or similar, before you start aufs: + + rm /usr/local/lib/cap/afpIDsock + afpidsrvr -l /usr/adm/afpidsrvr.log + + Then restart as appropriate. The first call to afpidsrvr will create + the database, and aufs processes will then use it. Note the first + line is to delete the socket used for communication. This normally + happens when afpidsrvr exits, but may not if the machine crashes. In + normal running, you should be careful about running this - ensure + there is no afpidsrvr server running. This will only happen in normal + running if the afpidsrvr falls over. If this does happen, run + afpidlist first to ensure you can printout the database. If you + have real problems, you may have to close down aufs and delete the + database before continuing. You may prefer to try to restore the + database off backup. + + John Forrest, + jf@ap.co.umist.ac.uk *** applications/aufs/afpidlist.c.orig Sat Apr 27 22:29:23 1996 --- applications/aufs/afpidlist.c Mon Apr 29 17:00:42 1996 *************** *** 0 **** --- 1,94 ---- + /* + * $Author: djh $ $Date: 1996/04/29 07:00:27 $ + * $Header: /mac/src/cap60/applications/aufs/RCS/afpidlist.c,v 2.2 1996/04/29 07:00:27 djh Rel djh $ + * $Revision: 2.2 $ + * + */ + + /* + * tool that prints out the contents of the AUFS fixed directory ID database + * + * John Forrest + * + */ + + #ifdef FIXED_DIRIDS + + #include + #include + #include + + #include "../../lib/afp/afpidaufs.h" + + void + print_tree(id, prefix) + sdword id; + char *prefix; + { + char me [MAXPATHLEN]; + sdword parent; + char *name; + int num_children; + sdword *children; + datum key, data; + int i; + + if (id != rootEid) { /* root a bit different, because name is "/" */ + strcpy(me, prefix); + strcat(me, "/"); + } else + strcpy(me, ""); + + key = num_datum(id); + data = dbm_fetch(db, key); + + if (data.dptr == NULL) { + printf("**Error** id %d not found (prefix '%s')\n", id, prefix); + return; + } + + if (extract_entry(data,&name,&parent,&num_children,&children) < 0) { + printf("**Error** had probs with data for id %d(prefix '%s')\n", + id, prefix); + return; + } + + if (id == rootEid) + printf("RootEid = %d (+%d)\n", id, num_children); + else { + strcat(me, name); + printf("%d = (%d) '%s' (+%d)\n", id, parent, me, num_children); + } + + children = copy_children(children, num_children); + + for (i = 0; i < num_children; i++) + print_tree(children[i], me); + + free(children); + } + + + main(argc, argv) + int argc; + char *argv[]; + { + int ret; + + if ((ret = open_dbase(1)) < 0) { + fprintf(stderr, "Can't open database %s (%d,%d)\n", + aufsDbName, ret, errno); + exit(-1); + } + + print_tree(rootEid, NULL); + close_dbase(); + exit(0); + } + #else FIXED_DIRIDS + #include + main() + { + printf("afpidlist: not compiled with -DFIXED_DIRIDS\n"); + } + #endif FIXED_DIRIDS *** applications/aufs/afpidsrvr.c.orig Sat Apr 27 22:29:23 1996 --- applications/aufs/afpidsrvr.c Wed May 1 01:26:24 1996 *************** *** 0 **** --- 1,743 ---- + /* + * $Author: djh $ $Date: 1996/04/30 15:25:51 $ + * $Header: /mac/src/cap60/applications/aufs/RCS/afpidsrvr.c,v 2.3 1996/04/30 15:25:51 djh Rel djh $ + * $Revision: 2.3 $ + * + */ + + /* + * Server to provide AUFS fixed directory ID database write facilities + * + * John Forrest + * + */ + + #ifdef FIXED_DIRIDS + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "../../lib/afp/afpidaufs.h" + + int verbose = 0; + int disconnect = 1; + char *log = NULL; + int continue_clean; + + extern char *optarg; + extern int optind, opterr; + + int queries; /* request socket */ + int bound_queries = 0; /* whether to delete socket or not */ + void create_queries(); + + void session(); + void set_signal(); + void do_disconnect(); + void clean_entries(); + + void open_database(); + + void + fatal(message) + char *message; + { + if (message != NULL) + fprintf(stderr, "%s:", message); + if (errno > 0) { + fprintf(stderr, " %d: ", errno); + perror(""); + } else + putc('\n', stderr); + if (db != NULL) + dbm_close(db); + if (bound_queries) + unlink(aufsSockname); + exit(-1); + } + + void + fatal2(message, a1) + char *message, *a1; + { + fprintf(stderr, "afpidsrvr: fatal error: %s%s :", message, a1); + fatal(NULL); + } + + void + clean_exit(n) + int n; + { + if (db != NULL) + dbm_close(db); + if (bound_queries) + unlink(aufsSockname); + exit(n); + } + + main(argc, argv) + char *argv[]; + { + int c; + extern char *optarg; + int doClean = 0; + + while ((c = getopt(argc, argv, "vtcl:")) != -1) { + switch (c) { + case 'v': + verbose = 1; + break; + case 't': + disconnect = 0; + break; + case 'l': + log = optarg; + break; + case 'c': + doClean = 1; + break; + case '?': + fprintf(stderr, + "usage: afpidsrvr [-c] [-v] [-t] [-l logfile]\n"); + exit(-1); + } + } + + set_signal(); + + if (disconnect) + do_disconnect(); + + if (log) { + int fd; + + if ((fd = open(log, O_WRONLY|O_APPEND|O_CREAT)) < 0) + fd = open("/dev/null", O_WRONLY); + + if (fd >= 0) { + #ifndef NODUP2 + dup2(fd, 2); + #else NODUP2 + close(2); + dup(fd); + #endif NODUP2 + close(fd); + } + } + + init_aufsExt(); + + open_database(); + + create_queries(); + + if (doClean) + do + clean_entries(); + while (continue_clean); + + { + time_t now; + + time(&now); + fprintf(stderr, "Starting afpidsrvr with %s at %s", + aufsDbName, ctime(&now)); + } + + session(); + /* NOTREACHED */ + } + + /* + * create queries "pipe" entry + * + */ + + void + create_queries() + { + struct sockaddr *addr; + int addrlen; + + if ((queries = query_socket()) < 0) + fatal("Problem creating socket"); + + query_addr(&addr, &addrlen); + if (bind(queries, addr, addrlen) < 0) + fatal2("Problem binding socket ", aufsSockname); + bound_queries = 1; + + if (listen(queries, 5) < 0) + fatal("Listen"); + } + + int do_exit() + { + clean_exit(-1); + } + + /* + * force clean exit + * + */ + + void + set_signal() + { + if (signal(SIGHUP, SIG_IGN)!=SIG_IGN) + signal(SIGHUP, do_exit); + if (signal(SIGINT, SIG_IGN)!=SIG_IGN) + signal(SIGINT, do_exit); + if (signal(SIGTERM, SIG_IGN)!=SIG_IGN) + signal(SIGTERM, do_exit); + } + + void + create_database() + { + datum initial_key, initial; + datum root, root_datum; + + if ((db = dbm_open(aufsDbName, O_RDWR|O_CREAT, 0644)) == NULL) + fatal("Creating db"); + + rootEid = valid_id(); /* any will do */ + root_datum = new_entry(aufsRootName, (sdword)0); + root = num_datum(rootEid); + if (dbm_store(db, root, root_datum, DBM_REPLACE) < 0) + fatal("Writing root record"); + + initial_key.dptr = "I"; + initial_key.dsize = strlen(initial_key.dptr); + initial = create_init(aufsDbVersion, rootEid); + if (dbm_store(db, initial_key, initial, DBM_REPLACE) < 0) + fatal("Writing root record"); + + flush_database(); + } + + + void + open_database() + { + datum initial_key, initial; + char *version; + + initial_key.dptr = "I"; + initial_key.dsize = strlen(initial_key.dptr); + + db = dbm_open(aufsDbName, O_RDWR, 0644); + if (db == NULL && errno == ENOENT) + create_database(); + if (db == NULL) + fatal("Opening db"); + + initial = dbm_fetch(db, initial_key); + if (initial.dptr == NULL) + fatal("Suspect Database"); + if (extract_init(initial, &version, &rootEid) < 0) + fatal("Problem with initial record"); + if (strcmp(version, aufsDbVersion) != 0) + fatal2("Incompatible d/b, can't deal with version ", version); + } + + void + add_entry(entry) + char *entry; + { + int ret; + + if (!is_directory(entry)) + return; + + if ((ret = lookup_path(entry, NULL, NULL, 1)) <= 0) + fprintf(stderr, "Failed to create '%s' (%d, %d)\n", + entry, ret, errno); + } + + void + delete_entry_id(); + + void + add_entry_id(parent, rest) + sdword parent; + char *rest; + { + int ret; + sdword id; + char *entry; + + if ((ret = lookup_path_id(parent, rest, &id, NULL, 1)) <= 0) { + fprintf(stderr, "Failed to create %d/'%s' (%d, %d)\n", + parent, rest, ret, errno); + return; + } + if (verbose) + fprintf(stderr, "Created entry %d/'%s' (%d, %d) id = %d\n", + parent, rest, ret, errno, id); + + entry = equiv_path(id); + if (!is_directory(entry)) /* check existance in restrospect! */ + delete_entry_id(id); + flush_database(); + } + + void + add_entry_fid(parent, rest) + sdword parent; + char *rest; + { + int ret; + sdword id; + char *entry; + + if ((ret = lookup_path_id(parent, rest, &id, NULL, 1)) <= 0) { + fprintf(stderr, "Failed to create %d/'%s' (%d, %d)\n", + parent, rest, ret, errno); + return; + } + entry = equiv_path(id); + if (!is_file(entry)) /* check existance in restrospect! */ + delete_entry_id(id); + flush_database(); + } + + void + delete_entry(entry) + char *entry; + { + sdword id, parent; + datum data; + + if (is_directory(entry) || is_file(entry)) + return; + + if (lookup_path(entry, &id, &data, 0) > 0){ + (void) extract_entry(data, NULL, &parent, NULL, NULL); + do_delete_entry(id); + delete_child(parent, id); + flush_database(); + } + } + + void + delete_entry_id(id) + sdword id; + { + sdword parent; + datum data; + char *entry = equiv_path(id); + + if (is_directory(entry) || is_file(entry)) + return; + + data = get_datum(id); + if (data.dptr == NULL) + return; + if (extract_entry(data, NULL, &parent, NULL, NULL) < 0) + return; + do_delete_entry(id); + delete_child(parent, id); + flush_database(); + } + + void + delete_entry_fid(id) + sdword id; + { + sdword parent; + datum data; + char *entry = equiv_path(id); + + if (is_file(entry)) + return; + + data = get_datum(id); + if (data.dptr == NULL) + return; + if (extract_entry(data, NULL, &parent, NULL, NULL) < 0) + return; + do_delete_entry(id); + delete_child(parent, id); + flush_database(); + } + + void + move_entry(from, to) + char *from, *to; + { + datum data; + sdword id, from_parent, to_parent; + char to_directory[MAXPATHLEN]; + char *new_name; + char *name; + char *ptr; + + assert(to[0] == '/'); + + if (is_directory(from) || !is_directory(to)) + if (is_file(from) || !is_file(to)) + return; + + if (lookup_path(from, &id, &data, 0) <= 0) { + /* did not know previously! */ + add_entry(to); + return; + } + + if (lookup_path(to, NULL, NULL, 0) > 0) /* exists already! */ + return; + + extract_entry(data, &name, &from_parent, NULL, NULL); + + name = string_copy(name); /* just in case it gets clobbered */ + + ptr = rindex(to, '/'); + strcpy(to_directory, ""); + strncat(to_directory, to, ptr-to); + new_name = ptr+1; + + assert(new_name[0] != '\0'); + /* will happen for trailing /, so be careful */ + + lookup_path(to_directory, &to_parent, NULL, 1); + + fprintf(stderr, "Moving %d/%s to %d/%s\n", + from_parent, name, to_parent, new_name); + + if (from_parent != to_parent) { + /* NB it may be quicker to try compare the two strings */ + delete_child(from_parent, id); + add_child(to_parent, id); + } + + data = get_datum(id); /* get again - in case overwritten */ + data = modify_parent(data, to_parent); + if (strcmp(name, new_name) != 0) /* name change too */ + data = modify_name(data, new_name); + store_datum(id, data, DBM_REPLACE); + flush_database(); + } + + void + move_entry_id(from_parent, name, to_parent, new_name) + sdword from_parent, to_parent; + char *name, *new_name; + { + datum data; + sdword id; + char *ptr; + + + if (lookup_path_id(from_parent, name, &id, NULL, 0) <= 0) { + /* did not know previously! */ + add_entry_id(from_parent, name); + return; + } + + if (lookup_path_id(to_parent, new_name, NULL, NULL, 0) > 0) + /* exists already! */ + return; + + if (is_directory(equiv_path(id))||is_file(equiv_path(id))) + return; + + if (from_parent == to_parent) { + data = get_datum(id); /* get here in case corrupted earlier */ + data = modify_name(data, new_name); + store_datum(id, data, DBM_REPLACE); + } else { + delete_child(from_parent, id); + add_child(to_parent, id); + data = get_datum(id); /* get here in case corrupted earlier */ + data = modify_parent(data, to_parent); + if (strcmp(name, new_name) != 0) /* name change too */ + data = modify_name(data, new_name); + store_datum(id, data, DBM_REPLACE); + } + if (! is_directory(equiv_path(id)) && ! is_file(equiv_path(id))) + delete_entry_id(id); /* does not actually exist */ + else + flush_database(); + } + + void + rename_entry_id(id, new_name) + sdword id; + char *new_name; + { + datum data; + int ret; + + if (verbose) + fprintf(stderr, "rename_entry_id: %d -> %s\n", + id, new_name); + data = get_datum(id); + if (data.dptr == NULL) { + if (verbose) + fprintf(stderr, "Unknown id: %d\n", id); + /* did not know previously! */ + return; + } + data = modify_name(data, new_name); + if (ret = store_datum(id, data, DBM_REPLACE) < 0) + if (verbose) + fprintf(stderr, "rename_entry_id: store returned %d\n", + ret); + + if (! is_directory(equiv_path(id)) && ! is_file(equiv_path(id))) { + if (verbose) + fprintf(stderr, "rename_entry_id: Ooops! %s doesn't exist!\n", + equiv_path(id)); + delete_entry_id(id); /* does not actually exist */ + } else + flush_database(); + } + + void + rename_entry(path, new_name) + char *path, *new_name; + { + datum data; + sdword id; + char *ptr; + + if (lookup_path(path, &id, &data, 0) <= 0) { + /* did not know previously! */ + return; + } + data = modify_name(data, new_name); + store_datum(id, data, DBM_REPLACE); + + if (! is_directory(equiv_path(id)) && ! is_file(equiv_path(id))) + delete_entry_id(id); /* does not actually exist */ + else + flush_database(); + } + + void + clean_entries() + { + /* currently no-op */ + continue_clean = 0; + } + + void + session() + { + struct sockaddr addr; + int addrlen; + int sock; + char buff[2*MAXPATHLEN+3]; + char command, arg1[MAXPATHLEN], arg2[MAXPATHLEN]; + sdword id1, id2; + int count; + int prob, args, fileID; + + for (;;) { + fileID = 0; + addrlen = sizeof(struct sockaddr); + if ((sock = accept(queries, &addr, &addrlen)) < 0) + fatal("Accept"); + if ((count = recv(sock, buff, 2*MAXPATHLEN+3, 0)) < 0) + fatal("Recv"); + buff[count] = '\0'; + if (verbose && count > 0) + fprintf(stderr, "Received: '%s'\n", buff); + + prob = 0; + + if (buff[0] != '\0') { + command = buff[0]; + switch (command) { /* first decode arguments */ + case 'A': case 'D': + args = sscanf(buff+1, "%[^\277]\277", arg1); + break; + case 'M': + args = sscanf(buff+1, "%[^\277]\277%[^\277]\277", arg1, arg2); + break; + case 'R': + args = sscanf(buff+1, "%[^\277]\277%[^\277]\277", arg1, arg2); + break; + case 'a': + args = sscanf(buff+1, "%d\277%[^\277]\277", &id1, arg1); + break; + case 'f': + args = sscanf(buff+1, "%d\277%[^\277]\277", &id1, arg1); + break; + case 'd': + args = sscanf(buff+1, "%d\277", &id1); + break; + case 'm': + args = sscanf(buff+1, "%d\277%[^\277]\277%d\277%[^\277]\277", + &id1, arg1, &id2, arg2); + break; + case 'r': + args = sscanf(buff+1, "%d\277%[^\277]\277", &id1, arg1); + break; + } + + switch (command) { + case 'A': + if (args < 1 || arg1[0] != '/') + prob = 1; + else + add_entry(arg1); + break; + case 'a': + if (args < 2) + prob = 1; + else + add_entry_id(id1, arg1); + break; + case 'f': + if (args < 2) + prob = 1; + else + add_entry_fid(id1, arg1); + break; + case 'D': + if (args < 1 || arg1[0] != '/') + prob = 1; + else + delete_entry(arg1); + break; + case 'd': + if (args < 1) + prob = 1; + else + delete_entry_id(id1); + break; + case 'M': + if (args < 2 || arg1[0] != '/' || arg2[0] != '/') + prob = 1; + else + move_entry(arg1, arg2); + break; + case 'm': + if (args < 4) + prob = 1; + else + move_entry_id(id1, arg1, id2, arg2); + break; + case 'R': + if (args < 2 || arg1[0] != '/') + prob = 1; + else + rename_entry(arg1, arg2); + break; + case 'r': + if (args < 2) + prob = 1; + else + rename_entry_id(id1, arg1); + break; + case 'C': + clean_entries(); + break; + default: + prob = 1; + break; + } + } + if (prob) + fprintf(stderr, "Bad command '%s'\n", buff); + close(sock); + } + } + + /* + * disconnect code from aufs itself + * + */ + + void + do_disconnect() + { + if (fork()) + _exit(0); + { + int f; + + for (f = 0; f < 10; f++) + (void) close(f); + } + (void) open("/", 0); + #ifndef NODUP2 + (void) dup2(0, 1); + (void) dup2(0, 2); + #else NODUP2 + (void)dup(0); /* for slot 1 */ + (void)dup(0); /* for slot 2 */ + #endif NODUP2 + #ifndef POSIX + #ifdef TIOCNOTTY + { + int t; + + if ((t = open("/dev/tty", 2)) >= 0) { + ioctl(t, TIOCNOTTY, (char *)0); + (void) close(t); + } + } + #endif TIOCNOTTY + #ifdef xenix5 + /* + * USG process groups: + * The fork guarantees that the child is not a process group leader. + * Then setpgrp() can work, whick loses the controllong tty. + * Note that we must be careful not to be the first to open any tty, + * or it will become our controlling tty. C'est la vie. + * + */ + setpgrp(); + #endif xenix5 + #else POSIX + (void) setsid(); + #endif POSIX + } + + /* + * These are here to ensure we pick up these + * versions for the server, and not those in lib_client.c + * + */ + + int + amAufsExt() + { + return(1); + } + + /* + * flush_database: force any outstanding writes + * + */ + + void + flush_database() + { + extern void open_database( /* void */ ); + + dbm_close(db); + open_database(); + } + #else FIXED_DIRIDS + #include + main() + { + printf("afpidsrvr: not compiled with -DFIXED_DIRIDS\n"); + } + #endif FIXED_DIRIDS *** applications/aufs/afpidtool.c.orig Sat Apr 27 22:29:23 1996 --- applications/aufs/afpidtool.c Sat Apr 27 22:29:30 1996 *************** *** 0 **** --- 1,208 ---- + /* + * $Author: djh $ $Date: 1996/04/27 12:27:36 $ + * $Header: /mac/src/cap60/applications/aufs/RCS/afpidtool.c,v 2.1 1996/04/27 12:27:36 djh Rel djh $ + * $Revision: 2.1 $ + * + */ + + /* + * Tell the AUFS fixed directory ID sever to do some basic things + * + * John Forrest + * + */ + + #ifdef FIXED_DIRIDS + + #include + #include + #include + #include + #include + + #include "../../lib/afp/afpidaufs.h" + + int verbose = 0; + + void + fatal(message) + char *message; + { + if (message != NULL) + fprintf(stderr, "%s:", message); + if (errno > 0) + perror(""); + else + putc('\n', stderr); + exit(-1); + } + + void + fatal2(message, a1) + char *message, *a1; + { + fprintf(stderr, "afpidtool: fatal error: %s%s :", message, a1); + fatal(NULL); + } + + void + getcdwd(path, result) + char *path, *result; + { + char command [256]; + FILE *pwd; + + sprintf(command, "cd '%s'; pwd\n", path); + if ((pwd = popen(command, "r")) == NULL) + strcpy(result, ""); + else { + fgets(result, MAXPATHLEN, pwd); + pclose(pwd); + if (result[0] != '/') + strcpy(result, ""); + result[strlen(result)-1] = '\0'; /* remove trailing lf */ + } + } + + void + doFullPath(path, fullPath) + char *path, *fullPath; + { + char *ptr; + + if (path[0] == '\0') + getwd(fullPath); + else + if (is_directory(path)) + getcdwd(path, fullPath); + else + if ((ptr = (char *)rindex(path, '/')) != NULL) { + *ptr = '\0'; + doFullPath(path, fullPath); + strcat(fullPath, "/"); + strcat(fullPath, ptr+1); + } else { /* directory name only */ + doFullPath("", fullPath); + strcat(fullPath, "/"); + strcat(fullPath, path); + } + } + + char *fullpath(path) + char *path; + { + char temp[MAXPATHLEN]; + char fullPath[MAXPATHLEN]; + + if (is_directory(path)) + getcdwd(path, fullPath); + else { + strcpy(temp, path); + doFullPath(path, fullPath); + } + + return string_copy(fullPath); + } + + main(argc, argv) + int argc; + char *argv[]; + { + int c; + extern char *optarg; + extern optind; + char *arg1, *arg2; + sdword id1, id2; + + int res; + + while ((c = getopt(argc, argv, "vn:a:m:d:r:cN:A:D:M:R:")) != -1) { + switch (c) { + case 'v': + verbose = 1; + break; + case 'n': case 'a': + arg1 = fullpath(optarg); + if (verbose) + fprintf(stderr, "New %s\n", arg1); + if (send_new(arg1) < 0) + fatal("Sending new"); + break; + case 'N': case 'A': + id1 = atoi(optarg); + arg1 = argv[optind++]; + if (verbose) + fprintf(stderr, "New %d/%s\n", id1, arg1); + if (send_new_id(id1,arg1) < 0) + fatal("Sending new"); + break; + case 'd': + arg1 = fullpath(optarg); + if (verbose) + fprintf(stderr, "Delete %s\n", arg1); + if (send_delete(arg1) < 0) + fatal("Sending delete"); + break; + case 'D': + id1 = atoi(optarg); + if (verbose) + fprintf(stderr, "Delete %d\n", id1); + if (send_delete_id(id1) < 0) + fatal("Sending delete"); + break; + case 'm': + arg1 = fullpath(optarg); + arg2 = fullpath(argv[optind++]); + if (verbose) + fprintf(stderr, "Move %s -> %s\n", arg1, arg2); + if (send_move(arg1, arg2) < 0) + fatal("Sending move"); + break; + case 'M': + id1 = atoi(optarg); + arg1 = argv[optind++]; + id2 = atoi(argv[optind++]); + arg2 = argv[optind++]; + if (verbose) + fprintf(stderr, "Move %d/%s -> %s\n", + id1, arg1, id2, arg2); + if (send_move_id(id1, arg1, id2, arg2) < 0) + fatal("Sending move"); + break; + case 'r': + arg1 = fullpath(optarg); + arg2 = argv[optind++]; + if (verbose) + fprintf(stderr, "Rename %s -> %s\n", arg1, arg2); + if (send_rename(arg1, arg2) < 0) + fatal("Sending rename"); + break; + case 'R': + id1 = atoi(optarg); + arg1 = argv[optind++]; + if (verbose) + fprintf(stderr, "Rename %d -> %s\n", id1, arg1); + if (send_rename_id(id1, arg1) < 0) + fatal("Sending rename"); + break; + case 'c': + if (verbose) + fprintf(stderr, "Clean\n"); + if (send_clean() < 0) + fatal("Sending clean"); + break; + case '?': + fprintf(stderr, + "usage: afpidtool [-v] [-n path] [-d path] [-m from to]\n"); + exit(-1); + } + } + exit(0); + } + #else FIXED_DIRIDS + #include + main() + { + printf("afpidtool: not compiled with -DFIXED_DIRIDS\n"); + } + #endif FIXED_DIRIDS *** applications/papif/papif.c.orig Tue Aug 29 11:55:54 1995 --- applications/papif/papif.c Sun Apr 28 17:12:57 1996 *************** *** 1,6 **** ! static char rcsid[] = "$Author: djh $ $Date: 1995/08/29 01:55:40 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/applications/papif/RCS/papif.c,v 2.22 1995/08/29 01:55:40 djh Rel djh $"; ! static char revision[] = "$Revision: 2.22 $"; /* * papif - UNIX AppleTalk test program: simple line printer input filter --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1996/04/28 07:12:46 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/applications/papif/RCS/papif.c,v 2.25 1996/04/28 07:12:46 djh Rel djh $"; ! static char revision[] = "$Revision: 2.25 $"; /* * papif - UNIX AppleTalk test program: simple line printer input filter *************** *** 34,39 **** --- 34,40 ---- #include #include /* include appletalk definitions */ + #include #include #ifdef USESTRINGDOTH # include *************** *** 51,56 **** --- 52,58 ---- #endif xenix5 #ifdef SOLARIS # include + # include #endif SOLARIS /* Configuration options */ *************** *** 481,487 **** *printer = *user = *host = '\0'; /* init to nothing */ *acctfile = NULL; ! for (i=0; i #include /* include appletalk definitions */ + #include #include #include #include "../../lib/cap/abpap.h" /* urk, puke, etc */ *************** *** 64,69 **** --- 65,75 ---- # include #endif NEEDFCNTLDOTH + #ifdef SOLARIS + #include + #define gethostname(n,l) (sysinfo(SI_HOSTNAME,(n),(l)) == (1) ? 0 : -1) + #endif SOLARIS + #ifdef LWSRV8 #include "list.h" #include "query.h" *************** *** 1412,1418 **** --- 1418,1428 ---- /* need for multi-forking, nice for single forking */ /* handle the connection in cno */ openlogfile(); + #ifdef SOLARIS + signal(SIGCHLD,SIG_DFL); + #else SOLARIS signal(SIGCHLD,SIG_IGN); + #endif SOLARIS #ifdef AUTHENTICATE if (nprt != 1) initauthenticate(*argv, prtp->prtname); *************** *** 1441,1446 **** --- 1451,1461 ---- void cMac2ISO(), cISO2Mac(); #endif ISO_TRANSLATE + if (myname = rindex(argv[0], '/')) + myname++; + else + myname = argv[0]; + doargs(argc,argv); /* handle args */ #ifdef LWSRV_AUFS_SECURITY *************** *** 1710,1716 **** --- 1725,1735 ---- /* need for multi-forking, nice for single forking */ /* handle the connection in cno */ openlogfile(); + #ifdef SOLARIS + signal(SIGCHLD,SIG_DFL); + #else SOLARIS signal(SIGCHLD,SIG_IGN); + #endif SOLARIS #ifdef AUTHENTICATE if (nprt != 1) initauthenticate(*argv, (char *)prtlist[prtno].prtname); *************** *** 1846,1855 **** #ifdef NeXT char dpistring[6]; #endif NeXT - #ifdef SOLARIS - pid_t pidf; - char outbuf[BUFSIZ]; - #endif SOLARIS #ifdef RUN_AS_USER int uid; #endif RUN_AS_USER --- 1865,1870 ---- *************** *** 1892,1898 **** perror(tname); #ifndef aux #if defined(__hpux) || defined(SOLARIS) ! if (setvbuf(outfile, NULL, _IOLBF, 256) != 0) perror(tname); #else /* __hpux || SOLARIS */ setlinebuf(outfile); --- 1907,1913 ---- perror(tname); #ifndef aux #if defined(__hpux) || defined(SOLARIS) ! if (setvbuf(outfile, NULL, _IOLBF, 0) != 0) perror(tname); #else /* __hpux || SOLARIS */ setlinebuf(outfile); *************** *** 2120,2125 **** --- 2135,2141 ---- childargv[argc++]=dpistring; } #endif NeXT + rhbuf[0] = rhbuf[1] = '\0'; #ifdef xenix5 /* will this work ... ? */ sprintf(rhbuf,"-%s%s",rflag ? "" : "r",hflag ? "" : "ob"); *************** *** 2132,2142 **** #endif xenix5 if (rhbuf[1] != '\0') childargv[argc++]=rhbuf; /* include h and/or r flags */ #ifndef USESYSVLP - #ifndef NOSYMLINK childargv[argc++]="-s"; /* better for > 1M files */ - #endif NOSYMLINK #endif USESYSVLP #ifdef LPRARGS if (lprargs) { register int n = NList(lprargs); --- 2148,2158 ---- #endif xenix5 if (rhbuf[1] != '\0') childargv[argc++]=rhbuf; /* include h and/or r flags */ + #ifdef USELPRSYM #ifndef USESYSVLP childargv[argc++]="-s"; /* better for > 1M files */ #endif USESYSVLP + #endif USELPRSYM #ifdef LPRARGS if (lprargs) { register int n = NList(lprargs); *************** *** 2325,2333 **** mktemp(tname); } ! if ((outfile = fopen(tname, "w+")) == NULL) { perror(tname); ! } if (singlefork) NewStatus("initializing"); --- 2341,2350 ---- mktemp(tname); } ! if ((outfile = fopen(tname, "w+")) == NULL) perror(tname); ! ! chmod(tname, 0600); if (singlefork) NewStatus("initializing"); *************** *** 2506,2511 **** --- 2523,2529 ---- childargv[argc++]=dpistring; } #endif NeXT + rhbuf[0] = rhbuf[1] = '\0'; #ifdef xenix5 /* will this work ... ? */ sprintf(rhbuf,"-%s%s",rflag ? "" : "r",hflag ? "" : "ob"); *** lib/cap/abatp.h.orig Tue Sep 28 18:28:30 1993 --- lib/cap/abatp.h Mon Mar 11 20:47:27 1996 *************** *** 1,8 **** /* ! * $Author: djh $ $Date: 1993/09/28 08:28:07 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abatp.h,v 2.2 1993/09/28 08:28:07 djh Rel djh $ ! * $Revision: 2.2 $ ! */ /* * abatp.c - Appletalk Transaction Protocol header file (internal only) --- 1,9 ---- /* ! * $Author: djh $ $Date: 1996/03/11 09:47:07 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abatp.h,v 2.3 1996/03/11 09:47:07 djh Rel djh $ ! * $Revision: 2.3 $ ! * ! */ /* * abatp.c - Appletalk Transaction Protocol header file (internal only) *************** *** 16,22 **** * * June 30, 1986 CCKim Created * ! */ #define atpheaderlength (atpSize+lapSize+ddpSize) --- 17,23 ---- * * June 30, 1986 CCKim Created * ! */ #define atpheaderlength (atpSize+lapSize+ddpSize) *************** *** 111,116 **** --- 112,118 ---- private TCB *find_tcb_abr(); private RqCB *create_rqcb(); + private RqCB *find_rqcb_abr(); private RqCB *find_rqcb(); private delete_rqcb(); *** lib/cap/abatp.c.orig Fri Dec 24 15:28:51 1993 --- lib/cap/abatp.c Mon Mar 11 20:39:48 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1993/12/24 04:28:29 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abatp.c,v 2.7 1993/12/24 04:28:29 djh Rel djh $ ! * $Revision: 2.7 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/03/11 09:39:33 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abatp.c,v 2.8 1996/03/11 09:39:33 djh Rel djh $ ! * $Revision: 2.8 $ * */ *************** *** 164,174 **** } /* * ATPReqCancel * ! * cancel an outstanding ATP request * ! */ OSErr ATPReqCancel(abr, async) ABusRecord *abr; --- 164,197 ---- } /* + * ATPKillGetReq + * + * cancel an outstanding ATPGetRequest + * + */ + + OSErr + ATPKillGetReq(abr, async) + ABusRecord *abr; + boolean async; + { + RqCB *rqcb; + + rqcb = find_rqcb_abr(abr); + if (rqcb == NULL) + return(cbNotFound); + rqcb->abr->abResult = sktClosed; + delete_rqcb(rqcb); + return(noErr); + } + + /* * ATPReqCancel * ! * cancel an outstanding ATPSndRequest * ! */ ! OSErr ATPReqCancel(abr, async) ABusRecord *abr; *************** *** 1270,1276 **** /* * Find the first RqCB found for the socket * ! */ private boolean match_rqcb(rqcb, skt) RqCB *rqcb; --- 1293,1316 ---- /* * Find the first RqCB found for the socket * ! */ ! ! private boolean ! match_rqcb_abr(rqcb, abr) ! RqCB *rqcb; ! ABusRecord *abr; ! { ! return(abr == rqcb->abr); ! } ! ! private RqCB * ! find_rqcb_abr(abr) ! ABusRecord *abr; ! { ! return((RqCB *)q_mapf(rqcblist[rqcb_hash(abr->proto.atp.atpSocket)], ! match_rqcb_abr, abr)); ! } ! private boolean match_rqcb(rqcb, skt) RqCB *rqcb; *************** *** 1289,1296 **** /* * remove the specified rqcb from the active list * ! */ ! private delete_rqcb(rqcb) RqCB *rqcb; { --- 1329,1338 ---- /* * remove the specified rqcb from the active list * ! */ ! ! private ! delete_rqcb(rqcb) RqCB *rqcb; { *** lib/cap/abnbp.c.orig Wed Aug 4 02:15:56 1993 --- lib/cap/abnbp.c Thu Mar 7 20:14:12 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1993/08/03 16:15:37 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abnbp.c,v 2.6 1993/08/03 16:15:37 djh Rel djh $ ! * $Revision: 2.6 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/03/07 09:13:56 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abnbp.c,v 2.7 1996/03/07 09:13:56 djh Rel djh $ ! * $Revision: 2.7 $ */ /* *************** *** 627,633 **** * entity should always be updated so that a very long term * NBPLookup can get network changes. * ! */ private int nbpcpy(pr,nbp) --- 627,633 ---- * entity should always be updated so that a very long term * NBPLookup can get network changes. * ! */ private int nbpcpy(pr,nbp) *************** *** 640,672 **** /* Add NBP tuples to user's data structure */ ! en = (NBPTEntry *) pr->nbpBufPtr; ! ! /* check if this entry is already in the table... */ ! /* XXX ok to just check the address? */ ! ! for (i = 0; i < (int)pr->nbpDataField; i++) ! if (bcmp(&en[i].addr,&nbp->tuple[0].addr,sizeof(AddrBlock)) == 0) ! return(1); /* identical address return */ for (ep = &nbp->tuple[0]; nbp->tcnt != 0; nbp->tcnt--) { ! ! i = pr->nbpDataField; /* count of tubles */ if (i > pr->nbpMaxEnt) /* more than wanted? */ return(nbpBuffOvr); /* yes, return now... */ - - #ifdef notdef - en[i].addr = ep->addr; /* copy the address to user */ - #else - /* work around possible alignment problem (shows up on sun) */ bcopy(&ep->addr, &en[i].addr, sizeof(AddrBlock)); - #endif len = pkt2c_ename(ep->name,&en[i].ent); pr->nbpDataField++; /* one more entry */ ! ep = (NBPTuple *) ((char *) ep+(len+sizeof(AddrBlock)+1)); } if (pr->nbpDataField == pr->nbpMaxEnt) return(noErr); return(1); } --- 640,665 ---- /* Add NBP tuples to user's data structure */ ! en = (NBPTEntry *)pr->nbpBufPtr; for (ep = &nbp->tuple[0]; nbp->tcnt != 0; nbp->tcnt--) { ! /* check if this tuple entry is already in the table... */ ! for (i = 0; i < (int)pr->nbpDataField; i++) ! if (bcmp(&en[i].addr, &ep->addr, sizeof(AddrBlock)) == 0) ! break; /* found identical */ ! if (i != pr->nbpDataField) ! continue; /* try next entry */ if (i > pr->nbpMaxEnt) /* more than wanted? */ return(nbpBuffOvr); /* yes, return now... */ bcopy(&ep->addr, &en[i].addr, sizeof(AddrBlock)); len = pkt2c_ename(ep->name,&en[i].ent); pr->nbpDataField++; /* one more entry */ ! ep = (NBPTuple *)((char *)ep+(len+sizeof(AddrBlock)+1)); } + if (pr->nbpDataField == pr->nbpMaxEnt) return(noErr); + return(1); } *** lib/cap/abmisc.c.orig Mon Aug 23 22:14:48 1993 --- lib/cap/abmisc.c Thu Mar 7 22:42:14 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1993/08/23 12:14:35 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abmisc.c,v 2.7 1993/08/23 12:14:35 djh Rel djh $ ! * $Revision: 2.7 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/03/07 11:42:04 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abmisc.c,v 2.8 1996/03/07 11:42:04 djh Rel djh $ ! * $Revision: 2.8 $ * */ *************** *** 611,616 **** --- 611,626 ---- } return; + } + + int + isISOprint(c) + u_char c; + { + if (c & 0x80) + return(ISO2Mac[c]); + else + return(isprintf(c); } #endif ISO_TRANSLATE *** samples/atlook.c.orig Mon Oct 24 16:43:46 1994 --- samples/atlook.c Mon Mar 11 15:20:40 1996 *************** *** 1,6 **** ! static char rcsid[] = "$Author: djh $ $Date: 1994/10/24 06:43:36 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/samples/RCS/atlook.c,v 2.12 1994/10/24 06:43:36 djh Rel djh $"; ! static char revision[] = "$Revision: 2.12 $"; /* * atlook - UNIX AppleTalk test program: lookup entities --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1996/03/11 04:20:29 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/samples/RCS/atlook.c,v 2.14 1996/03/11 04:20:29 djh Rel djh $"; ! static char revision[] = "$Revision: 2.14 $"; /* * atlook - UNIX AppleTalk test program: lookup entities *************** *** 142,148 **** [-r ] [-l ] nbpentity\n",s); fprintf(stderr,"\t -n means sort by net numbers\n"); fprintf(stderr,"\t -s means sort by socket numbers\n"); ! fprintf(stderr,"\t -r - specifies number of retries (>=0)\n"); fprintf(stderr,"\t -t [p] - timeout between retries\n"); fprintf(stderr,"\t unless timeout modified by 'p' for ping timeout\n"); fprintf(stderr,"\t -l - specifies ping packet length\n"); --- 142,148 ---- [-r ] [-l ] nbpentity\n",s); fprintf(stderr,"\t -n means sort by net numbers\n"); fprintf(stderr,"\t -s means sort by socket numbers\n"); ! fprintf(stderr,"\t -r - specifies number of retries (>0)\n"); fprintf(stderr,"\t -t [p] - timeout between retries\n"); fprintf(stderr,"\t unless timeout modified by 'p' for ping timeout\n"); fprintf(stderr,"\t -l - specifies ping packet length\n"); *************** *** 389,394 **** --- 389,400 ---- dumptostr(name+len, en->zoneStr.s); printf("Looking for %s ...\n",name); + #ifdef ISO_TRANSLATE + cISO2Mac(en->objStr.s); + cISO2Mac(en->typeStr.s); + cISO2Mac(en->zoneStr.s); + #endif ISO_TRANSLATE + /* * Find all objects in specified zone * *************** *** 503,508 **** --- 509,521 ---- printf("Address confirmed for socket %d\n",nbpr.nbpDataField); } + #ifdef ISO_TRANSLATE + # ifdef isprint + # undef isprint + # endif isprint + #define isprint isISOprint + #endif ISO_TRANSLATE + /* * Dump a PAP status message */ *************** *** 529,535 **** --- 542,552 ---- int i = 0; while ((c = *todump++)) { + #ifndef ISO_TRANSLATE if (c > 0 && isprint(c)) { + #else ISO_TRANSLATE + if (isprint(c)) { + #endif ISO_TRANSLATE *str++ = c; i++; } else { *** lib/cap/abpapc.c.orig Thu Jan 14 23:59:34 1993 --- lib/cap/abpapc.c Thu Apr 25 11:01:55 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1993/01/14 12:59:27 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abpapc.c,v 2.2 1993/01/14 12:59:27 djh Rel djh $ ! * $Revision: 2.2 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 01:01:44 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abpapc.c,v 2.3 1996/04/25 01:01:44 djh Rel djh $ ! * $Revision: 2.3 $ */ /* *************** *** 122,128 **** if (!getpname(&addr,&en)) { sprintf((char *)statusbuff->StatusStr+1, ! "%Can't find %s",printername); statusbuff->StatusStr[0] = (byte)(strlen(statusbuff->StatusStr+1)+1); return(-1); } --- 122,128 ---- if (!getpname(&addr,&en)) { sprintf((char *)statusbuff->StatusStr+1, ! "%%Can't find %s",printername); statusbuff->StatusStr[0] = (byte)(strlen(statusbuff->StatusStr+1)+1); return(-1); } *** lib/afp/Makefile.m4.orig Mon Jun 19 11:31:20 1995 --- lib/afp/Makefile.m4 Sat Apr 27 23:16:38 1996 *************** *** 5,12 **** I=includedir() DES=desloc() ! LIBAFPSRCS=afperr.c afpcmd.c afppacks.c afposlock.c afppass.c ! LIBAFPOBJS=afperr.o afpcmd.o afppacks.o afposlock.o des.o afppass.o $(LIBAFP): $(LIBAFPOBJS) ifdef([uselordertsort],[ar cr $(LIBAFP) `lorder $(LIBAFPOBJS)| tsort`], --- 5,14 ---- I=includedir() DES=desloc() ! LIBAFPSRCS=afperr.c afpcmd.c afppacks.c afposlock.c afppass.c \ ! afpidaufs.c afpidclnt.c afpidgnrl.c ! LIBAFPOBJS=afperr.o afpcmd.o afppacks.o afposlock.o des.o afppass.o \ ! afpidaufs.o afpidclnt.o afpidgnrl.o $(LIBAFP): $(LIBAFPOBJS) ifdef([uselordertsort],[ar cr $(LIBAFP) `lorder $(LIBAFPOBJS)| tsort`], *************** *** 50,53 **** --- 52,59 ---- afposlock.o: afposlock.c $I/netat/appletalk.h $I/netat/aberrors.h \ $I/netat/abqueue.h $I/netat/sysvcompat.h \ $I/netat/afp.h $I/netat/afpcmd.h + + afpidaufs.o: afpidaufs.c afpidaufs.h afpidnames.h + afpidclnt.o: afpidclnt.c afpidaufs.h afpidnames.h + afpidgnrl.o: afpidgnrl.c afpidaufs.h afpidnames.h afppass.o: afppass.c $I/netat/afppass.h *** lib/afp/afposlock.c.orig Mon Aug 28 07:59:27 1995 --- lib/afp/afposlock.c Thu Mar 7 20:53:04 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/08/27 21:59:04 $ ! * $Header: /mac/src/cap60/lib/afp/RCS/afposlock.c,v 2.11 1995/08/27 21:59:04 djh Rel djh $ ! * $Revision: 2.11 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/03/07 09:52:04 $ ! * $Header: /mac/src/cap60/lib/afp/RCS/afposlock.c,v 2.12 1996/03/07 09:52:04 djh Rel djh $ ! * $Revision: 2.12 $ * */ *************** *** 178,184 **** startendflag ? "end" : "start"); #endif DEBUG ! if (length < 0) /* can only be -1 */ length = 0; /* length zero means entire file! */ #ifdef USEFCNTLLOCK --- 178,185 ---- startendflag ? "end" : "start"); #endif DEBUG ! if (length < 0 /* can only be -1 */ ! || length == 0x7fffffff) /* or magic flag used by MicroSoft */ length = 0; /* length zero means entire file! */ #ifdef USEFCNTLLOCK *** lib/afp/afppacks.c.orig Mon Jun 19 11:31:19 1995 --- lib/afp/afppacks.c Thu Apr 25 13:26:47 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/06/19 01:31:07 $ ! * $Header: /mac/src/cap60/lib/afp/RCS/afppacks.c,v 2.4 1995/06/19 01:31:07 djh Rel djh $ ! * $Revision: 2.4 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 03:26:19 $ ! * $Header: /mac/src/cap60/lib/afp/RCS/afppacks.c,v 2.5 1996/04/25 03:26:19 djh Rel djh $ ! * $Revision: 2.5 $ * */ *************** *** 718,722 **** --- 718,749 ---- PACK(SrvrMsgReplyPtr, P_WORD, msgr_typ), /* message type */ PACK(SrvrMsgReplyPtr, P_WORD, msgr_bitmap), /* bitmap */ PAKS(SrvrMsgReplyPtr, P_PSTR, msgr_data), /* message string */ + PACKEND() + }; + + PackEntry ProtoCreateID[] = { /* CreateID */ + PACK(CreateIDPtr, P_BYTE, crid_cmd), /* command */ + PACK(CreateIDPtr, P_ZERO, crid_zero), /* always zero */ + PACK(CreateIDPtr, P_WORD, crid_volid),/* volume id */ + PACK(CreateIDPtr, P_DWRD, crid_dirid),/* directory id */ + PACK(CreateIDPtr, P_BYTE, crid_ptype),/* path type */ + PAKS(CreateIDPtr, P_PATH, crid_path), /* path */ + PACKEND() + }; + + PackEntry ProtoDelID[] = { /* DeleteID */ + PACK(DeleteIDPtr, P_BYTE, did_cmd), /* command */ + PACK(DeleteIDPtr, P_ZERO, did_zero), /* always zero */ + PACK(DeleteIDPtr, P_WORD, did_volid), /* volume id */ + PACK(DeleteIDPtr, P_DWRD, did_fileid), /* file id */ + PACKEND() + }; + + PackEntry ProtoRslvID[] = { /* ResolveID */ + PACK(ResolveIDPtr, P_BYTE, rid_cmd), /* command */ + PACK(ResolveIDPtr, P_ZERO, rid_zero), /* always zero */ + PACK(ResolveIDPtr, P_WORD, rid_volid), /* volume id */ + PACK(ResolveIDPtr, P_DWRD, rid_fileid), /* file id */ + PACK(ResolveIDPtr, P_WORD, rid_fbitmap), /* bitmap */ PACKEND() }; *** lib/afp/afpidaufs.h.orig Sat Apr 27 22:34:30 1996 --- lib/afp/afpidaufs.h Sat Apr 27 22:33:29 1996 *************** *** 0 **** --- 1,172 ---- + /* + * $Author: djh $ $Date: 1996/04/27 12:31:28 $ + * $Header: /mac/src/cap60/lib/afp/RCS/afpidaufs.h,v 2.1 1996/04/27 12:31:28 djh Rel djh $ + * $Revision: 2.1 $ + * + */ + + /* + * AUFS fixed directory IDs + * + * joint declarations for libafp.a + * + * John Forrest + * + */ + + #ifndef _afpidaufs_h + #define _afpidaufs_h + + #include + #include + #include + + #include "afpidnames.h" + + #ifndef LAP_ETALK /* not included before */ + #include + #endif LAP_ETALK + + /* query_socket: create socket for use for queries */ + int query_socket( /* void */ ); + + /* connect_query: connect created socket to query entry */ + int connect_query( /* int sock */ ); + + /* query_addr: setup pointer to query socket, and give socket length */ + void query_addr (/* sockaddr **addr, int *len */); + + /* is_directory: return true if a directory of this name exists */ + int is_directory ( /* char *name */ ); + + /* number_datum: returns properly setup datum for an external num */ + datum num_datum ( /* sdword num */ ); + + /* num_from_datum: returns numerical value in number datum */ + sdword num_from_datum ( /* datum dat */ ); + + /* new_entry: create virgin directory entry - assume exists */ + datum new_entry ( /* char *name, sdword parent */ ); + + /* modify: modify the given entry as appropriate - given new */ + datum modify_name ( /* datum entry, char *new_name */ ); + datum modify_parent ( /* datum entry, sdword parent */ ); + datum modify_children ( /* datum entry, int num_children, + sdword *children */ ); + + /* create_entry: create entry datum */ + datum create_entry ( /* char *name, sdword parent, + int num_children, sdword *children */ ); + + /* extract_entry: get data from entry. Returns neg on error. + NB. if NULL is given as actual param, will not return that + particular field. */ + int extract_entry ( /* datum entry, char **name, sdword *parent, + int *num_children, sdword **children */ ); + + /* copy_children: take copy of children (eg as returned by + extract_children). Needed because areas from db are static. */ + sdword *copy_children (/* sdword *children, int num_children */); + + /* lookup_path: if "create" then create elements as needs (from server only). + Return positive on found, neg on error, 0 if not found. Set id and data if found. */ + int lookup_path (/* char *path, sdword *id, data data, int create */); + + /* lookup_path_id: similar, but from already known parent */ + int lookup_path_id + (/* sdword parent, char *remaining, sdword *id, data data, int create */); + + /* get_datum: get datum for an id. result.dptr == NULL if not found */ + datum get_datum ( /* sdword id */ ); + + /* store_datum: write value for id to d/b */ + int store_datum ( /* sdword id, datum data, int flags */ ); + + /* do_delete_entry: delete entry data, but not the record in its parent. */ + void do_delete_entry ( /* sdword id */); + + /* add_child: add a child to its parents record */ + int add_child (/* sdword id, sdword child */); + + /* delete_child: delete a child from its parents record */ + int delete_child (/* sdword id, sdword child */); + + /* equiv_path. Given id, return equiv filename, NULL if not found */ + char *equiv_path (/* sdword id */); + + /* create_init: create initial datum contents */ + datum create_init ( /* char *version, sdword rootEid */ ); + + /* extract_init: extract initial datum contents */ + int extract_init ( /* datum initial, char **version, sdword *rootEid */ ); + + /* valid_id: returns random external id in valid range */ + sdword valid_id( /* void */ ); + + /* init_aufsExt: initialise library */ + void init_aufsExt ( /* void */ ); + + /* open_dbase: open database for reading, and check version if first */ + int open_dbase ( /* int first */ ); + + /* close_dbase: close database */ + void close_dbase ( /* void */ ); + + /* flush_database: force write - used in server only */ + void flush_database( /* void */ ); + + /* poll_db: if db has been changed since open, close and reopen. + returns 0 if has changed, pos if no change, neg on error. + if force, reopen anyway. + */ + int poll_db ( /* int force */ ); + + /* amAufsExt: 1 in server, 0 in clients */ + int amAufsExt ( /* void */); + + /* string_copy: general string copy routine. Should not + really be here! */ + char *string_copy ( /* char * */ ); + + /* send_X: send commands to the server. Neg result on error. */ + int send_new ( /* char *path */); + int send_new_id ( /* sdword parent, char *remaining */); + int send_delete ( /* char *path */); + int send_delete_id ( /* sdword id */ ); + int send_move ( /* char *from, char *to */); + int send_move_id ( /* sdword from_parent, char *old_name, + sdword to_parent, char*new_name */); + int send_rename ( /* char *old_path, char *new_name */); + int send_rename_id ( /* sdword id, char *new_name */ ); + int send_clean ( /* void */ ); + + #define is_init_datum(dat) (dat.dsize == 2 && dat.dptr[0]=='I' && dat.dptr[1] == '\0') + #define is_num_datum(dat) (dat.dptr[0]=='N') + + extern char * aufsSockname; + extern char * aufsDbName; + extern char * aufsDbVersion; + extern DBM *db; + extern sdword rootEid; + extern char * aufsRootName; + + /* The following are intended to be called from aufs */ + + /* initialise - call before other routines */ + void aufsExtInit ( /* void */ ); + + sdword aufsExtEDir ( /* char *path */ ); + sdword aufsExtEDirId ( /* sdword parent, char *name */ ); + char *aufsExtPath ( /* sdword edir */ ); + void aufsExtDel ( /* char *path */ ); + void aufsExtDelId ( /* sdword edir */ ); + void aufsExtMove ( /* char *from, *to */ ); + void aufsExtMoveId ( /* char *origPath, sdword newParent, + char *newName */ ); + void aufsExtMoveIds ( /* sdword orig, sdword newParent, + char *newName */ ); + void aufsExtRename ( /* char *origPath, char *newName */ ); + void aufsExtRenameId ( /* sdword edir, char *newName */ ); + sdword aufsExtLookForId ( /* sdword parent, char *name */ ); /* -1 if not found */ + + #endif /* _afpidaufs_h */ *** lib/afp/afpidaufs.c.orig Sat Apr 27 22:34:30 1996 --- lib/afp/afpidaufs.c Wed May 1 02:07:43 1996 *************** *** 0 **** --- 1,631 ---- + /* + * $Author: djh $ $Date: 1996/04/30 16:07:19 $ + * $Header: /mac/src/cap60/lib/afp/RCS/afpidaufs.c,v 2.3 1996/04/30 16:07:19 djh Rel djh $ + * $Revision: 2.3 $ + * + */ + + /* + * AUFS fixed directory IDs + * + * These routines provide the external <-> path mechanism for + * aufs itself. As well as the direct approach there is a backup + * mechanism using a direct table. This is not very efficient, + * and should not be used normally. It is intended to avoid + * crashing aufs if the server falls over for some reason. + * + * John Forrest + * + */ + + #ifdef FIXED_DIRIDS + + #include + #include + #include + #include + #include + + #include "afpidaufs.h" + #include "../../applications/aufs/afps.h" + + typedef struct { + sdword ext; + char *path; + } Xtable; + + #define TimeOut (15) /* time to wait for answer from server */ + + static Xtable *extras; + static int num_extras; + static int db_open; + static int server_probs; + + static + void check_db() + { + if (db_open) { + int temp = poll_db(FALSE); + + if (temp < 0) { + db_open = 0; + if (DBDIR) + logit(0, "Can't poll database %d\n", temp); + } + } + } + + void + aufsExtInit() + { + int temp; + + init_aufsExt(); + + if ((temp = open_dbase(TRUE)) >= 0) { + db_open = 1; + } else { + db_open = 0; + logit(0, "Can't open database %d\n",temp); + } + server_probs = 0; + extras = NULL; + } + + static int + existing_entry(id) + sdword id; + { + datum contents; + + contents = get_datum(id); + return(contents.dptr != NULL); + } + + static sdword + add_to_extras(path) + char *path; + { + for ( ; ; ) { + int found = 0; + sdword try = valid_id(); + + if (db_open && existing_entry(try)) /* first check in database */ + continue; + + if (extras != NULL) { /* and check for dup in Xtras */ + Xtable *ptr; + int found = 0; + + for (ptr = extras; ptr->path != NULL; ptr++) { + if (ptr->ext == try) { + found = 1; + break; + } + } + if (found) + continue; + } + + /* have unique id! */ + + if (extras == NULL) { + num_extras = 2; + extras = (Xtable *)calloc(num_extras, sizeof(*extras)); + } else { + num_extras += 1; + extras = (Xtable *)realloc(extras, num_extras*sizeof(*extras)); + extras[num_extras-1] = extras[num_extras-2]; + } + extras[num_extras-2].ext = try; + extras[num_extras-2].path = (char *)malloc(strlen(path)+1); + strcpy(extras[num_extras-2].path, path); + return(try); + } + /* NOTREACHED */ + } + + sdword + aufsExtFindId (path) + char *path; + { + int i, res; + + if (db_open) + check_db(); + + if (db_open) { + sdword id; + + /* have we got an existing entry ? */ + if (lookup_path(path, &id, NULL, 0) > 0) + return(id); + } + + /* + * No, return an error + */ + return (-1); + } + + void + aufsExtExchange(apath, bpath) + char *apath, *bpath; + { + sdword aID, bID; + char t_path[MAXPATHLEN]; + char *t_ptr; + char *tname = ".txxx"; + + /* + * Get the ID's + */ + aID = aufsExtFindId(apath); + bID = aufsExtFindId(bpath); + if (aID >= 0 && bID >= 0) { + /* + * Both have fileID's -- need to do three renames + */ + strcpy(t_path, apath); + t_ptr = (char *)strrchr(t_path, '/'); + if (t_ptr) { + t_ptr++; + strcpy(t_ptr, tname); + } + aufsExtRename(apath, t_path); + aufsExtRename(bpath, apath); + aufsExtRename(t_path, bpath); + } else if (aID >= 0) { + /* + * Only aID has a filID -- rename to bpath + */ + aufsExtRename(apath, bpath); + } else if (bID >= 0) { + /* + * Only bID has a filID -- rename to apath + */ + aufsExtRename(bpath, apath); + } + return; + } + + sdword + aufsExtEDir(path) + char *path; + { + int i, res; + + if (db_open) + check_db(); + + if (db_open) { + sdword id; + + /* have we got an existing entry ? */ + if (lookup_path(path, &id, NULL, 0) > 0) + return(id); + + /* ask the server to create a new record - even if having problems */ + if ((res = send_new(path)) >= 0 && server_probs < 5) { + for (i = 0; i < TimeOut*4; i++) { + int poll; + + abSleep(1, FALSE); /* wait 0.25s! */ + poll = poll_db( i%(4*4) == 0 ); /* force poll each 4 s */ + if (poll < 0) { /* lost dbase */ + logit(0, "Lost database %d errno=%d\n",poll,errno); + db_open = 0; + break; + } else { + if (poll == 0) /* db has changed */ + if (lookup_path(path, &id, NULL, 0) > 0) + return(id); + } + } + } else { + logit(0, "Send_new failed with %d errno=%d\n", res, errno); + server_probs++; + } + } + + if (DBDIR) + logit(0, "Lost connection to aufsExt server?\n"); + + return(add_to_extras(path)); + } + + sdword + aufsExtEDirId(parent, rest) + sdword parent; + char *rest; + { + int i, res; + + if (db_open) + check_db(); + + if (db_open) { + sdword id; + + /* have we got an existing entry ? */ + if (lookup_path_id(parent, rest, &id, NULL, 0) > 0) { + if (DBDIR) + logit(0, "aufsExtEDirId for %s is %d\n", rest, id); + return(id); + } + + /* ask the server to create a new record - even if having problems */ + if ((res = send_new_id(parent, rest)) >= 0 && server_probs < 5) { + for (i = 0; i < TimeOut*4; i++) { + int poll; + + abSleep(1, FALSE); /* wait 0.25s! */ + poll = poll_db( i%(4*4) == 0 ); /* force poll each 4 s */ + if (poll < 0) { /* lost dbase */ + logit(0, "Lost database %d errno=%d\n",poll,errno); + db_open = 0; + break; + } else { + if (poll == 0) { /* db has changed */ + if (lookup_path_id(parent, rest, &id, NULL, 0) > 0) { + if (DBDIR) + logit(0, "aufsExtEDirId created new id for %s:%d\n", rest, id); + return(id); + } + } + } + } + } else { + logit(0, "Send_new failed with %d errno=%d\n", res, errno); + server_probs++; + } + } + + if (DBDIR) + logit(0, "Lost connection to aufsExt server?\n"); + + { /* should never really get here, but just in case ... */ + char *str = equiv_path(parent); + char *temp = (char *)malloc(strlen(str) + strlen(rest) + 2); + sdword id; + + strcpy(temp, str); + if (strlen(str) > 1) + strcat(temp, "/"); + strcat(temp, rest); + id = add_to_extras(temp); + free(temp); + return(id); + } + } + + char * + aufsExtPath(edir) + sdword edir; + { + char *ans = NULL; + + if (db_open) + check_db(); + + if (db_open) + ans = equiv_path(edir); + + if (ans == NULL && extras != NULL) { /* lookup in extras */ + Xtable *ptr; + + for (ptr = extras; ptr->path != NULL; ptr++) + if (ptr->ext == edir) { + ans = ptr->path; + break; + } + } + return(ans); + } + + void + aufsExtDel(path) + char *path; + { + int found = 0; + + if (db_open) + check_db(); + + if (db_open) { + sdword id; + + if (lookup_path(path, &id, NULL, 0) > 1) { + found = 1; + send_delete_id(id); + } + } + + if (! found && extras != NULL) { /* lookup in extras */ + Xtable *ptr; + + for (ptr = extras; ptr->path != NULL; ptr++) { + if (ptr->ext == -1) + continue; + if (strcmp(path, ptr->path) == 0) { + free(ptr->path); + ptr->ext = -1; + break; + } + } + } + } + + void + aufsExtDelId(edir) + sdword edir; + { + int found = 0; + + if (db_open) + check_db(); + + if (db_open) { + if (existing_entry(edir)) { + found = 1; + send_delete_id(edir); + } + } + + if (! found && extras != NULL) { /* lookup in extras */ + Xtable *ptr; + + for (ptr = extras; ptr->path != NULL; ptr++) { + if (ptr->ext == -1) + continue; + if (ptr->ext == edir) { + free(ptr->path); + ptr->ext = -1; + break; + } + } + } + } + + sdword + aufsExtEFileId(parent, rest) + sdword parent; + char *rest; + { + int i, res; + + if (db_open) + check_db(); + + if (db_open) { + sdword id; + + /* have we got an existing entry ? */ + if (lookup_path_id(parent, rest, &id, NULL, 0) > 0) + return(id); + + /* ask the server to create a new record - even if having problems */ + if ((res = send_new_fid(parent, rest)) >= 0 && server_probs < 5) { + for (i = 0; i < TimeOut*4; i++) { + int poll; + + abSleep(1, FALSE); /* wait 0.25s! */ + poll = poll_db( i%(4*4) == 0 ); /* force poll each 4 s */ + if (poll < 0) { /* lost dbase */ + logit(0, "Lost database %d errno=%d\n",poll,errno); + db_open = 0; + break; + } else { + if (poll == 0) { /* db has changed */ + if (lookup_path_id(parent, rest, &id, NULL, 0) > 0) + return(id); + } + } + } + } else { + logit(0, "Send_new failed with %d errno=%d\n", res, errno); + server_probs++; + } + } + + if (DBDIR) + logit(0, "Lost connection to aufsExt server?\n"); + + return(-1); + } + + static void + move_in_extras(from, to) + char *from, *to; + { + if (extras) { /* go through and change any */ + Xtable *ptr; + + for (ptr = extras; ptr->path != NULL; ptr++) { + if (ptr->ext == -1) + continue; + if (strcmp(from, ptr->path) == 0) { + free(ptr->path); + ptr->path = string_copy(to); + break; + } + } + } + } + + static void + rename_in_extras(path, new_name) + char *path, *new_name; + { + char temp [MAXPATHLEN]; + char *ptr; + + strcpy(temp, path); + if ((ptr = (char *)rindex(temp, '/')) == NULL) + return; /* not a real path */ + strcpy(ptr+1, new_name); + move_in_extras(path, temp); + } + + static void + rename_id_in_extras(id, new_name) + sdword id; + char *new_name; + { + char temp [MAXPATHLEN]; + char *p; + + if (extras) { /* go through and change any */ + Xtable *ptr; + + for (ptr = extras; ptr->path != NULL; ptr++) { + if (ptr->ext == -1) + continue; + if (ptr->ext == id) { + strcpy(temp, ptr->path); + if ((p = (char *)rindex(temp, '/')) == NULL) + return; /* not a real path */ + strcpy(p+1, new_name); + free(ptr->path); + ptr->path = string_copy(temp); + break; + } + } + } + } + + + void + aufsExtMove(from, to) + char *from, *to; + { + send_move(from, to); /* send anyway */ + + if (extras) + move_in_extras(from, to); + } + + void + aufsExtMoveIds(orig, newParent, newName) + sdword orig, newParent; + char *newName; + { + datum data; + sdword parent; + char *name; + + if (db_open) + check_db(); + + if (db_open) { + data = get_datum(orig); + if (data.dptr != NULL) { + if (extract_entry(data, &name, &parent, NULL, NULL) < 0) + return; + send_move_id(parent, name, newParent, newName); + return; + } + } + + /* try to move the extras - note move this only and not children */ + + { + char *newParent_name = aufsExtPath(newParent); + char *temp = (char *)malloc(strlen(newParent_name)+strlen(newName)+2); + + strcpy(temp, newParent_name); + if (strlen(newParent_name) > 1) + strcat(temp, "/"); + strcat(temp, newName); + + move_in_extras(aufsExtPath(orig), temp); + + free(temp); + } + } + + void + aufsExtMoveId(origPath, newParent, newName) + sdword newParent; + char *newName, *origPath; + { + datum data; + sdword parent; + char *name; + + if (db_open) + check_db(); + + if (db_open) { + if (lookup_path(origPath, NULL, &data, 0) > 0) { + if (extract_entry(data, &name, &parent, NULL, NULL) < 0) + return; + send_move_id(parent, name, newParent, newName); + return; + } + } + + /* otherwise not sure what to do, try falling back on aufsExtMove! */ + + { + char *newParent_name = aufsExtPath(newParent); + char *temp = (char *)malloc(strlen(newParent_name)+strlen(newName)+2); + + strcpy(temp, newParent_name); + if (strlen(newParent_name) > 1) + strcat(temp, "/"); + strcat(temp, newName); + + aufsExtMove(origPath, temp); + + free(temp); + } + } + + void + aufsExtRename(path, newName) + char *path, *newName; + { + sdword id; + + if (db_open) + check_db(); + + if (db_open) { + if (lookup_path(path, &id, NULL, 0) > 0) { + send_rename_id(id, newName); + return; + } + } + + /* try to move the extras - note rename this only and not children */ + + rename_in_extras(path, newName); + } + + void + aufsExtRenameId(edir, newName) + sdword edir; char *newName; + { + datum data; + int found = 0; + char *name; + + if (db_open) + check_db(); + + if (db_open) { + data = get_datum(edir); + if (data.dptr != NULL) { + send_rename_id(edir, newName); + return; + } + } + + /* try to move the extras - note rename this only and not children */ + + rename_id_in_extras(edir, newName); + } + #else FIXED_DIRIDS + int afpdid_dummy_1; /* keep loader happy */ + #endif FIXED_DIRIDS *** lib/afp/afpidclnt.c.orig Sat Apr 27 22:34:30 1996 --- lib/afp/afpidclnt.c Wed May 1 02:07:48 1996 *************** *** 0 **** --- 1,271 ---- + /* + * $Author: djh $ $Date: 1996/04/30 16:07:19 $ + * $Header: /mac/src/cap60/lib/afp/RCS/afpidclnt.c,v 2.4 1996/04/30 16:07:19 djh Rel djh $ + * $Revision: 2.4 $ + * + */ + + /* + * AUFS fixed directory IDs + * + * library functions used by client programs only + * + * John Forrest + * + */ + + #ifdef FIXED_DIRIDS + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "afpidaufs.h" + + static time_t openTime; + static char *pagFile = NULL; + + int + connect_query(sock) + int sock; + { + struct sockaddr *addr; + int addrlen; + + query_addr(&addr, &addrlen); + return(connect(sock, addr, addrlen)); + } + + time_t + getMtime(file) + char *file; + { + struct stat buf; + + if (stat(file, &buf) < 0) + return(0); + + return(buf.st_mtime); + } + + void + setPagFile() + { + pagFile = (char *)malloc(strlen(aufsDbName)+4+1); + strcpy(pagFile, aufsDbName); + strcat(pagFile, ".pag"); + } + + + int + open_dbase(first) + int first; + { + datum initial_key, initial; + char *version; + + if (pagFile == NULL) + setPagFile(); + + openTime = getMtime(pagFile); /* do before for safety! */ + + if ((db = dbm_open(aufsDbName, O_RDONLY, 0644)) == NULL) + return(-1); + + if (first) { + initial_key.dptr = "I"; + initial_key.dsize = strlen(initial_key.dptr); + initial = dbm_fetch(db, initial_key); + if (initial.dptr == NULL) { + close_dbase(); + return(-1); + } + if (extract_init(initial, &version, &rootEid) < 0) { + close_dbase(); + return(-1); + } + if (strcmp(version, aufsDbVersion) != 0) { + close_dbase(); + return(-2); + } + } + return(1); + } + + void + close_dbase() + { + dbm_close(db); + } + + int + poll_db(force) + int force; + { + if (pagFile == NULL) + setPagFile(); + + if (force || getMtime(pagFile) > openTime) { + int res; + + close_dbase(); + res = open_dbase(FALSE); + return((res >= 0) ? 0 : res); + } + return(1); + } + + static int + send_command(command) + char *command; + { + int sock; + int n; + + if ((sock = query_socket()) < 0) + return(-2); + + if (connect_query(sock) < 0) { + close(sock); + return(-3); + } + + n = send(sock, command, strlen(command), 0); + close(sock); + + return(n); + } + + int + send_new(path) + char *path; + { + char command[MAXPATHLEN+3]; + + sprintf(command, "A%s\277", path); + return(send_command(command)); + } + + int + send_new_id(parent, remaining) + sdword parent; + char *remaining; + { + char command[MAXPATHLEN+3]; + + sprintf(command, "a%d\277%s\277", parent, remaining); + return(send_command(command)); + } + + int + send_new_fid(parent, remaining) + sdword parent; + char *remaining; + { + char command[MAXPATHLEN+3]; + + sprintf(command, "f%d\277%s\277", parent, remaining); + return(send_command(command)); + } + + int + send_delete(path) + char *path; + { + char command[MAXPATHLEN+3]; + + sprintf(command, "D%s\277", path); + return(send_command(command)); + } + + int + send_delete_id(id) + sdword id; + { + char command[10]; + + sprintf(command, "d%d\277", id); + return(send_command(command)); + } + + int + send_move(from, to) + char *from, *to; + { + char command[2*MAXPATHLEN+4]; + + sprintf(command, "M%s\277%s\277", from, to); + return(send_command(command)); + } + + int + send_move_id(from_parent, old_name, to_parent, new_name) + sdword from_parent, to_parent; + char *old_name, *new_name; + { + char command[MAXPATHLEN]; /* should be sufficient */ + + sprintf(command, "m%d\277%s\277%d\277%s\277", from_parent, + old_name, to_parent, new_name); + return(send_command(command)); + } + + int + send_rename(orig_path, new_name) + char *orig_path, *new_name; + { + char command[2*MAXPATHLEN+4]; + + sprintf(command, "R%s\277%s\277", orig_path, new_name); + return(send_command(command)); + } + + int + send_rename_id(id, new_name) + sdword id; + char *new_name; + { + char command[MAXPATHLEN]; + + sprintf(command, "r%d\277%s\277", id, new_name); + return(send_command(command)); + } + + int + send_clean() + { + char command[2]; + + sprintf(command, "C"); + return(send_command(command)); + } + + int + amAufsExt() + { + return(0); + } + + /* + * never called, but needed for linking + * + */ + + void + flush_database() + { + } + #else FIXED_DIRIDS + int afpdid_dummy_2; /* keep loader happy */ + #endif FIXED_DIRIDS *** lib/afp/afpidgnrl.c.orig Sat Apr 27 22:34:30 1996 --- lib/afp/afpidgnrl.c Wed May 1 02:07:51 1996 *************** *** 0 **** --- 1,749 ---- + /* + * $Author: djh $ $Date: 1996/04/30 16:07:19 $ + * $Header: /mac/src/cap60/lib/afp/RCS/afpidgnrl.c,v 2.3 1996/04/30 16:07:19 djh Rel djh $ + * $Revision: 2.3 $ + * + */ + + /* + * AUFS fixed directory IDs + * + * general library functions + * + * John Forrest + * + */ + + #ifdef FIXED_DIRIDS + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "afpidaufs.h" + + /* #define DEBUG 0 */ + + /* globals */ + char *aufsSockname = SOCKNAME; + char *aufsDbName = DBNAME; + char *aufsDbVersion = DBVERSION; + char *aufsRootName = ROOTNAME; + sdword rootEid; + DBM *db; + + char * + string_copy(str) + char *str; + { + char *new = (char *)malloc(strlen(str)+1); + + strcpy(new, str); + return(new); + } + + sdword * + copy_children(children, num_children) + sdword *children; + int num_children; + { + sdword *temp = (sdword*)calloc(num_children, sizeof(sdword)); + + bcopy(children, temp, num_children*sizeof(sdword)); + return(temp); + } + + int + query_socket() + { + return(socket(AF_UNIX, SOCK_STREAM, 0)); + } + + void + query_addr(addr, len) + struct sockaddr **addr; int *len; + { + static struct sockaddr_un un_addr; + + un_addr.sun_family = AF_UNIX; + sprintf((char *)un_addr.sun_path, "%s", aufsSockname); + *addr = (struct sockaddr *)&un_addr; + *len = strlen(un_addr.sun_path) + sizeof(un_addr.sun_family); + } + + int + is_directory(path) + char *path; + { + struct stat statbuf; + + if (stat(path, &statbuf) < 0) + return(0); + + return(S_ISDIR(statbuf.st_mode)); + } + + int + is_file(path) + char *path; + { + struct stat statbuf; + + if (stat(path, &statbuf) < 0) + return(0); + + return(S_ISREG(statbuf.st_mode)); + } + + datum + num_datum(num) + /* note only does one at a time! */ + sdword num; + { + datum temp; + static unsigned char data[1+sizeof(sdword)]; + + data[0] = 'N'; + bcopy((char *)&num, (char *)&data[1], sizeof(sdword)); + temp.dsize = 1+sizeof(sdword); + temp.dptr = (char *)&data[0]; + + return(temp); + } + + sdword + num_from_datum(dat) + datum dat; + { + sdword temp; + + if (dat.dptr == NULL || dat.dptr[0] != 'N') + return(-1); + + bcopy(&dat.dptr[1], (char *)&temp, sizeof(temp)); + + return(temp); + } + + /* + * format is {} + * all but are sdwords. name is null terminated string + * + */ + + static sdword sdtemp[MAXPATHLEN/sizeof(sdword)]; /* should be sufficient ! */ + static char *temp = (char *)sdtemp; + + datum + new_entry(name, parent) + char *name; + sdword parent; + { + datum new; + + sdtemp[0] = parent; + sdtemp[1] = 0; /* no children */ + strcpy((char *)&sdtemp[2], name); + new.dptr = temp; + new.dsize = 2*sizeof(sdword) + strlen(name)+1; + + return(new); + } + + datum + create_entry(name, parent, num_children, children) + char *name; + sdword parent; + int num_children; + sdword *children; + { + datum new; + + sdtemp[0] = parent; + sdtemp[1] = num_children; /* no. children */ + bcopy((char *)children,(char *)&sdtemp[2],num_children*sizeof(sdword)); + strcpy((char *)&sdtemp[2+num_children], name); + new.dptr = temp; + new.dsize = (2+num_children)*sizeof(sdword) + strlen(name)+1; + + return(new); + } + + int + extract_entry(entry, name, parent, num_children, children) + datum entry; + char **name; + sdword *parent; + int *num_children; + sdword **children; + { + if (entry.dptr == NULL) + return(-1); + + if (entry.dptr == temp) { /* we know we are word aligned! */ + if (parent != NULL) + *parent = sdtemp[0]; + if (num_children != NULL) + *num_children = sdtemp[1]; + if (children != NULL) + *children = &sdtemp[2]; + if (name != NULL) + *name = (char *)&sdtemp[2 + *num_children]; + } else { + int num; + sdword *area = (sdword *)entry.dptr; + + bcopy((char *)&area[1], (char *)&num, sizeof(sdword)); + if (parent != NULL) + bcopy((char *)&area[0], (char *)parent, sizeof(sdword)); + if (num_children != NULL) + *num_children = num; + if (children != NULL) { /* need to ensure this is word aligned! */ + bcopy((char *)&area[2], temp, num*sizeof(sdword)); + *children = sdtemp; + } + if (name != NULL) + *name = (char *)&area[2 + num]; + } + + return(0); + } + + datum + modify_name(entry, new_name) + datum entry; + char *new_name; + { + int num_children; + + assert(entry.dptr != NULL); + + if (entry.dptr != temp) { /* don't overwrite db */ + bcopy(entry.dptr, temp, entry.dsize); + entry.dptr = temp; + } + num_children = sdtemp[1]; + strcpy((char *)&sdtemp[2+num_children], new_name); + entry.dsize = (2+num_children)*sizeof(sdword)+strlen(new_name)+1; + + return(entry); + } + + datum + modify_parent(entry, parent) + datum entry; + sdword parent; + { + assert(entry.dptr != NULL); + + if (entry.dptr != temp) { /* don't overwrite db */ + bcopy(entry.dptr, temp, entry.dsize); + entry.dptr = temp; + } + sdtemp[0] = parent; + /* entry.dsize remains unchanged */ + + return(entry); + } + + datum + modify_children(entry, num_children, children) + datum entry; + int num_children; + sdword *children; + { + sdword *from; + sdword *temp_area = NULL; + datum new; + char *name; + int old_num; + + assert(entry.dptr != NULL); + + if (entry.dptr == temp) { + /* we are going to use temp to create new area! */ + temp_area = (sdword *)malloc(entry.dsize); + bcopy(entry.dptr, temp_area, entry.dsize); + from = temp_area; + } else + from = (sdword *)entry.dptr; + + bcopy((char *)&from[0],(char *)&sdtemp[0],sizeof(sdword)); /* parent */ + bcopy((char *)&from[1], (char *)&old_num, sizeof(sdword)); + sdtemp[1] = num_children; + bcopy(children, &sdtemp[2], num_children*sizeof(sdword)); + name = (char *)&from[2+old_num]; + strcpy((char *)&sdtemp[2+num_children], name); + + new.dsize = (num_children+2)*sizeof(sdword)+strlen(name)+1; + new.dptr = temp; + + if (temp_area != NULL) + free(temp_area); + + return(new); + } + + /* + * note we always place the db version as first field, even though + * it is a bit of a pain to extract the other data - since it is + * not alligned properly + * + */ + + datum + create_init(version, rootEid) + char *version; + sdword rootEid; + { + datum new; + int len = strlen(version); + + strcpy(temp, version); + bcopy((char *)&rootEid, &temp[len+1], sizeof(sdword)); + new.dptr = temp; + new.dsize = len+1+sizeof(sdword); + + return(new); + } + + int + extract_init(initial, version, rootEid) + datum initial; + char **version; + sdword *rootEid; + { + int len; + + if (initial.dptr == NULL) + return(-1); + + if (version != NULL) + *version = initial.dptr; + if (rootEid != NULL) { + len = strlen(initial.dptr); + bcopy(&initial.dptr[len+1], (char *)rootEid, sizeof(sdword)); + } + return(1); + } + + datum + get_datum(id) + sdword id; + { + datum key,entry; + + key = num_datum(id); + entry = dbm_fetch(db, key); + #ifdef DEBUG + fprintf(stderr, "Read for id %d datum (%d,%x)\n", + id, entry.dsize, entry.dptr); + #endif DEBUG + return(entry); + } + + int + store_datum(id, entry, flags) + sdword id; + datum entry; + int flags; + { + int ret; + datum key; + + key = num_datum(id); + ret = dbm_store(db, key, entry, flags); + #ifdef DEBUG + fprintf(stderr, "Write for id %d datum (%d,%x) gave %d\n", + id, entry.dsize, entry.dptr, ret); + #endif DEBUG + flush_database(); + return(ret); + } + + void + delete_datum(id) + sdword id; + { + datum key; + + key = num_datum(id); + dbm_delete(db, key); + } + + static + int find_equiv(id, buffer) + sdword id; + char *buffer; + { + if (id == rootEid) { + strcpy(buffer, ""); /* equiv path copes with special cases */ + return(1); + } else { + datum contents; + char *name; + sdword parent; + int ans; + + contents = get_datum(id); + if (contents.dptr == NULL) { + fprintf(stderr, "find_equiv: get_datum returns NULL\n"); + return(-1); + } + + if (extract_entry(contents, &name, &parent, NULL, NULL) < 0) { + #ifdef DEBUG + fprintf(stderr, "find_equiv: extract_entry returns -1\n"); + #endif DEBUG + return(-1); + } + + name = string_copy(name); /* avoid probs with recursion */ + + ans = find_equiv(parent, buffer); /* recurse */ + + if (ans >= 0) { + strcat(buffer, "/"); + strcat(buffer, name); + } + #ifdef DEBUG + else + fprintf(stderr, "find_equiv: find_equiv returns -1\n"); + #endif DEBUG + + free(name); + + return(ans); + } + } + + + char * + equiv_path(id) + sdword id; + { + static char buffer[MAXPATHLEN]; /* used for returned string */ + int result; + + if (id == rootEid) + return(aufsRootName); + + buffer[0] = '\0'; /* start with null string in buffer */ + + result = find_equiv(id, buffer); + + #ifdef DEBUG + fprintf(stderr, "Looking up %d gave %s\n", id, /* debug*/ + (result < 0) ? NULL : buffer); + #endif DEBUG + return((result < 0) ? NULL : buffer); + } + + #define null_string(str) (str == NULL || str[0] == '\0') + + static char * + next_ele(path, name) + char *path, *name; + { + char *ptr; + + if (null_string(path)) { /* given "/" to start with ? */ + strcpy(name, ""); + return(NULL); + } + + ptr = index(path, '/'); + if (ptr == NULL) { + strcpy(name, path); + return(NULL); + } + + name[0] = '\0'; /* use strncat to overcome occational bug */ + strncat(name, path, ptr-path); + + return(ptr+1); /* rest */ + } + + /* + * add child entry to record + * + */ + + int + add_child(id, child) + sdword id; + sdword child; + { + datum entry; + sdword *children, *new_children; + int num_children; + int ret; + + if (child <= 0 || id <= 0) + return(0); + + #ifdef DEBUG + fprintf(stderr, "adding child %d to %d\n", child, id); + #endif DEBUG + + entry = get_datum(id); + if (entry.dptr == NULL) /* must assume it exists */ + return(-1); + if (extract_entry(entry,NULL,NULL,&num_children,&children) < 0) + return(-1); + new_children = (sdword *)calloc(num_children+1, sizeof(sdword)); + bcopy(children, new_children, num_children*sizeof(sdword)); + num_children += 1; + new_children[num_children-1] = child; + entry = modify_children(entry, num_children, new_children); + if (ret = store_datum(id, entry, DBM_REPLACE) < 0) { + #ifdef DEBUG + fprintf(stderr, "add_child: store datum failed for id %d (%d)\n", + id, ret); + #endif DEBUG + } + free(new_children); + return(1); + } + + /* + * delete child entry to record + * + */ + + int + delete_child(id, child) + sdword id; + sdword child; + { + datum entry; + sdword *children, *new_children; + int num_children; + int i,new_num; + + if (child <= 0 || id <= 0) + return(0); + + entry = get_datum(id); + if (entry.dptr == NULL) /* must assume it exists */ + return(-1); + if (extract_entry(entry,NULL,NULL,&num_children,&children) < 0) + return(-1); + /* too big won't hurt */ + new_children = copy_children(children, num_children); + bcopy(children, new_children, num_children*sizeof(sdword)); + for (i=0,new_num=0; i= 0) + break; + } + + child = new_entries(id, remaining); /* recurse */ + + (void)add_child(id, child); /* not sure what to do with error */ + + return(id); + } + + int + lookup_path_id(parent, path, id, dat, create) + sdword parent; + char *path; /* relative to parent */ + sdword *id; + datum *dat; + int create; /* server only */ + { + sdword current = parent; + char name[128]; + char *remaining; + sdword *children = NULL, child; + int num_children; + datum data, child_data; + int indx; + char *child_name; + + data = get_datum(parent); + if (data.dptr == NULL) + return(-2); /* help!! Lost something !! */ + + remaining = next_ele(path, name); + + if (null_string(name)) { /* were after parent */ + if (dat) + *dat = data; + if (id) + *id = parent; + return(1); + } + + redo: + for ( ; ; ) { + #ifdef DEBUG + fprintf(stderr, "Looking up %d/%s\n", current, name); /* debug */ + #endif DEBUG + if (extract_entry(data, NULL, NULL, &num_children, &children) < 0) + return(-1); /* error */ + /* take copy in dbm overwrites original area */ + children = copy_children(children, num_children); + indx = 0; + while (indx < num_children) { + child = children[indx++]; + child_data = get_datum(child); + if (child_data.dptr == NULL) + continue; /* error - missing child */ + if (extract_entry(child_data, &child_name, NULL, NULL, NULL) < 0) + continue; /* error, no name? */ + if (strcmp(name, child_name) == 0) { /* found it ! */ + if (null_string(remaining)) { + if (id) + *id = child; + if (dat) + *dat = child_data; + free(children); + return(1); + } else { + free(children); + path = remaining; + remaining = next_ele(remaining, name); + current = child; + data = child_data; + goto redo; + } + } + } + /* if we get this far, something is missing */ + free(children); + + /* something missing */ + if (!create || !amAufsExt()) + return(0); + + /* assume we are in the server */ + + child = new_entries(current, path); + if (add_child(current, child) < 0) + return(-1); + flush_database(); + + /* having created object, loop back to it. Perhaps not the most + efficient way, but seems reliable */ + data = get_datum(current); + if (data.dptr == NULL) /* should never happen */ + return(-2); + } + } + + int + lookup_path(path, id, dat, create) + char *path; + sdword *id; + datum *dat; + int create; /* server only */ + { + char *remaining; + + + if (null_string(path)) + remaining = NULL; + else + remaining = path+1; /* skip '/' */ + + return(lookup_path_id(rootEid, remaining, id, dat, create)); + } + + void + do_delete_entry(id) + sdword id; + { + datum data; + sdword *children; + int num_children; + int i; + + data = get_datum(id); + if (data.dptr == NULL) + return; + if (extract_entry(data, NULL, NULL, &num_children, &children) >= 0) { + children = copy_children(children, num_children); + for (i=0; i < num_children ; i++) + do_delete_entry(children[i]); + free(children); + } + delete_datum(id); + } + + #define MINID 200 /* The first so many have special meanings. */ + #define MAXID ((1<<30)-1) /* 2^30-1, guessed that this is in range. */ + + sdword + valid_id() + { + #ifdef USERAND + sdword id = rand()%(MAXID-MINID)+MINID; + #else /* USERAND */ + sdword id = random()%(MAXID-MINID)+MINID; + #endif /* USERAND */ + + return(id); + } + + #undef MINID + #undef MAXID + + void + init_aufsExt() + { + #ifdef USERAND + srand(time(NULL)); + #else /* USERAND */ + srandom((int)time(NULL)); + #endif /* USERAND */ + } + #else FIXED_DIRIDS + int afpdid_dummy_3; /* keep loader happy */ + #endif FIXED_DIRIDS *** lib/afp/afpidnames.h.orig Sat Apr 27 22:34:30 1996 --- lib/afp/afpidnames.h Sat Apr 27 22:33:30 1996 *************** *** 0 **** --- 1,25 ---- + /* + * $Author: djh $ $Date: 1996/04/27 12:31:28 $ + * $Header: /mac/src/cap60/lib/afp/RCS/afpidnames.h,v 2.1 1996/04/27 12:31:28 djh Rel djh $ + * $Revision: 2.1 $ + * + */ + + /* + * AUFS fixed directory IDs + * + * database details + * + * John Forrest + * + */ + + #ifndef _afpidnames_h + #define _afpidnames_h + + #define DBVERSION "1.1" + #define DBNAME "/usr/local/lib/cap/afpIDdb" + #define SOCKNAME "/usr/local/lib/cap/afpIDsock" + #define ROOTNAME "/" + + #endif _afpidnames_h *** lib/afpc/afpc.c.orig Mon Jan 31 10:19:41 1994 --- lib/afpc/afpc.c Thu Apr 25 11:13:10 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1994/01/30 23:19:21 $ ! * $Header: /mac/src/cap60/lib/afpc/RCS/afpc.c,v 2.5 1994/01/30 23:19:21 djh Rel djh $ ! * $Revision: 2.5 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 01:12:53 $ ! * $Header: /mac/src/cap60/lib/afpc/RCS/afpc.c,v 2.6 1996/04/25 01:12:53 djh Rel djh $ ! * $Revision: 2.6 $ * */ *************** *** 749,755 **** if (epar) ntohPackXbitmap(ProtoFileAttr, p, rlen, epar, bitmap); #ifdef notdef ! printf("openfork CR = %X, %d\n",cr,-cr); printf("RLEN = %d\n",rlen); printf("Open file refnum = %d\n",*refnum); #endif --- 749,755 ---- if (epar) ntohPackXbitmap(ProtoFileAttr, p, rlen, epar, bitmap); #ifdef notdef ! printf("openfork CR = %X, %d\n",cr,-(*cr)); printf("RLEN = %d\n",rlen); printf("Open file refnum = %d\n",*refnum); #endif *** lib/afpc/afpcc.c.orig Tue Apr 13 18:16:07 1993 --- lib/afpc/afpcc.c Thu Apr 25 11:18:32 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1993/04/13 08:15:43 $ ! * $Header: /mac/src/cap60/lib/afpc/RCS/afpcc.c,v 2.4 1993/04/13 08:15:43 djh Rel djh $ ! * $Revision: 2.4 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 01:18:16 $ ! * $Header: /mac/src/cap60/lib/afpc/RCS/afpcc.c,v 2.5 1996/04/25 01:18:16 djh Rel djh $ ! * $Revision: 2.5 $ */ /* *************** *** 516,522 **** comp = FPLogin(srn, &lp, &lrp, cr); if (comp < 0) return(comp); ! if ((((long)*cr) != aeAuthContinue) && (uam != UAM_RANDNUM)) return(comp); if (desinit(0) < 0) { /* here handle randnum exchange */ --- 516,522 ---- comp = FPLogin(srn, &lp, &lrp, cr); if (comp < 0) return(comp); ! if ((((dword)*cr) != aeAuthContinue) && (uam != UAM_RANDNUM)) return(comp); if (desinit(0) < 0) { /* here handle randnum exchange */ *************** *** 699,705 **** err = FPRead(srn, &rp, buf, buflen, &rlen, cr); if (err < 0) return(err); ! if (*cr && ((long)*cr) != aeEOFErr) return(0); return(rlen); } --- 699,705 ---- err = FPRead(srn, &rp, buf, buflen, &rlen, cr); if (err < 0) return(err); ! if (*cr && ((dword)*cr) != aeEOFErr) return(0); return(rlen); } *** samples/ash.c.orig Fri Jun 30 09:17:52 1995 --- samples/ash.c Thu Apr 25 23:03:14 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/06/29 23:17:32 $ ! * $Header: /mac/src/cap60/samples/RCS/ash.c,v 2.5 1995/06/29 23:17:32 djh Rel djh $ ! * $Revision: 2.5 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 13:03:09 $ ! * $Header: /mac/src/cap60/samples/RCS/ash.c,v 2.6 1996/04/25 13:03:09 djh Rel djh $ ! * $Revision: 2.6 $ */ /* *************** *** 434,440 **** { char pbuf[9]; int i; ! dword cr; int uam = 2; if (!valid_uams[uam]) --- 434,440 ---- { char pbuf[9]; int i; ! dword cr = 0; int uam = 2; if (!valid_uams[uam]) *************** *** 512,517 **** --- 512,521 ---- dp = &ep->fdp_parms.dp_parms; printf(" [dir - %d, %d, %d entries]\n", dp->dp_dirid, ep->fdp_pdirid,dp->dp_nchild); + printf(" owner = %x, group = %x, accright = %x\n", + dp->dp_ownerid, /* owner id */ + dp->dp_groupid, /* group id */ + dp->dp_accright); /* access rights */ } else { long clock; char *created; *************** *** 673,681 **** int i, comp; FileDirParm epar; int toread; comp = eFPOpenFork(srn, volid, dirid, 0x1, path, type, ! (word)(type ? FP_RFLEN : FP_DFLEN), &epar, &fd, &cr); if (comp < 0) { return(FALSE); } --- 677,688 ---- int i, comp; FileDirParm epar; int toread; + word bitmap; + + bitmap = type ? FP_RFLEN : FP_DFLEN; comp = eFPOpenFork(srn, volid, dirid, 0x1, path, type, ! bitmap, &epar, &fd, &cr); if (comp < 0) { return(FALSE); } *** samples/getzones.c.orig Mon Oct 24 16:43:48 1994 --- samples/getzones.c Sun Apr 28 23:22:58 1996 *************** *** 1,15 **** ! static char rcsid[] = "$Author: djh $ $Date: 1994/10/24 06:43:36 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/samples/RCS/getzones.c,v 2.7 1994/10/24 06:43:36 djh Rel djh $"; ! static char revision[] = "$Revision: 2.7 $"; /* * getzones - retrieves the zone list from our bridge * - * MUST BE RUNNING KIP 1/88 to work properly (KIP 9/87 was the first - * revision with zones, but the code didn't return properly) - * - * Test program: most of this code will eventually be moved to abzip - * * AppleTalk package for UNIX (4.2 BSD). * * Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia --- 1,10 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1996/04/28 13:22:16 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/samples/RCS/getzones.c,v 2.9 1996/04/28 13:22:16 djh Rel djh $"; ! static char revision[] = "$Revision: 2.9 $"; /* * getzones - retrieves the zone list from our bridge * * AppleTalk package for UNIX (4.2 BSD). * * Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia *************** *** 44,57 **** u_char *GetMyZone(); u_char *myzone; int verbose = 0; int mzone = 0; extern int opterr; extern char *optarg; opterr = 0; function = zip_GetZoneList; ! while ((i = getopt(argc, argv, "d:D:lmv")) != EOF) { switch (i) { case 'd': case 'D': --- 39,54 ---- u_char *GetMyZone(); u_char *myzone; int verbose = 0; + int sortit = 0; int mzone = 0; extern int opterr; extern char *optarg; + int zonecmp(); opterr = 0; function = zip_GetZoneList; ! while ((i = getopt(argc, argv, "d:D:lmsv")) != EOF) { switch (i) { case 'd': case 'D': *************** *** 63,68 **** --- 60,68 ---- case 'm': mzone = 1; break; + case 's': + sortit = 1; + break; case 'v': verbose++; break; *************** *** 93,98 **** --- 93,105 ---- cnt = NUMZONES; } + /* + * Sort the Zone list, if required + * + */ + if (sortit) + qsort((char *)zones, cnt, sizeof(char *), zonecmp); + if (verbose) printf("Count is %d\n", cnt); *************** *** 112,114 **** --- 119,127 ---- FreeZoneList(zones, cnt); } + int + zonecmp(s1, s2) + void *s1, *s2; + { + return(strcmp(*(char **)s1, *(char **)s2)); + } *** support/ethertalk/aarpd.c.orig Wed May 31 17:34:18 1995 --- support/ethertalk/aarpd.c Sun Apr 28 00:57:00 1996 *************** *** 297,311 **** (void)dup2(0,1); (void)dup2(0,2); #endif NODUP2 #ifdef TIOCNOTTY ! if ((i = open("/dev/tty",2)) > 0) { (void)ioctl(i, TIOCNOTTY, (caddr_t)0); (void)close(i); } ! #endif TIOCNTTY ! #ifdef POSIX (void) setsid(); ! #endif POSIX } /* --- 297,312 ---- (void)dup2(0,1); (void)dup2(0,2); #endif NODUP2 + #ifndef POSIX #ifdef TIOCNOTTY ! if ((i = open("/dev/tty",2)) >= 0) { (void)ioctl(i, TIOCNOTTY, (caddr_t)0); (void)close(i); } ! #endif /* TIOCNTTY */ ! #else /* POSIX */ (void) setsid(); ! #endif /* POSIX */ } /* *** support/ethertalk/abelap.c.orig Mon May 29 20:45:36 1995 --- support/ethertalk/abelap.c Thu Apr 25 10:37:09 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/05/29 10:45:33 $ ! * $Header: /mac/src/cap60/support/ethertalk/RCS/abelap.c,v 2.11 1995/05/29 10:45:33 djh Rel djh $ ! * $Revision: 2.11 $ */ /* --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/25 00:37:02 $ ! * $Header: /mac/src/cap60/support/ethertalk/RCS/abelap.c,v 2.12 1996/04/25 00:37:02 djh Rel djh $ ! * $Revision: 2.12 $ */ /* *************** *** 580,585 **** --- 580,588 ---- struct ethertalkaddr etaddr; DDP *ddp; ShortDDP *sddp; + #ifdef USING_FDDI_NET + extern int source_offset; + #endif USING_FDDI_NET lastnet = -1; lastnode = -1; *************** *** 587,593 **** --- 590,600 ---- if ((cc = pi_reada(fd, pack, packsize, eaddrbuf)) <= 0) return(-1); + #ifdef USING_FDDI_NET + lasteaddr = eaddrbuf + source_offset; + #else USING_FDDI_NET lasteaddr = eaddrbuf + 6; + #endif USING_FDDI_NET if (cc <= lapSize) /* not much use if only lap */ return(-1); *************** *** 670,676 **** --- 677,687 ---- etaddr.dummy[0] = etaddr.dummy[1] = etaddr.dummy[2] = 0; #endif PHASE2 etaddr.node = ddp->srcNode; + #ifdef USING_FDDI_NET + aarp_insert(&aih, eaddrbuf+source_offset, &etaddr, FALSE); + #else USING_FDDI_NET aarp_insert(&aih, eaddrbuf+6, &etaddr, FALSE); + #endif USING_FDDI_NET } return(ddp_protocol(iov, iovlen, cc)); *** support/ethertalk/spfiltp.c.orig Mon Nov 25 02:27:33 1991 --- support/ethertalk/spfiltp.c Thu Apr 25 10:49:42 1996 *************** *** 1,6 **** ! static char rcsid[] = "$Author: djh $ $Date: 1991/11/24 15:27:18 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/spfiltp.c,v 2.5 1991/11/24 15:27:18 djh Rel djh $"; ! static char revision[] = "$Revision: 2.5 $"; /* * spfiltp.c - Simple "protocol" level interface to Ultrix packetfilter --- 1,6 ---- ! static char rcsid[] = "$Author: djh $ $Date: 1996/04/25 00:49:30 $"; ! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/spfiltp.c,v 2.6 1996/04/25 00:49:30 djh Rel djh $"; ! static char revision[] = "$Revision: 2.6 $"; /* * spfiltp.c - Simple "protocol" level interface to Ultrix packetfilter *************** *** 23,30 **** * * April 1991 Jeffrey Mogul @ DECWRL (created from senetp.c) * June 1991 David Hornsby, add Phase 2 support * ! */ static char columbia_copyright[] = "Copyright (c) 1988 by The Trustees of \ Columbia University in the City of New York"; --- 23,31 ---- * * April 1991 Jeffrey Mogul @ DECWRL (created from senetp.c) * June 1991 David Hornsby, add Phase 2 support + * June 1995 Conrad Huang, add FDDI support * ! */ static char columbia_copyright[] = "Copyright (c) 1988 by The Trustees of \ Columbia University in the City of New York"; *************** *** 50,55 **** --- 51,60 ---- #else pyr #include #endif pyr + #ifdef USING_FDDI_NET + #include + #include + #endif USING_FDDI_NET #include #include *************** *** 68,73 **** --- 73,85 ---- private EPHANDLE ephlist[MAXOPENPROT]; + private int header_size = 14; /* assume Ethernet for now */ + + #ifdef USING_FDDI_NET + export int source_offset = 6; /* assume Ethernet for now */ + export int using_fddi = 0; /* assume not FDDI for now */ + #endif USING_FDDI_NET + extern char interface[50]; /* *************** *** 284,290 **** { u_short offset; unsigned queuelen; ! struct ether_header eh; struct enfilter pf; register u_short *fwp = pf.enf_Filter; extern int errno; --- 296,302 ---- { u_short offset; unsigned queuelen; ! u_int dlt; struct enfilter pf; register u_short *fwp = pf.enf_Filter; extern int errno; *************** *** 296,303 **** --- 308,332 ---- return(-1); } + #ifdef USING_FDDI_NET + if (ioctl(s, BIOCGDLT, &dlt) < 0) { + perror("ioctl: get data link type"); + return(-1); + } + if (dlt == DLT_FDDI) { + header_size = 16; + source_offset = 10; + using_fddi = 1; + } + #endif USING_FDDI_NET + pf.enf_Priority = 128; + #ifdef USING_FDDI_NET + if (using_fddi) + offset = (header_size - 2) / sizeof (ushort); + else + #endif USING_FDDI_NET #define s_offset(structp, element) (&(((structp)0)->element)) offset = ((int)s_offset(struct ether_header *, ether_type))/sizeof(u_short); #ifdef PHASE2 *************** *** 435,448 **** { struct iovec iov[3]; struct ethernet_addresses ea; #ifdef PHASE2 char header[8]; #endif PHASE2 int cc; #ifdef PHASE2 iov[0].iov_base = (caddr_t)&ea; ! iov[0].iov_len = sizeof(ea); iov[1].iov_base = (caddr_t)header; /* consume 802.2 hdr & SNAP */ #ifdef ULT42PFBUG iov[1].iov_len = 0; --- 464,485 ---- { struct iovec iov[3]; struct ethernet_addresses ea; + #ifdef USING_FDDI_NET + struct fddi_header fh; + #endif USING_FDDI_NET #ifdef PHASE2 char header[8]; #endif PHASE2 int cc; #ifdef PHASE2 + #ifdef USING_FDDI_NET + if (using_fddi) + iov[0].iov_base = (caddr_t)&fh; + else + #endif USING_FDDI_NET iov[0].iov_base = (caddr_t)&ea; ! iov[0].iov_len = header_size; iov[1].iov_base = (caddr_t)header; /* consume 802.2 hdr & SNAP */ #ifdef ULT42PFBUG iov[1].iov_len = 0; *************** *** 452,457 **** --- 489,499 ---- iov[2].iov_base = (caddr_t)buf; iov[2].iov_len = bufsiz; cc = pi_readv(edx, iov, 3); + #ifdef USING_FDDI_NET + if (using_fddi) + return(cc - header_size - sizeof (header)); + else + #endif USING_FDDI_NET #ifdef ULT42PFBUG return(cc - sizeof(ea)); #else ULT42PFBUG *************** *** 481,494 **** #ifdef PHASE2 iov[0].iov_base = (caddr_t)eaddr; ! iov[0].iov_len = 14; iov[1].iov_base = (caddr_t)header; /* consume 802.2 hdr & SNAP but */ iov[1].iov_len = sizeof(header); /* make room for our fake LAP header */ iov[2].iov_base = (caddr_t)buf; iov[2].iov_len = bufsiz; #else PHASE2 iov[0].iov_base = (caddr_t)eaddr; ! iov[0].iov_len = 14; iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = bufsiz; #endif PHASE2 --- 523,536 ---- #ifdef PHASE2 iov[0].iov_base = (caddr_t)eaddr; ! iov[0].iov_len = header_size; iov[1].iov_base = (caddr_t)header; /* consume 802.2 hdr & SNAP but */ iov[1].iov_len = sizeof(header); /* make room for our fake LAP header */ iov[2].iov_base = (caddr_t)buf; iov[2].iov_len = bufsiz; #else PHASE2 iov[0].iov_base = (caddr_t)eaddr; ! iov[0].iov_len = header_size; iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = bufsiz; #endif PHASE2 *************** *** 506,514 **** buf[0] = buf[11]; /* destination node ID */ buf[1] = buf[12]; /* source node ID */ buf[2] = 0x02; /* always long DDP */ ! return(cc - 14 - sizeof(header)); #else PHASE2 ! return(cc - 14); #endif PHASE2 } --- 548,556 ---- buf[0] = buf[11]; /* destination node ID */ buf[1] = buf[12]; /* source node ID */ buf[2] = 0x02; /* always long DDP */ ! return(cc - header_size - 5); #else PHASE2 ! return(cc - header_size); #endif PHASE2 } *************** *** 521,534 **** { struct ephandle *eph; struct ether_header eh; struct sockaddr sa; struct iovec iov[2]; #ifdef PHASE2 char *q; #endif PHASE2 iov[0].iov_base = (caddr_t)&eh; ! iov[0].iov_len = 14; iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = buflen; --- 563,584 ---- { struct ephandle *eph; struct ether_header eh; + #ifdef USING_FDDI_NET + struct fddi_header fh; + #endif USING_FDDI_NET struct sockaddr sa; struct iovec iov[2]; #ifdef PHASE2 char *q; #endif PHASE2 + #ifdef USING_FDDI_NET + if (using_fddi) + iov[0].iov_base = (caddr_t)&fh; + else + #endif USING_FDDI_NET iov[0].iov_base = (caddr_t)&eh; ! iov[0].iov_len = header_size; iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = buflen; *************** *** 539,546 **** --- 589,608 ---- if (!eph->inuse) return(-1); + #ifdef USING_FDDI_NET + if (using_fddi) { + bcopy(eaddr, fh.fddi_dhost, 6); + fh.fddi_fc = FDDIFC_LLC_ASYNC; + fh.fddi_ph[0] = 0; + fh.fddi_ph[1] = 0; + fh.fddi_ph[2] = 0; + } else + #endif USING_FDDI_NET bcopy(eaddr, eh.ether_dhost, 6); #ifdef PHASE2 + #ifdef USING_FDDI_NET + if (!using_fddi) + #endif USING_FDDI_NET eh.ether_type = htons(buflen); /* * Fill in the remainder of the 802.2 and SNAP header bytes. *** lib/cap/abversion.c.orig Tue Aug 29 14:16:01 1995 --- lib/cap/abversion.c Wed May 1 03:25:44 1996 *************** *** 1,7 **** /* ! * $Author: djh $ $Date: 1995/08/29 04:15:48 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abversion.c,v 2.96 1995/08/29 04:15:48 djh Rel djh $ ! * $Revision: 2.96 $ * */ --- 1,7 ---- /* ! * $Author: djh $ $Date: 1996/04/30 17:25:37 $ ! * $Header: /mac/src/cap60/lib/cap/RCS/abversion.c,v 2.97 1996/04/30 17:25:37 djh Rel djh $ ! * $Revision: 2.97 $ * */ *************** *** 32,40 **** myversion.cv_name = "CAP"; myversion.cv_version = 6; myversion.cv_subversion = 0; ! myversion.cv_patchlevel = 196; ! myversion.cv_rmonth = "August"; ! myversion.cv_ryear = "1995"; switch (lap_proto) { case LAP_KIP: myversion.cv_type = "UDP encapsulation"; --- 32,40 ---- myversion.cv_name = "CAP"; myversion.cv_version = 6; myversion.cv_subversion = 0; ! myversion.cv_patchlevel = 197; ! myversion.cv_rmonth = "April"; ! myversion.cv_ryear = "1996"; switch (lap_proto) { case LAP_KIP: myversion.cv_type = "UDP encapsulation"; *** CAP60.README.orig Wed Jun 28 14:03:29 1995 --- CAP60.README Tue Apr 30 18:44:08 1996 *************** *** 80,85 **** --- 80,92 ---- support for getmnt() or statfs() to determine the amount of free space on a filesystem. Edward Moy + FIXED_DIRIDS + Implement server and AUFS code to provide support for + fixed directory and file IDs. The 'afpidsrvr' daemon must + be started before any AUFS processes. Refer to the file + "applications/aufs/afpid.notes" for more information. + John Forrest + Scooter Morris LWSRV_AUFS_SECURITY Require LWSRV LaserWriter spooler users to have an AUFS volume connected (and therefore be password validated). *************** *** 127,132 **** --- 134,143 ---- Activate AUFS login security based on an authorisation file. Check this file if normal password field is "*". Rusty Wright + DIGITAL_UNIX_SECURITY + Use Digital UNIX enhanced security for AUFS logins. + Andrew Greer + Richard Rogers USE_MAC_DATES Keep the modification date of the Mac file intact when copied to an AUFS volume (otherwise it is the latter of *************** *** 158,163 **** --- 169,183 ---- A SIGUSR1 signal sent to AUFS causes the global AFP volumes file to be re-read. Eugene Bogaart + CLOSE_LOG_SIG + A SIGUSR2 signal sent to AUFS causes the log file to be + closed and then re-opened (allows the file to be truncated, + for example, by a script which regularly does something like + 'cat > logfile; kill -USR2 '). See also PID_FILE. + Scooter Morris + PID_FILE + Cause AUFS to write a (named) process-ID file. + Scooter Morris XDEV_RENAME Allows AUFS to copy/move files across file systems. Mark Abbott *************** *** 277,282 **** --- 297,307 ---- sockets for server use. Rakesh Patel David Hornsby + USING_FDDI_NET + Includes code to determine if interface is running on + FDDI network and adjust packets accordingly. Digital UNIX + and Ultrix only at this stage. + Conrad Huang NOCAPDOTPRINTERS If defined, PAPIF will not use /etc/cap.printers, instead the first line of the file /etc/lp/printers/lw/comment (for *************** *** 316,323 **** on each successful AUFS connection. Allows usage tracking. Gavin Longmuir Heather Ebey ! LOG_WTMP_PATH ! Specifies alternat name for the wtmp file used in LOG_WTMP. Heather Ebey ADMIN_GRP If defined, AUFS will check if the user is a member of a --- 341,348 ---- on each successful AUFS connection. Allows usage tracking. Gavin Longmuir Heather Ebey ! LOG_WTMP_FILE ! Specifies alternate name for the wtmp file used in LOG_WTMP. Heather Ebey ADMIN_GRP If defined, AUFS will check if the user is a member of a *** README.orig Tue Aug 29 14:17:11 1995 --- README Mon Mar 11 21:46:26 1996 *************** *** 2,8 **** CAP - Columbia AppleTalk Package for UNIX o RELEASE NOTES ! o CAP Distribution 6.0, Patch Level 196, August 1995 Notice ------ --- 2,8 ---- CAP - Columbia AppleTalk Package for UNIX o RELEASE NOTES ! o CAP Distribution 6.0, Patch Level 197, April 1996 Notice ------ *************** *** 28,34 **** Portions Copyright (c) 1984, Apple Computer Inc. Gene Tyacke, Alan Oppenheimer, G. Sidhu, Rich Andrews. ! Portions Copyright (c) 1990 - 1995 The University of Melbourne Modules copyright in part or whole by any other entity than Columbia University are clearly marked as such. --- 28,34 ---- Portions Copyright (c) 1984, Apple Computer Inc. Gene Tyacke, Alan Oppenheimer, G. Sidhu, Rich Andrews. ! Portions Copyright (c) 1990 - 1996 The University of Melbourne Modules copyright in part or whole by any other entity than Columbia University are clearly marked as such. *************** *** 90,95 **** --- 90,135 ---- facilities with varying levels of functionality. Under certain systems, only portions will work. + Where + ----- + + CAP can be obtained by anonymous FTP from + + rutgers.EDU src/{cap60.pl100.tar.Z,cap60.patches/*} + munnari.OZ.AU mac/{cap60.pl100.tar.Z,cap.patches/*} + gatekeeper.DEC.COM pub/net/appletalk/cap/{cap60.pl100.tar.Z,cap.patches/*} + ftp.kuis.kyoto-u.AC.JP net/cap/{cap60.pl100.tar.Z,cap60.patches/*.Z} + src.doc.ic.AC.UK packages/multigate/{cap60.pl100.tar.Z,cap.patches/*} + + Please choose an appropriate site and an off-peak time for the transfer. + + The patches are available individually or as the files "patches.1-100.tar.Z", + "patches.101-126.tar.Z", "patches.127-143.tar.Z", "patches.144-154.tar.Z", + "patches.155-162.tar.Z", "patches.163-182.tar.Z" & "patches.183-192.tar.Z". + Additionally, for new users, a partially patched source file is available + as "cap60.pl100.tar.Z" (beware: the file cap60.tar.Z is totally unpatched). + + Patches + ------- + + To make the process of patching easier, you should get the 'patch' utility + written by Larry Wall, it is normally available from sites that archive + comp.sources.unix in volume7/patch2 and at GNU archive sites as + patch-2.1.tar.gz (which requires gzip-1.2.2.tar for unpacking). + + For each of the patches, run 'patch -p < cap60.patchNNN' from the top level + cap60 directory, for example, in csh + + foreach i (cap60.patches/cap60.patch*) + patch -p < $i >>& /tmp/patches + end + + and check the /tmp/patches file for patching errors (look for the strings + "rej", "failed", "offset", "fuzz" - should be none). To remove the *.orig + files that patch leaves behind (containing the original version of the file), + run 'make spotless' from the top level directory (note that spotless also + removes all makefiles so gen.makes needs to be run to regenerate them). + Information ----------- *************** *** 104,109 **** --- 144,154 ---- via the World Wide Web using http://www.cs.mu.OZ.AU/appletalk/atalk.html + + The CAP FAQ (Frequently Asked Questions) file is available via FTP + from munnari.OZ.AU as the file + + mac/CAP.faq Documentation -------------