int CheckAuth(const char *KeyList, const char *ActiveUSBKeys, const char *User, const char *TTY, const char *RHost) { char *KeyInfo=NULL; const char *ptr; int result=PAM_IGNORE; ptr=GetTok(KeyList, '|', &KeyInfo); while (ptr) { StripTrailingWhitespace(KeyInfo); StripLeadingWhitespace(KeyInfo); result=CheckAuthItem(KeyInfo, ActiveUSBKeys, User, TTY, RHost); ptr=GetTok(ptr, '|', &KeyInfo); } Destroy(KeyInfo); return(result); }
int CheckAuthItem(const char *KeyList, const char *ActiveUSBKeys, const char *User, const char *TTY, const char *RHost) { char *MatchList=NULL; const char *ptr; int UserMatch=FALSE, KeyMatch=FALSE, TTYMatch=FALSE, HostMatch=FALSE; ptr=GetTok(KeyList, ' ', &MatchList); while (ptr) { if (strncmp(MatchList,"rhost=",6)==0) HostMatch=ItemMatches(RHost, MatchList+6); if (User) { if (strncmp(MatchList,"user="******"users=",6)==0) UserMatch=ItemMatches(User, MatchList+6); } if (TTY) { if (strncmp(MatchList,"tty=",4)==0) TTYMatch=ItemMatches(TTY, MatchList+4); if (strncmp(MatchList,"ttys=",5)==0) TTYMatch=ItemMatches(TTY, MatchList+5); } if (KeyList) { if (strncmp(MatchList,"key=",4)==0) KeyMatch=ItemListMatches(ActiveUSBKeys, MatchList+4); if (strncmp(MatchList,"keys=",5)==0) KeyMatch=ItemListMatches(ActiveUSBKeys, MatchList+5); } ptr=GetTok(ptr, ' ', &MatchList); } Destroy(MatchList); if (UserMatch && (TTYMatch || HostMatch)) { if (! KeyMatch) return(PAM_PERM_DENIED); return(PAM_SUCCESS); } return(PAM_IGNORE); }
void T2E2WhiteSpace(int *buffLen,int *buffMarker,int *fileNum, char *dstFileRoot) { char prevWhiteSpace; tBool foundCr=kFalse; int maxWhite=kMaxWhiteLoopCheck; do { int oldBuffLen=strlen(gBlockBuff); prevWhiteSpace=GetWhiteSpace(gBlockBuff+oldBuffLen); if(prevWhiteSpace=='\t' && *gWordBuff=='(') { // ignore Tab EOL comment. gBlockBuff[oldBuffLen]='\0'; // if after tab. do { int buffPos=strlen(gBlockBuff); GetTok(gBlockBuff+buffPos,')',0); __DEBUG2("Cmt:[%s]",gBlockBuff+buffPos); }while(gTerminator!=')' && !feof(gSrcFile)); } __DEBUG2("Whi:[%s,",gBlockBuff+oldBuffLen); __DEBUG2("%d,",oldBuffLen); __DEBUG2("%d]",*gWordBuff); *buffLen=strlen(gBlockBuff); if(*buffLen>=kMaxLineLen) { // end of block during whitespace. T2E2ConvertBuff(buffLen,buffMarker,fileNum,dstFileRoot); } foundCr=CrCheck(); if(oldBuffLen==0) gBlockBuff[oldBuffLen]='\0'; // white space doesn't contribute at start. else if(gInColon==kFalse && foundCr && maxWhite==kMaxWhiteLoopCheck) { *buffMarker=*buffLen; // mark the current possible cut-off point. *buffLen=*buffLen+1; gCanDelGap=kTrue; __DEBUG1(" $$$ "); } if(*gWordBuff=='\014') __DEBUG1(" PBreak "); }while(--maxWhite>0 && *gWordBuff<=' ' && *gWordBuff!='\014' && !feof(gSrcFile)); if(*gWordBuff=='\014') __DEBUG1(" PBreak2 "); if(maxWhite<=0) { __DEBUG1("Too much whitespace!"); exit(1); } }
int T2E2Ragged(FILE *srcFile,char *dstFileRoot) { int buffLen,fileNum=0; //tBool gInColon=kFalse,foundCr=kFalse; int buffMarker=0; char prevWhiteSpace; gScreenLineLen=16; __DEBUG1(">T2E2Token\n"); do { T2E2WhiteSpace(&buffLen,&buffMarker,&fileNum,dstFileRoot); if(gCanDelGap) { gDelGap=buffLen; gCanDelGap=kFalse; } GetTok(gToken,' ',kForthNameChars); __DEBUG2("Tok:[%s]",gToken); /* if(gTokIndent>0) strncat(gBlockBuff," ",gTokIndent); */ tParseFlags tok=DictMatch(gToken); if(tok!=kTokIdPageBreak) strcat(gBlockBuff,gToken); //__DEBUG2("Blk:[%s]",gBlockBuff); switch(tok) { case kTokIdGeneric: break; case kTokIdColon: if(gInColon==kTrue) printf("Colon in Colon at: %s\n",gBlockBuff); // error location? gInColon=kTrue; break; case kTokIdExit: case kTokIdLocalExit: if(gInColon==kFalse) printf("Double exit at: %s\n",gBlockBuff); gInColon=kFalse; break; case kTokIdDotQuote: T2E2WhiteSpace(&buffLen,&buffMarker,&fileNum,dstFileRoot); GetTok(gBlockBuff+strlen(gBlockBuff),'\"',511); __DEBUG2("Str:[%s\"]",gToken); strcat(gBlockBuff,"\""); break; case kTokIdComment: { int buffPos0=strlen(gBlockBuff); do { int buffPos=strlen(gBlockBuff); GetTok(gBlockBuff+buffPos,')',prevWhiteSpace=='\t'?0:511); }while(*gWordBuff=='\0' && !feof(gSrcFile)); __DEBUG2("Rem:[%s)]",gBlockBuff+buffPos0); FilterCr(gBlockBuff+buffPos0,' '); if(prevWhiteSpace!='\t') strcat(gBlockBuff,")"); } break; /* case kTokIdPageBreak: T2E2ConvertBuff(&buffLen,&buffMarker,&fileNum,dstFileRoot); break; */ } buffLen=strlen(gBlockBuff); if(buffLen>=kMaxLineLen || tok==kTokIdPageBreak) { // end of block. T2E2ConvertBuff(&buffLen,&buffMarker,&fileNum,dstFileRoot); } /* foundCr=CrCheck(); if(foundCr==kFalse) strcat(gBlockBuff," "); // add a space at the end if no CR. else if(gInColon==kFalse && foundCr) buffMarker=buffLen; // mark the current possible cut-off point. */ }while(!feof(gSrcFile)); T2E2ConvertBuff(&buffLen,&buffMarker,&fileNum,dstFileRoot); if(gSrcFile!=NULL) fclose(gSrcFile); if(gDstFile!=NULL) fclose(gDstFile); }
int UDFParser::GetTok() { // Skip any whitespace. while (isspace(last_char_)) { last_char_ = GetNextChar(); } if (isalpha(last_char_)) { // identifier: [a-zA-Z][a-zA-Z0-9]* identifier_str_ = last_char_; while (isalnum((last_char_ = GetNextChar()))) { identifier_str_ += last_char_; } if (identifier_str_ == "BEGIN" || identifier_str_ == "begin") { return tok_begin; } else if (identifier_str_ == "IF" || identifier_str_ == "if") { return tok_if; } else if (identifier_str_ == "THEN" || identifier_str_ == "then") { return tok_then; } else if (identifier_str_ == "ELSE" || identifier_str_ == "else") { return tok_else; } else if (identifier_str_ == "END" || identifier_str_ == "end") { return tok_end; } else if (identifier_str_ == "RETURN" || identifier_str_ == "return") { return tok_return; } return tok_identifier; } /* TODO(PP): Do better error-handling for digits */ if (isdigit(last_char_) || last_char_ == '.') { // Number: [0-9.]+ std::string num_str; do { num_str += last_char_; last_char_ = GetNextChar(); } while (isdigit(last_char_) || last_char_ == '.'); num_val_ = strtod(num_str.c_str(), nullptr); return tok_number; } // Semicolon if (last_char_ == ';') { last_char_ = GetNextChar(); return tok_semicolon; } if (last_char_ == ',') { last_char_ = GetNextChar(); return tok_comma; } // Handles single line comments // (May not enter, since everything is flattened into one line) if (last_char_ == '-') { int nextChar = PeekNext(); if (nextChar == '-') { last_char_ = GetNextChar(); // Comment until end of line. do { last_char_ = GetNextChar(); } while (last_char_ != EOF && last_char_ != '\n' && last_char_ != '\r'); if (last_char_ != EOF) { return GetTok(); } } } // Check for end of file. Don't eat the EOF. if (last_char_ == EOF) { return tok_eof; } // Otherwise, just return the character as its ascii value. int this_char = last_char_; last_char_ = GetNextChar(); return this_char; }
int UDFParser::GetNextToken() { return cur_tok_ = GetTok(); }
bool ImportScript( const char* szFileName ) { char* str; int len; SCRIPT_OP* op; DWORD* cp = &code[0]; BOOL bResult = FALSE; int line = 1; void* file = ReadInTextFile( szFileName ); if( file == NULL ) goto lbl_end; // destroy previous string table micro_alloc_destroy(); ////////////////////////////////////////////////////////////// /************************************************************/ /************************************************************/ /////////////// part 1: compile ///////////////////////////// str = (char*)file; // start off with 2 NULL entries just like the game WRITE_CODE( 0 ); WRITE_CODE( 0 ); while( *str != '\0' ) { // get command len = GetTok( str ); if( len != 0 ) { op = in_command_set( str, len ); if( op == NULL ) { darkomen::detour::trace( "WHMTG: line %d: Unknown command. %s", line, str ); goto lbl_end; } if( op->address != 0 ) // if not label { WRITE_CODE( op->address ); } str += len; // do args int count = 0; while( len = GetTok( str ) ) // loop until end of line { if( count < op->arg_cnt ) { switch( op->arg_type[count] ) { case 1: // int { DWORD dw; if( !my_atoi( str, len, &dw ) ) { darkomen::detour::trace("WHMTG: line %d: bad formatting, expected integer value. Arg# %d.", line, count + 1); goto lbl_end; } WRITE_CODE( dw ); str += len; break; } case 2: // text { if( str[0] != '\"' ) { darkomen::detour::trace("WHMTG: line %d: bad formatting, expected text value." " Text must be enclosed within double quote(\") characters. Arg# %d.", line, count + 1 ); goto lbl_end; } // find ending quote if( str[ len-1 ] != '\"' ) { while( ( str[len] != '\"' ) && ( str[len] != '\r' ) && ( str[len] != '\n' ) && ( str[len] != '\0' ) ) { len++; } if( str[len] == '\"' ) len++; else { darkomen::detour::trace("WHMTG: line %d: bad formatting, expected text value." " Text must be enclosed within double quote(\") characters. Arg# %d.", line, count + 1 ); goto lbl_end; } } char* text = (char*) micro_alloc( len-1 ); if( text == NULL ) { darkomen::detour::trace("WHMTG: Internal Error (script line %d): Failed to allocate %d bytes. Arg# %d.", line, len - 1, count + 1); goto lbl_end; } memcpy( text, &str[1], len-2 ); WRITE_CODE( (uintptr_t)text ); str += len; break; } case 3: // jmp { char* text = (char*) micro_alloc( len+1 ); if( text == NULL ) { darkomen::detour::trace("WHMTG: Internal Error (script line %d): Failed to allocate %d bytes. Arg# %d.", line, len + 1, count + 1); goto lbl_end; } LABEL_ENTRY* le = (LABEL_ENTRY*) micro_alloc( sizeof(LABEL_ENTRY) ); if( le == NULL ) { darkomen::detour::trace("WHMTG: Internal Error (script line %d): Failed to allocate %d bytes. Arg# %d.", line, sizeof(LABEL_ENTRY), count + 1); goto lbl_end; } memcpy( text, str, len ); le->name_len = len; le->name = text; le->addr = cp; le->next = jmps; jmps = le; WRITE_CODE( (uintptr_t)le->name ); // place-holder str += len; break; } case 4: // var { DWORD dw; if( ( len < 4 ) || ( str[0] != 'v' ) || ( str[1] != 'a' ) || ( str[2] != 'r' ) || ( str[3] != '_' ) ) { darkomen::detour::trace("WHMTG: line %d: bad formatting, expected var_ keyword. Arg# %d.", line, count + 1); goto lbl_end; } if( !my_atoi( &str[4], len - 4, &dw ) ) { darkomen::detour::trace("WHMTG: line %d: bad formatting, unrecognized var. Arg# %d.", line, count + 1); goto lbl_end; } if( dw > 23 ) { darkomen::detour::trace("WHMTG: line %d: var index is outside of range. Arg# %d.", line, count + 1); goto lbl_end; } WRITE_CODE( ( var_base + dw * 4 ) ); str += len; break; } case 5: // cmp { DWORD dw = -1; if( len == 2 ) { if( str[1] == '=' ) { switch( *str ) { case '=': dw = 1; break; case '/': // fall-thru case '!': dw = 2; break; } } else { if( ( str[0] == '<' ) && ( str[1] == '>' ) ) { dw = 2; } } } if( len == 1 ) { switch( *str ) { case '=': dw = 1; break; case '<': dw = 3; break; case '>': dw = 4; break; } } if( dw == -1 ) { darkomen::detour::trace("WHMTG: line %d: bad formatting, unrecognized relationship/comparision operator. Arg# %d.", line, count); goto lbl_end; } WRITE_CODE( dw ); str += len; break; } case 6: // var_arg ( WHMTG_Speak ) { DWORD num_arg_groups = 0; DWORD i = 0; for(;;) { DWORD dw; if( !my_atoi( str, len, &dw ) ) { darkomen::detour::trace("WHMTG: line %d: bad formatting, expected integer value. Arg# %d.", line, i); goto lbl_end; } if( i == 0 ) num_arg_groups = dw; WRITE_CODE( dw ); str += len; i++; if( i >= ( 2 + num_arg_groups * 4 ) ) break; // exit loop // else get next arg len = GetTok( str ); if( len == 0 ) { darkomen::detour::trace("WHMTG: line %d: %s, expected %d arguments, found %d.", line, op->name, 2 + (num_arg_groups * 4), i); goto lbl_end; } } break; } case 7: // label { char* text = (char*) micro_alloc( len+1 ); if( text == NULL ) { darkomen::detour::trace("WHMTG: Internal Error (script line %d): Failed to allocate %d bytes. Arg# %d.", line, len + 1, count); goto lbl_end; } LABEL_ENTRY* le = (LABEL_ENTRY*) micro_alloc( sizeof(LABEL_ENTRY) ); if( le == NULL ) { darkomen::detour::trace("WHMTG: Internal Error (script line %d): Failed to allocate %d bytes. Arg# %d.", line, sizeof(LABEL_ENTRY), count); goto lbl_end; } memcpy( text, str, len ); // jmp targets are aligned to 8 if( (DWORD)cp & 4 ) WRITE_CODE( 0 ); // pad as per the game le->name_len = len; le->name = text; le->addr = cp; le->next = targets; targets = le; str += len; break; } default: { darkomen::detour::trace("WHMTG: Internal Error (script line %d): unknown arg type. Arg# %d.", line, count); goto lbl_end; } } } count++; } if( count != op->arg_cnt ) { darkomen::detour::trace("WHMTG: line %d: %s, expected %d arguments, found %d.", line, op->name, op->arg_cnt, count); goto lbl_end; } } // next line if( *str == '\r' ) str++; if( *str == '\n' ) str++; line++; } if( cp >= &code[_countof(code) - 1] ) { darkomen::detour::trace("WHMTG: Error: Byte-code exceeds maximum size of %d bytes.", sizeof(code)); goto lbl_end; } // end with a NULL entry because that is what the game does WRITE_CODE( 0 ); EP_EndScript = cp - 1; EP_StartScript = &code[0]; ////////////////////////////////////////////////////////////// /************************************************************/ /************************************************************/ /////////////// part 2: link //////////////////////////////// // find the entry points EP_NewGame = NULL; EP_Tutorial = NULL; EP_TheLivingGem = NULL; EP_HandyMan = NULL; EP_RideTheSrorm = NULL; EP_YouAndI = NULL; for( LABEL_ENTRY* t = targets; t != NULL; t = t->next ) { switch( t->name_len ) { case 7: if( !memcmp( t->name, "NEWGAME", 7 ) ) EP_NewGame = t->addr; else if( !memcmp( t->name, "YOUANDI", 7 ) ) EP_YouAndI = t->addr; break; case 8: if( !memcmp( t->name, "TUTORIAL", 8 ) ) EP_Tutorial = t->addr; else if( !memcmp( t->name, "HANDYMAN", 8 ) ) EP_HandyMan = t->addr; break; case 12: if( !memcmp( t->name, "THELIVINGGEM", 12 ) ) EP_TheLivingGem = t->addr; else if( !memcmp( t->name, "RIDETHESTORM", 12 ) ) EP_RideTheSrorm = t->addr; break; } } if( EP_NewGame == NULL ) EP_NewGame = EP_StartScript; if( EP_Tutorial == NULL ) EP_Tutorial = EP_NewGame; if( EP_TheLivingGem == NULL ) EP_TheLivingGem = EP_NewGame; if( EP_HandyMan == NULL ) EP_HandyMan = EP_NewGame; if( EP_RideTheSrorm == NULL ) EP_RideTheSrorm = EP_NewGame; if( EP_YouAndI == NULL ) EP_YouAndI = EP_NewGame; // link jmps with targets for( LABEL_ENTRY* j = jmps; j != NULL; j = j->next ) { LABEL_ENTRY* t; for( t = targets; t != NULL; t = t->next ) { if( j->name_len == t->name_len ) { if( !memcmp( j->name, t->name, t->name_len ) ) { //OutputDebugString("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); *j->addr = (DWORD)t->addr; break; } } } if( t == NULL ) { darkomen::detour::trace("WHMTG: Error: LABEL %s not found.", j->name); goto lbl_end; } } ////////////////////////////////////////////////////////////// /************************************************************/ /************************************************************/ /////////////// part 3: hook-in ///////////////////////////// DWORD dwPrevProtect; // .text section if( VirtualProtect( (void*)0x0040E000, 0x1F000, PAGE_READWRITE, &dwPrevProtect ) ) { *( (DWORD**)0x0040EFB4 ) = EP_StartScript; *( (DWORD**)0x0040EFCC ) = EP_EndScript; *( (DWORD**)0x0040EFAA ) = EP_StartScript; *( (DWORD**)0x00420F56 ) = EP_StartScript; *( (DWORD**)0x00420F8E ) = EP_EndScript; *( (DWORD**)0x00421B83 ) = EP_StartScript; *( (DWORD**)0x00421BC6 ) = EP_EndScript; *( (DWORD**)0x0042943F ) = EP_Tutorial; *( (DWORD**)0x0042C4F7 ) = EP_NewGame; VirtualProtect( (void*)0x0040E000, 0x1F000, dwPrevProtect, &dwPrevProtect ); } // .data section *( (DWORD**)0x004D7134 ) = EP_TheLivingGem; *( (DWORD**)0x004D715C ) = EP_HandyMan; *( (DWORD**)0x004D7184 ) = EP_RideTheSrorm; *( (DWORD**)0x004D71AC ) = EP_YouAndI; bResult = TRUE; /* HANDLE hFile = CreateFile("dump.bin", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); DWORD Written; WriteFile(hFile, code, sizeof( code ), &Written, NULL); CloseHandle(hFile); */ lbl_end: if( file != NULL ) VirtualFree( file, 0, MEM_RELEASE ); return !!bResult; }