/*
- * $Id: volume.c,v 1.107 2009-11-30 15:24:37 didg Exp $
+ * $Id: volume.c,v 1.108 2009-12-01 16:36:14 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#define VOLOPT_DFLTPERM 26 /* perm */
#define VOLOPT_EA_VFS 27 /* Extended Attributes vfs indirection */
-#define VOLOPT_MAX (VOLOPT_DFLTPERM +1)
-
-#define VOLOPT_NUM (VOLOPT_MAX + 1)
+#define VOLOPT_MAX 28 /* <== IMPORTANT !!!!!! */
+#define VOLOPT_NUM (VOLOPT_MAX + 1)
#define VOLPASSLEN 8
#define VOLOPT_DEFAULT ":DEFAULT:"
#endif
{NULL, 0, 0, 0}};
-typedef struct _volopt_name {
- const u_int32_t option;
- const char *name;
-} _vol_opt_name;
-
-
-/* Keep in sync with libatalk/util/volinfo.c ! */
-static const _vol_opt_name vol_opt_names[] = {
- {AFPVOL_A2VOL, "PRODOS"}, /* prodos volume */
- {AFPVOL_CRLF, "CRLF"}, /* cr/lf translation */
- {AFPVOL_NOADOUBLE, "NOADOUBLE"}, /* don't create .AppleDouble by default */
- {AFPVOL_RO, "READONLY"}, /* read-only volume */
- {AFPVOL_MSWINDOWS, "MSWINDOWS"}, /* deal with ms-windows yuckiness. this is going away. */
- {AFPVOL_NOHEX, "NOHEX"}, /* don't do :hex translation */
- {AFPVOL_USEDOTS, "USEDOTS"}, /* use real dots */
- {AFPVOL_LIMITSIZE, "LIMITSIZE"}, /* limit size for older macs */
- {AFPVOL_MAPASCII, "MAPASCII"}, /* map the ascii range as well */
- {AFPVOL_DROPBOX, "DROPBOX"}, /* dropkludge dropbox support */
- {AFPVOL_NOFILEID, "NOFILEID"}, /* don't advertise createid resolveid and deleteid calls */
- {AFPVOL_NOSTAT, "NOSTAT"}, /* advertise the volume even if we can't stat() it
- * maybe because it will be mounted later in preexec */
- {AFPVOL_UNIX_PRIV, "UNIXPRIV"}, /* support unix privileges */
- {AFPVOL_NODEV, "NODEV"}, /* always use 0 for device number in cnid calls */
- {AFPVOL_CASEINSEN, "CASEINSENSITIVE"}, /* volume is case insensitive */
- {AFPVOL_EILSEQ, "ILLEGALSEQ"}, /* encode illegal sequence */
- {AFPVOL_CACHE, "CACHEID"}, /* Use adouble v2 CNID caching. Default: yes */
- {AFPVOL_ACLS, "ACLS"}, /* Vol supports ACLs */
- {AFPVOL_TM, "TM"}, /* Set "kSupportsTMLockSteal" is volume attributes */
- {0, NULL}
-};
-
-static const _vol_opt_name vol_opt_casefold[] = {
- {AFPVOL_MTOUUPPER, "MTOULOWER"},
- {AFPVOL_MTOULOWER, "MTOULOWER"},
- {AFPVOL_UTOMUPPER, "UTOMUPPER"},
- {AFPVOL_UTOMLOWER, "UTOMLOWER"},
- {0, NULL}
-};
-
static void handle_special_folders (const struct vol *);
-static int savevoloptions (const struct vol *);
static void deletevol(struct vol *vol);
static void volume_free(struct vol *vol);
if (!(volume->v_flags & AFPVOL_RO)) {
handle_special_folders( volume );
- savevoloptions( volume);
+ savevolinfo(volume, Cnid_srv, Cnid_port);
}
/*
}
}
-/*
- * Save the volume options to a file, used by
- * shell utilities.
- * Writing the file everytime a volume is opened is
- * unnecessary, but it shouldn't hurt much.
- */
-static int savevoloptions (const struct vol *vol)
-{
- char buf[16348];
- char item[MAXPATHLEN];
- int fd;
- int ret = 0;
- struct flock lock;
- const _vol_opt_name *op = &vol_opt_names[0];
- const _vol_opt_name *cf = &vol_opt_casefold[0];
-
- strlcpy (item, vol->v_path, sizeof(item));
- strlcat (item, "/.AppleDesktop/", sizeof(item));
- strlcat (item, VOLINFOFILE, sizeof(item));
-
- if ((fd = open( item, O_RDWR | O_CREAT , 0666)) <0 ) {
- LOG(log_debug, logtype_afpd,"Error opening %s: %s", item, strerror(errno));
- return (-1);
- }
-
- /* try to get a lock */
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
- lock.l_type = F_WRLCK;
-
- if (fcntl(fd, F_SETLK, &lock) < 0) {
- if (errno == EACCES || errno == EAGAIN) {
- /* ignore, other process already writing the file */
- return 0;
- } else {
- LOG(log_error, logtype_cnid, "savevoloptions: cannot get lock: %s", strerror(errno));
- return (-1);
- }
- }
-
- /* write volume options */
- snprintf(buf, sizeof(buf), "MAC_CHARSET:%s\n", vol->v_maccodepage);
- snprintf(item, sizeof(item), "VOL_CHARSET:%s\n", vol->v_volcodepage);
- strlcat(buf, item, sizeof(buf));
-
- switch (vol->v_adouble) {
- case AD_VERSION1:
- strlcat(buf, "ADOUBLE_VER:v1\n", sizeof(buf));
- break;
- case AD_VERSION2:
- strlcat(buf, "ADOUBLE_VER:v2\n", sizeof(buf));
- break;
- case AD_VERSION2_OSX:
- strlcat(buf, "ADOUBLE_VER:osx\n", sizeof(buf));
- break;
- case AD_VERSION1_SFM:
- strlcat(buf, "ADOUBLE_VER:sfm\n", sizeof(buf));
- break;
- }
-
- strlcat(buf, "CNIDBACKEND:", sizeof(buf));
- strlcat(buf, vol->v_cnidscheme, sizeof(buf));
- strlcat(buf, "\n", sizeof(buf));
-
- strlcat(buf, "CNIDDBDHOST:", sizeof(buf));
- strlcat(buf, Cnid_srv, sizeof(buf));
- strlcat(buf, "\n", sizeof(buf));
-
- strlcat(buf, "CNIDDBDPORT:", sizeof(buf));
- strlcat(buf, Cnid_port, sizeof(buf));
- strlcat(buf, "\n", sizeof(buf));
-
- strcpy(item, "CNID_DBPATH:");
- if (vol->v_dbpath)
- strlcat(item, vol->v_dbpath, sizeof(item));
- else
- strlcat(item, vol->v_path, sizeof(item));
- strlcat(item, "\n", sizeof(item));
- strlcat(buf, item, sizeof(buf));
-
- /* volume flags */
- strcpy(item, "VOLUME_OPTS:");
- for (;op->name; op++) {
- if ( (vol->v_flags & op->option) ) {
- strlcat(item, op->name, sizeof(item));
- strlcat(item, " ", sizeof(item));
- }
- }
- strlcat(item, "\n", sizeof(item));
- strlcat(buf, item, sizeof(buf));
-
- /* casefold flags */
- strcpy(item, "VOLCASEFOLD:");
- for (;cf->name; cf++) {
- if ( (vol->v_casefold & cf->option) ) {
- strlcat(item, cf->name, sizeof(item));
- strlcat(item, " ", sizeof(item));
- }
- }
- strlcat(item, "\n", sizeof(item));
- strlcat(buf, item, sizeof(buf));
-
- if (strlen(buf) >= sizeof(buf)-1)
- LOG(log_debug, logtype_afpd,"Error writing .volinfo file: buffer too small, %s", buf);
-
-
- if (write( fd, buf, strlen(buf)) < 0 || ftruncate(fd, strlen(buf)) < 0 ) {
- LOG(log_debug, logtype_afpd,"Error writing .volinfo file: %s", strerror(errno));
- }
-
- lock.l_type = F_UNLCK;
- fcntl(fd, F_SETLK, &lock);
- close (fd);
- return ret;
-}
/*
- * $Id: volinfo.h,v 1.8 2009-10-02 09:32:41 franklahm Exp $
+ * $Id: volinfo.h,v 1.9 2009-12-01 16:36:14 franklahm Exp $
*/
#ifndef _ATALK_VOLINFO_H
#define _ATALK_VOLINFO_H 1
#include <atalk/unicode.h>
-
-/* FIXME: following duplicated from etc/afpd/volume.h */
-
-/* flags that alter volume behaviour. */
-#define AFPVOL_A2VOL (1 << 5) /* prodos volume */
-#define AFPVOL_CRLF (1 << 6) /* cr/lf translation */
-#define AFPVOL_NOADOUBLE (1 << 7) /* don't create .AppleDouble by default */
-#define AFPVOL_RO (1 << 8) /* read-only volume */
-#define AFPVOL_MSWINDOWS (1 << 9) /* deal with ms-windows yuckiness. this is going away. */
-#define AFPVOL_NOHEX (1 << 10) /* don't do :hex translation */
-#define AFPVOL_USEDOTS (1 << 11) /* use real dots */
-#define AFPVOL_LIMITSIZE (1 << 12) /* limit size for older macs */
-#define AFPVOL_MAPASCII (1 << 13) /* map the ascii range as well */
-#define AFPVOL_DROPBOX (1 << 14) /* dropkludge dropbox support */
-#define AFPVOL_NOFILEID (1 << 15) /* don't advertise createid resolveid and deleteid calls */
-#define AFPVOL_NOSTAT (1 << 16) /* advertise the volume even if we can't stat() it
- * maybe because it will be mounted later in preexec */
-#define AFPVOL_UNIX_PRIV (1 << 17) /* support unix privileges */
-#define AFPVOL_NODEV (1 << 18) /* always use 0 for device number in cnid calls
- * help if device number is notconsistent across reboot
- * NOTE symlink to a different device will return an ACCESS error */
-#define AFPVOL_CASEINSEN (1 << 19) /* volume is case insensitive */
-#define AFPVOL_EILSEQ (1 << 20) /* encode illegal sequence 'asis' UCS2, ex "\217-", which is not
- a valid SHIFT-JIS char, is encoded as U\217 -*/
-#define AFPVOL_CACHE (1 << 21) /* Use adouble v2 CNID caching, default don't use it */
-#define AFPVOL_INV_DOTS (1 << 22) /* dots files are invisible */
-#define AFPVOL_TM (1 << 24) /* Supports TimeMachine */
-#define AFPVOL_ACLS (1 << 25) /* Volume supports ACLS */
-
-/* handle casefolding */
-#define AFPVOL_MTOUUPPER (1 << 0)
-#define AFPVOL_MTOULOWER (1 << 1)
-#define AFPVOL_UTOMUPPER (1 << 2)
-#define AFPVOL_UTOMLOWER (1 << 3)
-#define AFPVOL_UMLOWER (AFPVOL_MTOULOWER | AFPVOL_UTOMLOWER)
-#define AFPVOL_UMUPPER (AFPVOL_MTOUUPPER | AFPVOL_UTOMUPPER)
-#define AFPVOL_UUPPERMLOWER (AFPVOL_MTOUUPPER | AFPVOL_UTOMLOWER)
-#define AFPVOL_ULOWERMUPPER (AFPVOL_MTOULOWER | AFPVOL_UTOMUPPER)
+#include <atalk/volume.h>
/* volinfo for shell utilities */
#define VOLINFODIR ".AppleDesktop"
#define VOLINFOFILE ".volinfo"
+typedef struct {
+ const u_int32_t option;
+ const char *name;
+} vol_opt_name_t;
+
struct volinfo {
char *v_name;
char *v_path;
int v_dbd_port;
};
+extern const vol_opt_name_t vol_opt_names[];
+extern const vol_opt_name_t vol_opt_casefold[];
+
extern int loadvolinfo(char *path, struct volinfo *vol);
+extern int savevolinfo(const struct vol *vol, const char *Cnid_srv, const char *Cnid_port);
extern int vol_load_charsets(struct volinfo *vol);
#endif
#include <atalk/util.h>
#include <atalk/logger.h>
#include <atalk/volinfo.h>
+#include <atalk/volume.h>
#ifdef CNID_DB
#include <atalk/cnid.h>
#endif /* CNID_DB*/
-#define MAC_CHARSET 0
-#define VOL_CHARSET 1
-#define ADOUBLE_VER 2
-#define CNIDBACKEND 3
-#define CNIDDBDHOST 4
-#define CNIDDBDPORT 5
-#define CNID_DBPATH 6
-#define VOLUME_OPTS 7
-#define VOLCASEFOLD 8
+/* Global: eg volume.c needs em */
-typedef struct _info_option {
- const char *name;
- int type;
-} _info_option;
-
-static const _info_option info_options[] = {
- {"MAC_CHARSET", MAC_CHARSET},
- {"VOL_CHARSET", VOL_CHARSET},
- {"ADOUBLE_VER", ADOUBLE_VER},
- {"CNIDBACKEND", CNIDBACKEND},
- {"CNIDDBDHOST", CNIDDBDHOST},
- {"CNIDDBDPORT", CNIDDBDPORT},
- {"CNID_DBPATH", CNID_DBPATH},
- {"VOLUME_OPTS", VOLUME_OPTS},
- {"VOLCASEFOLD", VOLCASEFOLD},
- {NULL, 0}
-};
-
-typedef struct _vol_opt_name {
- const u_int32_t option;
- const char *name;
-} _vol_opt_name;
-
-static const _vol_opt_name vol_opt_names[] = {
+const vol_opt_name_t vol_opt_names[] = {
{AFPVOL_A2VOL, "PRODOS"}, /* prodos volume */
{AFPVOL_CRLF, "CRLF"}, /* cr/lf translation */
{AFPVOL_NOADOUBLE, "NOADOUBLE"}, /* don't create .AppleDouble by default */
{0, NULL}
};
-static const _vol_opt_name vol_opt_casefold[] = {
+const vol_opt_name_t vol_opt_casefold[] = {
{AFPVOL_MTOUUPPER, "MTOULOWER"},
{AFPVOL_MTOULOWER, "MTOULOWER"},
{AFPVOL_UTOMUPPER, "UTOMUPPER"},
{0, NULL}
};
+typedef struct {
+ const char *name;
+ int type;
+} info_option_t;
+
+#define MAC_CHARSET 0
+#define VOL_CHARSET 1
+#define ADOUBLE_VER 2
+#define CNIDBACKEND 3
+#define CNIDDBDHOST 4
+#define CNIDDBDPORT 5
+#define CNID_DBPATH 6
+#define VOLUME_OPTS 7
+#define VOLCASEFOLD 8
+
+static const info_option_t info_options[] = {
+ {"MAC_CHARSET", MAC_CHARSET},
+ {"VOL_CHARSET", VOL_CHARSET},
+ {"ADOUBLE_VER", ADOUBLE_VER},
+ {"CNIDBACKEND", CNIDBACKEND},
+ {"CNIDDBDHOST", CNIDDBDHOST},
+ {"CNIDDBDPORT", CNIDDBDPORT},
+ {"CNID_DBPATH", CNID_DBPATH},
+ {"VOLUME_OPTS", VOLUME_OPTS},
+ {"VOLCASEFOLD", VOLCASEFOLD},
+ {NULL, 0}
+};
+
static char* find_in_path( char *path, char *subdir, size_t maxlen)
{
char *pos;
return 0;
}
-static int parse_options (char *buf, int *flags, const _vol_opt_name* options)
+static int parse_options (char *buf, int *flags, const vol_opt_name_t *options)
{
char *p, *q;
- const _vol_opt_name *op;
+ const vol_opt_name_t *op;
q = p = buf;
char *value;
size_t len;
int option=-1;
- const _info_option *p = &info_options[0];
+ const info_option_t *p = &info_options[0];
if (NULL == ( value = strchr(buf, ':')) )
return 1;
fclose(fp);
return 0;
}
+
+/*
+ * Save the volume options to a file, used by shell utilities. Writing the file
+ * everytime a volume is opened is unnecessary, but it shouldn't hurt much.
+ */
+int savevolinfo(const struct vol *vol, const char *Cnid_srv, const char *Cnid_port)
+{
+ char buf[16348];
+ char item[MAXPATHLEN];
+ int fd;
+ int ret = 0;
+ struct flock lock;
+ const vol_opt_name_t *op = &vol_opt_names[0];
+ const vol_opt_name_t *cf = &vol_opt_casefold[0];
+
+ strlcpy (item, vol->v_path, sizeof(item));
+ strlcat (item, "/.AppleDesktop/", sizeof(item));
+ strlcat (item, VOLINFOFILE, sizeof(item));
+
+ if ((fd = open( item, O_RDWR | O_CREAT , 0666)) <0 ) {
+ LOG(log_debug, logtype_afpd,"Error opening %s: %s", item, strerror(errno));
+ return (-1);
+ }
+
+ /* try to get a lock */
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+ lock.l_type = F_WRLCK;
+
+ if (fcntl(fd, F_SETLK, &lock) < 0) {
+ if (errno == EACCES || errno == EAGAIN) {
+ /* ignore, other process already writing the file */
+ return 0;
+ } else {
+ LOG(log_error, logtype_cnid, "savevoloptions: cannot get lock: %s", strerror(errno));
+ return (-1);
+ }
+ }
+
+ /* write volume options */
+ snprintf(buf, sizeof(buf), "MAC_CHARSET:%s\n", vol->v_maccodepage);
+ snprintf(item, sizeof(item), "VOL_CHARSET:%s\n", vol->v_volcodepage);
+ strlcat(buf, item, sizeof(buf));
+
+ switch (vol->v_adouble) {
+ case AD_VERSION1:
+ strlcat(buf, "ADOUBLE_VER:v1\n", sizeof(buf));
+ break;
+ case AD_VERSION2:
+ strlcat(buf, "ADOUBLE_VER:v2\n", sizeof(buf));
+ break;
+ case AD_VERSION2_OSX:
+ strlcat(buf, "ADOUBLE_VER:osx\n", sizeof(buf));
+ break;
+ case AD_VERSION1_SFM:
+ strlcat(buf, "ADOUBLE_VER:sfm\n", sizeof(buf));
+ break;
+ }
+
+ strlcat(buf, "CNIDBACKEND:", sizeof(buf));
+ strlcat(buf, vol->v_cnidscheme, sizeof(buf));
+ strlcat(buf, "\n", sizeof(buf));
+
+ strlcat(buf, "CNIDDBDHOST:", sizeof(buf));
+ strlcat(buf, Cnid_srv, sizeof(buf));
+ strlcat(buf, "\n", sizeof(buf));
+
+ strlcat(buf, "CNIDDBDPORT:", sizeof(buf));
+ strlcat(buf, Cnid_port, sizeof(buf));
+ strlcat(buf, "\n", sizeof(buf));
+
+ strcpy(item, "CNID_DBPATH:");
+ if (vol->v_dbpath)
+ strlcat(item, vol->v_dbpath, sizeof(item));
+ else
+ strlcat(item, vol->v_path, sizeof(item));
+ strlcat(item, "\n", sizeof(item));
+ strlcat(buf, item, sizeof(buf));
+
+ /* volume flags */
+ strcpy(item, "VOLUME_OPTS:");
+ for (;op->name; op++) {
+ if ( (vol->v_flags & op->option) ) {
+ strlcat(item, op->name, sizeof(item));
+ strlcat(item, " ", sizeof(item));
+ }
+ }
+ strlcat(item, "\n", sizeof(item));
+ strlcat(buf, item, sizeof(buf));
+
+ /* casefold flags */
+ strcpy(item, "VOLCASEFOLD:");
+ for (;cf->name; cf++) {
+ if ( (vol->v_casefold & cf->option) ) {
+ strlcat(item, cf->name, sizeof(item));
+ strlcat(item, " ", sizeof(item));
+ }
+ }
+ strlcat(item, "\n", sizeof(item));
+ strlcat(buf, item, sizeof(buf));
+
+ if (strlen(buf) >= sizeof(buf)-1)
+ LOG(log_debug, logtype_afpd,"Error writing .volinfo file: buffer too small, %s", buf);
+
+
+ if (write( fd, buf, strlen(buf)) < 0 || ftruncate(fd, strlen(buf)) < 0 ) {
+ LOG(log_debug, logtype_afpd,"Error writing .volinfo file: %s", strerror(errno));
+ }
+
+ lock.l_type = F_UNLCK;
+ fcntl(fd, F_SETLK, &lock);
+ close (fd);
+ return ret;
+}