]> git.sur5r.net Git - openldap/blob - servers/slurpd/replog.c
Initial revision
[openldap] / servers / slurpd / replog.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  * replog.c - routines which read and write replication log files.
16  */
17
18
19 #include <errno.h>
20 #include <stdio.h>
21 #include <syslog.h>
22 #include <sys/time.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <sys/param.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <string.h>
29
30 #include "portable.h"
31 #include "slurp.h"
32 #include "globals.h"
33
34 /*
35  * Externs
36  */
37 #ifdef NEEDPROTOS
38 extern FILE *lock_fopen( char *, char *, FILE ** );
39 extern char *ch_malloc( unsigned long );
40 #else /* NEEDPROTOS */
41 extern FILE *lock_fopen();
42 extern char *ch_malloc();
43 #endif /* NEEDPROTOS */
44
45 /*
46  * Forward declarations
47  */
48 #ifdef NEEDPROTOS
49 int file_nonempty( char * );
50 #else /* NEEDPROTOS */
51 int file_nonempty();
52 #endif /* NEEDPROTOS */
53
54
55 #ifndef SYSERRLIST_IN_STDIO
56 extern char *sys_errlist[];
57 #endif
58
59 /*
60  * Forward declarations
61  */
62 static int duplicate_replog( char *, char * );
63
64
65
66
67 /*
68  * Copy the replication log.  Returns 0 on success, 1 if a temporary
69  * error occurs, and -1 if a fatal error occurs.
70  */
71 int
72 copy_replog(
73     char        *src,
74     char        *dst
75 )
76 {
77     int         rc = 0;
78     FILE        *rfp;   /* replog fp */
79     FILE        *lfp;   /* replog lockfile fp */
80     FILE        *dfp;   /* duplicate replog fp */
81     FILE        *dlfp;  /* duplicate replog lockfile fp */
82     static char buf[ MAXPATHLEN ];
83     static char rbuf[ 1024 ];
84     char        *p;
85
86     Debug( LDAP_DEBUG_ARGS,
87             "copy replog \"%s\" to \"%s\"\n", 
88             src, dst, 0 );
89
90     /*
91      * Make sure the destination directory is writable.  If not, exit
92      * with a fatal error.
93      */
94     strcpy( buf, src );
95     if (( p = strrchr( buf, '/' )) == NULL ) {
96         strcpy( buf, "." );
97     } else {
98         *p = '\0';
99     }
100     if ( access( buf, W_OK ) < 0 ) {
101         Debug( LDAP_DEBUG_ANY,
102                 "Error: copy_replog (%d): Directory %s is not writable\n",
103                 getpid(), buf, 0 );
104         return( -1 );
105     }
106     strcpy( buf, dst );
107     if (( p = strrchr( buf, '/' )) == NULL ) {
108         strcpy( buf, "." );
109     } else {
110         *p = '\0';
111     }
112     if ( access( buf, W_OK ) < 0 ) {
113         Debug( LDAP_DEBUG_ANY,
114                 "Error: copy_replog (%d): Directory %s is not writable\n",
115                 getpid(), buf, 0 );
116         return( -1 );
117     }
118
119     /* lock src */
120     rfp = lock_fopen( src, "r", &lfp );
121     if ( rfp == NULL ) {
122         Debug( LDAP_DEBUG_ANY,
123                 "Error: copy_replog: Can't lock replog \"%s\" for read: %s\n",
124                 src, sys_errlist[ errno ], 0 );
125         return( 1 );
126     }
127
128     /* lock dst */
129     dfp = lock_fopen( dst, "a", &dlfp );
130     if ( dfp == NULL ) {
131         Debug( LDAP_DEBUG_ANY,
132                 "Error: copy_replog: Can't lock replog \"%s\" for write: %s\n",
133                 src, sys_errlist[ errno ], 0 );
134         lock_fclose( rfp );
135         return( 1 );
136     }
137
138     /*
139      * Make our own private copy of the replication log.
140      */
141     while (( p = fgets( rbuf, sizeof( buf ), rfp )) != NULL ) {
142         fputs( rbuf, dfp );
143     }
144     /* Only truncate the source file if we're not in one-shot mode */
145     if ( !sglob->one_shot_mode ) {
146         /* truncate replication log */
147         truncate( src, (off_t) 0 );
148     }
149
150     if ( lock_fclose( rfp, lfp ) == EOF ) {
151         Debug( LDAP_DEBUG_ANY,
152                 "Error: copy_replog: Error closing \"%s\"\n",
153                 src, 0, 0 );
154     }
155     if ( lock_fclose( dfp, dlfp ) == EOF ) {
156         Debug( LDAP_DEBUG_ANY,
157                 "Error: copy_replog: Error closing \"%s\"\n",
158                 src, 0, 0 );
159     }
160     return( rc );
161 }
162
163
164
165
166 /*
167  * Return 1 if the given file exists and has a nonzero size,
168  * 0 if it is empty or nonexistent.
169  */
170 int
171 file_nonempty(
172     char        *filename
173 )
174 {
175     static struct stat  stbuf;
176
177     if ( stat( filename, &stbuf ) < 0 ) {
178         return( 0 );
179     } else {
180         return( stbuf.st_size > (off_t ) 0 );
181     }
182 }