]> arthur.barton.de Git - netatalk.git/blob - libatalk/adouble/ad_flush.c
code cleaning
[netatalk.git] / libatalk / adouble / ad_flush.c
1 /*
2  * $Id: ad_flush.c,v 1.4 2002-09-29 17:39:59 didg 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 <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #ifdef HAVE_FCNTL_H
34 #include <fcntl.h>
35 #endif /* HAVE_FCNTL_H */
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif /* HAVE_UNISTD_H */
39 #include <sys/types.h>
40 #include <sys/mman.h>
41 #include <errno.h>
42
43 #include <netatalk/endian.h>
44 #include <atalk/adouble.h>
45
46 #include "ad_private.h"
47
48 /* rebuild the header */
49 void ad_rebuild_header(struct adouble *ad)
50 {
51     u_int32_t           eid;
52     u_int32_t           temp;
53     
54     u_int16_t           nent;
55     char                *buf, *nentp;
56
57     /*
58      * Rebuild any header information that might have changed.
59      */
60     buf = ad->ad_data;
61
62     temp = htonl( ad->ad_magic );
63     memcpy(buf, &temp, sizeof( temp ));
64     buf += sizeof( temp );
65     
66     temp = htonl( ad->ad_version );
67     memcpy(buf, &temp, sizeof( temp ));
68     buf += sizeof( temp );
69
70     memcpy(buf, ad->ad_filler, sizeof( ad->ad_filler ));
71     buf += sizeof( ad->ad_filler );
72     
73     nentp = buf;
74     buf += sizeof( nent );
75     for ( eid = 0, nent = 0; eid < ADEID_MAX; eid++ ) {
76       if ( ad->ad_eid[ eid ].ade_off == 0 ) {
77         continue;
78       }
79       temp = htonl( eid );
80       memcpy(buf, &temp, sizeof( temp ));
81       buf += sizeof( temp );
82
83       temp = htonl( ad->ad_eid[ eid ].ade_off );
84       memcpy(buf, &temp, sizeof( temp ));
85       buf += sizeof( temp );
86
87       temp = htonl( ad->ad_eid[ eid ].ade_len );
88       memcpy(buf, &temp, sizeof( temp ));
89       buf += sizeof( temp );
90       nent++;
91     }
92     nent = htons( nent );
93     memcpy(nentp, &nent, sizeof( nent ));
94 }
95
96
97 int ad_flush( ad, adflags )
98     struct adouble      *ad;
99     int                 adflags;
100 {
101 #ifndef USE_MMAPPED_HEADERS
102     int len;
103 #endif /* ! USE_MMAPPED_HEADERS */
104
105     if (( adflags & ADFLAGS_HF ) && ( ad->ad_hf.adf_flags & O_RDWR )) {
106         /* sync our header */
107         ad_rebuild_header(ad);
108
109 #ifdef USE_MMAPPED_HEADERS
110         /* now sync it */
111 #ifdef MS_SYNC
112         msync(ad->ad_data, ad_getentryoff(ad, ADEID_RFORK),
113               MS_SYNC | MS_INVALIDATE);
114 #else
115         msync(ad->ad_data, ad_getentryoff(ad, ADEID_RFORK));
116 #endif /* MS_SYNC */
117
118 #else /* USE_MMAPPED_HEADERS */
119         if ( ad->ad_hf.adf_off != 0 ) {
120             if ( lseek( ad->ad_hf.adf_fd, 0L, SEEK_SET ) < 0L ) {
121                 return( -1 );
122             }
123             ad->ad_hf.adf_off = 0;
124         }
125
126         /* now flush it out */
127         len = ad_getentryoff(ad, ADEID_RFORK);
128         if (write( ad->ad_hf.adf_fd, ad->ad_data, len) != len) {
129             if ( errno == 0 ) {
130                 errno = EIO;
131             }
132             return( -1 );
133         }
134         ad->ad_hf.adf_off = len;
135 #endif /* USE_MMAPPED_HEADERS */
136     }
137
138     return( 0 );
139 }
140
141 /* use refcounts so that we don't have to re-establish fcntl locks. */
142 int ad_close( ad, adflags )
143     struct adouble      *ad;
144     int                 adflags;
145 {
146     int                 err = 0;
147
148     if (( adflags & ADFLAGS_DF ) && ad->ad_df.adf_fd != -1 &&
149         !(--ad->ad_df.adf_refcount)) {
150         if ( close( ad->ad_df.adf_fd ) < 0 ) {
151             err = -1;
152         }
153         ad->ad_df.adf_fd = -1;
154         adf_lock_free(&ad->ad_df);
155     }
156
157     if (( adflags & ADFLAGS_HF ) && ad->ad_hf.adf_fd != -1 &&
158         !(--ad->ad_hf.adf_refcount)) {
159 #ifdef USE_MMAPPED_HEADERS
160         if (ad->ad_data != MAP_FAILED)
161           munmap(ad->ad_data, ad_getentryoff(ad, ADEID_RFORK));
162 #endif /* USE_MMAPPED_HEADERS */
163         if ( close( ad->ad_hf.adf_fd ) < 0 ) {
164             err = -1;
165         }
166         ad->ad_hf.adf_fd = -1;
167         adf_lock_free(&ad->ad_hf);
168     }
169
170     return( err );
171 }