info_lib.C 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  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: info_lib.C /main/9 1996/12/02 12:47:19 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 "misc/unique_id.h"
  50. #include "api/info_lib.h"
  51. #include "utility/db_version.h"
  52. #include "oliasdb/locator_hd.h"
  53. #include "oliasdb/graphic_hd.h"
  54. /*
  55. extern void report_total();
  56. extern void reset_total();
  57. */
  58. int g_mode_8_3 = 0;
  59. typedef char* charPtr;
  60. info_lib::info_lib(char** set_name_array, char** list_name_array,
  61. char* info_lib_dir, char* selected_base_name,
  62. char* infoLibName, int des) :
  63. set_nm_list(set_name_array), list_nm_list(list_name_array),
  64. f_bad_base_array_size(0), f_bad_info_bases(0),
  65. f_bad_info_base_names(0), f_bad_info_base_paths(0), f_descriptor(des)
  66. {
  67. //debug(cerr, info_lib_dir);
  68. //debug(cerr, infoLibName);
  69. int len;
  70. f_obj_dict = new object_dict;
  71. if ( info_lib_dir == 0 ) {
  72. throw(stringException("NULL info lib path"));
  73. }
  74. if ( check_and_create_dir(info_lib_dir) == false )
  75. throw(stringException(
  76. form("infolib %s does not exist or can't be created", info_lib_dir)
  77. )
  78. );
  79. len = MIN(strlen(info_lib_dir), PATHSIZ -1);
  80. *((char *) memcpy (info_lib_path, info_lib_dir, len) + len) = '\0';
  81. len = MIN(strlen(infoLibName), PATHSIZ -1);
  82. *((char *) memcpy (info_lib_name, infoLibName, len) + len) = '\0';
  83. fstream *map_in = 0;
  84. if ( exist_file(MAP_FILE_8_3, info_lib_dir) == true ) {
  85. map_in = new fstream(form("%s/%s", info_lib_dir, MAP_FILE_8_3), ios::in);
  86. g_mode_8_3 = 1;
  87. if ( !map_in -> getline(info_lib_name, PATHSIZ, '\t') ||
  88. !map_in -> getline(info_lib_uid, UIDSIZ, '\n')
  89. )
  90. {
  91. throw(stringException(
  92. form("infolib %s does not have correct name-id entry", info_lib_dir)
  93. )
  94. );
  95. }
  96. } else
  97. if ( exist_file(MAP_FILE, info_lib_dir) == true )
  98. map_in = new fstream(form("%s/%s", info_lib_dir, MAP_FILE), ios::in);
  99. else {
  100. return;
  101. }
  102. char base_name[PATHSIZ];
  103. char base_desc[PATHSIZ];
  104. char base_uid[UIDSIZ];
  105. char base_locale[PATHSIZ];
  106. char db_path_name[PATHSIZ];
  107. int major_mm_version = 0;
  108. int minor_mm_version = 0;
  109. while ( map_in -> getline(base_name, PATHSIZ, '\t') ) {
  110. map_in -> getline(base_desc, PATHSIZ, '\t');
  111. if ( g_mode_8_3 == 1 ) {
  112. map_in -> getline(base_uid, PATHSIZ, '\t');
  113. map_in -> getline(base_locale, PATHSIZ, '\t');
  114. }
  115. else
  116. base_uid[0] = 0;
  117. (*map_in) >> major_mm_version >> minor_mm_version;
  118. map_in -> get();
  119. if ( base_name[0] != CommentChar ) {
  120. //debug(cerr, base_name);
  121. //debug(cerr, base_desc);
  122. //fprintf(stderr, "base_name = %s\n", base_name);
  123. if ((selected_base_name == 0 ||
  124. strcmp(selected_base_name, base_name) == 0))
  125. {
  126. len = MIN(strlen(info_lib_dir) + strlen(base_name) +1, PATHSIZ -1);
  127. *((char *) memcpy (db_path_name,
  128. form("%s/%s", info_lib_dir, base_name),
  129. len) + len) = '\0';
  130. mm_version mmv_code(MAJOR, MINOR);
  131. mm_version mmv_base_data(2, 1);
  132. mm_version mmv_data(major_mm_version, minor_mm_version);
  133. ///////////////////////////////////////////////
  134. // Hardcoded knowledge of discontinuation of
  135. // backward compatibility
  136. ///////////////////////////////////////////////
  137. if ( mmv_data < mmv_base_data ||
  138. mmv_data == mmv_base_data ||
  139. mmv_code < mmv_data
  140. )
  141. {
  142. if ( f_bad_base_array_size == 0 ||
  143. f_bad_base_array_size <= f_bad_info_bases
  144. )
  145. {
  146. if ( f_bad_base_array_size == 0 ) {
  147. f_bad_base_array_size = 10;
  148. f_bad_info_base_names = new charPtr[f_bad_base_array_size];
  149. f_bad_info_base_paths = new charPtr[f_bad_base_array_size];
  150. for (int i=0; i<f_bad_base_array_size; i++) {
  151. f_bad_info_base_paths[i] = 0;
  152. f_bad_info_base_names[i] = 0;
  153. }
  154. } else {
  155. char** x = new charPtr[2*f_bad_base_array_size];
  156. char** y = new charPtr[2*f_bad_base_array_size];
  157. for (int i=0; i<2*f_bad_base_array_size; i++) {
  158. x[i] = 0;
  159. y[i] = 0;
  160. }
  161. memcpy(x, f_bad_info_base_names, sizeof(charPtr)*f_bad_base_array_size);
  162. memcpy(y, f_bad_info_base_paths, sizeof(charPtr)*f_bad_base_array_size);
  163. f_bad_base_array_size *= 2;
  164. delete [] f_bad_info_base_names;
  165. delete [] f_bad_info_base_paths;
  166. f_bad_info_base_names = x;
  167. f_bad_info_base_paths = y;
  168. }
  169. }
  170. f_bad_info_base_paths[f_bad_info_bases] = strdup(info_lib_dir);
  171. f_bad_info_base_names[f_bad_info_bases] = strdup(base_name);
  172. f_bad_info_bases++;
  173. MESSAGE(cerr, "Data and code version mismatch");
  174. MESSAGE(cerr, form("Data version: v%d.%d",
  175. major_mm_version, minor_mm_version
  176. ));
  177. MESSAGE(cerr, form("Code version: v%d.%d",
  178. MAJOR, MINOR
  179. ));
  180. MESSAGE(cerr, form("infobase %s is not available.", base_name));
  181. continue;
  182. }
  183. //reset_total();
  184. _init_info_base(db_path_name, base_name, base_desc, base_uid, base_locale,
  185. mm_version(major_mm_version, minor_mm_version));
  186. //report_total();
  187. }
  188. }
  189. }
  190. map_in -> close();
  191. delete map_in ;
  192. }
  193. info_lib::~info_lib()
  194. {
  195. long ind = first();
  196. while ( ind ) {
  197. info_base* x = (*this)(ind);
  198. delete x;
  199. next(ind) ;
  200. }
  201. if ( f_bad_info_base_paths ) {
  202. for (int i=0; i<f_bad_base_array_size; i++) {
  203. delete f_bad_info_base_paths[i];
  204. }
  205. delete f_bad_info_base_paths;
  206. }
  207. if ( f_bad_info_base_names ) {
  208. for (int i=0; i<f_bad_base_array_size; i++) {
  209. delete f_bad_info_base_names[i];
  210. }
  211. delete f_bad_info_base_names;
  212. }
  213. delete f_obj_dict;
  214. }
  215. /* *********************************************************/
  216. // init all bases. play the trick by changing the db_path
  217. // value to load all info bases (each has different db_path).
  218. /* *********************************************************/
  219. info_base *
  220. info_lib::_init_info_base( const char* base_path,
  221. const char* base_name,
  222. const char* base_desc,
  223. const char* base_uid,
  224. const char* base_locale,
  225. const mm_version& v
  226. )
  227. {
  228. /*
  229. debug(cerr, base_path);
  230. debug(cerr, base_name);
  231. */
  232. //fprintf(stderr, "init_base\n");
  233. //fprintf(stderr, "base_path=%s\n", base_path);
  234. //fprintf(stderr, "base_name=%s\n", base_name);
  235. info_base *x = 0;
  236. if ( ( x = get_info_base(base_name)) == 0 ) {
  237. if ( exist_dir(base_path) == false )
  238. return 0;
  239. //fprintf(stderr, "try to init %s\n", base_name);
  240. mtry {
  241. f_obj_dict -> init_a_base((char*)base_path, (char*)base_name);
  242. x = new info_base(*f_obj_dict, set_nm_list, list_nm_list,
  243. base_path, base_name, base_desc, base_uid, base_locale,
  244. v
  245. );
  246. info_base_list.insert_as_tail(new dlist_void_ptr_cell(x));
  247. }
  248. mcatch (mmdbException &,e)
  249. {
  250. //fprintf(stderr, "in catch block\n");
  251. return 0;
  252. } end_try;
  253. }
  254. return x;
  255. }
  256. /******************************************/
  257. //
  258. // def_strings array:
  259. //
  260. // def_strings[0] : infobase name
  261. // def_strings[1] : infobase textual description
  262. // def_strings[2] : define spec file name (full path)
  263. //
  264. /******************************************/
  265. Boolean
  266. info_lib::define_info_base( char* base_name, char* base_desc,
  267. char* spec_file_path
  268. )
  269. {
  270. //MESSAGE(cerr, "define_info_base()");
  271. //debug(cerr, base_name);
  272. //debug(cerr, base_desc);
  273. //debug(cerr, spec_file_path);
  274. char new_db_path[PATHSIZ];
  275. char f_name[PATHSIZ];
  276. char base_uid[UIDSIZ];
  277. int len;
  278. const char* uid;
  279. len = MIN(strlen(info_lib_path) + strlen(base_name) + 1, PATHSIZ -1);
  280. *((char *) memcpy (new_db_path,
  281. form("%s/%s", info_lib_path, base_name),
  282. len) + len) = '\0';
  283. uid = unique_id();
  284. len = MIN(strlen(uid), UIDSIZ -1);
  285. *((char *) memcpy(base_uid, uid, len) + len) = '\0';
  286. g_mode_8_3 = 1;
  287. info_base* base = get_info_base(base_name) ;
  288. /* no checking here. DDK assures unique base name case
  289. if ( base == 0 ) {
  290. */
  291. //////////////////////////
  292. // check info base path
  293. //////////////////////////
  294. if ( check_and_create_dir(new_db_path) == false ) {
  295. throw(stringException(form("bad base bath %s", new_db_path)));
  296. }
  297. //////////////////////////
  298. // remove any old files
  299. //////////////////////////
  300. len = MIN(strlen(base_name) + strlen(DATA_FILE_SUFFIX) +1, PATHSIZ -1);
  301. *((char *) memcpy(f_name,
  302. form("%s.%s", base_name, DATA_FILE_SUFFIX),
  303. len) + len) = '\0';
  304. if ( exist_file(f_name, new_db_path) == true )
  305. del_file(f_name, new_db_path);
  306. len = MIN(strlen(base_name) + strlen(INDEX_FILE_SUFFIX) + 1, PATHSIZ -1);
  307. *((char *) memcpy(f_name,
  308. form("%s.%s", base_name, INDEX_FILE_SUFFIX),
  309. len) + len) = '\0';
  310. if ( exist_file(f_name, new_db_path) == true )
  311. del_file(f_name, new_db_path);
  312. len = MIN(strlen(base_name) + strlen(SCHEMA_FILE_SUFFIX) +1, PATHSIZ -1);
  313. *((char *) memcpy(f_name,
  314. form("%s.%s", base_name, SCHEMA_FILE_SUFFIX),
  315. len) + len) = '\0';
  316. if ( exist_file(f_name, new_db_path) == true )
  317. del_file(f_name, new_db_path);
  318. f_obj_dict -> init_a_base(spec_file_path, new_db_path, base_name);
  319. const char* lang;
  320. if ((lang = getenv("LC_ALL")) == NULL)
  321. if ((lang = getenv("LC_CTYPE")) == NULL)
  322. if ((lang = getenv("LANG")) == NULL)
  323. lang = "C.UTF-8";
  324. base = new info_base(*f_obj_dict, set_nm_list, list_nm_list,
  325. new_db_path, base_name, base_desc, base_uid,
  326. lang, mm_version(MAJOR, MINOR)
  327. );
  328. info_base_list.insert_as_tail(new dlist_void_ptr_cell(base));
  329. /*************************************/
  330. // add the base name and description
  331. // to the names file
  332. /*************************************/
  333. char* lib_nm = form("%s/%s", info_lib_path, MAP_FILE_8_3);
  334. fstream nm_out(lib_nm, ios::out | ios::app);
  335. // fstream nm_out(lib_nm, ios::app, open_file_prot());
  336. if ( !nm_out ) {
  337. MESSAGE(cerr, form("can't open %s/%s for append",
  338. info_lib_path, MAP_FILE_8_3)
  339. );
  340. throw(streamException(nm_out.rdstate()));
  341. }
  342. if ( bytes(lib_nm) == 0 ) {
  343. char* lib_entry = form("%s\t%s\n", info_lib_name, unique_id());
  344. if ( !(nm_out << lib_entry) ) {
  345. MESSAGE(cerr,
  346. form("write %s.%s failed", info_lib_path, MAP_FILE_8_3));
  347. throw(streamException(nm_out.rdstate()));
  348. }
  349. }
  350. char* base_entry = form("%s\t%s\t%s\t%s\t%d\t%d\n",
  351. base_name, base_desc, base_uid,
  352. lang, MAJOR, MINOR
  353. );
  354. if ( !(nm_out << base_entry) ) {
  355. MESSAGE(cerr, form("write %s.%s failed", info_lib_path, MAP_FILE_8_3));
  356. throw(streamException(nm_out.rdstate()));
  357. }
  358. nm_out.close();
  359. if ( nm_out.fail() ) {
  360. MESSAGE(cerr, form("close %s.%s failed", info_lib_path, MAP_FILE_8_3));
  361. throw(streamException(nm_out.rdstate()));
  362. }
  363. //}
  364. //MESSAGE(cerr, "define() done");
  365. return true;
  366. }
  367. info_base* info_lib::get_info_base(const char* info_base_nm)
  368. {
  369. long ind = first();
  370. //debug(cerr, ind);
  371. while ( ind ) {
  372. info_base* x = (*this)(ind);
  373. /*
  374. debug(cerr, int(x));
  375. debug(cerr, x -> base_name);
  376. debug(cerr, info_base_nm);
  377. */
  378. if ( strcmp ( x -> base_name, info_base_nm) == 0 )
  379. return x;
  380. next(ind) ;
  381. }
  382. return 0;
  383. }
  384. /* inline */
  385. /*
  386. int info_lib::num_of_bases()
  387. {
  388. return info_base_list.count();
  389. }
  390. */
  391. /*************************/
  392. // iteration funcstions
  393. /*************************/
  394. /* inline */
  395. /*
  396. int info_lib::first()
  397. {
  398. return info_base_list.first();
  399. }
  400. info_base* info_lib::operator()(int ind)
  401. {
  402. return (info_base*)(((dlist_void_ptr_cell*)ind)->void_ptr());
  403. }
  404. void info_lib::next(int& ind)
  405. {
  406. info_base_list.next(ind) ;
  407. }
  408. */
  409. int info_lib::bad_infobases()
  410. {
  411. return f_bad_info_bases;
  412. }
  413. const char* info_lib::get_bad_infobase_path(int x)
  414. {
  415. if ( x <= 0 || x > f_bad_info_bases )
  416. return 0;
  417. return f_bad_info_base_paths[x-1];
  418. }
  419. const char* info_lib::get_bad_infobase_name(int x)
  420. {
  421. if ( x <= 0 || x > f_bad_info_bases )
  422. return 0;
  423. return f_bad_info_base_names[x-1];
  424. }
  425. info_base*
  426. info_lib::getInfobaseByComponent(const char *locator_string, enum TestSelector sel)
  427. {
  428. if ( locator_string == 0 )
  429. return 0;
  430. info_base* ib = 0;
  431. long ind = first();
  432. while ( ind ) {
  433. ib = (*this)(ind);
  434. if (ib==0)
  435. throw(stringException("null info_base ptr"));
  436. mtry { // since an infobase may not have any graphics, we catch
  437. // any exceptions there and try next infobase.
  438. switch (sel) {
  439. case LOC:
  440. {
  441. locator_smart_ptr loc(ib, locator_string);
  442. //fprintf(stderr, "inside-loc-string=%s\n", loc.inside_node_locator_str());
  443. //fprintf(stderr, "loc-string=%s\n", locator_string);
  444. if ( strcmp( loc.inside_node_locator_str(), locator_string) == 0 ) {
  445. return ib;
  446. }
  447. }
  448. case GRA:
  449. {
  450. graphic_smart_ptr graphic(ib, locator_string);
  451. if ( strcmp( graphic.locator(), locator_string) == 0 ) {
  452. return ib;
  453. }
  454. }
  455. }
  456. }
  457. mcatch (mmdbException &,e)
  458. {
  459. } end_try;
  460. next(ind);
  461. }
  462. return 0;
  463. }
  464. info_base**
  465. info_lib::getInfobasesByComponent(char **locator_strings, int count, enum TestSelector sel)
  466. {
  467. info_base** ibs = new info_basePtr[count];
  468. int i;
  469. for ( i=0; i<count; ibs[i++] = 0 );
  470. info_base* ib = 0;
  471. long ind = first();
  472. while ( ind ) {
  473. ib = (*this)(ind);
  474. if (ib == 0)
  475. throw(stringException("null info_base ptr"));
  476. for ( i=0; i<count; i++ ) {
  477. mtry {
  478. if ( locator_strings[i] && ibs[i] == 0 ) {
  479. switch (sel) {
  480. case LOC:
  481. {
  482. locator_smart_ptr loc(ib, locator_strings[i]);
  483. if ( strcmp( loc.inside_node_locator_str(),
  484. locator_strings[i]) == 0
  485. )
  486. ibs[i] = ib;
  487. }
  488. break;
  489. case GRA:
  490. {
  491. graphic_smart_ptr graphic(ib, locator_strings[i]);
  492. if ( strcmp( graphic.locator(),
  493. locator_strings[i]) == 0
  494. )
  495. ibs[i] = ib;
  496. }
  497. break;
  498. }
  499. }
  500. }
  501. mcatch (mmdbException &,e)
  502. {
  503. } end_try;
  504. }
  505. next(ind);
  506. }
  507. return ibs;
  508. }