user_base.C 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /*
  24. * $XConsortium: user_base.cc /main/8 1996/08/15 14:13:12 cde-hal $
  25. *
  26. * Copyright (c) 1992 HAL Computer Systems International, Ltd.
  27. * All rights reserved. Unpublished -- rights reserved under
  28. * the Copyright Laws of the United States. USE OF A COPYRIGHT
  29. * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
  30. * OR DISCLOSURE.
  31. *
  32. * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
  33. * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. USE,
  34. * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
  35. * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
  36. * INTERNATIONAL, LTD.
  37. *
  38. * RESTRICTED RIGHTS LEGEND
  39. * Use, duplication, or disclosure by the Government is subject
  40. * to the restrictions as set forth in subparagraph (c)(l)(ii)
  41. * of the Rights in Technical Data and Computer Software clause
  42. * at DFARS 252.227-7013.
  43. *
  44. * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
  45. * 1315 Dell Avenue
  46. * Campbell, CA 95008
  47. *
  48. */
  49. #include "oliasdb/user_base.h"
  50. #include "oliasdb/mark.h"
  51. #include "utility/debug.h"
  52. #include "misc/unique_id.h"
  53. #define LOCK_DIR "lock"
  54. #define AT_LOCK "at_lock"
  55. #define W_LOCK "w_lock"
  56. #define ACCESS_INFO "access_info"
  57. extern void_ptr_array g_store_array;
  58. extern Boolean g_transaction_on;
  59. extern int g_mode_8_3;
  60. user_base::user_base( const char* spec_path, rw_flag_t rw) :
  61. base(0), backup_file(0), rw_flag(rw), first_desc_ptr(0),
  62. spec_name(spec_path)
  63. {
  64. g_mode_8_3 = 1;
  65. int len;
  66. f_obj_dict = new object_dict;
  67. char* path = getenv("DTINFO_USER_DB") ;
  68. if ( path == 0 ) {
  69. char* home = getenv("HOME");
  70. char* lang = getenv("LANG");
  71. if ( home == 0 )
  72. throw(stringException("HOME unspecified"));
  73. if ( lang == 0 )
  74. throw(stringException("LANG unknown"));
  75. path = form("%s/.dt/dtinfo/%s", home, lang);
  76. }
  77. char* name = getenv("USER");
  78. if ( name == 0 )
  79. name = (char*)"";
  80. len = MIN(strlen(path), PATHSIZ - 1);
  81. *((char *) memcpy(base_path, path, len) + len) = '\0';
  82. len = MIN(strlen(name), PATHSIZ - 1);
  83. *((char *) memcpy(base_name, name, len) + len) = '\0';
  84. len = MIN(strlen(""), PATHSIZ - 1);
  85. *((char *) memcpy(base_desc, "", len) + len) = '\0';
  86. _init();
  87. }
  88. user_base::user_base( const char* base_dir,
  89. const char* base_nm,
  90. const char* base_ds,
  91. const char* spec_path,
  92. rw_flag_t rw
  93. ) :
  94. base(0, 0, 0, base_dir, base_nm, base_ds, ""), backup_file(0),
  95. rw_flag(rw), checking_status(SUCC), first_desc_ptr(0),
  96. spec_name(spec_path)
  97. {
  98. g_mode_8_3 = 1;
  99. f_obj_dict = new object_dict;
  100. _init();
  101. }
  102. user_base::checking_status_t user_base::check_mode()
  103. {
  104. mtry {
  105. switch ( rw_flag ) {
  106. case user_base::READ:
  107. {
  108. if ( exist_dir(base_path) == false ) {
  109. return user_base::FAIL;
  110. }
  111. break;
  112. }
  113. case user_base::WRITE:
  114. {
  115. if ( check_and_create_dir(base_path) == false ) {
  116. return user_base::FAIL;
  117. }
  118. break;
  119. }
  120. }
  121. }
  122. mcatch (systemException&, e)
  123. {
  124. return user_base::FAIL;
  125. }
  126. end_try;
  127. if ( exist_file(SCHEMA_FILE, base_path) == true )
  128. return user_base::SUCC;
  129. if ( exist_file(form("%s.%s", base_name, SCHEMA_FILE_SUFFIX), base_path) == true )
  130. return user_base::SUCC;
  131. return user_base::NO_BASE;
  132. }
  133. user_base::checking_status_t user_base::check_lock()
  134. {
  135. char lock_dir[PATHSIZ+5];
  136. int len;
  137. snprintf(lock_dir, sizeof(lock_dir), "%s/%s", base_path, LOCK_DIR);
  138. if ( check_and_create_dir(lock_dir) == false ) {
  139. MESSAGE(cerr, form("no write permission to %s", lock_dir));
  140. return user_base::CREATE_LOCKFILE_FAIL;
  141. }
  142. len = MIN(strlen(atomic_lock_path), strlen(lock_dir) + strlen(AT_LOCK) + 1);
  143. *((char *) memcpy(atomic_lock_path,
  144. form("%s/%s", lock_dir, AT_LOCK), len) + len) = '\0';
  145. len = MIN(strlen(write_lock_path), strlen(lock_dir) + strlen(W_LOCK) + 1);
  146. *((char *) memcpy(write_lock_path,
  147. form("%s/%s", lock_dir, W_LOCK), len) + len) = '\0';
  148. len = MIN(strlen(ai_path), strlen(lock_dir) + strlen(ACCESS_INFO) + 1);
  149. *((char *) memcpy(ai_path,
  150. form("%s/%s", lock_dir, ACCESS_INFO), len) + len) = '\0';
  151. char* ai_info = 0;
  152. switch (rw_flag) {
  153. case user_base::READ:
  154. if (
  155. read_lock(atomic_lock_path, write_lock_path,
  156. ai_path, access_info((char*)"read"), offset, ai_info
  157. ) == false
  158. ) {
  159. if ( ai_info ) {
  160. debug(cerr, ai_info);
  161. delete [] ai_info;
  162. }
  163. return user_base::RLOCK_FAIL;
  164. } else
  165. return user_base::SUCC;
  166. break;
  167. case user_base::WRITE:
  168. if (
  169. write_lock(atomic_lock_path, write_lock_path,
  170. ai_path, access_info((char*)"write"), ai_info
  171. ) == false
  172. ) {
  173. if ( ai_info ) {
  174. debug(cerr, ai_info);
  175. //
  176. // int x = strlen(ai_info);
  177. // if ( x >= 5 && strncmp(ai_info + x - 5, "read", 4) == 0 )
  178. // {
  179. // rw_flag = user_base::READ;
  180. // MESSAGE(cerr, "write locking failed, try read mode");
  181. // int ok = check_lock();
  182. // delete ai_info;
  183. // return ok;
  184. // }
  185. delete [] ai_info;
  186. }
  187. return user_base::WLOCK_FAIL;
  188. } else {
  189. return user_base::SUCC;
  190. }
  191. break;
  192. default:
  193. abort();
  194. }
  195. }
  196. void user_base::_init()
  197. {
  198. set_mode(HEALTH, true);
  199. checking_status = check_mode();
  200. MESSAGE(cerr, "Initial mode");
  201. debug(cerr, checking_status);
  202. first_desc_ptr = 0;
  203. switch ( checking_status ) {
  204. case user_base::NO_BASE:
  205. if ( disk_space(base_path) < 10*KB ) {
  206. checking_status = user_base::FAIL;
  207. break;
  208. }
  209. mtry
  210. {
  211. ubase_trans.begin();
  212. define();
  213. ubase_trans.sync();
  214. ubase_trans.end();
  215. }
  216. mcatch (beginTransException &,e)
  217. {
  218. // cases: can't open log or write size info to log
  219. checking_status = user_base::FAIL;
  220. clean_up();
  221. break;
  222. }
  223. mcatch (commitTransException &,e)
  224. {
  225. // cases: bad log file, can't write to store, etc.
  226. checking_status = user_base::FAIL;
  227. clean_up();
  228. break;
  229. }
  230. // cases: can't do define()
  231. mcatch (mmdbException &,e)
  232. {
  233. checking_status = user_base::FAIL;
  234. ubase_trans.rollback();
  235. ubase_trans.abort();
  236. clean_up();
  237. break;
  238. }
  239. end_try;
  240. checking_status = check_mode();
  241. break;
  242. case user_base::SUCC:
  243. mtry {
  244. ubase_trans.begin();
  245. first_desc_ptr = f_obj_dict -> init_a_base(base_path, base_name);
  246. ubase_trans.end();
  247. }
  248. mcatch (mmdbException &,e) {
  249. #ifdef DEBUG
  250. fprintf(stderr, "mmdbException caught @ %s line:%d.\n",
  251. __FILE__, __LINE__);
  252. #endif
  253. ubase_trans.abort();
  254. set_mode(HEALTH, false);
  255. checking_status = user_base::FAIL;
  256. break;
  257. } end_try;
  258. break;
  259. default:
  260. set_mode(HEALTH, false);
  261. break;
  262. }
  263. #ifndef NO_DB_LOCK
  264. if ( checking_status == user_base::SUCC ) {
  265. checking_status = check_lock();
  266. debug(cerr, checking_status);
  267. if ( checking_status != user_base::SUCC ) {
  268. set_mode(HEALTH, false);
  269. return;
  270. }
  271. }
  272. #endif
  273. MESSAGE(cerr, "Final mode"); debug(cerr, checking_status);
  274. switch ( checking_status ) {
  275. case user_base::SUCC:
  276. set_mode(HEALTH, true);
  277. MESSAGE(cerr, form("userbase \"%s\" available", base_name));
  278. break;
  279. default:
  280. set_mode(HEALTH, false);
  281. break;
  282. }
  283. return;
  284. }
  285. user_base::~user_base()
  286. {
  287. if ( checking_status == user_base::SUCC &&
  288. exist_dir(form("%s/%s", base_path, LOCK_DIR)) == true )
  289. {
  290. #ifndef NO_DB_LOCK
  291. switch (rw_flag) {
  292. case user_base::READ:
  293. read_unlock(atomic_lock_path, ai_path, offset);
  294. break;
  295. case user_base::WRITE:
  296. write_unlock(atomic_lock_path, write_lock_path, ai_path);
  297. );
  298. break;
  299. }
  300. #endif
  301. }
  302. delete f_obj_dict;
  303. }
  304. void user_base::clean_up()
  305. {
  306. abs_storage* store_ptr = 0;
  307. desc* desc_ptr = first_desc_ptr;
  308. while ( desc_ptr ) {
  309. store_ptr = desc_ptr -> get_store();
  310. if ( store_ptr ) {
  311. mtry {
  312. /*
  313. MESSAGE(cerr, "removing: ");
  314. MESSAGE(cerr, store_ptr -> my_name());
  315. */
  316. store_ptr->remove();
  317. }
  318. mcatch (mmdbException &,e)
  319. {
  320. } end_try;
  321. }
  322. desc_ptr = desc_ptr -> get_next_desc();
  323. }
  324. if ( exist_file(SCHEMA_FILE, base_path) == true )
  325. del_file(SCHEMA_FILE, base_path);
  326. }
  327. Boolean user_base::define()
  328. {
  329. int len;
  330. if ( check_and_create_dir(base_path) == false ) {
  331. throw(stringException(form("can't create %s", base_path)));
  332. }
  333. char spec_file_path[PATHSIZ];
  334. //char* x = getenv("DTINFO_LIB");
  335. char* x = getenv("DTINFO_MARKSPECPATH");
  336. if ( x == 0 ) {
  337. len = MIN(strlen(spec_name), PATHSIZ - 1);
  338. *((char *) memcpy(spec_file_path, spec_name, len) + len) = '\0';
  339. }
  340. else {
  341. len = MIN(strlen(x) + strlen(spec_name) + 1, PATHSIZ - 1);
  342. *((char *) memcpy(spec_file_path,
  343. form("%s/%s", x, spec_name), len) + len) = '\0';
  344. }
  345. if (exist_file(spec_file_path) == false) {
  346. debug(cerr, spec_file_path);
  347. throw(stringException(
  348. form("missing %s. can't define user_base", spec_file_path)
  349. )
  350. );
  351. }
  352. /*
  353. char unique_nm[PATHSIZ];
  354. const char* uid;
  355. uid = unique_id();
  356. len = MIN(strlen(base_name) + strlen(uid) + 1, PATHSIZ - 1);
  357. *((char *) memcpy(unique_nm,
  358. form("%s.%s", base_name, uid), len) + len) = '\0';
  359. */
  360. first_desc_ptr =
  361. f_obj_dict -> init_a_base(spec_file_path, base_path, base_name);
  362. return true;
  363. }