Workaround for Network Trash and system without byte locking (broken nfs/afs) mangle OS9 "Network Trash Folder/Trash Can #2" name to "Network Trash Folder/Trash Can #2.." So multiple clients can share the same volume and have a working trash. Index: etc/afpd/directory.c =================================================================== RCS file: /cvsroot/netatalk/netatalk/etc/afpd/directory.c,v retrieving revision 1.71.2.4.2.12 diff -u -r1.71.2.4.2.12 directory.c --- etc/afpd/directory.c 11 Mar 2004 16:16:40 -0000 1.71.2.4.2.12 +++ etc/afpd/directory.c 21 Apr 2004 12:42:03 -0000 @@ -554,6 +554,7 @@ * attempt to extend the current dir. tree to include path * as a side-effect, movecwd to that point and return the new dir */ + static struct dir * extenddir( vol, dir, path ) struct vol *vol; @@ -563,7 +564,25 @@ char *save_m_name; if ( path->u_name == NULL) { - path->u_name = mtoupath(vol, path->m_name, dir->d_did, (path->m_type==3) ); +#ifdef DISABLE_LOCKING + int l = strlen(TRASH_PREFIX); + /* XXX replace mac name with unix name */ + if (vol->v_trash_id && vol->v_trash_id == dir->d_did && vol->v_ip && + !strncmp(TRASH_PREFIX , path->m_name, l ) ) + { + static char temp[MAXPATHLEN + 1]; + char *u; + + strcpy(temp, path->m_name); + u = temp +l; + strcat(temp, "."); + strcat(temp, vol->v_ip); + path->u_name = temp; + + } + else +#endif + path->u_name = mtoupath(vol, path->m_name, dir->d_did, (path->m_type==3) ); } path->dir = NULL; Index: etc/afpd/enumerate.c =================================================================== RCS file: /cvsroot/netatalk/netatalk/etc/afpd/enumerate.c,v retrieving revision 1.39.2.2.2.4 diff -u -r1.39.2.2.2.4 enumerate.c --- etc/afpd/enumerate.c 11 Mar 2004 02:01:59 -0000 1.39.2.2.2.4 +++ etc/afpd/enumerate.c 21 Apr 2004 12:42:04 -0000 @@ -54,9 +54,39 @@ if (id == 0) { return NULL; } + +#ifdef DISABLE_LOCKING + if (!path->m_name) { + int l = strlen(TRASH_PREFIX); + /* XXX */ + if (vol->v_trash_id && vol->v_trash_id == dir->d_did && vol->v_ip && + !strncmp(TRASH_PREFIX , upath, l ) ) + { + static char temp[MAXPATHLEN + 1]; + char *u; + + strcpy(temp, upath); + u = temp +l; + + while (*u >= '0' && *u <= '9') { + u++; + } + if (*u == '.') { + *u = '\0'; + } + path->m_name = temp; + } + + else if(!(path->m_name = utompath(vol, upath, id , utf8_encoding()))) { + return NULL; + } + } +#else if (!path->m_name && !(path->m_name = utompath(vol, upath, id , utf8_encoding()))) { - return NULL; + return NULL; } +#endif + name = path->m_name; if ((cdir = dirnew(name, upath)) == NULL) { LOG(log_error, logtype_afpd, "adddir: malloc: %s", strerror(errno) ); @@ -185,6 +215,32 @@ return name; } +#ifdef DISABLE_LOCKING +/* ----------------------------- */ +int check_trash(const struct vol *vol, char *name) +{ +int l = strlen(TRASH_PREFIX); +char *u; + + if (strncmp(TRASH_PREFIX , name, l)) + return 0; + /* */ + u = name +l; + while (*u >= '0' && *u <= '9') { + u++; + } + + if (u == name +l) + return 0; + + if (*u == '.' && !strcmp(vol->v_ip, u +1)) { + return 0; + } + /* hide this one */ + return 1; +} +#endif + /* ----------------------------- */ int for_each_dirent(const struct vol *vol, char *name, dir_loop fn, void *data) @@ -193,15 +249,28 @@ struct dirent *de; char *m_name; int ret; +#ifdef DISABLE_LOCKING + int mangle_trash = 0; +#endif if (NULL == ( dp = opendir( name)) ) { return -1; } + +#ifdef DISABLE_LOCKING + if (vol->v_trash_id && vol->v_trash_id == curdir->d_did && !strcmp(name, ".")) { + mangle_trash = 1; + } +#endif ret = 0; for ( de = readdir( dp ); de != NULL; de = readdir( dp )) { if (!(m_name = check_dirent(vol, de->d_name))) continue; +#ifdef DISABLE_LOCKING + if (mangle_trash && check_trash(vol, de->d_name)) + continue; +#endif ret++; if (fn && fn(de,m_name, data) < 0) { closedir(dp); Index: etc/afpd/volume.c =================================================================== RCS file: /cvsroot/netatalk/netatalk/etc/afpd/volume.c,v retrieving revision 1.51.2.7.2.28 diff -u -r1.51.2.7.2.28 volume.c --- etc/afpd/volume.c 6 Apr 2004 23:29:37 -0000 1.51.2.7.2.28 +++ etc/afpd/volume.c 21 Apr 2004 12:42:05 -0000 @@ -73,7 +73,11 @@ static struct vol *Volumes = NULL; static u_int16_t lastvid = 0; -static char *Trash = "\02\024Network Trash Folder"; + +/* type, len, name */ +static char *Trash2 = "\02\024Network Trash Folder"; +/* type, hint (4 bytes), len (2bytes), name */ +static char *Trash3 = "\03\0\0\0\0\0\024Network Trash Folder"; static struct extmap *Extmap = NULL, *Defextmap = NULL; static int Extmap_cnt; @@ -1038,6 +1042,10 @@ free(vol->v_forceuid); free(vol->v_forcegid); #endif /* FORCE_UIDGID */ + +#ifdef DISABLE_LOCKING + free(vol->v_ip); +#endif } /* ------------------------------- */ @@ -1730,9 +1738,31 @@ goto openvol_err; } } - else { - p = Trash; - cname( volume, volume->v_dir, &p ); +#ifndef DISABLE_LOCKING + else +#endif + { + struct path *s_path; + + /* use the right name format */ + p = (afp_version>= 30)?Trash3:Trash2; + s_path = cname( volume, volume->v_dir, &p ); +#ifdef DISABLE_LOCKING + if (s_path && *s_path->m_name == '\0' ) { + /* XXXX should do the same with ASP, could use volxlate but there's ':' in $p */ + if (obj->proto == AFPPROTO_DSI) { + DSI *dsi = obj->handle; + + /* cname moved into dest folder */ + volume->v_trash_id = curdir->d_did; + volume->v_ip = malloc(MAXPATHLEN +1); + if (volume->v_ip) { + sprintf(volume->v_ip, "%s.%u", inet_ntoa(dsi->client.sin_addr), + ntohs(dsi->client.sin_port)); + } + } + } +#endif } return( AFP_OK ); } Index: etc/afpd/volume.h =================================================================== RCS file: /cvsroot/netatalk/netatalk/etc/afpd/volume.h,v retrieving revision 1.19.2.5.2.6 diff -u -r1.19.2.5.2.6 volume.h --- etc/afpd/volume.h 11 Mar 2004 02:02:04 -0000 1.19.2.5.2.6 +++ etc/afpd/volume.h 21 Apr 2004 12:42:05 -0000 @@ -81,6 +81,12 @@ /* adouble indirection */ int (*validupath)(const struct vol *, const char *); char *(*ad_path)(const char *, int); + +#ifdef DISABLE_LOCKING + /* for OS 9 trash when there's no working byte locking (afs, nfs) */ + cnid_t v_trash_id; + char *v_ip; +#endif }; #ifdef NO_LARGE_VOL_SUPPORT @@ -167,6 +173,8 @@ #define VOLPBIT_BSIZE 11 /* block size */ +#define TRASH_PREFIX "Trash Can #" + #define vol_noadouble(vol) (((vol)->v_flags & AFPVOL_NOADOUBLE) ? \ ADFLAGS_NOADOUBLE : 0) #ifdef AFP3x