/*
+ * $Id: filedir.c,v 1.14 2001-09-06 20:00:59 rufustfirefly Exp $
+ *
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
+#endif /* HAVE_CONFIG_H */
#include <errno.h>
#include <sys/syslog.h>
#include <atalk/adouble.h>
#include <atalk/afp.h>
#include <atalk/util.h>
+#ifdef CNID_DB
#include <atalk/cnid.h>
+#endif /* CNID_DB */
#include <stdio.h>
#include <stdlib.h>
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
#include <dirent.h>
+
+/* STDC check */
+#if STDC_HEADERS
#include <string.h>
+#else /* STDC_HEADERS */
+#ifndef HAVE_STRCHR
+#define strchr index
+#define strrchr index
+#endif /* HAVE_STRCHR */
+char *strchr (), *strrchr ();
+#ifndef HAVE_MEMCPY
+#define memcpy(d,s,n) bcopy ((s), (d), (n))
+#define memmove(d,s,n) bcopy ((s), (d), (n))
+#endif /* ! HAVE_MEMCPY */
+#endif /* STDC_HEADERS */
+
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
#include "directory.h"
#include "desktop.h"
#ifdef DEBUG
syslog (LOG_INFO, "begin matchfile2dirperms:");
-#endif DEBUG
+#endif /* DEBUG */
if (stat(upath, &st ) < 0)
- syslog(LOG_ERR, "Could not stat %s: %m", upath);
+ syslog(LOG_ERR, "Could not stat %s: %s", upath, strerror(errno));
strcpy (adpath, "./.AppleDouble/");
strcat (adpath, upath);
if (( dir = dirsearch( vol, did )) == NULL ) {
}
else if (stat(".", &sb) < 0) {
syslog (LOG_ERR,
- "matchfile2dirperms: Error checking directory \"%s\": %m",
- dir->d_name);
+ "matchfile2dirperms: Error checking directory \"%s\": %s",
+ dir->d_name, strerror(errno));
return(AFPERR_NOOBJ );
}
else {
if (lchown(upath, sb.st_uid, sb.st_gid) < 0)
{
syslog (LOG_ERR,
- "matchfile2dirperms: Error changing owner/gid of %s: %m", upath);
+ "matchfile2dirperms: Error changing owner/gid of %s: %s",
+ upath, strerror(errno));
return (AFPERR_ACCESS);
}
if (chmod(upath,(st.st_mode&0x0FFFF)| S_IRGRP| S_IROTH) < 0)
{
syslog (LOG_ERR,
- "matchfile2dirperms: Error adding file read permissions: %m");
+ "matchfile2dirperms: Error adding file read permissions: %s",
+ strerror(errno));
return (AFPERR_ACCESS);
}
#ifdef DEBUG
else
syslog (LOG_INFO,
- "matchfile2dirperms: Added S_IRGRP and S_IROTH: %m");
-#endif DEBUG
+ "matchfile2dirperms: Added S_IRGRP and S_IROTH: %s",
+ strerror(errno));
+#endif /* DEBUG */
if (lchown(adpath, sb.st_uid, sb.st_gid) < 0)
{
syslog (LOG_ERR,
- "matchfile2dirperms: Error changing AppleDouble owner/gid %s: %m",
- adpath);
+ "matchfile2dirperms: Error changing AppleDouble owner/gid %s: %s",
+ adpath, strerror(errno));
return (AFPERR_ACCESS);
}
if (chmod(adpath, (st.st_mode&0x0FFFF)| S_IRGRP| S_IROTH) < 0)
{
syslog (LOG_ERR,
- "matchfile2dirperms: Error adding AD file read permissions: %m");
+ "matchfile2dirperms: Error adding AD file read permissions: %s",
+ strerror(errno));
return (AFPERR_ACCESS);
}
#ifdef DEBUG
else
syslog (LOG_INFO,
- "matchfile2dirperms: Added S_IRGRP and S_IROTH to AD: %m");
-#endif DEBUG
+ "matchfile2dirperms: Added S_IRGRP and S_IROTH to AD: %s",
+ strerror(errno));
+#endif /* DEBUG */
}
#ifdef DEBUG
else
syslog (LOG_INFO,
"matchfile2dirperms: No ownership change necessary.");
-#endif DEBUG
+#endif /* DEBUG */
} /* end else if stat success */
seteuid(uid); /* Restore process ownership to normal */
#ifdef DEBUG
syslog (LOG_INFO, "end matchfile2dirperms:");
-#endif DEBUG
+#endif /* DEBUG */
return (AFP_OK);
#ifdef DEBUG
syslog(LOG_INFO, "begin afp_getfildirparams:");
-#endif DEBUG
+#endif /* DEBUG */
*rbuflen = 0;
ibuf += 2;
buflen = 0;
if (S_ISDIR(st.st_mode)) {
- if (dbitmap && ( ret = getdirparams(vol, dbitmap, ".", curdir,
- &st, rbuf + 3 * sizeof( u_int16_t ), &buflen )) != AFP_OK ) {
- return( ret );
+ if (dbitmap) {
+ ret = getdirparams(vol, dbitmap, ".", curdir,
+ &st, rbuf + 3 * sizeof( u_int16_t ), &buflen );
+ if (ret != AFP_OK )
+ return( ret );
}
/* this is a directory */
- *(rbuf + 2 * sizeof( u_int16_t )) = FILDIRBIT_ISDIR;
+ *(rbuf + 2 * sizeof( u_int16_t )) = (char) FILDIRBIT_ISDIR;
} else {
if (fbitmap && ( ret = getfilparams(vol, fbitmap, path, curdir, &st,
rbuf + 3 * sizeof( u_int16_t ), &buflen )) != AFP_OK ) {
#ifdef DEBUG
syslog(LOG_INFO, "end afp_getfildirparams:");
-#endif DEBUG
+#endif /* DEBUG */
return( AFP_OK );
}
#ifdef DEBUG
syslog(LOG_INFO, "begin afp_setfildirparams:");
-#endif DEBUG
+#endif /* DEBUG */
*rbuflen = 0;
ibuf += 2;
#ifdef DEBUG
syslog(LOG_INFO, "end afp_setfildirparams:");
-#endif DEBUG
+#endif /* DEBUG */
return( rc );
}
u_int32_t did;
int plen;
u_int16_t vid;
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
cnid_t id;
-#endif
+#endif /* CNID_DB */
#ifdef DEBUG
syslog(LOG_INFO, "begin afp_rename:");
-#endif DEBUG
+#endif /* DEBUG */
*rbuflen = 0;
ibuf += 2;
if ( strcasecmp( path, ibuf ) == 0 ) {
return( AFP_OK );
}
-#endif notdef
+#endif /* notdef */
/* if a curdir/newname ofork exists, return busy */
if (of_findname(vol, curdir, ibuf))
if (!validupath(vol, newpath))
return AFPERR_EXIST;
+ /* check for vetoed filenames */
+ if (veto_file(vol->v_veto, newpath))
+ return AFPERR_EXIST;
+
/* the strdiacasecmp deals with case-insensitive, case preserving
filesystems */
if (stat( newpath, &st ) == 0 && strdiacasecmp(path, ibuf))
upath = mtoupath(vol, path);
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
-#endif
+#endif /* CNID_DB */
if ( rename( upath, newpath ) < 0 ) {
switch ( errno ) {
}
}
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
if (stat(newpath, &st) < 0) /* this shouldn't fail */
return AFPERR_MISC;
cnid_update(vol->v_db, id, &st, curdir->d_did, newpath, strlen(newpath));
-#endif
+#endif /* CNID_DB */
if ( !odir ) {
newadpath = obj->newtmp;
isad = 0;
}
if ((buf = realloc( odir->d_name, plen + 1 )) == NULL ) {
- syslog( LOG_ERR, "afp_rename: realloc: %m" );
+ syslog( LOG_ERR, "afp_rename: realloc: %s", strerror(errno) );
if (isad) {
ad_flush(&ad, ADFLAGS_HF); /* in case of create */
ad_close(&ad, ADFLAGS_HF);
#ifdef DEBUG
syslog(LOG_INFO, "end afp_rename:");
-#endif DEBUG
+#endif /* DEBUG */
return( AFP_OK );
}
#ifdef DEBUG
syslog(LOG_INFO, "begin afp_delete:");
-#endif DEBUG
+#endif /* DEBUG */
*rbuflen = 0;
ibuf += 2;
} else if (of_findname(vol, curdir, path)) {
rc = AFPERR_BUSY;
} else if ((rc = deletefile( upath = mtoupath(vol, path ))) == AFP_OK) {
-#if AD_VERSION > AD_VERSION1 /* get rid of entry */
+#ifdef CNID_DB /* get rid of entry */
cnid_t id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
cnid_delete(vol->v_db, id);
-#endif
+#endif /* CNID_DB */
}
if ( rc == AFP_OK ) {
setvoltime(obj, vol );
#ifdef DEBUG
syslog(LOG_INFO, "end afp_delete:");
-#endif DEBUG
+#endif /* DEBUG */
return( rc );
}
char *oldname, *newname;
char *path, *p, *upath;
int did, rc;
- int plen, retvalue;
+ int plen;
u_int16_t vid;
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
cnid_t id;
-#endif
+#endif /* CNID_DB */
+#ifdef DROPKLUDGE
+ int retvalue;
+#endif /* DROPKLUDGE */
#ifdef DEBUG
syslog(LOG_INFO, "begin afp_moveandrename:");
-#endif DEBUG
+#endif /* DEBUG */
*rbuflen = 0;
ibuf += 2;
/* not a directory */
strcpy(newname, path);
strcpy(oldname, path); /* an extra copy for of_rename */
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
p = mtoupath(vol, path);
id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
-#endif
+#endif /* CNID_DB */
p = ctoupath( vol, sdir, newname );
} else {
odir = curdir;
strcpy( newname, odir->d_name );
- strcpy(oldname, odir->d_name);
+ strcpy(oldname, odir->d_name);
p = ctoupath( vol, odir->d_parent, newname );
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
id = curdir->d_did; /* we already have the CNID */
-#endif
+#endif /* CNID_DB */
}
/*
* p now points to the full pathname of the source fs object.
if (!validupath(vol, upath))
return AFPERR_EXIST;
+ /* check for vetoed filenames */
+ if (veto_file(vol->v_veto, upath))
+ return AFPERR_EXIST;
+
/* source == destination. we just silently accept this. */
if (curdir == sdir) {
if (strcmp(oldname, newname) == 0)
}
#ifdef DROPKLUDGE
- if (retvalue=matchfile2dirperms (newname, vol, did) != AFP_OK)
- return retvalue;
-#endif DROPKLUDGE
+ if (vol->v_flags & AFPVOL_DROPBOX) {
+ if (retvalue=matchfile2dirperms (newname, vol, did) != AFP_OK) {
+ return retvalue;
+ }
+ }
+#endif /* DROPKLUDGE */
if ( rc == AFP_OK ) {
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
/* renaming may have moved the file/dir across a filesystem */
- if (stat(upath, &st) < 0)
+ if (stat(upath, &st) < 0)
return AFPERR_MISC;
-
+
/* fix up the catalog entry */
cnid_update(vol->v_db, id, &st, curdir->d_did, upath, strlen(upath));
-#endif
+#endif /* CNID_DB */
setvoltime(obj, vol );
}
#ifdef DEBUG
syslog(LOG_INFO, "end afp_moveandrename:");
-#endif DEBUG
+#endif /* DEBUG */
return( rc );
}
+int veto_file(const char*veto_str, const char*path)
+/* given a veto_str like "abc/zxc/" and path "abc", return 1
+ * veto_str should be '/' delimited
+ * if path matches any one of the veto_str elements exactly, then 1 is returned
+ * otherwise, 0 is returned.
+ */
+{
+ int i; /* index to veto_str */
+ int j; /* index to path */
+
+ if ((veto_str == NULL) || (path == NULL))
+ return 0;
+/*
+#ifdef DEBUG
+ syslog(LOG_DEBUG, "veto_file \"%s\", \"%s\"", veto_str, path);
+#endif
+*/
+ for(i=0, j=0; veto_str[i] != '\0'; i++) {
+ if (veto_str[i] == '/') {
+ if ((j>0) && (path[j] == '\0'))
+ return 1;
+ j = 0;
+ } else {
+ if (veto_str[i] != path[j]) {
+ while ((veto_str[i] != '/')
+ && (veto_str[i] != '\0'))
+ i++;
+ j = 0;
+ continue;
+ }
+ j++;
+ }
+ }
+ return 0;
+}
+