ca76526b11
if it exists.
586 lines
15 KiB
Plaintext
586 lines
15 KiB
Plaintext
--- etc/afpd/volume.c.orig Tue Mar 31 02:57:11 1998
|
|
+++ etc/afpd/volume.c Wed Nov 24 15:09:21 1999
|
|
@@ -16,10 +16,13 @@
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
+#include <unistd.h>
|
|
#include <ctype.h>
|
|
-#include <strings.h>
|
|
+#include <string.h>
|
|
#include <pwd.h>
|
|
+#include <utime.h>
|
|
|
|
+#include "unix.h"
|
|
#include "directory.h"
|
|
#include "file.h"
|
|
#include "volume.h"
|
|
@@ -30,6 +33,14 @@
|
|
char *Trash = "\02\024Network Trash Folder";
|
|
struct extmap *extmap = NULL, *defextmap = NULL;
|
|
|
|
+void creatvol(), setextmap(), freedir();
|
|
+int readvolfile();
|
|
+int initline(), parseline();
|
|
+int getvolparams();
|
|
+
|
|
+int strdiacasecmp();
|
|
+
|
|
+void
|
|
initvolumes()
|
|
{
|
|
struct passwd *pwent;
|
|
@@ -69,6 +80,7 @@
|
|
return;
|
|
}
|
|
|
|
+int
|
|
afp_getsrvrparms( ibuf, ibuflen, rbuf, rbuflen )
|
|
char *ibuf, *rbuf;
|
|
int ibuflen, *rbuflen;
|
|
@@ -76,9 +88,9 @@
|
|
struct timeval tv;
|
|
struct stat st;
|
|
struct vol *volume;
|
|
- struct passwd *pwent;
|
|
char *data;
|
|
int vcnt, len;
|
|
+ u_int32_t secs;
|
|
|
|
initvolumes();
|
|
|
|
@@ -91,11 +103,20 @@
|
|
if (( st.st_mode & S_IFDIR ) == 0 ) {
|
|
continue; /* not a dir */
|
|
}
|
|
-
|
|
+
|
|
+ /* Apple 2 clients running ProDOS-8 expect one volume to have
|
|
+ bit 0 of this byte set. They will not recognize anything
|
|
+ on the server unless this is the case. I have not
|
|
+ completely worked this out, but it's related to booting
|
|
+ from the server. Support for that function is a ways
|
|
+ off.. <shirsch@ibm.net> */
|
|
+ if ( volume->v_flags & AFPVOL_A2VOL )
|
|
+ *data++ = (u_char) 1;
|
|
+ else
|
|
*data++ = 0;
|
|
len = strlen( volume->v_name );
|
|
*data++ = len;
|
|
- bcopy( volume->v_name, data, len );
|
|
+ memcpy( data, volume->v_name, len );
|
|
data += len;
|
|
vcnt++;
|
|
}
|
|
@@ -106,21 +127,27 @@
|
|
syslog( LOG_ERR, "afp_getsrvrparms: gettimeofday: %m" );
|
|
exit( 1 );
|
|
}
|
|
- tv.tv_sec = htonl( tv.tv_sec );
|
|
- bcopy( &tv.tv_sec, data, sizeof( tv.tv_sec ));
|
|
- data += sizeof( tv.tv_sec );
|
|
+ secs = tv.tv_sec;
|
|
+ secs = htonl( secs );
|
|
+ memcpy( data, &secs, sizeof( secs ));
|
|
+ data += sizeof( secs );
|
|
*data = vcnt;
|
|
return( AFP_OK );
|
|
}
|
|
|
|
-creatvol( path, name )
|
|
+ /* Allow volume-specific flag setting to be passed in on mount. Not
|
|
+ specific to P8; this will be needed for parameter support from the
|
|
+ Applevolumes file. */
|
|
+void
|
|
+creatvol( path, name, flags )
|
|
char *path, *name;
|
|
+ int flags;
|
|
{
|
|
struct vol *volume;
|
|
- int vlen;
|
|
+ size_t vlen, len;
|
|
|
|
if ( name == NULL || *name == '\0' ) {
|
|
- if (( name = rindex( path, '/' )) == NULL ) {
|
|
+ if (( name = strrchr( path, '/' )) == NULL ) {
|
|
return; /* Obviously not a fully qualified path */
|
|
}
|
|
name++;
|
|
@@ -147,18 +174,21 @@
|
|
syslog( LOG_ERR, "creatvol: malloc: %m" );
|
|
exit( 1 );
|
|
}
|
|
+ len = (strlen( path ) + 1);
|
|
if (( volume->v_path =
|
|
- (char *)malloc( strlen( path ) + 1 )) == NULL ) {
|
|
+ (char *)malloc( len )) == NULL ) {
|
|
syslog( LOG_ERR, "creatvol: malloc: %m" );
|
|
exit( 1 );
|
|
}
|
|
|
|
- strcpy( volume->v_name, name );
|
|
- strcpy( volume->v_path, path );
|
|
+ (void)strlcpy( volume->v_name, name, (vlen + 1) );
|
|
+ (void)strlcpy( volume->v_path, path, len );
|
|
|
|
volume->v_dir = NULL;
|
|
volume->v_did = NULL;
|
|
- volume->v_flags = 0;
|
|
+
|
|
+ /* Start with flag settings parsed from AppleVolumes */
|
|
+ volume->v_flags = flags;
|
|
#ifdef __svr4__
|
|
volume->v_qfd = -1;
|
|
#else __svr4__
|
|
@@ -209,6 +239,7 @@
|
|
* <unix path> [<volume name> [<flags>,...]]
|
|
* <extension> TYPE [CREATOR]
|
|
*/
|
|
+int
|
|
readvolfile( p1, p2, user )
|
|
char *p1, *p2;
|
|
int user;
|
|
@@ -218,13 +249,13 @@
|
|
volname[ 28 ], buf[ BUFSIZ ],
|
|
type[ 5 ], creator[ 5 ];
|
|
char *u, *p;
|
|
- int quoted = 0;
|
|
struct passwd *pw;
|
|
+ int flags;
|
|
|
|
- strcpy( path, p1 );
|
|
+ (void)strlcpy( path, p1, sizeof(path) );
|
|
if ( p2 != NULL ) {
|
|
- strcat( path, "/" );
|
|
- strcat( path, p2 );
|
|
+ (void)strlcat( path, "/", sizeof(path) );
|
|
+ (void)strlcat( path, p2, sizeof(path) );
|
|
}
|
|
|
|
if (( fp = fopen( path, "r" )) == NULL ) {
|
|
@@ -240,7 +271,7 @@
|
|
continue;
|
|
|
|
case '~' :
|
|
- if (( p = index( path, '/' )) != NULL ) {
|
|
+ if (( p = strchr( path, '/' )) != NULL ) {
|
|
*p++ = '\0';
|
|
}
|
|
u = path;
|
|
@@ -251,17 +282,24 @@
|
|
if ( u == NULL || ( pw = getpwnam( u )) == NULL ) {
|
|
continue;
|
|
}
|
|
- strcpy( tmp, pw->pw_dir );
|
|
+ (void)strlcpy( tmp, pw->pw_dir, sizeof(tmp) );
|
|
if ( p != NULL && *p != '\0' ) {
|
|
- strcat( tmp, "/" );
|
|
- strcat( tmp, p );
|
|
+ (void)strlcat( tmp, "/", sizeof(tmp) );
|
|
+ (void)strlcat( tmp, p, sizeof(tmp) );
|
|
}
|
|
- strcpy( path, tmp );
|
|
+ (void)strlcpy( path, tmp, sizeof(path) );
|
|
/* fall through */
|
|
|
|
case '/' :
|
|
parseline( sizeof( volname ) - 1, volname );
|
|
- creatvol( path, volname );
|
|
+
|
|
+ /* FIXME!! Real crude and quick way to grab a
|
|
+ user-supplied integer in [0..3] and shift it into the
|
|
+ ProDOS bits of the volume flag. Obviously some room
|
|
+ for improvement here. <shirsch@ibm.net> */
|
|
+ parseline( sizeof( tmp ) - 1, tmp );
|
|
+ flags = ( atoi ( tmp ) & 3 ) << 5;
|
|
+ creatvol( path, volname, flags );
|
|
break;
|
|
|
|
case '.' :
|
|
@@ -280,6 +318,7 @@
|
|
return( 0 );
|
|
}
|
|
|
|
+void
|
|
setextmap( ext, type, creator, user )
|
|
char *ext, *type, *creator;
|
|
int user;
|
|
@@ -304,17 +343,17 @@
|
|
return;
|
|
}
|
|
|
|
- strcpy( em->em_ext, ext );
|
|
+ (void)strlcpy( em->em_ext, ext, sizeof(em->em_ext) );
|
|
|
|
if ( *type == '\0' ) {
|
|
- bcopy( "????", em->em_type, sizeof( em->em_type ));
|
|
+ memcpy( em->em_type, "????", sizeof( em->em_type ));
|
|
} else {
|
|
- bcopy( type, em->em_type, sizeof( em->em_type ));
|
|
+ memcpy( em->em_type, type, sizeof( em->em_type ));
|
|
}
|
|
if ( *creator == '\0' ) {
|
|
- bcopy( "UNIX", em->em_creator, sizeof( em->em_creator ));
|
|
+ memcpy( em->em_creator, "UNIX", sizeof( em->em_creator ));
|
|
} else {
|
|
- bcopy( creator, em->em_creator, sizeof( em->em_creator ));
|
|
+ memcpy( em->em_creator, creator, sizeof( em->em_creator ));
|
|
}
|
|
|
|
if ( strcmp( ext, "." ) == 0 ) {
|
|
@@ -329,7 +368,7 @@
|
|
char *p;
|
|
struct extmap *em;
|
|
|
|
- if (( p = rindex( path, '.' )) == NULL ) {
|
|
+ if (( p = strrchr( path, '.' )) == NULL ) {
|
|
return( defextmap );
|
|
}
|
|
|
|
@@ -345,6 +384,7 @@
|
|
}
|
|
}
|
|
|
|
+int
|
|
afp_openvol( ibuf, ibuflen, rbuf, rbuflen )
|
|
char *ibuf, *rbuf;
|
|
int ibuflen, *rbuflen;
|
|
@@ -354,19 +394,20 @@
|
|
struct vol *volume;
|
|
struct dir *dir;
|
|
int len, ret, buflen;
|
|
- u_short bitmap;
|
|
+ u_int16_t bitmap;
|
|
+ size_t dlen;
|
|
|
|
ibuf += 2;
|
|
- bcopy( ibuf, &bitmap, sizeof( u_short ));
|
|
+ memcpy( &bitmap, ibuf, sizeof( bitmap ));
|
|
bitmap = ntohs( bitmap );
|
|
- ibuf += sizeof( u_short );
|
|
+ ibuf += sizeof( bitmap );
|
|
if (( bitmap & (1<<VOLPBIT_VID)) == 0 ) {
|
|
*rbuflen = 0;
|
|
return( AFPERR_BITMAP );
|
|
}
|
|
|
|
len = *ibuf++;
|
|
- bcopy( ibuf, volname, len );
|
|
+ memcpy( volname, ibuf, len );
|
|
volname[ len ] = '\0';
|
|
|
|
initvolumes();
|
|
@@ -394,12 +435,13 @@
|
|
dir->d_balance = 0;
|
|
dir->d_did = htonl( 2 );
|
|
dir->d_flags = 0;
|
|
- if (( dir->d_name = (char *)malloc( strlen( volume->v_name ) + 1 ))
|
|
+ dlen = (strlen( volume->v_name ) + 1);
|
|
+ if (( dir->d_name = (char *)malloc( dlen ))
|
|
== NULL ) {
|
|
syslog( LOG_ERR, "afp_openvol: malloc: %m" );
|
|
exit( 1 );
|
|
}
|
|
- strcpy( dir->d_name, volume->v_name );
|
|
+ (void)strlcpy( dir->d_name, volume->v_name, dlen );
|
|
volume->v_dir = dir;
|
|
volume->v_did = dir;
|
|
volume->v_flags |= AFPVOL_OPEN;
|
|
@@ -410,15 +452,15 @@
|
|
return( AFPERR_PARAM );
|
|
}
|
|
|
|
- buflen = *rbuflen - sizeof( u_short );
|
|
+ buflen = *rbuflen - sizeof( bitmap );
|
|
if (( ret = getvolparams( bitmap, volume, &st,
|
|
- rbuf + sizeof( u_short ), &buflen )) != AFP_OK ) {
|
|
+ rbuf + sizeof( bitmap ), &buflen )) != AFP_OK ) {
|
|
*rbuflen = 0;
|
|
return( ret );
|
|
}
|
|
- *rbuflen = buflen + sizeof( u_short );
|
|
+ *rbuflen = buflen + sizeof( bitmap );
|
|
bitmap = htons( bitmap );
|
|
- bcopy( &bitmap, rbuf, sizeof( u_short ));
|
|
+ memcpy( rbuf, &bitmap, sizeof( bitmap ));
|
|
|
|
/*
|
|
* If you mount a volume twice, the second time the trash appears on
|
|
@@ -438,16 +480,17 @@
|
|
return( AFP_OK );
|
|
}
|
|
|
|
+int
|
|
afp_closevol( ibuf, ibuflen, rbuf, rbuflen )
|
|
char *ibuf, *rbuf;
|
|
int ibuflen, *rbuflen;
|
|
{
|
|
struct vol *vol, *ovol;
|
|
- u_short vid;
|
|
+ u_int16_t vid;
|
|
|
|
*rbuflen = 0;
|
|
ibuf += 2;
|
|
- bcopy( ibuf, &vid, sizeof( u_short ));
|
|
+ memcpy( &vid, ibuf, sizeof( vid ));
|
|
if (( vol = getvolbyvid( vid )) == NULL ) {
|
|
return( AFPERR_PARAM );
|
|
}
|
|
@@ -471,6 +514,7 @@
|
|
return( AFP_OK );
|
|
}
|
|
|
|
+void
|
|
freedir( dir )
|
|
struct dir *dir;
|
|
{
|
|
@@ -484,6 +528,7 @@
|
|
free( dir );
|
|
}
|
|
|
|
+int
|
|
afp_getvolparams( ibuf, ibuflen, rbuf, rbuflen )
|
|
char *ibuf, *rbuf;
|
|
int ibuflen, *rbuflen;
|
|
@@ -491,12 +536,12 @@
|
|
struct stat st;
|
|
struct vol *vol;
|
|
int buflen, ret;
|
|
- u_short vid, bitmap;
|
|
+ u_int16_t vid, bitmap;
|
|
|
|
ibuf += 2;
|
|
- bcopy( ibuf, &vid, sizeof( u_short ));
|
|
- ibuf += sizeof( u_short );
|
|
- bcopy( ibuf, &bitmap, sizeof( u_short ));
|
|
+ memcpy( &vid, ibuf, sizeof( vid ));
|
|
+ ibuf += sizeof( vid );
|
|
+ memcpy( &bitmap, ibuf, sizeof( bitmap ));
|
|
bitmap = ntohs( bitmap );
|
|
|
|
if (( vol = getvolbyvid( vid )) == NULL ) {
|
|
@@ -509,24 +554,25 @@
|
|
return( AFPERR_PARAM );
|
|
}
|
|
|
|
- buflen = *rbuflen - sizeof( u_short );
|
|
+ buflen = *rbuflen - sizeof( bitmap );
|
|
if (( ret = getvolparams( bitmap, vol, &st,
|
|
- rbuf + sizeof( u_short ), &buflen )) != AFP_OK ) {
|
|
+ rbuf + sizeof( bitmap ), &buflen )) != AFP_OK ) {
|
|
*rbuflen = 0;
|
|
return( ret );
|
|
}
|
|
- *rbuflen = buflen + sizeof( u_short );
|
|
+ *rbuflen = buflen + sizeof( bitmap );
|
|
bitmap = htons( bitmap );
|
|
- bcopy( &bitmap, rbuf, sizeof( u_short ));
|
|
+ memcpy( rbuf, &bitmap, sizeof( bitmap ));
|
|
return( AFP_OK );
|
|
}
|
|
|
|
+int
|
|
getvolspace( vol, bfree, btotal )
|
|
struct vol *vol;
|
|
- u_long *bfree, *btotal;
|
|
+ u_int32_t *bfree, *btotal;
|
|
{
|
|
int spaceflag, rc;
|
|
- u_long qfree, qtotal;
|
|
+ u_int32_t qfree, qtotal;
|
|
|
|
spaceflag = AFPVOL_GVSMASK & vol->v_flags;
|
|
|
|
@@ -555,14 +601,26 @@
|
|
}
|
|
#endif linux
|
|
|
|
- *bfree = min( *bfree, 0x7fffffff );
|
|
- *btotal = min( *btotal, 0x7fffffff );
|
|
+ /* If this is designated as a ProDOS-8 volume, make sure to avoid
|
|
+ wrap-around by capping reported free space under 64k blocks. */
|
|
+ if ( vol->v_flags & AFPVOL_A2VOL )
|
|
+ {
|
|
+ *bfree = min( *bfree, 0x01fffe00 );
|
|
+ *btotal = min( *btotal, 0x01fffe00 );
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ *bfree = min( *bfree, 0x7fffffff );
|
|
+ *btotal = min( *btotal, 0x7fffffff );
|
|
+ }
|
|
+
|
|
vol->v_flags = ( ~AFPVOL_GVSMASK & vol->v_flags ) | AFPVOL_USTATFS;
|
|
return( AFP_OK );
|
|
}
|
|
|
|
+int
|
|
getvolparams( bitmap, vol, st, buf, buflen )
|
|
- u_short bitmap;
|
|
+ u_int16_t bitmap;
|
|
struct vol *vol;
|
|
struct stat *st;
|
|
char *buf;
|
|
@@ -570,15 +628,44 @@
|
|
{
|
|
struct adouble ad;
|
|
int bit = 0, aint, isad = 1;
|
|
- u_short ashort;
|
|
- u_long bfree, btotal;
|
|
+ u_int16_t ashort;
|
|
+ u_int32_t bfree, btotal;
|
|
char *data, *nameoff = 0;
|
|
+ char *fi, *slash;
|
|
+
|
|
+ /*
|
|
+ * For MacOS8.x support we need to create the
|
|
+ * .Parent file here if it doesn't exists - we
|
|
+ * need to set the FILERINFO bit that says
|
|
+ * we have a custom icon before MacOS8.x sees it.
|
|
+ */
|
|
|
|
if ( ad_open( vol->v_path, ADFLAGS_HF|ADFLAGS_DIR,
|
|
- O_RDONLY, 0, &ad ) < 0 ) {
|
|
+ O_RDWR|O_CREAT, 0666, &ad ) < 0 ) {
|
|
isad = 0;
|
|
}
|
|
|
|
+ /*
|
|
+ * If we did create the .Parent file here then we need to
|
|
+ * set the pathname and filerinfo bit to say we have a
|
|
+ * custom icon for MacOS8.x.
|
|
+ */
|
|
+
|
|
+ if ( isad && (ad_getoflags( &ad, ADFLAGS_HF ) & O_CREAT )) {
|
|
+ fi = ad_entry(&ad, ADEID_FINDERI);
|
|
+ slash = strrchr( vol->v_path, '/' );
|
|
+ if(slash)
|
|
+ slash++;
|
|
+ else
|
|
+ slash = vol->v_path;
|
|
+
|
|
+ ad_setentrylen( &ad, ADEID_NAME, strlen( slash ));
|
|
+ memcpy( ad_entry( &ad, ADEID_NAME ),
|
|
+ slash, ad_getentrylen( &ad, ADEID_NAME ));
|
|
+
|
|
+ fi[8] |= FINDERINFO_CUSTOMICON;
|
|
+ }
|
|
+
|
|
if (( bitmap & ( (1<<VOLPBIT_BFREE)|(1<<VOLPBIT_BTOTAL) )) != 0 ) {
|
|
if ( getvolspace( vol, &bfree, &btotal ) < 0 ) {
|
|
if ( isad ) {
|
|
@@ -598,28 +685,28 @@
|
|
switch ( bit ) {
|
|
case VOLPBIT_ATTR :
|
|
ashort = 0;
|
|
- bcopy( &ashort, data, sizeof( u_short ));
|
|
- data += sizeof( u_short );
|
|
+ memcpy( data, &ashort, sizeof( ashort ));
|
|
+ data += sizeof( ashort );
|
|
break;
|
|
|
|
case VOLPBIT_SIG :
|
|
ashort = htons( AFPVOLSIG_FIX );
|
|
- bcopy( &ashort, data, sizeof( u_short ));
|
|
- data += sizeof( u_short );
|
|
+ memcpy( data, &ashort, sizeof( ashort ));
|
|
+ data += sizeof( ashort );
|
|
break;
|
|
|
|
case VOLPBIT_CDATE :
|
|
if ( isad ) {
|
|
- bcopy( ad_entry( &ad, ADEID_FILEI ) + FILEIOFF_CREATE, &aint,
|
|
- sizeof( int ));
|
|
+ memcpy( &aint, ad_entry( &ad, ADEID_FILEI ) + FILEIOFF_CREATE,
|
|
+ sizeof( aint ));
|
|
if ( aint == 0 ) {
|
|
aint = htonl( st->st_mtime );
|
|
}
|
|
} else {
|
|
aint = htonl( st->st_mtime );
|
|
}
|
|
- bcopy( &aint, data, sizeof( int ));
|
|
- data += sizeof( int );
|
|
+ memcpy( data, &aint, sizeof( aint ));
|
|
+ data += sizeof( aint );
|
|
break;
|
|
|
|
case VOLPBIT_MDATE :
|
|
@@ -629,41 +716,41 @@
|
|
} else {
|
|
aint = htonl( vol->v_time );
|
|
}
|
|
- bcopy( &aint, data, sizeof( int ));
|
|
- data += sizeof( int );
|
|
+ memcpy( data, &aint, sizeof( aint ));
|
|
+ data += sizeof( aint );
|
|
break;
|
|
|
|
case VOLPBIT_BDATE :
|
|
if ( isad ) {
|
|
- bcopy( ad_entry( &ad, ADEID_FILEI ) + FILEIOFF_BACKUP, &aint,
|
|
- sizeof( int ));
|
|
+ memcpy( &aint, ad_entry( &ad, ADEID_FILEI ) + FILEIOFF_BACKUP,
|
|
+ sizeof( aint ));
|
|
} else {
|
|
aint = 0;
|
|
}
|
|
- bcopy( &aint, data, sizeof( int ));
|
|
- data += sizeof( int );
|
|
+ memcpy( data, &aint, sizeof( aint ));
|
|
+ data += sizeof( aint );
|
|
break;
|
|
|
|
case VOLPBIT_VID :
|
|
- bcopy( &vol->v_vid, data, sizeof( vol->v_vid ));
|
|
+ memcpy( data, &vol->v_vid, sizeof( vol->v_vid ));
|
|
data += sizeof( vol->v_vid );
|
|
break;
|
|
|
|
case VOLPBIT_BFREE :
|
|
bfree = htonl( bfree );
|
|
- bcopy( &bfree, data, sizeof( int ));
|
|
+ memcpy( data, &bfree, sizeof( int ));
|
|
data += sizeof( int );
|
|
break;
|
|
|
|
case VOLPBIT_BTOTAL :
|
|
btotal = htonl( btotal );
|
|
- bcopy( &btotal, data, sizeof( int ));
|
|
+ memcpy( data, &btotal, sizeof( int ));
|
|
data += sizeof( int );
|
|
break;
|
|
|
|
case VOLPBIT_NAME :
|
|
nameoff = data;
|
|
- data += sizeof( u_short );
|
|
+ data += sizeof( u_int16_t );
|
|
break;
|
|
|
|
default :
|
|
@@ -677,13 +764,14 @@
|
|
}
|
|
if ( nameoff != 0 ) {
|
|
ashort = htons( data - buf );
|
|
- bcopy( &ashort, nameoff, sizeof( u_short ));
|
|
+ memcpy( nameoff, &ashort, sizeof( ashort ));
|
|
aint = strlen( vol->v_name );
|
|
*data++ = aint;
|
|
- bcopy( vol->v_name, data, aint );
|
|
+ memcpy( data, vol->v_name, aint );
|
|
data += aint;
|
|
}
|
|
if ( isad ) {
|
|
+ ad_flush( &ad, ADFLAGS_HF );
|
|
ad_close( &ad, ADFLAGS_HF );
|
|
}
|
|
*buflen = data - buf;
|
|
@@ -708,6 +796,7 @@
|
|
return( vol );
|
|
}
|
|
|
|
+void
|
|
setvoltime( vol )
|
|
struct vol *vol;
|
|
{
|