/* FIXME path : unix or mac name ? (for now it's unix name ) */
void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data, int islink)
{
+ struct extmap *em;
void *ad_finder = NULL;
int chk_ext = 0;
if (ad_finder) {
memcpy(data, ad_finder, ADEDLEN_FINDERI);
+ /* default type ? */
+ if (default_type(ad_finder))
+ chk_ext = 1;
}
else {
memcpy(data, ufinderi, ADEDLEN_FINDERI);
memcpy((char *)data + FINDERINFO_FRCREATOFF,"rhap",4);
}
+ /** Only enter if no appledouble information and no finder information found. */
+ if (chk_ext && (em = getextmap( upath ))) {
+ memcpy(data, em->em_type, sizeof( em->em_type ));
+ memcpy((char *)data + 4, em->em_creator, sizeof(em->em_creator));
+ }
+
return data;
}
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);
ad_setdate(adp, AD_DATE_BACKUP, bdate);
break;
case FILPBIT_FINFO :
+ if (default_type( ad_entry( adp, ADEID_FINDERI ))
+ && (
+ ((em = getextmap( path->m_name )) &&
+ !memcmp(finder_buf, em->em_type, sizeof( em->em_type )) &&
+ !memcmp(finder_buf + 4, em->em_creator,sizeof( em->em_creator)))
+ || ((em = getdefextmap()) &&
+ !memcmp(finder_buf, em->em_type, sizeof( em->em_type )) &&
+ !memcmp(finder_buf + 4, em->em_creator,sizeof( em->em_creator)))
+ )) {
+ memcpy(finder_buf, ufinderi, 8 );
+ }
memcpy(ad_entry( adp, ADEID_FINDERI ), finder_buf, 32 );
break;
case FILPBIT_UNIXPR :
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);
uint32_t sid, did;
uint16_t vid;
- uid_t uid;
- gid_t gid;
-
*rbuflen = 0;
ibuf += 2;
/* change perms, src gets dest perm and vice versa */
- uid = geteuid();
- gid = getegid();
- if (seteuid(0)) {
- LOG(log_error, logtype_afpd, "seteuid failed %s", strerror(errno));
- err = AFP_OK; /* ignore error */
- goto err_temp_to_dest;
- }
+ become_root();
/*
* we need to exchange ACL entries as well
setfilunixmode(vol, path, srcst.st_mode);
setfilowner(vol, srcst.st_uid, srcst.st_gid, path);
- if ( setegid(gid) < 0 || seteuid(uid) < 0) {
- LOG(log_error, logtype_afpd, "can't seteuid back %s", strerror(errno));
- exit(EXITERR_SYS);
- }
+ unbecome_root();
err = AFP_OK;
goto err_exchangefile;