X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffiledir.c;h=c5fbd10595964cef45cf91706f020fefa1ba607d;hb=4a63d5961aeae41acf4bdeb3c08e1b8512b9d97a;hp=bf3a8c0681c1fea7b5ab371ef53a923923716998;hpb=8f6bea54f2115259a524ebade0fa346be1e0c2dd;p=netatalk.git diff --git a/etc/afpd/filedir.c b/etc/afpd/filedir.c index bf3a8c06..c5fbd105 100644 --- a/etc/afpd/filedir.c +++ b/etc/afpd/filedir.c @@ -1,6 +1,4 @@ /* - * $Id: filedir.c,v 1.73 2010/03/12 15:16:49 franklahm Exp $ - * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. */ @@ -41,6 +39,7 @@ char *strchr (), *strrchr (); #include #include #include +#include #include "directory.h" #include "dircache.h" @@ -176,7 +175,7 @@ int afp_getfildirparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *r LOG(log_debug, logtype_afpd, "getfildirparams(vid:%u, did:%u, f/d:%04x/%04x) {cwdid:%u, cwd: %s, name:'%s'}", ntohs(vid), ntohl(dir->d_did), fbitmap, dbitmap, - ntohl(curdir->d_did), cfrombstring(curdir->d_fullpath), s_path->u_name); + ntohl(curdir->d_did), cfrombstr(curdir->d_fullpath), s_path->u_name); st = &s_path->st; if (!s_path->st_valid) { @@ -339,7 +338,7 @@ static int moveandrename(const struct vol *vol, struct ofork *opened = NULL; struct path path; cnid_t id; - int cwd_fd; + int cwd_fd = -1; ad_init(&ad, vol->v_adouble, vol->v_ad_options); adp = &ad; @@ -389,47 +388,58 @@ static int moveandrename(const struct vol *vol, if (sdir_fd != -1) { if ((cwd_fd = open(".", O_RDONLY)) == -1) return AFPERR_MISC; - if (fchdir(sdir_fd) != 0) - return AFPERR_MISC; + if (fchdir(sdir_fd) != 0) { + rc = AFPERR_MISC; + goto exit; + } } if (!ad_metadata(p, adflags, adp)) { u_int16_t bshort; ad_getattr(adp, &bshort); ad_close_metadata( adp); - if ((bshort & htons(ATTRBIT_NORENAME))) - return(AFPERR_OLOCK); + if ((bshort & htons(ATTRBIT_NORENAME))) { + rc = AFPERR_OLOCK; + goto exit; + } } if (sdir_fd != -1) { if (fchdir(cwd_fd) != 0) { LOG(log_error, logtype_afpd, "moveandrename: %s", strerror(errno) ); - return AFPERR_MISC; + rc = AFPERR_MISC; + goto exit; } } - if (NULL == (upath = mtoupath(vol, newname, curdir->d_did, utf8_encoding()))){ - return AFPERR_PARAM; + if (NULL == (upath = mtoupath(vol, newname, curdir->d_did, utf8_encoding()))){ + rc = AFPERR_PARAM; + goto exit; } path.u_name = upath; st = &path.st; if (0 != (rc = check_name(vol, upath))) { - return rc; + goto exit; } /* source == destination. we just silently accept this. */ if ((!isdir && curdir == sdir) || (isdir && curdir->d_did == sdir->d_pdid)) { - if (strcmp(oldname, newname) == 0) - return AFP_OK; + if (strcmp(oldname, newname) == 0) { + rc = AFP_OK; + goto exit; + } if (stat(upath, st) == 0 || caseenumerate(vol, &path, curdir) == 0) { if (!stat(p, &nst) && !(nst.st_dev == st->st_dev && nst.st_ino == st->st_ino) ) { /* not the same file */ - return AFPERR_EXIST; + rc = AFPERR_EXIST; + goto exit; } errno = 0; } - } else if (stat(upath, st ) == 0 || caseenumerate(vol, &path, curdir) == 0) - return AFPERR_EXIST; + } else if (stat(upath, st ) == 0 || caseenumerate(vol, &path, curdir) == 0) { + rc = AFPERR_EXIST; + goto exit; + } if ( !isdir ) { path.st_valid = 1; @@ -446,13 +456,30 @@ static int moveandrename(const struct vol *vol, } if ( rc == AFP_OK && id ) { /* renaming may have moved the file/dir across a filesystem */ - if (stat(upath, st) < 0) + if (stat(upath, st) < 0) { + rc = AFPERR_MISC; + goto exit; + } + + if (dir_modify(vol, + sdir, + curdir->d_did, + 0, + newname, + upath, + S_ISDIR(st->st_mode) ? curdir->d_fullpath : NULL) != 0) { + LOG(log_error, logtype_afpd, "moveandrename: dir_modify error: %s -> %s", + p, upath); return AFPERR_MISC; + } /* fix up the catalog entry */ cnid_update(vol->v_cdb, id, st, curdir->d_did, upath, strlen(upath)); } +exit: + if (cwd_fd != -1) + close(cwd_fd); return rc; } @@ -511,7 +538,7 @@ int afp_rename(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size if ( movecwd( vol, dirlookup(vol, sdir->d_pdid) ) < 0 ) { return afp_errno; } - memcpy(oldname, cfrombstring(sdir->d_m_name), blength(sdir->d_m_name) +1); + memcpy(oldname, cfrombstr(sdir->d_m_name), blength(sdir->d_m_name) +1); } /* another place where we know about the path type */ @@ -584,8 +611,8 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size rc = deletefile(vol, -1, upath, 1); struct dir *cachedfile; - if (cachedfile = dircache_search_by_name(vol, dir, upath, strlen(upath))) { - dircache_remove(vol, dir, DIRCACHE | DIDNAME_INDEX | QUEUE_INDEX); + if ((cachedfile = dircache_search_by_name(vol, dir, upath, strlen(upath)))) { + dircache_remove(vol, cachedfile, DIRCACHE | DIDNAME_INDEX | QUEUE_INDEX); dir_free(cachedfile); } } @@ -615,9 +642,9 @@ char *absupath(const struct vol *vol, struct dir *dir, char *u) if (path->slen > MAXPATHLEN) return NULL; - LOG(log_debug, logtype_afpd, "absupath: %s", cfrombstring(path)); + LOG(log_debug, logtype_afpd, "absupath: %s", cfrombstr(path)); - strncpy(pathbuf, cfrombstring(path), blength(path) + 1); + strncpy(pathbuf, cfrombstr(path), blength(path) + 1); bdestroy(path); return(pathbuf); @@ -687,7 +714,7 @@ int afp_moveandrename(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U } strcpy(oldname, path->m_name); /* an extra copy for of_rename */ } else { - memcpy(oldname, cfrombstring(sdir->d_m_name), blength(sdir->d_m_name) + 1); + memcpy(oldname, cfrombstr(sdir->d_m_name), blength(sdir->d_m_name) + 1); } #ifdef HAVE_RENAMEAT