/*
- * $Id: ad_open.c,v 1.71 2010-03-07 18:27:59 didg Exp $
- *
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
/* last place for failure. */
if (sys_ftruncate(fd, st.st_size + shiftdata) < 0) {
+ munmap(buf, st.st_size + shiftdata);
goto bail_lock;
}
if (!p) {
return -1;
}
-//FIXME!
- return lstat( p, stbuf );
+
+ return stat(p, stbuf);
}
/* ----------------
if (default_uid != (uid_t)-1) {
/* we are root (admin) */
id = (default_uid)?default_uid:stbuf->st_uid;
- ret = lchown( path, id, stbuf->st_gid );
+ ret = chown(path, id, stbuf->st_gid);
}
#endif
return ret;
int st_invalid;
struct stat stbuf;
- LOG(log_debug, logtype_default, "ad_mkdir: creating ad-directory '%s/%s' with mode %04o",
- getcwdpath(), path, mode);
+ LOG(log_debug, logtype_default, "ad_mkdir(\"%s\", %04o) {cwd: \"%s\"}",
+ path, mode, getcwdpath());
st_invalid = ad_mode_st(path, &mode, &stbuf);
ret = mkdir( path, mode );
}
}
- ad->ad_data_fork.adf_fd =open( path, hoflags | O_NOFOLLOW, admode );
+ ad->ad_data_fork.adf_fd = open(path, hoflags | ad_get_syml_opt(ad), admode);
- if (ad->ad_data_fork.adf_fd < 0 ) {
+ if (ad->ad_data_fork.adf_fd == -1) {
if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
hoflags = oflags;
- ad->ad_data_fork.adf_fd = open( path, hoflags | O_NOFOLLOW, admode );
+ ad->ad_data_fork.adf_fd = open( path, hoflags | ad_get_syml_opt(ad), admode );
}
- if (ad->ad_data_fork.adf_fd < 0 && errno == ELOOP) {
+ if (ad->ad_data_fork.adf_fd == -1 && errno == OPEN_NOFOLLOW_ERRNO) {
int lsz;
- if (oflags != O_RDONLY)
- return -1;
-
- ad->ad_data_fork.adf_syml = malloc(PATH_MAX+1);
- lsz = readlink(path, ad->ad_data_fork.adf_syml, PATH_MAX);
+ ad->ad_data_fork.adf_syml = malloc(MAXPATHLEN+1);
+ lsz = readlink(path, ad->ad_data_fork.adf_syml, MAXPATHLEN);
if (lsz <= 0) {
free(ad->ad_data_fork.adf_syml);
return -1;
}
- ad->ad_data_fork.adf_syml[lsz]=0;
- ad->ad_data_fork.adf_syml = realloc(ad->ad_data_fork.adf_syml,lsz+1);
- // XX
- ad->ad_data_fork.adf_fd = 0;
+ ad->ad_data_fork.adf_syml[lsz] = 0;
+ ad->ad_data_fork.adf_fd = -2; /* -2 means its a symlink */
}
}
- if ( ad->ad_data_fork.adf_fd < 0)
+ if ( ad->ad_data_fork.adf_fd == -1 )
return -1;
AD_SET(ad->ad_data_fork.adf_off);
if (!(adflags & ADFLAGS_RDONLY)) {
hoflags = (hoflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
}
- ad->ad_md->adf_fd = open( ad_p, hoflags | O_NOFOLLOW, 0 );
+ ad->ad_md->adf_fd = open(ad_p, hoflags | ad_get_syml_opt(ad), 0);
if (ad->ad_md->adf_fd < 0 ) {
if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
hoflags = oflags & ~(O_CREAT | O_EXCL);
- ad->ad_md->adf_fd = open( ad_p, hoflags | O_NOFOLLOW, 0 );
+ ad->ad_md->adf_fd = open(ad_p, hoflags | ad_get_syml_opt(ad), 0);
}
}
* here.
* if ((oflags & O_CREAT) ==> (oflags & O_RDWR)
*/
- LOG(log_debug, logtype_default, "ad_open: creating new adouble file: %s/%s", getcwdpath(), ad_p);
+ LOG(log_debug, logtype_default, "ad_open(\"%s\"): {cwd: \"%s\"} creating adouble file",
+ ad_p, getcwdpath());
admode = mode;
errno = 0;
st_invalid = ad_mode_st(ad_p, &admode, &st_dir);
}
admode = ad_hf_mode(admode);
if ((errno == ENOENT) && (ad->ad_flags != AD_VERSION2_OSX)) {
- if (ad->ad_ops->ad_mkrf( ad_p) < 0) {
+ if (ad->ad_ops->ad_mkrf(ad_p) < 0) {
return ad_error(ad, adflags);
}
admode = mode;
return ret;
}
+/*
+ * @brief openat like wrapper for ad_metadata
+ */
+int ad_metadataat(int dirfd, const char *name, int flags, struct adouble *adp)
+{
+ int ret = 0;
+ int cwdfd = -1;
+
+ if (dirfd != -1) {
+ if ((cwdfd = open(".", O_RDONLY) == -1) || (fchdir(dirfd) != 0)) {
+ ret = -1;
+ goto exit;
+ }
+ }
+
+ if (ad_metadata(name, flags, adp) < 0) {
+ ret = -1;
+ goto exit;
+ }
+
+ if (dirfd != -1) {
+ if (fchdir(cwdfd) != 0) {
+ LOG(log_error, logtype_afpd, "ad_openat: cant chdir back, exiting");
+ exit(EXITERR_SYS);
+ }
+ }
+
+exit:
+ if (cwdfd != -1)
+ close(cwdfd);
+
+ return ret;
+
+}
+
/* ----------------------------------- */
static int new_rfork(const char *path, struct adouble *ad, int adflags)
{
memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
}
- if (lstat(path, &st) < 0) {
+ if (ostat(path, &st, ad_get_syml_opt(ad)) < 0) {
return -1;
}
return ad->ad_ops->ad_header_read(ad, NULL);
}
+
+int ad_openat(int dirfd, /* dir fd openat like */
+ const char *path,
+ int adflags,
+ int oflags,
+ int mode,
+ struct adouble *ad)
+{
+ int ret = 0;
+ int cwdfd = -1;
+
+ if (dirfd != -1) {
+ if ((cwdfd = open(".", O_RDONLY) == -1) || (fchdir(dirfd) != 0)) {
+ ret = -1;
+ goto exit;
+ }
+ }
+
+ if (ad_open(path, adflags, oflags, mode, ad) < 0) {
+ ret = -1;
+ goto exit;
+ }
+
+ if (dirfd != -1) {
+ if (fchdir(cwdfd) != 0) {
+ LOG(log_error, logtype_afpd, "ad_openat: cant chdir back, exiting");
+ exit(EXITERR_SYS);
+ }
+ }
+
+exit:
+ if (cwdfd != -1)
+ close(cwdfd);
+
+ return ret;
+}