generation.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. #include <stdio.h>
  42. #include <time.h>
  43. #include "rwlock.h"
  44. #include "slap.h"
  45. /*
  46. * Create a new data version string.
  47. */
  48. static const char *
  49. new_dataversion()
  50. {
  51. struct tm t;
  52. char* dataversion;
  53. time_t curtime= current_time();
  54. #ifdef _WIN32
  55. memcpy (&t, gmtime (&curtime), sizeof(t));
  56. #else
  57. gmtime_r (&curtime, &t);
  58. #endif
  59. dataversion = slapi_ch_smprintf("0%.4li%.2i%.2i%.2i%.2i%.2i", 1900L + t.tm_year, 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
  60. return dataversion;
  61. }
  62. /* ---------------- Database Data Version ---------------- */
  63. /*
  64. * Return the generation ID for the database whose mapping tree node is "dn"
  65. */
  66. char *
  67. get_database_dataversion(const char *dn)
  68. {
  69. char *dataversion= NULL;
  70. int r;
  71. Slapi_PBlock *resultpb= NULL;
  72. Slapi_Entry** entry = NULL;
  73. resultpb= slapi_search_internal( dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, NULL, 1);
  74. slapi_pblock_get( resultpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entry );
  75. slapi_pblock_get( resultpb, SLAPI_PLUGIN_INTOP_RESULT, &r );
  76. if(r==LDAP_SUCCESS && entry!=NULL && entry[0]!=NULL)
  77. {
  78. dataversion= slapi_entry_attr_get_charptr( entry[0], "nsslapd-dataversion"); /* JCMREPL - Shouldn't be a Netscape specific attribute name */
  79. }
  80. slapi_free_search_results_internal(resultpb);
  81. slapi_pblock_destroy(resultpb);
  82. return dataversion;
  83. }
  84. void
  85. set_database_dataversion(const char *dn, const char *dataversion)
  86. {
  87. LDAPMod gen_mod;
  88. LDAPMod *mods[2];
  89. struct berval* gen_vals[2];
  90. struct berval gen_val;
  91. Slapi_PBlock *pb;
  92. memset (&gen_mod, 0, sizeof(gen_mod));
  93. gen_mod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
  94. gen_mod.mod_type = "nsslapd-dataversion"; /* JCMREPL - Shouldn't be a Netscape specific attribute name */
  95. gen_mod.mod_bvalues = gen_vals;
  96. gen_vals[0] = &gen_val;
  97. gen_vals[1] = NULL;
  98. gen_val.bv_val = (char *)dataversion;
  99. gen_val.bv_len = strlen (gen_val.bv_val);
  100. mods[0] = &gen_mod;
  101. mods[1] = NULL;
  102. pb = slapi_modify_internal (dn, mods, 0, 0 /* !log_change */);
  103. if (NULL != pb)
  104. {
  105. Slapi_Entry *e;
  106. slapi_pblock_get (pb, SLAPI_ENTRY_PRE_OP, &e);
  107. slapi_entry_free(e);
  108. }
  109. slapi_pblock_destroy(pb);
  110. }
  111. /* ---------------- Server Data Version ---------------- */
  112. static char *server_dataversion_id= NULL;
  113. const char *
  114. get_server_dataversion()
  115. {
  116. lenstr *l = NULL;
  117. Slapi_Backend *be;
  118. char *cookie;
  119. /* we already cached the copy - just return it */
  120. if(server_dataversion_id!=NULL)
  121. {
  122. return server_dataversion_id;
  123. }
  124. l= lenstr_new();
  125. /* Loop over the backends collecting the backend data versions */
  126. /* Combine them into a single blob */
  127. be = slapi_get_first_backend(&cookie);
  128. while ( be )
  129. {
  130. /* Don't generate dataversion for remote entries */
  131. if((!be->be_private) && !(slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA)))
  132. {
  133. const char * dataversion;
  134. Slapi_DN be_configdn;
  135. slapi_sdn_init(&be_configdn);
  136. (void)be_getconfigdn(be, &be_configdn);
  137. dataversion= get_database_dataversion(slapi_sdn_get_ndn(&be_configdn));
  138. if(dataversion==NULL)
  139. {
  140. /* The database either doesn't support the storage of a dataverion, */
  141. /* or has just been created, or has been reinitialised */
  142. dataversion= new_dataversion();
  143. set_database_dataversion(slapi_sdn_get_ndn(&be_configdn), dataversion);
  144. }
  145. addlenstr(l, dataversion);
  146. slapi_ch_free((void**)&dataversion);
  147. slapi_sdn_done(&be_configdn);
  148. }
  149. be = slapi_get_next_backend(cookie);
  150. }
  151. slapi_ch_free ((void **)&cookie);
  152. if(l->ls_buf!=NULL)
  153. {
  154. server_dataversion_id= slapi_ch_strdup(l->ls_buf);
  155. }
  156. lenstr_free(&l);
  157. return server_dataversion_id;
  158. }