=====================
* NEW: afpd: Per volume "login message", NetAFP bug ID #18
+* NEW: afpd: Cross-platform locking (share modes) on Solaris and derivates
+ with Solaris CIFS/SMB server. Uses new Solaris fcntl F_SHARE share
+ reservation locking primitives.
* NEW: ad: ad set subcommand for changing Mac metadata on the server
* UPD: unix charset is UTF8 by default
vol charset is same value as unix charset by default
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 );
int denyreadset;
int denywriteset;
+#ifdef HAVE_FSHARE_T
+ fshare_t shmd;
+
+ shmd.f_access = (access & OPENACC_RD ? F_RDACC : 0) | (access & OPENACC_WR ? F_WRACC : 0);
+ if (shmd.f_access == 0)
+ /* we must give an access mode, otherwise fcntl will complain */
+ shmd.f_access = F_RDACC;
+ shmd.f_deny = (access & OPENACC_DRD ? F_RDDNY : F_NODNY) | (access & OPENACC_DWR) ? F_WRDNY : 0;
+ shmd.f_id = ofrefnum;
+
+ int fd = (eid == ADEID_DFORK) ? ad_data_fileno(adp) : ad_reso_fileno(adp);
+
+ if (fd != -1 && fd != -2 && fcntl(fd, F_SHARE, &shmd) != 0) {
+ LOG(log_debug, logtype_afpd, "fork_setmode: fcntl: %s", strerror(errno));
+ errno = EACCES;
+ return -1;
+ }
+
+#endif
if (! (access & (OPENACC_WR | OPENACC_RD | OPENACC_DWR | OPENACC_DRD))) {
return ad_lock(adp, eid, ADLOCK_RD | ADLOCK_FILELOCK, AD_FILELOCK_OPEN_NONE, 1, ofrefnum);
}
LOG(log_debug, logtype_afpd, "afp_closefork(fork: %s)",
(ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
+#ifdef HAVE_FSHARE_T
+ fshare_t shmd;
+ shmd.f_id = ofork->of_refnum;
+ if (AD_DATA_OPEN(ofork->of_ad))
+ fcntl(ad_data_fileno(ofork->of_ad), F_UNSHARE, &shmd);
+ if (AD_RSRC_OPEN(ofork->of_ad))
+ fcntl(ad_reso_fileno(ofork->of_ad), F_UNSHARE, &shmd);
+#endif
+
if ( of_closefork( ofork ) < 0 ) {
LOG(log_error, logtype_afpd, "afp_closefork(%s): of_closefork: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );