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 /* $TOG: ActionDb.c /main/8 1998/07/30 12:09:13 mgreess $ */
24 /*************************************<+>*************************************
25 *****************************************************************************
31 ** Description: Source file for the action database loading functions.
35 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
36 ** (c) Copyright 1993, 1994 International Business Machines Corp.
37 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
38 ** (c) Copyright 1993, 1994 Novell, Inc.
39 ****************************************************************************
40 ************************************<+>*************************************/
43 #include <sys/types.h>
48 #include <X11/Intrinsic.h>
54 #include <Dt/Message.h>
55 #include <Dt/DbReader.h>
56 #include <Dt/Connect.h>
57 #include <Dt/DtNlUtils.h>
58 #include <Dt/UserMsg.h>
59 #include <Dt/CommandM.h>
61 #include <Dt/ActionUtilP.h>
62 #include <Dt/ActionP.h>
63 #include <Dt/ActionDbP.h>
65 #include <Dt/Utility.h>
69 #include "myassertP.h"
70 #include "DtSvcLock.h"
72 /******** Global Function Declarations ********/
74 extern Boolean _DtEmptyString(
77 /******** End Private Function Declarations ********/
80 /******** Static Function Declarations ********/
82 static void InitializeLocalizedStrings ( void ) ;
84 /******** End Static Function Declarations ********/
87 * Pointers to the localized strings.
90 static char *noFields;
91 static char *unrecogField;
92 static char *unrecogType;
94 static char *noExecString;
95 static char *unrecogMsgType;
96 static char *dupFields;
97 static char *invldField;
98 static char *missingField;
99 static char *missingName;
100 static char *unrecogMsgType2;
103 /*****************************************************************************
104 *****************************************************************************
106 * Public API Functions
108 *****************************************************************************
109 *****************************************************************************/
113 /******************************************************************************
114 ******************************************************************************
116 * Private API Functions
118 ******************************************************************************
119 ******************************************************************************/
121 /******************************************************************************
125 ******************************************************************************/
128 * See if two strings are exactly the same.
136 if ((strcmp(string1, string2) == 0) && (strlen(string1) == strlen(string2)))
144 * Return TRUE if the string pointer is NULL, or if the string is empty.
145 * Empty is also defined to be nothing but spaces.
152 if ((str == NULL)||(strlen(str) == 0)||(strlen(str) == DtStrspn(str, " ")))
164 #ifdef _DT_ALLOW_DT_MSGS
166 * The "DT_ARGn_VALUE" and "TT_ARGn_VALUE" field names are represented by
167 * macros (_DtACTION_DTN_VALUE, _DtACTION_TTN_VALUE) which define identical
168 * strings "_VALUE". (The field names minus the "[DT]_ARGn" prefix.)
170 * To allow an unambiguous table lookup by field name we add the
171 * _DtPFX prefix macro to the "DT_ARGn" field name.
174 #endif /* _DT_ALLOW_DT_MSGS */
177 * List all the action record fields we care about
178 * along with the bitmask that represents the field.
180 static _DtActNameAndBit _DtActNamesAndBits[] = {
181 { _DtACTION_LABEL, _ActDb_LABEL_SET, },
182 { _DtACTION_TYPE, _ActDb_TYPE_SET, },
183 { _DtACTION_ARG_CLASS, _ActDb_ARG_CLASS_SET, },
184 { _DtACTION_ARG_MODE, _ActDb_ARG_MODE_SET, },
185 { _DtACTION_ARG_TYPE, _ActDb_ARG_TYPE_SET, },
186 { _DtACTION_ARG_COUNT, _ActDb_ARG_COUNT_SET, },
187 { _DtACTION_DESCRIPTION, _ActDb_DESCRIPTION_SET, },
188 { _DtACTION_ICON, _ActDb_ICON_SET, },
189 /*******************************************************************
190 Meaningless for actions -- ignore these for now
191 { _DtACTION_INSTANCE_ICON, _ActDb_INSTANCE_ICON_SET, },
192 *******************************************************************/
193 { _DtACTION_MAP_ACTION, _ActDb_MAP_ACTION_SET, },
194 { _DtACTION_EXEC_STRING, _ActDb_EXEC_STRING_SET, },
195 { _DtACTION_EXEC_HOST, _ActDb_EXEC_HOST_SET, },
196 { _DtACTION_CWD, _ActDb_CWD_SET, },
197 { _DtACTION_WINDOW_TYPE, _ActDb_WINDOW_TYPE_SET, },
198 { _DtACTION_TERM_OPTS, _ActDb_TERM_OPTS_SET, },
199 { _DtACTION_TT_CLASS, _ActDb_TT_CLASS_SET, },
200 { _DtACTION_TT_SCOPE, _ActDb_TT_SCOPE_SET, },
201 { _DtACTION_TT_OPERATION, _ActDb_TT_OPERATION_SET, },
202 { _DtACTION_TT_FILE, _ActDb_TT_FILE_SET, },
203 { _DtACTION_TTN_MODE, _ActDb_TT_ARGN_MODE_SET, },
204 { _DtACTION_TTN_VTYPE, _ActDb_TT_ARGN_VTYP_SET, },
205 { _DtACTION_TTN_REP_TYPE, _ActDb_TT_ARGN_RTYP_SET, },
206 { _DtACTION_TTN_VALUE, _ActDb_TT_ARGN_VAL_SET, },
208 #ifdef _DT_ALLOW_DT_MSGS
209 { _DtACTION_DT_REQUEST_NAME, _ActDb_DT_REQ_NAME_SET, },
210 { _DtACTION_DT_SVC, _ActDb_DT_SVC_SET, },
211 { _DtACTION_DT_NOTIFY_NAME, _ActDb_DT_NTFY_NAME_SET, },
212 { _DtACTION_DT_NGROUP, _ActDb_DT_NGROUP_SET, },
213 { _DtPFX _DtACTION_DTN_VALUE, _ActDb_DT_ARGN_VAL_SET, },
214 #endif /* _DT_ALLOW_DT_MSGS */
218 #define NUM_FIELD_NAMES sizeof(_DtActNamesAndBits)/sizeof(_DtActNameAndBit) - 1
220 /******************************************************************************
222 * _DtActFieldBitLookup
223 * Lookup the mask value associated with the given field name in the array
224 * of names and field bits. If the field name is not recognized return the
225 * default value associated with the NULL field name (i.e. 0 ).
227 ******************************************************************************/
231 _DtActFieldBitLookup(char *name)
235 #ifdef _DT_ALLOW_DT_MSGS
236 char dtnamebuf[sizeof(_DtPFX) + sizeof(_DtACTION_DTN_VALUE)] = _DtPFX;
237 #endif /* _DT_ALLOW_DT_MSGS */
242 * Check for [DT]T_ARGn_ fields
243 * The following code assumes that a unique suffix identifying each
244 * field results from stripping off the leading "[DT]_ARGn" string.
245 * This assumption is not valid for DT_ARGn_VALUE and TT_ARGn_VALUE.
246 * so we resort to further skulduggery.
248 if ( !strncmp("TT_ARG",np,sizeof("TT_ARG")-1) )
250 np = np + sizeof("TT_ARG"); /* first char beyond prefix */
251 while( *np && (mblen(np,MB_CUR_MAX) == 1) && DtIsdigit(np) )
252 np=DtNextChar(np); /* skip past digits */
254 #ifdef _DT_ALLOW_DT_MSGS
255 else if ( !strncmp("DT_ARG",np,sizeof("DT_ARG")-1) )
257 np = np + sizeof("DT_ARG"); /* first char beyond prefix */
258 while( *np && (mblen(np,MB_CUR_MAX) == 1) && DtIsdigit(np) )
259 np=DtNextChar(np); /* skip past digits */
262 * Add the prefix to disambiguate the field name for
265 np=strcat(dtnamebuf,np);
269 #endif /* _DT_ALLOW_DT_MSGS */
274 for ( j = 0; j < NUM_FIELD_NAMES; j++ )
275 if ( !strcmp(_DtActNamesAndBits[j].name,np) )
276 break; /* found matching field name */
278 return _DtActNamesAndBits[j].bit;
281 /******************************************************************************
283 * _DtActFieldNameLookup
284 * Lookup the name string associated with the given mask bit in the array
285 * of names and field bits. If the mask bit is not recognized return the
286 * default value associated with the NULL field name (i.e. 0 ).
288 ******************************************************************************/
291 _DtActFieldNameLookup(long bitmask)
298 for ( j = 0; j < NUM_FIELD_NAMES; j++ )
299 if ( _DtActNamesAndBits[j].bit == bitmask )
300 break; /* found matching field name */
302 return _DtActNamesAndBits[j].name;
306 /******************************************************************************
308 * _DtActDupFieldNameCheck
309 * return True if "name" duplicates an existing fieldName.
311 ******************************************************************************/
313 _DtActDupFieldNameCheck(DtDtsDbField **fields,int numFields,XrmQuark name)
317 for ( i = 0; i < numFields; i++ )
319 if (fields[i]->fieldName == name)
327 /******************************************************************************
329 * _DtActValidateFieldValue
330 * Given a bitmask and action database field value apply some heuristics
331 * to determine the validity of the value. Return a newly allocated
332 * "sanitized" value for valid fields, NULL otherwise.
334 ******************************************************************************/
336 _DtActValidateFieldValue( long bit, char *value, char *actName, char *filename)
341 char bigBuf[_DtAct_MAX_BUF_SIZE];
344 if (!(value && *value))
347 * Empty field value -- ignore
352 /* work on a new copy of the value */
353 val = strdup( value );
356 * Strip trailing blanks from all fields except EXEC_STRING and
357 * DESCRIPTION. The database reader should guarantee that leading
358 * blanks have been stripped from the value field.
360 if ( !(bit & ( _ActDb_EXEC_STRING_SET | _ActDb_DESCRIPTION_SET )))
361 _DtRemoveTrailingBlanksInPlace(&val);
365 case _ActDb_TYPE_SET:
366 if ( strcmp(_DtACTION_MAP,val)
367 && strcmp(_DtACTION_COMMAND,val)
368 && strcmp(_DtACTION_TT_MSG,val)
369 #ifdef _DT_ALLOW_DT_MSGS
370 && strcmp(_DtACTION_DT_REQUEST,val)
371 && strcmp(_DtACTION_DT_NOTIFY,val)
372 #endif /* _DT_ALLOW_DT_MSGS */
376 * Invalid field value -- issue error msg.
378 buf = malloc(_DtAct_MAX_BUF_SIZE);
379 (void) sprintf(buf, unrecogMsgType, actName, filename,
380 val, _DtACTION_TYPE);
381 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
387 case _ActDb_EXEC_HOST_SET:
389 * Do NOT add to an existing EXEC_HOST definition.
392 case _ActDb_ARG_CLASS_SET:
394 /* Check the list of classes */
397 while ( (p = DtStrchr(start,_DtACT_LIST_SEPARATOR_CHAR)) )
400 * temporarily truncate string for testing
403 if ( strcmp(_DtACT_ANY,start) &&
404 strcmp(_DtACTION_FILE,start) &&
405 strcmp(_DtACTION_BUFFER,start) )
408 * Invalid field value -- issue error msg.
410 buf = malloc(_DtAct_MAX_BUF_SIZE);
411 (void) sprintf(buf, unrecogMsgType, actName, filename,
412 start, _DtACTION_ARG_CLASS);
413 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
418 *p = _DtACT_LIST_SEPARATOR_CHAR;
421 if ( strcmp(_DtACT_ANY,start) &&
422 strcmp(_DtACTION_FILE,start) &&
423 strcmp(_DtACTION_BUFFER,start) )
426 * Invalid field value -- issue error msg.
428 buf = malloc(_DtAct_MAX_BUF_SIZE);
429 (void) sprintf(buf, unrecogMsgType, actName, filename,
430 start, _DtACTION_ARG_CLASS);
431 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
437 case _ActDb_ARG_MODE_SET:
438 /* Check for the valid values of ARG_MODE */
439 if ( strcmp(val,_DtACT_ANY)
440 && strcmp(val, _DtACT_ARG_MODE_WRITE)
441 && strcmp(val, _DtACT_ARG_MODE_NOWRITE) )
443 /* Invalid Value for ARG_MODE */
444 buf = malloc(_DtAct_MAX_BUF_SIZE);
445 (void) sprintf(buf, unrecogMsgType, actName, filename,
446 val, _DtACTION_ARG_MODE);
447 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
452 break; /* valid value */
453 case _ActDb_ARG_TYPE_SET:
454 /* We cannot yet check arg types the database is not complete */
456 case _ActDb_ARG_COUNT_SET:
457 if ( !strcmp(val,_DtACT_ANY) )
459 for (p=val; *p; p=DtNextChar(p))
461 if ( p == val && ((*p == _DtACT_LT_CHAR)
462 || (*p == _DtACT_GT_CHAR)))
464 /* skip past "> or <" modifiers */
467 if ( !(mblen(p,MB_CUR_MAX) == 1 && DtIsdigit(p)) )
470 * Report Error -- invalid field
472 buf = malloc(_DtAct_MAX_BUF_SIZE);
473 (void) sprintf(buf, unrecogMsgType, actName,
475 _DtACTION_ARG_COUNT);
476 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
483 case _ActDb_WINDOW_TYPE_SET:
484 if ( strcmp(_DtACTION_TERMINAL,val) &&
485 strcmp(_DtACTION_PERM_TERMINAL,val) &&
486 strcmp(_DtACTION_NO_STDIO,val) )
489 * Invalid field value -- issue error msg.
491 buf = malloc(_DtAct_MAX_BUF_SIZE);
492 (void) sprintf(buf, unrecogMsgType, actName, filename,
493 val, _DtACTION_WINDOW_TYPE);
494 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
502 * This field must be in [host:]/path format
504 * WE REQUIRE A FULL PATH NAME TO BE SPECIFIED FOR THE
505 * DIRECTORY OTHERWISE WE CANNOT DISTINGUISH BETWEEN A
506 * RELATIVE FILE ENDING IN ':' AND A HOSTNAME FOLLOWED
510 && !( (mblen(val,MB_CUR_MAX) == 1)
511 && DtIsspace(DtNextChar(val))) )
512 break; /* Accept as good with no hostname */
514 for ( p = val; *p ; p=DtNextChar(p) )
518 * Accept as a valid hostname as long as
519 * there is a string of non-white
520 * and non-slash characters before the first
521 * colon and the first colon is immediately
522 * followed by a slash.
525 && ( *(DtNextChar(p)) == '/' ) && ( p != val) )
526 break; /* Accept this as good with hostname */
530 || ( (mblen(p,MB_CUR_MAX) == 1) && DtIsspace(p)))
532 /* looks like an error */
533 buf = malloc(_DtAct_MAX_BUF_SIZE);
534 (void) sprintf(buf, unrecogMsgType, actName,
535 filename, val, _DtACTION_CWD);
536 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
539 /*********************
540 reject the entire record containing this field
541 *********************/
547 /* looks like an error */
548 buf = malloc(_DtAct_MAX_BUF_SIZE);
549 (void) sprintf(buf, unrecogMsgType, actName,
550 filename, val, _DtACTION_CWD);
551 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
554 /*********************
555 reject the entire record containing this field
556 *********************/
560 case _ActDb_TT_CLASS_SET:
561 if ( strcmp(_DtACTION_TT_NOTICE,val) &&
562 strcmp(_DtACTION_TT_REQUEST,val) )
565 * Invalid field value -- issue error msg.
567 buf = malloc(_DtAct_MAX_BUF_SIZE);
568 (void) sprintf(buf, unrecogMsgType, actName, filename,
569 val, _DtACTION_TT_CLASS);
570 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
576 case _ActDb_TT_SCOPE_SET:
577 if ( strcmp(_DtACTION_TT_SESSION,val) &&
578 strcmp(_DtACTION_TT_FILE,val) &&
579 strcmp(_DtACTION_TT_BOTH,val) &&
580 strcmp(_DtACTION_TT_FILE_IN_SESSION,val) )
583 * Invalid field value -- issue error msg.
585 buf = malloc(_DtAct_MAX_BUF_SIZE);
586 (void) sprintf(buf, unrecogMsgType, actName, filename,
587 val, _DtACTION_TT_SCOPE);
588 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
594 case _ActDb_TT_FILE_SET:
596 * Must be a real file (host:/syntax?)
597 * -- convert to network file syntax?
598 * or %ARG_n% keyword.
599 * NOTE: only one file may be specified
602 case _ActDb_TT_ARGN_MODE_SET:
604 * MODE is required for tooltalk actions
605 * it must be one of TT_IN, TT_OUT or TT_INOUT
607 if ( strcmp(_DtACTION_TT_MODE_IN,val ) &&
608 strcmp(_DtACTION_TT_MODE_OUT,val) &&
609 strcmp(_DtACTION_TT_MODE_INOUT,val) )
612 * Invalid field value -- issue error msg.
614 buf = malloc(_DtAct_MAX_BUF_SIZE);
615 (void) sprintf(buf, unrecogMsgType2, actName, filename,
616 val, _DtACTION_TTN_ARG,
617 "n", _DtACTION_TTN_MODE);
618 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
624 case _ActDb_TT_ARGN_VTYP_SET:
626 * VTYPE -- semantic type name (i.e. title) applied to tooltalk
627 * message value (TT_ARGn_VALUE). The value of this field is
628 * either an arbitrary string, or an action argument reference
632 case _ActDb_TT_ARGN_RTYP_SET:
634 * REP_TYPE -- representation type of the corresponding tooltalk value.
635 * Valid values are: UNDEFINED, INTEGER, BUFFER, and STRING.
637 if ( strcmp(_DtACTION_TT_RTYP_UND,val ) &&
638 strcmp(_DtACTION_TT_RTYP_INT,val) &&
639 strcmp(_DtACTION_TT_RTYP_BUF,val) &&
640 strcmp(_DtACTION_TT_RTYP_STR,val) )
643 * Invalid field value -- issue error msg.
645 buf = malloc(_DtAct_MAX_BUF_SIZE);
646 (void) sprintf(buf, unrecogMsgType2, actName, filename,
647 val, _DtACTION_TTN_ARG,
648 "n", _DtACTION_TTN_REP_TYPE);
649 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
655 case _ActDb_TT_ARGN_VAL_SET:
657 * The value for the Nth tooltalk argument. This field may be
658 * an arbitrary string.
661 #ifdef _DT_ALLOW_DT_MSGS
662 case _ActDb_DT_REQ_NAME_SET:
664 case _ActDb_DT_NTFY_NAME_SET:
666 #endif /* _DT_ALLOW_DT_MSGS */
684 sizeof(_DtACTION_TTN_ARG) + /* ARGn prefix */
685 3 + /* space for 3 decimal digits */
686 sizeof(_DtACTION_TTN_REP_TYPE) /* space for longest suffix */
687 + 8]; /* addition space for warning prevention incase the digits are more than 3 */
690 myassert(actionType); /* actionType should never be NULL */
693 * Check action type information for accuracy/completeness.
695 if ( !strcmp(actionType,_DtACTION_COMMAND) )
698 * Check that all recognized fields are suitable for
699 * COMMAND type actions.
703 #ifdef _DT_ALLOW_DT_MSGS
704 | _ActDb_DT_REQUEST_BITS
705 | _ActDb_DT_NOTIFY_BITS
706 #endif /* _DT_ALLOW_DT_MSGS */
710 * Fields unsuitable for COMMAND type actions were
711 * found. -- reject this record.
713 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
714 (void) sprintf (buf, invldField,
715 XrmQuarkToString(actp->recordName),
716 fileName, _DtACTION_COMMAND );
721 * Check that all required fields are present or that
722 * the appropriate default has been set.
724 if ( !(mask & _ActDb_EXEC_STRING_SET) )
726 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
727 (void) sprintf (buf, noExecString,
728 XrmQuarkToString(actp->recordName),
729 fileName, _DtACTION_EXEC_STRING);
733 else if ( !strcmp(actionType,_DtACTION_MAP) )
736 * Check that all recognized fields are suitable for
741 #ifdef _DT_ALLOW_DT_MSGS
742 | _ActDb_DT_REQUEST_BITS
743 | _ActDb_DT_NOTIFY_BITS
744 #endif /* _DT_ALLOW_DT_MSGS */
748 * Fields unsuitable for MAP type actions were
749 * found. -- reject this record.
751 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
752 (void) sprintf (buf, invldField,
753 XrmQuarkToString(actp->recordName),
754 fileName, _DtACTION_MAP );
758 * Check for required fields
760 if ( !(mask & _ActDb_MAP_ACTION_SET) )
762 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
763 (void) sprintf (buf, missingField,
764 XrmQuarkToString(actp->recordName),
765 fileName, _DtACTION_MAP_ACTION, _DtACTION_MAP);
770 else if ( !strcmp(actionType,_DtACTION_TT_MSG) )
773 * Check that all recognized fields are suitable for
774 * TT_MSG type actions.
778 #ifdef _DT_ALLOW_DT_MSGS
779 | _ActDb_DT_NOTIFY_BITS
780 | _ActDb_DT_REQUEST_BITS
781 #endif /* _DT_ALLOW_DT_MSGS */
785 * Fields unsuitable for TT_MSG type actions were
786 * found. -- reject this record.
788 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
789 (void) sprintf (buf, invldField,
790 XrmQuarkToString(actp->recordName),
791 fileName, _DtACTION_TT_MSG );
796 * Insure that all the required fields are present.
798 if ( !(mask & _ActDb_TT_CLASS_SET) )
800 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
801 (void) sprintf (buf, missingField,
802 XrmQuarkToString(actp->recordName),
803 fileName, _DtACTION_TT_CLASS, _DtACTION_TT_MSG);
806 if ( !(mask & _ActDb_TT_SCOPE_SET) )
808 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
809 (void) sprintf (buf, missingField,
810 XrmQuarkToString(actp->recordName),
811 fileName, _DtACTION_TT_SCOPE, _DtACTION_TT_MSG);
814 if ( !(mask & _ActDb_TT_OPERATION_SET) )
816 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
817 (void) sprintf (buf, missingField,
818 XrmQuarkToString(actp->recordName),
819 fileName, _DtACTION_TT_OPERATION,
825 * Check if tooltalk arg info is supplied by this action
827 if ( (mask & _ActDb_TT_ARGN_BITS) )
830 * Check for consistency of the fields
831 * describing tooltalk arguments.
833 if ( !( mask & _ActDb_TT_ARGN_MODE_SET) )
835 char argModeString[ 1
836 + sizeof(_DtACTION_TTN_ARG)
837 + sizeof(_DtACTION_TTN_MODE)];
839 * Missing required arg mode
841 sprintf(argModeString,"%s%s%s",
845 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
846 (void) sprintf (buf, missingField,
847 XrmQuarkToString(actp->recordName),
855 * For each tt arg mode specifier see that the other
856 * required info has been supplied.
857 * -- If a mode specifier is missing for a TT argument;
858 * that argument and all subsequent TT args will
860 * MOVE THIS UP TO DATABASE LOAD TIME
862 for ( i = 0; True; i++ )
864 sprintf(argnFieldName,"%s%d%s",
865 _DtACTION_TTN_ARG, i, _DtACTION_TTN_MODE);
866 if ( !(s = _DtDtsDbGetFieldByName(actp,
868 break; /* no argn mode specified */
870 * See that the other required tt argn
871 * fields exist for n == i.
874 if ( strcmp(s, _DtACTION_TT_MODE_OUT ) )
878 * VTYPE is required for mode
881 sprintf(argnFieldName,"%s%d%s",
882 _DtACTION_TTN_ARG, i,
883 _DtACTION_TTN_VTYPE);
884 if (!(s= _DtDtsDbGetFieldByName(actp,
888 * Missing required field
890 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
893 XrmQuarkToString(actp->recordName),
900 /* RWV -- more checks to add */
906 #ifdef _DT_ALLOW_DT_MSGS
907 else if ( !strcmp(actionType,_DtACTION_DT_REQUEST))
910 * Check that all recognized fields are suitable for
911 * DT_REQUEST type actions.
913 if ( mask & ( _ActDb_CMD_BITS
914 | _ActDb_DT_NOTIFY_BITS
919 * Fields unsuitable for DT_REQUEST type actions were
920 * found. -- reject this record.
922 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
923 (void) sprintf (buf, invldField,
924 XrmQuarkToString(actp->recordName),
925 fileName, _DtACTION_DT_REQUEST );
930 else if ( !strcmp(actionType,_DtACTION_DT_NOTIFY))
933 * Check that all recognized fields are suitable for
934 * Dt_NOTIFY type actions.
936 if ( mask & ( _ActDb_DT_REQUEST_BITS
942 * Fields unsuitable for DT_NOTIFY type actions were
943 * found. -- reject this record.
945 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
946 (void) sprintf (buf, invldField,
947 XrmQuarkToString(actp->recordName),
948 fileName, _DtACTION_DT_NOTIFY );
953 #endif /* _DT_ALLOW_DT_MSGS */
958 * Unrecognized action type
959 * Throw out the whole record
961 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
962 (void) sprintf (buf, unrecogType, _DtACTION_TYPE,
963 actionType, fileName );
968 * The record checks out OK
973 /******************************************************************************
975 * _DtActionConverter - given a list of the fields for an action
976 * definition, put the definition into an internal array.
978 * Returns 'True' if the definition was rejected for any reason, otherwise,
979 * 'False' is returned.
981 * Note: Space that is allocated for database structures uses vanilla
982 * malloc/strdup/realloc/free functions because the database
983 * component (Dts) attempts to be independent of X and Xt.
984 * Space for local usage is allocated using XtMalloc/XtNewString/
985 * /XtRealloc/XtFree family of functions which are somewhat more robust
986 * than the vanilla allocators.
988 * (Replaces _DtParseActionDbEntry)
989 *****************************************************************************/
992 _DtActionConverter(DtDtsDbField * fields,
995 Boolean rejectionStatus)
997 static int firstTime = True;
998 DtDtsDbDatabase *act_db;
999 DtDtsDbRecord *act_rec;
1002 unsigned int mask = 0;
1003 char bigBuf[_DtAct_MAX_BUF_SIZE];
1005 char *fileName = _DtDbPathIdToString(pathId);
1008 _DtSvcProcessLock();
1012 InitializeLocalizedStrings ();
1016 * The action database should have been initialized in
1019 act_db = _DtDtsDbGet(_DtACTION_NAME);
1022 /* Action records require that an action name be specified */
1023 if (fields[0].fieldValue == NULL)
1026 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
1027 sprintf (buf, missingName, _DtACTION_NAME, fileName);
1028 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
1031 _DtSvcProcessUnlock();
1034 else if ( fields[1].fieldName == 0)
1036 /* The record contains no fields */
1037 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
1038 (void) sprintf (buf, noFields, fields[0].fieldValue, fileName);
1039 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
1042 _DtSvcProcessUnlock();
1048 * The first field contains the record name.
1050 act_rec = _DtDtsDbAddRecord(act_db);
1051 act_rec->recordName = XrmStringToQuark(fields[0].fieldValue);
1054 * Get all the field data -- we may get an arbitrary number
1055 * of TT_ARGn_MODE, TT_ARGn_VTYPE, or DT_ARGn_VALUE fields.
1056 * We may also want to support user-defined fields at some
1057 * time in the future -- for now reject unrecognized fileds.
1059 for ( i=1; fields[i].fieldName; i++)
1061 unsigned long ThisBit = 0;
1062 char *fieldVal = NULL;
1064 /* find the corresponding field entry and bitmask */
1066 if ((ThisBit = _DtActFieldBitLookup(XrmQuarkToString(fields[i].fieldName))) != 0)
1068 switch ((intptr_t)(fieldVal=_DtActValidateFieldValue(ThisBit,
1069 fields[i].fieldValue, fields[0].fieldValue,
1074 * invalid minor field
1075 * -- reject field only
1081 * Invalid critical field
1082 * --reject entire record
1084 _DtDtsDbDeleteRecord(act_rec,act_db);
1086 _DtSvcProcessUnlock();
1091 * validated fieldVal returned
1096 if ( ThisBit == _ActDb_TYPE_SET )
1097 actionType = fieldVal;
1099 else /* Unrecognized Field */
1103 * Unrecognized Field:
1104 * issue a warning and ignore it for now.
1105 * --- Later we may decide to
1106 * store arbitrary fields for users.
1107 * As a control we may require that a user field
1108 * name begin with some well-known string
1111 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
1112 (void) sprintf (buf, unrecogField,
1113 fields[0].fieldValue,
1115 XrmQuarkToString(fields[i].fieldName),
1116 fields[i].fieldValue);
1120 /*************************************************
1121 * Unrecognized Field -- lets NOT reject the
1122 * entire record (for now) and just ignore the
1123 * unrecognized field. -- this allows old
1124 * syntax to exist in an action record without
1125 * causing outright rejection of the record.
1126 * We may decide to reject such records again
1127 * once things settle down, hence the UNREACHABLE
1128 * code which follows the continue statement.
1129 *************************************************/
1130 _DtSimpleError(DtProgName,DtWarning, NULL, "%s", buf);
1135 if ( mask & ThisBit )
1138 * An exhaustive name check is required for the "*_ARGn_"
1139 * fields -- a simple bitmask check is sufficient for
1140 * other field names.
1142 if ( ((ThisBit & _ActDb_ARGN_BITS)
1143 && _DtActDupFieldNameCheck( act_rec->fieldList,
1144 act_rec->fieldCount,
1145 fields[i].fieldName))
1146 || !(ThisBit & _ActDb_ARGN_BITS) )
1149 * Attempt to redefine a field
1150 * reject this record.
1152 buf = XtMalloc(_DtAct_MAX_BUF_SIZE);
1153 (void) sprintf (buf,dupFields, fields[0].fieldValue,
1155 XrmQuarkToString(fields[i].fieldName));
1156 _DtSimpleError(DtProgName,DtError, NULL, "%s", buf);
1157 _DtDtsDbDeleteRecord(act_rec,act_db);
1161 _DtSvcProcessUnlock();
1168 fld = _DtDtsDbAddField(act_rec);
1169 fld->fieldName = fields[i].fieldName;
1170 fld->fieldValue = fieldVal;
1175 * Fill in default action type if necessary
1177 if ( !(mask & _ActDb_TYPE_SET) )
1180 * No type specified for this action
1181 * -- revert to default type (i.e. COMMAND).
1183 mask |= _ActDb_TYPE_SET;
1184 actionType = _DtACT_TYPE_DFLT;
1189 * Now check the record for consistency
1192 if ( (buf = _DtActCheckRecord(act_rec,actionType,mask,fileName))
1196 * This is an invalid record
1198 _DtSimpleError(DtProgName,DtError,NULL,"%s",buf);
1199 _DtDtsDbDeleteRecord(act_rec,act_db);
1203 _DtSvcProcessUnlock();
1207 act_rec->seq = ++(act_db->ActionSequenceNumber);
1208 act_rec->pathId = pathId;
1211 _DtSvcProcessUnlock();
1217 _DtFreeActionDB( void )
1219 DtDtsDbDatabase *act_db = _DtDtsDbGet(_DtACTION_NAME);
1223 _DtDtsDbDeleteDb(act_db);
1228 /********************
1230 * InitializeLocalizedStrings - initializes the localized strings.
1232 * MODIFIED: The following variables are all initialized.
1235 * char *unrecogField;
1236 * char *unrecogType;
1238 * char *noExecString;
1239 * char *unrecogMsgType;
1242 * char *missingField;
1243 * char *missingName;
1244 * char *unrecogMsgType2;
1246 ********************/
1249 InitializeLocalizedStrings ( void )
1251 noFields = XtNewString (((char *) Dt11GETMESSAGE (6, 1, "The action definition \"%s\" in the file:\n \"%s\"\n does not have any fields.\n")));
1253 unrecogField = XtNewString (((char *) Dt11GETMESSAGE (6, 2, "The action definition \"%s\" in the file\n \"%s\"\n contains the following unrecognized field name and value:\n \"%s\":\"%s\"\n")));
1255 unrecogType = XtNewString (((char *) Dt11GETMESSAGE (6, 4, "The \"%s\" field in the action definition \"%s\"\n in the file \"%s\"\n has an unrecognized action type.\n")));
1257 noMapTo = XtNewString (((char *) Dt11GETMESSAGE (6, 5, "The action definition \"%s\" in the file\n \"%s\"\n is not mapped properly. The \"%s\" field\n should be: TYPE MAP action_mapped_to.\n")));
1259 noExecString = XtNewString (((char *) Dt11GETMESSAGE (6, 8, "The action definition \"%s\" in the file\n \"%s\"\n is a \"COMMAND\" action type but lacks the\n required field \"%s\".\n")));
1261 unrecogMsgType = XtNewString (((char *) Dt11GETMESSAGE (6, 11, "The action definition \"%s\" in the file\n \"%s\"\n has the illegal value \"%s\" in the \"%s\" field.\n")));
1263 dupFields = XtNewString (((char *) Dt11GETMESSAGE (6, 12, "The action definition \"%s\" in the file\n \"%s\"\n contains duplicate fields named:\n \"%s\".\n")));
1265 invldField = XtNewString (((char *) Dt11GETMESSAGE (6, 13, "The action definition \"%s\" in the file\n \"%s\"\n contains invalid fields for \"%s\" type actions.\n")));
1267 missingField = XtNewString (((char *) Dt11GETMESSAGE (6, 14, "The action definition \"%s\" in the file\n \"%s\"\n is missing the required field, \"%s\"\n for \"%s\" type actions.\n")));
1269 missingName = XtNewString (((char *) Dt11GETMESSAGE (4, 1, "A \"%s\" definition in the file:\n \"%s\"\n is missing a name. Add the name\n to the definition.\n")));
1271 unrecogMsgType2 = XtNewString (((char *) Dt11GETMESSAGE (6, 16, "The action definition \"%s\" in the file\n \"%s\"\n has the illegal value \"%s\" in the \"%s%s%s\" field.\n")));