void fromBase64(const string& input, vector<uint8_t>& output) { // openssl doesn't like whitespace, so remove it. string cleanInput(input); cleanInput.erase (remove_if(cleanInput.begin(), cleanInput.end(), ::isspace), cleanInput.end()); BIO *base64 = BIO_new(BIO_f_base64()); if (!base64) throw runtime_error("fromBase64: BIO_new failed"); BIO_set_flags(base64, BIO_FLAGS_BASE64_NO_NL); BIO *inputBuffer = BIO_new_mem_buf((char*)&cleanInput[0], cleanInput.size()); if (!inputBuffer) { BIO_free(base64); throw runtime_error("fromBase64: BIO_new_mem_buf failed"); } inputBuffer = BIO_push(base64, inputBuffer); // The output will be shorter than the input. output.resize(cleanInput.size()); int outputLength = BIO_read(inputBuffer, &output[0], cleanInput.size()); if (outputLength < 0) { BIO_free_all(inputBuffer); throw runtime_error("fromBase64: BIO_read failed to decode"); } output.resize(outputLength); BIO_free_all(inputBuffer); }
int AgiEngine::agiDeinit() { int ec; cleanInput(); // remove all words from memory agiUnloadResources(); // unload resources in memory _loader->unloadResource(rLOGIC, 0); ec = _loader->deinit(); unloadObjects(); unloadWords(); clearImageStack(); return ec; }
/* * int main: Starts and runs the Air Force Shell. * Author: C1C Ian Goodbody * Date: 2 Feb 2015 * * Documentation: * - I pulled heavily from "The C programming Language" for library references, language constructs, and order * of operations. It's infuence was used throughout the project * - The Online documentation for the "unistd.h" library was used as a reference for the "chdir", "getcwd", "fork", * and "execvp" commands. * - I referenced the Ubuntu community help forum to research environment variables */ int main(void){ // Allocate memory for function buffers and objects char* inputStr = (char*) malloc(STR_MAX); char* cleanInputStr = (char*) malloc(STR_MAX); char* cwdStr = (char*) malloc(STR_MAX); char** argList = (char**) malloc(ARG_ARRAY_MAX); node* historyList = NULL; printf("\nWelcome to the Air Force Shell (afsh)\n\n"); while(1) { // Get input from user printf("Prompt> "); fgets(inputStr, STR_MAX, stdin); parseInput(inputStr, argList, ARG_ARRAY_MAX); // Check for no command entered, skip the rest of the loop and do not process anything. if(!*argList) continue; // If the commands are not "history", "exit", or "recall" add the command to the history list if(strcmp(*argList, "history") && strcmp(*argList, "recall") && strcmp(*argList, "exit")) { cleanInput(cleanInputStr, argList); historyList = list_remove(historyList, cleanInputStr); historyList = list_insert_head(historyList, cleanInputStr); } // Execute the argument in the list, check for exit condition if(execArgs(argList, historyList, cwdStr)) { // if execArgs returns 1 for exit clear allocated memory and exit the program free(inputStr); free(cleanInputStr); free(argList); free(cwdStr); list_destroy(historyList); exit(0); } } }
/* -------------------------------------------------- Function to get user input. It calls cleanInput right away to be sure there isn't junk in the input buffer. It grabs the initial character and checks it for certain special cases. If it isn't one of those, it grabs the rest of the line. Then it calls parseLine() to move the string into an array of commands. -------------------------------------------------- */ int getInput(){ cleanInput(); INPUTCHAR = getchar(); //Check for EOF if(INPUTCHAR == -1){ CONT = 0; return 1; } //Check for newline character (if user hits enter), or # (comment) if((INPUTCHAR == '\n') || (INPUTCHAR == '#')){ INPUTCHAR = '\0'; printPrompt(); return 1; } while((INPUTCHAR != '\n') && (NUMINPUTCHARS < 1024)){ BUFFER[NUMINPUTCHARS++] = INPUTCHAR; INPUTCHAR = getchar(); } BUFFER[NUMINPUTCHARS] = '\0'; //printf("%s\n",BUFFER); //debugging code parseLine(); return 0; }
bool Msg7::inject ( char *url , long forcedIp , char *content , long contentLen , bool recycleContent, uint8_t contentType, char *coll , bool quickReply , char *username , char *pwd , long niceness, void *state , void (*callback)(void *state), long firstIndexed, long lastSpidered, long hopCount, char newOnly, short charset, char spiderLinks, char deleteIt, char hasMime, bool doConsistencyTesting ) { m_quickReply = quickReply; // store coll if ( ! coll ) { g_errno = ENOCOLLREC; return true; } long collLen = gbstrlen ( coll ); if ( collLen > MAX_COLL_LEN ) collLen = MAX_COLL_LEN; strncpy ( m_coll , coll , collLen ); m_coll [ collLen ] = '\0'; // store user //long ulen = 0; //if ( username ) ulen = gbstrlen(username); //if ( ulen >= MAX_USER_SIZE-1 ) {g_errno = EBUFOVERFLOW; return true;} //if ( username ) strcpy( m_username, username ); // store password //long pwdLen = 0; //if ( pwd ) pwdLen = gbstrlen(pwd); //m_pwd [ 0 ] ='\0'; //if ( pwdLen > 31 ) pwdLen = 31; //if ( pwdLen > 0 ) strncpy ( m_pwd , pwd , pwdLen ); //m_pwd [ pwdLen ] = '\0'; // store url if ( ! url ) { g_errno = 0; return true; } long urlLen = gbstrlen(url); if ( urlLen > MAX_URL_LEN ) {g_errno = EBADENGINEER; return true; } // skip injecting if no url given! just print the admin page. if ( urlLen <= 0 ) return true; //strcpy ( m_url , url ); if ( g_repairMode ) { g_errno = EREPAIRING; return true; } // send template reply if no content supplied if ( ! content && ! recycleContent ) { log("inject: no content supplied to inject command and " "recycleContent is false."); //return true; } // clean url? // normalize and add www. if it needs it Url uu; uu.set ( url , gbstrlen(url) , true ); // remove >'s i guess and store in st1->m_url[] buffer char cleanUrl[MAX_URL_LEN+1]; urlLen = cleanInput ( cleanUrl, MAX_URL_LEN, uu.getUrl(), uu.getUrlLen() ); // this can go on the stack since set4() copies it SpiderRequest sreq; sreq.reset(); strcpy(sreq.m_url, cleanUrl ); // parentdocid of 0 long firstIp = hash32n(cleanUrl); if ( firstIp == -1 || firstIp == 0 ) firstIp = 1; sreq.setKey( firstIp,0LL, false ); sreq.m_isInjecting = 1; sreq.m_isPageInject = 1; sreq.m_hopCount = hopCount; sreq.m_hopCountValid = 1; sreq.m_fakeFirstIp = 1; sreq.m_firstIp = firstIp; // shortcut XmlDoc *xd = &m_xd; // log it now //log("inject: injecting doc %s",cleanUrl); static char s_dummy[3]; // sometims the content is indeed NULL... if ( newOnly && ! content ) { // don't let it be NULL because then xmldoc will // try to download the page! s_dummy[0] = '\0'; content = s_dummy; //char *xx=NULL;*xx=0; } } // . use the enormous power of our new XmlDoc class // . this returns false with g_errno set on error if ( //m_needsSet && ! xd->set4 ( &sreq , NULL , m_coll , NULL , // pbuf // give it a niceness of 1, we have to be // careful since we are a niceness of 0!!!! niceness, // 1 , // inject this content content , deleteIt, // false, // deleteFromIndex , forcedIp , contentType , lastSpidered , hasMime )) { // g_errno should be set if that returned false if ( ! g_errno ) { char *xx=NULL;*xx=0; } return true; } // do not re-call the set //m_needsSet = false; // make this our callback in case something blocks xd->setCallback ( state , callback ); xd->m_doConsistencyTesting = doConsistencyTesting; // . set xd from the old title rec if recycle is true // . can also use XmlDoc::m_loadFromOldTitleRec flag if ( recycleContent ) xd->m_recycleContent = true; // othercrap if ( firstIndexed ) { xd->m_firstIndexedDate = firstIndexed; xd->m_firstIndexedDateValid = true; } if ( lastSpidered ) { xd->m_spideredTime = lastSpidered; xd->m_spideredTimeValid = true; } if ( hopCount != -1 ) { xd->m_hopCount = hopCount; xd->m_hopCountValid = true; } if ( charset != -1 && charset != csUnknown ) { xd->m_charset = charset; xd->m_charsetValid = true; } // avoid looking up ip of each outlink to add "firstip" tag to tagdb // because that can be slow!!!!!!! xd->m_spiderLinks = spiderLinks; xd->m_spiderLinks2 = spiderLinks; xd->m_spiderLinksValid = true; // . newOnly is true --> do not inject if document is already indexed! // . maybe just set indexCode xd->m_newOnly = newOnly; // do not re-lookup the robots.txt xd->m_isAllowed = true; xd->m_isAllowedValid = true; xd->m_crawlDelay = -1; // unknown xd->m_crawlDelayValid = true; // set this now g_inPageInject = true; // log it now //log("inject: indexing injected doc %s",cleanUrl); // . now tell it to index // . this returns false if blocked bool status = xd->indexDoc ( ); // log it. i guess only for errors when it does not block? // because xmldoc.cpp::indexDoc calls logIt() if ( status ) xd->logIt(); // undo it g_inPageInject = false; // note that it blocked //if ( ! status ) log("inject: blocked for %s",cleanUrl); // return false if it blocked return status; }
// -----------------Initial call to program ----------------- int main(int argc, char *argv[]) { // ---------deprecated for #3 ---------- // if a file name for input is passed // use that name instead of the default in // FNS[0] = input.txt // ---------deprecated for #3 ---------- int i = 0; // -------must redo this section to take -l -a -v user input from console // ---------deprecated for #3 ---------- if(argc > 1) { FNS[input_txt] = argv[1]; } // initialize global ctype int arrays gInitGlobalintIsCharArrays(); // create file pointers for input output // createFilePointers handles null pointer exception createFilePointers(); // copy input file pointer FILE *ifp = m_FPS[input_txt]; // copy clean input file pointer FILE *cifp = m_FPS[cleaninput_txt]; // how many characters in file int count = charCount(ifp); if (count < 0) { printError(err27, FNS[input_txt]); //fileReadError(FNS[input_txt], input_txt); // this is fatal error exit(EXIT_FAILURE); } char code[count]; // cleanCode will have input without comments char cleanCode[count]; // initialize code arrays for (i = 0; i < count; i++) { code[i] = ' '; cleanCode[i] = ' '; } // read input file into array code[] readInput(ifp, code); // close the input file fclose(ifp); // remove comments from input //cleanCode[] will contain -comments free- input cleanInput(cifp, code, count, cleanCode); // close the -clean input- file fclose(cifp); // there will be at most m_nCleanCount separate string tokens char *caCleanInputTokens[m_nCleanCount]; // separate cleanCode into tokens, allocate space as needed with calloc // need to free each caCleanInputTokens[] array index that calloc was done to // if caCleanInputTokens[] is not null, free it before exiting program // or after printing it to file splitInputTokens(cleanCode, caCleanInputTokens); // there will be at most m_nCleanCount separate namerecord_t tokens namerecord_t namerecord_table[m_nCleanCount]; initializeNamerecord_table(namerecord_table); // identify what kind of lexeme each token is IdentifyInputToken(caCleanInputTokens, namerecord_table); // print each record to both lexemelist.txt and lexemetable.txt printNamerecord_table(namerecord_table); // call freeInputTokenCalloc after finishing the use of the array freeInputTokenCalloc(caCleanInputTokens); // program finished, if no error were found, it will reach this point // ---------------------- deprecated for #3 ---------------------- /* / deprecated for #3 printf("\nYou can find the input/ output files: \n"); for (i = 0; i < MAX_FILES; i++) { // print the file names that were used and created printf("%s \n", FNS[i]); } printf("in the same folder where scanner.c is located \n\n"); */ // deprecated for #3 // ---------------------- deprecated for #3 ---------------------- // program finished, if no error were found, it will reach this point return 0; }
void AgiEngine::dictionaryWords(char *msg) { char *p = NULL; char *q = NULL; int wid, wlen; assert(msg); debugC(2, kDebugLevelScripts, "msg = \"%s\"", msg); cleanInput(); for (p = msg; *p && getvar(vWordNotFound) == 0;) { if (*p == 0x20) p++; if (*p == 0) break; wid = findWord(p, &wlen); debugC(2, kDebugLevelScripts, "find_word(p) == %d", wid); switch (wid) { case -1: debugC(2, kDebugLevelScripts, "unknown word"); _game.egoWords[_game.numEgoWords].word = strdup(p); q = _game.egoWords[_game.numEgoWords].word; _game.egoWords[_game.numEgoWords].id = 19999; setvar(vWordNotFound, 1 + _game.numEgoWords); _game.numEgoWords++; p += strlen(p); break; case 0: // ignore this word debugC(2, kDebugLevelScripts, "ignore word"); p += wlen; q = NULL; break; default: // an OK word debugC(3, kDebugLevelScripts, "ok word (%d)", wid); _game.egoWords[_game.numEgoWords].id = wid; _game.egoWords[_game.numEgoWords].word = myStrndup(p, wlen); _game.numEgoWords++; p += wlen; break; } if (*p) { debugC(2, kDebugLevelScripts, "p = %s", p); *p = 0; p++; } if (q != NULL) { for (; (*q != 0 && *q != 0x20); q++) ; if (*q) { *q = 0; q++; } } } debugC(4, kDebugLevelScripts, "num_ego_words = %d", _game.numEgoWords); if (_game.numEgoWords > 0) { setflag(fEnteredCli, true); setflag(fSaidAcceptedInput, false); } }
void execute_cmd(void) { currcmd = currcmd % MAXCMDS; int curr = currcmd; FILE *f; if(comtab[curr].external == 0) { // Built-in Command aliasroot = NULL; aliasDepth = 0; switch(comtab[curr].code) { case CHD : { if( chdir(getHOME) ) { printf("ERROR at line %d\n", __LINE__); break; } setenv("PWD", getHOME, 1); break; } case CDX : { char* dest = cleanInput(comtab[curr].atptr[0]); if( chdir(dest) == -1 ) { printf("ERROR: \n%s is not a directory\n", dest); } char pwd[5000]; getcwd( pwd, sizeof(pwd) ); setenv("PWD", pwd, 1); break; } case SETENV : { char* name = cleanInput(comtab[curr].atptr[0]); char* word = cleanInput(comtab[curr].atptr[1]); if( setenv( name, word, 1 ) == -1 ) { printf("setenv failed, could not set %s to %s\n", name, word ); } break; } case UNSETENV : { char* name = cleanInput(comtab[curr].atptr[0]); if( getenv(name) ){ unsetenv(name); } else { printf("unsetenv failed, could not find %s\n", name); } break; } case PRINTENV : { if(ofileredir) { if(comtab[curr].append) { f = fopen(comtab[curr].outfd, "a"); } else { f = fopen(comtab[curr].outfd, "w"); } if(f == NULL) return SYSERR; } else print_env(); if(ofileredir) fclose(f); break; } case SETALIAS : { char* name = cleanInput(comtab[curr].atptr[0]); char* word = cleanInput(comtab[curr].atptr[1]); setalias(name, word); break; } case UNALIAS : { char* name = cleanInput(comtab[curr].atptr[0]); removealias(name); break; } case PRINTALIAS : { if(ofileredir) { if(comtab[curr].append) { f = fopen(comtab[curr].outfd, "a"); } else { f = fopen(comtab[curr].outfd, "w"); } } else printalias(); if(ofileredir) fclose(f); break; } case PWD : { printf("%s\n", getPWD); break; } } } else { // Handle aliasing int acurr = isalias(comtab[curr].comname); if(acurr != -1) { comtab[curr].external = 0; if(aliasroot == NULL) { aliasroot = aliastab[acurr].alname; } // Check for infinite aliasing if( aliasDepth > 30 ) { printf("ERR: Infinite aliasing detected. Exiting...\n"); return; } else { ignoreEOF = 1; parse_string(aliastab[acurr].alstring); aliasDepth++; execute_cmd(); } } else { // External Command aliasroot = NULL; aliasDepth = 0; pid_t child = fork(); int stat; int success = -1; while(waitpid(child, &stat, 0) == -1) { if(errno != EINTR) { stat = -1; break; } } if(child < 0) exit(1); else if(child == 0) { // Prepare for execv call char tmp[256]; char *paths = strcpy(tmp, getenv("PATH")); char *tok = strtok(paths, ":"); char *cmp = "./"; while(tok) { char place[255]; if(comtab[curr].comname[0] == cmp[0] || comtab[curr].comname[0] == cmp[1]) { // If destination is specified strcpy(place, comtab[curr].comname); } else { // If destination is not specified strcpy(place, tok); strcat(place, "/"); // Append command name strcat(place, comtab[curr].comname); } char *cmds[comtab[curr].nargs + 2]; cmds[0] = place; cmds[comtab[curr].nargs + 1] = (char *)NULL; int i = 0; for(i; i<comtab[curr].nargs; i++) { cmds[i+1] = comtab[curr].atptr[i]; } if(execv(place, cmds) == -1) { tok = strtok(NULL, ":"); continue; } else { _exit(0); success = 1; break; } } if(success == -1) { printf("ERR: Command not found: %s\n", comtab[curr].comname); _exit(1); } } } } currcmd += 1; comtab[currcmd].external = 0; ignoreEOF = 0; }
// . returns false if blocked, true otherwise // . sets g_errno on error bool sendPageAddUrl ( TcpSocket *s , HttpRequest *r ) { // . get fields from cgi field of the requested url // . get the search query long urlLen = 0; char *url = r->getString ( "u" , &urlLen , NULL /*default*/); // see if they provided a url of a file of urls if they did not // provide a url to add directly //bool isAdmin = g_collectiondb.isAdmin ( r , s ); bool isAdmin = r->getIsLocal(); long ufuLen = 0; char *ufu = NULL; if ( isAdmin ) // get the url of a file of urls (ufu) ufu = r->getString ( "ufu" , &ufuLen , NULL ); // can't be too long, that's obnoxious if ( urlLen > MAX_URL_LEN || ufuLen > MAX_URL_LEN ) { g_errno = EBUFTOOSMALL; g_msg = " (error: url too long)"; return g_httpServer.sendErrorReply(s,500,"url too long"); } // get the collection long collLen = 0; char *coll = r->getString("c",&collLen); if ( ! coll || ! coll[0] ) { //coll = g_conf.m_defaultColl; coll = g_conf.getDefaultColl( r->getHost(), r->getHostLen() ); collLen = gbstrlen(coll); } // get collection rec CollectionRec *cr = g_collectiondb.getRec ( coll ); // bitch if no collection rec found if ( ! cr ) { g_errno = ENOCOLLREC; g_msg = " (error: no collection)"; return g_httpServer.sendErrorReply(s,500,"no coll rec"); } // . make sure the ip is not banned // . we may also have an exclusive list of IPs for private collections if ( ! cr->hasSearchPermission ( s ) ) { g_errno = ENOPERM; g_msg = " (error: permission denied)"; return g_httpServer.sendErrorReply(s,500,mstrerror(g_errno)); } // make a new state State1 *st1 ; try { st1 = new (State1); } catch ( ... ) { g_errno = ENOMEM; log("PageAddUrl: new(%i): %s", sizeof(State1),mstrerror(g_errno)); return g_httpServer.sendErrorReply(s,500,mstrerror(g_errno)); } mnew ( st1 , sizeof(State1) , "PageAddUrl" ); // save socket and isAdmin st1->m_socket = s; st1->m_isAdmin = isAdmin; // assume no url buf yet, set below //st1->m_ubuf = NULL; //st1->m_ubufAlloc = NULL; //st1->m_metaList = NULL; // save the url st1->m_url[0] = '\0'; if ( url ) { // normalize and add www. if it needs it Url uu; uu.set ( url , gbstrlen(url) , true ); // remove >'s i guess and store in st1->m_url[] buffer st1->m_urlLen=cleanInput ( st1->m_url, MAX_URL_LEN, uu.getUrl(), uu.getUrlLen() ); // point to that as the url "buf" to add //st1->m_ubuf = st1->m_url; //st1->m_ubufSize = urlLen; //st1->m_ubufAlloc = NULL; // do not free it! } // save the "ufu" (url of file of urls) st1->m_ufu[0] = '\0'; st1->m_ufuLen = ufuLen; memcpy ( st1->m_ufu , ufu , ufuLen ); st1->m_ufu[ufuLen] = '\0'; st1->m_doTuringTest = cr->m_doTuringTest; char *username = g_users.getUsername(r); if(username) strcpy(st1->m_username,username); //st1->m_user = g_pages.getUserType ( s , r ); st1->m_spiderLinks = true; st1->m_strip = true; //st1->m_raw = r->getLong("raw",0); // init state2 for ( long i = 0; i < 5; i++ ){ st1->m_state2[i].m_buf = NULL; st1->m_state2[i].m_bufLen = 0; st1->m_state2[i].m_bufMaxLen = 0; } // save the collection name in the State1 class if ( collLen > MAX_COLL_LEN ) collLen = MAX_COLL_LEN; strncpy ( st1->m_coll , coll , collLen ); st1->m_coll [ collLen ] = '\0'; // assume they answered turing test correctly st1->m_goodAnswer = true; // if addurl is turned off, just print "disabled" msg if ( ! g_conf.m_addUrlEnabled ) return sendReply ( st1 , false ); // can also be turned off in the collection rec if ( ! cr->m_addUrlEnabled ) return sendReply ( st1 , false ); // or if in read-only mode if ( g_conf.m_readOnlyMode ) return sendReply ( st1 , false ); // cannot add if another Msg10 from here is still in progress if ( s_inprogress ) return sendReply ( st1 , true ); // use now as the spiderTime // get ip of submitter //unsigned long h = ipdom ( s->m_ip ); // . use top 2 bytes now, some isps have large blocks // . if this causes problems, then they can do pay for inclusion unsigned long h = iptop ( s->m_ip ); long codeLen; char* code = r->getString("code", &codeLen); if(g_autoBan.hasCode(code, codeLen, s->m_ip)) { long uipLen = 0; char* uip = r->getString("uip",&uipLen); long hip = 0; //use the uip when we have a raw query to test if //we can submit if(uip) { hip = atoip(uip, uipLen); h = iptop( hip ); } } st1->m_strip = r->getLong("strip",0); // Remember, for cgi, if the box is not checked, then it is not // reported in the request, so set default return value to 0 long spiderLinks = r->getLong("spiderLinks",-1); // also support all lowercase like PageInject.cpp uses if ( spiderLinks == -1 ) spiderLinks = r->getLong("spiderlinks",0); // . should we force it into spiderdb even if already in there // . use to manually update spider times for a url // . however, will not remove old scheduled spider times // . mdw: made force on the default st1->m_forceRespider = r->getLong("force",1); // 0); long now = getTimeGlobal(); // . allow 1 submit every 1 hour // . restrict by submitter domain ip if ( ! st1->m_isAdmin && ! canSubmit ( h , now , cr->m_maxAddUrlsPerIpDomPerDay ) ) { // return error page g_errno = ETOOEARLY; return sendReply ( st1 , true ); } //st1->m_query = r->getString( "qts", &st1->m_queryLen ); // check it, if turing test is enabled for this collection if ( ! st1->m_isAdmin && cr->m_doTuringTest && ! g_turingTest.isHuman(r) ) { // log note so we know it didn't make it g_msg = " (error: bad answer)"; //log("PageAddUrl:: addurl failed for %s : bad answer", // iptoa(s->m_ip)); st1->m_goodAnswer = false; return sendReply ( st1 , true /*addUrl enabled?*/ ); } //if ( st1->m_queryLen > 0 ) // return getPages( st1 ); // if no url given, just print a blank page if ( ! url ) return sendReply ( st1 , true ); // // make a SpiderRequest // SpiderRequest *sreq = &st1->m_sreq; // reset it sreq->reset(); // make the probable docid long long probDocId = g_titledb.getProbableDocId ( st1->m_url ); // make one up, like we do in PageReindex.cpp long firstIp = (probDocId & 0xffffffff); // . now fill it up // . TODO: calculate the other values... lazy!!! (m_isRSSExt, // m_siteNumInlinks,...) sreq->m_isNewOutlink = 1; sreq->m_isAddUrl = 1; sreq->m_addedTime = now; sreq->m_fakeFirstIp = 1; sreq->m_probDocId = probDocId; sreq->m_firstIp = firstIp; sreq->m_hopCount = 0; // its valid if root Url uu; uu.set ( st1->m_url ); if ( uu.isRoot() ) sreq->m_hopCountValid = true; // too big? //long len = st1->m_urlLen; // the url! includes \0 strcpy ( sreq->m_url , st1->m_url ); // call this to set sreq->m_dataSize now sreq->setDataSize(); // make the key dude -- after setting url sreq->setKey ( firstIp , 0LL, false ); // need a fake first ip lest we core! //sreq->m_firstIp = (pdocId & 0xffffffff); // how to set m_firstIp? i guess addurl can be throttled independently // of the other urls??? use the hash of the domain for it! long dlen; char *dom = getDomFast ( st1->m_url , &dlen ); // fake it for this... //sreq->m_firstIp = hash32 ( dom , dlen ); // sanity if ( ! dom ) { g_errno = EBADURL; return sendReply ( st1 , true ); } // shortcut Msg4 *m = &st1->m_msg4; // now add that to spiderdb using msg4 if ( ! m->addMetaList ( (char *)sreq , sreq->getRecSize() , coll , st1 , // state addedStuff , MAX_NICENESS , RDB_SPIDERDB ) ) // we blocked return false; // send back the reply return sendReply ( st1 , true ); }
int AgiEngine::loadGame(const Common::String &fileName, bool checkId) { char description[31], saveVersion, loadId[8]; int i, vtEntries = MAX_VIEWTABLE; uint8 t; int16 parm[7]; Common::InSaveFile *in; debugC(3, kDebugLevelMain | kDebugLevelSavegame, "AgiEngine::loadGame(%s)", fileName.c_str()); if (!(in = _saveFileMan->openForLoading(fileName))) { warning("Can't open file '%s', game not loaded", fileName.c_str()); return errBadFileOpen; } else { debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for reading", fileName.c_str()); } uint32 typea = in->readUint32BE(); if (typea == AGIflag) { debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Has AGI flag, good start"); } else { warning("This doesn't appear to be an AGI savegame, game not restored"); delete in; return errOK; } in->read(description, 31); debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Description is: %s", description); saveVersion = in->readByte(); if (saveVersion < 2) // is the save game pre-ScummVM? warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, SAVEGAME_VERSION); if (saveVersion < 3) warning("This save game contains no AGIPAL data, if the game is using the AGIPAL hack, it won't work correctly"); if (saveVersion >= 4) { // We don't need the thumbnail here, so just read it and discard it Graphics::skipThumbnail(*in); in->readUint32BE(); // save date in->readUint16BE(); // save time // TODO: played time } _game.state = (State)in->readByte(); in->read(loadId, 8); if (strcmp(loadId, _game.id) && checkId) { delete in; warning("This save seems to be from a different AGI game (save from %s, running %s), not loaded", loadId, _game.id); return errBadFileOpen; } strncpy(_game.id, loadId, 8); if (saveVersion >= 5) { char md5[32 + 1]; for (i = 0; i < 32; i++) { md5[i] = in->readByte(); } md5[i] = 0; // terminate // As noted above in AgiEngine::saveGame the MD5 sum field may be all zero // when the save was made via a fallback matched game. In this case we will // replace the MD5 sum with a nicer string, so that the user can easily see // this fact in the debug output. The string saved in "md5" will never match // any valid MD5 sum, thus it is safe to do that here. if (md5[0] == 0) strcpy(md5, "fallback matched"); debug(0, "Saved game MD5: \"%s\"", md5); if (!getGameMD5()) { warning("Since your game was only detected via the fallback detector, there is no possibility to assure the save is compatible with your game version"); debug(0, "The game used for saving is \"%s\".", md5); } else if (strcmp(md5, getGameMD5())) { warning("Game was saved with different gamedata - you may encounter problems"); debug(0, "Your game is \"%s\" and save is \"%s\".", getGameMD5(), md5); } } for (i = 0; i < MAX_FLAGS; i++) _game.flags[i] = in->readByte(); for (i = 0; i < MAX_VARS; i++) _game.vars[i] = in->readByte(); setvar(vFreePages, 180); // Set amount of free memory to realistic value (Overwriting the just loaded value) _game.horizon = in->readSint16BE(); _game.lineStatus = in->readSint16BE(); _game.lineUserInput = in->readSint16BE(); _game.lineMinPrint = in->readSint16BE(); // These are never saved _game.cursorPos = 0; _game.inputBuffer[0] = 0; _game.echoBuffer[0] = 0; _game.keypress = 0; _game.inputMode = (InputMode)in->readSint16BE(); _game.lognum = in->readSint16BE(); _game.playerControl = in->readSint16BE(); if (in->readSint16BE()) quitGame(); _game.statusLine = in->readSint16BE(); _game.clockEnabled = in->readSint16BE(); _game.exitAllLogics = in->readSint16BE(); _game.pictureShown = in->readSint16BE(); _game.hasPrompt = in->readSint16BE(); _game.gameFlags = in->readSint16BE(); _game.inputEnabled = in->readSint16BE(); for (i = 0; i < _HEIGHT; i++) _game.priTable[i] = in->readByte(); if (_game.hasWindow) closeWindow(); _game.msgBoxTicks = 0; _game.block.active = false; // game.window - fixed by close_window() // game.has_window - fixed by close_window() _game.gfxMode = in->readSint16BE(); _game.cursorChar = in->readByte(); _game.colorFg = in->readSint16BE(); _game.colorBg = in->readSint16BE(); // game.hires - rebuilt from image stack // game.sbuf - rebuilt from image stack // game.ego_words - fixed by clean_input // game.num_ego_words - fixed by clean_input _game.numObjects = in->readSint16BE(); for (i = 0; i < (int16)_game.numObjects; i++) objectSetLocation(i, in->readSint16BE()); // Those are not serialized for (i = 0; i < MAX_DIRS; i++) { _game.controllerOccured[i] = false; } for (i = 0; i < MAX_STRINGS; i++) in->read(_game.strings[i], MAX_STRINGLEN); for (i = 0; i < MAX_DIRS; i++) { if (in->readByte() & RES_LOADED) agiLoadResource(rLOGIC, i); else agiUnloadResource(rLOGIC, i); _game.logics[i].sIP = in->readSint16BE(); _game.logics[i].cIP = in->readSint16BE(); } for (i = 0; i < MAX_DIRS; i++) { if (in->readByte() & RES_LOADED) agiLoadResource(rPICTURE, i); else agiUnloadResource(rPICTURE, i); } for (i = 0; i < MAX_DIRS; i++) { if (in->readByte() & RES_LOADED) agiLoadResource(rVIEW, i); else agiUnloadResource(rVIEW, i); } for (i = 0; i < MAX_DIRS; i++) { if (in->readByte() & RES_LOADED) agiLoadResource(rSOUND, i); else agiUnloadResource(rSOUND, i); } // game.pictures - loaded above // game.logics - loaded above // game.views - loaded above // game.sounds - loaded above for (i = 0; i < vtEntries; i++) { VtEntry *v = &_game.viewTable[i]; v->stepTime = in->readByte(); v->stepTimeCount = in->readByte(); v->entry = in->readByte(); v->xPos = in->readSint16BE(); v->yPos = in->readSint16BE(); v->currentView = in->readByte(); // v->view_data - fixed below v->currentLoop = in->readByte(); v->numLoops = in->readByte(); // v->loop_data - fixed below v->currentCel = in->readByte(); v->numCels = in->readByte(); // v->cel_data - fixed below // v->cel_data_2 - fixed below v->xPos2 = in->readSint16BE(); v->yPos2 = in->readSint16BE(); // v->s - fixed below v->xSize = in->readSint16BE(); v->ySize = in->readSint16BE(); v->stepSize = in->readByte(); v->cycleTime = in->readByte(); v->cycleTimeCount = in->readByte(); v->direction = in->readByte(); v->motion = (MotionType)in->readByte(); v->cycle = (CycleType)in->readByte(); v->priority = in->readByte(); v->flags = in->readUint16BE(); v->parm1 = in->readByte(); v->parm2 = in->readByte(); v->parm3 = in->readByte(); v->parm4 = in->readByte(); } for (i = vtEntries; i < MAX_VIEWTABLE; i++) { memset(&_game.viewTable[i], 0, sizeof(VtEntry)); } // Fix some pointers in viewtable for (i = 0; i < MAX_VIEWTABLE; i++) { VtEntry *v = &_game.viewTable[i]; if (_game.dirView[v->currentView].offset == _EMPTY) continue; if (!(_game.dirView[v->currentView].flags & RES_LOADED)) agiLoadResource(rVIEW, v->currentView); setView(v, v->currentView); // Fix v->view_data setLoop(v, v->currentLoop); // Fix v->loop_data setCel(v, v->currentCel); // Fix v->cel_data v->celData2 = v->celData; v->s = NULL; // not sure if it is used... } _sprites->eraseBoth(); // Clear input line _gfx->clearScreen(0); writeStatus(); // Recreate background from saved image stack clearImageStack(); while ((t = in->readByte()) != 0) { for (i = 0; i < 7; i++) parm[i] = in->readSint16BE(); replayImageStackCall(t, parm[0], parm[1], parm[2], parm[3], parm[4], parm[5], parm[6]); } // Load AGIPAL Data if (saveVersion >= 3) _gfx->setAGIPal(in->readSint16BE()); delete in; debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Closed %s", fileName.c_str()); setflag(fRestoreJustRan, true); _game.hasPrompt = 0; // force input line repaint if necessary cleanInput(); _sprites->eraseBoth(); _sprites->blitBoth(); _sprites->commitBoth(); _picture->showPic(); _gfx->doUpdate(); return errOK; }