bool ascs_chk_priv( char *user_name, char *priv_name ) { char pmsym[128], userbuf[DB_OWN_MAXNAME+1], *value, *valueptr ; char *strbuf = 0; int priv_len; /* ** privileges entries are of the form ** ii.<host>.*.privilege.<user>: SERVER_CONTROL,NET_ADMIN,... ** ** Currently known privs are: SERVER_CONTROL,NET_ADMIN, ** MONITOR,TRUSTED */ STlcopy( user_name, userbuf, DB_OWN_MAXNAME ); STtrmwhite( userbuf ); STprintf(pmsym, "$.$.privileges.user.%s", userbuf); /* check to see if entry for given user */ /* Assumes PMinit() and PMload() have already been called */ if( PMget(pmsym, &value) != OK ) return FALSE; valueptr = value ; priv_len = STlength(priv_name) ; /* ** STindex the PM value string and compare each individual string ** with priv_name */ while ( *valueptr != EOS && (strbuf=STindex(valueptr, "," , 0))) { if (!STscompare(valueptr, priv_len, priv_name, priv_len)) return TRUE ; /* skip blank characters after the ','*/ valueptr = STskipblank(strbuf+1, 10); } /* we're now at the last or only (or NULL) word in the string */ if ( *valueptr != EOS && !STscompare(valueptr, priv_len, priv_name, priv_len)) return TRUE ; return FALSE; }
/* ** Name: WTSOpenUpLoad() - ** ** Description: ** ** Inputs: ** contentType ** session ** ** Outputs: ** ** Returns: ** GSTATUS : GSTAT_OK ** ** Exceptions: ** None ** ** Side Effects: ** None ** ** History: */ GSTATUS WTSOpenUpLoad( char *contentType, WTS_SESSION *session) { GSTATUS err; i4 length = STlength(MULTIPART); PWTS_UPLOAD load = NULL; char* bound; i4 blen; if (contentType != NULL && STscompare(contentType, length, MULTIPART, length) == 0) { session->status = UPLOAD; if ((err = GAlloc ((char**)&load, sizeof(WTS_UPLOAD), FALSE)) == GSTAT_OK) { session->load = load; bound = STindex (contentType, BOUNDARY, 0) + STlength(BOUNDARY); blen = STlength (bound); /* ** Allocate space for a start boundary and and en boundary ** each having the delimiters and null terminator. */ if (((err = GAlloc (&load->start, blen + 3, FALSE)) == GSTAT_OK) && ((err = GAlloc (&load->end, blen + 5, FALSE)) == GSTAT_OK)) { STcopy ("--",load->start); STlcopy (bound, load->start + 2, blen); STcopy (load->start, load->end); STcat (load->end, "--"); } load->state = US_BEGIN; } } else { session->status = NO_UPLOAD; session->load = NULL; } session->list = NULL; session->variable = NULL; session->vlen = 0; return(GSTAT_OK); }
void main(int argc, char *argv[]) { #define MAXBUF 4095 #define MAX_NAME 32 char buf[ MAXBUF+1 ]; char repbuf[ MAXBUF+1 ]; int iarg, ibuf, ichr; char *database = NULL; char username[MAX_NAME] = {""}; LOCATION tloc; LOCATION loc_out; LOCATION loc_in; char loc_buf[MAX_LOC + 1]; char tmp_buf[MAX_LOC + 1]; char otmp_buf[MAX_LOC + 1]; char dev[MAX_LOC + 1]; char path[MAX_LOC + 1]; char fprefix[MAX_LOC + 1]; char fsuffix[MAX_LOC + 1]; char version[MAX_LOC + 1]; char odev[MAX_LOC + 1]; char opath[MAX_LOC + 1]; char ofprefix[MAX_LOC + 1]; char ofsuffix[MAX_LOC + 1]; char oversion[MAX_LOC + 1]; char *new_filename; char *temploc; CL_ERR_DESC err_code; char *p1 = NULL; bool usergiven = FALSE; bool Repmod = FALSE; bool nowait = TRUE; char waitflag[3]; if (argc < 2) { usage(); PCexit(FAIL); } /* Get the temporary path location */ NMloc(TEMP, PATH, NULL, &tloc); LOcopy(&tloc, tmp_buf, &loc_in); LOtos(&tloc, &temploc); LOcopy(&tloc, otmp_buf, &loc_out); /* Get the new filename for path location */ LOuniq(ERx("usrmod"), ERx("sql"), &loc_in); LOtos(&loc_in, &new_filename); LOuniq(ERx("usrmod"), ERx("out"), &loc_out); /* Get just the filename for copydb code */ LOdetail(&loc_in, dev, path, fprefix, fsuffix, version); if ( *fsuffix != '\0' ) { STcat(fprefix, "."); STcat(fprefix, fsuffix); } /* Get just the filename for copydb code */ LOdetail(&loc_out, odev, opath, ofprefix, ofsuffix,oversion); STcat(ofprefix, "."); STcat(ofprefix, ofsuffix); STprintf(buf, ERx("copydb -with_modify -nodependency_check -with_index -with_comments -no_persist -parallel -no_repmod -group_tab_idx -no_warn -d\"%s\" -infile=\"%s\" -outfile=\"%s\"" ), temploc, fprefix,ofprefix); ibuf = STlength(buf); for (iarg = 1; (iarg < argc) && (ibuf < MAXBUF); iarg++) { if( STscompare( argv[ iarg ], 1, ERx( "-" ), 1 ) == 0 ) { p1 = argv[ iarg ]; (void) CMnext( p1 ); if ( (STlength(p1) == 0) || !(((STscompare( p1, 1, ERx( "u" ), 1 ) == 0 ) || (STscompare( p1, 5, ERx( "noint" ), 5 ) == 0 ) || (STscompare( p1, 6, ERx( "repmod" ), 6 ) == 0 ) || (STscompare( p1, 1, ERx( "w" ), 6 ) == 0 ) || (STscompare( p1, 6, ERx( "online"), 6 ) == 0 )) && ( argc > 2 ) )) { usage(); PCexit(FAIL); } /* ** Get the username if the -u flag is passed in ** with the input */ if (STscompare( p1, 1, ERx( "u" ), 1 ) == 0 ) { STcopy(&argv[iarg][2] , (char *)&username); usergiven = TRUE; } else if (STscompare( p1, 1, ERx( "r" ), 1 ) == 0 ) { Repmod = TRUE; continue; } else if (STscompare( p1, 1, ERx( "w"), 1 ) == 0) { nowait = TRUE; continue; } } if( STscompare( argv[ iarg ], 1, ERx( "+" ), 1 ) == 0 ) { p1 = argv[ iarg ]; (void) CMnext( p1 ); if (STscompare( p1, 1, ERx( "w" ), 1 ) == 0 ) { nowait = FALSE; continue; } else { usage(); PCexit(FAIL); } } if((database == NULL) && (STscompare( argv[ iarg ], 1, ERx( "+" ), 1 ) != 0) && (STscompare( argv[ iarg ], 1, ERx( "-" ), 1 ) != 0)) { database = argv[ iarg ]; } buf[ibuf++] = ' '; for (ichr = 0; (argv[iarg][ichr] != '\0') && (ibuf < MAXBUF); ichr++, ibuf++) { buf[ibuf] = argv[iarg][ichr]; } buf[ibuf] = '\0'; } /* ** Execute the command. */ if( PCcmdline((LOCATION *) NULL, buf, PC_WAIT, (LOCATION *) NULL, &err_code) != OK ) PCexit(FAIL); /* ** we should run the sql script ** sql dbname < new_filename ** if -u flag given then run: ** sql -uusername dbname < new_filename */ if (usergiven) STprintf(buf, ERx( "sql -u%s -s %s <%s" ), username, database, new_filename ); else STprintf(buf, ERx( "sql -s %s <%s" ), database, new_filename ); /* ** Execute the command. */ if( PCcmdline((LOCATION *) NULL, buf, PC_WAIT, (LOCATION *) NULL, &err_code) != OK ) { STprintf(buf, ERx(" Warning: Non-persistent objects associated with the base table\n in the failed query may have been lost. Please refer to\n %s\n to determine whether any corrective action is required.\n"), new_filename); SIfprintf(stdout, buf); PCexit(FAIL); } /* Now execute the repmod command if the replicator ** modify is also required by the user (-repmod) */ if (Repmod) { if (nowait) STcopy("-w", waitflag) ; else STcopy("+w", waitflag) ; if (usergiven) STprintf(repbuf, ERx( "repmod -u%s %s %s" ), username, database, waitflag ); else STprintf(repbuf, ERx( "repmod %s %s" ), database, waitflag ); if( PCcmdline((LOCATION *) NULL, repbuf, PC_WAIT, (LOCATION *) NULL, &err_code) != OK ) PCexit(FAIL); } /* ** Delete the location */ LOdelete(&loc_in); LOdelete(&loc_out); PCexit(OK); }
main(int argc, char **argv) { char *value = NULL; char *host, *server_type, *command_line; char *server_location, *env, *arguments; u_i4 command_line_length; char config_string[256]; char iidbms[256]; STARTUPINFO si; PROCESS_INFORMATION ProcessInfo; BOOL Status; SECURITY_ATTRIBUTES sa; HANDLE hRead, hWrite; HANDLE hStdout; char buffer[512]; DWORD bufferl = sizeof(buffer); DWORD pipe_size = 0; /* Use default buffer size */ DWORD datal = 0; bool havequote, failed = FALSE; MEadvise( ME_INGRES_ALLOC ); switch (argc) { case 1: server_type = ERx("dbms"); server_location = ERx("*"); break; case 2: server_type = argv[1]; server_location = ERx("*"); break; default: server_type = argv[1]; if (STcompare(server_type, "recovery") == 0) server_location = ERx("*"); else server_location = argv[2]; break; } get_sys_dependencies(); /* ** Get the host name, formally used iipmhost. */ host = PMhost(); /* ** Build the string we will search for in the config.dat file. */ STprintf( config_string, ERx("%s.%s.%s.%s.image_name"), SystemCfgPrefix, host, server_type, server_location ); /* ** Get set up for the PMget call. */ PMinit(); if( PMload( NULL, (PM_ERR_FUNC *)NULL ) != OK ) PCexit( FAIL ); /* ** Go search config.dat for a match on the string we just built. */ PMget( config_string, &value ); if ( value == NULL ) { NMgtAt( SystemLocationVariable, &env ); if (STcompare(server_type, "recovery") == 0) { STprintf(iidbms, ERx("%s\\%s\\bin\\%sdbms"), env, SystemLocationSubdirectory, SystemCfgPrefix); } else { STprintf(iidbms, ERx("%s\\%s\\bin\\%s%s"), env, SystemLocationSubdirectory, SystemCfgPrefix, server_type); } } else if ( *value == '/' || *value == '\\' || (*(value+1) == ':' && *(value+2) == '\\') ) { /* Must be a qualified path name */ STcopy( value, iidbms ); } else { NMgtAt( SystemLocationVariable, &env ); STprintf( iidbms, ERx("%s\\%s\\bin\\%s"), env, SystemLocationSubdirectory, value ); } /* ** Initialize the startinfo structure. */ ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); /* ** Get the original command line. */ arguments = GetCommandLine(); havequote = FALSE; while (*arguments != '\0' && *arguments != '\n') { if ( *arguments == '"' ) havequote = (havequote) ? FALSE : TRUE; if ( CMwhite(arguments) && havequote == FALSE ) break; arguments++; } /* ** Put together a command line to create a process with. ** - 4 blank separators, quotes, null termination */ command_line_length = STlength(arguments) + STlength(iidbms) + STlength(iirun) + 6 + 1; if((command_line = (char *) MEreqmem(0, command_line_length, TRUE, NULL)) == NULL) { error(ERx("Request for memory failed"),NULL); } STprintf( command_line, "%s \"%s\" %s", iirun, iidbms, arguments ); /* ** Save standard out's handle, to be restored later. */ hStdout = GetStdHandle(STD_OUTPUT_HANDLE); /* ** Initialize the security attributes structure that will ** be used to make the pipe handles inheritable. */ sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* Make object inheritable */ /* ** Define a anonymous pipe to catch the server's startup message. */ if((Status = CreatePipe(&hRead,&hWrite,&sa,pipe_size)) != TRUE) { error(ERx("CreatePipe failed"),ERx("error code = ")); } SetStdHandle(STD_OUTPUT_HANDLE,hWrite); /* ** Initialize the security attributes structure that will ** be used to make the pipe handles inheritable. */ sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* Make object inheritable */ /* ** Initialize the startup information structure. */ ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); /* ** Start it up. */ /* ** Start iirun which will start the server. */ if ((Status = CreateProcess(NULL,command_line,&sa,NULL,TRUE, HIGH_PRIORITY_CLASS, NULL, NULL,&si,&ProcessInfo)) != TRUE) { DWORD dwError = GetLastError(); switch(dwError) { case ERROR_ACCESS_DENIED: error(ERROR_REQ_PRIVILEGE, ERx("")); break; case ERROR_ELEVATION_REQUIRED: error(ERROR_DENIED_PRIVILEGE, ERROR_REQ_ELEVATION); break; default: error(ERx("CreateProcess failed"),ERx("error code = ")); break; } } SetStdHandle(STD_OUTPUT_HANDLE,hStdout); for (;;) { char *tmpptr; if((Status = ReadFile(hRead,&buffer,bufferl,&datal,NULL)) != TRUE) { error(ERx("ReadFile failed"),ERx("error code = ")); } buffer[datal] = '\0'; if ((tmpptr = STstrindex(buffer, "PASS\n", 0, FALSE))) { *tmpptr = '\0'; if (STlength(buffer)) SIfprintf(stdout, "%s", buffer); break; } SIfprintf(stdout, "%s", buffer); if ((tmpptr = STstrindex(buffer, bad_msg, 0, FALSE))) { *tmpptr = '\0'; if (STlength(buffer)) SIfprintf(stdout, "%s", buffer); failed = TRUE; break; } } /* ** Close handles since we don't need them anymore. */ CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); CloseHandle(hRead); CloseHandle(hWrite); if (failed && STscompare(server_type, STlength(server_type), "gcb", 3) != 0 && STscompare(server_type, STlength(server_type), "gcc", 3) != 0 && STscompare(server_type, STlength(server_type), "jdbc", 4) != 0) { SIfprintf( stderr,"\n%s: server would not start.\n", iirundbms ); SIfprintf(stderr, " %s must be set in your environment.\n", SystemLocationVariable ); SIfprintf(stderr, " Has the csinstall program been run?\n"); SIfprintf(stderr, " %s_DATABASE, %s_CHECKPOINT, %s_JOURNAL and %s_DUMP\n", SystemVarPrefix, SystemVarPrefix, SystemVarPrefix, SystemVarPrefix ); SIfprintf(stderr, " must also be set. See %s_CONFIG\\symbol.tbl.\n", SystemVarPrefix ); SIfprintf(stderr, " Check the file '%%%s%%\\%s\\files\\errlog.log'\n", SystemLocationVariable, SystemLocationSubdirectory ); SIfprintf(stderr, " for more details concerning internal errors.\n"); SIfprintf(stderr, " See your Installation and Operation Guide for more\n"); SIfprintf(stderr, " information concerning server startup.\n"); PCexit(FAIL); } else { PCexit(OK); } }
/*{ ** Name: adt_compare() - Compare 2 data values. ** ** Description: ** This routine compares two data values. This will tell the caller if the ** supplied values are equal, or if not, which one is "greater than" the ** other. ** ** This routine exists as a performance boost for DMF. DMF is not allowed ** to know how to compare data values for the various datatypes. ** Therefore, if this routine did not exist, DMF would have to make a ** function call to "adc_compare()" for every attribute in the tuples ** being compared. Even though tuples are constructs that seem a level ** above what ADF logically handles, the performance improvement in this ** case justifies this routine. ** ** To avoid the overhead of an adc_compare call, ** this routine has built into it the semantics for ** comparing several of the most common datatypes supported by INGRES. ** ** If the routine does run across a datatype that is not in this list, it ** will call the general routine "adc_compare()", thereby guaranteeing ** that it will function (perhaps slower), for ALL datatypes, even future ** user defined ADTs. ** ** When NULL values are involved, this routine will use the same semantics ** that "adc_compare()" uses: a NULL value will be considered greater ** than any other value, and equal to another NULL value. ** ** PLEASE NOTE: As with "adc_compare()", no pattern matching for ** ----------- the string datatypes is done within this routine. ** ** ** Inputs: ** adf_scb Pointer to an ADF session control block. ** .adf_errcb ADF_ERROR struct. ** .ad_ebuflen The length, in bytes, of the buffer ** pointed to by ad_errmsgp. ** .ad_errmsgp Pointer to a buffer to put formatted ** error message in, if necessary. ** atr Pointer to DB_ATTR. ** d1 Pointer to first value. ** d2 Pointer to second value. ** ** Outputs: ** adf_scb Pointer to an ADF session control block. ** .adf_errcb ADF_ERROR struct. If an ** error occurs the following fields will ** be set. NOTE: if .ad_ebuflen = 0 or ** .ad_errmsgp = NULL, no error message ** will be formatted. ** .ad_errcode ADF error code for the error. ** .ad_errclass Signifies the ADF error class. ** .ad_usererr If .ad_errclass is ADF_USER_ERROR, ** this field is set to the corresponding ** user error which will either map to ** an ADF error code or a user-error code. ** .ad_emsglen The length, in bytes, of the resulting ** formatted error message. ** .adf_errmsgp Pointer to the formatted error message. ** status Status returned from ** adc_compare(), if called. ** ** The following DB_STATUS codes may be returned by adc_compare(): ** E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_SEVERE, E_DB_FATAL ** ** If a DB_STATUS code other than E_DB_OK is returned, the caller ** can look in the field adf_scb.adf_errcb.ad_errcode to determine ** the ADF error code. The following is a list of possible ADF error ** codes that can be returned by this routine: ** ** E_AD0000_OK Operation succeeded. ** E_AD2004_BAD_DTID Datatype id unknown to ADF. ** E_AD2005_BAD_DTLEN Internal length is illegal for ** the given datatype. ** (Others not yet defined) ** ** Returns: ** i4 < 0 if 1st < 2nd ** = 0 if 1st = 2nd ** > 0 if 1st > 2nd ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 10-Feb-86 (thurston) ** Initial creation. ** 03-apr-86 (thurston) ** Initial coding. Also, added two more return statuses (stati?): ** E_AD2004_BAD_DTID and E_AD2005_BAD_DTLEN. ** 11-jun-86 (jennifer) ** Fixed bug compare result asigned to adt_cmp_result instead ** of indirect through this pointer, i.e. *adt_cmp_result. ** 11-jun-86 (jennifer) ** Fixed bug where the first entry of attribute array (0) ** was being used. This entry is always garbage since ** attributes are numbered from 1. ** 27-jul-86 (ericj) ** Converted for new ADF error handling. ** 19-nov-86 (thurston) ** Fixed the comparison for text. ** 22-sep-88 (thurston) ** Added bit representation check as a first pass on each attr. Also, ** added code to deal with nullable types here ... this could be a big ** win, since all nullable types were going through adc_compare(), now ** they need not. Also, added cases for CHAR and VARCHAR. ** 21-oct-88 (thurston) ** Got rid of all of the `#ifdef BYTE_ALIGN' stuff by using the ** appropriate [I2,I4,F4,F8]ASSIGN_MACROs. This also avoids a bunch ** of MEcopy() calls on BYTE_ALIGN machines. ** 21-Apr-89 (anton) ** Added local collation support ** 17-Jun-89 (anton) ** Moved local collation routines to ADU from CL ** 25-jul-89 (jrb) ** Added support for decimal datatype. ** 02-jan-90 (jrb) ** Fix alignment problem. ** 08-aug-91 (seg) ** "d1" and "d2" are dereferenced too often with the assumption ** that (PTR) == (char *) to fix. Made them (char *). ** 28-mar-2001 (abbjo03) ** Add support for DB_NCHR_TYPE and DB_NVCHR_TYPE. ** 16-dec-04 (inkdo01) ** Add collation ID parm to aduucmp() calls. ** 02-Feb-2005 (jenjo02) ** Consolidated from the nine adt functions which duplicated ** this "compare" code. Runs the most optimal compare ** based on datatype for a single attribute. ** ** Optimized CHA/VCH compares to use MEcmp rather than ** CMcmpcase loop when possible. ** ** Replace giant switch statement with if-then-else ** ordered most likely to least likely, more or less. ** The switch was consuming 27% of the CPU used by this ** function. ** ** Added DB_STATUS *status as a function parameter so ** if adc_compare returns an error, it will be returned ** to the caller rather than as a bogus compare "result". ** 27-Apr-2005 (jenjo02 for stial01) ** Replaced computing compare value using arithmetic ** (d1 - d2) with logical compares ( d1 < d2...) as ** the arithmetic may over/underflow and return the ** wrong result. ** 13-May-2005 (thaju02) ** For differing length vchar, return value based on ** comparison of longer length vchar to blank. (B114514) ** 19-Jun-2006 (gupsh01) ** Added support for new date/time types. ** 3-may-2007 (dougi) ** Tweak slightly to allow MEcmp() on collation/double byte ** if they're bytewise equal. ** 10-may-2007 (dougi) ** Add logic to handle ordering of c/text/char/varchar in UTF8 ** server. ** 25-jul-2007 (gupsh01) ** Although UTF8 is multibyte it is meant to be processed through ** UTF8 comparison code utilizing unicode comparison. ** 17-Aug-2007 (gupsh01) ** Fix the UTF8 handling. */ i4 adt_compare( ADF_CB *adf_scb, DB_ATTS *atr, /* Attribute in question */ char *d1, /* Ptr to 1st value */ char *d2, /* Ptr to 2nd value */ DB_STATUS *status) /* Status from adc_compare */ { i4 cur_cmp; /* Result of latest attr cmp */ i4 vi1, vi2; /* Temp i4's used to cmp ints */ i8 lli1, lli2; /* Compare i8's */ f8 vf1, vf2; /* Temp f8's used to cmp flts */ u_char *lc1, *lc2; u_char blank; i4 atr_bdt; /* Base datatype of attr */ i2 atr_len; /* Length of cur attribute */ i4 d1_isnull, d2_isnull; DB_DATA_VALUE dv1, dv2; /* Data value structs for call ** to adc_compare(), if that is ** necessary. */ u_char *tc1, *tc2; /* Temps used for string compare */ u_char *endtc1, *endtc2; UCS2 *tn1, *tn2; /* Temps used for Nstring compare */ UCS2 *endtn1, *endtn2; /* ** The following four lines provide temp storage to solve ** byte allignment problems on some archictectures. */ i2 i2_t1, i2_t2; i4 i4_t1, i4_t2; f4 f4_t1, f4_t2; f8 f8_t1, f8_t2; #define ADT_LT (i4)-1 #define ADT_EQ (i4)0 #define ADT_GT (i4)1 *status = E_DB_OK; atr_len = atr->length; if ( (atr_bdt = atr->type) < 0 ) { /* Nullable datatype */ d1_isnull = (*((char *)d1 + atr_len - 1) & ADF_NVL_BIT); d2_isnull = (*((char *)d2 + atr_len - 1) & ADF_NVL_BIT); if ( !d1_isnull && !d2_isnull ) { /* Neither is the Null value, look at data */ atr_bdt = -atr_bdt; atr_len--; } else if (d1_isnull && d2_isnull) return(ADT_EQ); /* both are Null values; 1st = 2nd */ else if (d1_isnull) return(ADT_GT); /* 1st is Null value; 1st > 2nd */ else return(ADT_LT); /* 2nd is Null value; 1st < 2nd */ } /* "if then else" consumes ~27% less CPU than "switch" */ if ( atr_bdt == DB_INT_TYPE ) { /* If both operands aligned... */ /* Extra casts to shut up compilers -- only care about low bits */ if ( (((i4)(SCALARP)d1 | (i4)(SCALARP)d2) & atr_len-1) == 0 ) { if ( atr_len == 4 ) { if (*(i4*)d1 < *(i4*)d2) return(ADT_LT); else if (*(i4*)d1 > *(i4*)d2) return(ADT_GT); else return(ADT_EQ); } if ( atr_len == 8 ) { if (*(i8*)d1 < *(i8*)d2) return(ADT_LT); else if (*(i8*)d1 > *(i8*)d2) return(ADT_GT); else return(ADT_EQ); } if ( atr_len == 2 ) { if (*(i2*)d1 < *(i2*)d2) return(ADT_LT); else if (*(i2*)d1 > *(i2*)d2) return(ADT_GT); else return(ADT_EQ); } if (*(i1*)d1 < *(i1*)d2) return(ADT_LT); else if (*(i1*)d1 > *(i1*)d2) return(ADT_GT); else return(ADT_EQ); } /* One or both not aligned... */ if (atr_len == 4) { I4ASSIGN_MACRO(*d1, i4_t1); I4ASSIGN_MACRO(*d2, i4_t2); if (i4_t1 < i4_t2) return(ADT_LT); else if (i4_t1 > i4_t2) return(ADT_GT); else return(ADT_EQ); } if (atr_len == 8) { I8ASSIGN_MACRO(*d1, lli1); I8ASSIGN_MACRO(*d2, lli2); if (lli1 < lli2) return(ADT_LT); else if (lli1 > lli2) return(ADT_GT); else return(ADT_EQ); } if (atr_len == 2) { I2ASSIGN_MACRO(*d1, i2_t1); I2ASSIGN_MACRO(*d2, i2_t2); if (i2_t1 < i2_t2) return(ADT_LT); else if (i2_t1 > i2_t2) return(ADT_GT); else return(ADT_EQ); } if (*(i1*)d1 < *(i1*)d2) return(ADT_LT); else if (*(i1*)d1 > *(i1*)d2) return(ADT_GT); else return(ADT_EQ); } if ( atr_bdt == DB_FLT_TYPE || atr_bdt == DB_MNY_TYPE ) { /* If both operands aligned... */ /* Extra casts to shut up compilers, only care about low bits */ if ( (((i4)(SCALARP)d1 | (i4)(SCALARP)d2) & atr_len-1) == 0 ) { if ( atr_len == 8 ) { if (*(f8*)d1 < *(f8*)d2) return(ADT_LT); else if (*(f8*)d1 > *(f8*)d2) return(ADT_GT); else return(ADT_EQ); } if (*(f4*)d1 < *(f4*)d2) return(ADT_LT); else if (*(f4*)d1 > *(f4*)d2) return(ADT_GT); else return(ADT_EQ); } /* One or both not aligned... */ if ( atr_len == 8 ) { F8ASSIGN_MACRO(*d1, f8_t1); F8ASSIGN_MACRO(*d2, f8_t2); if (f8_t1 < f8_t2) return(ADT_LT); else if (f8_t1 > f8_t2) return(ADT_GT); else return(ADT_EQ); } F4ASSIGN_MACRO(*d1, f4_t1); F4ASSIGN_MACRO(*d2, f4_t2); if (f4_t1 < f4_t2) return(ADT_LT); else if (f4_t1 > f4_t2) return(ADT_GT); else return(ADT_EQ); } if ( atr_bdt == DB_BYTE_TYPE || atr_bdt == DB_TABKEY_TYPE || atr_bdt == DB_LOGKEY_TYPE ) { return(MEcmp(d1, d2, atr_len)); } if ( atr_bdt == DB_CHA_TYPE || atr_bdt == DB_VCH_TYPE ) { if ( atr_bdt == DB_CHA_TYPE ) { /* Try the turbo compare. */ cur_cmp = MEcmp(d1, d2, atr_len); /* If not equal and UTF8-enabled ... */ if (cur_cmp && (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)) return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, d1, d2, status)); /* If neither collation nor doublebyte or if byte-wise equal ... */ if ( !(adf_scb->adf_collation || Adf_globs->Adi_status & ADI_DBLBYTE) || cur_cmp == 0) { return(cur_cmp); } tc1 = (u_char *) d1; tc2 = (u_char *) d2; endtc1 = tc1 + atr_len; endtc2 = tc2 + atr_len; } else { I2ASSIGN_MACRO(((DB_TEXT_STRING *)d1)->db_t_count, i2_t1); I2ASSIGN_MACRO(((DB_TEXT_STRING *)d2)->db_t_count, i2_t2); tc1 = (u_char *)d1 + DB_CNTSIZE; tc2 = (u_char *)d2 + DB_CNTSIZE; /* Try the turbo compare on the prefix. */ cur_cmp = MEcmp((char *)tc1, (char *)tc2, min(i2_t1, i2_t2)); /* If neither collation nor doublebyte... */ if ( !(adf_scb->adf_collation || Adf_globs->Adi_status & ADI_DBLBYTE) || (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)) { i2 diff = i2_t1 - i2_t2; /* If not equal or lengths differ and UTF8-enabled ... */ if ((diff || cur_cmp) && (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)) return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, d1, d2, status)); /* If short compare produces inequality or lengths are ** the same ... */ if ( cur_cmp || diff == 0 ) { return(cur_cmp); } /* ** Equal for shorter length. ** If longer trails all blanks, they're equal */ if ( diff > 0 ) { /* tc1 is longer */ tc1 += i2_t2; while ( *(tc1++) == MIN_CHAR && --diff > 0 ); if (!diff) return( ADT_EQ ); else { tc1--; if (*tc1 > MIN_CHAR) return(ADT_GT); else return(ADT_LT); } } else { /* tc2 is longer */ tc2 += i2_t1; while ( *(tc2++) == MIN_CHAR && ++diff < 0 ); if (!diff) return( ADT_EQ ); else { tc2--; if (MIN_CHAR > *tc2) return(ADT_GT); else return(ADT_LT); } } } else if (i2_t1 == i2_t2 && cur_cmp == 0) return(cur_cmp); /* byte wise compare returns "=" */ endtc1 = tc1 + i2_t1; endtc2 = tc2 + i2_t2; } if (adf_scb->adf_collation) return(adugcmp((ADULTABLE *)adf_scb->adf_collation, ADUL_BLANKPAD, tc1, endtc1, tc2, endtc2)); /* Doublebyte is rather more tedious */ blank = (u_char)MIN_CHAR; cur_cmp = ADT_EQ; while ( cur_cmp == ADT_EQ ) { if (tc1 < endtc1) { lc1 = tc1; CMnext(tc1); } else { lc1 = ␣ } if (tc2 < endtc2) { lc2 = tc2; CMnext(tc2); } else { lc2 = ␣ } /* if both pointing to blank or we happen to be comparing ** a string to itself then break */ if (lc1 == lc2) break; cur_cmp = CMcmpcase(lc1, lc2); } return(cur_cmp); } if ( atr_bdt == DB_NCHR_TYPE || atr_bdt == DB_NVCHR_TYPE ) { if ( atr_bdt == DB_NCHR_TYPE ) { tn1 = (UCS2 *)d1; tn2 = (UCS2 *)d2; endtn1 = tn1 + atr_len / sizeof(UCS2); endtn2 = tn2 + atr_len / sizeof(UCS2); } else { tn1 = ((DB_NVCHR_STRING *)d1)->element_array; tn2 = ((DB_NVCHR_STRING *)d2)->element_array; I2ASSIGN_MACRO(((DB_NVCHR_STRING *)d1)->count, i2_t1); I2ASSIGN_MACRO(((DB_NVCHR_STRING *)d2)->count, i2_t2); endtn1 = tn1 + i2_t1; endtn2 = tn2 + i2_t2; } *status = aduucmp(adf_scb, ADUL_BLANKPAD, tn1, endtn1, tn2, endtn2, &cur_cmp, atr->collID); return (cur_cmp); } if ( atr_bdt == DB_CHR_TYPE ) { if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED) return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, d1, d2, status)); if (adf_scb->adf_collation) return(adugcmp((ADULTABLE *)adf_scb->adf_collation, ADUL_SKIPBLANK, (u_char *)d1, atr_len + (u_char *)d1, (u_char *)d2, atr_len + (u_char *)d2)); return(STscompare((char *)d1, atr_len, (char *)d2, atr_len)); } if ( atr_bdt == DB_TXT_TYPE ) { if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED) return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, d1, d2, status)); I2ASSIGN_MACRO(((DB_TEXT_STRING *)d1)->db_t_count, i2_t1); I2ASSIGN_MACRO(((DB_TEXT_STRING *)d2)->db_t_count, i2_t2); tc1 = (u_char *)d1 + DB_CNTSIZE; tc2 = (u_char *)d2 + DB_CNTSIZE; endtc1 = tc1 + i2_t1; endtc2 = tc2 + i2_t2; if (adf_scb->adf_collation) return(adugcmp((ADULTABLE *)adf_scb->adf_collation, 0, tc1, endtc1, tc2, endtc2)); cur_cmp = ADT_EQ; while (cur_cmp == ADT_EQ && tc1 < endtc1 && tc2 < endtc2) { if ( (cur_cmp = CMcmpcase(tc1, tc2)) == ADT_EQ ) { CMnext(tc1); CMnext(tc2); } } /* If equal up to shorter, short strings < long */ return( (cur_cmp) ? cur_cmp : (endtc1 - tc1) - (endtc2 - tc2) ); } if ( atr_bdt == DB_DEC_TYPE ) { /* See if the bit representation is identical. */ if ( MEcmp(d1, d2, atr_len) ) { i4 pr; i4 sc; pr = DB_P_DECODE_MACRO(atr->precision); sc = DB_S_DECODE_MACRO(atr->precision); return(MHpkcmp((PTR)d1, pr, sc, (PTR)d2, pr, sc)); } return(ADT_EQ); } /* Bit-equivalent dates we can handle here */ if (( atr_bdt == DB_DTE_TYPE || atr_bdt == DB_ADTE_TYPE || atr_bdt == DB_TMWO_TYPE || atr_bdt == DB_TMW_TYPE || atr_bdt == DB_TME_TYPE || atr_bdt == DB_TSWO_TYPE || atr_bdt == DB_TSW_TYPE || atr_bdt == DB_TSTMP_TYPE || atr_bdt == DB_INYM_TYPE || atr_bdt == DB_INDS_TYPE ) && MEcmp(d1, d2, (u_i2)atr_len) == 0 ) { return(ADT_EQ); } /* Will have to do it the slow way */ dv1.db_datatype = dv2.db_datatype = (DB_DT_ID)atr_bdt; dv1.db_prec = dv2.db_prec = atr->precision; dv1.db_length = dv2.db_length = atr_len; dv1.db_collID = dv2.db_collID = atr->collID; dv1.db_data = d1; dv2.db_data = d2; *status = adc_compare(adf_scb, &dv1, &dv2, &cur_cmp); return(cur_cmp); }
/*{ ** Name: scs_monitor - Implement the SCS part of the monitor task ** ** Description: ** This routine is called ala the regular thread processing routine. ** It parses its input, decides what to do, and returns the output. ** ** The commmands completely interpreted here are: ** ** set server shut (CS_CLOSE) ** Disallow new connections, shutdown when ** last current session exits. ** ** remove SESSION ** New improved "safe" version, acts the same ** as front-end exiting and dropping GCA connection. ** ** kill SESSION ** Signal CS_KILL_EVENT to a user session actively ** running a query. ** ** NEW: ** set server closed ** Disallow new regular user sessions. ** ** set server open ** Reallow new regular user sessions. Cancel ** any pending 'set server shut' shutdown. ** ** show server listen ** ** crash session SESSIONID ** ** Commands partially handled here and partially in CSmonitor are: ** ** stop server (CS_KILL) ** Kill user sessions, shutdown when they're gone. ** ** stop server conditional (CS_COND_CLOSE) ** Shutdown if no sessions, which never works because ** this session always exists. ** ** crash server (CS_CRASH) ** Take the server down immediately. ** ** All other commands are passed to CSmonitor for handling. ** ** Inputs: ** mode Mode of operation ** CS_INPUT, _OUPUT, ... ** scb Sessions control block to monitor ** *command Text of the command ** powerful Is this user powerful ** output_fcn Function to call to perform the output. ** This routine will be called as ** (*output_fcn)(newline_present, ** length, ** buffer) ** where buffer is the length character ** output string, and newline_present ** indicates whether a newline needs to ** be added to the end of the string. ** ** Outputs: ** next_mode As above. ** Returns: ** OK ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 26-Jul-1993 (daveb) ** created. ** 15-Sep-1993 (daveb) ** ifdef out all but drop connection for now. ** 1-Nov-1993 (daveb) ** Match LRC proposal. Drop becomes remove, remove becomes kill. ** 10-Nov-1993 (daveb) ** Match approved proposal. Kill becomes "crash session SESSIONID" ** 15-dec-93 (robf) ** Add prototype "broadcast" message request. ** 4-mar-94 (robf) ** Add initial security auditing to iimonitor events. ** 12-dec-1996 (canor01) ** Add support for sampler thread. ** 24-Apr-2003 (jenjo02) ** Added "kill" command to abort eligible queries ** while leaving the session intact, SIR 110141. ** 17-Sep-2004 (schka24) ** Manual fix to remove command so that it fires. ** 05-may-2005 (horda03) Bug 114453/INGSRV 3290 ** For server/session changes log the command. ** 22-may-2007 (horda03) Bug 117966 ** Log the command before calling CSmonitor, as ** the CS could be crashing the server. ** 23-Sep-2009 (hanal04) Bug 115316 ** Added "SHOW SERVER CAPABILITIES". */ static STATUS scs_monitor( i4 mode, CS_SCB *scb, i4 *nmode, char *command, i4 powerful, i4 (*output_fcn)(PTR, i4, char *) ) { STATUS ret_stat; char buf[81]; bool completely_done; PTR ptr_scb; SCD_SCB *an_scb; i4 log_cmd = 0; i4 local_error; SCD_SCB *my_scb = (SCD_SCB*)scb; *nmode = CS_EXCHANGE; completely_done = FALSE; ret_stat = OK; switch (mode) { case CS_INITIATE: *nmode = CS_INPUT; break; case CS_TERMINATE: break; case CS_INPUT: CVlower(command); if (STscompare("setservershut", 0, command, 0) == 0) { /* Audit log the attempt here? */ if (!powerful) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Superuser status required to stop servers"); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_FAIL, I_SX274D_SET_SERVER_SHUT ); } else /* disallow regular listens, exit when last conn exits */ { Sc_main_cb->sc_listen_mask = (SC_LSN_TERM_IDLE |SC_LSN_SPECIAL_OK) ; TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Server will stop. %d. sessions remaining", Sc_main_cb->sc_current_conns ); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_SUCCESS, I_SX274D_SET_SERVER_SHUT ); log_cmd = 1; } completely_done = TRUE; } else if (STscompare("setserverclosed", 0, command, 0) == 0) { /* Audit log the attempt here? */ if (!powerful) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Superuser status required to disable connections"); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_FAIL, I_SX2748_SET_SERVER_CLOSED ); } else /* Disallow regular listens */ { if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_SUCCESS, I_SX2748_SET_SERVER_CLOSED ); Sc_main_cb->sc_listen_mask &= (~SC_LSN_REGULAR_OK); TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "User connections now disabled" ); log_cmd = 1; } completely_done = TRUE; } else if (STscompare("setserveropen", 0, command, 0) == 0) { /* Audit log the attempt here? */ if (!powerful) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Superuser status required to enable connections"); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_FAIL, I_SX2749_SET_SERVER_OPEN ); } else /* allow all listens, cancel any impending shutdown */ { Sc_main_cb->sc_listen_mask = (SC_LSN_REGULAR_OK | SC_LSN_SPECIAL_OK); TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "User connections now allowed" ); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_SUCCESS, I_SX2749_SET_SERVER_OPEN ); log_cmd = 1; } completely_done = TRUE; } else if (STncasecmp("broadcast", command, 9) == 0) { /* Audit log the attempt here? */ if (!powerful) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Superuser status required to broadcast messages"); } else { /* ** Broadcast the message to any connected sessions */ scs_scan_scbs(scs_broadcast_mesg, (PTR)(command+10)); } completely_done = TRUE; } else if (STscompare("stopserverconditional", 0, command, 0) == 0 || STscompare("stopserver", 0, command, 0) == 0 || STscompare("crashserver", 0, command, 0) == 0 ) { /* Audit log the attempt here? */ if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, powerful? SXF_A_CONTROL|SXF_A_SUCCESS: SXF_A_CONTROL|SXF_A_FAIL, /* Action */ I_SX274A_STOP_SERVER ); log_cmd = powerful; } else if (STscompare("showservercapabilities", 0, command, 0) == 0) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%v", SC_CAPABILITIES_FLAGS, Sc_main_cb->sc_capabilities ); completely_done = TRUE; } else if (STscompare("showserverlisten", 0, command, 0) == 0) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%s", Sc_main_cb->sc_listen_mask & SC_LSN_REGULAR_OK ? "OPEN" : "CLOSED" ); completely_done = TRUE; } else if (STscompare("showservershutdown", 0, command, 0) == 0) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%s", Sc_main_cb->sc_listen_mask & SC_LSN_TERM_IDLE ? "PENDING" : "OPEN" ); completely_done = TRUE; } # ifdef NOT_SUPPORTED else if (STscompare("showconnections", 0, command, 0) == 0 ) { scs_scan_scbs( scs_show_func, (PTR)&powerful ); completely_done = TRUE; } else if (STscompare("show connection", 15, command, 15) == 0 ) { completely_done = TRUE; STzapblank(command, command); if (CVaxptr(command + 14, &ptr_scb) || !scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) ) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Invalid connection id"); break; } scs_show_func( an_scb, &powerful ); } # endif else if (STscompare("remove", 6, command, 6) == 0) { completely_done = TRUE; STzapblank(command, command); if (CVaxptr(command + 6, &ptr_scb) || scb == NULL || !scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) || an_scb == my_scb ) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Invalid session id"); break; } if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username, sizeof(scb->cs_username))) && !powerful) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Superuser or owner status required to remove session"); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_FAIL, I_SX274B_REMOVE_SESSION ); break; } if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_SUCCESS, I_SX274B_REMOVE_SESSION ); scs_remove_sess( an_scb ); TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Session %p removed", an_scb); log_cmd = 1; } else if (STscompare("crash session", 13, command, 13) == 0) { completely_done = TRUE; STzapblank(command, command); if (CVaxptr(command + 12, &ptr_scb) || scb == NULL || !scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) || an_scb == my_scb ) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Invalid session id"); break; } if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username, sizeof(scb->cs_username))) && !powerful) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Superuser or owner status required to crash session"); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_FAIL, I_SX274C_CRASH_SESSION ); break; } if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_SUCCESS, I_SX274C_CRASH_SESSION ); scs_crash_sess( an_scb ); TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Session %p crashed", an_scb); log_cmd = 1; } else if (STscompare("kill", 4, command, 4) == 0) { completely_done = TRUE; STzapblank(command, command); if (CVaxptr(command + 4, &ptr_scb) || scb == NULL || !scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) || an_scb == my_scb ) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Invalid session id"); } else if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username, sizeof(scb->cs_username))) && !powerful) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Superuser or owner status required to kill query"); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_FAIL, I_SX2755_KILL_QUERY ); } else switch ( an_scb->scb_sscb.sscb_qmode ) { case 0: TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Session %p is not executing a query", an_scb); break; /* Honor only "meaningful" types of queries: */ case PSQ_RETRIEVE: case PSQ_RETINTO: case PSQ_APPEND: case PSQ_REPLACE: case PSQ_DELETE: case PSQ_COPY: case PSQ_MODIFY: case PSQ_EXECQRY: case PSQ_EXCURS: case PSQ_CALLPROC: case PSQ_REPCURS: case PSQ_RETCURS: case PSQ_EXEDBP: case PSQ_REGPROC: case PSQ_DDEXECPROC: case PSQ_CREATE: if ( an_scb->scb_sscb.sscb_force_abort || an_scb->scb_sscb.sscb_interrupt ) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Session %p query already aborting", an_scb); } else { scs_kill_query( an_scb ); if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE ) scs_mon_audit((SCD_SCB*)scb, SXF_A_CONTROL|SXF_A_SUCCESS, I_SX2755_KILL_QUERY ); TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Session %p query killed", an_scb); } break; default: TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "Session %p query cannot be killed", an_scb); break; } } # ifdef NOT_SUPPORTED else if (STscompare("help", 0, command, 0) == 0) { TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "SCS monitor commands:\nset server shut\nset server closed\nset server open\nshow server listen\nshow server shutdown\nremove SESSION\ncrash session SESSION\n\nCS monitor commands:\n"); } # endif else if (! CS_is_mt()) /* OS Thread version will start an OS thread in the CS */ if ((STscompare("start sampling", 14, command, 14) == 0)) { if (!powerful) { TRformat(output_fcn, (i4 *) 1, buf, sizeof(buf)-1, "Superuser status required to start sampling.", 0L); } else { GCA_LS_PARMS local_crb; CL_ERR_DESC errdesc; local_crb.gca_status = 0; local_crb.gca_assoc_id = 0; local_crb.gca_size_advise = 0; local_crb.gca_user_name = "<Sampler Thread>"; local_crb.gca_account_name = 0; local_crb.gca_access_point_identifier = "NONE"; local_crb.gca_application_id = 0; /* set up all the CS control blocks for the sampler */ ret_stat = CSmonitor( mode, scb, nmode, command, powerful, output_fcn ); if ( ret_stat == OK ) ret_stat = CSadd_thread(CS_LIM_PRIORITY-1, (PTR) &local_crb, SCS_SSAMPLER, (CS_SID*)NULL, &errdesc); if (ret_stat) { TRformat(output_fcn, (i4 *) 1, buf, sizeof(buf)-1, "Sampling failed to start."); } } } /* log the command before calling CSmonitor(), as the server could be left in an ** unknown state if the command CRASH SERVER or STOP SERVER are used */ if (log_cmd) { ule_format( I_SC051E_IIMONITOR_CMD, 0, ULE_LOG, NULL, 0, 0, 0, &local_error, 3, STlength(command), command, DB_OWN_MAXNAME, &((SCD_SCB *)scb)->scb_sscb.sscb_ics.ics_rusername, sizeof(DB_TERM_NAME), &((SCD_SCB *)scb)->scb_sscb.sscb_ics.ics_terminal, 0, 0); } if( !completely_done ) ret_stat = CSmonitor( mode, scb, nmode, command, powerful, output_fcn ); break; case CS_OUTPUT: break; } return( ret_stat ); }
/* ** 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; } }