+
+/* --------------------------- */
+int of_closefork(struct ofork *ofork)
+{
+ struct timeval tv;
+ int adflags, doflush = 0;
+ int ret;
+
+ adflags = 0;
+ if ((ofork->of_flags & AFPFORK_DATA) && (ad_data_fileno( ofork->of_ad ) != -1)) {
+ adflags |= ADFLAGS_DF;
+ }
+ if ( (ofork->of_flags & AFPFORK_OPEN) && ad_reso_fileno( ofork->of_ad ) != -1 ) {
+ adflags |= ADFLAGS_HF;
+ /*
+ * Only set the rfork's length if we're closing the rfork.
+ */
+ 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 );
+ }
+ }
+ }
+ ret = 0;
+ if ( ad_close( ofork->of_ad, adflags ) < 0 ) {
+ ret = -1;
+ }
+
+ of_dealloc( ofork );
+ return ret;
+}
+
+/* ----------------------
+
+*/
+struct adouble *of_ad(const struct vol *vol, struct path *path, struct adouble *ad)
+{
+ struct ofork *of;
+ struct adouble *adp;
+
+ if ((of = of_findname(path))) {
+ adp = of->of_ad;
+ } else {
+ ad_init(ad, vol->v_adouble, vol->v_ad_options);
+ adp = ad;
+ }
+ return adp;
+}
+
+/* ----------------------
+ close all forks for a volume
+*/
+void of_closevol(const struct vol *vol)
+{
+ int refnum;
+
+ if (!oforks)
+ return;
+
+ for ( refnum = 0; refnum < nforks; refnum++ ) {
+ if (oforks[ refnum ] != NULL && oforks[refnum]->of_vol == vol) {
+ if (of_closefork( oforks[ refnum ]) < 0 ) {
+ LOG(log_error, logtype_afpd, "of_closevol: %s", strerror(errno) );
+ }
+ }
+ }
+ return;
+}
+