vol->v_path);
vol->v_cdb = cnid_open(vol->v_path, vol->v_umask, "tdb", flags, NULL, NULL);
if (vol->v_cdb) {
- /* set ro mode*/
- vol->v_flags |= AFPVOL_RO;
-#ifdef SERVERTEXT
- /* kill ourself with SIGUSR2 aka msg pending */
- setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB instead."
- "Check server messages for details. Switching to read-only mode.");
- kill(getpid(), SIGUSR2);
-#endif
- goto restart; /* not try again with the temp CNID db */
+ if (!(vol->v_flags & AFPVOL_TM)) {
+ vol->v_flags |= AFPVOL_RO;
+ setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB instead."
+ "Check server messages for details. Switching to read-only mode.");
+ kill(getpid(), SIGUSR2);
+ }
+ goto restart; /* now try again with the temp CNID db */
} else {
-#ifdef SERVERTEXT
setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB failed too!"
"Check server messages for details, can't recover from this state!");
-#endif
}
}
afp_errno = AFPERR_MISC;
goto exit;
}
}
- else if (adp && (adcnid != dbcnid)) { /* 4 */
+ else if (adp && adcnid && (adcnid != dbcnid)) { /* 4 */
/* Update the ressource fork. For a folder adp is always null */
LOG(log_debug, logtype_afpd, "get_id(%s/%s): calling ad_setid(old: %u, new: %u)",
getcwdpath(), upath, htonl(adcnid), htonl(dbcnid));
if (ad_setid(adp, st->st_dev, st->st_ino, dbcnid, did, vol->v_stamp)) {
- ad_flush(adp);
+ if (ad_flush(adp) != 0)
+ LOG(log_error, logtype_afpd, "get_id(\"%s\"): can't flush", fullpathname(upath));
}
}
}
}
/* ----------------------- */
-int getfilparams(const AFPObj *obj,
- struct vol *vol,
- uint16_t bitmap,
- struct path *path, struct dir *dir,
- char *buf, size_t *buflen )
+int getfilparams(const AFPObj *obj, struct vol *vol, uint16_t bitmap, struct path *path,
+ struct dir *dir, char *buf, size_t *buflen, int in_enumerate)
{
struct adouble ad, *adp;
int opened = 0;
if (opened) {
char *upath;
- flags = (bitmap & (1 << FILPBIT_ATTR)) ? ADFLAGS_CHECK_OF : 0;
+ /*
+ * Dont check for and resturn open fork attributes when enumerating
+ * This saves a lot of syscalls, the client will hopefully only use the result
+ * in FPGetFileParms where we return the correct value
+ */
+ flags = (!in_enumerate &&(bitmap & (1 << FILPBIT_ATTR))) ? ADFLAGS_CHECK_OF : 0;
adp = of_ad(vol, path, &ad);
upath = path->u_name;
return( AFPERR_ACCESS );
case EDQUOT:
case ENOSPC :
+ LOG(log_info, logtype_afpd, "afp_createfile: DISK FULL");
return( AFPERR_DFULL );
default :
return( AFPERR_PARAM );
return AFPERR_MISC;
}
- (void)get_id(vol, &ad, &st, dir->d_did, upath, strlen(upath));
+ cnid_t id;
+ if ((id = get_id(vol, &ad, &st, dir->d_did, upath, strlen(upath))) == CNID_INVALID) {
+ LOG(log_error, logtype_afpd, "afp_createfile(\"%s\"): CNID error", upath);
+ goto createfile_iderr;
+ }
+ (void)ad_setid(&ad, st.st_dev, st.st_ino, id, dir->d_did, vol->v_stamp);
+createfile_iderr:
ad_flush(&ad);
ad_close(&ad, ADFLAGS_DF|ADFLAGS_HF );
fce_register_new_file(s_path);
if (ad_open(adp, s_path->u_name, ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF | ADFLAGS_RDONLY | ADFLAGS_SETSHRMD) < 0) {
return AFPERR_DENYCONF;
}
+#ifdef HAVE_FSHARE_T
+ fshare_t shmd;
+ shmd.f_access = F_RDACC;
+ shmd.f_deny = F_NODNY;
+ if (fcntl(ad_data_fileno(adp), F_SHARE, &shmd) != 0) {
+ retvalue = AFPERR_DENYCONF;
+ goto copy_exit;
+ }
+ if (AD_RSRC_OPEN(adp) && fcntl(ad_reso_fileno(adp), F_SHARE, &shmd) != 0) {
+ retvalue = AFPERR_DENYCONF;
+ goto copy_exit;
+ }
+#endif
denyreadset = (ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_DENY_RD) != 0 ||
ad_testlock(adp, ADEID_RFORK, AD_FILELOCK_DENY_RD) != 0 );
case EDQUOT:
case EFBIG:
case ENOSPC:
+ LOG(log_info, logtype_afpd, "copyfile: DISK FULL");
return AFPERR_DFULL;
case ENOENT:
return AFPERR_NOOBJ;
}
path.id = cnid;
if (AFP_OK != (err = getfilparams(obj, vol, bitmap, &path , curdir,
- rbuf + sizeof(bitmap), &buflen))) {
+ rbuf + sizeof(bitmap), &buflen, 0))) {
return err;
}
*rbuflen = buflen + sizeof(bitmap);