]> arthur.barton.de Git - netatalk.git/blob - libatalk/adouble/ad_flush.c
#include "config.h" -> #include <config.h>
[netatalk.git] / libatalk / adouble / ad_flush.c
1 /*
2  * $Id: ad_flush.c,v 1.6 2003-01-28 15:30:56 srittau 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
39 /* rebuild the header */
40 void ad_rebuild_header(struct adouble *ad)
41 {
42     u_int32_t           eid;
43     u_int32_t           temp;
44     
45     u_int16_t           nent;
46     char                *buf, *nentp;
47
48     /*
49      * Rebuild any header information that might have changed.
50      */
51     buf = ad->ad_data;
52
53     temp = htonl( ad->ad_magic );
54     memcpy(buf, &temp, sizeof( temp ));
55     buf += sizeof( temp );
56     
57     temp = htonl( ad->ad_version );
58     memcpy(buf, &temp, sizeof( temp ));
59     buf += sizeof( temp );
60
61     memcpy(buf, ad->ad_filler, sizeof( ad->ad_filler ));
62     buf += sizeof( ad->ad_filler );
63     
64     nentp = buf;
65     buf += sizeof( nent );
66     for ( eid = 0, nent = 0; eid < ADEID_MAX; eid++ ) {
67       if ( ad->ad_eid[ eid ].ade_off == 0 ) {
68         continue;
69       }
70       temp = htonl( eid );
71       memcpy(buf, &temp, sizeof( temp ));
72       buf += sizeof( temp );
73
74       temp = htonl( ad->ad_eid[ eid ].ade_off );
75       memcpy(buf, &temp, sizeof( temp ));
76       buf += sizeof( temp );
77
78       temp = htonl( ad->ad_eid[ eid ].ade_len );
79       memcpy(buf, &temp, sizeof( temp ));
80       buf += sizeof( temp );
81       nent++;
82     }
83     nent = htons( nent );
84     memcpy(nentp, &nent, sizeof( nent ));
85 }
86
87
88 int ad_flush( ad, adflags )
89     struct adouble      *ad;
90     int                 adflags;
91 {
92     int len;
93
94     if (( adflags & ADFLAGS_HF ) && ( ad->ad_hf.adf_flags & O_RDWR )) {
95         /* sync our header */
96         if (ad->ad_rlen > 0xffffffff) {
97             ad_setentrylen(ad, ADEID_RFORK, 0xffffffff);
98         }
99         else {
100             ad_setentrylen(ad, ADEID_RFORK, ad->ad_rlen);
101         }
102         ad_rebuild_header(ad);
103         len = ad_getentryoff(ad, ADEID_RFORK);
104         /* now flush it out */
105         if (adf_pwrite(&ad->ad_hf, ad->ad_data, len, 0) != len) {
106             if ( errno == 0 ) {
107                 errno = EIO;
108             }
109             return( -1 );
110         }
111     }
112
113     return( 0 );
114 }
115
116 /* use refcounts so that we don't have to re-establish fcntl locks. */
117 int ad_close( ad, adflags )
118     struct adouble      *ad;
119     int                 adflags;
120 {
121     int                 err = 0;
122
123     if (( adflags & ADFLAGS_DF ) && ad->ad_df.adf_fd != -1 &&
124             !(--ad->ad_df.adf_refcount)) {
125         if ( close( ad->ad_df.adf_fd ) < 0 ) {
126             err = -1;
127         }
128         ad->ad_df.adf_fd = -1;
129         adf_lock_free(&ad->ad_df);
130     }
131
132     if (( adflags & ADFLAGS_HF ) && ad->ad_hf.adf_fd != -1 &&
133             !(--ad->ad_hf.adf_refcount)) {
134         if ( close( ad->ad_hf.adf_fd ) < 0 ) {
135             err = -1;
136         }
137         ad->ad_hf.adf_fd = -1;
138         adf_lock_free(&ad->ad_hf);
139     }
140
141     return( err );
142 }