- added unix name in struct dir.
- added pread/pwrite, (there was at least one bug in adf_off book keeping).
- removed (temporary?) memory mmap header, it was unused and made the code
unreadable.
- used a new struct path with unix name, mac name and file stat.
- fixed for catsearch (not well tested)
- temporary ATACC and NO_UAM_LOAD, I will remove them (ATACC is a test coverage tool).
- added AFP 3.1 calls readext,writeext, bytelockext, enumerateext2
(catsearchext, enumerateext are the same) . --afp3 parameter in
configure. configure.in changes aren't good. Maybe get CVS samba stuff
(eg for linux there's no sendfile64 on 32 bits box). The biggest change
is that we can't use the ressource fork len in the header (it's too
small). Not well tested.
- fixed few signed/unsigned missmatch, mainly when a signed fetched from the wire is checked
against and unsigned buffer size.
#undef USE_OLD_RQUOTA
#undef USE_UFS_QUOTA_H
#undef WITH_CATSEARCH
+#undef AFP3x
#undef HAVE_DECL_ERRNO
#undef HAVE_DECL_SYS_ERRLIST
#undef HAVE_DECL_SYS_NERR
-dnl $Id: configure.in,v 1.168 2002-10-04 15:11:57 srittau Exp $
+dnl $Id: configure.in,v 1.169 2002-10-11 14:18:22 didg Exp $
dnl configure.in for netatalk
AC_INIT(bin/adv1tov2/adv1tov2.c)
# Be sure to test before adding AFS libs in LIBS path as AFS lib
# has such a function that works only on AFS filesystems.
AC_CHECK_FUNCS(access)
+#
+AC_CHECK_FUNCS(pread pwrite)
dnl Checks for header files.
AC_HEADER_DIRENT
AC_TYPE_SIGNAL
AC_FUNC_UTIME_NULL
AC_FUNC_WAIT3
-AC_CHECK_FUNCS(flock getcwd gethostname gettimeofday getusershell mkdir rmdir select socket strdup strstr strtoul setpgrp strchr memcpy)
+AC_CHECK_FUNCS(flock getcwd gethostname gettimeofday getusershell mkdir rmdir select socket strdup strcasestr strstr strtoul setpgrp strchr memcpy)
AC_FUNC_SETPGRP
dnl Checks for (v)snprintf
fi
)
+afp3=no
+AC_ARG_ENABLE(afp3,
+ [ --enable-afp3 enable AFP 3.x calls],
+ if test "$enableval" = "yes"; then
+ afp3=yes
+ AC_DEFINE(AFP3x, 1)
+ AC_MSG_RESULT([enabling AFP 3.x calls])
+ fi
+)
+
+if test "$afp3" = "yes"; then
+ AC_SYS_LARGEFILE
+fi
+
dnl ----------- A NOTE ABOUT DROPKLUDGE
dnl The trouble with this fix is that if you know what the file is called, it
/*
- * $Id: afp_dsi.c,v 1.24 2002-08-30 19:32:40 didg Exp $
+ * $Id: afp_dsi.c,v 1.25 2002-10-11 14:18:23 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
* Copyright (c) 1990,1993 Regents of The University of Michigan.
it.it_interval.tv_usec = 0;
it.it_value.tv_sec = 300;
it.it_value.tv_usec = 0;
+
if ( setitimer( ITIMER_REAL, &it, 0 ) < 0 ) {
LOG(log_error, logtype_afpd, "afp_timedown: setitimer: %s", strerror(errno) );
afp_dsi_die(1);
}
-
memset(&sv, 0, sizeof(sv));
sv.sa_handler = afp_dsi_die;
sigemptyset( &sv.sa_mask );
/* if we're in the midst of processing something,
don't die. */
if ((child.flags & CHILD_RUNNING) || (child.tickle++ < child.obj->options.timeout)) {
- dsi_tickle(child.obj->handle);
+ if (!pollvoltime(child.obj))
+ dsi_tickle(child.obj->handle);
} else { /* didn't receive a tickle. close connection */
LOG(log_error, logtype_afpd, "afp_alarm: child timed out");
afp_dsi_die(1);
if (child.flags & CHILD_DIE)
dsi_tickle(dsi);
continue;
- } else if (!(child.flags & CHILD_DIE)) /* reset tickle timer */
+ } else if (!(child.flags & CHILD_DIE)) { /* reset tickle timer */
setitimer(ITIMER_REAL, &dsi->timer, NULL);
-
+ }
switch(cmd) {
case DSIFUNC_CLOSE:
afp_dsi_close(obj);
/*
- * $Id: afs.c,v 1.12 2002-10-05 14:04:47 didg Exp $
+ * $Id: afs.c,v 1.13 2002-10-11 14:18:24 didg Exp $
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*/
struct ViceIoctl vi;
struct vol *vol;
struct dir *dir;
- char *path;
+ struct path *path;
u_int32_t did;
u_int16_t vid;
*rbuflen = 0;
return( AFPERR_NOOBJ );
}
- if ( *path != '\0' ) {
+ if ( *path->m_name != '\0' ) {
*rbuflen = 0;
return( AFPERR_BITMAP );
}
struct ViceIoctl vi;
struct vol *vol;
struct dir *dir;
- char *path, *iend;
+ char *iend;
+ struct path *path;
u_int32_t did;
u_int16_t vid;
*rbuflen = 0;
return( AFPERR_NOOBJ );
}
- if ( *path != '\0' ) {
+ if ( *path->m_name != '\0' ) {
*rbuflen = 0;
return( AFPERR_BITMAP );
}
/*
- * $Id: appl.c,v 1.7 2002-10-05 14:04:47 didg Exp $
+ * $Id: appl.c,v 1.8 2002-10-11 14:18:25 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
strncpy( p, path, strlen( path ));
while ( dir->d_parent != NULL ) {
- p -= strlen( dir->d_name ) + 1;
- strcpy( p, dir->d_name );
+ p -= strlen( dir->d_m_name ) + 1;
+ strcpy( p, dir->d_m_name );
dir = dir->d_parent;
}
return( p );
int tfd, cc;
u_int32_t did;
u_int16_t vid, mplen;
- char *path, *dtf, *p, *mp;
+ struct path *path;
+ char *dtf, *p, *mp;
u_char creator[ 4 ];
u_char appltag[ 4 ];
char *mpath, *tempfile;
if (( path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- if ( *path == '\0' ) {
+ if ( *path->m_name == '\0' ) {
return( AFPERR_BADTYPE );
}
return( AFPERR_PARAM );
}
mpath = obj->newtmp;
- mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path );
+ mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path->m_name );
mplen = mpath + AFPOBJ_TMPSIZ - mp;
/* write the new appl entry at start of temporary file */
int tfd, cc;
u_int32_t did;
u_int16_t vid, mplen;
- char *path, *dtf, *mp;
+ struct path *path;
+ char *dtf, *mp;
u_char creator[ 4 ];
char *tempfile, *mpath;
if (( path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- if ( *path == '.' ) {
+ if ( *path->m_name == '\0' ) {
return( AFPERR_BADTYPE );
}
return( AFPERR_PARAM );
}
mpath = obj->newtmp;
- mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path );
+ mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path->m_name );
mplen = mpath + AFPOBJ_TMPSIZ - mp;
cc = copyapplfile( sa.sdt_fd, tfd, mp, mplen );
close( tfd );
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
- struct stat st;
struct vol *vol;
char *p, *q;
int cc, buflen;
u_char creator[ 4 ];
u_char appltag[ 4 ];
char *buf, *cbuf;
-
+ struct path *path;
+
ibuf += 2;
memcpy( &vid, ibuf, sizeof( vid ));
memcpy( q, p, len );
q = cbuf;
- if (( p = cname( vol, vol->v_dir, &q )) == NULL ) {
+ if (( path = cname( vol, vol->v_dir, &q )) == NULL ) {
*rbuflen = 0;
return( AFPERR_NOITEM );
}
- if ( stat( mtoupath(vol, p), &st ) < 0 ) {
+ if ( *path->m_name == '\0' || path->st_errno ) {
*rbuflen = 0;
return( AFPERR_NOITEM );
}
buflen = *rbuflen - sizeof( bitmap ) - sizeof( appltag );
- if ( getfilparams(vol, bitmap, p, curdir, &st, rbuf + sizeof( bitmap ) +
+ if ( getfilparams(vol, bitmap, path, curdir, rbuf + sizeof( bitmap ) +
sizeof( appltag ), &buflen ) != AFP_OK ) {
*rbuflen = 0;
return( AFPERR_BITMAP );
/*
- * $Id: auth.c,v 1.29 2002-09-26 00:02:47 didg Exp $
+ * $Id: auth.c,v 1.30 2002-10-11 14:18:25 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include "switch.h"
#include "status.h"
+#include "fork.h"
+
int afp_version = 11;
static int afp_version_index;
{ "AFPVersion 1.1", 11 },
{ "AFPVersion 2.0", 20 },
{ "AFPVersion 2.1", 21 },
- { "AFP2.2", 22 }
+ { "AFP2.2", 22 },
+#ifdef AFP3x
+ { "AFP3.0", 30 },
+ { "AFP3.1", 31 }
+#endif
};
static struct uam_mod uam_modules = {NULL, NULL, &uam_modules, &uam_modules};
uuid = pwd->pw_uid;
afp_switch = postauth_switch;
+ switch (afp_version) {
+ case 31:
+ uam_afpserver_action(AFP_ENUMERATE_EXT2, UAM_AFPSERVER_POSTAUTH, afp_enumerate_ext2, NULL);
+ case 30:
+ uam_afpserver_action(AFP_BYTELOCK_EXT, UAM_AFPSERVER_POSTAUTH, afp_bytelock_ext, NULL);
+ /* enumerate_ext and catsearch_ext are using the same packet as no ext calls */
+#ifdef WITH_CATSEARCH
+ uam_afpserver_action(AFP_CATSEARCH_EXT, UAM_AFPSERVER_POSTAUTH, afp_catsearch, NULL);
+#endif
+ uam_afpserver_action(AFP_ENUMERATE_EXT, UAM_AFPSERVER_POSTAUTH, afp_enumerate, NULL);
+ uam_afpserver_action(AFP_READ_EXT, UAM_AFPSERVER_POSTAUTH, afp_read_ext, NULL);
+ uam_afpserver_action(AFP_WRITE_EXT, UAM_AFPSERVER_POSTAUTH, afp_write_ext, NULL);
+ break;
+ }
obj->logout = logout;
#ifdef FORCE_UIDGID
}
if ( i == num ) /* An inappropo version */
return send_reply(obj, AFPERR_BADVERS );
+
+ if (afp_version >= 30 && obj->proto != AFPPROTO_DSI)
+ return send_reply(obj, AFPERR_BADVERS );
+
ibuf += len;
ibuflen -= len;
char username[MACFILELEN + 1], *start = ibuf;
struct uam_obj *uam;
struct passwd *pwd;
- int len;
+ size_t len;
+ int ret;
*rbuflen = 0;
ibuf += 2;
/* send it off to the uam. we really don't use ibuflen right now. */
ibuflen -= (ibuf - start);
- len = uam->u.uam_changepw(obj, username, pwd, ibuf, ibuflen,
+ ret = uam->u.uam_changepw(obj, username, pwd, ibuf, ibuflen,
rbuf, rbuflen);
LOG(log_info, logtype_afpd, "password change %s.",
- (len == AFPERR_AUTHCONT) ? "continued" :
- (len ? "failed" : "succeeded"));
- return len;
+ (ret == AFPERR_AUTHCONT) ? "continued" :
+ (ret ? "failed" : "succeeded"));
+ return ret;
}
#include <errno.h>
#include <syslog.h>
#include <unistd.h>
+#include <ctype.h>
#if STDC_HEADERS
#include <string.h>
*
*/
struct dsitem {
- char *lname; /* Long name */
+ char *m_name; /* Mac name */
+ char *u_name; /* unix name (== strrchr('/', path)) */
struct dir *dir; /* Structure describing this directory */
int pidx; /* Parent's dsitem structure index. */
int checked; /* Have we checked this directory ? */
- char *path; /* UNIX path to this directory */
+ char *path; /* absolute UNIX path to this directory */
};
static struct scrit c1, c2; /* search criteria */
/* Puts new item onto directory stack. */
-static int addstack(char *lname, struct dir *dir, int pidx)
+static int addstack(char *uname, char *mname, struct dir *dir, int pidx)
{
struct dsitem *ds;
+ int l;
/* check if we have some space on stack... */
if (dsidx >= dssize) {
/* Put new element. Allocate and copy lname and path. */
ds = dstack + dsidx++;
- ds->lname = strdup(lname);
+ if (!(ds->m_name = strdup(mname)))
+ return -1;
ds->dir = dir;
ds->pidx = pidx;
if (pidx >= 0) {
- ds->path = malloc(strlen(dstack[pidx].path) + strlen(ds->lname) + 2);
+ l = strlen(dstack[pidx].path);
+ if (!(ds->path = malloc(l + strlen(uname) + 2) ))
+ return -1;
strcpy(ds->path, dstack[pidx].path);
strcat(ds->path, "/");
- strcat(ds->path, ds->lname);
+ strcat(ds->path, uname);
+ ds->u_name = ds->path +l +1;
}
ds->checked = 0;
while (dsidx > 0) {
if (dstack[dsidx-1].checked) {
dsidx--;
- free(dstack[dsidx].lname);
+ free(dstack[dsidx].m_name);
free(dstack[dsidx].path);
/* Check if we need to free (or release) dir structures */
} else
save_cidx = -1;
while (dsidx > 0) {
dsidx--;
- free(dstack[dsidx].lname);
+ free(dstack[dsidx].m_name);
free(dstack[dsidx].path);
/* Check if we need to free (or release) dir structures */
}
/* Fills in dir field of dstack[cidx]. Must fill parent dirs' fields if needed... */
static int resolve_dir(struct vol *vol, int cidx)
{
- struct dir *dir, *curdir;
- struct stat statbuf;
-
+ struct dir *dir, *cdir;
+
if (dstack[cidx].dir != NULL)
return 1;
if (dstack[dstack[cidx].pidx].dir == NULL && resolve_dir(vol, dstack[cidx].pidx) == 0)
return 0;
- curdir = dstack[dstack[cidx].pidx].dir;
- dir = curdir->d_child;
+ cdir = dstack[dstack[cidx].pidx].dir;
+ dir = cdir->d_child;
while (dir) {
- if (strcmp(dir->d_name, dstack[cidx].lname) == 0)
+ if (strcmp(dir->d_m_name, dstack[cidx].m_name) == 0)
break;
- dir = (dir == curdir->d_child->d_prev) ? NULL : dir->d_next;
+ dir = (dir == cdir->d_child->d_prev) ? NULL : dir->d_next;
} /* while */
- if (!dir)
- if (stat(dstack[cidx].path, &statbuf)==-1) {
+ if (!dir) {
+ struct path path;
+
+ path.u_name = dstack[cidx].path;
+ if (of_stat(&path)==-1) {
syslog(LOG_DEBUG, "resolve_dir: stat %s: %s", dstack[cidx].path, strerror(errno));
return 0;
}
-
- if (!dir && ((dir = adddir(vol, curdir, dstack[cidx].lname, strlen(dstack[cidx].lname),
- dstack[cidx].path, strlen(dstack[cidx].path), &statbuf)) == NULL))
+ path.m_name = dstack[cidx].m_name;
+ path.u_name = dstack[cidx].u_name;
+ /* adddir works with a filename not absolute pathname */
+ if ((dir = adddir(vol, cdir, &path)) == NULL)
return 0;
+ }
dstack[cidx].dir = dir;
return 1;
} /* resolve_dir */
/* Looks up for an opened adouble structure, opens resource fork of selected file. */
-static struct adouble *adl_lkup(char *upath, struct stat *sb)
+static struct adouble *adl_lkup(struct path *path)
{
static struct adouble ad;
struct adouble *adp;
struct ofork *of;
- int isdir = S_ISDIR(sb->st_mode);
+ int isdir = S_ISDIR(path->st.st_mode);
- if (!isdir && (of = of_findname(upath, sb ))) {
+ if (!isdir && (of = of_findname(path))) {
adp = of->of_ad;
} else {
memset(&ad, 0, sizeof(ad));
adp = &ad;
}
- if ( ad_open( upath, ADFLAGS_HF | (isdir)?ADFLAGS_DIR:0, O_RDONLY, 0, adp) < 0 ) {
+ if ( ad_open( path->u_name, ADFLAGS_HF | (isdir)?ADFLAGS_DIR:0, O_RDONLY, 0, adp) < 0 ) {
return NULL;
}
return adp;
* fname - our fname (translated to UNIX)
* cidx - index in directory stack
*/
-static int crit_check(struct vol *vol, char *uname, char *fname, int cidx) {
+static int crit_check(struct vol *vol, struct path *path, int cidx) {
int r = 0;
- struct stat sbuf;
u_int16_t attr;
- struct finderinfo *finfo = NULL;
+ struct finderinfo *finfo = NULL, finderinfo;
struct adouble *adp = NULL;
time_t c_date, b_date;
- if (stat(uname, &sbuf) < 0)
- return 0;
-
- if (S_ISDIR(sbuf.st_mode)) {
+ if (S_ISDIR(path->st.st_mode)) {
r = 2;
if (!c1.dbitmap)
return r;
/* Kind of optimization:
* -- first check things we've already have - filename
* -- last check things we get from ad_open()
+ * FIXME strmcp strstr (icase)
*/
/* Check for filename */
if (c1.rbitmap & (1<<DIRPBIT_LNAME)) {
if (c1.rbitmap & (1<<CATPBIT_PARTIAL)) {
- if (strstr(fname, c1.lname) == NULL)
+ if (strcasestr(path->u_name, c1.lname) == NULL)
goto crit_check_ret;
} else
- if (strcmp(fname, c1.lname) != 0)
+ if (strcasecmp(path->u_name, c1.lname) != 0)
goto crit_check_ret;
} /* if (c1.rbitmap & ... */
/* Check for modification date FIXME: should we look at adouble structure ? */
if ((c1.rbitmap & (1<<DIRPBIT_MDATE)))
- if (sbuf.st_mtime < c1.mdate || sbuf.st_mtime > c2.mdate)
+ if (path->st.st_mtime < c1.mdate || path->st.st_mtime > c2.mdate)
goto crit_check_ret;
/* Check for creation date... */
if (c1.rbitmap & (1<<DIRPBIT_CDATE)) {
- if (adp || (adp = adl_lkup(uname, &sbuf))) {
+ if (adp || (adp = adl_lkup(path))) {
if (ad_getdate(adp, AD_DATE_CREATE, (u_int32_t*)&c_date) >= 0)
c_date = AD_DATE_TO_UNIX(c_date);
- else c_date = sbuf.st_mtime;
- } else c_date = sbuf.st_mtime;
+ else c_date = path->st.st_mtime;
+ } else c_date = path->st.st_mtime;
if (c_date < c1.cdate || c_date > c2.cdate)
goto crit_check_ret;
}
/* Check for backup date... */
if (c1.rbitmap & (1<<DIRPBIT_BDATE)) {
- if (adp || (adp == adl_lkup(uname, &sbuf))) {
+ if (adp || (adp == adl_lkup(path))) {
if (ad_getdate(adp, AD_DATE_BACKUP, (u_int32_t*)&b_date) >= 0)
b_date = AD_DATE_TO_UNIX(b_date);
- else b_date = sbuf.st_mtime;
- } else b_date = sbuf.st_mtime;
+ else b_date = path->st.st_mtime;
+ } else b_date = path->st.st_mtime;
if (b_date < c1.bdate || b_date > c2.bdate)
goto crit_check_ret;
}
/* Check attributes */
- if ((c1.rbitmap & (1<<DIRPBIT_ATTR)) && c2.attr != 0)
- if (adp || (adp = adl_lkup(uname, &sbuf))) {
+ if ((c1.rbitmap & (1<<DIRPBIT_ATTR)) && c2.attr != 0) {
+ if (adp || (adp = adl_lkup(path))) {
ad_getattr(adp, &attr);
if ((attr & c2.attr) != c1.attr)
goto crit_check_ret;
} else goto crit_check_ret;
-
+ }
/* Check file type ID */
- if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0)
- if (adp || (adp = adl_lkup(uname, &sbuf))) {
- finfo = (struct finderinfo*)ad_entry(adp, ADEID_FINDERI);
- if (finfo->f_type != c1.finfo.f_type)
- goto crit_check_ret;
- } else goto crit_check_ret;
-
- /* Check creator ID */
- if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.creator != 0)
- if (adp || (adp = adl_lkup(uname, &sbuf))) {
- finfo = (struct finderinfo*)ad_entry(adp, ADEID_FINDERI);
- if (finfo->creator != c1.finfo.creator)
- goto crit_check_ret;
- } else goto crit_check_ret;
+ if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0) {
+ if (!adp)
+ adp = adl_lkup(path);
+ finfo = get_finderinfo(path->m_name, adp, &finderinfo);
+ if (finfo->f_type != c1.finfo.f_type)
+ goto crit_check_ret;
+ }
+ /* Check creator ID */
+ if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.creator != 0) {
+ if (!finfo) {
+ if (!adp)
+ adp = adl_lkup(path);
+ finfo = get_finderinfo(path->m_name, adp, &finderinfo);
+ }
+ if (finfo->creator != c1.finfo.creator)
+ goto crit_check_ret;
+ }
+
/* Check finder info attributes */
- if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.attrs != 0)
- if (adp || (adp = adl_lkup(uname, &sbuf))) {
+ if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.attrs != 0) {
+ u_int8_t attrs = 0;
+
+ if (adp || (adp = adl_lkup(path))) {
finfo = (struct finderinfo*)ad_entry(adp, ADEID_FINDERI);
- if ((finfo->attrs & c2.finfo.attrs) != c1.finfo.attrs)
- goto crit_check_ret;
- } else goto crit_check_ret;
+ attrs = finfo->attrs;
+ }
+ else if (*path->u_name == '.') {
+ attrs = htons(FINDERINFO_INVISIBLE);
+ }
+ if ((attrs & c2.finfo.attrs) != c1.finfo.attrs)
+ goto crit_check_ret;
+ }
+
/* Check label */
- if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.label != 0)
- if (adp || (adp = adl_lkup(uname, &sbuf))) {
+ if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.label != 0) {
+ if (adp || (adp = adl_lkup(path))) {
finfo = (struct finderinfo*)ad_entry(adp, ADEID_FINDERI);
if ((finfo->label & c2.finfo.label) != c1.finfo.label)
goto crit_check_ret;
} else goto crit_check_ret;
-
+ }
/* FIXME: Attributes check ! */
/* All criteria are met. */
/* Adds an item to resultset. */
-static int rslt_add(struct vol *vol, struct stat *statbuf, char *fname, short cidx, int isdir, char **rbuf)
+static int rslt_add(struct vol *vol, char *fname, short cidx, int isdir, char **rbuf)
{
char *p = *rbuf;
int l = fname != NULL ? strlen(fname) : 0;
/* Fill offset of returned file name */
if (fname != NULL) {
*p++ = 0;
- *p++ = (int)(p - *rbuf) - 1;
+ *p = (int)(p - *rbuf) - 1;
+ p++;
p[0] = l;
strcpy(p+1, fname);
p += l + 1;
static int catsearch(struct vol *vol, struct dir *dir,
int rmatches, int *pos, char *rbuf, u_int32_t *nrecs, int *rsize)
{
- int cidx, r, i;
+ int cidx, r;
char *fname = NULL;
struct dirent *entry;
- struct stat statbuf;
int result = AFP_OK;
int ccr;
+ struct path path;
char *orig_dir = NULL;
int orig_dir_len = 128;
- char *path = vol->v_path;
+ char *vpath = vol->v_path;
char *rrbuf = rbuf;
-
+
if (*pos != 0 && *pos != cur_pos)
return AFPERR_CATCHNG;
if (dirpos != NULL) {
closedir(dirpos);
dirpos = NULL;
- } /* if (dirpos != NULL) */
+ }
- if (addstack("", dir, -1) == -1) {
+ if (addstack("","", dir, -1) == -1) {
result = AFPERR_MISC;
goto catsearch_end;
}
- dstack[0].path = strdup(path);
+ dstack[0].path = strdup(vpath);
/* FIXME: Sometimes DID is given by klient ! (correct this one above !) */
}
chdir(dstack[cidx].path);
while ((entry=readdir(dirpos)) != NULL) {
(*pos)++;
- if (veto_file(VETO_STR, entry->d_name))
- continue;
- if (stat(entry->d_name, &statbuf) != 0) {
+
+ if (!(fname = path.m_name = check_dirent(vol, entry->d_name)))
+ continue;
+
+ path.u_name = entry->d_name;
+ if (of_stat(&path) != 0) {
switch (errno) {
case EACCES:
case ELOOP:
result = AFPERR_MISC;
goto catsearch_end;
} /* switch (errno) */
- } /* if (stat(entry->d_name, &statbuf) != 0) */
- fname = utompath(vol, entry->d_name);
+ } /* if (stat(entry->d_name, &path.st) != 0) */
+#if 0
for (i = 0; fname[i] != 0; i++)
fname[i] = tolower(fname[i]);
- if (strlen(fname) > MACFILELEN)
- continue;
- ccr = crit_check(vol, entry->d_name, fname, cidx);
+#endif
+ ccr = crit_check(vol, &path, cidx);
+ /* bit 1 means that we have to descend into this directory. */
+ if ((ccr & 2) && S_ISDIR(path.st.st_mode)) {
+ if (addstack(entry->d_name, fname, NULL, cidx) == -1) {
+ result = AFPERR_MISC;
+ goto catsearch_end;
+ }
+ }
+
/* bit 0 means that criteria has ben met */
- if (ccr & 1) {
- r = rslt_add(vol, &statbuf,
+ if ((ccr & 1)) {
+ r = rslt_add(vol,
(c1.fbitmap&(1<<FILPBIT_LNAME))|(c1.dbitmap&(1<<DIRPBIT_LNAME)) ?
- utompath(vol, entry->d_name) : NULL,
+ fname : NULL,
(c1.fbitmap&(1<<FILPBIT_PDID))|(c1.dbitmap&(1<<DIRPBIT_PDID)) ?
cidx : -1,
- S_ISDIR(statbuf.st_mode), &rrbuf);
+ S_ISDIR(path.st.st_mode), &rrbuf);
if (r == 0) {
result = AFPERR_MISC;
goto catsearch_end;
/* Block size limit */
if (rrbuf - rbuf >= 448)
goto catsearch_pause;
-
}
- /* bit 1 means that we have to descend into this directory. */
- if (ccr & 2) {
- if (S_ISDIR(statbuf.st_mode))
- if (addstack(entry->d_name, NULL, cidx) == -1) {
- result = AFPERR_MISC;
- goto catsearch_end;
- } /* if (addstack... */
- }
} /* while ((entry=readdir(dirpos)) != NULL) */
- closedir(dirpos);dirpos = NULL;
+ closedir(dirpos);
+ dirpos = NULL;
dstack[cidx].checked = 1;
} /* while (current_idx = reducestack()) != -1) */
u_int32_t rmatches, reserved;
u_int32_t catpos[4];
u_int32_t pdid = 0;
- char *lname = NULL;
- struct dir *dir;
- int ret, rsize, i = 0;
+ int ret, rsize;
u_int32_t nrecs = 0;
- static int nrr = 1;
- char *spec1, *spec2, *bspec1, *bspec2;
+ unsigned char *spec1, *spec2, *bspec1, *bspec2;
memset(&c1, 0, sizeof(c1));
memset(&c2, 0, sizeof(c2));
ibuf += sizeof(vid);
*rbuflen = 0;
- if ((vol = getvolbyvid(vid)) == NULL)
+ if ((vol = getvolbyvid(vid)) == NULL) {
return AFPERR_PARAM;
-
+ }
+
memcpy(&rmatches, ibuf, sizeof(rmatches));
rmatches = ntohl(rmatches);
ibuf += sizeof(rmatches);
ibuf += sizeof(c1.rbitmap);
if (! (c1.fbitmap || c1.dbitmap)) {
- *rbuflen = 0;
return AFPERR_BITMAP;
}
/* ressource fork length */
}
else {
- /* error */
+ return AFPERR_BITMAP; /* error */
}
} /* Offspring count/ressource fork length */
/* Get the long filename */
memcpy(c1.lname, bspec1 + spec1[1] + 1, (bspec1 + spec1[1])[0]);
c1.lname[(bspec1 + spec1[1])[0]]= 0;
+#if 0
for (i = 0; c1.lname[i] != 0; i++)
c1.lname[i] = tolower(c1.lname[i]);
+#endif
/* FIXME: do we need it ? It's always null ! */
memcpy(c2.lname, bspec2 + spec2[1] + 1, (bspec2 + spec2[1])[0]);
c2.lname[(bspec2 + spec2[1])[0]]= 0;
+#if 0
for (i = 0; c2.lname[i] != 0; i++)
c2.lname[i] = tolower(c2.lname[i]);
+#endif
}
ret = catsearch(vol, vol->v_dir, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize);
memcpy(rbuf, catpos, sizeof(catpos));
rbuf += sizeof(catpos);
+
c1.fbitmap = htons(c1.fbitmap);
memcpy(rbuf, &c1.fbitmap, sizeof(c1.fbitmap));
rbuf += sizeof(c1.fbitmap);
+
c1.dbitmap = htons(c1.dbitmap);
memcpy(rbuf, &c1.dbitmap, sizeof(c1.dbitmap));
rbuf += sizeof(c1.dbitmap);
+
nrecs = htonl(nrecs);
memcpy(rbuf, &nrecs, sizeof(nrecs));
rbuf += sizeof(nrecs);
/*
- * $Id: desktop.c,v 1.18 2002-10-05 14:04:47 didg Exp $
+ * $Id: desktop.c,v 1.19 2002-10-11 14:18:26 didg Exp $
*
* See COPYRIGHT.
+ *
+ * bug:
+ * afp_XXXcomment are (the only) functions able to open
+ * a ressource fork when there's no data fork, eg after
+ * it was removed with samba.
*/
#ifdef HAVE_CONFIG_H
{
static char path[ MAXPATHLEN + 1];
char *p;
- int i;
+ unsigned int i;
strcpy( path, vol->v_path );
strcat( path, "/.AppleDesktop/" );
return( path );
}
+/*
+ * mpath is only a filename
+*/
char *mtoupath(const struct vol *vol, char *mpath)
{
static char upath[ MAXPATHLEN + 1];
char *m, *u;
int i = 0;
-
+ int changed = 0;
+
if ( *mpath == '\0' ) {
return( "." );
}
#ifdef FILE_MANGLING
- mpath = demangle(vol, mpath);
+ m = demangle(vol, mpath);
+ if (m != mpath) {
+ changed = 1;
+ mpath = m;
+ }
#endif /* FILE_MANGLING */
m = mpath;
if (vol->v_mtoupage && ((*m & 0x80) ||
vol->v_flags & AFPVOL_MAPASCII)) {
*u = vol->v_mtoupage->map[(unsigned char) *m].value;
+ changed = 1;
if (!*u && *m) {
/* if conversion failed, encode in hex
* to prevent silly truncation
*u++ = ':';
*u++ = hexdig[ ( *m & 0xf0 ) >> 4 ];
*u = hexdig[ *m & 0x0f ];
+ changed = 1;
} else
*u = *m;
u++;
LOG(log_debug, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath);
#endif /* DEBUG */
- return( upath );
+ return( (changed)?upath:mpath );
}
#define hextoint( c ) ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
struct vol *vol;
struct dir *dir;
struct ofork *of;
- char *path, *name, *upath;
+ struct path *path;
+ char *name, *upath;
int clen;
u_int32_t did;
u_int16_t vid;
clen = (u_char)*ibuf++;
clen = min( clen, 199 );
- upath = mtoupath( vol, path );
- if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
+
+ upath = path->u_name;
+ if (check_access(upath, OPENACC_WR ) < 0) {
+ return AFPERR_ACCESS;
+ }
+
+ if (*path->m_name == '\0' || !(of = of_findname(path))) {
memset(&ad, 0, sizeof(ad));
adp = &ad;
} else
adp = of->of_ad;
+
if (ad_open( upath , vol_noadouble(vol) |
- (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
+ (( *path->m_name == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
O_RDWR|O_CREAT, 0666, adp) < 0 ) {
return( AFPERR_ACCESS );
}
- if ( ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT ) {
- if ( *path == '\0' ) {
- name = curdir->d_name;
+ if ( (ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT) ) {
+ if ( *path->m_name == '\0' ) {
+ name = curdir->d_m_name;
} else {
- name = path;
+ name = path->m_name;
}
ad_setentrylen( adp, ADEID_NAME, strlen( name ));
memcpy( ad_entry( adp, ADEID_NAME ), name,
struct vol *vol;
struct dir *dir;
struct ofork *of;
+ struct path *s_path;
char *path, *upath;
u_int32_t did;
u_int16_t vid;
return( AFPERR_NOOBJ );
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
+ upath = s_path->u_name;
+ path = s_path->m_name;
- upath = mtoupath( vol, path );
- if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
+ if (*path == '\0' || !(of = of_findname(s_path))) {
memset(&ad, 0, sizeof(ad));
adp = &ad;
} else
ad_getentrylen( adp, ADEID_COMMENT ));
*rbuflen = ad_getentrylen( adp, ADEID_COMMENT ) + 1;
ad_close( adp, ADFLAGS_HF );
+
+ /* return AFPERR_NOITEM if len == 0 ? */
return( AFP_OK );
}
struct vol *vol;
struct dir *dir;
struct ofork *of;
+ struct path *s_path;
char *path, *upath;
u_int32_t did;
u_int16_t vid;
return( AFPERR_NOOBJ );
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- upath = mtoupath( vol, path );
- if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
+ upath = s_path->u_name;
+ path = s_path->m_name;
+ if (check_access(upath, OPENACC_WR ) < 0) {
+ return AFPERR_ACCESS;
+ }
+
+ if (path == '\0' || !(of = of_findname(s_path))) {
memset(&ad, 0, sizeof(ad));
adp = &ad;
} else
/*
- * $Id: directory.c,v 1.41 2002-10-05 14:04:47 didg Exp $
+ * $Id: directory.c,v 1.42 2002-10-11 14:18:27 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#define SENTINEL (&sentinel)
static struct dir sentinel = { SENTINEL, SENTINEL, NULL, DIRTREE_COLOR_BLACK,
- NULL, NULL, NULL, NULL, NULL, 0, 0, NULL };
-static struct dir rootpar = { SENTINEL, SENTINEL, NULL, 0,
- NULL, NULL, NULL, NULL, NULL, 0, 0, NULL };
+ NULL, NULL, NULL, NULL, NULL, 0, 0,
+ 0, 0, NULL, NULL};
+static struct dir rootpar = { SENTINEL, SENTINEL, NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, 0, 0,
+ 0, 0, NULL, NULL};
/* (from IM: Toolbox Essentials)
* dirFinderInfo (DInfo) fields:
dir = vol->v_root;
while ( dir != SENTINEL ) {
if (dir->d_did == did)
- return dir->d_name ? dir : NULL;
+ return dir->d_m_name ? dir : NULL;
dir = (dir->d_did > did) ? dir->d_left : dir->d_right;
}
return NULL;
/* i'm not sure if it really helps to delete stuff. */
#ifndef REMOVE_NODES
- free(dir->d_name);
- dir->d_name = NULL;
+ if (dir->d_u_name != dir->d_m_name) {
+ free(dir->d_u_name);
+ }
+ free(dir->d_m_name);
+ dir->d_m_name = NULL;
+ dir->d_u_name = NULL;
#else /* ! REMOVE_NODES */
/* go searching for a node with at most one child */
}
/* set the node's d_name */
- node->d_name = save.d_name;
+ node->d_m_name = save.d_m_name;
+ node->d_u_name = save.d_u_name;
}
if (node->d_color == DIRTREE_COLOR_BLACK)
dir_rmrecolor(vol, leaf);
- free(node->d_name);
+
+ if (node->d_u_name != node->d_m_name) {
+ free(node->d_u_name);
+ }
+ free(node->d_m_name);
free(node);
#endif /* ! REMOVE_NODES */
}
* 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;
+struct vol *vol;
struct dir *dir;
-char *path;
+struct path *path;
{
char *p;
- struct stat st;
- p = mtoupath(vol, path );
- if ( stat( p, &st ) != 0 ) {
+ path->u_name = p = mtoupath(vol, path->m_name );
+ if ( of_stat( path ) != 0 ) {
return( NULL );
}
- if (!S_ISDIR(st.st_mode)) {
+
+ if (!S_ISDIR(path->st.st_mode)) {
return( NULL );
}
- if (( dir = adddir( vol, dir, path, strlen( path ), p, strlen(p),
- &st)) == NULL ) {
+ if (( dir = adddir( vol, dir, path)) == NULL ) {
return( NULL );
}
DIR *dp;
struct dirent *de;
struct stat st;
- int len, err;
+ size_t len;
+ int err;
if ((len = strlen(dir)) > sizeof(path))
return AFPERR_PARAM;
struct dirent *de;
struct stat st;
struct utimbuf ut;
- int slen, dlen, err;
+ size_t slen, dlen;
+ int err;
/* doesn't exist or the path is too long. */
if (((slen = strlen(src)) > sizeof(spath) - 2) ||
}
if (dir != SENTINEL) {
- free( dir->d_name );
+ if (dir->d_u_name != dir->d_m_name) {
+ free(dir->d_u_name);
+ }
+ free(dir->d_m_name);
free( dir );
}
}
-
-struct dir *dirnew(const int len)
+/* --------------------------------------------
+ * most of the time mac name and unix name are the same
+*/
+struct dir *dirnew(const char *m_name, const char *u_name)
{
struct dir *dir;
if (!dir)
return NULL;
- if ((dir->d_name = (char *) malloc(sizeof(char)*len)) == NULL) {
+ if ((dir->d_m_name = strdup(m_name)) == NULL) {
+ free(dir);
+ return NULL;
+ }
+
+ if (m_name == u_name) {
+ dir->d_u_name = dir->d_m_name;
+ }
+ else if ((dir->d_u_name = strdup(u_name)) == NULL) {
+ free(dir->d_m_name);
free(dir);
return NULL;
}
return dir;
}
-
-/* XXX: this needs to be changed to handle path types */
-char *
+/* -------------------------------------------------- */
+/* XXX: this needs to be changed to handle path types
+ return
+ if it's a filename:
+ in extenddir:
+ compute unix name
+ stat the file
+ return mac name
+ if it's a dirname:
+ not in the cache
+ in extenddir
+ compute unix name
+ stat the dir
+ in the cache
+
+ u_name can be
+ XXXX u_name can be an alias on m_name if the m_name is
+ a valid unix name.
+
+*/
+struct path *
cname( vol, dir, cpath )
const struct vol *vol;
struct dir *dir;
char **cpath;
{
- struct dir *cdir;
- static char path[ MAXPATHLEN + 1];
+ struct dir *cdir;
+ static char path[ MAXPATHLEN + 1];
+ static struct path ret;
+
char *data, *p;
char *u;
int extend = 0;
*cpath += len + 2;
*path = '\0';
u = NULL;
-
+ ret.m_name = path;
+ ret.st_errno = 0;
+ ret.st_valid = 0;
for ( ;; ) {
if ( len == 0 ) {
if ( !extend && movecwd( vol, dir ) < 0 ) {
strncpy(path, u, olen);
path[olen] = '\0';
}
- return( path );
+ if (!ret.st_valid || *path == '\0') {
+ ret.u_name = ".";
+ }
+ return &ret;
}
if ( *data == '\0' ) {
while ( *data == '\0' && len > 0 ) {
if ( dir->d_parent == NULL ) {
- return( NULL );
+ return NULL;
}
dir = dir->d_parent;
data++;
if (len == 1)
len--;
-#ifdef notdef
- /*
- * Dung Nguyen <ntd@adb.fr>
- *
- * AFPD cannot handle paths with "::" if the "::" notation is
- * not at the beginning of the path. The following path will not
- * be interpreted correctly:
- *
- * :a:b:::c: (directory c at the same level as directory a) */
- if ( len > 0 ) {
- data++;
- len--;
- }
-#endif /* notdef */
*p = '\0';
if ( p != path ) { /* we got something */
if ( !extend ) {
cdir = dir->d_child;
while (cdir) {
- if ( strcasecmp( cdir->d_name, path ) == 0 ) {
+ if ( strcasecmp( cdir->d_m_name, path ) == 0 ) {
break;
}
cdir = (cdir == dir->d_child->d_prev) ? NULL :
++extend;
/* if dir == curdir it always succeed,
even if curdir is deleted.
- it's not a pb because it will failed in extenddir
+ it's not a pb because it will fail in extenddir
*/
if ( movecwd( vol, dir ) < 0 ) {
/* dir is not valid anymore
we delete dir from the cache and abort.
*/
dir_invalidate(vol, dir);
- return( NULL );
+ return NULL;
}
- cdir = extenddir( vol, dir, path );
+ cdir = extenddir( vol, dir, &ret );
}
} else {
- cdir = extenddir( vol, dir, path );
+ cdir = extenddir( vol, dir, &ret );
}
if ( cdir == NULL ) {
if ( len > 0 ) {
- return( NULL );
+ return NULL;
}
} else {
*p = '.';
for ( d = dir; d->d_parent != NULL && d != curdir; d = d->d_parent ) {
*--p = '/';
- u = mtoupath(vol, d->d_name );
+ u = d->d_u_name;
n = strlen( u );
p -= n;
strncpy( p, u, n );
return( 0 );
}
+/*
+ * We can't use unix file's perm to support Apple's inherited protection modes.
+ * If we aren't the file's owner we can't change its perms when moving it and smb
+ * nfs,... don't even try.
+*/
+#define AFP_CHECK_ACCESS
+
+int check_access(char *path, int mode)
+{
+#ifdef AFP_CHECK_ACCESS
+struct maccess ma;
+char *p;
+
+ p = ad_dir(path);
+ if (!p)
+ return -1;
+
+ accessmode(p, &ma, curdir, NULL);
+ if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
+ return -1;
+ if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
+ return -1;
+#endif
+ return 0;
+}
+
+/* ------------------------------
+ (".", curdir)
+ (name, dir) with curdir:name == dir, from afp_enumerate
+*/
int getdirparams(const struct vol *vol,
- u_int16_t bitmap,
- char *upath, struct dir *dir, struct stat *st,
+ u_int16_t bitmap, struct path *s_path,
+ struct dir *dir,
char *buf, int *buflen )
{
struct maccess ma;
struct adouble ad;
char *data, *nameoff = NULL;
- DIR *dp;
- struct dirent *de;
- int bit = 0, isad = 1;
+ int bit = 0, isad = 0;
u_int32_t aint;
u_int16_t ashort;
-
- memset(&ad, 0, sizeof(ad));
-
- if ( ad_open( upath, ADFLAGS_HF|ADFLAGS_DIR, O_RDONLY,
- DIRBITS | 0777, &ad) < 0 ) {
- isad = 0;
+ int ret;
+ struct stat *st = &s_path->st;
+ char *upath = s_path->u_name;
+
+ if ((bitmap & ((1 << DIRPBIT_ATTR) |
+ (1 << DIRPBIT_CDATE) |
+ (1 << DIRPBIT_MDATE) |
+ (1 << DIRPBIT_BDATE) |
+ (1 << DIRPBIT_FINFO)))) {
+ memset(&ad, 0, sizeof(ad));
+ if ( !ad_open( upath, ADFLAGS_HF|ADFLAGS_DIR, O_RDONLY,
+ DIRBITS | 0777, &ad)) {
+ isad = 1;
+ }
}
data = buf;
break;
case DIRPBIT_LNAME :
- if (dir->d_name) /* root of parent can have a null name */
+ if (dir->d_m_name) /* root of parent can have a null name */
nameoff = data;
else
memset(data, 0, sizeof(u_int16_t));
case DIRPBIT_OFFCNT :
ashort = 0;
/* this needs to handle current directory access rights */
- if ((dp = opendir( upath ))) {
- while (( de = readdir( dp )) != NULL ) {
- if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, "."))
- continue;
-
- if (!validupath(vol, de->d_name))
- continue;
-
- /* check for vetoed filenames */
- if (veto_file(vol->v_veto, de->d_name))
- continue;
-
- /* now check against too long a filename */
- if (strlen(utompath(vol, de->d_name)) > MACFILELEN)
- continue;
-
- ashort++;
- }
- closedir( dp );
+ if (st->st_ctime == dir->ctime) {
+ ashort = dir->offcnt;
+ }
+ else if ((ret = for_each_dirent(vol, upath, NULL,NULL)) >= 0) {
+ ashort = ret;
+ dir->offcnt = ashort;
+ dir->ctime = st->st_ctime;
}
ashort = htons( ashort );
memcpy( data, &ashort, sizeof( ashort ));
ashort = htons( data - buf );
memcpy( nameoff, &ashort, sizeof( ashort ));
- if ((aint = strlen( dir->d_name )) > MACFILELEN)
+ if ((aint = strlen( dir->d_m_name )) > MACFILELEN)
aint = MACFILELEN;
*data++ = aint;
- memcpy( data, dir->d_name, aint );
+ memcpy( data, dir->d_m_name, aint );
data += aint;
}
if ( isad ) {
return( AFP_OK );
}
+/* ----------------------------- */
int afp_setdirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
{
struct vol *vol;
struct dir *dir;
- char *path;
+ struct path *path;
u_int16_t vid, bitmap;
u_int32_t did;
int rc;
return( AFPERR_NOOBJ );
}
- if ( *path != '\0' ) {
+ if ( *path->m_name != '\0' ) {
return( AFPERR_BADTYPE ); /* not a directory */
}
*
* assume path == '\0' eg. it's a directory in canonical form
*/
+
+struct path Cur_Path = {
+ "", /* mac name */
+ ".", /* unix name */
+ 0, /* stat is not set */
+ 0, /* */
+};
+
int setdirparams(const struct vol *vol,
- char *path, u_int16_t bitmap, char *buf )
+ struct path *path, u_int16_t bitmap, char *buf )
{
struct maccess ma;
struct adouble ad;
int change_parent_mdate = 0;
int newdate = 0;
- upath = mtoupath(vol, path);
+ upath = path->u_name;
memset(&ad, 0, sizeof(ad));
if (ad_open( upath, vol_noadouble(vol)|ADFLAGS_HF|ADFLAGS_DIR,
* to set our name, etc.
*/
if ( ad_getoflags( &ad, ADFLAGS_HF ) & O_CREAT ) {
- ad_setentrylen( &ad, ADEID_NAME, strlen( curdir->d_name ));
- memcpy( ad_entry( &ad, ADEID_NAME ), curdir->d_name,
+ ad_setentrylen( &ad, ADEID_NAME, strlen( curdir->d_m_name ));
+ memcpy( ad_entry( &ad, ADEID_NAME ), curdir->d_m_name,
ad_getentrylen( &ad, ADEID_NAME ));
}
}
if (!movecwd(vol, curdir->d_parent)) {
newdate = AD_DATE_FROM_UNIX(tv.tv_sec);
bitmap = 1<<DIRPBIT_MDATE;
- setdirparams(vol, "", bitmap, (char *)&newdate);
+ setdirparams(vol, &Cur_Path, bitmap, (char *)&newdate);
/* should we reset curdir ?*/
}
}
int ibuflen, *rbuflen;
{
struct adouble ad;
- struct stat st;
struct vol *vol;
struct dir *dir;
- char *path, *upath;
+ char *upath;
+ struct path *s_path;
u_int32_t did;
u_int16_t vid;
return( AFPERR_NOOBJ );
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
switch( errno ) {
case EACCES:
return( AFPERR_ACCESS );
- case EEXIST: /* FIXME this on is impossible? */
+ case EEXIST: /* FIXME this one is impossible? */
return( AFPERR_EXIST );
default:
return( AFPERR_NOOBJ );
}
}
/* FIXME check done elswhere? cname was able to move curdir to it! */
- if (*path == '\0')
- return AFPERR_EXIST;
- upath = mtoupath(vol, path);
+ if (*s_path->m_name == '\0')
+ return AFPERR_EXIST;
+
+ upath = s_path->u_name;
{
int ret;
if (0 != (ret = check_name(vol, upath))) {
}
}
- if (stat(upath, &st) < 0) {
+ if (of_stat(s_path) < 0) {
return AFPERR_MISC;
}
-
- if ((dir = adddir( vol, curdir, path, strlen( path ), upath,
- strlen(upath), &st)) == NULL) {
+ if ((dir = adddir( vol, curdir, s_path)) == NULL) {
return AFPERR_MISC;
}
return( AFPERR_ACCESS );
}
- ad_setentrylen( &ad, ADEID_NAME, strlen( path ));
- memcpy( ad_entry( &ad, ADEID_NAME ), path,
+ ad_setentrylen( &ad, ADEID_NAME, strlen( s_path->m_name ));
+ memcpy( ad_entry( &ad, ADEID_NAME ), s_path->m_name,
ad_getentrylen( &ad, ADEID_NAME ));
ad_flush( &ad, ADFLAGS_HF );
ad_close( &ad, ADFLAGS_HF );
return( AFP_OK );
}
-
+/*
+ * dst new unix filename (not a pathname)
+ * newname new mac name
+ * newparent curdir
+ *
+*/
int renamedir(src, dst, dir, newparent, newname, noadouble)
char *src, *dst, *newname;
struct dir *dir, *newparent;
struct dir *parent;
char *buf;
int len, err;
-
+
/* existence check moved to afp_moveandrename */
if ( rename( src, dst ) < 0 ) {
switch ( errno ) {
ad_close( &ad, ADFLAGS_HF );
renamedir_done:
- if ((buf = (char *) realloc( dir->d_name, len + 1 )) == NULL ) {
- LOG(log_error, logtype_afpd, "renamedir: realloc: %s", strerror(errno) );
+ if (dir->d_m_name == dir->d_u_name)
+ dir->d_u_name = NULL;
+
+ if ((buf = (char *) realloc( dir->d_m_name, len + 1 )) == NULL ) {
+ LOG(log_error, logtype_afpd, "renamedir: realloc mac name: %s", strerror(errno) );
+ /* FIXME : fatal ? */
return AFPERR_MISC;
}
- dir->d_name = buf;
- strcpy( dir->d_name, newname );
+ dir->d_m_name = buf;
+ strcpy( dir->d_m_name, newname );
+
+ if (newname == dst) {
+ free(dir->d_u_name);
+ dir->d_u_name = dir->d_m_name;
+ }
+ else {
+ if ((buf = (char *) realloc( dir->d_u_name, strlen(dst) + 1 )) == NULL ) {
+ LOG(log_error, logtype_afpd, "renamedir: realloc unix name: %s", strerror(errno) );
+ return AFPERR_MISC;
+ }
+ dir->d_u_name = buf;
+ strcpy( dir->d_u_name, dst );
+ }
if (( parent = dir->d_parent ) == NULL ) {
return( AFP_OK );
return( AFPERR_NOOBJ );
}
- if ( rmdir(mtoupath(vol, fdir->d_name)) < 0 ) {
+ if ( rmdir(fdir->d_u_name) < 0 ) {
switch ( errno ) {
case ENOENT :
return( AFPERR_NOOBJ );
return( AFP_OK );
}
-/* variable DID support */
+/* ------------------------------------
+ variable DID support
+*/
int afp_closedir(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
return AFP_OK;
}
-/* did creation gets done automatically */
+/* did creation gets done automatically
+ * there's a pb again with case but move it to cname
+*/
int afp_opendir(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
struct vol *vol;
- struct dir *dir, *parentdir;
- struct stat st;
- char *path, *upath;
+ struct dir *parentdir;
+ struct path *path;
u_int32_t did;
u_int16_t vid;
}
}
- /* see if we already have the directory. */
- upath = mtoupath(vol, path);
- if ( stat( upath, &st ) < 0 ) {
- return( AFPERR_NOOBJ );
+ if ( *path->m_name != '\0' ) {
+ return( AFPERR_BADTYPE ); /* not a directory */
}
- dir = parentdir->d_child;
- while (dir) {
- if (strdiacasecmp(dir->d_name, path) == 0) {
- memcpy(rbuf, &dir->d_did, sizeof(dir->d_did));
- *rbuflen = sizeof(dir->d_did);
- return AFP_OK;
- }
- dir = (dir == parentdir->d_child->d_prev) ? NULL : dir->d_next;
+ if ( !path->st_valid && of_stat(path ) < 0 ) {
+ return( AFPERR_NOOBJ );
}
-
- /* we don't already have a did. add one in. */
- if ((dir = adddir(vol, parentdir, path, strlen(path),
- upath, strlen(upath), &st)) == NULL) {
- return AFPERR_MISC;
+ if ( path->st_errno ) {
+ return( AFPERR_NOOBJ );
}
- memcpy(rbuf, &dir->d_did, sizeof(dir->d_did));
- *rbuflen = sizeof(dir->d_did);
+ memcpy(rbuf, &curdir->d_did, sizeof(curdir->d_did));
+ *rbuflen = sizeof(curdir->d_did);
return AFP_OK;
}
/*
- * $Id: directory.h,v 1.5 2002-07-15 14:19:09 srittau Exp $
+ * $Id: directory.h,v 1.6 2002-10-11 14:18:28 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
#include <sys/types.h>
/*#include <sys/stat.h>*/ /* including it here causes some confusion */
#include <netatalk/endian.h>
+#include <dirent.h>
/* sys/types.h usually snarfs in major/minor macros. if they don't
* try this file. */
void *d_ofork; /* oforks using this directory. */
u_int32_t d_did;
int d_flags;
- char *d_name;
+
+ time_t ctime; /* inode ctime */
+ int offcnt; /* offspring count */
+
+ char *d_m_name; /* mac name */
+ char *d_u_name; /* unix name */
+};
+
+struct path {
+ char *m_name; /* mac name */
+ char *u_name; /* unix name */
+
+ int st_valid;
+ int st_errno;
+ struct stat st;
};
/* child addition/removal macros */
#define AR_UWRITE (1<<2)
#define AR_UOWN (1<<7)
-extern struct dir *dirnew __P((const int));
+extern struct dir *dirnew __P((const char *, const char *));
extern void dirfree __P((struct dir *));
extern struct dir *dirsearch __P((const struct vol *, u_int32_t));
extern struct dir *dirlookup __P((const struct vol *, u_int32_t));
-extern struct dir *adddir __P((struct vol *, struct dir *, char *,
- int, char *, int, struct stat *));
+
+extern struct dir *adddir __P((struct vol *, struct dir *,
+ struct path *));
+
extern struct dir *dirinsert __P((struct vol *, struct dir *));
extern int movecwd __P((const struct vol *, struct dir *));
extern int deletecurdir __P((const struct vol *, char *, int));
-extern char *cname __P((const struct vol *, struct dir *,
+extern struct path *cname __P((const struct vol *, struct dir *,
char **));
extern mode_t mtoumode __P((struct maccess *));
extern void utommode __P((struct stat *, struct maccess *));
-extern int getdirparams __P((const struct vol *, u_int16_t, char *,
- struct dir *, struct stat *, char *, int *));
-extern int setdirparams __P((const struct vol *, char *, u_int16_t, char *));
+extern int getdirparams __P((const struct vol *, u_int16_t, struct path *,
+ struct dir *, char *, int *));
+extern int setdirparams __P((const struct vol *, struct path *, u_int16_t, char *));
extern int renamedir __P((char *, char *, struct dir *,
struct dir *, char *, const int));
+typedef int (*dir_loop)(struct dirent *, char *, void *);
+
+extern int for_each_dirent __P((const struct vol *, char *, dir_loop , void *));
+
+extern int check_access __P((char *name , int mode));
+
+/* from enumerate.c */
+extern char *check_dirent __P((const struct vol *, char *));
/* FP functions */
extern int afp_createdir __P((AFPObj *, char *, int, char *, int *));
extern int afp_mapname __P((AFPObj *, char *, int, char *, int *));
/* from enumerate.c */
-extern int afp_enumerate __P((AFPObj *, char *, int, char *, int *));
+extern int afp_enumerate __P((AFPObj *, char *, unsigned int, char *, unsigned int *));
+extern int afp_enumerate_ext2 __P((AFPObj *, char *, unsigned int, char *, unsigned int *));
extern int afp_catsearch __P((AFPObj *, char *, int, char *, int *));
#endif
/*
- * $Id: enumerate.c,v 1.23 2002-10-05 14:04:47 didg Exp $
+ * $Id: enumerate.c,v 1.24 2002-10-11 14:18:28 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <dirent.h>
#include <errno.h>
#include <atalk/logger.h>
#include "volume.h"
#include "globals.h"
#include "file.h"
+#include "fork.h"
#include "filedir.h"
#define min(a,b) ((a)<(b)?(a):(b))
+/* ---------------------------- */
struct dir *
- adddir( vol, dir, name, namlen, upath, upathlen, st )
- struct vol *vol;
+ adddir( vol, dir, path)
+struct vol *vol;
struct dir *dir;
-char *name, *upath;
-int namlen, upathlen;
-struct stat *st;
+struct path *path;
{
struct dir *cdir, *edir;
-#if AD_VERSION > AD_VERSION1
- struct adouble ad;
-#endif /* AD_VERSION > AD_VERSION1 */
-
+ int upathlen;
+ char *name;
+ char *upath;
#ifndef USE_LASTDID
struct stat lst, *lstp;
#endif /* USE_LASTDID */
+ struct stat *st;
- if ((cdir = dirnew(namlen + 1)) == NULL) {
+ upath = path->u_name;
+ name = path->m_name;
+ st = &path->st;
+ upathlen = strlen(upath);
+ if ((cdir = dirnew(name, upath)) == NULL) {
LOG(log_error, logtype_afpd, "adddir: malloc: %s", strerror(errno) );
return NULL;
}
- strcpy( cdir->d_name, name );
- cdir->d_name[namlen] = '\0';
cdir->d_did = 0;
-#if AD_VERSION > AD_VERSION1
- /* look in AD v2 header */
- memset(&ad, 0, sizeof(ad));
- if (ad_open(upath, ADFLAGS_HF|ADFLAGS_DIR, O_RDONLY, 0, &ad) >= 0) {
- /* if we can parse the AppleDouble header, retrieve the DID entry into cdir->d_did */
- memcpy(&cdir->d_did, ad_entry(&ad, ADEID_DID), sizeof(cdir->d_did));
- ad_close(&ad, ADFLAGS_HF);
- }
-#endif /* AD_VERSION */
-
#ifdef CNID_DB
/* add to cnid db */
cdir->d_did = cnid_add(vol->v_db, st, dir->d_did, upath,
}
if ((edir = dirinsert( vol, cdir ))) {
-#ifndef CNID_DB
- if (edir->d_name) {
- if (strcmp(edir->d_name, cdir->d_name)) {
- LOG(log_info, logtype_afpd, "WARNING: DID conflict for '%s' and '%s'. Are these the same file?", edir->d_name, cdir->d_name);
- }
- free(cdir->d_name);
- free(cdir);
- return edir;
- }
-#endif /* CNID_DB */
- edir->d_name = cdir->d_name;
+ edir->d_m_name = cdir->d_m_name;
+ edir->d_u_name = cdir->d_u_name;
free(cdir);
cdir = edir;
}
dirchildadd(dir, cdir);
return( cdir );
}
-
/*
* Struct to save directory reading context in. Used to prevent
* O(n^2) searches on a directory.
*/
struct savedir {
- u_short sd_vid;
- int sd_did;
- int sd_buflen;
- char *sd_buf;
- char *sd_last;
- int sd_sindex;
+ u_short sd_vid;
+ u_int32_t sd_did;
+ int sd_buflen;
+ char *sd_buf;
+ char *sd_last;
+ unsigned int sd_sindex;
};
#define SDBUFBRK 1024
-int afp_enumerate(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+static int enumerate_loop(struct dirent *de, char *mname, void *data)
+{
+ struct savedir *sd = data;
+ char *start, *end;
+ int len;
+
+ end = sd->sd_buf + sd->sd_buflen;
+ len = strlen(de->d_name);
+ *(sd->sd_last)++ = len;
+
+ if ( sd->sd_last + len + 2 > end ) {
+ char *buf;
+
+ start = sd->sd_buf;
+ if (!(buf = realloc( sd->sd_buf, sd->sd_buflen +SDBUFBRK )) ) {
+ LOG(log_error, logtype_afpd, "afp_enumerate: realloc: %s",
+ strerror(errno) );
+ errno = ENOMEM;
+ return -1;
+ }
+ sd->sd_buf = buf;
+ sd->sd_buflen += SDBUFBRK;
+ sd->sd_last = ( sd->sd_last - start ) + sd->sd_buf;
+ end = sd->sd_buf + sd->sd_buflen;
+ }
+
+ memcpy( sd->sd_last, de->d_name, len + 1 );
+ sd->sd_last += len + 1;
+ return 0;
+}
+
+/* ----------------------------- */
+char *check_dirent(const struct vol *vol, char *name)
+{
+ char *m_name = NULL;
+
+ if (!strcmp(name, "..") || !strcmp(name, "."))
+ return NULL;
+
+ if (!(validupath(vol, name)))
+ return NULL;
+
+ /* check for vetoed filenames */
+ if (veto_file(vol->v_veto, name))
+ return NULL;
+
+ /* now check against too big a file */
+ if (strlen(m_name = utompath(vol, name)) > MACFILELEN)
+ return NULL;
+
+ return m_name;
+}
+
+/* ----------------------------- */
+int
+for_each_dirent(const struct vol *vol, char *name, dir_loop fn, void *data)
+{
+ DIR *dp;
+ struct dirent *de;
+ char *m_name;
+ int ret;
+
+ if (( dp = opendir( name)) == NULL ) {
+ return -1;
+ }
+ ret = 0;
+ for ( de = readdir( dp ); de != NULL; de = readdir( dp )) {
+ if (!(m_name = check_dirent(vol, de->d_name)))
+ continue;
+
+ ret++;
+ if (fn && fn(de,m_name, data) < 0) {
+ closedir(dp);
+ return -1;
+ }
+ }
+ closedir(dp);
+ return ret;
+}
+
+/* ----------------------------- */
+static int enumerate(obj, ibuf, ibuflen, rbuf, rbuflen, is64 )
+AFPObj *obj;
+char *ibuf, *rbuf;
+unsigned int ibuflen, *rbuflen;
+int is64;
{
- struct stat st;
static struct savedir sd = { 0, 0, 0, NULL, NULL, 0 };
struct vol *vol;
struct dir *dir;
- struct dirent *de;
- DIR *dp;
int did, ret, esz, len, first = 1;
- char *path, *data, *end, *start;
+ char *data, *start;
u_int16_t vid, fbitmap, dbitmap, reqcnt, actcnt = 0;
- u_int16_t sindex, maxsz, sz = 0;
-
+ u_int16_t temp16;
+ u_int32_t sindex, maxsz, sz = 0;
+ struct path *o_path;
+ struct path s_path;
+
if ( sd.sd_buflen == 0 ) {
if (( sd.sd_buf = (char *)malloc( SDBUFBRK )) == NULL ) {
LOG(log_error, logtype_afpd, "afp_enumerate: malloc: %s", strerror(errno) );
reqcnt = ntohs( reqcnt );
ibuf += sizeof( reqcnt );
- memcpy( &sindex, ibuf, sizeof( sindex ));
- sindex = ntohs( sindex );
- ibuf += sizeof( sindex );
-
- memcpy( &maxsz, ibuf, sizeof( maxsz ));
- maxsz = ntohs( maxsz );
- ibuf += sizeof( maxsz );
-
+ if (is64) {
+ memcpy( &sindex, ibuf, sizeof( sindex ));
+ sindex = ntohs( sindex );
+ ibuf += sizeof( sindex );
+ }
+ else {
+ memcpy( &temp16, ibuf, sizeof( temp16 ));
+ sindex = ntohs( temp16 );
+ ibuf += sizeof( temp16 );
+ }
+
+ if (is64) {
+ memcpy( &maxsz, ibuf, sizeof( maxsz ));
+ maxsz = ntohs( maxsz );
+ ibuf += sizeof( maxsz );
+ }
+ else {
+ memcpy( &temp16, ibuf, sizeof( temp16 ));
+ maxsz = ntohs( temp16 );
+ ibuf += sizeof( temp16 );
+ }
+
maxsz = min(maxsz, *rbuflen);
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( o_path = cname( vol, dir, &ibuf )) == NULL) {
*rbuflen = 0;
return( AFPERR_NODIR );
}
+
+ if ( *o_path->m_name != '\0') {
+ *rbuflen = 0;
+ return( AFPERR_BADTYPE );
+ }
+
data = rbuf + 3 * sizeof( u_int16_t );
sz = 3 * sizeof( u_int16_t );
*/
if ( sindex == 1 || curdir->d_did != sd.sd_did || vid != sd.sd_vid ) {
sd.sd_last = sd.sd_buf;
-
- if (( dp = opendir( mtoupath(vol, path ))) == NULL ) {
- *rbuflen = 0;
- return (errno == ENOTDIR) ? AFPERR_BADTYPE : AFPERR_NODIR;
+ if ( !o_path->st_valid && stat( ".", &o_path->st ) < 0 ) {
+ switch (errno) {
+ case EACCES:
+ return AFPERR_ACCESS;
+ case ENOTDIR:
+ return AFPERR_BADTYPE;
+ case ENOMEM:
+ return AFPERR_MISC;
+ default:
+ return AFPERR_NODIR;
+ }
}
-
- end = sd.sd_buf + sd.sd_buflen;
- for ( de = readdir( dp ); de != NULL; de = readdir( dp )) {
- if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, "."))
- continue;
-
- if (!(validupath(vol, de->d_name)))
- continue;
-
- /* check for vetoed filenames */
- if (veto_file(vol->v_veto, de->d_name))
- continue;
-
- /* now check against too big a file */
- if (strlen(utompath(vol, de->d_name)) > MACFILELEN)
- continue;
-
- len = strlen(de->d_name);
- *(sd.sd_last)++ = len;
-
- if ( sd.sd_last + len + 2 > end ) {
- char *buf;
-
- start = sd.sd_buf;
- if ((buf = (char *) realloc( sd.sd_buf, sd.sd_buflen +
- SDBUFBRK )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_enumerate: realloc: %s",
- strerror(errno) );
- closedir(dp);
- *rbuflen = 0;
- return AFPERR_MISC;
- }
- sd.sd_buf = buf;
- sd.sd_buflen += SDBUFBRK;
- sd.sd_last = ( sd.sd_last - start ) + sd.sd_buf;
- end = sd.sd_buf + sd.sd_buflen;
+ curdir->ctime = o_path->st.st_ctime; /* play safe */
+ if ((ret = for_each_dirent(vol, ".", enumerate_loop, (void *)&sd)) < 0) {
+ *rbuflen = 0;
+ switch (errno) {
+ case EACCES:
+ return AFPERR_ACCESS;
+ case ENOTDIR:
+ return AFPERR_BADTYPE;
+ case ENOMEM:
+ return AFPERR_MISC;
+ default:
+ return AFPERR_NODIR;
}
-
- memcpy( sd.sd_last, de->d_name, len + 1 );
- sd.sd_last += len + 1;
}
+ curdir->offcnt = ret;
*sd.sd_last = 0;
sd.sd_last = sd.sd_buf;
sd.sd_sindex = 1;
- closedir( dp );
sd.sd_vid = vid;
sd.sd_did = did;
}
while ( sd.sd_sindex < sindex ) {
len = *(sd.sd_last)++;
if ( len == 0 ) {
- sd.sd_did = -1; /* invalidate sd struct to force re-read */
+ sd.sd_did = 0; /* invalidate sd struct to force re-read */
*rbuflen = 0;
return( AFPERR_NOOBJ );
}
sd.sd_last += len + 1;
continue;
}
-
- if (stat( sd.sd_last, &st ) < 0 ) {
+ s_path.u_name = sd.sd_last;
+ if (of_stat( &s_path) < 0 ) {
/*
* Somebody else plays with the dir, well it can be us with
* "Empty Trash..."
/* so the next time it won't try to stat it again
* another solution would be to invalidate the cache with
- * sd.sd_did = -1 but if it's not ENOENT error it will start again
+ * sd.sd_did = 0 but if it's not ENOENT error it will start again
*/
*sd.sd_last = 0;
sd.sd_last += len + 1;
* inaccurate, since that means /dev/null is a file, /dev/printer
* is a file, etc.
*/
- if ( S_ISDIR(st.st_mode)) {
+ if ( S_ISDIR(s_path.st.st_mode)) {
if ( dbitmap == 0 ) {
sd.sd_last += len + 1;
continue;
}
- path = utompath(vol, sd.sd_last);
dir = curdir->d_child;
+ s_path.m_name = NULL;
while (dir) {
- if ( strcmp( dir->d_name, path ) == 0 ) {
+ if ( strcmp( dir->d_u_name, s_path.u_name ) == 0 ) {
break;
}
dir = (dir == curdir->d_child->d_prev) ? NULL : dir->d_next;
}
- if (!dir && ((dir = adddir( vol, curdir, path, strlen( path ),
- sd.sd_last, len, &st)) == NULL)) {
- *rbuflen = 0;
- return AFPERR_MISC;
+ if (!dir) {
+ s_path.m_name = utompath(vol, s_path.u_name);
+ if ((dir = adddir( vol, curdir, &s_path)) == NULL) {
+ *rbuflen = 0;
+ return AFPERR_MISC;
+ }
}
-
- if (( ret = getdirparams(vol, dbitmap, sd.sd_last, dir,
- &st, data + 2 * sizeof( u_char ), &esz )) != AFP_OK ) {
+ if (( ret = getdirparams(vol, dbitmap, &s_path, dir,
+ data + 2 * sizeof( u_char ), &esz )) != AFP_OK ) {
*rbuflen = 0;
return( ret );
}
sd.sd_last += len + 1;
continue;
}
-
- if (( ret = getfilparams(vol, fbitmap, utompath(vol, sd.sd_last),
- curdir, &st, data + 2 * sizeof( u_char ), &esz )) !=
- AFP_OK ) {
+ s_path.m_name = utompath(vol, s_path.u_name);
+ if (( ret = getfilparams(vol, fbitmap, &s_path, curdir,
+ data + 2 * sizeof( u_char ), &esz )) != AFP_OK ) {
*rbuflen = 0;
return( ret );
}
sz += esz + 2 * sizeof( u_char );
*data++ = esz + 2 * sizeof( u_char );
- *data++ = S_ISDIR(st.st_mode) ? FILDIRBIT_ISDIR : FILDIRBIT_ISFILE;
+ *data++ = S_ISDIR(s_path.st.st_mode) ? FILDIRBIT_ISDIR : FILDIRBIT_ISFILE;
data += esz;
actcnt++;
sd.sd_last += len + 1;
if ( actcnt == 0 ) {
*rbuflen = 0;
- sd.sd_did = -1; /* invalidate sd struct to force re-read */
+ sd.sd_did = 0; /* invalidate sd struct to force re-read */
return( AFPERR_NOOBJ );
}
sd.sd_sindex = sindex + actcnt;
return( AFP_OK );
}
+/* ----------------------------- */
+int afp_enumerate(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj;
+char *ibuf, *rbuf;
+unsigned int ibuflen, *rbuflen;
+{
+ return enumerate(obj, ibuf,ibuflen ,rbuf,rbuflen , 0);
+}
+
+/* ----------------------------- */
+int afp_enumerate_ext2(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj;
+char *ibuf, *rbuf;
+unsigned int ibuflen, *rbuflen;
+{
+ return enumerate(obj, ibuf,ibuflen ,rbuf,rbuflen , 1);
+}
/*
- * $Id: file.c,v 1.62 2002-10-05 14:04:47 didg Exp $
+ * $Id: file.c,v 1.63 2002-10-11 14:18:29 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
0, 0, 0, 0, 0, 0, 0, 0
};
+/* FIXME mpath : unix or mac name ? (for now it's mac name ) */
+void *get_finderinfo(const char *mpath, struct adouble *adp, void *data)
+{
+ struct extmap *em;
+
+ if (adp) {
+ memcpy(data, ad_entry(adp, ADEID_FINDERI), 32);
+ }
+ else {
+ memcpy(data, ufinderi, 32);
+ }
+
+ if ((!adp || !memcmp(ad_entry(adp, ADEID_FINDERI),ufinderi , 8 ))
+ && (em = getextmap( mpath ))
+ ) {
+ memcpy(data, em->em_type, sizeof( em->em_type ));
+ memcpy(data + 4, em->em_creator, sizeof(em->em_creator));
+ }
+ return data;
+}
+
+#define PARAM_NEED_ADP(b) ((b) & ((1 << FILPBIT_ATTR) |\
+ (1 << FILPBIT_CDATE) |\
+ (1 << FILPBIT_MDATE) |\
+ (1 << FILPBIT_BDATE) |\
+ (1 << FILPBIT_FINFO) |\
+ (1 << FILPBIT_RFLEN) |\
+ (1 << FILPBIT_EXTRFLEN) |\
+ (1 << FILPBIT_PDINFO)))
+
+
int getmetadata(struct vol *vol,
u_int16_t bitmap,
char *path, struct dir *dir, struct stat *st,
#ifndef USE_LASTDID
struct stat lst, *lstp;
#endif /* USE_LASTDID */
- struct stat hst;
- struct extmap *em;
char *data, *nameoff = NULL, *upath;
int bit = 0;
u_int32_t aint;
u_int16_t ashort;
u_char achar, fdType[4];
- struct maccess ma;
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin getmetadata:");
#if 0
/* FIXME do we want a visual clue if the file is read only
*/
+ struct maccess ma;
accessmode( ".", &ma, dir , NULL);
if ((ma.ma_user & AR_UWRITE)) {
accessmode( upath, &ma, dir , st);
break;
case FILPBIT_FINFO :
- if (adp)
- memcpy(data, ad_entry(adp, ADEID_FINDERI), 32);
- else {
- memcpy(data, ufinderi, 32);
+ get_finderinfo(path, adp, (char *)data);
+ if (!adp) {
if (*upath == '.') { /* make it invisible */
ashort = htons(FINDERINFO_INVISIBLE);
memcpy(data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
}
}
- if ((!adp || !memcmp(ad_entry(adp, ADEID_FINDERI),ufinderi , 8 ))
- && (em = getextmap( path ))
- ) {
- memcpy(data, em->em_type, sizeof( em->em_type ));
- memcpy(data + 4, em->em_creator, sizeof(em->em_creator));
- }
data += 32;
break;
break;
case FILPBIT_DFLEN :
- aint = htonl( st->st_size );
+ if (st->st_size > 0xffffffff)
+ aint = 0xffffffff;
+ else
+ aint = htonl( st->st_size );
memcpy(data, &aint, sizeof( aint ));
data += sizeof( aint );
break;
case FILPBIT_RFLEN :
if ( adp ) {
- aint = htonl( ad_getentrylen( adp, ADEID_RFORK ));
+ if (adp->ad_rlen > 0xffffffff)
+ aint = 0xffffffff;
+ else
+ aint = htonl( adp->ad_rlen);
} else {
aint = 0;
}
memset(data, 0, sizeof( ashort ));
data += sizeof( ashort );
break;
-
+ case FILPBIT_EXTDFLEN:
+ aint = htonl(st->st_size >> 32);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ aint = htonl(st->st_size);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ break;
+ case FILPBIT_EXTRFLEN:
+ aint = 0;
+ if (adp)
+ aint = htonl(adp->ad_rlen >> 32);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ if (adp)
+ aint = htonl(adp->ad_rlen);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ break;
default :
return( AFPERR_BITMAP );
}
/* ----------------------- */
int getfilparams(struct vol *vol,
u_int16_t bitmap,
- char *path, struct dir *dir, struct stat *st,
+ struct path *path, struct dir *dir,
char *buf, int *buflen )
{
struct adouble ad, *adp;
struct ofork *of;
char *upath;
u_int16_t attrbits = 0;
+ int opened = 0;
int rc;
+
#ifdef DEBUG
- LOG(log_info, logtype_afpd, "begin getfilparams:");
+ LOG(log_info, logtype_default, "begin getfilparams:");
#endif /* DEBUG */
- upath = mtoupath(vol, path);
- if ((of = of_findname(upath, st))) {
- adp = of->of_ad;
- attrbits = ((of->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
- attrbits |= ((of->of_ad->ad_hf.adf_refcount > of->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0);
-
- } else {
- memset(&ad, 0, sizeof(ad));
- adp = &ad;
- }
+ opened = PARAM_NEED_ADP(bitmap);
+ adp = NULL;
+ if (opened) {
+ upath = path->u_name;
+ if ((of = of_findname(path))) {
+ adp = of->of_ad;
+ attrbits = ((of->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
+ attrbits |= ((of->of_ad->ad_hf.adf_refcount > of->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0);
+ } else {
+ memset(&ad, 0, sizeof(ad));
+ adp = &ad;
+ }
- if ( ad_open( upath, ADFLAGS_HF, O_RDONLY, 0, adp) < 0 ) {
- adp = NULL;
- }
- else {
-#if 0
- /* FIXME
- we need to check if the file is open by another process.
- it's slow so we only do it if we have to:
- - bitmap is requested.
- - we don't already have the answer!
- */
- if ((bitmap & (1 << FILPBIT_ATTR))) {
- if (!(attrbits & ATTRBIT_ROPEN)) {
- }
- if (!(attrbits & ATTRBIT_DOPEN)) {
- }
+ if ( ad_open( upath, ADFLAGS_HF, O_RDONLY, 0, adp) < 0 ) {
+ adp = NULL;
+ }
+ else {
+ /* FIXME
+ we need to check if the file is open by another process.
+ it's slow so we only do it if we have to:
+ - bitmap is requested.
+ - we don't already have the answer!
+ */
+ if ((bitmap & (1 << FILPBIT_ATTR))) {
+ if (!(attrbits & ATTRBIT_ROPEN)) {
+ }
+ if (!(attrbits & ATTRBIT_DOPEN)) {
+ }
+ }
}
-#endif
}
- rc = getmetadata(vol, bitmap, path, dir, st, buf, buflen, adp, attrbits);
+ rc = getmetadata(vol, bitmap, path->m_name, dir, &path->st, buf, buflen, adp, attrbits);
if ( adp ) {
ad_close( adp, ADFLAGS_HF );
}
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
- struct stat st;
+ struct stat *st;
struct adouble ad, *adp;
struct vol *vol;
struct dir *dir;
int creatf, did, openf, retvalue = AFP_OK;
u_int16_t vid;
int ret;
+ struct path *s_path;
+
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin afp_createfile:");
#endif /* DEBUG */
return( AFPERR_NOOBJ );
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- upath = mtoupath(vol, path);
+ if ( *s_path->m_name == '\0' ) {
+ return( AFPERR_BADTYPE );
+ }
+
+ upath = s_path->u_name;
if (0 != (ret = check_name(vol, upath)))
return ret;
-
- ret = stat(upath, &st);
+
/* if upath is deleted we already in trouble anyway */
- if (!ret && (of = of_findname(upath, &st))) {
+ if ((of = of_findname(s_path))) {
adp = of->of_ad;
} else {
memset(&ad, 0, sizeof(ad));
}
if ( creatf) {
/* on a hard create, fail if file exists and is open */
- if (!ret && of)
+ if (of)
return AFPERR_BUSY;
openf = O_RDWR|O_CREAT|O_TRUNC;
} else {
return( AFPERR_ACCESS );
case ENOENT:
/* on noadouble volumes, just creating the data fork is ok */
- if (vol_noadouble(vol) && (stat(upath, &st) == 0))
+ st = &s_path->st;
+ if (vol_noadouble(vol) && (stat(upath, st) == 0))
goto createfile_done;
/* fallthrough */
default :
return( AFPERR_PARAM );
}
}
-
+ path = s_path->m_name;
ad_setentrylen( adp, ADEID_NAME, strlen( path ));
memcpy(ad_entry( adp, ADEID_NAME ), path,
ad_getentrylen( adp, ADEID_NAME ));
{
struct vol *vol;
struct dir *dir;
- char *path;
+ struct path *s_path;
int did, rc;
u_int16_t vid, bitmap;
bitmap = ntohs( bitmap );
ibuf += sizeof( bitmap );
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- if ( *path == '\0' ) {
+ if ( *s_path->m_name == '\0' ) {
return( AFPERR_BADTYPE ); /* it's a directory */
}
ibuf++;
}
- if (( rc = setfilparams(vol, path, bitmap, ibuf )) == AFP_OK ) {
+ if (( rc = setfilparams(vol, s_path, bitmap, ibuf )) == AFP_OK ) {
setvoltime(obj, vol );
}
* cf AFP3.0.pdf page 252 for change_mdate and change_parent_mdate logic
*
*/
+extern struct path Cur_Path;
int setfilparams(struct vol *vol,
- char *path, u_int16_t bitmap, char *buf )
+ struct path *path, u_int16_t bitmap, char *buf )
{
struct adouble ad, *adp;
struct ofork *of;
LOG(log_info, logtype_afpd, "begin setfilparams:");
#endif /* DEBUG */
- upath = mtoupath(vol, path);
- if ((of = of_findname(upath, NULL))) {
+ upath = path->u_name;
+ if ((of = of_findname(path))) {
adp = of->of_ad;
} else {
memset(&ad, 0, sizeof(ad));
}
isad = 0;
} else if ((ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT) ) {
- ad_setentrylen( adp, ADEID_NAME, strlen( path ));
- memcpy(ad_entry( adp, ADEID_NAME ), path,
+ ad_setentrylen( adp, ADEID_NAME, strlen( path->m_name ));
+ memcpy(ad_entry( adp, ADEID_NAME ), path->m_name,
ad_getentrylen( adp, ADEID_NAME ));
}
if (!memcmp( ad_entry( adp, ADEID_FINDERI ), ufinderi, 8 )
&& (
- ((em = getextmap( path )) &&
+ ((em = getextmap( path->m_name )) &&
!memcmp(buf, em->em_type, sizeof( em->em_type )) &&
!memcmp(buf + 4, em->em_creator,sizeof( em->em_creator)))
|| ((em = getdefextmap()) &&
if (change_parent_mdate && gettimeofday(&tv, NULL) == 0) {
newdate = AD_DATE_FROM_UNIX(tv.tv_sec);
bitmap = 1<<FILPBIT_MDATE;
- setdirparams(vol, "", bitmap, (char *)&newdate);
+ setdirparams(vol, &Cur_Path, bitmap, (char *)&newdate);
}
#ifdef DEBUG
return( AFP_OK );
}
+/* -----------------------------------
+*/
int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
{
struct vol *vol;
struct dir *dir;
- char *newname, *path, *p, *upath;
+ char *newname, *p, *upath;
+ struct path *s_path;
u_int32_t sdid, ddid;
- int plen, err, retvalue = AFP_OK;
+ size_t plen;
+ int err, retvalue = AFP_OK;
u_int16_t svid, dvid;
#ifdef DEBUG
memcpy(&ddid, ibuf, sizeof( ddid ));
ibuf += sizeof( ddid );
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- if ( *path == '\0' ) {
+ if ( *s_path->m_name == '\0' ) {
return( AFPERR_BADTYPE );
}
* we just balk if the file is opened already. */
newname = obj->newtmp;
- strcpy( newname, path );
+ strcpy( newname, s_path->m_name );
- upath = mtoupath(vol, newname );
- if (of_findname(upath, NULL))
+ if (of_findname(s_path))
return AFPERR_DENYCONF;
p = ctoupath( vol, curdir, newname );
return( AFPERR_PARAM );
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- if ( *path != '\0' ) {
+ if ( *s_path->m_name != '\0' ) {
return( AFPERR_BADTYPE ); /* not a directory. AFPERR_PARAM? */
}
const int noadouble;
{
struct adouble ad;
+#ifdef SENDFILE_FLAVOR_LINUX
struct stat st;
+#endif
char filebuf[8192];
int sfd, dfd, len, err = AFP_OK;
ssize_t cc;
return err;
}
-
+/* ------------------------------------ */
#ifdef CNID_DB
/* return a file id */
int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
- struct stat st;
+ struct stat *st;
+#if AD_VERSION > AD_VERSION1
struct adouble ad;
+#endif
struct vol *vol;
struct dir *dir;
- char *path, *upath;
+ char *upath;
int len;
cnid_t did, id;
u_short vid;
+ struct path *s_path;
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin afp_createid:");
return( AFPERR_PARAM );
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_PARAM );
}
- if ( *path == '\0' ) {
+ if ( *s_path->m_name == '\0' ) {
return( AFPERR_BADTYPE );
}
- upath = mtoupath(vol, path);
- if (stat(upath, &st) < 0) {
- switch (errno) {
+ upath = s_path->u_name;
+ switch (s_path->st_errno) {
+ case 0:
+ break; /* success */
case EPERM:
case EACCES:
return AFPERR_ACCESS;
return AFPERR_NOOBJ;
default:
return AFPERR_PARAM;
- }
}
-
- if (id = cnid_lookup(vol->v_db, &st, did, upath, len = strlen(upath))) {
+ st = &s_path->st;
+ if ((id = cnid_lookup(vol->v_db, st, did, upath, len = strlen(upath)))) {
memcpy(rbuf, &id, sizeof(id));
*rbuflen = sizeof(id);
return AFPERR_EXISTID;
}
#endif /* AD_VERSION > AD_VERSION1 */
- if (id = cnid_add(vol->v_db, &st, did, upath, len, id) != CNID_INVALID) {
+ if ((id = cnid_add(vol->v_db, st, did, upath, len, id)) != CNID_INVALID) {
memcpy(rbuf, &id, sizeof(id));
*rbuflen = sizeof(id);
return AFP_OK;
}
}
-/* resolve a file id */
+/* ------------------------------
+ resolve a file id */
int afp_resolveid(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
- struct stat st;
struct vol *vol;
struct dir *dir;
char *upath;
+ struct path path;
int err, buflen;
cnid_t id;
u_int16_t vid, bitmap;
if (( dir = dirlookup( vol, id )) == NULL ) {
return AFPERR_NOID; /* idem AFPERR_PARAM */
}
-
- if ((movecwd(vol, dir) < 0) || (stat(upath, &st) < 0)) {
+ path.u_name = upath;
+ if (movecwd(vol, dir) < 0 || of_stat(&path) < 0) {
switch (errno) {
case EACCES:
case EPERM:
return AFPERR_PARAM;
}
}
-
/* directories are bad */
- if (S_ISDIR(st.st_mode))
+ if (S_ISDIR(path.st.st_mode))
return AFPERR_BADTYPE;
memcpy(&bitmap, ibuf, sizeof(bitmap));
bitmap = ntohs( bitmap );
-
- if ((err = getfilparams(vol, bitmap, utompath(vol, upath), curdir, &st,
- rbuf + sizeof(bitmap), &buflen)) != AFP_OK)
+ path.m_name = utompath(vol, upath);
+ if ((err = getfilparams(vol, bitmap, &path , curdir,
+ rbuf + sizeof(bitmap), &buflen)) != AFP_OK) {
return err;
-
+ }
*rbuflen = buflen + sizeof(bitmap);
memcpy(rbuf, ibuf, sizeof(bitmap));
return AFP_OK;
}
+/* ------------------------------ */
int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
struct stat srcst, destst;
struct vol *vol;
struct dir *dir, *sdir;
- char *spath, temp[17], *path, *p;
+ char *spath, temp[17], *p;
char *supath, *upath;
+ struct path *path;
int err;
struct adouble ads;
struct adouble add;
return( AFPERR_PARAM );
}
- if ( *path == '\0' ) {
+ if ( *path->m_name == '\0' ) {
return( AFPERR_BADTYPE ); /* it's a dir */
}
- upath = mtoupath(vol, path);
- if (stat(upath, &srcst) < 0) {
- switch (errno) {
+ upath = path->u_name;
+ switch (path->st_errno) {
+ case 0:
+ break;
case ENOENT:
return AFPERR_NOID;
case EPERM:
return AFPERR_ACCESS;
default:
return AFPERR_PARAM;
- }
}
memset(&ads, 0, sizeof(ads));
adsp = &ads;
- if ((s_of = of_findname(upath, &srcst))) {
+ if ((s_of = of_findname(path))) {
/* reuse struct adouble so it won't break locks */
adsp = s_of->of_ad;
}
+ memcpy(&srcst, &path->st, sizeof(struct stat));
/* save some stuff */
sdir = curdir;
spath = obj->oldtmp;
supath = obj->newtmp;
- strcpy(spath, path);
+ strcpy(spath, path->m_name);
strcpy(supath, upath); /* this is for the cnid changing */
- p = ctoupath( vol, sdir, spath);
+ p = absupath( vol, sdir, upath);
/* look for the source cnid. if it doesn't exist, don't worry about
* it. */
return( AFPERR_PARAM );
}
- if ( *path == '\0' ) {
+ if ( *path->m_name == '\0' ) {
return( AFPERR_BADTYPE );
}
/* FPExchangeFiles is the only call that can return the SameObj
* error */
- if ((curdir == sdir) && strcmp(spath, path) == 0)
+ if ((curdir == sdir) && strcmp(spath, path->m_name) == 0)
return AFPERR_SAMEOBJ;
+ memcpy(&srcst, &path->st, sizeof(struct stat));
- upath = mtoupath(vol, path);
- if (stat(upath, &destst) < 0) {
- switch (errno) {
+ switch (errno) {
+ case 0:
+ break;
case ENOENT:
return AFPERR_NOID;
case EPERM:
return AFPERR_ACCESS;
default:
return AFPERR_PARAM;
- }
}
memset(&add, 0, sizeof(add));
addp = &add;
- if ((d_of = of_findname( upath, &destst))) {
+ if ((d_of = of_findname( path))) {
/* reuse struct adouble so it won't break locks */
addp = d_of->of_ad;
}
+ memcpy(&destst, &path->st, sizeof(struct stat));
/* they are not on the same device and at least one is open
*/
if ((d_of || s_of) && srcst.st_dev != destst.st_dev)
return AFPERR_MISC;
+ upath = path->u_name;
#ifdef CNID_DB
/* look for destination id. */
did = cnid_lookup(vol->v_db, &destst, curdir->d_did, upath,
/* rename destination to source */
if ((err = renamefile(upath, p, spath, vol_noadouble(vol), addp)) < 0)
goto err_src_to_tmp;
- of_rename(vol, d_of, curdir, path, sdir, spath);
+ of_rename(vol, d_of, curdir, path->m_name, sdir, spath);
/* rename temp to destination */
- if ((err = renamefile(temp, upath, path, vol_noadouble(vol), adsp)) < 0)
+ if ((err = renamefile(temp, upath, path->m_name, vol_noadouble(vol), adsp)) < 0)
goto err_dest_to_src;
- of_rename(vol, s_of, curdir, temp, curdir, path);
+ of_rename(vol, s_of, curdir, temp, curdir, path->m_name);
#ifdef CNID_DB
/* id's need switching. src -> dest and dest -> src. */
err_dest_to_src:
/* rename source back to dest */
- renamefile(p, upath, path, vol_noadouble(vol), addp);
- of_rename(vol, d_of, sdir, spath, curdir, path);
+ renamefile(p, upath, path->m_name, vol_noadouble(vol), addp);
+ of_rename(vol, d_of, sdir, spath, curdir, path->m_name);
err_src_to_tmp:
/* rename temp back to source */
/*
- * $Id: file.h,v 1.11 2002-10-09 18:46:31 didg Exp $
+ * $Id: file.h,v 1.12 2002-10-11 14:18:31 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
extern struct extmap *getextmap __P((const char *));
extern struct extmap *getdefextmap __P((void));
-extern int getfilparams __P((struct vol *, u_int16_t, char *,
- struct dir *, struct stat *, char *buf,
- int *));
-extern int setfilparams __P((struct vol *, char *, u_int16_t, char *));
+extern int getfilparams __P((struct vol *, u_int16_t, struct path *,
+ struct dir *, char *buf, int *));
+
+extern int setfilparams __P((struct vol *, struct path *, u_int16_t, char *));
extern int renamefile __P((char *, char *, char *, const int, struct adouble *));
extern int copyfile __P((char *, char *, char *, const int));
extern int deletefile __P((char *, int));
+extern void *get_finderinfo __P((const char *, struct adouble *, void *));
+
/* FP functions */
extern int afp_exchangefiles __P((AFPObj *, char *, int, char *, int *));
extern int afp_setfilparams __P((AFPObj *, char *, int, char *, int *));
/*
- * $Id: filedir.c,v 1.32 2002-10-05 14:04:47 didg Exp $
+ * $Id: filedir.c,v 1.33 2002-10-11 14:18:31 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include "file.h"
#include "globals.h"
#include "filedir.h"
+#include "unix.h"
int matchfile2dirperms(upath, vol, did)
/* Since it's kinda' big; I decided against an
struct stat st, sb;
struct dir *dir;
char *adpath;
- int uid;
+ uid_t uid;
int ret = AFP_OK;
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin matchfile2dirperms:");
else if (stat(".", &sb) < 0) {
LOG(log_error, logtype_afpd,
"matchfile2dirperms: Error checking directory \"%s\": %s",
- dir->d_name, strerror(errno));
- ret AFPERR_NOOBJ;
+ dir->d_m_name, strerror(errno));
+ ret = AFPERR_NOOBJ;
}
else {
uid=geteuid();
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
- struct stat st;
+ struct stat *st;
struct vol *vol;
struct dir *dir;
u_int32_t did;
int buflen, ret;
- char *path;
u_int16_t fbitmap, dbitmap, vid;
+ struct path *s_path;
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin afp_getfildirparams:");
dbitmap = ntohs( dbitmap );
ibuf += sizeof( dbitmap );
- if (( path = cname( vol, dir, &ibuf )) == NULL) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL) {
return( AFPERR_NOOBJ );
}
- if ( stat( mtoupath(vol, path ), &st ) < 0 ) {
+ st = &s_path->st;
+ if (!s_path->st_valid) {
+ /* it's a dir and it should be there
+ * because we chdir in it in cname
+ */
+ of_stat(s_path);
+ }
+ if ( s_path->st_errno != 0 ) {
return( AFPERR_NOOBJ );
}
buflen = 0;
- if (S_ISDIR(st.st_mode)) {
+ if (S_ISDIR(st->st_mode)) {
if (dbitmap) {
- ret = getdirparams(vol, dbitmap, ".", curdir,
- &st, rbuf + 3 * sizeof( u_int16_t ), &buflen );
+ ret = getdirparams(vol, dbitmap, s_path, curdir,
+ rbuf + 3 * sizeof( u_int16_t ), &buflen );
if (ret != AFP_OK )
return( ret );
}
/* this is a directory */
*(rbuf + 2 * sizeof( u_int16_t )) = (char) FILDIRBIT_ISDIR;
} else {
- if (fbitmap && ( ret = getfilparams(vol, fbitmap, path, curdir, &st,
+ if (fbitmap && ( ret = getfilparams(vol, fbitmap, s_path, curdir,
rbuf + 3 * sizeof( u_int16_t ), &buflen )) != AFP_OK ) {
return( ret );
}
return( AFP_OK );
}
-/*
- * We can't use unix file's perm to support Apple's inherited protection modes.
- * If we aren't the file's owner we can't change its perms when moving it and smb
- * nfs,... don't even try.
-*/
-#define AFP_CHECK_ACCESS
-
-int check_access(char *path, int mode)
-{
-#ifdef AFP_CHECK_ACCESS
-struct maccess ma;
-char *p;
-
- p = ad_dir(path);
- if (!p)
- return -1;
-
- accessmode(p, &ma, curdir, NULL);
- if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
- return -1;
- if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
- return -1;
-#endif
- return 0;
-}
-
int afp_setfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
- struct stat st;
+ struct stat *st;
struct vol *vol;
struct dir *dir;
- char *path;
+ struct path *path;
u_int16_t vid, bitmap;
int did, rc;
return( AFPERR_NOOBJ );
}
- if ( stat( mtoupath(vol, path ), &st ) < 0 ) {
- return( AFPERR_NOOBJ );
+ st = &path->st;
+ if (!path->st_valid) {
+ /* it's a dir and it should be there
+ * because we chdir in it in cname
+ */
+ of_stat(path);
}
+ if ( path->st_errno != 0 ) {
+ return( AFPERR_NOOBJ );
+ }
/*
* If ibuf is odd, make it even.
*/
ibuf++;
}
- if (S_ISDIR(st.st_mode)) {
+ if (S_ISDIR(st->st_mode)) {
rc = setdirparams(vol, path, bitmap, ibuf );
} else {
rc = setfilparams(vol, path, bitmap, ibuf );
char *p;
char *upath;
int rc;
- struct stat st;
+ struct stat *st;
int adflags;
struct adouble ad;
struct adouble *adp;
- struct ofork *opened;
-
+ struct ofork *opened = NULL;
+ struct path path;
#ifdef CNID_DB
cnid_t id;
#endif /* CNID_DB */
id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
#endif /* CNID_DB */
p = ctoupath( vol, sdir, oldname );
- if ((opened = of_findname(p, NULL))) {
+ path.st_valid = 0;
+ path.u_name = p;
+ if ((opened = of_findname(&path))) {
/* reuse struct adouble so it won't break locks */
adp = opened->of_ad;
}
}
upath = mtoupath(vol, newname);
+ path.u_name = upath;
+ st = &path.st;
if (0 != (rc = check_name(vol, upath))) {
return rc;
}
return AFP_OK;
/* deal with case insensitive, case-preserving filesystems. */
- if ((stat(upath, &st) == 0) && strdiacasecmp(oldname, newname))
+ if ((stat(upath, st) == 0) && strdiacasecmp(oldname, newname))
return AFPERR_EXIST;
- } else if (stat(upath, &st ) == 0)
+ } else if (stat(upath, st ) == 0)
return AFPERR_EXIST;
if ( !isdir ) {
- if (of_findname(upath, &st)) {
+ path.st_valid = 1;
+ path.st_errno = errno;
+ if (of_findname(&path)) {
rc = AFPERR_EXIST; /* was AFPERR_BUSY; */
} else {
rc = renamefile( p, upath, newname,vol_noadouble(vol), adp );
if ( rc == AFP_OK ) {
#ifdef CNID_DB
/* renaming may have moved the file/dir across a filesystem */
- if (stat(upath, &st) < 0)
+ if (stat(upath, st) < 0)
return AFPERR_MISC;
/* fix up the catalog entry */
- cnid_update(vol->v_db, id, &st, curdir->d_did, upath, strlen(upath));
+ cnid_update(vol->v_db, id, st, curdir->d_did, upath, strlen(upath));
#endif /* CNID_DB */
}
{
struct vol *vol;
struct dir *sdir;
- char *path, *oldname, *newname;
+ char *oldname, *newname;
+ struct path *path;
u_int32_t did;
- int plen;
+ size_t plen;
u_int16_t vid;
int isdir = 0;
int rc;
sdir = curdir;
newname = obj->newtmp;
oldname = obj->oldtmp;
- if ( *path != '\0' ) {
- strcpy(oldname, path); /* an extra copy for of_rename */
+ if ( *path->m_name != '\0' ) {
+ strcpy(oldname, path->m_name); /* an extra copy for of_rename */
}
else {
if ( sdir->d_parent == NULL ) { /* root directory */
return( AFPERR_NOOBJ );
}
isdir = 1;
- strcpy(oldname, sdir->d_name);
+ strcpy(oldname, sdir->d_m_name);
}
/* another place where we know about the path type */
{
struct vol *vol;
struct dir *dir;
- char *path, *upath;
+ struct path *s_path;
+ char *upath;
int did, rc;
u_int16_t vid;
return( AFPERR_NOOBJ );
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- upath = mtoupath(vol, path );
- if ( *path == '\0' ) {
+ upath = s_path->u_name;
+ if ( *s_path->m_name == '\0' ) {
rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
- } else if (of_findname(upath, NULL)) {
+ } else if (of_findname(s_path)) {
rc = AFPERR_BUSY;
} else if ((rc = deletefile( upath, 1)) == AFP_OK) {
#ifdef CNID_DB /* get rid of entry */
return( rc );
}
-
-char *ctoupath( vol, dir, name )
+char *absupath( vol, dir, u )
const struct vol *vol;
struct dir *dir;
-char *name;
+char *u;
{
struct dir *d;
static char path[ MAXPATHLEN + 1];
- char *p, *u;
+ char *p;
int len;
p = path + sizeof( path ) - 1;
*p = '\0';
- u = mtoupath(vol, name );
len = strlen( u );
p -= len;
strncpy( p, u, len );
for ( d = dir; d->d_parent; d = d->d_parent ) {
*--p = '/';
- u = mtoupath(vol, d->d_name );
+ u = d->d_u_name;
len = strlen( u );
p -= len;
strncpy( p, u, len );
return( p );
}
+char *ctoupath( vol, dir, name )
+const struct vol *vol;
+struct dir *dir;
+char *name;
+{
+ return absupath(vol, dir, mtoupath(vol, name));
+}
+
/* ------------------------- */
int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
struct vol *vol;
struct dir *sdir, *ddir;
int isdir = 0;
- char *oldname, *newname;
- char *path;
+ char *oldname, *newname;
+ struct path *path;
int did;
- int plen;
+ size_t plen;
u_int16_t vid;
int rc;
#ifdef DROPKLUDGE
sdir = curdir;
newname = obj->newtmp;
oldname = obj->oldtmp;
- if ( *path != '\0' ) {
+ if ( *path->m_name != '\0' ) {
/* not a directory */
- strcpy(oldname, path); /* an extra copy for of_rename */
+ strcpy(oldname, path->m_name); /* an extra copy for of_rename */
} else {
isdir = 1;
- strcpy(oldname, sdir->d_name);
+ strcpy(oldname, sdir->d_m_name);
}
/* get the destination directory */
if (( path = cname( vol, ddir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- if ( *path != '\0' ) {
+ if ( *path->m_name != '\0' ) {
return( AFPERR_BADTYPE );
}
char *upath = mtoupath(vol, newname);
#ifdef DROPKLUDGE
if (vol->v_flags & AFPVOL_DROPBOX) {
- if (retvalue=matchfile2dirperms (upath, vol, did) != AFP_OK) {
+ if ((retvalue=matchfile2dirperms (upath, vol, did)) != AFP_OK) {
return retvalue;
}
}
/*
- * $Id: filedir.h,v 1.8 2002-08-29 18:57:26 didg Exp $
+ * $Id: filedir.h,v 1.9 2002-10-11 14:18:32 didg Exp $
*/
#ifndef AFPD_FILEDIR_H
extern char *ctoupath __P((const struct vol *, struct dir *,
char *));
+extern char *absupath __P((const struct vol *, struct dir *,
+ char *));
extern int veto_file __P((const char *veto_str, const char *path));
extern int check_name __P((const struct vol *vol, char *name));
-extern int check_access __P((char *name , int mode));
/* FP functions */
extern int matchfile2dirperms __P((char *, struct vol *, int));
/*
- * $Id: fork.c,v 1.37 2002-10-05 14:04:47 didg Exp $
+ * $Id: fork.c,v 1.38 2002-10-11 14:18:32 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include "volume.h"
#define BYTELOCK_MAX 0x7FFFFFFFU
+#define BYTELOCK_MAXL 0x7FFFFFFFFFFFFFFFULL
struct ofork *writtenfork;
extern int getmetadata(struct vol *vol,
int *buflen;
const u_int16_t attrbits;
{
-#ifndef USE_LASTDID
- struct stat lst, *lstp;
-#endif /* !USE_LASTDID */
struct stat st;
char *upath;
- u_int32_t aint;
struct adouble *adp;
struct dir *dir;
struct vol *vol;
+
+ /* can only get the length of the opened fork */
+ if ( ( (bitmap & ((1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN)))
+ && (ofork->of_flags & AFPFORK_RSRC))
+ ||
+ ( (bitmap & ((1<<FILPBIT_RFLEN) | (1<<FILPBIT_EXTRFLEN)))
+ && (ofork->of_flags & AFPFORK_DATA))) {
+ return( AFPERR_BITMAP );
+ }
+
if ( ad_hfileno( ofork->of_ad ) == -1 ) {
adp = NULL;
} else {
- aint = ad_getentrylen( ofork->of_ad, ADEID_RFORK );
- if ( ad_refresh( ofork->of_ad ) < 0 ) {
- LOG(log_error, logtype_afpd, "getforkparams: ad_refresh: %s", strerror(errno) );
- return( AFPERR_PARAM );
- }
- /* See afp_closefork() for why this is bad */
- ad_setentrylen( ofork->of_ad, ADEID_RFORK, aint );
adp = ofork->of_ad;
}
- /* can only get the length of the opened fork */
- if (((bitmap & (1<<FILPBIT_DFLEN)) && (ofork->of_flags & AFPFORK_RSRC)) ||
- ((bitmap & (1<<FILPBIT_RFLEN)) && (ofork->of_flags & AFPFORK_DATA))) {
- return( AFPERR_BITMAP );
- }
-
vol = ofork->of_vol;
dir = ofork->of_dir;
- if ( bitmap & ( 1<<FILPBIT_DFLEN | 1<<FILPBIT_FNUM |
- (1 << FILPBIT_CDATE) | (1 << FILPBIT_MDATE) |
- (1 << FILPBIT_BDATE))) {
+ if ( bitmap & ( (1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) |
+ (1<<FILPBIT_FNUM) | (1 << FILPBIT_CDATE) |
+ (1 << FILPBIT_MDATE) | (1 << FILPBIT_BDATE))) {
if ( ad_dfileno( ofork->of_ad ) == -1 ) {
upath = mtoupath(vol, ofork->of_name);
if (movecwd(vol, dir) < 0)
u_int32_t did;
u_int16_t vid, bitmap, access, ofrefnum, attrbits = 0;
char fork, *path, *upath;
- struct stat st;
+ struct stat *st;
u_int16_t bshort;
-
+ struct path *s_path;
+
ibuf++;
fork = *ibuf++;
memcpy(&vid, ibuf, sizeof( vid ));
return AFPERR_VLOCK;
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
- return( AFPERR_NOOBJ );
+ if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
+ return AFPERR_NOOBJ;
}
- if ( fork == OPENFORK_DATA ) {
- eid = ADEID_DFORK;
- adflags = ADFLAGS_DF|ADFLAGS_HF;
- } else {
- eid = ADEID_RFORK;
- adflags = ADFLAGS_HF;
+ if (*s_path->m_name == '\0') {
+ /* it's a dir ! */
+ return AFPERR_BADTYPE;
}
- upath = mtoupath(vol, path);
+ /* stat() data fork st is set because it's not a dir */
+ switch ( s_path->st_errno ) {
+ case 0:
+ break;
+ case ENOENT:
+ return AFPERR_NOOBJ;
+ case EACCES:
+ return (access & OPENACC_WR) ? AFPERR_LOCK : AFPERR_ACCESS;
+ default:
+ LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
+ return AFPERR_PARAM;
+ }
+ /* FIXME should we check first ? */
+ upath = s_path->u_name;
if (check_access(upath, access ) < 0) {
return AFPERR_ACCESS;
}
- /* stat() data fork */
- if (stat(upath, &st) < 0) {
- switch ( errno ) {
- case ENOENT:
- return AFPERR_NOOBJ;
- case EACCES:
- return (access & OPENACC_WR) ? AFPERR_LOCK : AFPERR_ACCESS;
- default:
- LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
- return AFPERR_PARAM;
- }
- }
-
+ st = &s_path->st;
/* XXX: this probably isn't the best way to do this. the already
open bits should really be set if the fork is opened by any
program, not just this one. however, that's problematic to do
ad_open so that we can keep file locks together.
FIXME: add the fork we are opening?
*/
- if ((opened = of_findname(upath, &st))) {
+ if ((opened = of_findname(s_path))) {
attrbits = ((opened->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
attrbits |= ((opened->of_ad->ad_hf.adf_refcount > opened->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0);
adsame = opened->of_ad;
}
+ if ( fork == OPENFORK_DATA ) {
+ eid = ADEID_DFORK;
+ adflags = ADFLAGS_DF|ADFLAGS_HF;
+ } else {
+ eid = ADEID_RFORK;
+ adflags = ADFLAGS_HF;
+ }
+
+ path = s_path->m_name;
if (( ofork = of_alloc(vol, curdir, path, &ofrefnum, eid,
- adsame, &st)) == NULL ) {
+ adsame, st)) == NULL ) {
return( AFPERR_NFILE );
}
*/
#define ENDBIT(a) ((a) & 0x80)
#define UNLOCKBIT(a) ((a) & 0x01)
-int afp_bytelock(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
+
+static off_t get_off_t(ibuf, is64)
+char **ibuf;
+int is64;
+{
+ u_int32_t temp;
+ off_t ret;
+
+ memcpy(&temp, *ibuf, sizeof( temp ));
+ ret = ntohl(temp); /* ntohl is unsigned */
+ *ibuf += sizeof(temp);
+
+ if (is64) {
+ memcpy(&temp, *ibuf, sizeof( temp ));
+ *ibuf += sizeof(temp);
+ ret = ntohl(temp)| (ret << 32);
+ }
+ return ret;
+}
+
+/* ---------------------- */
+static int set_off_t(offset, rbuf, is64)
+off_t offset;
+char *rbuf;
+int is64;
+{
+ u_int32_t temp;
+ int ret;
+
+ ret = 0;
+ if (is64) {
+ temp = htonl(offset >> 32);
+ memcpy(rbuf, &temp, sizeof( temp ));
+ ret = sizeof( temp );
+ offset &= 0xffffffff;
+ }
+ temp = htonl(offset);
+ memcpy(rbuf, &temp, sizeof( temp ));
+ ret += sizeof( temp );
+
+ return ret;
+}
+
+/* ---------------------- */
+static int byte_lock(obj, ibuf, ibuflen, rbuf, rbuflen, is64 )
+AFPObj *obj;
char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int ibuflen, *rbuflen;
+int is64;
{
struct ofork *ofork;
- int32_t offset, length;
+ off_t offset, length;
int eid;
u_int16_t ofrefnum;
u_int8_t flags;
} else
return AFPERR_PARAM;
- memcpy(&offset, ibuf, sizeof( offset ));
- offset = ntohl(offset);
- ibuf += sizeof(offset);
-
- memcpy(&length, ibuf, sizeof( length ));
- length = ntohl(length);
- if (length == 0xFFFFFFFF)
- length = BYTELOCK_MAX;
- else if (length <= 0) {
- return AFPERR_PARAM;
- } else if ((length >= AD_FILELOCK_BASE) &&
- (ad_hfileno(ofork->of_ad) == -1))
- return AFPERR_LOCK;
+ offset = get_off_t(&ibuf, is64);
+ length = get_off_t(&ibuf, is64);
+ if (is64) {
+ if (length == -1)
+ length = BYTELOCK_MAXL;
+ else if (length <= 0) {
+ return AFPERR_PARAM;
+ } else if ((length >= AD_FILELOCK_BASE) &&
+ (ad_hfileno(ofork->of_ad) == -1)) {
+ return AFPERR_LOCK;
+ }
+ }
+ else {
+ if (length == 0xFFFFFFFF)
+ length = BYTELOCK_MAX;
+ else if (!length || (length & (1 << 31))) {
+ return AFPERR_PARAM;
+ } else if ((length >= AD_FILELOCK_BASE) &&
+ (ad_hfileno(ofork->of_ad) == -1)) {
+ return AFPERR_LOCK;
+ }
+ }
+
if (ENDBIT(flags))
offset += ad_size(ofork->of_ad, eid);
break;
}
}
-
- offset = htonl(offset);
- memcpy(rbuf, &offset, sizeof( offset ));
- *rbuflen = sizeof( offset );
+ *rbuflen = set_off_t (offset, rbuf, is64);
return( AFP_OK );
}
-#undef UNLOCKBIT
+/* --------------------------- */
+int afp_bytelock(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj;
+char *ibuf, *rbuf;
+int ibuflen, *rbuflen;
+{
+ return byte_lock ( obj, ibuf, ibuflen, rbuf, rbuflen , 0);
+}
+/* --------------------------- */
+int afp_bytelock_ext(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj;
+char *ibuf, *rbuf;
+int ibuflen, *rbuflen;
+{
+ return byte_lock ( obj, ibuf, ibuflen, rbuf, rbuflen , 1);
+}
+
+#undef UNLOCKBIT
+
+/* --------------------------- */
static __inline__ int crlf( of )
struct ofork *of;
{
*
* with dsi, should we check that reqcount < server quantum?
*/
-int afp_read(obj, ibuf, ibuflen, rbuf, rbuflen)
+static int read_fork(obj, ibuf, ibuflen, rbuf, rbuflen, is64)
AFPObj *obj;
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
+int is64;
{
struct ofork *ofork;
off_t size;
- int32_t offset, saveoff, reqcount, savereqcount;
+ off_t offset, saveoff, reqcount, savereqcount;
int cc, err, eid, xlate = 0;
u_int16_t ofrefnum;
u_char nlmask, nlchar;
-
+
ibuf += 2;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
ibuf += sizeof( u_short );
err = AFPERR_ACCESS;
goto afp_read_err;
}
+ offset = get_off_t(&ibuf, is64);
+ reqcount = get_off_t(&ibuf, is64);
- memcpy(&offset, ibuf, sizeof( offset ));
- offset = ntohl( offset );
- ibuf += sizeof( offset );
- memcpy(&reqcount, ibuf, sizeof( reqcount ));
- reqcount = ntohl( reqcount );
- ibuf += sizeof( reqcount );
-
- nlmask = *ibuf++;
- nlchar = *ibuf++;
-
+ if (is64) {
+ nlmask = nlchar = 0;
+ }
+ else {
+ nlmask = *ibuf++;
+ nlchar = *ibuf++;
+ }
/* if we wanted to be picky, we could add in the following
* bit: if (afp_version == 11 && !(nlmask == 0xFF || !nlmask))
*/
if (obj->options.flags & OPTION_DEBUG) {
printf( "(read) reply: %d/%d, %d\n", *rbuflen,
- reqcount, dsi->clientID);
+ (int) reqcount, dsi->clientID);
bprint(rbuf, *rbuflen);
}
/* subtract off the offset */
return err;
}
+/* ---------------------- */
+int afp_read(obj, ibuf, ibuflen, rbuf, rbuflen)
+AFPObj *obj;
+char *ibuf, *rbuf;
+int ibuflen, *rbuflen;
+{
+ return read_fork(obj, ibuf, ibuflen, rbuf, rbuflen, 0);
+}
+
+/* ---------------------- */
+int afp_read_ext(obj, ibuf, ibuflen, rbuf, rbuflen)
+AFPObj *obj;
+char *ibuf, *rbuf;
+int ibuflen, *rbuflen;
+{
+ return read_fork(obj, ibuf, ibuflen, rbuf, rbuflen, 1);
+}
+
+/* ---------------------- */
int afp_flush(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
struct ofork *ofork;
{
struct timeval tv;
- int len, err = 0, doflush = 0;
+
+ int err = 0, doflush = 0;
if ( ad_dfileno( ofork->of_ad ) != -1 &&
fsync( ad_dfileno( ofork->of_ad )) < 0 ) {
err = -1;
}
- if ( ad_hfileno( ofork->of_ad ) != -1 ) {
+ if ( ad_hfileno( ofork->of_ad ) != -1 &&
+ (ofork->of_flags & AFPFORK_RSRC)) {
/* read in the rfork length */
- len = ad_getentrylen(ofork->of_ad, ADEID_RFORK);
ad_refresh(ofork->of_ad);
/* set the date if we're dirty */
- if ((ofork->of_flags & AFPFORK_DIRTY) &&
- (gettimeofday(&tv, NULL) == 0)) {
+ if ((ofork->of_flags & AFPFORK_DIRTY) && !gettimeofday(&tv, NULL)) {
ad_setdate(ofork->of_ad, AD_DATE_MODIFY|AD_DATE_UNIX, tv.tv_sec);
ofork->of_flags &= ~AFPFORK_DIRTY;
doflush++;
}
- /* if we're actually flushing this fork, make sure to set the
- * length. otherwise, just use the stored length */
- if ((ofork->of_flags & AFPFORK_RSRC) &&
- (len != ad_getentrylen(ofork->of_ad, ADEID_RFORK))) {
- ad_setentrylen(ofork->of_ad, ADEID_RFORK, len);
- doflush++;
- }
-
-
- /* flush the header (if it is a resource fork) */
- if (ofork->of_flags & AFPFORK_RSRC)
- if (doflush && (ad_flush(ofork->of_ad, ADFLAGS_HF) < 0))
+ /* flush the header */
+ if (doflush && ad_flush(ofork->of_ad, ADFLAGS_HF) < 0)
err = -1;
if (fsync( ad_hfileno( ofork->of_ad )) < 0)
{
struct ofork *ofork;
struct timeval tv;
- int adflags, aint, doflush = 0;
+ int adflags, doflush = 0;
u_int16_t ofrefnum;
*rbuflen = 0;
if ( ad_hfileno( ofork->of_ad ) != -1 ) {
adflags |= ADFLAGS_HF;
-
- aint = ad_getentrylen( ofork->of_ad, ADEID_RFORK );
- ad_refresh( ofork->of_ad );
- if ((ofork->of_flags & AFPFORK_DIRTY) &&
- (gettimeofday(&tv, NULL) == 0)) {
- ad_setdate(ofork->of_ad, AD_DATE_MODIFY | AD_DATE_UNIX,
- tv.tv_sec);
- doflush++;
- }
-
/*
* Only set the rfork's length if we're closing the rfork.
*/
- if ((ofork->of_flags & AFPFORK_RSRC) && aint !=
- ad_getentrylen( ofork->of_ad, ADEID_RFORK )) {
- ad_setentrylen( ofork->of_ad, ADEID_RFORK, aint );
- doflush++;
- }
- if ( doflush ) {
- ad_flush( ofork->of_ad, adflags );
+ if ((ofork->of_flags & AFPFORK_RSRC)) {
+ ad_refresh( ofork->of_ad );
+ if ((ofork->of_flags & AFPFORK_DIRTY) &&
+ !gettimeofday(&tv, NULL)) {
+ ad_setdate(ofork->of_ad, AD_DATE_MODIFY | AD_DATE_UNIX,tv.tv_sec);
+ doflush++;
+ }
+ if ( doflush ) {
+ ad_flush( ofork->of_ad, adflags );
+ }
}
}
/* FPWrite. NOTE: on an error, we always use afp_write_err as
* the client may have sent us a bunch of data that's not reflected
* in reqcount et al. */
-int afp_write(obj, ibuf, ibuflen, rbuf, rbuflen)
+static int write_fork(obj, ibuf, ibuflen, rbuf, rbuflen, is64)
AFPObj *obj;
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
+int is64;
{
struct ofork *ofork;
- int32_t offset, saveoff, reqcount;
+ off_t offset, saveoff, reqcount;
int endflag, eid, xlate = 0, err = AFP_OK;
u_int16_t ofrefnum;
ssize_t cc;
ibuf++;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
ibuf += sizeof( ofrefnum );
- memcpy(&offset, ibuf, sizeof( offset ));
- offset = ntohl( offset );
- ibuf += sizeof( offset );
- memcpy(&reqcount, ibuf, sizeof( reqcount ));
- reqcount = ntohl( reqcount );
- ibuf += sizeof( reqcount );
+
+ offset = get_off_t(&ibuf, is64);
+ reqcount = get_off_t(&ibuf, is64);
if (( ofork = of_find( ofrefnum )) == NULL ) {
LOG(log_error, logtype_afpd, "afp_write: of_find");
if (!reqcount) { /* handle request counts of 0 */
err = AFP_OK;
- offset = htonl(offset);
- memcpy(rbuf, &offset, sizeof(offset));
+ *rbuflen = set_off_t (offset, rbuf, is64);
goto afp_write_err;
}
if ( ad_hfileno( ofork->of_ad ) != -1 )
ofork->of_flags |= AFPFORK_DIRTY;
- offset = htonl( offset );
-#if defined(__GNUC__) && defined(HAVE_GCC_MEMCPY_BUG)
- bcopy(&offset, rbuf, sizeof(offset));
-#else /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
- memcpy(rbuf, &offset, sizeof(offset));
-#endif /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
- *rbuflen = sizeof(offset);
+ *rbuflen = set_off_t (offset, rbuf, is64);
return( AFP_OK );
afp_write_err:
return err;
}
+/* ---------------------------- */
+int afp_write(obj, ibuf, ibuflen, rbuf, rbuflen)
+AFPObj *obj;
+char *ibuf, *rbuf;
+int ibuflen, *rbuflen;
+{
+ return write_fork(obj, ibuf, ibuflen, rbuf, rbuflen, 0);
+}
+
+/* ---------------------------- */
+int afp_write_ext(obj, ibuf, ibuflen, rbuf, rbuflen)
+AFPObj *obj;
+char *ibuf, *rbuf;
+int ibuflen, *rbuflen;
+{
+ return write_fork(obj, ibuf, ibuflen, rbuf, rbuflen, 1);
+}
+/* ---------------------------- */
int afp_getforkparams(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
attrbits = ((ofork->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
attrbits |= ((ofork->of_ad->ad_hf.adf_refcount > ofork->of_ad->ad_df.adf_refcount) ? ATTRBIT_ROPEN : 0);
+ if ( ad_hfileno( ofork->of_ad ) != -1 ) {
+ if ( ad_refresh( ofork->of_ad ) < 0 ) {
+ LOG(log_error, logtype_afpd, "getforkparams: ad_refresh: %s", strerror(errno) );
+ return( AFPERR_PARAM );
+ }
+ }
+
if (( ret = getforkparams( ofork, bitmap,
rbuf + sizeof( u_short ), &buflen, attrbits )) != AFP_OK ) {
return( ret );
/*
- * $Id: fork.h,v 1.5 2002-09-05 14:52:07 didg Exp $
+ * $Id: fork.h,v 1.6 2002-10-11 14:18:34 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
struct stat *));
extern void of_dealloc __P((struct ofork *));
extern struct ofork *of_find __P((const u_int16_t));
-extern struct ofork *of_findname __P((const char *, struct stat *));
+extern struct ofork *of_findname __P((struct path *));
extern int of_rename __P((const struct vol *,
struct ofork *,
struct dir *, const char *,
struct dir *, const char *));
extern int of_flush __P((const struct vol *));
extern void of_pforkdesc __P((FILE *));
-
+extern int of_stat __P((struct path *));
/* in fork.c */
extern int flushfork __P((struct ofork *));
extern int afp_flush __P((AFPObj *, char *, int, char *, int *));
extern int afp_closefork __P((AFPObj *, char *, int, char *, int *));
+extern int afp_bytelock_ext __P((AFPObj *, char *, int, char *, int *));
+extern int afp_read_ext __P((AFPObj *, char *, int, char *, int *));
+extern int afp_write_ext __P((AFPObj *, char *, int, char *, int *));
#endif
/*
- * $Id: ofork.c,v 1.19 2002-09-06 02:57:49 didg Exp $
+ * $Id: ofork.c,v 1.20 2002-10-11 14:18:34 didg Exp $
*
* Copyright (c) 1996 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return( oforks[ ofrefnum % nforks ] );
}
-/* --------------------------
-*/
+/* -------------------------- */
+int of_stat (struct path *path)
+{
+int ret;
+ path->st_errno = 0;
+ path->st_valid = 1;
+ if ((ret = stat(path->u_name, &path->st)) < 0)
+ path->st_errno = errno;
+ return ret;
+}
+
+
+/* -------------------------- */
struct ofork *
- of_findname(const char *name, struct stat *st)
+ of_findname(struct path *path)
{
struct ofork *of;
struct file_key key;
- struct stat buffer;
- char *p;
- if (st == NULL) {
- st = &buffer;
- if (stat(name, st) < 0)
- return NULL;
+ if (!path->st_valid) {
+ of_stat(path);
}
- key.dev = st->st_dev;
- key.inode = st->st_ino;
+
+ if (path->st_errno)
+ return NULL;
+
+ key.dev = path->st.st_dev;
+ key.inode = path->st.st_ino;
for (of = ofork_table[hashfn(&key)]; of; of = of->next) {
if (key.dev == of->key.dev && key.inode == of->key.inode ) {
/*
- * $Id: volume.c,v 1.37 2002-10-10 20:27:36 jmarcus Exp $
+ * $Id: volume.c,v 1.38 2002-10-11 14:18:35 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
LOG(log_error, logtype_afpd, "setextmap: calloc: %s", strerror(errno) );
return;
}
-
}
ext++;
for ( em = extmap, cnt = 0; em->em_ext; em++, cnt++) {
}
if (( volume->v_flags & AFPVOL_OPEN ) == 0 ) {
- if ((dir = dirnew(strlen(volume->v_name) + 1)) == NULL) {
+ /* FIXME unix name != mac name */
+ if ((dir = dirnew(volume->v_name, volume->v_name) ) == NULL) {
LOG(log_error, logtype_afpd, "afp_openvol: malloc: %s", strerror(errno) );
ret = AFPERR_MISC;
goto openvol_err;
}
dir->d_did = DIRDID_ROOT;
dir->d_color = DIRTREE_COLOR_BLACK; /* root node is black */
- strcpy( dir->d_name, volume->v_name );
volume->v_dir = volume->v_root = dir;
volume->v_flags |= AFPVOL_OPEN;
}
/*
- * $Id: adouble.h,v 1.10 2002-09-07 19:19:00 didg Exp $
+ * $Id: adouble.h,v 1.11 2002-10-11 14:18:35 didg Exp $
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
*
#ifndef _ATALK_ADOUBLE_H
#define _ATALK_ADOUBLE_H
+/* -------------------
+ * need pread() and pwrite()
+*/
+#ifdef HAVE_PREAD
+
+#ifndef HAVE_PWRITE
+#undef HAVE_PREAD
+#endif
+
+#endif
+
+#ifdef HAVE_PWRITE
+
+#ifndef HAVE_PREAD
+#undef HAVE_PWRITE
+#endif
+
+#endif
+
+#ifdef HAVE_PREAD
+#define _XOPEN_SOURCE 500
+#endif
+
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#ifdef HAVE_FLOCK
#include <sys/file.h>
#define LOCK_UN 8
extern int flock (int /*fd*/, int /*operation*/);
#endif
+
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#endif
+
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <netatalk/endian.h>
-
/* XXX: this is the wrong place to put this.
- * NOTE: as of 2.2.1, linux can't do a sendfile from a socket. */
+ * NOTE: as of 2.2.1, linux can't do a sendfile from a socket.
+ * and it doesn't have 64 bits sendfile
+ */
#ifdef SENDFILE_FLAVOR_LINUX
+
+#if _FILE_OFFSET_BITS == 64
+
+#undef SENDFILE_FLAVOR_LINUX
+
+#else
#define HAVE_SENDFILE_READ
#define HAVE_SENDFILE_WRITE
#include <asm/unistd.h>
+
#ifdef __NR_sendfile
-static inline int sendfile(int fdout, int fdin, off_t *off, size_t count)
+#ifndef ATACC
+static __inline__ int sendfile(int fdout, int fdin, off_t *off, size_t count)
{
+#if _FILE_OFFSET_BITS == 64
+ return syscall(__NR_sendfile64, fdout, fdin, off, count);
+#else
return syscall(__NR_sendfile, fdout, fdin, off, count);
+#endif
}
+#else
+extern int sendfile __P((int , int , off_t *, size_t ));
+#endif /* ATACC */
+
#else
#include <sys/sendfile.h>
#endif
#endif
+#endif /* SENDFILE_FLAVOR_LINUX */
#ifdef SENDFILE_FLAVOR_BSD
#define HAVE_SENDFILE_READ
struct ad_fd {
int adf_fd;
+
+#ifndef HAVE_PREAD
off_t adf_off;
+#endif
+
int adf_flags;
adf_lock_t *adf_lock;
int adf_refcount, adf_lockcount, adf_lockmax;
struct ad_entry ad_eid[ ADEID_MAX ];
struct ad_fd ad_df, ad_hf;
int ad_flags, ad_inited;
- int ad_refcount; /* used in afpd/ofork.c */
+ int ad_refcount; /* used in afpd/ofork.c */
+ off_t ad_rlen; /* ressource fork len with AFP 3.0
+ the header parameter size is too small.
+ */
#ifdef USE_MMAPPED_HEADERS
char *ad_data;
#else
#endif
/* ad_open.c */
-extern char *ad_dir __P((char *));
-extern char *ad_path __P((char *, int));
-extern int ad_mode __P((char *, int));
-extern int ad_mkdir __P((char *, int));
-extern int ad_open __P((char *, int, int, int, struct adouble *));
+extern char *ad_dir __P((const char *));
+extern char *ad_path __P((const char *, int));
+extern int ad_mode __P((const char *, int));
+extern int ad_mkdir __P((const char *, int));
+extern int ad_open __P((const char *, int, int, int, struct adouble *));
extern int ad_refresh __P((struct adouble *));
/* extend header to RW if R or W (W if R for locking),
*/
-static inline mode_t ad_hf_mode (mode_t mode)
+#ifndef ATACC
+static __inline__ mode_t ad_hf_mode (mode_t mode)
{
#ifndef USE_FLOCK_LOCKS
/* fnctl lock need write access */
return mode;
}
+#else
+extern mode_t ad_hf_mode __P((mode_t ));
+#endif
/* ad_read.c/ad_write.c */
extern ssize_t ad_read __P((struct adouble *, const u_int32_t,
const off_t, char *, const size_t));
+extern ssize_t ad_pread __P((struct ad_fd *, void *, size_t, off_t));
+
extern ssize_t ad_write __P((struct adouble *, const u_int32_t, off_t,
const int, const char *, const size_t));
+
+extern ssize_t adf_pread __P((struct ad_fd *, void *, size_t, off_t));
+extern ssize_t adf_pwrite __P((struct ad_fd *, const void *, size_t, off_t));
+
extern int ad_dtruncate __P((struct adouble *, const size_t));
extern int ad_rtruncate __P((struct adouble *, const size_t));
char child, inited, *commands;
char cmdbuf[ASP_CMDMAXSIZ];
char data[ASP_DATAMAXSIZ];
- int cmdlen, datalen;
+ unsigned int cmdlen, datalen;
size_t read_count, write_count;
} *ASP;
u_int32_t attn_quantum, datasize, server_quantum;
u_int16_t serverID, clientID;
u_int8_t *status, commands[DSI_CMDSIZ], data[DSI_DATASIZ];
- int statuslen, datalen, cmdlen;
+ int statuslen;
+ unsigned int datalen, cmdlen;
size_t read_count, write_count;
/* inited = initialized?, child = a child?, noreply = send reply? */
char child, inited, noreply;
extern size_t dsi_stream_write __P((DSI *, void *, const size_t));
extern size_t dsi_stream_read __P((DSI *, void *, const size_t));
extern int dsi_stream_send __P((DSI *, void *, size_t));
-extern int dsi_stream_receive __P((DSI *, void *, const int, int *));
+extern int dsi_stream_receive __P((DSI *, void *, const size_t, size_t *));
/* client writes -- dsi_write.c */
extern size_t dsi_writeinit __P((DSI *, void *, const size_t));
/*
- * $Id: ad_flush.c,v 1.4 2002-09-29 17:39:59 didg Exp $
+ * $Id: ad_flush.c,v 1.5 2002-10-11 14:18:36 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <atalk/adouble.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif /* HAVE_FCNTL_H */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#include <sys/types.h>
-#include <sys/mman.h>
#include <errno.h>
-#include <netatalk/endian.h>
-#include <atalk/adouble.h>
-
#include "ad_private.h"
/* rebuild the header */
struct adouble *ad;
int adflags;
{
-#ifndef USE_MMAPPED_HEADERS
int len;
-#endif /* ! USE_MMAPPED_HEADERS */
if (( adflags & ADFLAGS_HF ) && ( ad->ad_hf.adf_flags & O_RDWR )) {
/* sync our header */
+ if (ad->ad_rlen > 0xffffffff) {
+ ad_setentrylen(ad, ADEID_RFORK, 0xffffffff);
+ }
+ else {
+ ad_setentrylen(ad, ADEID_RFORK, ad->ad_rlen);
+ }
ad_rebuild_header(ad);
-
-#ifdef USE_MMAPPED_HEADERS
- /* now sync it */
-#ifdef MS_SYNC
- msync(ad->ad_data, ad_getentryoff(ad, ADEID_RFORK),
- MS_SYNC | MS_INVALIDATE);
-#else
- msync(ad->ad_data, ad_getentryoff(ad, ADEID_RFORK));
-#endif /* MS_SYNC */
-
-#else /* USE_MMAPPED_HEADERS */
- if ( ad->ad_hf.adf_off != 0 ) {
- if ( lseek( ad->ad_hf.adf_fd, 0L, SEEK_SET ) < 0L ) {
- return( -1 );
- }
- ad->ad_hf.adf_off = 0;
- }
-
- /* now flush it out */
len = ad_getentryoff(ad, ADEID_RFORK);
- if (write( ad->ad_hf.adf_fd, ad->ad_data, len) != len) {
+ /* now flush it out */
+ if (adf_pwrite(&ad->ad_hf, ad->ad_data, len, 0) != len) {
if ( errno == 0 ) {
errno = EIO;
}
return( -1 );
}
- ad->ad_hf.adf_off = len;
-#endif /* USE_MMAPPED_HEADERS */
}
return( 0 );
int err = 0;
if (( adflags & ADFLAGS_DF ) && ad->ad_df.adf_fd != -1 &&
- !(--ad->ad_df.adf_refcount)) {
+ !(--ad->ad_df.adf_refcount)) {
if ( close( ad->ad_df.adf_fd ) < 0 ) {
err = -1;
}
}
if (( adflags & ADFLAGS_HF ) && ad->ad_hf.adf_fd != -1 &&
- !(--ad->ad_hf.adf_refcount)) {
-#ifdef USE_MMAPPED_HEADERS
- if (ad->ad_data != MAP_FAILED)
- munmap(ad->ad_data, ad_getentryoff(ad, ADEID_RFORK));
-#endif /* USE_MMAPPED_HEADERS */
+ !(--ad->ad_hf.adf_refcount)) {
if ( close( ad->ad_hf.adf_fd ) < 0 ) {
err = -1;
}
/*
- * $Id: ad_open.c,v 1.20 2002-10-10 20:27:36 jmarcus Exp $
+ * $Id: ad_open.c,v 1.21 2002-10-11 14:18:37 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
* Copyright (c) 1990,1991 Regents of The University of Michigan.
off = ad->ad_eid[ADEID_RFORK].ade_off;
-#ifdef USE_MMAPPED_HEADERS
- /* okay, unmap our old ad header and point it to our local copy */
- munmap(ad->ad_data, off);
- ad->ad_data = buf;
-#endif /* USER_MMAPPED_HEADERS */
-
/* move the RFORK. this assumes that the RFORK is at the end */
memmove(buf + off + SHIFTDATA, buf + off,
ad->ad_eid[ADEID_RFORK].ade_len);
close(fd);
ad_tmplock(ad, ADEID_RFORK, ADLOCK_CLR, 0, 0);
-#ifdef USE_MMAPPED_HEADERS
- /* now remap our header */
- ad->ad_data = mmap(NULL, ADEDOFF_RFORK_V2, PROT_READ | PROT_WRITE,
- (ad_getoflags(ad, ADFLAGS_HF) & O_RDWR) ? MAP_SHARED :
- MAP_PRIVATE, ad->ad_hf.adf_fd, 0);
- if (ad->ad_data == MAP_FAILED)
- goto bail_err;
-#endif /* USE_MMAPPED_HEADERS */
-
return 0;
bail_truncate:
}
#endif /* AD_VERSION == AD_VERSION2 */
+#ifdef ATACC
+mode_t ad_hf_mode (mode_t mode)
+{
+#ifndef USE_FLOCK_LOCKS
+ /* fnctl lock need write access */
+ if ((mode & S_IRUSR))
+ mode |= S_IWUSR;
+ if ((mode & S_IRGRP))
+ mode |= S_IWGRP;
+ if ((mode & S_IROTH))
+ mode |= S_IWOTH;
+#endif
+ /* if write mode set add read mode */
+ if ((mode & S_IWUSR))
+ mode |= S_IRUSR;
+ if ((mode & S_IWGRP))
+ mode |= S_IRGRP;
+ if ((mode & S_IWOTH))
+ mode |= S_IROTH;
+
+ return mode;
+}
+
+#endif
-/* read in the entries */
-static __inline__ void parse_entries(struct adouble *ad, char *buf,
+/* -------------------------------------
+ read in the entries
+*/
+static void parse_entries(struct adouble *ad, char *buf,
u_int16_t nentries)
{
u_int32_t eid, len, off;
* NOTE: we're assuming that the resource fork is kept at the end of
* the file. also, mmapping won't work for the hfs fs until it
* understands how to mmap header files. */
-static __inline__ int ad_header_read(struct adouble *ad)
+static int ad_header_read(struct adouble *ad, struct stat *hst)
{
-#ifdef USE_MMAPPED_HEADERS
- char buf[AD_ENTRY_LEN*ADEID_MAX];
-#else /* USE_MMAPPED_HEADERS */
char *buf = ad->ad_data;
-#endif /* USE_MMAPPED_HEADERS */
u_int16_t nentries;
int len;
+ ssize_t header_len;
static int warning = 0;
+ struct stat st;
/* read the header */
- if ( ad->ad_hf.adf_off != 0 ) {
- if ( lseek( ad->ad_hf.adf_fd, 0L, SEEK_SET ) < 0L ) {
- return( -1 );
- }
- ad->ad_hf.adf_off = 0;
+ if ((header_len = adf_pread( &ad->ad_hf, buf, sizeof(ad->ad_data), 0)) < 0) {
+ return -1;
}
-
- if (read( ad->ad_hf.adf_fd, buf, AD_HEADER_LEN) != AD_HEADER_LEN) {
- if ( errno == 0 ) {
- errno = EIO;
- }
- return( -1 );
+ if (header_len < AD_HEADER_LEN) {
+ errno = EIO;
+ return -1;
}
- ad->ad_hf.adf_off = AD_HEADER_LEN;
memcpy(&ad->ad_magic, buf, sizeof( ad->ad_magic ));
- memcpy(&ad->ad_version, buf + ADEDOFF_VERSION,
- sizeof( ad->ad_version ));
+ memcpy(&ad->ad_version, buf + ADEDOFF_VERSION, sizeof( ad->ad_version ));
/* tag broken v1 headers. just assume they're all right.
* we detect two cases: null magic/version
ad->ad_magic = AD_MAGIC;
ad->ad_version = AD_VERSION1;
- } else if ((ad->ad_magic == AD_MAGIC) &&
- (ad->ad_version == AD_VERSION1)) {
+ } else if (ad->ad_magic == AD_MAGIC && ad->ad_version == AD_VERSION1) {
if (!warning) {
LOG(log_debug, logtype_default, "notice: fixing up byte-swapped v1 magic/version.");
warning++;
/* read in all the entry headers. if we have more than the
* maximum, just hope that the rfork is specified early on. */
len = nentries*AD_ENTRY_LEN;
-#ifdef USE_MMAPPED_HEADERS
- if (len > sizeof(buf))
- len = sizeof(buf);
-#else /* USE_MMAPPED_HEADERS */
+
if (len + AD_HEADER_LEN > sizeof(ad->ad_data))
len = sizeof(ad->ad_data) - AD_HEADER_LEN;
+
buf += AD_HEADER_LEN;
-#endif /* USE_MMAPPED_HEADERS */
- if (read(ad->ad_hf.adf_fd, buf, len) != len) {
- if (errno == 0)
- errno = EIO;
+ if (len > header_len - AD_HEADER_LEN) {
+ errno = EIO;
LOG(log_debug, logtype_default, "ad_header_read: can't read entry info.");
return -1;
}
- ad->ad_hf.adf_off += len;
/* figure out all of the entry offsets and lengths. if we aren't
* able to read a resource fork entry, bail. */
parse_entries(ad, buf, nentries);
if (!ad_getentryoff(ad, ADEID_RFORK)
-#ifndef USE_MMAPPED_HEADERS
|| (ad_getentryoff(ad, ADEID_RFORK) > sizeof(ad->ad_data))
-#endif /* ! USE_MMAPPED_HEADERS */
) {
LOG(log_debug, logtype_default, "ad_header_read: problem with rfork entry offset.");
return -1;
}
- /* read/mmap up to the beginning of the resource fork. */
-#ifdef USE_MMAPPED_HEADERS
- ad->ad_data = mmap(NULL, ad_getentryoff(ad, ADEID_RFORK),
- PROT_READ | PROT_WRITE,
- (ad_getoflags(ad, ADFLAGS_HF) & O_RDWR) ? MAP_SHARED :
- MAP_PRIVATE, ad->ad_hf.adf_fd, 0);
- if (ad->ad_data == MAP_FAILED)
- return -1;
-#else /* USE_MMAPPED_HEADERS */
- buf += len;
- len = ad_getentryoff(ad, ADEID_RFORK) - ad->ad_hf.adf_off;
- if (read(ad->ad_hf.adf_fd, buf, len) != len) {
- if (errno == 0)
- errno = EIO;
+ if (ad_getentryoff(ad, ADEID_RFORK) > header_len) {
+ errno = EIO;
LOG(log_debug, logtype_default, "ad_header_read: can't read in entries.");
return -1;
}
-#endif /* USE_MMAPPED_HEADERS */
+ if (hst == NULL) {
+ hst = &st;
+ if (fstat(ad->ad_hf.adf_fd, &st) < 0) {
+ return 1; /* fail silently */
+ }
+ }
+ ad->ad_rlen = hst->st_size - ad_getentryoff(ad, ADEID_RFORK);
+
/* fix up broken dates */
if (ad->ad_version == AD_VERSION1) {
- struct stat st;
u_int32_t aint;
- if (fstat(ad->ad_hf.adf_fd, &st) < 0) {
- return 1; /* fail silently */
- }
-
/* check to see if the ad date is wrong. just see if we have
* a modification date in the future. */
if (((ad_getdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, &aint)) == 0) &&
- (aint > TIMEWARP_DELTA + st.st_mtime)) {
+ (aint > TIMEWARP_DELTA + hst->st_mtime)) {
ad_setdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, aint - AD_DATE_DELTA);
ad_getdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, &aint);
ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, aint - AD_DATE_DELTA);
*/
char *
ad_path( path, adflags )
- char *path;
+ const char *path;
int adflags;
{
static char pathbuf[ MAXPATHLEN + 1];
char
*ad_dir(path)
- char *path;
+ const char *path;
{
static char modebuf[ MAXPATHLEN + 1];
char *slash;
int
ad_mode( path, mode )
- char *path;
+ const char *path;
int mode;
{
struct stat stbuf;
*/
int
ad_mkdir( path, mode )
- char *path;
+ const char *path;
int mode;
{
#ifdef DEBUG
}
+static int new_rfork(const char *path, struct adouble *ad, int adflags);
+
+#ifdef HAVE_PREAD
+#define AD_SET(a)
+#else
+#define AD_SET(a) a = 0
+#endif
/*
* It's not possible to open the header file O_RDONLY -- the read
* will fail and return an error. this refcounts things now.
*/
int ad_open( path, adflags, oflags, mode, ad )
- char *path;
+ const char *path;
int adflags, oflags, mode;
struct adouble *ad;
{
- const struct entry *eid;
struct stat st;
char *slash, *ad_p;
int hoflags, admode;
- u_int16_t ashort;
if (ad->ad_inited != AD_INITED) {
ad_dfileno(ad) = -1;
ad_hfileno(ad) = -1;
adf_lock_init(&ad->ad_df);
adf_lock_init(&ad->ad_hf);
-#ifdef USE_MMAPPED_HEADERS
- ad->ad_data = MAP_FAILED;
-#endif /* USE_MMAPPED_HEADERS */
ad->ad_inited = AD_INITED;
ad->ad_refcount = 1;
}
- if (adflags & ADFLAGS_DF) {
+ if ((adflags & ADFLAGS_DF)) {
if (ad_dfileno(ad) == -1) {
hoflags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
admode = ad_mode( path, mode );
}
}
if ( ad->ad_df.adf_fd < 0)
- return -1;
- ad->ad_df.adf_off = 0;
+ return -1;
+
+ AD_SET(ad->ad_df.adf_off);
ad->ad_df.adf_flags = hoflags;
}
else {
ad->ad_df.adf_refcount++;
}
- if (adflags & ADFLAGS_HF) {
- if (ad_hfileno(ad) == -1) {
- ad_p = ad_path( path, adflags );
-
- hoflags = oflags & ~O_CREAT;
- hoflags = (hoflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
- if (( ad->ad_hf.adf_fd = open( ad_p, hoflags, 0 )) < 0 ) {
- if (errno == EACCES && !(oflags & O_RDWR)) {
- hoflags = oflags & ~O_CREAT;
- ad->ad_hf.adf_fd = open( ad_p, hoflags, 0 );
- }
- }
- if ( ad->ad_hf.adf_fd < 0 ) {
- if (errno == ENOENT && (oflags & O_CREAT) ) {
- /*
- * We're expecting to create a new adouble header file,
- * here.
- * if ((oflags & O_CREAT) ==> (oflags & O_RDWR)
- */
- admode = ad_hf_mode(ad_mode( ad_p, mode ));
- errno = 0;
- if (( ad->ad_hf.adf_fd = open( ad_p, oflags,
- admode )) < 0 ) {
+ if (!(adflags & ADFLAGS_HF))
+ return 0;
+
+ if (ad_hfileno(ad) != -1) { /* the file is already open */
+ if ((oflags & ( O_RDWR | O_WRONLY)) &&
+ !(ad->ad_hf.adf_flags & ( O_RDWR | O_WRONLY))) {
+ if (adflags & ADFLAGS_DF) {
+ /* don't call with ADFLAGS_HF because we didn't open ressource fork */
+ ad_close( ad, ADFLAGS_DF );
+ }
+ errno == EACCES;
+ return -1;
+ }
+ ad_refresh(ad);
+ ad->ad_hf.adf_refcount++;
+ return 0;
+ }
+
+ ad_p = ad_path( path, adflags );
+
+ hoflags = oflags & ~O_CREAT;
+ hoflags = (hoflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
+ if (( ad->ad_hf.adf_fd = open( ad_p, hoflags, 0 )) < 0 ) {
+ if (errno == EACCES && !(oflags & O_RDWR)) {
+ hoflags = oflags & ~O_CREAT;
+ ad->ad_hf.adf_fd = open( ad_p, hoflags, 0 );
+ }
+ }
+
+ if ( ad->ad_hf.adf_fd < 0 ) {
+ if (errno == ENOENT && (oflags & O_CREAT) ) {
+ /*
+ * We're expecting to create a new adouble header file,
+ * here.
+ * if ((oflags & O_CREAT) ==> (oflags & O_RDWR)
+ */
+ admode = ad_hf_mode(ad_mode( ad_p, mode ));
+ errno = 0;
+ if (( ad->ad_hf.adf_fd = open( ad_p, oflags,admode )) < 0 ) {
/*
* Probably .AppleDouble doesn't exist, try to
* mkdir it.
*/
- if ((errno == ENOENT) &&
- ((adflags & ADFLAGS_NOADOUBLE) == 0)) {
- if (( slash = strrchr( ad_p, '/' )) == NULL ) {
- ad_close( ad, adflags );
- return( -1 );
- }
- *slash = '\0';
- errno = 0;
- if ( ad_mkdir( ad_p, 0777 ) < 0 ) {
- ad_close( ad, adflags );
- return( -1 );
- }
- *slash = '/';
- if (( ad->ad_hf.adf_fd =
- open( ad_p, oflags, ad_mode( ad_p, mode) )) < 0 ) {
- ad_close( ad, adflags );
- return( -1 );
- }
+ if (errno == ENOENT && (adflags & ADFLAGS_NOADOUBLE) == 0) {
+ if (( slash = strrchr( ad_p, '/' )) == NULL ) {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
+ *slash = '\0';
+ errno = 0;
+ if ( ad_mkdir( ad_p, 0777 ) < 0 ) {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
+ *slash = '/';
+ if (( ad->ad_hf.adf_fd =
+ open( ad_p, oflags, ad_mode( ad_p, mode) )) < 0 ) {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
} else {
ad_close( ad, adflags );
return( -1 );
}
- }
- ad->ad_hf.adf_flags = oflags;
- } else {
- ad_close( ad, adflags );
- return( -1 );
}
- } else if ((fstat(ad->ad_hf.adf_fd, &st) == 0) &&
- (st.st_size == 0)) {
- /* for 0 length files, treat them as new. */
- ad->ad_hf.adf_flags = (oflags & ~O_RDONLY) | O_RDWR;
- } else {
- ad->ad_hf.adf_flags = hoflags;
- }
- ad->ad_hf.adf_off = 0;
+ ad->ad_hf.adf_flags = oflags;
+ } else {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
+ } else if (fstat(ad->ad_hf.adf_fd, &st) == 0 && st.st_size == 0) {
+ /* for 0 length files, treat them as new. */
+ ad->ad_hf.adf_flags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR | O_TRUNC;
+ } else {
+ ad->ad_hf.adf_flags = hoflags;
+ }
+ AD_SET(ad->ad_hf.adf_off);
- /*
- * This is a new adouble header file. Initialize the structure,
- * instead of reading it.
- */
- memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
- if ( ad->ad_hf.adf_flags & ( O_TRUNC | O_CREAT )) {
- struct stat st;
-
- ad->ad_magic = AD_MAGIC;
- ad->ad_version = AD_VERSION;
- memset(ad->ad_filler, 0, sizeof( ad->ad_filler ));
-
-#ifdef USE_MMAPPED_HEADERS
- /* truncate the header file and mmap it. */
- ftruncate(ad->ad_hf.adf_fd, AD_DATASZ);
- ad->ad_data = mmap(NULL, AD_DATASZ, PROT_READ | PROT_WRITE,
- MAP_SHARED, ad->ad_hf.adf_fd, 0);
- if (ad->ad_data == MAP_FAILED) {
- ad_close(ad, adflags);
- return -1;
- }
-#else /* USE_MMAPPED_HEADERS */
- memset(ad->ad_data, 0, sizeof(ad->ad_data));
-#endif /* USE_MMAPPED_HEADERS */
-
- eid = entry_order;
- while (eid->id) {
- ad->ad_eid[eid->id].ade_off = eid->offset;
- ad->ad_eid[eid->id].ade_len = eid->len;
- eid++;
- }
-
- /* put something sane in the directory finderinfo */
- if (adflags & ADFLAGS_DIR) {
- /* set default view */
- ashort = htons(FINDERINFO_CLOSEDVIEW);
- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRVIEWOFF,
- &ashort, sizeof(ashort));
- } else {
- /* set default creator/type fields */
- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRTYPEOFF,
- "TEXT", 4);
- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRCREATOFF,
- "UNIX", 4);
- }
+ memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
+ if ((ad->ad_hf.adf_flags & ( O_TRUNC | O_CREAT ))) {
+ /*
+ * This is a new adouble header file. Initialize the structure,
+ * instead of reading it.
+ */
+ if (new_rfork(path, ad, adflags) < 0) {
+ ad_close(ad, adflags);
+ return -1;
+ }
+ } else {
+ /* Read the adouble header in and parse it.*/
+ if ((ad_header_read( ad , &st) < 0)
+#if AD_VERSION == AD_VERSION2
+ || (ad_v1tov2(ad, ad_p) < 0)
+#endif /* AD_VERSION == AD_VERSION2 */
+ ) {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
+ }
+ ad->ad_hf.adf_refcount++;
+ return 0 ;
+}
- /* make things invisible */
- if ((*path == '.') && strcmp(path, ".") && strcmp(path, "..")) {
- ashort = htons(ATTRBIT_INVISIBLE);
- ad_setattr(ad, ashort);
- ashort = htons(FINDERINFO_INVISIBLE);
- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,
- &ashort, sizeof(ashort));
- }
+/* ----------------------------------- */
+static int new_rfork(const char *path, struct adouble *ad, int adflags)
+{
+#if 0
+ struct timeval tv;
+#endif
+ const struct entry *eid;
+ u_int16_t ashort;
+ struct stat st;
- /*if (gettimeofday(&tv, NULL) < 0) {
- ad_close(ad, adflags);
- return -1;
- }*/
+ ad->ad_magic = AD_MAGIC;
+ ad->ad_version = AD_VERSION;
- if (stat(path, &st) < 0) {
- ad_close(ad, adflags);
- return -1;
- }
+ memset(ad->ad_filler, 0, sizeof( ad->ad_filler ));
+ memset(ad->ad_data, 0, sizeof(ad->ad_data));
+
+ eid = entry_order;
+ while (eid->id) {
+ ad->ad_eid[eid->id].ade_off = eid->offset;
+ ad->ad_eid[eid->id].ade_len = eid->len;
+ eid++;
+ }
- /* put something sane in the date fields */
- ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime);
- ad_setdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime);
- ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
- ad_setdate(ad, AD_DATE_BACKUP, AD_DATE_START);
+ /* put something sane in the directory finderinfo */
+ if (adflags & ADFLAGS_DIR) {
+ /* set default view */
+ ashort = htons(FINDERINFO_CLOSEDVIEW);
+ memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRVIEWOFF,
+ &ashort, sizeof(ashort));
+ } else {
+ /* set default creator/type fields */
+ memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRTYPEOFF,"TEXT", 4);
+ memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRCREATOFF,"UNIX", 4);
+ }
- } else {
- /*
- * Read the adouble header in and parse it.
- */
- if ((ad_header_read( ad ) < 0)
-#if AD_VERSION == AD_VERSION2
- || (ad_v1tov2(ad, ad_p) < 0)
-#endif /* AD_VERSION == AD_VERSION2 */
- ) {
- ad_close( ad, adflags );
- return( -1 );
- }
- }
- }
- else { /* already open */
- if ((oflags & ( O_RDWR | O_WRONLY)) &&
- !(ad->ad_hf.adf_flags & ( O_RDWR | O_WRONLY))) {
- if (adflags & ADFLAGS_DF) {
- /* don't call with ADFLAGS_HF because we didn't open ressource fork */
- ad_close( ad, ADFLAGS_DF );
- }
- errno == EACCES;
- return -1;
- }
- }
- ad->ad_hf.adf_refcount++;
+ /* make things invisible */
+ if ((*path == '.') && strcmp(path, ".") && strcmp(path, "..")) {
+ ashort = htons(ATTRBIT_INVISIBLE);
+ ad_setattr(ad, ashort);
+ ashort = htons(FINDERINFO_INVISIBLE);
+ memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,
+ &ashort, sizeof(ashort));
+ }
+
+#if 0
+ if (gettimeofday(&tv, NULL) < 0) {
+ return -1;
+ }
+#endif
+
+ if (stat(path, &st) < 0) {
+ return -1;
}
-
- return( 0 );
+
+ /* put something sane in the date fields */
+ ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime);
+ ad_setdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime);
+ ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
+ ad_setdate(ad, AD_DATE_BACKUP, AD_DATE_START);
+ return 0;
}
/* to do this with mmap, we need the hfs fs to understand how to mmap
header files. */
int ad_refresh(struct adouble *ad)
{
-#ifdef USE_MMAPPED_HEADERS
- off_t off;
-#endif /* USE_MMAPPED_HEADERS */
if (ad->ad_hf.adf_fd < -1)
return -1;
-#ifdef USE_MMAPPED_HEADERS
- if (ad->ad_data == MAP_FAILED)
- return -1;
-
- /* re-read the header */
- off = ad_getentryoff(ad, ADEID_RFORK);
- memcpy(&nentries, ad->ad_data + ADEDOFF_NENTRIES, sizeof(nentries));
- nentries = ntohs(nentries);
- parse_entries(ad, ad->ad_data + AD_HEADER_LEN, nentries);
-
- /* check to see if something screwy happened */
- if (!ad_getentryoff(ad, ADEID_RFORK))
- return -1;
-
- /* if there's a length discrepancy, remap the header. this shouldn't
- * really ever happen. */
- if (off != ad_getentryoff(ad, ADEID_RFORK)) {
- char *buf = ad->ad_data;
- buf = ad->ad_data;
- ad->ad_data = mmap(NULL, ad_getentryoff(ad, ADEID_RFORK),
- PROT_READ | PROT_WRITE,
- (ad_getoflags(ad, ADFLAGS_HF) & O_RDWR) ?
- MAP_SHARED : MAP_PRIVATE, ad->ad_hf.adf_fd, 0);
- if (ad->ad_data == MAP_FAILED) {
- ad->ad_data = buf;
- return -1;
- }
- munmap(buf, off);
- }
- return 0;
-
-#else /* USE_MMAPPED_HEADERS */
- return ad_header_read(ad);
-#endif /* USE_MMAPPED_HEADERS */
+ return ad_header_read(ad, NULL);
}
/*
- * $Id: ad_read.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: ad_read.c,v 1.4 2002-10-11 14:18:37 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <atalk/adouble.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/param.h>
-#include <atalk/adouble.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif /* ! MIN */
-/* XXX: this would probably benefit from pread.
- * locks have to be checked before each stream of consecutive
+ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset)
+{
+ ssize_t cc;
+
+#ifndef HAVE_PREAD
+ if ( ad_fd->adf_off != offset ) {
+ if ( lseek( ad_fd->adf_fd, offset, SEEK_SET ) < 0 ) {
+ return -1;
+ }
+ ad_fd->adf_off = offset;
+ }
+ if (( cc = read( ad_fd.adf_fd, buf, count )) < 0 ) {
+ return -1;
+ }
+ ad_fd->adf_off += cc;
+#else
+ cc = pread(ad_fd->adf_fd, buf, count, offset );
+#endif
+ return cc;
+}
+
+/* XXX: locks have to be checked before each stream of consecutive
* ad_reads to prevent a denial in the middle from causing
* problems. */
ssize_t ad_read( ad, eid, off, buf, buflen)
/* We're either reading the data fork (and thus the data file)
* or we're reading anything else (and thus the header file). */
if ( eid == ADEID_DFORK ) {
- if ( ad->ad_df.adf_off != off ) {
- if ( lseek( ad->ad_df.adf_fd, (off_t) off, SEEK_SET ) < 0 ) {
- return( -1 );
- }
- ad->ad_df.adf_off = off;
- }
- if (( cc = read( ad->ad_df.adf_fd, buf, buflen )) < 0 ) {
- return( -1 );
- }
- ad->ad_df.adf_off += cc;
+ cc = adf_pread(&ad->ad_df, buf, buflen, off);
} else {
- cc = ad->ad_eid[eid].ade_off + off;
-
-#ifdef USE_MMAPPED_HEADERS
- if (eid != ADEID_RFORK) {
- memcpy(buf, ad->ad_data + cc, buflen);
- cc = buflen;
- goto ad_read_done;
- }
-#endif /* USE_MMAPPED_HEADERS */
- if ( ad->ad_hf.adf_off != cc ) {
- if ( lseek( ad->ad_hf.adf_fd, (off_t) cc, SEEK_SET ) < 0 ) {
- return( -1 );
- }
- ad->ad_hf.adf_off = cc;
- }
-
- if (( cc = read( ad->ad_hf.adf_fd, buf, buflen )) < 0 ) {
+ off_t r_off;
+
+ r_off = ad_getentryoff(ad, eid) + off;
+
+ if (( cc = adf_pread( &ad->ad_hf, buf, buflen, r_off )) < 0 ) {
return( -1 );
}
-
-#ifndef USE_MMAPPED_HEADERS
/*
* We've just read in bytes from the disk that we read earlier
* into ad_data. If we're going to write this buffer out later,
* we need to update ad_data.
+ * FIXME : always false?
*/
- if (ad->ad_hf.adf_off < ad_getentryoff(ad, ADEID_RFORK)) {
+ if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
if ( ad->ad_hf.adf_flags & O_RDWR ) {
- memcpy(buf, ad->ad_data + ad->ad_hf.adf_off,
- MIN(sizeof( ad->ad_data ) - ad->ad_hf.adf_off, cc));
+ memcpy(buf, ad->ad_data + r_off,
+ MIN(sizeof( ad->ad_data ) - r_off, cc));
} else {
- memcpy(ad->ad_data + ad->ad_hf.adf_off, buf,
- MIN(sizeof( ad->ad_data ) - ad->ad_hf.adf_off, cc));
+ memcpy(ad->ad_data + r_off, buf,
+ MIN(sizeof( ad->ad_data ) - r_off, cc));
}
}
- ad->ad_hf.adf_off += cc;
-#else /* ! USE_MMAPPED_HEADERS */
-ad_read_done:
-#endif /* ! USE_MMAPPED_HEADERS */
}
return( cc );
/*
- * $Id: ad_sendfile.c,v 1.4 2002-01-04 04:45:48 sibaz Exp $
+ * $Id: ad_sendfile.c,v 1.5 2002-10-11 14:18:38 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
static int _ad_sendfile_dummy;
+#ifdef ATACC
+
+#if defined(HAVE_SENDFILE_READ)
+#ifdef __NR_sendfile
+int sendfile(int fdout, int fdin, off_t *off, size_t count)
+{
+#if _FILE_OFFSET_BITS == 64
+#error sendfile
+ return syscall(__NR_sendfile64, fdout, fdin, off, count);
+#else
+ return syscall(__NR_sendfile, fdout, fdin, off, count);
+#endif
+}
+#endif
+#endif
+#endif
+
#if defined(HAVE_SENDFILE_READ) || defined(HAVE_SENDFILE_WRITE)
static __inline__ int ad_sendfile_init(const struct adouble *ad,
const int eid, off_t *off,
/*
- * $Id: ad_size.c,v 1.4 2002-01-04 04:45:48 sibaz Exp $
+ * $Id: ad_size.c,v 1.5 2002-10-11 14:18:38 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
return 0;
return st.st_size;
}
-
+#if 0
return ad_getentrylen(ad, eid);
+#endif
+ return ad->ad_rlen;
}
/*
- * $Id: ad_write.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: ad_write.c,v 1.4 2002-10-11 14:18:39 didg Exp $
*
* Copyright (c) 1990,1995 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <atalk/adouble.h>
+
#include <string.h>
-#include <sys/types.h>
#include <sys/param.h>
-#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif /* HAVE_FCNTL_H */
#include <errno.h>
-#include <atalk/adouble.h>
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif /* ! MIN */
-/* XXX: this would benefit from pwrite.
- * locking has to be checked before each stream of consecutive
+/* XXX: locking has to be checked before each stream of consecutive
* ad_writes to prevent a lock in the middle from causing problems.
*/
+
+ssize_t adf_pwrite(struct ad_fd *ad_fd, const void *buf, size_t count, off_t offset)
+{
+ ssize_t cc;
+
+#ifndef HAVE_PWRITE
+ if ( ad_fd->adf_off != off ) {
+ if ( lseek( ad_fd->adf_fd, offset, SEEK_SET ) < 0 ) {
+ return -1;
+ }
+ ad_fd->adf_off = offset;
+ }
+ cc = write( ad_fd->adf_fd, buf, count );
+ if ( cc < 0 ) {
+ return -1;
+ }
+ ad_fd->adf_off += cc;
+#else
+ cc = pwrite(ad_fd->adf_fd, buf, count, offset );
+#endif
+ return cc;
+}
+
+
ssize_t ad_write( ad, eid, off, end, buf, buflen )
struct adouble *ad;
const u_int32_t eid;
{
struct stat st;
ssize_t cc;
-
+
if ( eid == ADEID_DFORK ) {
if ( end ) {
if ( fstat( ad->ad_df.adf_fd, &st ) < 0 ) {
}
off = st.st_size - off;
}
+ cc = adf_pwrite(&ad->ad_df, buf, buflen, off);
+ } else if ( eid == ADEID_RFORK ) {
+ off_t r_off;
- if ( ad->ad_df.adf_off != off ) {
- if ( lseek( ad->ad_df.adf_fd, (off_t) off, SEEK_SET ) < 0 ) {
+ if ( end ) {
+ if ( fstat( ad->ad_df.adf_fd, &st ) < 0 ) {
return( -1 );
}
- ad->ad_df.adf_off = off;
- }
- cc = write( ad->ad_df.adf_fd, buf, buflen );
- if ( cc < 0 ) {
- return( -1 );
+ off = st.st_size - off -ad_getentryoff(ad, eid);
}
- ad->ad_df.adf_off += cc;
- } else {
- if ( end ) {
- off = ad->ad_eid[ eid ].ade_len - off;
- }
- cc = ad->ad_eid[eid].ade_off + off;
-
-#ifdef USE_MMAPPED_HEADERS
- if (eid != ADEID_RFORK) {
- memcpy(ad->ad_data + cc, buf, buflen);
- cc = buflen;
- goto ad_write_done;
- }
-#endif /* ! USE_MMAPPED_HEADERS */
-
- if ( ad->ad_hf.adf_off != cc ) {
- if ( lseek( ad->ad_hf.adf_fd, (off_t) cc, SEEK_SET ) < 0 ) {
- return( -1 );
- }
- ad->ad_hf.adf_off = cc;
- }
-
- if ((cc = write( ad->ad_hf.adf_fd, buf, buflen )) < 0)
- return( -1 );
- ad->ad_hf.adf_off += cc;
-
-#ifndef USE_MMAPPED_HEADERS
- /* sync up our internal buffer */
- if (ad->ad_hf.adf_off < ad_getentryoff(ad, ADEID_RFORK))
- memcpy(ad->ad_data + ad->ad_hf.adf_off, buf,
- MIN(sizeof(ad->ad_data) - ad->ad_hf.adf_off, cc));
-#else /* ! USE_MMAPPED_HEADERS */
-ad_write_done:
-#endif /* ! USE_MMAPPED_HEADERS */
- if ( ad->ad_eid[ eid ].ade_len < off + cc ) {
- ad->ad_eid[ eid ].ade_len = off + cc;
- }
+ r_off = ad_getentryoff(ad, eid) + off;
+ cc = adf_pwrite(&ad->ad_hf, buf, buflen, r_off);
+
+ /* sync up our internal buffer FIXME always false? */
+ if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
+ memcpy(ad->ad_data + r_off, buf, MIN(sizeof(ad->ad_data) -r_off, cc));
+ }
+ if ( ad->ad_rlen < r_off + cc ) {
+ ad->ad_rlen = r_off + cc;
+ }
+ }
+ else {
+ return -1; /* we don't know how to write if it's not a ressource or data fork */
}
-
return( cc );
}
errno = err;
return( -1 );
}
+ ad->ad_rlen = size;
+#if 0
ad->ad_eid[ ADEID_RFORK ].ade_len = size;
if ( lseek( ad->ad_hf.adf_fd, ad->ad_eid[ADEID_RFORK].ade_off,
SEEK_SET ) < 0 ) {
}
ad->ad_hf.adf_off = ad->ad_eid[ADEID_RFORK].ade_off;
+#endif
ad_tmplock(ad, ADEID_RFORK, ADLOCK_CLR, 0, 0);
return( 0 );
}
err = errno;
ad_tmplock(ad, ADEID_DFORK, ADLOCK_CLR, 0, 0);
errno = err;
+ return -1;
} else
ad_tmplock(ad, ADEID_DFORK, ADLOCK_CLR, 0, 0);
/*
- * $Id: dsi_stream.c,v 1.8 2002-02-02 21:09:13 jmarcus Exp $
+ * $Id: dsi_stream.c,v 1.9 2002-10-11 14:18:39 didg Exp $
*
* Copyright (c) 1998 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
sigset_t oldset;
#ifdef USE_WRITEV
struct iovec iov[2];
- size_t towrite;
+ size_t towrite;
ssize_t len;
#endif /* USE_WRITEV */
/* read data. function on success. 0 on failure. data length gets
* stored in length variable. this should really use size_t's, but
* that would require changes elsewhere. */
-int dsi_stream_receive(DSI *dsi, void *buf, const int ilength,
- int *rlength)
+int dsi_stream_receive(DSI *dsi, void *buf, const size_t ilength,
+ size_t *rlength)
{
char block[DSI_BLOCKSIZ];
module.c \
server_child.c \
server_lock.c \
+ strcasestr.c \
strdicasecmp.c
--- /dev/null
+/* Return the offset of one string within another.
+ Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ * My personal strstr() implementation that beats most other algorithms.
+ * Until someone tells me otherwise, I assume that this is the
+ * fastest implementation of strstr() in C.
+ * I deliberately chose not to comment it. You should have at least
+ * as much fun trying to understand it, as I had to write it :-).
+ *
+ * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
+/* added strcasestr support, davidm@lineo.com */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef HAVE_STRCASESTR
+
+#if defined HAVE_STRING_H
+# include <string.h>
+#endif
+
+typedef unsigned chartype;
+
+#include <ctype.h>
+#define VAL(x) tolower(x)
+#define FUNC strcasestr
+#undef strcasestr
+
+char * FUNC ( const char *phaystack, const char *pneedle)
+{
+ register const unsigned char *haystack, *needle;
+ register chartype b, c;
+
+ haystack = (const unsigned char *) phaystack;
+ needle = (const unsigned char *) pneedle;
+
+ b = *needle;
+ if (b != '\0') {
+ haystack--; /* possible ANSI violation */
+ do {
+ c = *++haystack;
+ if (c == '\0')
+ goto ret0;
+ }
+ while (VAL(c) != VAL(b));
+
+ c = *++needle;
+ if (c == '\0')
+ goto foundneedle;
+ ++needle;
+ goto jin;
+
+ for (;;) {
+ register chartype a;
+ register const unsigned char *rhaystack, *rneedle;
+
+ do {
+ a = *++haystack;
+ if (a == '\0')
+ goto ret0;
+ if (VAL(a) == VAL(b))
+ break;
+ a = *++haystack;
+ if (a == '\0')
+ goto ret0;
+ shloop:}
+ while (VAL(a) != VAL(b));
+
+ jin:a = *++haystack;
+ if (a == '\0')
+ goto ret0;
+
+ if (VAL(a) != VAL(c))
+ goto shloop;
+
+ rhaystack = haystack-- + 1;
+ rneedle = needle;
+ a = *rneedle;
+
+ if (VAL(*rhaystack) == VAL(a))
+ do {
+ if (a == '\0')
+ goto foundneedle;
+ ++rhaystack;
+ a = *++needle;
+ if (VAL(*rhaystack) != VAL(a))
+ break;
+ if (a == '\0')
+ goto foundneedle;
+ ++rhaystack;
+ a = *++needle;
+ }
+ while (VAL(*rhaystack) == VAL(a));
+
+ needle = rneedle; /* took the register-poor approach */
+
+ if (a == '\0')
+ break;
+ }
+ }
+ foundneedle:
+ return (char *) haystack;
+ ret0:
+ return 0;
+}
+#endif