X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fafpd%2Fvolume.c;h=da57a30a822491746f603ba6112516b3ac325dac;hp=a8b0754dd0cd799eb7c9a8c914ee3f6fa9b381e4;hb=4d70a1cdf1cab29dde087f4224759a1a910524b4;hpb=8a1fcacef082abe5bdb60421b3129d7cd39f6b76 diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index a8b0754d..da57a30a 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -58,63 +57,6 @@ extern int afprun(int root, char *cmd, int *outfd); -typedef struct _special_folder { - const char *name; - int precreate; - mode_t mode; - int hide; -} _special_folder; - -static const _special_folder special_folders[] = { - {".AppleDesktop", 1, 0777, 0}, - {NULL, 0, 0, 0}}; - -/* Forward declarations */ -static void handle_special_folders (const struct vol *); - -static void showvol(const ucs2_t *name) -{ - struct vol *volume = getvolumes(); - - for ( ; volume; volume = volume->v_next ) { - if (volume->v_hide && !strcasecmp_w( volume->v_name, name ) ) { - volume->v_hide = 0; - return; - } - } -} - -static void closevol(struct vol *vol) -{ - if (!vol) - return; - - vol->v_flags &= ~AFPVOL_OPEN; - - of_closevol(vol); - - dir_free( vol->v_root ); - vol->v_root = NULL; - if (vol->v_cdb != NULL) { - cnid_close(vol->v_cdb); - vol->v_cdb = NULL; - } - - if (vol->v_postexec) { - afprun(0, vol->v_postexec, NULL); - } - if (vol->v_root_postexec) { - afprun(1, vol->v_root_postexec, NULL); - } - - if (vol->v_deleted) { - showvol(vol->v_name); - volume_free(vol); - volume_unlink(vol); - free(vol); - } -} - /*! * Read band-size info from Info.plist XML file of an TM sparsebundle * @@ -277,7 +219,7 @@ static int getvolspace(const AFPObj *obj, struct vol *vol, spaceflag = AFPVOL_GVSMASK & vol->v_flags; /* report up to 2GB if afp version is < 2.2 (4GB if not) */ - maxsize = (afp_version < 22) ? 0x7fffffffL : 0xffffffffL; + maxsize = (obj->afp_version < 22) ? 0x7fffffffL : 0xffffffffL; #ifdef AFS if ( spaceflag == AFPVOL_NONE || spaceflag == AFPVOL_AFSGVS ) { @@ -379,7 +321,7 @@ static int getvolparams(const AFPObj *obj, uint16_t bitmap, struct vol *vol, str * .Parent file here if it doesn't exist. */ /* Convert adouble:v2 to adouble:ea on the fly */ - (void)ad_convert(vol->v_path, st, vol); + (void)ad_convert(vol->v_path, st, vol, NULL); ad_init(&ad, vol); if (ad_open(&ad, vol->v_path, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0 ) { @@ -438,12 +380,12 @@ static int getvolparams(const AFPObj *obj, uint16_t bitmap, struct vol *vol, str ashort |= VOLPBIT_ATTR_RO; } /* prior 2.1 only VOLPBIT_ATTR_RO is defined */ - if (afp_version > 20) { + if (obj->afp_version > 20) { if (vol->v_cdb != NULL && (vol->v_cdb->flags & CNID_FLAG_PERSISTENT)) ashort |= VOLPBIT_ATTR_FILEID; ashort |= VOLPBIT_ATTR_CATSEARCH; - if (afp_version >= 30) { + if (obj->afp_version >= 30) { ashort |= VOLPBIT_ATTR_UTF8; if (vol->v_flags & AFPVOL_UNIX_PRIV) ashort |= VOLPBIT_ATTR_UNIXPRIV; @@ -451,7 +393,7 @@ static int getvolparams(const AFPObj *obj, uint16_t bitmap, struct vol *vol, str ashort |= VOLPBIT_ATTR_TM; if (vol->v_flags & AFPVOL_NONETIDS) ashort |= VOLPBIT_ATTR_NONETIDS; - if (afp_version >= 32) { + if (obj->afp_version >= 32) { if (vol->v_vfs_ea) ashort |= VOLPBIT_ATTR_EXT_ATTRS; if (vol->v_flags & AFPVOL_ACLS) @@ -601,7 +543,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf int vcnt; size_t len; - load_volumes(obj, of_closevol); + load_volumes(obj, closevol); data = rbuf + 5; for ( vcnt = 0, volume = getvolumes(); volume; volume = volume->v_next ) { @@ -621,11 +563,8 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf continue; /* no r-x access */ } } - if (volume->v_hide) { - continue; /* config file changed but the volume was mounted */ - } - if (utf8_encoding()) { + if (utf8_encoding(obj)) { len = ucs2_to_charset_allocate(CH_UTF8_MAC, &namebuf, volume->v_u8mname); } else { len = ucs2_to_charset_allocate(obj->options.maccharset, &namebuf, volume->v_macname); @@ -674,7 +613,7 @@ static int volume_codepage(AFPObj *obj, struct vol *volume) } 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); + LOG (log_warning, logtype_afpd, "WARNING: volume encoding %s is *not* supported by netatalk, expect problems!", volume->v_volcodepage); } if (!volume->v_maccodepage) @@ -702,22 +641,14 @@ static int volume_openDB(const AFPObj *obj, struct vol *volume) 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); - } - - LOG(log_info, logtype_afpd, "CNID server: %s:%s", - volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv, - volume->v_cnidport ? volume->v_cnidport : obj->options.Cnid_port); + LOG(log_debug, logtype_afpd, "CNID server: %s:%s", volume->v_cnidserver, volume->v_cnidport); volume->v_cdb = cnid_open(volume->v_path, volume->v_umask, volume->v_cnidscheme, flags, - volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv, - volume->v_cnidport ? volume->v_cnidport : obj->options.Cnid_port); + volume->v_cnidserver, + volume->v_cnidport); if ( ! volume->v_cdb && ! (flags & CNID_FLAG_MEMORY)) { /* The first attempt failed and it wasn't yet an attempt to open in-memory */ @@ -776,7 +707,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t if ((volname_tmp = strchr(volname,'+')) != NULL) volname = volname_tmp+1; - if (utf8_encoding()) { + if (utf8_encoding(obj)) { namelen = convert_string(CH_UTF8_MAC, CH_UCS2, ibuf, len, volname, sizeof(obj->oldtmp)); } else { namelen = convert_string(obj->options.maccharset, CH_UCS2, ibuf, len, volname, sizeof(obj->oldtmp)); @@ -790,7 +721,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t if ((len + 1) & 1) /* pad to an even boundary */ ibuf++; - load_volumes(obj, of_closevol); + load_volumes(obj, closevol); for ( volume = getvolumes(); volume; volume = volume->v_next ) { if ( strcasecmp_w( (ucs2_t*) volname, volume->v_name ) == 0 ) { @@ -869,7 +800,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t /* initialize volume variables * FIXME file size */ - if (utf8_encoding()) { + if (utf8_encoding(obj)) { volume->max_filename = UTF8FILELEN_EARLY; } else { @@ -879,7 +810,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t volume->v_flags |= AFPVOL_OPEN; volume->v_cdb = NULL; - if (utf8_encoding()) { + if (utf8_encoding(obj)) { len = convert_string_allocate(CH_UCS2, CH_UTF8_MAC, volume->v_u8mname, namelen, &vol_mname); } else { len = convert_string_allocate(CH_UCS2, obj->options.maccharset, volume->v_macname, namelen, &vol_mname); @@ -921,12 +852,6 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t ret = stat_vol(obj, bitmap, volume, rbuf, rbuflen); if (ret == AFP_OK) { - handle_special_folders(volume); - savevolinfo(volume, - volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv, - volume->v_cnidport ? volume->v_cnidport : obj->options.Cnid_port); - - /* * If you mount a volume twice, the second time the trash appears on * the desk-top. That's because the Mac remembers the DID for the @@ -946,6 +871,11 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t goto openvol_err; } } + + const char *msg; + if ((msg = iniparser_getstring(obj->iniconfig, volume->v_configname, "login message", NULL)) != NULL) + setmessage(msg); + return( AFP_OK ); } @@ -964,21 +894,45 @@ openvol_err: return ret; } +void closevol(const AFPObj *obj, struct vol *vol) +{ + if (!vol) + return; + + vol->v_flags &= ~AFPVOL_OPEN; + + of_closevol(obj, vol); + + dir_free( vol->v_root ); + vol->v_root = NULL; + if (vol->v_cdb != NULL) { + cnid_close(vol->v_cdb); + vol->v_cdb = NULL; + } + + if (vol->v_postexec) { + afprun(0, vol->v_postexec, NULL); + } + if (vol->v_root_postexec) { + afprun(1, vol->v_root_postexec, NULL); + } +} + /* ------------------------- */ -void close_all_vol(void) +void close_all_vol(const AFPObj *obj) { struct vol *ovol; curdir = NULL; for ( ovol = getvolumes(); ovol; ovol = ovol->v_next ) { if ( (ovol->v_flags & AFPVOL_OPEN) ) { ovol->v_flags &= ~AFPVOL_OPEN; - closevol(ovol); + closevol(obj, ovol); } } } /* ------------------------- */ -int afp_closevol(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) +int afp_closevol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { struct vol *vol; uint16_t vid; @@ -991,7 +945,8 @@ int afp_closevol(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ } (void)chdir("/"); - closevol(vol); + curdir = NULL; + closevol(obj, vol); return( AFP_OK ); } @@ -1015,7 +970,7 @@ int pollvoltime(AFPObj *obj) struct timeval tv; struct stat st; - if (!(afp_version > 21 && obj->options.flags & OPTION_SERVERNOTIF)) + if (!(obj->afp_version > 21 && obj->options.flags & OPTION_SERVERNOTIF)) return 0; if ( gettimeofday( &tv, NULL ) < 0 ) @@ -1055,7 +1010,7 @@ void setvoltime(AFPObj *obj, struct vol *vol) /* or finder doesn't update free space * AFP 3.2 and above clients seem to be ok without so many notification */ - if (afp_version < 32 && obj->options.flags & OPTION_SERVERNOTIF) { + if (obj->afp_version < 32 && obj->options.flags & OPTION_SERVERNOTIF) { obj->attention(obj->dsi, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED); } } @@ -1123,97 +1078,3 @@ int afp_setvolparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf ad_close(&ad, ADFLAGS_HF); return( AFP_OK ); } - -/* - * precreate a folder - * this is only intended for folders in the volume root - * It will *not* work if the folder name contains extended characters - */ -static int create_special_folder (const struct vol *vol, const struct _special_folder *folder) -{ - char *p,*q,*r; - struct adouble ad; - uint16_t attr; - struct stat st; - int ret; - - - p = (char *) malloc ( strlen(vol->v_path)+strlen(folder->name)+2); - if ( p == NULL) { - LOG(log_error, logtype_afpd,"malloc failed"); - exit (EXITERR_SYS); - } - - q=strdup(folder->name); - if ( q == NULL) { - LOG(log_error, logtype_afpd,"malloc failed"); - exit (EXITERR_SYS); - } - - strcpy(p, vol->v_path); - strcat(p, "/"); - - r=q; - while (*r) { - if ((vol->v_casefold & AFPVOL_MTOUUPPER)) - *r=toupper(*r); - else if ((vol->v_casefold & AFPVOL_MTOULOWER)) - *r=tolower(*r); - r++; - } - strcat(p, q); - - if ( (ret = stat( p, &st )) < 0 ) { - if (folder->precreate) { - if (ad_mkdir(p, folder->mode)) { - LOG(log_debug, logtype_afpd,"Creating '%s' failed in %s: %s", p, vol->v_path, strerror(errno)); - free(p); - free(q); - return -1; - } - ret = 0; - } - } - - if ( !ret && folder->hide) { - /* Hide it */ - ad_init(&ad, vol); - if (ad_open(&ad, p, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) { - free(p); - free(q); - return (-1); - } - - ad_setname(&ad, folder->name); - - ad_getattr(&ad, &attr); - attr |= htons( ntohs( attr ) | ATTRBIT_INVISIBLE ); - ad_setattr(&ad, attr); - - /* do the same with the finder info */ - if (ad_entry(&ad, ADEID_FINDERI)) { - memcpy(&attr, ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, sizeof(attr)); - attr |= htons(FINDERINFO_INVISIBLE); - memcpy(ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,&attr, sizeof(attr)); - } - - ad_flush(&ad); - ad_close(&ad, ADFLAGS_HF); - } - free(p); - free(q); - return 0; -} - -static void handle_special_folders (const struct vol * vol) -{ - const _special_folder *p = &special_folders[0]; - - become_root(); - - for (; p->name != NULL; p++) { - create_special_folder (vol, p); - } - - unbecome_root(); -}