2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 //%% (c) Copyright 1993, 1994 Hewlett-Packard Company
24 //%% (c) Copyright 1993, 1994 International Business Machines Corp.
25 //%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
26 //%% (c) Copyright 1993, 1994 Novell, Inc.
27 //%% $TOG: mp_type_comp.C /main/4 1999/10/14 18:37:58 mgreess $
32 * Copyright (c) 1990 by Sun Microsystems, Inc.
34 * ToolTalk type compiler. Performs syntax and semantics checks on
35 * type input file and then writes out the type table in xdr format
36 * or in Classing Engine format.
42 #if defined(__linux__)
45 #if defined(sgi) || defined(CSRG_BASED)
48 #include "mp/mp_global.h"
52 #include "mp_types_table.h"
53 #include "mp_typedb.h"
54 #include "util/copyright.h"
55 #include "util/tt_global_env.h"
56 #include "util/tt_xdr_version.h"
57 #include "util/tt_port.h"
58 #include "util/tt_gettext.h"
60 #define _TT_DBCLIENT_SIDE
61 #include "db/db_server.h"
63 typedef void (*cmd_fn)();
68 static char PatchID[] = "Patch Id: 100626_03.";
69 static int Patch_ID100626_03;
73 _Tt_typedbLevel cedb = TypedbNone;
75 _Tt_string_list_ptr cargs;
77 int option_remap_ptypes = 1;
78 _Tt_string cpp_options("");
81 print_usage_and_exit()
83 _tt_syslog(stderr, LOG_ERR, "%s",
84 catgets(_ttcatd, 4, 2,
86 "tt_type_comp [-s] [-d db] [-mM] source_file\n"
87 "tt_type_comp [-s] [-d db] -r type ...\n"
88 "-M merge source types into specified database, not updating existing types\n"
89 "-m merge, but update existing types. Default.\n"
90 "-r remove source types from the specified database\n"
91 "-d db database to operate on. One of: user, system, or network. Default: user\n"
92 "-G perform garbage collection on the ToolTalk database server.\n"
94 "tt_type_comp [-sE] -p|O|P [-d db]\n"
95 "tt_type_comp [-s] -p|O|P compiled_file\n"
96 "-O enumerate on stdout the names of all otypes read\n"
97 "-P enumerate on stdout the names of all ptypes read\n"
98 "-p pretty-print on stdout all the ToolTalk types read\n"
99 "-E use the Classing Engine database(s) instead of the XDR database(s)\n"
100 "-d db database to read from. One of: user, system, or network. Default: all\n"
102 "tt_type_comp [-s] -x [-o compiled_file] source_file\n"
103 "-x compile types from source_file (or stdin, if file is \"-\")\n"
104 "-o write compiled types to compiled_file (or stdout, if file is \"-\")\n"
105 " Default: source_file.xdr, or \"types.xdr\" if source is stdin\n"
107 "tt_type_comp [-hv]\n"
108 "-v print out version number\n"
109 "-h print out this message\n"
110 "-s do not print out any status messages.\n"
112 "These cpp options will be passed through:\n"
113 " -undef -Dname -Idirectory -Uname -Ydirectory"));
119 read_types(_Tt_string file, _Tt_typedb_ptr &db)
121 _Tt_parse_status result;
122 _Tt_types_table *table;
124 table = new _Tt_types_table(stdin, result);
126 table = new _Tt_types_table(file, result);
129 if (result == _TT_PARSE_OK) {
130 db = new _Tt_typedb();
132 if (table->check_semantics() != _TT_PARSE_OK) {
133 _tt_syslog(stderr, LOG_ERR,
134 catgets(_ttcatd, 4, 3,
135 "Semantic error in types file"));
138 db->ptable = table->ptypes();
139 db->otable = table->otypes();
141 _Tt_string msg = catgets(_ttcatd, 4, 4,
142 "Not a valid ToolTalk types file" );
143 if (file.len() > 0) {
144 msg = msg.cat( ": " ).cat( file );
146 _tt_syslog(stderr, LOG_ERR, msg);
157 db = new _Tt_typedb();
158 if (db->init_ce(cedb) != TT_OK) {
159 _tt_syslog(stderr, LOG_ERR,
160 catgets(_ttcatd, 4, 5,
161 "Cannot read any ToolTalk types "
162 "from Classing Engine database"));
165 db->pretty_print(stdout);
175 _Tt_ptype_table_cursor db_ptypes;
176 _Tt_otype_table_cursor db_otypes;
180 Tt_status st = TT_OK;
182 if (cedb == TypedbNone) {
187 _tt_syslog(stderr, LOG_ERR,
188 catgets(_ttcatd, 4, 6,
189 "Merging Classing Engine tables is no "
190 "longer supported"));
194 xdb = new _Tt_typedb();
195 read_types(ifile, db);
197 if ((st=xdb->init_xdr(cedb)) != TT_OK) {
198 // if TT_ERR_DBEXIST is returned from init_ce
199 // we continue with the merge. It just means
200 // we're starting up in an environment where
201 // no tooltalk namespaces exist in any of the
202 // Classing Engine databases.
203 if (st != TT_ERR_DBEXIST) {
204 if (st == TT_ERR_NO_MATCH) {
205 _tt_syslog(stderr, LOG_ERR,
206 catgets(_ttcatd, 4, 7,
207 "Cannot read types in %s data"
208 "base - version mismatch"),
209 _Tt_typedb::level_name(cedb));
211 _tt_syslog(stderr, LOG_ERR,
212 catgets(_ttcatd, 4, 8,
213 "Cannot read types in %s data"
215 _Tt_typedb::level_name(cedb));
218 * The most common way for this to fail seems to be
219 * to not have OPENWINHOME set. Suggest this
222 if (0==getenv("OPENWINHOME")) {
223 _tt_syslog(stderr, LOG_ERR,
224 catgets(_ttcatd, 4, 9,
225 "$OPENWINHOME not set"));
231 if (! xdb->begin_write(cedb)) {
232 _tt_syslog(stderr, LOG_ERR,
233 catgets(_ttcatd, 4, 10,
234 "Cannot initialize %s database for writing"),
235 _Tt_typedb::level_name(cedb));
239 db_otypes.reset(db->otable);
240 while (db_otypes.next()) {
241 ot = xdb->otable->lookup(db_otypes->otid());
242 exists = (! ot.is_null());
247 if (! xdb->remove_otype(db_otypes->otid())) {
248 _tt_syslog(stderr, LOG_ERR,
249 catgets(_ttcatd, 4, 11,
250 "Could not remove old "
251 "definition for %s"),
252 (char *)db_otypes->otid());
257 if (! _tt_global->silent) {
258 printf( "%s %s...\n",
260 ? catgets(_ttcatd, 4, 12, "Overwriting")
261 : catgets(_ttcatd, 4, 13, "Writing"),
262 (char *)db_otypes->otid());
264 if (! xdb->insert(*db_otypes)) {
265 _tt_syslog(stderr, LOG_ERR,
266 catgets(_ttcatd, 4, 14, "Could not add "
267 "new definition for %s"),
268 (char *)db_otypes->otid());
274 db_ptypes.reset(db->ptable);
275 while (db_ptypes.next()) {
276 pt = xdb->ptable->lookup(db_ptypes->ptid());
277 exists = (! pt.is_null());
282 if (! xdb->remove_ptype(db_ptypes->ptid())) {
283 _tt_syslog(stderr, LOG_ERR,
284 catgets(_ttcatd, 4, 15,
285 "Could not remove old "
286 "definition for %s"),
287 (char *)db_ptypes->ptid());
291 if (! _tt_global->silent) {
294 ? catgets(_ttcatd, 4, 16, "Overwriting")
295 : catgets(_ttcatd, 4, 17, "Writing"),
296 (char *)db_ptypes->ptid());
298 if (! xdb->insert(*db_ptypes)) {
299 _tt_syslog(stderr, LOG_ERR,
300 catgets(_ttcatd, 4, 18, "Could not add "
301 "new definition for %s"),
302 (char *)db_ptypes->ptid());
307 if (! xdb->end_write()) {
308 // diagnostic emitted by ::end_write()
321 f_merge_no_overwrite()
328 f_list_types(int otypes)
334 if (cedb == TypedbNone) {
337 db = new _Tt_typedb();
339 if (ifile.len() > 0) {
341 status = db->init_xdr( stdin );
343 status = db->init_xdr( ifile );
346 status = db->init_xdr( cedb );
349 status = db->init_ce( cedb );
351 if (status != TT_OK) {
352 if (status == TT_ERR_NO_MATCH) {
353 _tt_syslog(stderr, LOG_ERR,
354 catgets(_ttcatd, 4, 19, "Version mismatch "
355 "in compiled types"));
357 _tt_syslog(stderr, LOG_ERR,
358 catgets(_ttcatd, 4, 20, "Cannot read types "
362 // The most common way for this to fail seems to be
363 // to not have OPENWINHOME set. Suggest this
366 if (0==getenv("OPENWINHOME")) {
367 _tt_syslog(stderr, LOG_ERR,
368 catgets(_ttcatd, 4, 21,
369 "$OPENWINHOME not set"));
374 _Tt_otype_table_cursor db_otypes;
375 db_otypes.reset(db->otable);
376 while (db_otypes.next()) {
377 printf("%s\n", (char *)db_otypes->otid());
380 _Tt_ptype_table_cursor db_ptypes;
381 db_ptypes.reset(db->ptable);
382 while (db_ptypes.next()) {
383 printf("%s\n", (char *)db_ptypes->ptid());
403 _Tt_string_list_cursor argc;
410 if (cedb == TypedbNone) {
413 db = new _Tt_typedb();
414 if ((option_xdr && (err = db->init_xdr(cedb)) != TT_OK) ||
415 (!option_xdr && (err = db->init_ce(cedb)) != TT_OK)) {
416 if (err == TT_ERR_NO_MATCH) {
417 _tt_syslog(stderr, LOG_ERR,
418 catgets(_ttcatd, 4, 22,
419 "Cannot read types in %s data"
420 "base - version mismatch"),
421 _Tt_typedb::level_name(cedb));
423 _tt_syslog(stderr, LOG_ERR,
424 catgets(_ttcatd, 4, 23,
425 "Cannot read types in %s database"),
426 _Tt_typedb::level_name(cedb));
429 * The most common way for this to fail seems to be
430 * to not have OPENWINHOME set. Suggest this
433 if (0==getenv("OPENWINHOME")) {
434 _tt_syslog(stderr, LOG_ERR,
435 catgets(_ttcatd, 4, 24,
436 "$OPENWINHOME not set"));
441 if (! db->begin_write(cedb)) {
442 // diagnostic emitted
447 while (argc.next()) {
448 pt = db->ptable->lookup(*argc);
450 ot = db->otable->lookup(*argc);
451 if (! ot.is_null()) {
452 if (! _tt_global->silent) {
453 printf(catgets(_ttcatd, 4, 25,
454 "Removing otype %s\n"),
458 db->remove_otype(*argc);
461 if (! _tt_global->silent) {
462 printf(catgets(_ttcatd, 4, 26,
463 "Removing ptype %s\n"),
466 db->remove_ptype(*argc);
472 if (! db->end_write()) {
486 if (ofile.len() == 0) {
490 ofile = ifile.cat(".xdr");
493 read_types(ifile, db);
497 status = db->write( stdout );
499 status = db->write( ofile );
501 if (status != TT_OK) {
505 _Tt_typedb::send_saved( ofile );
506 printf(catgets(_ttcatd, 4, 27, "output written to %s\n"),
518 db = new _Tt_typedb();
519 if (ifile.len() != 0) {
521 status = db->init_xdr( stdin );
523 status = db->init_xdr( ifile );
526 if (cedb == TypedbNone) {
529 status = db->init_xdr(cedb);
531 if (status != TT_OK) {
532 // diagnostic emitted
536 db->pretty_print(stdout);
541 // This sends messages to the 'default' ToolTalk files.
542 // This forces an attempt to contact the sessions registered for
543 // each file, if they are dead, then a deleteSession() is sent
544 // to clear out (garbage collect) the information for that dead
545 // session. Dead sessions can occur in the dbserver if the system
546 // that had registered died without un-registering with dbserver
552 _Tt_db_client dbClient;
553 _Tt_string sessionId;
555 if (dbClient.getConnectionResults() == TT_DB_OK) {
557 _Tt_string_list *sessions;
558 sessions = dbClient.get_all_sessions();
560 if (sessions != NULL && sessions->count() > 0) {
562 // Delete the list of sessions that are dead.
566 sessionId = sessions->top();
568 = tt_default_session_set(sessionId))
570 dbClient.delete_session(sessionId);
573 } while(sessions->count() > 0);
575 dbClient.garbage_collect_in_server();
581 process_args(int argc, char **argv)
591 // default function is to merge types
592 fn = f_merge_overwrite;
594 // Need to parse out the cpp options specially because they
595 // don't work with getopt
596 for (int i = 1; i < argc; i++) {
597 if (argv[i][0] == '-' &&
598 (argv[i][1] == 'u' || argv[i][1] == 'D' ||
599 argv[i][1] == 'I' || argv[i][1] == 'U' ||
600 argv[i][1] == 'Y')) {
601 if (argv[i][1] == 'u' &&
602 strcmp(argv[i], "-undef") != 0) {
603 print_usage_and_exit();
605 cpp_options = cpp_options.cat(argv[i]).cat(" ");
606 // getopt stops processing on an empty string, so
607 // need a fake option for below
612 int only_one_input = 0;
613 while ((c = getopt(argc, argv, "XEGOPsd:hmMo:prvxY")) != -1) {
634 _tt_global->silent = 1;
637 cedb = _Tt_typedb::level( optarg );
638 if (cedb == TypedbNone) {
639 _tt_syslog( stderr, LOG_ERR,
640 catgets(_ttcatd, 4, 28,
641 "Invalid database: %s"),
643 print_usage_and_exit();
647 print_usage_and_exit();
651 fn = f_merge_overwrite;
655 fn = f_merge_no_overwrite;
675 _TT_PRINT_VERSIONS((char *)_tt_global->progname)
682 // A cpp option was handled, ignore this
687 fn = f_garbage_collect;
691 print_usage_and_exit();
696 _tt_syslog(stderr, LOG_ERR,
697 catgets(_ttcatd, 4, 29,
698 "Specify only one of the options "
699 "-O -P -m -M -p -r -x"));
700 print_usage_and_exit();
703 // Extra args are always either a filename or types to remove
705 ifile = argv[optind];
706 if (ifile.len() == 0) {
708 print_usage_and_exit();
711 if (only_one_input && (cedb != TypedbNone)) {
712 print_usage_and_exit();
715 if ((ofile.len() > 0) && (fn != f_xdr_file)) {
716 print_usage_and_exit();
719 cargs = new _Tt_string_list();
720 while (argv[args_left]) {
721 cargs->append(_Tt_string(argv[args_left++]));
726 int main(int argc, char **argv)
728 _tt_global = new _Tt_global();
729 _tt_global->progname = argv[0];
730 setlocale( LC_ALL, "" );
731 _tt_openlog( _tt_global->progname, LOG_NOWAIT, 0 );
732 process_args(argc, argv);