X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fvolume.c;h=c802f8173d7083af335fa9e5667149c87bfdb413;hb=6d36dfa12919387d2822025297deb24cb96403af;hp=2226b7185b65da5bcd7912afa0b73c91874772e9;hpb=75fe310224dffb96868d7f2cb1ec9125a84f2a08;p=netatalk.git diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 2226b718..c802f817 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -1,5 +1,5 @@ /* - * $Id: volume.c,v 1.98 2009-11-05 14:38:07 franklahm Exp $ + * $Id: volume.c,v 1.105 2009-11-24 11:40:11 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -556,8 +556,8 @@ static void volset(struct vol_option *options, struct vol_option *save, } else if (optionok(tmp, "ea:", val)) { if (strcasecmp(val + 1, "ad") == 0) /* the default anyway */ options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AD; - else if (strcasecmp(val + 1, "solaris") == 0) - options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_SOLARIS; + else if (strcasecmp(val + 1, "sys") == 0) + options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_SYS; } else { /* ignore unknown options */ @@ -623,7 +623,7 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, if (tmpvlen + suffixlen > obj->options.volnamelen) { flags = CONV_FORCE; tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, obj->options.volnamelen - suffixlen, &flags); - tmpname[tmpvlen != (size_t)-1 ? tmpvlen : 0] = 0; + tmpname[tmpvlen >= 0 ? tmpvlen : 0] = 0; } strcat(tmpname, suffix); tmpvlen = strlen(tmpname); @@ -649,7 +649,7 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, if (tmpvlen + suffixlen > AFPVOL_MACNAMELEN) { flags = CONV_FORCE; tmpvlen = convert_charset(obj->options.unixcharset, obj->options.maccharset, 0, name, vlen, tmpname, AFPVOL_MACNAMELEN - suffixlen, &flags); - tmpname[tmpvlen != (size_t)-1 ? tmpvlen : 0] = 0; + tmpname[tmpvlen >= 0 ? tmpvlen : 0] = 0; } strcat(tmpname, suffix); tmpvlen = strlen(tmpname); @@ -770,7 +770,32 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, else volume->v_adouble = AD_VERSION; + /* Mac to Unix conversion flags*/ + volume->v_mtou_flags = 0; + if (!(volume->v_flags & AFPVOL_NOHEX)) + volume->v_mtou_flags |= CONV_ESCAPEHEX; + if (!(volume->v_flags & AFPVOL_USEDOTS)) + volume->v_mtou_flags |= CONV_ESCAPEDOTS; + if ((volume->v_flags & AFPVOL_EILSEQ)) + volume->v_mtou_flags |= CONV__EILSEQ; + + if ((volume->v_casefold & AFPVOL_MTOUUPPER)) + volume->v_mtou_flags |= CONV_TOUPPER; + else if ((volume->v_casefold & AFPVOL_MTOULOWER)) + volume->v_mtou_flags |= CONV_TOLOWER; + + /* Unix to Mac conversion flags*/ + volume->v_utom_flags = CONV_IGNORE | CONV_UNESCAPEHEX; + if ((volume->v_casefold & AFPVOL_UTOMUPPER)) + volume->v_utom_flags |= CONV_TOUPPER; + else if ((volume->v_casefold & AFPVOL_UTOMLOWER)) + volume->v_utom_flags |= CONV_TOLOWER; + + if ((volume->v_flags & AFPVOL_EILSEQ)) + volume->v_utom_flags |= CONV__EILSEQ; + initvol_vfs(volume); + #ifdef FORCE_UIDGID if (options[VOLOPT_FORCEUID].c_value) { volume->v_forceuid = strdup(options[VOLOPT_FORCEUID].c_value); @@ -1443,7 +1468,7 @@ static int getvolparams( u_int16_t bitmap, struct vol *vol, struct stat *st, cha (1<v_volcodepage) + volume->v_volcodepage = strdup("UTF8"); + + if ( (charset_t) -1 == ( volume->v_volcharset = add_charset(volume->v_volcodepage)) ) { + LOG (log_error, logtype_afpd, "Setting codepage %s as volume codepage failed", volume->v_volcodepage); + return -1; + } + + if ( NULL == (charset = find_charset_functions(volume->v_volcodepage)) || charset->flags & CHARSET_ICONV ) { + LOG (log_warning, logtype_afpd, "WARNING: volume encoding %s is *not* supported by netatalk, expect problems !!!!", volume->v_volcodepage); + } + + if (!volume->v_maccodepage) + volume->v_maccodepage = strdup(obj->options.maccodepage); + + if ( (charset_t) -1 == ( volume->v_maccharset = add_charset(volume->v_maccodepage)) ) { + LOG (log_error, logtype_afpd, "Setting codepage %s as mac codepage failed", volume->v_maccodepage); + return -1; + } + + if ( NULL == ( charset = find_charset_functions(volume->v_maccodepage)) || ! (charset->flags & CHARSET_CLIENT) ) { + LOG (log_error, logtype_afpd, "Fatal error: mac charset %s not supported", volume->v_maccodepage); + return -1; + } + volume->v_kTextEncoding = htonl(charset->kTextEncoding); + return 0; +} + +/* ------------------------- */ +static int volume_openDB(struct vol *volume) +{ + int flags = 0; + + if ((volume->v_flags & AFPVOL_NODEV)) { + flags |= CNID_FLAG_NODEV; + } + + if (volume->v_cnidscheme == NULL) { + volume->v_cnidscheme = strdup(DEFAULT_CNID_SCHEME); + LOG(log_info, logtype_afpd, "Volume %s use CNID scheme %s.", volume->v_path, volume->v_cnidscheme); + } + if (volume->v_dbpath) + volume->v_cdb = cnid_open (volume->v_dbpath, volume->v_umask, volume->v_cnidscheme, flags); + else + volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, volume->v_cnidscheme, flags); + return (!volume->v_cdb)?-1:0; +} + /* ------------------------- * we are the user here */ @@ -1777,6 +1856,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t struct stat st; char *volname; char *p; + struct vol *volume; struct dir *dir; int len, ret; @@ -1786,13 +1866,14 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t char *vol_uname; char *vol_mname; char *volname_tmp; - + ibuf += 2; memcpy(&bitmap, ibuf, sizeof( bitmap )); bitmap = ntohs( bitmap ); ibuf += sizeof( bitmap ); + + *rbuflen = 0; if (( bitmap & (1<options.maccharset, CH_UCS2, ibuf, len, volname, sizeof(obj->oldtmp)); } - if ( namelen <= 0){ - *rbuflen = 0; + if ( namelen <= 0) { return AFPERR_PARAM; } @@ -1826,13 +1906,11 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t } if ( volume == NULL ) { - *rbuflen = 0; return AFPERR_PARAM; } /* check for a volume password */ if (volume->v_password && strncmp(ibuf, volume->v_password, VOLPASSLEN)) { - *rbuflen = 0; return AFPERR_ACCESS; } @@ -1844,27 +1922,10 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t return stat_vol(bitmap, volume, rbuf, rbuflen); } - /* initialize volume variables - * FIXME file size - */ - if (utf8_encoding()) { - volume->max_filename = 255; - } - else { - volume->max_filename = MACFILELEN; - } - - volume->v_dir = volume->v_root = NULL; - volume->v_hash = NULL; - - volume->v_flags |= AFPVOL_OPEN; - volume->v_cdb = NULL; - if (volume->v_root_preexec) { if ((ret = afprun(1, volume->v_root_preexec, NULL)) && volume->v_root_preexec_close) { LOG(log_error, logtype_afpd, "afp_openvol(%s): root preexec : %d", volume->v_path, ret ); - ret = AFPERR_MISC; - goto openvol_err; + return AFPERR_MISC; } } @@ -1875,21 +1936,45 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t if (volume->v_preexec) { if ((ret = afprun(0, volume->v_preexec, NULL)) && volume->v_preexec_close) { LOG(log_error, logtype_afpd, "afp_openvol(%s): preexec : %d", volume->v_path, ret ); - ret = AFPERR_MISC; - goto openvol_err; + return AFPERR_MISC; } } if ( stat( volume->v_path, &st ) < 0 ) { - ret = AFPERR_PARAM; - goto openvol_err; + return AFPERR_PARAM; } if ( chdir( volume->v_path ) < 0 ) { - ret = AFPERR_PARAM; - goto openvol_err; + return AFPERR_PARAM; + } + + if ( NULL == getcwd(path, MAXPATHLEN)) { + /* shouldn't be fatal but it will fail later */ + LOG(log_error, logtype_afpd, "afp_openvol(%s): volume pathlen too long", volume->v_path); + return AFPERR_MISC; + } + + if (volume_codepage(obj, volume) < 0) { + ret = AFPERR_MISC; + goto openvol_err; + } + + /* initialize volume variables + * FIXME file size + */ + if (utf8_encoding()) { + volume->max_filename = 255; + } + else { + volume->max_filename = MACFILELEN; } + volume->v_dir = volume->v_root = NULL; + volume->v_hash = NULL; + + volume->v_flags |= AFPVOL_OPEN; + volume->v_cdb = NULL; + if (utf8_encoding()) { len = convert_string_allocate(CH_UCS2, CH_UTF8_MAC, volume->v_u8mname, namelen, &vol_mname); } else { @@ -1900,13 +1985,6 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t goto openvol_err; } - if ( NULL == getcwd(path, MAXPATHLEN)) { - /* shouldn't be fatal but it will fail later */ - LOG(log_error, logtype_afpd, "afp_openvol(%s): volume pathlen too long", volume->v_path); - ret = AFPERR_MISC; - goto openvol_err; - } - if ((vol_uname = strrchr(path, '/')) == NULL) vol_uname = path; else if (*(vol_uname + 1) != '\0') @@ -1924,54 +2002,17 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t dir->d_color = DIRTREE_COLOR_BLACK; /* root node is black */ dir->d_m_name_ucs2 = strdup_w(volume->v_name); volume->v_dir = volume->v_root = dir; + volume->v_curdir = NULL; volume->v_hash = dirhash(); curdir = volume->v_dir; - if (volume->v_cnidscheme == NULL) { - volume->v_cnidscheme = strdup(DEFAULT_CNID_SCHEME); - LOG(log_info, logtype_afpd, "Volume %s use CNID scheme %s.", volume->v_path, volume->v_cnidscheme); - } - if (volume->v_dbpath) - volume->v_cdb = cnid_open (volume->v_dbpath, volume->v_umask, volume->v_cnidscheme, (volume->v_flags & AFPVOL_NODEV)); - else - volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, volume->v_cnidscheme, (volume->v_flags & AFPVOL_NODEV)); - if (volume->v_cdb == NULL) { + if (volume_openDB(volume) < 0) { LOG(log_error, logtype_afpd, "Fatal error: cannot open CNID or invalid CNID backend for %s: %s", volume->v_path, volume->v_cnidscheme); ret = AFPERR_MISC; goto openvol_err; } - /* Codepages */ - - if (!volume->v_volcodepage) - volume->v_volcodepage = strdup("UTF8"); - - if ( (charset_t) -1 == ( volume->v_volcharset = add_charset(volume->v_volcodepage)) ) { - LOG (log_error, logtype_afpd, "Setting codepage %s as volume codepage failed", volume->v_volcodepage); - ret = AFPERR_MISC; - goto openvol_err; - } - - if ( NULL == ( volume->v_vol = find_charset_functions(volume->v_volcodepage)) || volume->v_vol->flags & CHARSET_ICONV ) { - LOG (log_warning, logtype_afpd, "WARNING: volume encoding %s is *not* supported by netatalk, expect problems !!!!", volume->v_volcodepage); - } - - if (!volume->v_maccodepage) - volume->v_maccodepage = strdup(obj->options.maccodepage); - - if ( (charset_t) -1 == ( volume->v_maccharset = add_charset(volume->v_maccodepage)) ) { - LOG (log_error, logtype_afpd, "Setting codepage %s as mac codepage failed", volume->v_maccodepage); - ret = AFPERR_MISC; - goto openvol_err; - } - - if ( NULL == ( volume->v_mac = find_charset_functions(volume->v_maccodepage)) || ! (volume->v_mac->flags & CHARSET_CLIENT) ) { - LOG (log_error, logtype_afpd, "Fatal error: mac charset %s not supported", volume->v_maccodepage); - ret = AFPERR_MISC; - goto openvol_err; - } - ret = stat_vol(bitmap, volume, rbuf, rbuflen); if (ret == AFP_OK) { @@ -2135,11 +2176,11 @@ struct extmap *getextmap(const char *path) char *p; struct extmap *em; - if (NULL == ( p = strrchr( path, '.' )) ) { + if (!Extmap_cnt || NULL == ( p = strrchr( path, '.' )) ) { return( Defextmap ); } p++; - if (!*p || !Extmap_cnt) { + if (!*p) { return( Defextmap ); } em = bsearch(p, Extmap, Extmap_cnt, sizeof(struct extmap), ext_cmp_key);