Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / api / info_lib.C
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 librararies 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
50
51 #include "unique_id.h"
52 #include "api/info_lib.h"
53 #include "utility/db_version.h"
54 #include "oliasdb/locator_hd.h"
55 #include "oliasdb/graphic_hd.h"
56
57 #ifdef DtinfoClient
58 #include <lib/DtSvc/DtUtil2/LocaleXlate.h>
59 #endif
60
61 /*
62 extern void report_total();
63 extern void reset_total();
64 */
65
66 int g_mode_8_3 = 0;
67
68
69 typedef char* charPtr;
70
71 info_lib::info_lib(char** set_name_array, char** list_name_array,
72                    char* info_lib_dir, char* selected_base_name, 
73                    char* infoLibName, int des) :
74 set_nm_list(set_name_array), list_nm_list(list_name_array),
75 f_bad_base_array_size(0), f_bad_info_bases(0), 
76 f_bad_info_base_names(0), f_bad_info_base_paths(0), f_descriptor(des)
77
78 {
79 //debug(cerr, info_lib_dir);
80 //debug(cerr, infoLibName);
81
82    int len;
83
84    f_obj_dict = new object_dict;
85
86    if ( info_lib_dir == 0 ) {
87       throw(stringException("NULL info lib path"));
88    }
89
90    if ( check_and_create_dir(info_lib_dir) == false )
91       throw(stringException(
92         form("infolib %s does not exist or can't be created", info_lib_dir)
93                            )
94            );
95
96    len = MIN(strlen(info_lib_dir), PATHSIZ -1);
97    *((char *) memcpy (info_lib_path, info_lib_dir, len) + len) = '\0';
98    len = MIN(strlen(infoLibName), PATHSIZ -1);
99    *((char *) memcpy (info_lib_name, infoLibName, len) + len) = '\0';
100
101    fstream *map_in = 0;
102
103    if ( exist_file(MAP_FILE_8_3, info_lib_dir) == true ) {
104
105       map_in = new fstream(form("%s/%s", info_lib_dir, MAP_FILE_8_3), ios::in);
106
107       g_mode_8_3 = 1;
108
109       if ( !map_in -> getline(info_lib_name, PATHSIZ, '\t') ||
110            !map_in -> getline(info_lib_uid, UIDSIZ, '\n')
111          )
112       {
113          throw(stringException(
114            form("infolib %s does not have correct name-id entry", info_lib_dir)
115                               )
116               );
117       }
118    } else
119    if ( exist_file(MAP_FILE, info_lib_dir) == true )
120       map_in = new fstream(form("%s/%s", info_lib_dir, MAP_FILE), ios::in);
121    else {
122       return;
123    }
124
125    char base_name[PATHSIZ];
126    char base_desc[PATHSIZ];
127    char base_uid[UIDSIZ];
128    char base_locale[PATHSIZ];
129    char db_path_name[PATHSIZ];
130
131    int major_mm_version = 0;
132    int minor_mm_version = 0;
133
134
135    while ( map_in -> getline(base_name, PATHSIZ, '\t') ) {
136
137       map_in -> getline(base_desc, PATHSIZ, '\t');
138
139       if ( g_mode_8_3 == 1 ) {
140          map_in -> getline(base_uid, PATHSIZ, '\t');
141          map_in -> getline(base_locale, PATHSIZ, '\t');
142       }
143       else
144          base_uid[0] = 0;
145
146       (*map_in) >> major_mm_version >> minor_mm_version;
147
148       map_in -> get();
149
150       if ( base_name[0] != CommentChar ) {
151
152 //debug(cerr, base_name);
153 //debug(cerr, base_desc);
154 //fprintf(stderr, "base_name = %s\n", base_name);
155
156          char* mmdb_lang = getenv("MMDB_LANG");
157 #ifdef MMDB_LANG_DEBUG
158          cerr << "base_locale=" << base_locale << endl;
159          if (mmdb_lang)
160            cerr << "mmdb_lang=" << mmdb_lang << endl;
161 #endif
162
163          if ((selected_base_name == 0 ||
164               strcmp(selected_base_name, base_name) == 0) &&
165              (mmdb_lang == NULL ||
166               strcmp(mmdb_lang, base_locale) == 0 ||
167               strcmp("C.ISO-8859-1", base_locale) == 0))
168          {
169
170             len = MIN(strlen(info_lib_dir) + strlen(base_name) +1, PATHSIZ -1);
171             *((char *) memcpy (db_path_name,
172                                form("%s/%s", info_lib_dir, base_name),
173                                len) + len) = '\0';
174  
175             mm_version mmv_code(MAJOR, MINOR);
176             mm_version mmv_base_data(2, 1);
177             mm_version mmv_data(major_mm_version, minor_mm_version);
178
179 ///////////////////////////////////////////////
180 // Hardcoded knowledge of discontinuation of 
181 // backward compatibility
182 ///////////////////////////////////////////////
183             if ( mmv_data < mmv_base_data ||
184                  mmv_data == mmv_base_data || 
185                  mmv_code < mmv_data
186                ) 
187             {
188
189
190                if ( f_bad_base_array_size == 0 ||
191                     f_bad_base_array_size <= f_bad_info_bases 
192                   ) 
193                {
194                  
195                  if ( f_bad_base_array_size == 0 ) {
196                     f_bad_base_array_size = 10;
197                     f_bad_info_base_names = new charPtr[f_bad_base_array_size];
198                     f_bad_info_base_paths = new charPtr[f_bad_base_array_size];
199
200                     for (int i=0; i<f_bad_base_array_size; i++) {
201                       f_bad_info_base_paths[i] = 0;
202                       f_bad_info_base_names[i] = 0;
203                     }
204
205                  } else {
206                     char** x = new charPtr[2*f_bad_base_array_size];
207                     char** y = new charPtr[2*f_bad_base_array_size];
208
209                     for (int i=0; i<2*f_bad_base_array_size; i++) {
210                       x[i] = 0;
211                       y[i] = 0;
212                     }
213
214                     memcpy(x, f_bad_info_base_names, sizeof(charPtr)*f_bad_base_array_size);
215                     memcpy(y, f_bad_info_base_paths, sizeof(charPtr)*f_bad_base_array_size);
216                     f_bad_base_array_size *= 2;
217
218                     delete f_bad_info_base_names;
219                     delete f_bad_info_base_paths;
220
221                     f_bad_info_base_names = x;
222                     f_bad_info_base_paths = y;
223                      
224                  }
225
226
227                } 
228
229
230                f_bad_info_base_paths[f_bad_info_bases] = strdup(info_lib_dir);
231                f_bad_info_base_names[f_bad_info_bases] = strdup(base_name);
232
233                f_bad_info_bases++;
234
235                MESSAGE(cerr, "Data and code version mismatch");
236
237                MESSAGE(cerr, form("Data version: v%d.%d",
238                     major_mm_version, minor_mm_version
239                            ));
240
241                MESSAGE(cerr, form("Code version: v%d.%d", 
242                         MAJOR, MINOR
243                            ));
244
245                MESSAGE(cerr, form("infobase %s is not available.", base_name));
246
247                continue;
248             }
249
250 //reset_total();
251             _init_info_base(db_path_name, base_name, base_desc, base_uid, base_locale,
252                             mm_version(major_mm_version, minor_mm_version));
253 //report_total();
254          }
255       }
256
257    }
258    map_in -> close();
259    delete map_in ;
260 }
261
262 info_lib::~info_lib()
263 {
264    long ind = first();
265    while ( ind ) {
266
267      info_base* x = (*this)(ind);
268      delete x;
269
270      next(ind) ;
271    }
272
273    if ( f_bad_info_base_paths ) {
274       for (int i=0; i<f_bad_base_array_size; i++) {
275         delete f_bad_info_base_paths[i];
276       }
277       delete f_bad_info_base_paths;
278    }
279
280
281    if ( f_bad_info_base_names ) {
282       for (int i=0; i<f_bad_base_array_size; i++) {
283         delete f_bad_info_base_names[i];
284       }
285       delete f_bad_info_base_names;
286    }
287
288    delete f_obj_dict;
289 }
290
291
292 /* *********************************************************/
293 // init all bases. play the trick by changing the db_path 
294 // value to load all info bases (each has different db_path).
295 /* *********************************************************/
296    
297 info_base *
298 info_lib::_init_info_base( const char* base_path, 
299                            const char* base_name, 
300                            const char* base_desc,
301                            const char* base_uid,
302                            const char* base_locale,
303                            const mm_version& v
304                          )
305 {
306
307 /*
308 debug(cerr, base_path);
309 debug(cerr, base_name);
310 */
311
312 //fprintf(stderr, "init_base\n");
313 //fprintf(stderr, "base_path=%s\n", base_path);
314 //fprintf(stderr, "base_name=%s\n", base_name);
315
316    info_base *x = 0;
317
318    if ( ( x = get_info_base(base_name)) == 0 ) {
319
320      if ( exist_dir(base_path) == false )
321         return 0;
322
323 //fprintf(stderr, "try to init %s\n", base_name);
324
325      mtry {
326         f_obj_dict -> init_a_base((char*)base_path, (char*)base_name);
327
328         x = new info_base(*f_obj_dict, set_nm_list, list_nm_list,
329                        base_path, base_name, base_desc, base_uid, base_locale,
330                        v
331                       );
332
333         info_base_list.insert_as_tail(new dlist_void_ptr_cell(x));
334      }
335
336      mcatch (mmdbException &,e)
337      {
338 //fprintf(stderr, "in catch block\n");
339        return 0;
340      } end_try;
341
342    }
343
344    return x;
345 }
346
347
348 /******************************************/
349 // 
350 // def_strings array:
351 //
352 //   def_strings[0] : infobase name
353 //   def_strings[1] : infobase textual description
354 //   def_strings[2] : define spec file name (full path)
355 //
356 /******************************************/
357
358 Boolean 
359 info_lib::define_info_base( char* base_name, char* base_desc, 
360                             char* spec_file_path
361                           )
362 {
363 //MESSAGE(cerr, "define_info_base()");
364 //debug(cerr, base_name);
365 //debug(cerr, base_desc);
366 //debug(cerr, spec_file_path);
367
368    char new_db_path[PATHSIZ]; 
369    char f_name[PATHSIZ]; 
370    char base_uid[UIDSIZ]; 
371    int len;
372    const char* uid;
373
374    len = MIN(strlen(info_lib_path) + strlen(base_name) + 1, PATHSIZ -1);
375    *((char *) memcpy (new_db_path,
376                       form("%s/%s", info_lib_path, base_name),
377                       len) + len) = '\0';
378
379    uid = unique_id();
380    len = MIN(strlen(uid), UIDSIZ -1);
381    *((char *) memcpy(base_uid, uid, len) + len) = '\0';
382
383    g_mode_8_3 = 1;
384
385    info_base* base = get_info_base(base_name) ;
386
387 /* no checking here. DDK assures unique base name case
388    if ( base == 0 ) {
389 */
390       
391 //////////////////////////
392 // check info base path
393 //////////////////////////
394       if ( check_and_create_dir(new_db_path) == false ) {
395          throw(stringException(form("bad base bath %s", new_db_path)));
396       }
397
398 //////////////////////////
399 // remove any old files 
400 //////////////////////////
401
402       len = MIN(strlen(base_name) + strlen(DATA_FILE_SUFFIX) +1, PATHSIZ -1);
403       *((char *) memcpy(f_name,
404                         form("%s.%s", base_name, DATA_FILE_SUFFIX),
405                         len) + len) = '\0';
406       if ( exist_file(f_name, new_db_path) == true )
407          del_file(f_name, new_db_path);
408
409       len = MIN(strlen(base_name) + strlen(INDEX_FILE_SUFFIX) + 1, PATHSIZ -1);
410       *((char *) memcpy(f_name,
411                         form("%s.%s", base_name, INDEX_FILE_SUFFIX),
412                         len) + len) = '\0';
413       if ( exist_file(f_name, new_db_path) == true )
414          del_file(f_name, new_db_path);
415
416       len = MIN(strlen(base_name) + strlen(SCHEMA_FILE_SUFFIX) +1, PATHSIZ -1);
417       *((char *) memcpy(f_name,
418                         form("%s.%s", base_name, SCHEMA_FILE_SUFFIX),
419                         len) + len) = '\0';
420       if ( exist_file(f_name, new_db_path) == true )
421          del_file(f_name, new_db_path);
422
423
424       f_obj_dict -> init_a_base(spec_file_path, new_db_path, base_name);
425
426       const char* lang;
427       if ((lang = getenv("LC_ALL")) == NULL)
428         if ((lang = getenv("LC_CTYPE")) == NULL)
429           if ((lang = getenv("LANG")) == NULL)
430             lang = "C";
431
432 #ifdef DtinfoClient
433       _DtXlateDb db    = NULL;
434       char* std_locale = NULL;
435
436       if (_DtLcxOpenAllDbs(&db) == 0)
437       {
438         char platform[_DtPLATFORM_MAX_LEN + 1];
439         int execver, compver;
440
441         if (_DtXlateGetXlateEnv(db, platform, &execver, &compver) == 0)
442         {
443           _DtLcxXlateOpToStd(db, platform, compver, DtLCX_OPER_SETLOCALE,
444                                         lang, &std_locale, NULL, NULL, NULL);
445         }
446         _DtLcxCloseDb(&db);
447         db = NULL;
448       }
449 #endif
450
451       base = new info_base(*f_obj_dict, set_nm_list, list_nm_list,
452                            new_db_path, base_name, base_desc, base_uid,
453 #ifdef DtinfoClient
454                            std_locale ? std_locale : lang,
455 #else
456                            lang,
457 #endif
458                            mm_version(MAJOR, MINOR)
459                           );
460
461       info_base_list.insert_as_tail(new dlist_void_ptr_cell(base));
462
463 /*************************************/
464 // add the base name and description
465 // to the names file
466 /*************************************/
467       char* lib_nm = form("%s/%s", info_lib_path, MAP_FILE_8_3);
468
469       fstream nm_out(lib_nm, ios::out | ios::app);
470 //    fstream nm_out(lib_nm, ios::app, open_file_prot());
471
472       if ( !nm_out ) {
473          MESSAGE(cerr, form("can't open %s/%s for append", 
474                             info_lib_path, MAP_FILE_8_3)
475                 );
476          throw(streamException(nm_out.rdstate()));
477       }
478
479       if ( bytes(lib_nm) == 0 ) {
480          char* lib_entry = form("%s\t%s\n", info_lib_name, unique_id());
481
482          if ( !(nm_out << lib_entry) ) {
483             MESSAGE(cerr, 
484                form("write %s.%s failed", info_lib_path, MAP_FILE_8_3));
485             throw(streamException(nm_out.rdstate()));
486          }
487       }
488
489       char* base_entry = form("%s\t%s\t%s\t%s\t%d\t%d\n", 
490                               base_name, base_desc, base_uid,
491 #ifdef DtinfoClient
492                               std_locale ? std_locale: lang,
493 #else
494                               lang,
495 #endif
496                               MAJOR, MINOR
497                              );
498 #ifdef DtinfoClient
499       if (std_locale)
500         free(std_locale);
501 #endif
502
503       if ( !(nm_out << base_entry) ) {
504          MESSAGE(cerr, form("write %s.%s failed", info_lib_path, MAP_FILE_8_3));
505          throw(streamException(nm_out.rdstate()));
506       }
507
508       nm_out.close();
509
510       if ( nm_out.fail() ) {
511          MESSAGE(cerr, form("close %s.%s failed", info_lib_path, MAP_FILE_8_3));
512          throw(streamException(nm_out.rdstate()));
513       }
514
515    //}
516
517
518 //MESSAGE(cerr, "define() done");
519    return true;
520 }
521
522 info_base* info_lib::get_info_base(const char* info_base_nm)
523 {
524    long ind = first();
525 //debug(cerr, ind);
526
527    while ( ind ) {
528      info_base* x = (*this)(ind);  
529
530 /*
531 debug(cerr, int(x));
532 debug(cerr, x -> base_name);
533 debug(cerr, info_base_nm);
534 */
535
536      if ( strcmp ( x -> base_name, info_base_nm) == 0 )
537         return x;
538      next(ind) ;
539    }
540    return 0;
541 }
542
543 /* inline */
544 /*
545 int info_lib::num_of_bases()
546 {
547    return info_base_list.count();
548 }
549 */
550
551 /*************************/
552 // iteration funcstions
553 /*************************/
554 /* inline */
555 /*
556 int info_lib::first()
557 {
558    return info_base_list.first();
559 }
560
561 info_base* info_lib::operator()(int ind)
562 {
563    return (info_base*)(((dlist_void_ptr_cell*)ind)->void_ptr());  
564 }
565
566 void info_lib::next(int& ind)
567 {
568    info_base_list.next(ind) ;
569 }
570 */
571
572
573 int info_lib::bad_infobases()
574 {
575    return f_bad_info_bases;
576
577 }
578    
579 const char* info_lib::get_bad_infobase_path(int x)
580 {
581    if ( x <= 0 || x > f_bad_info_bases )
582       return 0;
583
584    return f_bad_info_base_paths[x-1];
585 }
586    
587 const char* info_lib::get_bad_infobase_name(int x)
588 {
589    if ( x <= 0 || x > f_bad_info_bases )
590       return 0;
591
592    return f_bad_info_base_names[x-1];
593 }
594
595
596 info_base* 
597 info_lib::getInfobaseByComponent(const char *locator_string, enum TestSelector sel)
598 {
599
600    if ( locator_string == 0 )
601       return 0;
602
603    info_base* ib = 0;
604
605    long ind = first();
606
607    while ( ind ) {
608
609       ib =  (*this)(ind);
610
611       if (ib==0)
612          throw(stringException("null info_base ptr"));
613
614       mtry { // since an infobase may not have any graphics, we catch
615             // any exceptions there and try next infobase.
616
617          switch (sel) {
618           case LOC:
619            {
620             locator_smart_ptr loc(ib, locator_string);
621    
622 //fprintf(stderr, "inside-loc-string=%s\n", loc.inside_node_locator_str());
623 //fprintf(stderr, "loc-string=%s\n", locator_string);
624             if ( strcmp( loc.inside_node_locator_str(), locator_string) == 0 ) {
625                return ib;
626             }
627    
628            }
629           case GRA:
630            {
631             graphic_smart_ptr graphic(ib, locator_string);
632    
633             if ( strcmp( graphic.locator(), locator_string) == 0 ) {
634                return ib;
635             }
636            }
637          }
638       }
639
640       mcatch (mmdbException &,e)
641       {
642       } end_try;
643
644
645       next(ind);
646    }
647
648    return 0;
649 }
650
651 info_base** 
652 info_lib::getInfobasesByComponent(char **locator_strings, int count, enum TestSelector sel)
653 {
654    info_base** ibs = new info_basePtr[count];
655    int i;
656    for ( i=0; i<count; ibs[i++] = 0 );
657
658    info_base* ib = 0;
659
660    long ind = first();
661
662    while ( ind ) {
663
664       ib =  (*this)(ind);
665
666       if (ib == 0)
667          throw(stringException("null info_base ptr"));
668
669       for ( i=0; i<count; i++ ) {
670
671          mtry {
672    
673             if ( locator_strings[i] && ibs[i] == 0 ) {  
674               switch (sel) {
675                case LOC:
676               {
677                   locator_smart_ptr loc(ib, locator_strings[i]);
678    
679                   if ( strcmp( loc.inside_node_locator_str(), 
680                             locator_strings[i]) == 0 
681                   )
682                      ibs[i] = ib;
683                  }
684               break;
685    
686                case GRA:
687               {
688                   graphic_smart_ptr graphic(ib, locator_strings[i]);
689    
690                   if ( strcmp( graphic.locator(), 
691                             locator_strings[i]) == 0 
692                   )
693                      ibs[i] = ib;
694                  }
695               break;
696               }
697             }
698          }
699
700          mcatch (mmdbException &,e)
701          {
702          } end_try;
703
704       }
705
706       next(ind);
707    }
708
709    return ibs;
710 }
711