X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffile.c;h=93c91c049634d8ef786afdfecd8e99880a255185;hb=b35812db1e932c31154b7da72c564dabe95fd03d;hp=c165eb93f37680a0d6c10290d955e61c01d9c2b4;hpb=fa3903158f401ef06aaa524059c64f4412c39c7e;p=netatalk.git diff --git a/etc/afpd/file.c b/etc/afpd/file.c index c165eb93..93c91c04 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -37,6 +37,7 @@ char *strchr (), *strrchr (); #include #include #include +#include #include #include "directory.h" @@ -46,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): @@ -264,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; @@ -327,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); @@ -342,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(vol, cachedfile)) != 0) { LOG(log_error, logtype_afpd, "getmetadata: fatal dircache error"); - exit(EXITERR_SYS); + return AFPERR_MISC; } } } else { @@ -385,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); } @@ -554,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 )); @@ -730,6 +735,7 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, return( AFPERR_ACCESS ); case EDQUOT: case ENOSPC : + LOG(log_info, logtype_afpd, "afp_createfile: DISK FULL"); return( AFPERR_DFULL ); default : return( AFPERR_PARAM ); @@ -769,7 +775,7 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, ad_close( adp, ADFLAGS_DF|ADFLAGS_HF ); createfile_done: - curdir->offcnt++; + curdir->d_offcnt++; #ifdef DROPKLUDGE if (vol->v_flags & AFPVOL_DROPBOX) { @@ -1366,7 +1372,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) { @@ -1546,7 +1552,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); } } @@ -1587,6 +1594,7 @@ done: case EDQUOT: case EFBIG: case ENOSPC: + LOG(log_info, logtype_afpd, "copyfile: DISK FULL"); return AFPERR_DFULL; case ENOENT: return AFPERR_NOOBJ; @@ -1850,7 +1858,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;