]> arthur.barton.de Git - netatalk.git/blob - libatalk/adouble/ad_flush.c
- merge branch-netatalk-afp-3x-dev, HEAD was tagged before
[netatalk.git] / libatalk / adouble / ad_flush.c
1 /*
2  * $Id: ad_flush.c,v 1.7 2005-04-28 20:49:52 bfernhomberg Exp $
3  *
4  * Copyright (c) 1990,1991 Regents of The University of Michigan.
5  * All Rights Reserved.
6  *
7  * Permission to use, copy, modify, and distribute this software and
8  * its documentation for any purpose and without fee is hereby granted,
9  * provided that the above copyright notice appears in all copies and
10  * that both that copyright notice and this permission notice appear
11  * in supporting documentation, and that the name of The University
12  * of Michigan not be used in advertising or publicity pertaining to
13  * distribution of the software without specific, written prior
14  * permission. This software is supplied as is without expressed or
15  * implied warranties of any kind.
16  *
17  *      Research Systems Unix Group
18  *      The University of Michigan
19  *      c/o Mike Clark
20  *      535 W. William Street
21  *      Ann Arbor, Michigan
22  *      +1-313-763-0525
23  *      netatalk@itd.umich.edu
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif /* HAVE_CONFIG_H */
29
30 #include <atalk/adouble.h>
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <errno.h>
36
37 #include "ad_private.h"
38 #if AD_VERSION == AD_VERSION1 
39
40 #define EID_DISK(a) (a)
41
42 #else
43
44 static const u_int32_t set_eid[] = {
45 0,1,2,3,4,5,6,7,8,
46 9,10,11,12,13,14,15,
47 AD_DEV, AD_INO, AD_SYN, AD_ID
48 };
49
50 #define EID_DISK(a) (set_eid[a])
51 #endif
52
53 /* rebuild the header */
54 void ad_rebuild_header(struct adouble *ad)
55 {
56     u_int32_t           eid;
57     u_int32_t           temp;
58     
59     u_int16_t           nent;
60     char                *buf, *nentp;
61
62     /*
63      * Rebuild any header information that might have changed.
64      */
65     buf = ad->ad_data;
66
67     temp = htonl( ad->ad_magic );
68     memcpy(buf, &temp, sizeof( temp ));
69     buf += sizeof( temp );
70     
71     temp = htonl( ad->ad_version );
72     memcpy(buf, &temp, sizeof( temp ));
73     buf += sizeof( temp );
74
75     memcpy(buf, ad->ad_filler, sizeof( ad->ad_filler ));
76     buf += sizeof( ad->ad_filler );
77     
78     nentp = buf;
79     buf += sizeof( nent );
80     for ( eid = 0, nent = 0; eid < ADEID_MAX; eid++ ) {
81       if ( ad->ad_eid[ eid ].ade_off == 0 ) {
82         continue;
83       }
84       temp = htonl( EID_DISK(eid) );
85       memcpy(buf, &temp, sizeof( temp ));
86       buf += sizeof( temp );
87
88       temp = htonl( ad->ad_eid[ eid ].ade_off );
89       memcpy(buf, &temp, sizeof( temp ));
90       buf += sizeof( temp );
91
92       temp = htonl( ad->ad_eid[ eid ].ade_len );
93       memcpy(buf, &temp, sizeof( temp ));
94       buf += sizeof( temp );
95       nent++;
96     }
97     nent = htons( nent );
98     memcpy(nentp, &nent, sizeof( nent ));
99 }
100
101
102 int ad_flush( ad, adflags )
103     struct adouble      *ad;
104     int                 adflags;
105 {
106     int len;
107
108     if (( adflags & ADFLAGS_HF ) && ( ad->ad_hf.adf_flags & O_RDWR )) {
109         /* sync our header */
110         if (ad->ad_rlen > 0xffffffff) {
111             ad_setentrylen(ad, ADEID_RFORK, 0xffffffff);
112         }
113         else {
114             ad_setentrylen(ad, ADEID_RFORK, ad->ad_rlen);
115         }
116         ad_rebuild_header(ad);
117         len = ad_getentryoff(ad, ADEID_RFORK);
118         /* now flush it out */
119         if (adf_pwrite(&ad->ad_hf, ad->ad_data, len, 0) != len) {
120             if ( errno == 0 ) {
121                 errno = EIO;
122             }
123             return( -1 );
124         }
125     }
126
127     return( 0 );
128 }
129
130 /* use refcounts so that we don't have to re-establish fcntl locks. */
131 int ad_close( ad, adflags )
132     struct adouble      *ad;
133     int                 adflags;
134 {
135     int                 err = 0;
136
137     if (( adflags & ADFLAGS_DF ) && ad->ad_df.adf_fd != -1 &&
138             !(--ad->ad_df.adf_refcount)) {
139         if ( close( ad->ad_df.adf_fd ) < 0 ) {
140             err = -1;
141         }
142         ad->ad_df.adf_fd = -1;
143         adf_lock_free(&ad->ad_df);
144     }
145
146     if (( adflags & ADFLAGS_HF ) && ad->ad_hf.adf_fd != -1 &&
147             !(--ad->ad_hf.adf_refcount)) {
148         if ( close( ad->ad_hf.adf_fd ) < 0 ) {
149             err = -1;
150         }
151         ad->ad_hf.adf_fd = -1;
152         adf_lock_free(&ad->ad_hf);
153     }
154
155     return( err );
156 }