/* ** Name: log_errmsg - logs a user and VMS error status to errlog.log ** ** Description: ** This routine converts OpenVMS status code to an OpenVMS text ** error message, then puts the specified message with ": status" ** appended and then the VMS error message output to the errlog.log ** ** Inputs: ** usrmsg - user specified error text (24 characters) ** code - VMS status code ** flg - 0 send message to error.log only, ** 1 write to standard out and to errlog.log ** ** Outputs: ** None ** ** Returns: ** void ** ** History: ** 22-nov-1993 (eml) ** Created to allow the use ot ERoptlog to write all error messages. ** 31-jan-1994 (bryanp) ** Even if SYS$GETMSG fails, report the "usrmsg" anyway. */ static void log_errmsg( const char *usrmsg, const unsigned int code, const unsigned int flg ) { static $DESCALLOC( bufadr ); char stsbuf[256]; char msgbuf[256]; unsigned short len; STATUS status; $DESCFILL( bufadr, sizeof( stsbuf ), stsbuf ); status = sys$getmsg( code, &len, &bufadr, 0x0F, NULL ); if ( !(status & 1) ) { /* ** "code" was not a valid VMS message status, or at least not one which ** we could turn into message text. So just format it in hex. Assume ** that the result is exactly eight characters long (does CVlx null ** terminate its output? If so, could set len = STlength(stsbuf);). */ CVlx(code, stsbuf); len = 8; } STcopy( usrmsg, msgbuf ); STcat( msgbuf, ": Status" ); stsbuf[len] = '\0'; ERoptlog( msgbuf, stsbuf ); if ( flg ) { SIprintf( "%s = %s\n", msgbuf, stsbuf ); SIflush( stdout ); } return; }
/* ** Name: main -main routine. ** ** Description: ** This routine is the main control routine for iirundbms. Starting an ** iidbms server consists of: ** 1) Opening and reading the PM data ** 2) Validating server arguments, converting to VMS internal format. ** 3) Creating mailbox for communication with server. ** 4) creating server processing. ** 5) Sending server process its commands. ** 6) Checking whether server startup succeeded or not. ** ** iirundbms command line format is: ** iirundbms <server type> <server flavor> ** where server type is something like "dbms", "recovery", "star", and ** server flavor is something like "public", "nonames", "benchmark". ** ** Inputs: ** argc - number of arguments (should be 1, 2 or 3) ** argv - argument array. ** ** Outputs: ** None ** ** Returns: ** a VMS status code is returned. ** ** History: ** 31-jan-1994 (bryanp) ** Added comment header. ** 21-Jan-1998 (horda03) Bug 68559 ** For GCC servers where a server flavour has been specified, ** command line to start the server must specify the server ** flavour in the form; "-instance=<server_flavor>" in order ** for the GCC to pickup the correct configuration details. ** 22-feb-1998 (chash01) ** RMCMD (Visual DBA backend server) startup takes two VMS CREPRC ** calls, one ihere, one in rmcmd.exe. When RMCMD server starts ** the PID returned by CREPRC in this module is no longer valid. ** WE have to first decode pid in the t_user_data field returned by ** RMCMD server in termination mailbox before print PID and ** server name to terminal. ** 31-Aug-2007 (ashco01) Bug #113490 & Bug #119021. ** Corrected detection of 'instance name' for GCB & GCD. ** 05-Dec-2007 (ashco01) Bug #119561. ** Ensure that all Ingres back-end detached processes define the ** SYS$SCRATCH logical as this is referenced via II_TEMPORARY ** when placing temporary DCL files. ** 10-Dec-2007 (ashco01) Bug #119561 ** Define SYS$SCRATCH within all detached processes. */ main( int argc, char **argv ) { static $DESCALLOC( prcnam ); unsigned int pqlcnt = 0; $DESCALLOC( uicdsc ); char *param; char prcbuf[16]; ACCDEF2 accmsg; unsigned int pid; unsigned short chan; unsigned short term; unsigned int mbxunt; int dviitem; char buf[128], tmp[128]; II_VMS_MASK_LONGWORD efc_state; char *log_start_commands; IOSB iosb; ER_ARGUMENT dummy_arg; i4 i; STATUS status; i4 gcc = 0; i4 gcc_instance = 0; i4 gcb = 0; i4 gcb_instance = 0; i4 gcd = 0; i4 gcd_instance = 0; /* ** setup the type and server_flavor parameters */ if ( argc >= 2 ) { server_type = argv[1]; /* Are we starting a GCB, GCC or GCD ? */ if (STbcompare( server_type, 3, "gcc", 3, TRUE ) == 0) gcc++; if (STbcompare( server_type, 3, "gcb", 3, TRUE ) == 0) gcb++; if (STbcompare( server_type, 3, "gcd", 3, TRUE ) == 0) gcd++; } if ( argc >= 3 ) { server_flavor = argv[2]; /* Need to precede server_flavor with "-instance=" ** if we're starting a GCB, GCC or GCD. */ gcc_instance = gcc; gcb_instance = gcb; gcd_instance = gcd; } /* ** initialize PM routines and setup the default ** search parameters for config.dat */ status = PMinit( ); if (status) { pmerr_func(status, 0, &dummy_arg); return (status); } switch( status = PMload((LOCATION *)NULL, pmerr_func) ) { case OK: /* Loaded sucessfully */ break; case PM_FILE_BAD: /* syntax error */ if (status != FAIL) /* As of Nov 1993, PM.H defines PM_FILE_BAD 1 */ pmerr_func(status, (i4)0, &dummy_arg); return (status); default: /* unable to open file */ if (status != FAIL) /* FAIL is a useless status to report... */ pmerr_func(status, (i4)0, &dummy_arg); return (status); } #ifdef EDBC PMsetDefault( 0, ERx( "ed" ) ); #else PMsetDefault( 0, ERx( "ii" ) ); #endif PMsetDefault( 1, PMhost( ) ); PMsetDefault( 2, server_type ); PMsetDefault( 3, server_flavor ); /* read and process pm parameters */ for ( i = 0; pm_option[i].PM_name != NULL; i++ ) { status = PMget( pm_option[i].PM_name, ¶m ); if ( status != OK ) continue; switch ( pm_option[i].type ) { unsigned int *target; case TYPE_CLRFLG: if ( STbcompare(param, 0, "off", 0, TRUE) != 0 && STbcompare(param, 0, "on", 0, TRUE) != 0 ) { SIprintf("IIRUNDBMS: %s value must be ON or OFF\n", pm_option[i].PM_name); SIflush(stdout); log_errmsg( "Must be ON or OFF", SS$_BADPARAM, 1 ); return (SS$_BADPARAM); } target = (unsigned int *)pm_option[i].target; if ( STbcompare(param, 0, pm_option[i].keyword, 0, TRUE) == 0) *target &= ~(int)pm_option[i].parameter; if ( msg_echo && (STscompare( pm_option[i].PM_name, 0, echo, 0 ) == 0) ) ERoptlog( pm_option[i].PM_name, param ); break; case TYPE_SETFLG: if ( STbcompare(param, 0, "off", 0, TRUE) != 0 && STbcompare(param, 0, "on", 0, TRUE) != 0 ) { SIprintf("IIRUNDBMS: %s value must be ON or OFF\n", pm_option[i].PM_name); SIflush(stdout); log_errmsg( "Must be ON or OFF", SS$_BADPARAM, 1 ); return (SS$_BADPARAM); } target = (unsigned int *)pm_option[i].target; if ( STbcompare(param, 0, pm_option[i].keyword, 0, TRUE) == 0) *target |= (int)pm_option[i].parameter; if ( msg_echo ) ERoptlog( pm_option[i].PM_name, param ); break; case TYPE_INT: target = (unsigned int *)pm_option[i].target; status = CVal( param, target ); if (status) { SIprintf("IIRUNDBMS: %s value must be an integer\n", pm_option[i].PM_name); SIflush(stdout); pmerr_func(status, 0, &dummy_arg); return (SS$_BADPARAM); } if ( msg_echo ) { STprintf( buf, "%d", *target ); ERoptlog( pm_option[i].PM_name, buf ); } break; case TYPE_UIC: { $DESCINIT( uicdsc, param ); status = iics_cvtuic( &uicdsc, (char *)pm_option[i].target ); if ( !(status & 1) ) { log_errmsg( "vms_uic invalid", status, 1 ); return (status); /* B56811 */ } if ( msg_echo ) { if ( *(unsigned int *)(pm_option[i].target) != 0 ) { STprintf( buf, "%s [%o,%o]", param, ((uic >> 16) & 0xffff), (uic & 0xffff) ); ERoptlog( pm_option[i].PM_name, buf ); } } break; } case TYPE_STR: if (STlength(param) > MAX_STRING_OPTION_LENGTH) { SIprintf("IIRUNDBMS: Max length for %s is %d\n", pm_option[i].PM_name, MAX_STRING_OPTION_LENGTH); SIflush(stdout); return (SS$_BADPARAM); } STcopy( param, (char *)pm_option[i].target ); if ( msg_echo ) ERoptlog( pm_option[i].PM_name, param ); break; case TYPE_PQL: /* ** build VMS process quota block */ quota[pqlcnt].name = (char)pm_option[i].parameter; status = CVal( param, "a[pqlcnt].value ); if (status) { SIprintf("IIRUNDBMS: %s value must be an integer\n", pm_option[i].PM_name); SIflush(stdout); pmerr_func(status, 0, &dummy_arg); return (SS$_BADPARAM); } pqlcnt++; if ( msg_echo ) ERoptlog( pm_option[i].PM_name, param ); break; case TYPE_PRIV: { char prvbuf[512]; char *p, *q; i4 j; /* ** Remove white space then ** convert the string to upper case, then ** remove leading and trailing parens */ if (STlength(param) >= sizeof(prvbuf)) { SIprintf("IIRUNDBMS: vms_privileges are too long\n"); SIprintf(" Actual length (%d) exceeds maximum (%d)\n", STlength(param), sizeof(prvbuf)); SIflush(stdout); return (SS$_BADPARAM); } STcopy( param, prvbuf); STtrmwhite( prvbuf ); CVupper( prvbuf ); /* ** Scan the comma seperated privilege list and set the ** privileges for each privileges keywork in the list. */ for ( p = prvbuf; p != 0 && *p != 0; p = q ) { if ( (q = STindex( p, ERx( "," ), 0 )) != NULL ) *q++ = '\0'; else if ( (q = STindex( p, ERx( ")" ), 0 )) != NULL ) *q++ = '\0'; if ( *p == '(' ) p++; for ( j = 0; prv_table[j].prv_name != NULL; j++ ) { if ( STscompare( p, 4, prv_table[j].prv_name, 4 ) == 0 ) { prvadr[0] |= prv_table[j].prv_code_low; prvadr[1] |= prv_table[j].prv_code_hi; if ( msg_echo ) ERoptlog( pm_option[i].PM_name, prv_table[j].prv_name ); break; } } if (prv_table[j].prv_name == NULL) { /* ** We failed to find privilege "p" in our table */ SIprintf("IIRUNDBMS: Syntax error in privilege list\n"); SIprintf(" Error near byte %d of string %s", p - prvbuf, param); SIflush(stdout); ERoptlog("Unrecognized privilege:", p); return (SS$_BADPARAM); } } break; } default: break; } }
/****************************************************************************** ** Name: CSoptions() - fetch a pile of options using PMget() ** ** Description: ** Calls PMget() for each option in the option table, converts the ** value appropriately, and distributes the value into the right ** spot in the CS_SYSTEM block. ** ** Note special cruddiness surrounding CSO_SERVER_CLASS: the CL ** fetches this only to set cs_isstar, used by CSinitiate() to ** calculate the file descriptor fluff factors: STAR uses more of 'em. ******************************************************************************/ STATUS CSoptions( CS_SYSTEM *cssb ) { i4 echo = 1; struct CSO_OPTIONS *csopt; i4 failures = 0; for( csopt = cso_opttab; csopt->cso_name; csopt++ ) { char *cs_svalue; i4 cs_value = 0; STATUS status = OK; /* * Get option's value using PMget() */ if( PMget( csopt->cso_name, &cs_svalue ) != OK ) continue; if( echo ) ERoptlog( csopt->cso_name, cs_svalue ); /* * Convert & check the option's value, according to argtype */ switch( csopt->cso_argtype ) { case 'g': /* String option */ break; case 'm': /* numeric option or the word "max" if( !STcompare( cs_svalue, "max" ) ) { cs_value = -1; break; } /* fall through */ case 'o': case 'n': /* set a numeric option */ if( CVal( cs_svalue, &cs_value ) != OK ) { status = E_CS0025_NUMERIC_ARG; } else if( csopt->cso_argtype == 'o' && cs_value < 0 ) { status = E_CS0026_POSITIVE_VALUE; } break; case 't': /* set a switch option: on = true */ if( STbcompare( cs_svalue, 0, "on", 0, TRUE ) ) continue; break; case 'z': /* clear a switch option */ if( !STbcompare( cs_svalue, 0, "on", 0, TRUE ) ) continue; break; } if( status ) { (*cssb->cs_elog)( status, (CL_ERR_DESC *)0, 1, STlength( csopt->cso_name ), csopt->cso_name ); failures++; break; } /* * Distribute option value, according to index */ switch( csopt->cso_index ) { case CSO_ECHO: /* echo: off */ echo = 0; break; case CSO_ACT_SESSION: cssb->cs_max_active = cs_value; break; case CSO_CON_SESSION: cssb->cs_max_sessions = cs_value; break; case CSO_MAXLDB_CON: // cssb->cs_max_ldb_connections = cs_value; break; case CSO_MAX_WS: # if defined( xCL_034_GETRLIMIT_EXISTS) && defined( RLIMIT_RSS ) { struct rlimit rlim; getrlimit( RLIMIT_RSS, &rlim ); rlim.rlim_cur = cs_value; if( cs_value < 0 || cs_value > rlim.rlim_max ) rlim.rlim_cur = rlim.rlim_max; setrlimit( RLIMIT_RSS, &rlim ); } #endif break; case CSO_PRIORITY: /* Process priority */ # ifdef xCL_033_SETPRIORITY_EXISTS // setpriority( PRIO_PROCESS, 0, cs_value ); # else // nice( cs_value ); # endif break; case CSO_QUANTUM: // cssb->cs_quantum = cs_value; break; case CSO_SESS_ACCTNG: cssb->cs_mask |= CS_ACCNTING_MASK; cssb->cs_mask |= CS_CPUSTAT_MASK; break; case CSO_CPUSTATS: cssb->cs_mask |= CS_CPUSTAT_MASK; break; case CSO_STK_SIZE: cssb->cs_stksize = cs_value; break; case CSO_SERVER_CLASS: // cssb->cs_isstar = !STcompare( cs_svalue, "STAR" ); /* cheesy */ break; case CSO_DEFINE: cssb->cs_define = TRUE; break; } } return (OK); }