]> git.sur5r.net Git - openldap/blob - servers/slurpd/reject.c
Listener commit broke test048, skip listener check on Hidden DBs
[openldap] / servers / slurpd / reject.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2007 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15 /* Portions Copyright (c) 1996 Regents of the University of Michigan.
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms are permitted
19  * provided that this notice is preserved and that due credit is given
20  * to the University of Michigan at Ann Arbor. The name of the University
21  * may not be used to endorse or promote products derived from this
22  * software without specific prior written permission. This software
23  * is provided ``as is'' without express or implied warranty.
24  */
25 /* ACKNOWLEDGEMENTS:
26  * This work was originally developed by the University of Michigan
27  * (as part of U-MICH LDAP).
28  */
29
30
31 /*
32  * reject.c - routines to write replication records to reject files.
33  * An Re struct is writted to a reject file if it cannot be propagated
34  * to a replica LDAP server.
35  */
36
37 #include "portable.h"
38
39 #include <stdio.h>
40
41 #include <ac/stdlib.h>
42 #include <ac/string.h>
43 #include <ac/errno.h>
44 #include <ac/unistd.h>
45
46 #include <sys/stat.h>
47 #include <fcntl.h>
48
49 #include "slurp.h"
50 #include "globals.h"
51
52 #include "lber_pvt.h"
53 #include "lutil.h"
54
55 #ifdef _WIN32
56 #define PORTSEP ","
57 #else
58 #define PORTSEP ":"
59 #endif
60
61 /*
62  * Write a replication record to a reject file.  The reject file has the
63  * same name as the replica's private copy of the file but with ".rej"
64  * appended (e.g. "/usr/tmp/<hostname>:<port>.rej")
65  *
66  * If errmsg is non-NULL, use that as the error message in the reject
67  * file.  Otherwise, use ldap_err2string( lderr ).
68  */
69 void
70 write_reject(
71     Ri          *ri,
72     Re          *re,
73     int         lderr,
74     char        *errmsg
75 )
76 {
77     char        rejfile[ MAXPATHLEN ];
78     FILE        *rfp, *lfp;
79     int         rc;
80
81     ldap_pvt_thread_mutex_lock( &sglob->rej_mutex );
82     snprintf( rejfile, sizeof rejfile, "%s" LDAP_DIRSEP "%s" PORTSEP "%d.rej",
83                 sglob->slurpd_rdir, ri->ri_hostname, ri->ri_port );
84
85     if ( access( rejfile, F_OK ) < 0 ) {
86         /* Doesn't exist - try to create */
87         int rjfd;
88         if (( rjfd = open( rejfile, O_RDWR|O_APPEND|O_CREAT|O_EXCL,
89                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP )) < 0 ) {
90             Debug( LDAP_DEBUG_ANY,
91                 "Error: write_reject: Cannot create \"%s\": %s\n",
92                 rejfile, sys_errlist[ errno ], 0 );
93             ldap_pvt_thread_mutex_unlock( &sglob->rej_mutex );
94             return;
95         } else {
96             close( rjfd );
97         }
98     }
99     if (( rc = acquire_lock( rejfile, &rfp, &lfp )) < 0 ) {
100         Debug( LDAP_DEBUG_ANY, "Error: cannot open reject file \"%s\"\n",
101                 rejfile, 0, 0 );
102     } else {
103         struct berval   bv = BER_BVNULL,
104                         errstrbv,
105                         errmsgbv = BER_BVNULL;
106         char            *ptr;
107
108         ber_str2bv( ldap_err2string( lderr ), 0, 0, &errstrbv );
109         if ( errmsg && *errmsg ) {
110                 ber_str2bv( errmsg, 0, 0, &errmsgbv );
111                 bv.bv_len = errstrbv.bv_len
112                         + STRLENOF( ": " ) + errmsgbv.bv_len;
113
114                 ptr = bv.bv_val = ber_memalloc( bv.bv_len + 1 );
115                 ptr = lutil_strcopy( ptr, errstrbv.bv_val );
116                 ptr = lutil_strcopy( ptr, ": " );
117                 ptr = lutil_strcopy( ptr, errmsgbv.bv_val );
118
119         } else {
120                 bv = errstrbv;
121         }
122
123         fseek( rfp, 0, 2 );
124
125         ptr = ldif_put( LDIF_PUT_VALUE, ERROR_STR, bv.bv_val, bv.bv_len );
126         if ( bv.bv_val != errstrbv.bv_val ) {
127                 ber_memfree( bv.bv_val );
128         }
129         if ( ptr == NULL ) {
130                 Debug( LDAP_DEBUG_ANY,
131                         "Error: cannot convert error message(s) \"%s%s%s\" "
132                         "into LDIF format\n",
133                         errstrbv.bv_val,
134                         BER_BVISNULL( &errmsgbv ) ? "" : ": ",
135                         BER_BVISNULL( &errmsgbv ) ? "" : errmsgbv.bv_val );
136                 return;
137         }
138
139         fputs( ptr, rfp );
140         ber_memfree( ptr );
141
142         if ((rc = re->re_write( ri, re, rfp )) < 0 ) {
143             Debug( LDAP_DEBUG_ANY,
144                     "Error: cannot write reject file \"%s\"\n",
145                     rejfile, 0, 0 );
146         }
147         (void) relinquish_lock( rejfile, rfp, lfp );
148         Debug( LDAP_DEBUG_ANY,
149                 "Error: ldap operation failed, data written to \"%s\"\n",
150                 rejfile, 0, 0 );
151     }
152     ldap_pvt_thread_mutex_unlock( &sglob->rej_mutex );
153     return;
154 }
155