31355b4571
more syslogging of login failures so we have have more info on why. patch-etcafpd-volumec Update to partially resolve the current problem with afpd not behaving correctly with permisions on /etc/netatalk. Log correctly to /var/log/daemon when we can't access configuration files. Put in place proper error checking when reading them. Would be nice if the origional programmers actually checked for failure for anything. People can now see just why things are not working as they like. Mar 29 18:08:38 kashmir afpd[6210]: session from 39148.187:250 on 39148.169:129 Mar 29 18:08:38 kashmir afpd[6210]: login dingo (uid 1002, gid 10) Mar 29 18:08:38 kashmir afpd[6210]: unable to access /etc/netatalk/AppleVolumes.system: Permission denied Mar 29 18:08:40 kashmir afpd[6210]: done Mar 29 18:08:40 kashmir afpd[21593]: asp_chld 6210 done Pass the CORRECT arguments to creatvol. from "Benninghoff, John" <JABenninghoff@dainrauscher.com> Return AFPERR_PARAM when we can't access configuration files to the appleshare client requesting access. This stops possible DOS under MacOS. In it's current form the Appleshare client has to be killed on the MAC side by killing the "CHOOSER" Application. By returning proper errors the appleshare client exits gracefully with error: "An Appleshare system error occured." patch-etcpapd-lpc cosmetic change: remove an unused variable. patch-version changes made bump version. -- From: maintainer
699 lines
20 KiB
Plaintext
699 lines
20 KiB
Plaintext
$OpenBSD: patch-etcafpd-volumec,v 1.3 2001/04/18 13:17:44 brad Exp $
|
|
--- etc/afpd/volume.c.orig Tue Mar 31 02:57:11 1998
|
|
+++ etc/afpd/volume.c Thu Apr 5 12:20:22 2001
|
|
@@ -16,29 +16,47 @@
|
|
#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"
|
|
#include "globals.h"
|
|
+#include "cvolume_iconres.h"
|
|
|
|
struct vol *volumes = NULL;
|
|
int lastvid = 0;
|
|
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();
|
|
+
|
|
+int
|
|
initvolumes()
|
|
{
|
|
struct passwd *pwent;
|
|
|
|
if ( !uservolfirst ) {
|
|
- readvolfile( systemvol, NULL, 0 );
|
|
+ if (readvolfile( systemvol, NULL, 0 ) < 0) {
|
|
+ syslog(LOG_INFO, "unable to access %s: %m ", systemvol);
|
|
+ return(-1);
|
|
+ }
|
|
}
|
|
if ( username == NULL ) {
|
|
- readvolfile( defaultvol, NULL, 1 );
|
|
+ if (readvolfile( defaultvol, NULL, 1 ) < 0) {
|
|
+ syslog(LOG_INFO, "unable to access %s: %m ", defaultvol);
|
|
+ return(-1);
|
|
+ }
|
|
} else if (( pwent = getpwnam( username )) != NULL ) {
|
|
/*
|
|
* Read user's AppleVolumes or .AppleVolumes file
|
|
@@ -49,7 +67,7 @@ initvolumes()
|
|
readvolfile( pwent->pw_dir, ".applevolumes", 1 ) < 0 &&
|
|
defaultvol != NULL ) {
|
|
if ( readvolfile( defaultvol, NULL, 1 ) < 0 ) {
|
|
- creatvol( pwent->pw_dir, NULL );
|
|
+ creatvol( pwent->pw_dir, NULL, 0 );
|
|
}
|
|
}
|
|
#else !DOWNCASE
|
|
@@ -57,18 +75,22 @@ initvolumes()
|
|
readvolfile( pwent->pw_dir, ".AppleVolumes", 1 ) < 0 &&
|
|
defaultvol != NULL ) {
|
|
if ( readvolfile( defaultvol, NULL, 1 ) < 0 ) {
|
|
- creatvol( pwent->pw_dir, NULL );
|
|
+ creatvol( pwent->pw_dir, NULL, 0 );
|
|
}
|
|
}
|
|
#endif DOWNCASE
|
|
}
|
|
- if ( uservolfirst ) {
|
|
- readvolfile( systemvol, NULL, 0 );
|
|
+ if ( uservolfirst && systemvol !=NULL) {
|
|
+ if (readvolfile( systemvol, NULL, 0 ) < 0) {
|
|
+ syslog(LOG_INFO, "unable to access %s: %m ", defaultvol);
|
|
+ return(-1);
|
|
+ }
|
|
}
|
|
|
|
- return;
|
|
+ return(0);
|
|
}
|
|
|
|
+int
|
|
afp_getsrvrparms( ibuf, ibuflen, rbuf, rbuflen )
|
|
char *ibuf, *rbuf;
|
|
int ibuflen, *rbuflen;
|
|
@@ -76,11 +98,14 @@ afp_getsrvrparms( ibuf, ibuflen, rbuf, r
|
|
struct timeval tv;
|
|
struct stat st;
|
|
struct vol *volume;
|
|
- struct passwd *pwent;
|
|
char *data;
|
|
- int vcnt, len;
|
|
+ char iconpath[MAXPATHLEN], iconpathres[MAXPATHLEN];
|
|
+ char parentpath[MAXPATHLEN];
|
|
+ int vcnt, len, iconfd;
|
|
+ u_int32_t secs;
|
|
|
|
- initvolumes();
|
|
+ if (initvolumes() < 0)
|
|
+ return(AFPERR_PARAM);
|
|
|
|
data = rbuf + 5;
|
|
for ( vcnt = 0, volume = volumes; volume; volume = volume->v_next ) {
|
|
@@ -91,13 +116,71 @@ afp_getsrvrparms( ibuf, ibuflen, rbuf, r
|
|
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++;
|
|
+
|
|
+ /* check for colour icon file in the root directory of the volume.
|
|
+ If it's not there, we will create one. First we need to create
|
|
+ an Icon\015 file with an empty data fork in volume->v_path.
|
|
+ Next we need to create the resource fork for Icon\015 file in
|
|
+ volume->v_path+.AppleDouble. Copy our Colour_Volume_icon[] data
|
|
+ into the resource fork. i.mcwilliam@uws.edu.au */
|
|
+
|
|
+ if (username != NULL) {
|
|
+ syslog(LOG_INFO, "Colour Icon for volume: %s ?", volume->v_name );
|
|
+
|
|
+ /* build a path to the icon file. */
|
|
+ snprintf(iconpath, sizeof(iconpath), "%s/Icon\015", volume->v_path);
|
|
+ snprintf(iconpathres, sizeof(iconpathres),
|
|
+ "%s/.AppleDouble/Icon\015", volume->v_path);
|
|
+ syslog( LOG_INFO, "iconpath: %s", iconpath);
|
|
+ if (!access(iconpath, F_OK)) {
|
|
+ syslog( LOG_INFO, "Icon^M found for volume: %s", volume->v_name );
|
|
+ syslog( LOG_INFO, "Not updating icon for volume: %s", volume->v_name);
|
|
+ } else {
|
|
+ /* create an empty data fork and populate the resource fork
|
|
+ with the new icon data. */
|
|
+ if (( iconfd = open( iconpath, O_CREAT | O_WRONLY, 0664 )) < 0 ) {
|
|
+ syslog( LOG_INFO, "can't open iconpath!: %m");
|
|
+ } else { close(iconfd); }
|
|
+
|
|
+ if (( iconfd = open( iconpathres, O_CREAT | O_WRONLY, 0664 )) < 0 ) {
|
|
+ syslog( LOG_INFO, "can't open iconpathres!: %m");
|
|
+ } else {
|
|
+ /* copy our resource data into the file. */
|
|
+
|
|
+ write(iconfd, Colour_Volume_icon, sizeof(Colour_Volume_icon));
|
|
+ fsync(iconfd);
|
|
+ close(iconfd);
|
|
+ syslog (LOG_INFO, "Colour Icon added to volume: %s",
|
|
+ volume->v_name);
|
|
+
|
|
+ /* remove the .AppleDouble/.Parent file otherwise
|
|
+ the icon will not show up on the desktop. The
|
|
+ .Parent file will be recreated */
|
|
+ snprintf(parentpath, sizeof(parentpath), "%s/.AppleDouble/.Parent", volume->v_path);
|
|
+ if (!access(parentpath, F_OK)) {
|
|
+ syslog(LOG_INFO, "removing .Parent file: %s", parentpath);
|
|
+ unlink(parentpath);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
}
|
|
|
|
*rbuflen = data - rbuf;
|
|
@@ -106,21 +189,27 @@ afp_getsrvrparms( ibuf, ibuflen, rbuf, r
|
|
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 +236,21 @@ creatvol( path, name )
|
|
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 +301,7 @@ char *myfgets( buf, size, fp )
|
|
* <unix path> [<volume name> [<flags>,...]]
|
|
* <extension> TYPE [CREATOR]
|
|
*/
|
|
+int
|
|
readvolfile( p1, p2, user )
|
|
char *p1, *p2;
|
|
int user;
|
|
@@ -218,13 +311,13 @@ readvolfile( p1, p2, user )
|
|
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 +333,7 @@ readvolfile( p1, p2, user )
|
|
continue;
|
|
|
|
case '~' :
|
|
- if (( p = index( path, '/' )) != NULL ) {
|
|
+ if (( p = strchr( path, '/' )) != NULL ) {
|
|
*p++ = '\0';
|
|
}
|
|
u = path;
|
|
@@ -251,17 +344,24 @@ readvolfile( p1, p2, user )
|
|
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 +380,7 @@ readvolfile( p1, p2, user )
|
|
return( 0 );
|
|
}
|
|
|
|
+void
|
|
setextmap( ext, type, creator, user )
|
|
char *ext, *type, *creator;
|
|
int user;
|
|
@@ -304,17 +405,17 @@ setextmap( ext, type, creator, user )
|
|
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 +430,7 @@ getextmap( path )
|
|
char *p;
|
|
struct extmap *em;
|
|
|
|
- if (( p = rindex( path, '.' )) == NULL ) {
|
|
+ if (( p = strrchr( path, '.' )) == NULL ) {
|
|
return( defextmap );
|
|
}
|
|
|
|
@@ -345,6 +446,7 @@ getextmap( path )
|
|
}
|
|
}
|
|
|
|
+int
|
|
afp_openvol( ibuf, ibuflen, rbuf, rbuflen )
|
|
char *ibuf, *rbuf;
|
|
int ibuflen, *rbuflen;
|
|
@@ -354,22 +456,24 @@ afp_openvol( ibuf, ibuflen, rbuf, rbufle
|
|
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();
|
|
+ if (initvolumes() < 0 )
|
|
+ return(AFPERR_PARAM);
|
|
|
|
for ( volume = volumes; volume; volume = volume->v_next ) {
|
|
if ( strcasecmp( volname, volume->v_name ) == 0 ) {
|
|
@@ -394,12 +498,13 @@ afp_openvol( ibuf, ibuflen, rbuf, rbufle
|
|
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 +515,15 @@ afp_openvol( ibuf, ibuflen, rbuf, rbufle
|
|
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 +543,17 @@ afp_openvol( ibuf, ibuflen, rbuf, rbufle
|
|
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 +577,7 @@ afp_closevol( ibuf, ibuflen, rbuf, rbufl
|
|
return( AFP_OK );
|
|
}
|
|
|
|
+void
|
|
freedir( dir )
|
|
struct dir *dir;
|
|
{
|
|
@@ -484,6 +591,7 @@ freedir( dir )
|
|
free( dir );
|
|
}
|
|
|
|
+int
|
|
afp_getvolparams( ibuf, ibuflen, rbuf, rbuflen )
|
|
char *ibuf, *rbuf;
|
|
int ibuflen, *rbuflen;
|
|
@@ -491,12 +599,12 @@ afp_getvolparams( ibuf, ibuflen, rbuf, r
|
|
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 +617,25 @@ afp_getvolparams( ibuf, ibuflen, rbuf, r
|
|
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 +664,26 @@ getvolspace( vol, bfree, btotal )
|
|
}
|
|
#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 +691,44 @@ getvolparams( bitmap, vol, st, buf, bufl
|
|
{
|
|
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 +748,28 @@ getvolparams( bitmap, vol, st, buf, bufl
|
|
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 +779,41 @@ getvolparams( bitmap, vol, st, buf, bufl
|
|
} 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 +827,14 @@ getvolparams( bitmap, vol, st, buf, bufl
|
|
}
|
|
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 +859,7 @@ getvolbyvid( vid )
|
|
return( vol );
|
|
}
|
|
|
|
+void
|
|
setvoltime( vol )
|
|
struct vol *vol;
|
|
{
|