]> git.sur5r.net Git - openldap/blob - servers/slurpd/st.c
Fix idl_insert_key() return codes.
[openldap] / servers / slurpd / st.c
1 /*
2  * Copyright (c) 1996 Regents of the University of Michigan.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of Michigan at Ann Arbor. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12
13
14 /*
15  * st.c - routines for managing the status structure, and for reading and
16  * writing status information to disk.
17  */
18
19 #include "portable.h"
20
21 #include <stdio.h>
22
23 #include <ac/stdlib.h>
24 #include <ac/string.h>
25 #include <ac/unistd.h>
26
27 #include "slurp.h"
28 #include "globals.h"
29
30 /*
31  * Add information about replica host specified by Ri to list
32  * of hosts.
33  */
34 static Stel *
35 St_add(
36     St  *st,
37     Ri  *ri
38 )
39 {
40     int ind;
41
42     if ( st == NULL || ri == NULL ) {
43         return NULL;
44     }
45
46     /* Serialize access to the St struct */
47     ldap_pvt_thread_mutex_lock( &(st->st_mutex ));
48
49     st->st_nreplicas++;
50     ind = st->st_nreplicas - 1;
51     st->st_data = ( Stel ** ) ch_realloc( st->st_data, 
52             ( st->st_nreplicas * sizeof( Stel * )));
53     if ( st->st_data == NULL ) {
54         ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
55         return NULL;
56     }
57     st->st_data[ ind ]  = ( Stel * ) ch_malloc( sizeof( Stel ) );
58     if ( st->st_data[ ind ] == NULL ) {
59         ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
60         return NULL;
61     }
62
63     st->st_data[ ind ]->hostname = strdup( ri->ri_hostname );
64     st->st_data[ ind ]->port = ri->ri_port;
65     memset( st->st_data[ ind ]->last, 0, sizeof( st->st_data[ ind ]->last )); 
66     st->st_data[ ind ]->seq = 0;
67
68     ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
69     return st->st_data[ ind ];
70 }
71
72
73
74 /*
75  * Write the contents of an St to disk.
76  */
77 static int
78 St_write (
79     St  *st
80 )
81 {
82     int         rc;
83     Stel        *stel;
84     int         i;
85
86     if ( st == NULL ) {
87         return -1;
88     }
89     ldap_pvt_thread_mutex_lock( &(st->st_mutex ));
90     if ( st->st_fp == NULL ) {
91         /* Open file */
92         if (( rc = acquire_lock( sglob->slurpd_status_file, &(st->st_fp),
93                 &(st->st_lfp))) < 0 ) {
94             if ( !st->st_err_logged ) {
95                 Debug( LDAP_DEBUG_ANY,
96                         "Error: cannot open status file \"%s\": %s\n",
97                         sglob->slurpd_status_file, sys_errlist[ errno ], 0 );
98                 st->st_err_logged = 1;
99                 ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
100                 return -1;
101             }
102         } else {
103             st->st_err_logged = 0;
104         }
105     }
106
107     /* Write data to the file */
108     truncate( sglob->slurpd_status_file, 0L );
109     fseek( st->st_fp, 0L, 0 );
110     for ( i = 0; i < st->st_nreplicas; i++ ) {
111         stel = st->st_data[ i ];
112         fprintf( st->st_fp, "%s:%d:%s:%d\n", stel->hostname, stel->port,
113                 stel->last, stel->seq );
114     }
115     fflush( st->st_fp );
116
117     ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
118
119     return 0;
120 }
121     
122
123
124
125 /*
126  * Update the entry for a given host.
127  */
128 static int
129 St_update(
130     St          *st,
131     Stel        *stel,
132     Re          *re
133 )
134 {
135     if ( stel == NULL || re == NULL ) {
136         return -1;
137     }
138
139     ldap_pvt_thread_mutex_lock( &(st->st_mutex ));
140     strcpy( stel->last, re->re_timestamp );
141     stel->seq = re->re_seq;
142     ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
143     return 0;
144 }
145
146
147
148
149 /*
150  * Read status information from disk file.
151  */
152 static int
153 St_read(
154     St  *st
155 )
156 {
157     FILE        *fp;
158     FILE        *lfp;
159     char        buf[ 255 ];
160     int         i;
161     int         rc;
162     char        *hostname, *port, *timestamp, *seq, *p, *t;
163     int         found;
164
165     if ( st == NULL ) {
166         return -1;
167     }
168     ldap_pvt_thread_mutex_lock( &(st->st_mutex ));
169     if ( access( sglob->slurpd_status_file, F_OK ) < 0 ) {
170         /*
171          * File doesn't exist, so create it and return.
172          */
173         if (( fp = fopen( sglob->slurpd_status_file, "w" )) == NULL ) {
174             Debug( LDAP_DEBUG_ANY, "Error: cannot create status file \"%s\"\n",
175                     sglob->slurpd_status_file, 0, 0 );
176             ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
177             return -1;
178         }
179         (void) fclose( fp );
180         ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
181         Debug( LDAP_DEBUG_ARGS, "No status file found, defaulting values\n",
182                 0, 0, 0 );
183         return 0;
184     }
185     if (( rc = acquire_lock( sglob->slurpd_status_file, &fp, &lfp)) < 0 ) {
186         ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
187         return 0;
188     }
189     while ( fgets( buf, sizeof( buf ), fp ) != NULL ) {
190         p = buf;
191         hostname = p;
192         if (( t = strchr( p, ':' )) == NULL ) {
193             goto bad;
194         }
195         *t++ = '\0';
196         p = t;
197         port = p;
198         if (( t = strchr( p, ':' )) == NULL ) {
199             goto bad;
200         }
201         *t++ = '\0';
202         p = t;
203         timestamp = p;
204         if (( t = strchr( p, ':' )) == NULL ) {
205             goto bad;
206         }
207         *t++ = '\0';
208         seq = t;
209         if (( t = strchr( seq, '\n' )) != NULL ) {
210             *t = '\0';
211         }
212
213         found = 0;
214         for ( i = 0; i < sglob->st->st_nreplicas; i++ ) {
215             if ( !strcmp( hostname, sglob->st->st_data[ i ]->hostname ) &&
216                     atoi( port ) == sglob->st->st_data[ i ]->port ) {
217                 found = 1;
218                 strcpy( sglob->st->st_data[ i ]->last, timestamp );
219                 sglob->st->st_data[ i ]->seq = atoi( seq );
220                 break;
221             }
222         }
223         if ( found ) {
224             char tbuf[ 255 ];
225             sprintf( tbuf, "%s:%s (timestamp %s.%s)", hostname, port,
226                     timestamp, seq );
227             Debug( LDAP_DEBUG_ARGS,
228                     "Retrieved state information for %s\n", tbuf, 0, 0 );
229         } else {
230             Debug(  LDAP_DEBUG_ANY,
231                     "Warning: saved state for %s:%s, not a known replica\n",
232                     hostname, port, 0 );
233         }
234     }
235     (void) relinquish_lock( sglob->slurpd_status_file, fp, lfp);
236     ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
237     return 0;
238
239 bad:
240     (void) relinquish_lock( sglob->slurpd_status_file, fp, lfp);
241     ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
242     return -1;
243 }
244     
245
246
247
248 /*
249  * Lock an St struct.
250  */
251 static int
252 St_lock(
253     St *st
254 )
255 {
256     return( ldap_pvt_thread_mutex_lock( &st->st_mutex ));
257 }
258
259
260
261
262 /*
263  * Lock an St struct.
264  */
265 static int
266 St_unlock(
267     St *st
268 )
269 {
270     return( ldap_pvt_thread_mutex_unlock( &st->st_mutex ));
271 }
272
273
274
275
276 /*
277  * Allocate and initialize an St struct.
278  */
279 int
280 St_init(
281     St **st
282 )
283 {
284     if ( st == NULL ) {
285         return -1;
286     }
287
288     (*st) = (St *) malloc( sizeof( St ));
289     if ( *st == NULL ) {
290         return -1;
291     }
292
293     ldap_pvt_thread_mutex_init( &((*st)->st_mutex) );
294     (*st)->st_data = NULL;
295     (*st)->st_fp = NULL;
296     (*st)->st_lfp = NULL;
297     (*st)->st_nreplicas = 0;
298     (*st)->st_err_logged = 0;
299     (*st)->st_update = St_update;
300     (*st)->st_add = St_add;
301     (*st)->st_write = St_write;
302     (*st)->st_read = St_read;
303     (*st)->st_lock = St_lock;
304     (*st)->st_unlock = St_unlock;
305     return 0;
306 }
307