From: franklahm Date: Tue, 1 Dec 2009 16:36:14 +0000 (+0000) Subject: Nicely move all volinfo file code to libatalk X-Git-Tag: branch-symlink-start~54 X-Git-Url: https://arthur.barton.de/gitweb/?p=netatalk.git;a=commitdiff_plain;h=b684c667e321c2b6bd5f949dc751ded276e11020 Nicely move all volinfo file code to libatalk --- diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index cadd14ea..44374be7 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -1,5 +1,5 @@ /* - * $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. @@ -128,9 +128,8 @@ m=u -> map both ways #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:" @@ -158,47 +157,7 @@ static const _special_folder special_folders[] = { #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); @@ -2038,7 +1997,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t if (!(volume->v_flags & AFPVOL_RO)) { handle_special_folders( volume ); - savevoloptions( volume); + savevolinfo(volume, Cnid_srv, Cnid_port); } /* @@ -2478,119 +2437,3 @@ static void handle_special_folders (const struct vol * vol) } } -/* - * 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; -} diff --git a/include/atalk/volinfo.h b/include/atalk/volinfo.h index 541f2873..5c7a5997 100644 --- a/include/atalk/volinfo.h +++ b/include/atalk/volinfo.h @@ -1,54 +1,22 @@ /* - * $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 - -/* 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 /* 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; @@ -67,7 +35,11 @@ struct volinfo { 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 diff --git a/libatalk/util/volinfo.c b/libatalk/util/volinfo.c index 167c93c9..0c56f6f4 100644 --- a/libatalk/util/volinfo.c +++ b/libatalk/util/volinfo.c @@ -39,44 +39,14 @@ #include #include #include +#include #ifdef CNID_DB #include #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 */ @@ -101,7 +71,7 @@ static const _vol_opt_name vol_opt_names[] = { {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"}, @@ -109,6 +79,34 @@ static const _vol_opt_name vol_opt_casefold[] = { {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; @@ -195,10 +193,10 @@ int vol_load_charsets( struct volinfo *vol) 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; @@ -227,7 +225,7 @@ static int parseline ( char *buf, struct volinfo *vol) 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; @@ -386,3 +384,118 @@ int loadvolinfo (char *path, struct volinfo *vol) 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; +}