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.
45 #if defined(sgi) || defined(CSRG_BASED)
49 #include "tt_options.h"
50 #if defined(OPT_BUG_USL)
51 extern "C" int getopt(int, char *const *, const char *);
54 #include "mp/mp_global.h"
58 #include "mp_types_table.h"
59 #include "mp_typedb.h"
60 #include "util/copyright.h"
61 #include "util/tt_global_env.h"
62 #include "util/tt_xdr_version.h"
63 #include "util/tt_port.h"
64 #include "util/tt_gettext.h"
66 #define _TT_DBCLIENT_SIDE
67 #include "db/db_server.h"
70 extern "C" void xdrstdio_create(XDR *, FILE *, enum xdr_op);
73 typedef void (*cmd_fn)();
78 static char PatchID[] = "Patch Id: 100626_03.";
79 static int Patch_ID100626_03;
83 _Tt_typedbLevel cedb = TypedbNone;
85 _Tt_string_list_ptr cargs;
87 int option_remap_ptypes = 1;
88 _Tt_string cpp_options("");
91 print_usage_and_exit()
93 _tt_syslog(stderr, LOG_ERR, "%s",
94 catgets(_ttcatd, 4, 2,
96 "tt_type_comp [-s] [-d db] [-mM] source_file\n"
97 "tt_type_comp [-s] [-d db] -r type ...\n"
98 "-M merge source types into specified database, not updating existing types\n"
99 "-m merge, but update existing types. Default.\n"
100 "-r remove source types from the specified database\n"
101 "-d db database to operate on. One of: user, system, or network. Default: user\n"
102 "-G perform garbage collection on the ToolTalk database server.\n"
104 "tt_type_comp [-sE] -p|O|P [-d db]\n"
105 "tt_type_comp [-s] -p|O|P compiled_file\n"
106 "-O enumerate on stdout the names of all otypes read\n"
107 "-P enumerate on stdout the names of all ptypes read\n"
108 "-p pretty-print on stdout all the ToolTalk types read\n"
109 "-E use the Classing Engine database(s) instead of the XDR database(s)\n"
110 "-d db database to read from. One of: user, system, or network. Default: all\n"
112 "tt_type_comp [-s] -x [-o compiled_file] source_file\n"
113 "-x compile types from source_file (or stdin, if file is \"-\")\n"
114 "-o write compiled types to compiled_file (or stdout, if file is \"-\")\n"
115 " Default: source_file.xdr, or \"types.xdr\" if source is stdin\n"
117 "tt_type_comp [-hv]\n"
118 "-v print out version number\n"
119 "-h print out this message\n"
120 "-s do not print out any status messages.\n"
122 "These cpp options will be passed through:\n"
123 " -undef -Dname -Idirectory -Uname -Ydirectory"));
129 read_types(_Tt_string file, _Tt_typedb_ptr &db)
131 _Tt_parse_status result;
132 _Tt_types_table *table;
134 table = new _Tt_types_table(stdin, result);
136 table = new _Tt_types_table(file, result);
139 if (result == _TT_PARSE_OK) {
140 db = new _Tt_typedb();
142 if (table->check_semantics() != _TT_PARSE_OK) {
143 _tt_syslog(stderr, LOG_ERR,
144 catgets(_ttcatd, 4, 3,
145 "Semantic error in types file"));
148 db->ptable = table->ptypes();
149 db->otable = table->otypes();
151 _Tt_string msg = catgets(_ttcatd, 4, 4,
152 "Not a valid ToolTalk types file" );
153 if (file.len() > 0) {
154 msg = msg.cat( ": " ).cat( file );
156 _tt_syslog(stderr, LOG_ERR, msg);
167 db = new _Tt_typedb();
168 if (db->init_ce(cedb) != TT_OK) {
169 _tt_syslog(stderr, LOG_ERR,
170 catgets(_ttcatd, 4, 5,
171 "Cannot read any ToolTalk types "
172 "from Classing Engine database"));
175 db->pretty_print(stdout);
185 _Tt_ptype_table_cursor db_ptypes;
186 _Tt_otype_table_cursor db_otypes;
190 Tt_status st = TT_OK;
192 if (cedb == TypedbNone) {
197 _tt_syslog(stderr, LOG_ERR,
198 catgets(_ttcatd, 4, 6,
199 "Merging Classing Engine tables is no "
200 "longer supported"));
204 xdb = new _Tt_typedb();
205 read_types(ifile, db);
207 if ((st=xdb->init_xdr(cedb)) != TT_OK) {
208 // if TT_ERR_DBEXIST is returned from init_ce
209 // we continue with the merge. It just means
210 // we're starting up in an environment where
211 // no tooltalk namespaces exist in any of the
212 // Classing Engine databases.
213 if (st != TT_ERR_DBEXIST) {
214 if (st == TT_ERR_NO_MATCH) {
215 _tt_syslog(stderr, LOG_ERR,
216 catgets(_ttcatd, 4, 7,
217 "Cannot read types in %s data"
218 "base - version mismatch"),
219 _Tt_typedb::level_name(cedb));
221 _tt_syslog(stderr, LOG_ERR,
222 catgets(_ttcatd, 4, 8,
223 "Cannot read types in %s data"
225 _Tt_typedb::level_name(cedb));
228 * The most common way for this to fail seems to be
229 * to not have OPENWINHOME set. Suggest this
232 if (0==getenv("OPENWINHOME")) {
233 _tt_syslog(stderr, LOG_ERR,
234 catgets(_ttcatd, 4, 9,
235 "$OPENWINHOME not set"));
241 if (! xdb->begin_write(cedb)) {
242 _tt_syslog(stderr, LOG_ERR,
243 catgets(_ttcatd, 4, 10,
244 "Cannot initialize %s database for writing"),
245 _Tt_typedb::level_name(cedb));
249 db_otypes.reset(db->otable);
250 while (db_otypes.next()) {
251 ot = xdb->otable->lookup(db_otypes->otid());
252 exists = (! ot.is_null());
257 if (! xdb->remove_otype(db_otypes->otid())) {
258 _tt_syslog(stderr, LOG_ERR,
259 catgets(_ttcatd, 4, 11,
260 "Could not remove old "
261 "definition for %s"),
262 (char *)db_otypes->otid());
267 if (! _tt_global->silent) {
268 printf( "%s %s...\n",
270 ? catgets(_ttcatd, 4, 12, "Overwriting")
271 : catgets(_ttcatd, 4, 13, "Writing"),
272 (char *)db_otypes->otid());
274 if (! xdb->insert(*db_otypes)) {
275 _tt_syslog(stderr, LOG_ERR,
276 catgets(_ttcatd, 4, 14, "Could not add "
277 "new definition for %s"),
278 (char *)db_otypes->otid());
284 db_ptypes.reset(db->ptable);
285 while (db_ptypes.next()) {
286 pt = xdb->ptable->lookup(db_ptypes->ptid());
287 exists = (! pt.is_null());
292 if (! xdb->remove_ptype(db_ptypes->ptid())) {
293 _tt_syslog(stderr, LOG_ERR,
294 catgets(_ttcatd, 4, 15,
295 "Could not remove old "
296 "definition for %s"),
297 (char *)db_ptypes->ptid());
301 if (! _tt_global->silent) {
304 ? catgets(_ttcatd, 4, 16, "Overwriting")
305 : catgets(_ttcatd, 4, 17, "Writing"),
306 (char *)db_ptypes->ptid());
308 if (! xdb->insert(*db_ptypes)) {
309 _tt_syslog(stderr, LOG_ERR,
310 catgets(_ttcatd, 4, 18, "Could not add "
311 "new definition for %s"),
312 (char *)db_ptypes->ptid());
317 if (! xdb->end_write()) {
318 // diagnostic emitted by ::end_write()
331 f_merge_no_overwrite()
338 f_list_types(int otypes)
344 if (cedb == TypedbNone) {
347 db = new _Tt_typedb();
349 if (ifile.len() > 0) {
351 status = db->init_xdr( stdin );
353 status = db->init_xdr( ifile );
356 status = db->init_xdr( cedb );
359 status = db->init_ce( cedb );
361 if (status != TT_OK) {
362 if (status == TT_ERR_NO_MATCH) {
363 _tt_syslog(stderr, LOG_ERR,
364 catgets(_ttcatd, 4, 19, "Version mismatch "
365 "in compiled types"));
367 _tt_syslog(stderr, LOG_ERR,
368 catgets(_ttcatd, 4, 20, "Cannot read types "
372 // The most common way for this to fail seems to be
373 // to not have OPENWINHOME set. Suggest this
376 if (0==getenv("OPENWINHOME")) {
377 _tt_syslog(stderr, LOG_ERR,
378 catgets(_ttcatd, 4, 21,
379 "$OPENWINHOME not set"));
384 _Tt_otype_table_cursor db_otypes;
385 db_otypes.reset(db->otable);
386 while (db_otypes.next()) {
387 printf("%s\n", (char *)db_otypes->otid());
390 _Tt_ptype_table_cursor db_ptypes;
391 db_ptypes.reset(db->ptable);
392 while (db_ptypes.next()) {
393 printf("%s\n", (char *)db_ptypes->ptid());
413 _Tt_string_list_cursor argc;
420 if (cedb == TypedbNone) {
423 db = new _Tt_typedb();
424 if ((option_xdr && (err = db->init_xdr(cedb)) != TT_OK) ||
425 (!option_xdr && (err = db->init_ce(cedb)) != TT_OK)) {
426 if (err == TT_ERR_NO_MATCH) {
427 _tt_syslog(stderr, LOG_ERR,
428 catgets(_ttcatd, 4, 22,
429 "Cannot read types in %s data"
430 "base - version mismatch"),
431 _Tt_typedb::level_name(cedb));
433 _tt_syslog(stderr, LOG_ERR,
434 catgets(_ttcatd, 4, 23,
435 "Cannot read types in %s database"),
436 _Tt_typedb::level_name(cedb));
439 * The most common way for this to fail seems to be
440 * to not have OPENWINHOME set. Suggest this
443 if (0==getenv("OPENWINHOME")) {
444 _tt_syslog(stderr, LOG_ERR,
445 catgets(_ttcatd, 4, 24,
446 "$OPENWINHOME not set"));
451 if (! db->begin_write(cedb)) {
452 // diagnostic emitted
457 while (argc.next()) {
458 pt = db->ptable->lookup(*argc);
460 ot = db->otable->lookup(*argc);
461 if (! ot.is_null()) {
462 if (! _tt_global->silent) {
463 printf(catgets(_ttcatd, 4, 25,
464 "Removing otype %s\n"),
468 db->remove_otype(*argc);
471 if (! _tt_global->silent) {
472 printf(catgets(_ttcatd, 4, 26,
473 "Removing ptype %s\n"),
476 db->remove_ptype(*argc);
482 if (! db->end_write()) {
496 if (ofile.len() == 0) {
500 ofile = ifile.cat(".xdr");
503 read_types(ifile, db);
507 status = db->write( stdout );
509 status = db->write( ofile );
511 if (status != TT_OK) {
515 _Tt_typedb::send_saved( ofile );
516 printf(catgets(_ttcatd, 4, 27, "output written to %s\n"),
528 db = new _Tt_typedb();
529 if (ifile.len() != 0) {
531 status = db->init_xdr( stdin );
533 status = db->init_xdr( ifile );
536 if (cedb == TypedbNone) {
539 status = db->init_xdr(cedb);
541 if (status != TT_OK) {
542 // diagnostic emitted
546 db->pretty_print(stdout);
551 // This sends messages to the 'default' ToolTalk files.
552 // This forces an attempt to contact the sessions registered for
553 // each file, if they are dead, then a deleteSession() is sent
554 // to clear out (garbage collect) the information for that dead
555 // session. Dead sessions can occur in the dbserver if the system
556 // that had registered died without un-registering with dbserver
562 _Tt_db_client dbClient;
563 _Tt_string sessionId;
565 if (dbClient.getConnectionResults() == TT_DB_OK) {
567 _Tt_string_list *sessions;
568 sessions = dbClient.get_all_sessions();
570 if (sessions != NULL && sessions->count() > 0) {
572 // Delete the list of sessions that are dead.
576 sessionId = sessions->top();
578 = tt_default_session_set(sessionId))
580 dbClient.delete_session(sessionId);
583 } while(sessions->count() > 0);
585 dbClient.garbage_collect_in_server();
591 process_args(int argc, char **argv)
601 // default function is to merge types
602 fn = f_merge_overwrite;
604 // Need to parse out the cpp options specially because they
605 // don't work with getopt
606 for (int i = 1; i < argc; i++) {
607 if (argv[i][0] == '-' &&
608 (argv[i][1] == 'u' || argv[i][1] == 'D' ||
609 argv[i][1] == 'I' || argv[i][1] == 'U' ||
610 argv[i][1] == 'Y')) {
611 if (argv[i][1] == 'u' &&
612 strcmp(argv[i], "-undef") != 0) {
613 print_usage_and_exit();
615 cpp_options = cpp_options.cat(argv[i]).cat(" ");
616 // getopt stops processing on an empty string, so
617 // need a fake option for below
622 int only_one_input = 0;
623 while ((c = getopt(argc, argv, "XEGOPsd:hmMo:prvxY")) != -1) {
644 _tt_global->silent = 1;
647 cedb = _Tt_typedb::level( optarg );
648 if (cedb == TypedbNone) {
649 _tt_syslog( stderr, LOG_ERR,
650 catgets(_ttcatd, 4, 28,
651 "Invalid database: %s"),
653 print_usage_and_exit();
657 print_usage_and_exit();
661 fn = f_merge_overwrite;
665 fn = f_merge_no_overwrite;
685 _TT_PRINT_VERSIONS((char *)_tt_global->progname)
692 // A cpp option was handled, ignore this
697 fn = f_garbage_collect;
701 print_usage_and_exit();
706 _tt_syslog(stderr, LOG_ERR,
707 catgets(_ttcatd, 4, 29,
708 "Specify only one of the options "
709 "-O -P -m -M -p -r -x"));
710 print_usage_and_exit();
713 // Extra args are always either a filename or types to remove
715 ifile = argv[optind];
716 if (ifile.len() == 0) {
718 print_usage_and_exit();
721 if (only_one_input && (cedb != TypedbNone)) {
722 print_usage_and_exit();
725 if ((ofile.len() > 0) && (fn != f_xdr_file)) {
726 print_usage_and_exit();
729 cargs = new _Tt_string_list();
730 while (argv[args_left]) {
731 cargs->append(_Tt_string(argv[args_left++]));
736 int main(int argc, char **argv)
738 _tt_global = new _Tt_global();
739 _tt_global->progname = argv[0];
740 setlocale( LC_ALL, "" );
741 _tt_openlog( _tt_global->progname, LOG_NOWAIT, 0 );
742 process_args(argc, argv);