]> git.sur5r.net Git - openldap/blob - libraries/liblutil/csn.c
0c95ccfef83a432c0d78920b74d70394b42413fa
[openldap] / libraries / liblutil / csn.c
1 /*
2  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /* Portions
6  * Copyright 2000, John E. Schimmel, All rights reserved.
7  * This software is not subject to any license of Mirapoint, Inc.
8  *
9  * This is free software; you can redistribute and use it
10  * under the same terms as OpenLDAP itself.
11  */
12 /* Adapted for incorporatation into OpenLDAP by Kurt Zeilenga */
13
14 /*
15  * This file contains routines to generate a change sequence number.  Every
16  * add, delete, and modification is given a unique identifier for use in
17  * resolving conflicts during replication operations.
18  *
19  * These routines are (loosly) based upon draft-ietf-ldup-model-03.txt,
20  * A WORK IN PROGRESS.  The format will likely change.
21  *
22  * The format of a CSN string is: yyyymmddhhmmssz#s#r#c
23  * where s is a counter of operations within a timeslice, r is
24  * the replica id (normally zero), and c is a counter of
25  * modifications within this operation.  s, r, and c are
26  * represented in hex and zero padded to lengths of 6, 2, and
27  * 6, respectively.
28  *
29  * Calls to this routine MUST be serialized with other calls
30  * to gmtime().
31  */
32 #include "portable.h"
33
34 #include <stdio.h>
35 #include <ac/time.h>
36
37 #include <lutil.h>
38
39 size_t
40 lutil_csnstr(char *buf, size_t len, unsigned int replica, unsigned int mod)
41 {
42         static time_t csntime;
43         static unsigned int csnop;
44
45         time_t t;
46         unsigned int op;
47         struct tm *ltm;
48         int n;
49
50         time( &t );
51         if ( t > csntime ) {
52                 csntime = t;
53                 csnop = 0;
54         }
55         op = ++csnop;
56
57         ltm = gmtime( &t );
58         n = snprintf( buf, len,
59                 "%4d%02d%02d%02d%02d%02dZ#%06x#%02x#%06x",
60             ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, ltm->tm_hour,
61             ltm->tm_min, ltm->tm_sec, op, replica, mod );
62
63         if( n < 0 ) return 0;
64         return ( (size_t) n < len ) ? n : 0;
65 }
66
67 #ifdef TEST
68 int
69 main(int argc, char **argv)
70 {
71         char buf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
72
73         if ( ! lutil_csnstr( buf, (size_t) 10, 0, 0 ) ) {
74                 fprintf(stderr, "failed lutil_csnstr\n");
75         }
76         if ( ! lutil_csnstr( buf, sizeof(buf), 0, 0 ) ) {
77                 fprintf(stderr, "failed lutil_csnstr\n");
78         }
79 }
80 #endif