--- etc/afpd/unix.c.orig	Tue Aug 19 11:32:59 1997
+++ etc/afpd/unix.c	Wed Nov 24 14:17:12 1999
@@ -11,9 +11,12 @@
 #include <dirent.h>
 #include <limits.h>
 #include <atalk/afp.h>
+#include <string.h>
 #include <strings.h>
 #include <stdio.h>
+#include <unistd.h>
 #include <fcntl.h>
+#include <ufs/ufs/quota.h>
 #include "auth.h"
 #include "directory.h"
 #include "volume.h"
@@ -38,7 +41,6 @@
 #endif __svr4__
 
 #ifdef BSD4_4
-#include <ufs/ufs/quota.h>
 #include <sys/mount.h>
 #define dqb_btimelimit	dqb_btime
 #include <stdlib.h>
@@ -69,16 +71,17 @@
 /*
  * Get the free space on a partition.
  */
+int
 ustatfs_getvolspace( vol, bfree, btotal )
     struct vol	*vol;
-    u_long	*bfree, *btotal;
+    u_int32_t	*bfree, *btotal;
 {
 #ifdef ultrix
     struct fs_data	sfs;
 #else ultrix
     struct statfs	sfs;
 #endif ultrix
-    u_long	multi;
+    u_int32_t	multi;
 
     if ( statfs( vol->v_path, &sfs ) < 0 ) {
 	return( AFPERR_PARAM );
@@ -162,7 +165,7 @@
     static struct fs_data	fsd;
 
     if ( getmnt(0, &fsd, 0, STAT_ONE, file ) < 0 ) {
-	syslog( "special: getmnt %s: %m", file );
+	syslog(LOG_INFO, "special: getmnt %s: %m", file );
 	return( NULL );
     }
 
@@ -220,11 +223,17 @@
 #endif ultrix
 #endif __svr4__
 
+int	getquota(), overquota();
+int	gmem();
+int	utombits(), mtoubits();
+
+int
 getquota( vol, dq )
     struct vol		*vol;
     struct dqblk	*dq;
 {
     char		*p;
+    size_t		len;
 #ifdef __svr4__
     char		buf[ MAXNAMLEN ];
     struct quotctl	qc;
@@ -235,7 +244,7 @@
 	    return( AFPERR_PARAM );
 	}
 
-	sprintf( buf, "%s/quotas", p );
+	snprintf( buf, sizeof ( buf ), "%s/quotas", p );
 	if (( vol->v_qfd = open( buf, O_RDONLY, 0 )) < 0 ) {
 	    syslog( LOG_INFO, "open %s: %m", buf );
 	    return( AFPERR_PARAM );
@@ -255,12 +264,13 @@
 	    syslog( LOG_ERR, "getquota: special %s fails", vol->v_path );
 	    return( AFPERR_PARAM );
 	}
-
-	if (( vol->v_gvs = (char *)malloc( strlen( p ) + 1 )) == NULL ) {
+	
+	len = (strlen( p ) + 1);
+	if (( vol->v_gvs = (char *)malloc( len )) == NULL ) {
 	    syslog( LOG_ERR, "getquota: malloc: %m" );
 	    exit( 1 );
 	}
-	strcpy( vol->v_gvs, p );
+	strlcpy( vol->v_gvs, p, len );
     }
 
 #ifdef ultrix
@@ -283,9 +293,10 @@
     return( 0 );
 }
 
+int
 uquota_getvolspace( vol, bfree, btotal )
     struct vol	*vol;
-    u_long	*bfree, *btotal;
+    u_int32_t	*bfree, *btotal;
 {
     struct dqblk	dqblk;
 
@@ -304,6 +315,7 @@
     return( AFP_OK );
 }
 
+int
 overquota( dqblk )
     struct dqblk	*dqblk;
 {
@@ -336,6 +348,7 @@
 
 #endif linux
 
+void
 utommode( stat, ma )
     struct stat		*stat;
     struct maccess	*ma;
@@ -370,6 +383,7 @@
     }
 }
 
+int
 utombits( bits )
     mode_t	bits;
 {
@@ -384,6 +398,7 @@
     return( mbits );
 }
 
+int
 gmem( gid )
     int	gid;
 {
@@ -397,6 +412,7 @@
     return( 0 );
 }
 
+mode_t
 mtoumode( ma )
     struct maccess	*ma;
 {
@@ -414,6 +430,7 @@
     return( mode );
 }
 
+int
 mtoubits( bits )
     u_char	bits;
 {
@@ -428,15 +445,16 @@
     return( mode );
 }
 
+int
 setdeskmode( mode )
     mode_t	mode;
 {
     static char		wd[ MAXPATHLEN ];
-    char		c, modbuf[ 12 ], *m;
+    char		modbuf[ 12 ], *m;
     struct dirent	*deskp, *subp;
     DIR			*desk, *sub;
 
-    if ( getwd( wd ) == NULL ) {
+    if ( getcwd( wd, MAXPATHLEN ) == NULL ) {
 	return( -1 );
     }
     if ( chdir( ".AppleDesktop" ) < 0 ) {
@@ -454,9 +472,9 @@
 		strcmp( deskp->d_name, ".." ) == 0 || strlen( deskp->d_name ) > 2 ) {
 	    continue;
 	}
-	strcpy( modbuf, deskp->d_name );
-	strcat( modbuf, "/" );
-	m = index( modbuf, '\0' );
+	(void)strlcpy( modbuf, deskp->d_name, sizeof(modbuf) );
+	(void)strlcat( modbuf, "/", sizeof(modbuf) );
+	m = strchr( modbuf, '\0' );
 	if (( sub = opendir( deskp->d_name )) == NULL ) {
 	    continue;
 	}
@@ -466,13 +484,13 @@
 		continue;
 	    }
 	    *m = '\0';
-	    strcat( modbuf, subp->d_name );
+	    (void)strlcat( modbuf, subp->d_name, sizeof(modbuf) );
 	    if ( chmod( modbuf, mode ) < 0 ) {
 		syslog( LOG_DEBUG, "setdeskmode: chmod %s: %m", modbuf );
 	    }
 	}
 	closedir( sub );
-	if ( chmod( deskp->d_name, mode ) < 0 ) {
+	if ( chmod( deskp->d_name, S_ISGID | mode ) < 0 ) {
 	    syslog( LOG_DEBUG, "setdeskmode: chmod %s: %m", deskp->d_name );
 	}
     }
@@ -481,12 +499,13 @@
 	syslog( LOG_ERR, "setdeskmode: chdir %s: %m", wd );
 	exit( 1 );
     }
-    if ( chmod( ".AppleDesktop", mode ) < 0 ) {
+    if ( chmod( ".AppleDesktop", S_ISGID | mode ) < 0 ) {
 	syslog( LOG_DEBUG, "setdeskmode: chmod .AppleDesktop: %m" );
     }
     return( 0 );
 }
 
+int
 setdirmode( mode )
     mode_t	mode;
 {
@@ -508,8 +527,15 @@
 	    syslog( LOG_DEBUG, "setdirmode: stat %s: %m", dirp->d_name );
 	    continue;
 	}
-	if (( st.st_mode & S_IFMT ) == S_IFREG ) {
-	    if ( chmod( dirp->d_name, mode ) < 0 ) {
+
+	if (S_ISREG(st.st_mode)) {
+	    /* XXX: need to preserve special modes
+		asun@zoology.washington.edu */
+	    if (S_ISDIR(st.st_mode)) {
+	      if ( chmod( dirp->d_name, S_ISGID | mode ) < 0 ) {
+		syslog( LOG_DEBUG, "setdirmode: chmod %s: %m", dirp->d_name );
+	      }
+	    } else if ( chmod( dirp->d_name, mode ) < 0 ) {
 		syslog( LOG_DEBUG, "setdirmode: chmod %s: %m", dirp->d_name );
 	    }
 	}
@@ -519,42 +545,43 @@
 	syslog( LOG_ERR, "setdirmode: opendir .AppleDouble: %m" );
 	return( -1 );
     }
-    strcpy( buf, ".AppleDouble" );
-    strcat( buf, "/" );
-    m = index( buf, '\0' );
+    (void)strlcpy( buf, ".AppleDouble", sizeof(buf) );
+    (void)strlcat( buf, "/", sizeof(buf) );
+    m = strchr( buf, '\0' );
     for ( dirp = readdir( dir ); dirp != NULL; dirp = readdir( dir )) {
 	if ( strcmp( dirp->d_name, "." ) == 0 ||
 		strcmp( dirp->d_name, ".." ) == 0 ) {
 	    continue;
 	}
 	*m = '\0';
-	strcat( buf, dirp->d_name );
+	(void)strlcat( buf, dirp->d_name, sizeof(buf) );
 	if ( chmod( buf, mode ) < 0 ) {
 	    syslog( LOG_DEBUG, "setdirmode: chmod %s: %m", buf );
 	}
     }
     closedir( dir );
-    if ( chmod( ".AppleDouble", mode ) < 0 ) {
+    if ( chmod( ".AppleDouble", S_ISGID | mode ) < 0 ) {
 	syslog( LOG_ERR, "setdirmode: chmod .AppleDouble: %m" );
 	return( -1 );
     }
-    if ( chmod( ".", mode ) < 0 ) {
+    if ( chmod( ".", S_ISGID | mode ) < 0 ) {
 	syslog( LOG_ERR, "setdirmode: chmod .: %m" );
 	return( -1 );
     }
     return( 0 );
 }
 
+int
 setdeskowner( uid, gid )
     int		uid;
     int		gid;
 {
     static char		wd[ MAXPATHLEN ];
-    char		c, modbuf[ 12 ], *m;
+    char		modbuf[ 12 ], *m;
     struct dirent	*deskp, *subp;
     DIR			*desk, *sub;
 
-    if ( getwd( wd ) == NULL ) {
+    if ( getcwd( wd, MAXPATHLEN ) == NULL ) {
 	return( -1 );
     }
     if ( chdir( ".AppleDesktop" ) < 0 ) {
@@ -572,9 +599,9 @@
 		strcmp( deskp->d_name, ".." ) == 0 || strlen( deskp->d_name ) > 2 ) {
 	    continue;
 	}
-	strcpy( modbuf, deskp->d_name );
-	strcat( modbuf, "/" );
-	m = index( modbuf, '\0' );
+	(void)strlcpy( modbuf, deskp->d_name, sizeof(modbuf) );
+	(void)strlcat( modbuf, "/", sizeof(modbuf) );
+	m = strchr( modbuf, '\0' );
 	if (( sub = opendir( deskp->d_name )) == NULL ) {
 	    continue;
 	}
@@ -584,7 +611,7 @@
 		continue;
 	    }
 	    *m = '\0';
-	    strcat( modbuf, subp->d_name );
+	    (void)strlcat( modbuf, subp->d_name, sizeof(modbuf) );
 	    if ( chown( modbuf, uid, gid ) < 0 ) {
 		syslog( LOG_DEBUG, "setdeskown: chown %s: %m", modbuf );
 	    }
@@ -605,6 +632,7 @@
     return( 0 );
 }
 
+int
 setdirowner( uid, gid )
     int		uid;
     int		gid;
@@ -636,16 +664,16 @@
     if (( dir = opendir( ".AppleDouble" )) == NULL ) {
 	return( -1 );
     }
-    strcpy( buf, ".AppleDouble" );
-    strcat( buf, "/" );
-    m = index( buf, '\0' );
+    (void)strlcpy( buf, ".AppleDouble", sizeof(buf) );
+    (void)strlcat( buf, "/", sizeof(buf) );
+    m = strchr( buf, '\0' );
     for ( dirp = readdir( dir ); dirp != NULL; dirp = readdir( dir )) {
 	if ( strcmp( dirp->d_name, "." ) == 0 ||
 		strcmp( dirp->d_name, ".." ) == 0 ) {
 	    continue;
 	}
 	*m = '\0';
-	strcat( buf, dirp->d_name );
+	(void)strlcat( buf, dirp->d_name, sizeof(buf) );
 	if ( chown( buf, uid, gid ) < 0 ) {
 	    syslog( LOG_DEBUG, "setdirowner: chown %d/%d %s: %m",
 		    uid, gid, buf );
