X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=efc002bc0bfd11eb8797e8046b1aa71bda92e240;hb=18f2ef43a479721553a989931d8c60e84c5e1cac;hp=d3bf5600b36e1f68c91a15d3b1fadfe2eaa73f71;hpb=c27da5ec4487778eb8c60cd52d480a97b099cbdc;p=netatalk.git diff --git a/etc/afpd/file.c b/etc/afpd/file.c index d3bf5600..efc002bc 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -37,6 +37,8 @@ char *strchr (), *strrchr (); #include #include #include +#include +#include #include "directory.h" #include "dircache.h" @@ -45,7 +47,6 @@ char *strchr (), *strrchr (); #include "fork.h" #include "file.h" #include "filedir.h" -#include "globals.h" #include "unix.h" /* the format for the finderinfo fields (from IM: Toolbox Essentials): @@ -165,8 +166,8 @@ char *set_name(const struct vol *vol, char *data, cnid_t pid, char *name, cnid_t else { u_int16_t temp; - if (aint > 255) /* FIXME safeguard, anyway if no ascii char it's game over*/ - aint = 255; + if (aint > UTF8FILELEN_EARLY) /* FIXME safeguard, anyway if no ascii char it's game over*/ + aint = UTF8FILELEN_EARLY; utf8 = vol->v_kTextEncoding; memcpy(data, &utf8, sizeof(utf8)); @@ -263,21 +264,17 @@ restart: vol->v_path); vol->v_cdb = cnid_open(vol->v_path, vol->v_umask, "tdb", flags, NULL, NULL); if (vol->v_cdb) { - /* deactivate cnid caching/storing in AppleDouble files and set ro mode*/ vol->v_flags &= ~AFPVOL_CACHE; - vol->v_flags |= AFPVOL_RO; -#ifdef SERVERTEXT - /* kill ourself with SIGUSR2 aka msg pending */ - setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB instead." - "Check server messages for details. Switching to read-only mode."); - kill(getpid(), SIGUSR2); -#endif - goto restart; /* not try again with the temp CNID db */ + if (!(vol->v_flags & AFPVOL_TM)) { + vol->v_flags |= AFPVOL_RO; + setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB instead." + "Check server messages for details. Switching to read-only mode."); + kill(getpid(), SIGUSR2); + } + goto restart; /* now try again with the temp CNID db */ } else { -#ifdef SERVERTEXT setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB failed too!" "Check server messages for details, can't recover from this state!"); -#endif } } afp_errno = AFPERR_MISC; @@ -316,6 +313,8 @@ int getmetadata(struct vol *vol, struct stat *st; struct maccess ma; + LOG(log_debug, logtype_afpd, "getmetadata(\"%s\")", path->u_name); + upath = path->u_name; st = &path->st; data = buf; @@ -324,9 +323,10 @@ int getmetadata(struct vol *vol, || (bitmap & ( (1 << FILPBIT_LNAME) ) && utf8_encoding()) /* FIXME should be m_name utf8 filename */ || (bitmap & (1 << FILPBIT_FNUM))) { if (!path->id) { + bstring fullpath; struct dir *cachedfile; int len = strlen(upath); - if ((cachedfile = dircache_search_by_name(vol, dir, upath, len, st->st_ctime)) != NULL) + if ((cachedfile = dircache_search_by_name(vol, dir, upath, len)) != NULL) id = cachedfile->d_did; else { id = get_id(vol, adp, st, dir->d_did, upath, len); @@ -339,18 +339,26 @@ int getmetadata(struct vol *vol, if (path->m_name == NULL) { if ((path->m_name = utompath(vol, upath, id, utf8_encoding())) == NULL) { LOG(log_error, logtype_afpd, "getmetadata: utompath error"); - exit(EXITERR_SYS); + return AFPERR_MISC; } } - if ((cachedfile = dir_new(path->m_name, upath, vol, dir->d_did, id, NULL, st->st_ctime)) == NULL) { + /* Build fullpath */ + if (((fullpath = bstrcpy(dir->d_fullpath)) == NULL) + || (bconchar(fullpath, '/') != BSTR_OK) + || (bcatcstr(fullpath, upath)) != BSTR_OK) { + LOG(log_error, logtype_afpd, "getmetadata: fullpath: %s", strerror(errno)); + return AFPERR_MISC; + } + + if ((cachedfile = dir_new(path->m_name, upath, vol, dir->d_did, id, fullpath, st)) == NULL) { LOG(log_error, logtype_afpd, "getmetadata: error from dir_new"); - exit(EXITERR_SYS); + return AFPERR_MISC; } - if ((dircache_add(cachedfile)) != 0) { + if ((dircache_add(vol, cachedfile)) != 0) { LOG(log_error, logtype_afpd, "getmetadata: fatal dircache error"); - exit(EXITERR_SYS); + return AFPERR_MISC; } } } else { @@ -382,9 +390,9 @@ int getmetadata(struct vol *vol, /* FIXME do we want a visual clue if the file is read only */ struct maccess ma; - accessmode( ".", &ma, dir , NULL); + accessmode(vol, ".", &ma, dir , NULL); if ((ma.ma_user & AR_UWRITE)) { - accessmode( upath, &ma, dir , st); + accessmode(vol, upath, &ma, dir , st); if (!(ma.ma_user & AR_UWRITE)) { ashort |= htons(ATTRBIT_NOWRITE); } @@ -551,7 +559,7 @@ int getmetadata(struct vol *vol, break; case FILPBIT_UNIXPR : /* accessmode may change st_mode with ACLs */ - accessmode( upath, &ma, dir , st); + accessmode(vol, upath, &ma, dir , st); aint = htonl(st->st_uid); memcpy( data, &aint, sizeof( aint )); @@ -613,6 +621,8 @@ int getfilparams(struct vol *vol, int opened = 0; int rc; + LOG(log_debug, logtype_afpd, "getfilparams(\"%s\")", path->u_name); + opened = PARAM_NEED_ADP(bitmap); adp = NULL; @@ -746,11 +756,25 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, path = s_path->m_name; ad_setname(adp, path); + + struct stat st; + if (lstat(upath, &st) != 0) { + LOG(log_error, logtype_afpd, "afp_createfile(\"%s\"): stat: %s", + upath, strerror(errno)); + ad_close( adp, ADFLAGS_DF|ADFLAGS_HF); + return AFPERR_MISC; + } + + (void)get_id(vol, adp, &st, dir->d_did, upath, strlen(upath)); + ad_flush( adp); + + fce_register_new_file(s_path); + ad_close( adp, ADFLAGS_DF|ADFLAGS_HF ); createfile_done: - curdir->offcnt++; + curdir->d_offcnt++; #ifdef DROPKLUDGE if (vol->v_flags & AFPVOL_DROPBOX) { @@ -1097,6 +1121,9 @@ int renamefile(const struct vol *vol, int sdir_fd, char *src, char *dst, char *n { int rc; + LOG(log_debug, logtype_afpd, + "renamefile: src[%d, \"%s\"] -> dst[\"%s\"]", sdir_fd, src, dst); + if ( unix_rename( sdir_fd, src, -1, dst ) < 0 ) { switch ( errno ) { case ENOENT : @@ -1344,7 +1371,7 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si retvalue = err; goto copy_exit; } - curdir->offcnt++; + curdir->d_offcnt++; #ifdef DROPKLUDGE if (vol->v_flags & AFPVOL_DROPBOX) { @@ -1524,7 +1551,8 @@ int copyfile(const struct vol *s_vol, if (ad_reso_fileno(adp) == -1 || 0 == (err = copy_fork(ADEID_RFORK, &add, adp))){ /* copy the data fork */ if ((err = copy_fork(ADEID_DFORK, &add, adp)) == 0) { - err = d_vol->vfs->vfs_copyfile(d_vol, sfd, src, dst); + if (ad_meta_fileno(adp) != -1) + err = d_vol->vfs->vfs_copyfile(d_vol, sfd, src, dst); } } @@ -1828,7 +1856,7 @@ reenumerate_id(struct vol *vol, char *name, struct dir *dir) if (dirreenumerate(dir, &st)) { /* we already did it once and the dir haven't been modified */ - return dir->offcnt; + return dir->d_offcnt; } data.vol = vol;