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