int bcopy_01() { BFILE* in; BFILE* out; int i = 0; in = bfopen("test.txt", "rb"); TEST_EXPECT(in != NULL); out = bfopen("copy.txt", "wb"); TEST_EXPECT(out != NULL); while (!bfeof(in)) { bfputc(bfgetc(in), out); i++; } bfclose(in); bfclose(out); if (i == LENGTH_OF_TEST_FILE) { TEST_SUCCESS; } else { TEST_FAILURE("didn't copy all expected data (total bytes copied incorrect)."); } }
int bopen_01() { BFILE* f; f = bfopen("nonexistant.blah", "rb"); TEST_EXPECT(f == NULL); f = bfopen("test.txt", "rb"); TEST_EXPECT(f != NULL); bfclose(f); TEST_SUCCESS; }
void test2(void) { FILE *in1; bfile *in2; int ch; in1 = fopen("bitfiles.c", "rb"); in2 = bfopen("bitfiles.cc", "rb"); if ((NULL == in1) || (NULL == in2)) { printf("Can't open test files\n"); exit(1); } while (!feof(in1) && !feof(in2->file)) { ch = fgetc(in1); if (ch < ' ') ch = '.'; printf(" '%c' ", ch); for (ch = 0; ch < 8; ch++) printf("%c", "01"[bfread(in2)]); printf(" "); } fclose(in1); bfclose(in2); }
FILE *lockcoll(char subname[]) { char lockfile[512]; FILE *LOCK; //oppretter var mappen hvis den ikke finnes. Dette slik at vi slipper og gjøre dette under instalsjonen bmkdir_p(bfile("var/"),0755); sprintf(lockfile,"var/boitho-collections-%s.lock",subname); printf("locking lock \"%s\"\n",lockfile); if ((LOCK = bfopen(lockfile,"w+")) == NULL) { perror(lockfile); return NULL; } //geting the lock. if (flock(fileno(LOCK),LOCK_EX) != 0) { fclose(LOCK); return NULL; } return LOCK; }
void test1(void) { bfile *out; bfile *in; FILE *in1; FILE *in2; in = bfopen("bitfiles.c", "rb"); out = bfopen("bitfiles.cc", "wb"); if ((NULL == in) || (NULL == out)) { printf("Can't open/create test files\n"); exit(1); } while (!feof(in->file)) bfwrite(bfread(in), out); bfclose(in); bfclose(out); in1 = fopen("bitfiles.c", "rb"); in2 = fopen("bitfiles.cc", "rb"); if ((NULL == in1) || (NULL == in2)) { printf("Can't open test files for verifying\n"); exit(1); } while (!feof(in1) && !feof(in2)) { if (fgetc(in1) != fgetc(in2)) { printf("Files not identical, copy failed!\n"); exit(1); } } if (!feof(in1) || !feof(in2)) { printf("Not same size, copy failed!\n"); exit(1); } fclose(in1); fclose(in2); }
FILE *openMaplist() { FILE *MAPLIST; char *cptr; //sjekker først om vi har en env variabel kalt "BOITHOMAPLIST". Hvis vi har det så bruker vi den filen //gjør det slik slik at vi kan ha lokal maplist, på hver bbs, man fortsat ha resten likt på alle, og på read onlu nfs. if ((cptr = getenv("BOITHOMAPLIST")) != NULL) { if ( (MAPLIST = fopen(cptr,"r")) == NULL) { perror(cptr); exit(1); } } //leser liten over mapper vi kan bruke. else if ( (MAPLIST = bfopen("config/maplist.conf","r")) == NULL) { perror(bfile("config/maplist.conf")); exit(1); } return MAPLIST; }
/* Encodes a block of up to BUF samples. The first output is a 32-bit integer showing the size of the block. After that follow 3 blocks of that size containing the delta-encoding of the timestamp, then the humidity data, and the temperature data. Returns the block size or EOF on error. */ int handleblock() { char buf[64]; int ret; int32_t i; struct tm tm = (struct tm) {0}; tm.tm_isdst = -1; int32_t diffs[BUF][3]; time_t oldtime, curtime; int32_t hum, humd, temp, tempd; int32_t oldhum, curhum, oldtemp, curtemp; /* Read up to BUF samples into the diffs[] array */ if(fgets(buf, 64, stdin) == NULL) { return EOF; } ret = sscanf(buf, "%d-%d-%d_%d:%d:%d %d.%d %d.%d\n", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &hum, &humd, &temp, &tempd); if(ret != 10) { return EOF; } tm.tm_year -= 1900; tm.tm_mon -= 1; oldtime = mktime(&tm); oldhum = hum * 10 + humd; oldtemp = temp * 10 + tempd; diffs[0][0] = oldtime; diffs[0][1] = oldhum; diffs[0][2] = oldtemp; for(i = 1; i < BUF; i++) { if(fgets(buf, 64, stdin) == NULL) { /* End of file, stop */ break; } ret = sscanf(buf, "%d-%d-%d_%d:%d:%d %d.%d %d.%d\n", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &hum, &humd, &temp, &tempd); if(ret != 10) { if(ret == 0) { /* Maybe an empty line */ break; } else { /* Other crap */ return EOF; } } tm.tm_year -= 1900; tm.tm_mon -= 1; curtime = mktime(&tm); curhum = hum * 10 + humd; curtemp = temp * 10 + tempd; diffs[i][0] = curtime - oldtime; diffs[i][1] = curhum - oldhum; diffs[i][2] = curtemp - oldtemp; oldtime = curtime; oldhum = curhum; oldtemp = curtemp; } /* Write the block size */ bfwrite(i, 32, bf); /* Pack the timestamps, then the humidity, then the temperature. */ for(int j = 0; j < 3; j++) { for(int k = 0; k < i; k++) { if(pack(diffs[k][j]) == EOF) { return EOF; } } } return i; } int main() { bf = bfopen(stdout); bfwrite(PACKBITS, 8, bf); while(handleblock() != EOF); bfclose(bf); return 0; }
/* This is the routine that is executed from a new thread */ void *do_chld(void *arg) { // starter loging bblog(DEBUGINFO, "searchd_child: Starting new thread."); bblog(DEBUGINFO, "searchd: do_chld()"); // deklarerer variabler struct searchd_configFORMAT *searchd_config = arg; int mysocfd = (*searchd_config).newsockfd; struct timeval globalstart_time, globalend_time; FILE *LOGFILE; int i,n; struct queryNodeHederFormat queryNodeHeder; struct SiderFormat *Sider; int net_status; int ranking; struct hashtable *crc32hashmap; int nrOfSubnames; config_setting_t *cfgstring; config_setting_t *cfgcollection; config_setting_t *cfgcollections; struct subnamesConfigFormat subnamesDefaultsConfig; char **Data; int Count; char groupOrQuery[1024]; groupOrQuery[0] = '\0'; struct SiderHederFormat *SiderHeder; // Setter signalhånterer for allarm. Hvis allarm skjer i straten av programet, er noe seriøst galt. For eks er vi tom for minne. //Da fungerer det dårlig å logge, syslog kan kalle malloc og slikt. Vil resette den til en versjon som logger før vi kjører søk. signal (SIGALRM, catch_alarm_nolog); /* Set an alarm to go off in a little while. This so we don't run forever if we get en ever loop */ alarm (searchd_config->optAlarm); dp_priority_locl_start(); // første malloc. Har vi forlite minne vil vi henge her. if ((SiderHeder = malloc(sizeof(struct SiderHederFormat))) == NULL) { bblog(ERROR, "malloc()"); bblog(CLEAN, "~do_chld()"); return 0; } gettimeofday(&globalstart_time, NULL); #ifdef WITH_THREAD bblog(DEBUGINFO, "Child thread [%d]: Socket number = %d", pthread_self(), mysocfd); #else bblog(DEBUGINFO, "Socket number = %d",mysocfd); #endif #ifdef DEBUG struct timeval start_time, end_time; #endif // Setter signalhånterer for allarm. Hvis allarm skjer i straten av programet, er noe seriøst galt. For eks er vi tom for minne. //Da fungerer det dårlig å logge, syslog kan kalle malloc og slikt. Nå resetter vi den den til en versjon som logger søk. signal (SIGALRM, catch_alarm); /* Disable tcp delay */ int nodelayflag = 1; setsockopt(mysocfd, IPPROTO_TCP, TCP_NODELAY, &nodelayflag, sizeof(int)); /* read from the given socket */ if ((i=recv(mysocfd, &queryNodeHeder, sizeof(queryNodeHeder),MSG_WAITALL)) == -1) { bblog_errno(ERROR, "recv()"); } // Read collections /w cfg. if ((recv(mysocfd, &nrOfSubnames, sizeof nrOfSubnames, MSG_WAITALL)) == -1) bblog_errno(ERROR, "recv nrOfSubnames"); bblog(DEBUGINFO, "nrOfSubnames: %d",nrOfSubnames); struct subnamesFormat subnames[nrOfSubnames]; if (nrOfSubnames > 0) { if ((recv(mysocfd, &subnames, sizeof subnames, MSG_WAITALL)) == -1) bblog_errno(ERROR, "recv subnames"); } //sender svar med en gang at vi kan gjøre dette net_status = net_CanDo; //if ((n=sendall(mysocfd,&net_status, sizeof(net_status))) != sizeof(net_status)) { if ((n=send(mysocfd,&net_status, sizeof(net_status),MSG_NOSIGNAL)) != sizeof(net_status)) { bblog_errno(ERROR, "searchd_child: Warning! Sent only %i of %i bytes at %s:%d",n,sizeof(net_status),__FILE__,__LINE__); } bblog(DEBUGINFO, "MaxsHits %i",queryNodeHeder.MaxsHits); //Sider = (struct SiderFormat *)malloc(sizeof(struct SiderFormat) * (queryNodeHeder.MaxsHits)); bblog(DEBUGINFO, "Ranking search?"); #ifndef BLACK_BOKS //ToDo: må ha låsing her if ((LOGFILE = bfopen("config/query.log","a")) == NULL) { bblog_errno(ERROR, "logfile"); } else { fprintf(LOGFILE,"%s\n",queryNodeHeder.query); fclose(LOGFILE); } #endif bblog(DEBUGINFO, "searchd_child: Incoming query: %s",queryNodeHeder.query); strcpy(SiderHeder->servername,servername); #ifndef WITHOUT_THESAURUS // TODO: Denne må skalere til flere språk: char *lang = NULL; switch (queryNodeHeder.lang) { case LANG_NBO: lang = "nbo"; break; case LANG_ENG: lang = "eng"; break; } bblog(INFO, "[searchd] lang_id = %i", queryNodeHeder.lang); bblog(INFO, "[searchd] lang = %s", lang); searchd_config->thesaurusp = NULL; if (lang != NULL && searchd_config->thesaurus_all != NULL) { iterator it = map_find(searchd_config->thesaurus_all, lang); if (it.valid) { bblog(INFO, "[searchd] Loading %s thesaurus", lang); searchd_config->thesaurusp = map_val(it).ptr; } else { bblog(INFO, "[searchd] No thesaurus for %s", lang); } } #endif /***************************************/ /****************/ //dekoder subname bblog(DEBUGINFO, "nrOfSubnames %i",nrOfSubnames); /* nrOfSubnames = 1; subnames = malloc(sizeof(struct subnamesFormat) * nrOfSubnames); strscpy(subnames[0].subname,"www",sizeof(subnames[0].subname)); */ #ifdef DEBUG bblog(DEBUGINFO, "searchd_child: "); bblog(DEBUGINFO, "##########################################################"); bblog(DEBUGINFO, "searchd_child: subnames:"); bblog(DEBUGINFO, "Total of %i", nrOfSubnames); for (i=0;i<nrOfSubnames;i++) { bblog(DEBUGINFO, "searchd_child: subname nr %i: \"%s\"",i,subnames[i].subname); } bblog(DEBUGINFO, "searchd_child: ##########################################################"); #endif SiderHeder->filtypesnrof = MAXFILTYPES; SiderHeder->errorstrlen=sizeof(SiderHeder->errorstr); int parsing_failed; attr_conf *navmenu_cfg = parse_navmenu_cfg(queryNodeHeder.navmenucfg, &parsing_failed, globalOptVerbose); if (parsing_failed) { SiderHeder->responstype = searchd_responstype_error; snprintf(SiderHeder->errorstr, sizeof SiderHeder->errorstr, "An error occurred while parsing configuration for navigation menu."); SiderHeder->errorstrlen = strlen(SiderHeder->errorstr); // TODO: is errorstrlen even used? } if (!dosearch(queryNodeHeder.query, strlen(queryNodeHeder.query),&Sider,SiderHeder,SiderHeder->hiliteQuery, servername,subnames,nrOfSubnames,queryNodeHeder.MaxsHits, queryNodeHeder.start, queryNodeHeder.filterOn, "",queryNodeHeder.orderby,SiderHeder->dates,queryNodeHeder.search_user, &SiderHeder->filters, searchd_config, SiderHeder->errorstr, &SiderHeder->errorstrlen, &global_DomainIDs, queryNodeHeder.HTTP_USER_AGENT, groupOrQuery, queryNodeHeder.anonymous, navmenu_cfg, spelling )) { bblog(WARN, "searchd_child: dosearch did not return success"); SiderHeder->responstype = searchd_responstype_error; //setter at vi ikke hadde noen svar SiderHeder->TotaltTreff = 0; SiderHeder->showabal = 0; bblog(ERROR, "searchd_child: can't do dosearch: \"%s\"", SiderHeder->errorstr); } show_attributes_destroy(navmenu_cfg); dp_priority_locl_end(); //kopierer inn subnames. Kan bare sende over MAX_COLLECTIONS, men søker i alle for (i=0;((i<MAX_COLLECTIONS) && (i<nrOfSubnames));i++) { SiderHeder->subnames[i] = subnames[i]; } SiderHeder->nrOfSubnames = i--; if (globalOptVerbose) { bblog(INFO, "searchd_child: subnames:"); for (i=0;i<SiderHeder->nrOfSubnames;i++) { bblog(INFO, "searchd_child: \t%s: %i",SiderHeder->subnames[i].subname,SiderHeder->subnames[i].hits); } bblog(INFO, "searchd_child:"); } //finer først tiden vi brukte gettimeofday(&globalend_time, NULL); SiderHeder->total_usecs = getTimeDifference(&globalstart_time,&globalend_time); //printf("query \"%s\", TotaltTreff %i,showabal %i,filtered %i,total_usecs %f\n",queryNodeHeder.query,SiderHeder->TotaltTreff,SiderHeder->showabal,SiderHeder->filtered,SiderHeder->total_usecs); bblog(CLEAN, "|%-40s | %-11i | %-11i | %-11i | %-11f|", queryNodeHeder.query, SiderHeder->TotaltTreff, SiderHeder->showabal, SiderHeder->filtered, SiderHeder->total_usecs); #ifdef DEBUG gettimeofday(&start_time, NULL); #endif #if 1 #ifdef DEBUG gettimeofday(&end_time, NULL); bblog(DEBUGINFO, "searchd_child: Time debug: sending SiderHeder %f",getTimeDifference(&start_time,&end_time)); #endif #ifdef DEBUG gettimeofday(&start_time, NULL); #endif struct sendarrayFormat{ int size; void *p; int copy; }; void send_to_array (struct sendarrayFormat *sendarray, int *sendarraylength, void *p, int size, int copy) { #ifdef DEBUG printf("send_to_array(sendarraylength=%i,size=%i)\n",*sendarraylength,size); #endif if (size == 0) { return; } sendarray[*sendarraylength].copy = copy; if (copy) { sendarray[*sendarraylength].p = malloc(size); memcpy(sendarray[*sendarraylength].p,p,size); sendarray[*sendarraylength].size = size; } else { sendarray[*sendarraylength].p = p; sendarray[*sendarraylength].size = size; } *sendarraylength += 1; }
int main(int argc, char *argv[]) { bblog_init("searchd"); bblog(CLEAN, "Initializing..."); int sockfd; int runCount; //int newsockfd; socklen_t clilen; struct sockaddr_in cli_addr, serv_addr; FILE *LOGFILE; //FILE *LOCK; struct searchd_configFORMAT searchd_config; struct config_t maincfg; searchd_config.searchport = 0; searchd_config.optLog = 0; searchd_config.optMax = 0; searchd_config.optSingle = 0; searchd_config.optrankfile = NULL; searchd_config.optPreOpen = 0; searchd_config.optFastStartup = 0; searchd_config.optCacheIndexes = 1; searchd_config.optAlarm = 60; // Needed for the speller to properly convert utf8 to wchar_t setlocale(LC_ALL, "en_US.UTF-8"); /* Ignore collection updates for now */ signal(SIGUSR2, SIG_IGN); /* And ignore spelling updates */ signal(SIGUSR1, SIG_IGN); char c; while ((c=getopt(argc,argv,"clp:m:b:vsofA:L:S:a:"))!=-1) { switch (c) { case 'p': searchd_config.searchport = atoi(optarg); bblog(CLEAN, "searchd: Option -p: Using port %i.",searchd_config.searchport); break; case 'l': searchd_config.optLog = 1; break; case 'o': searchd_config.optPreOpen = 1; break; case 'm': searchd_config.optMax = atoi(optarg); break; case 'b': searchd_config.optrankfile = optarg; break; case 'v': /* XXX: Remove now that we have severity in the logger? */ bblog(CLEAN, "searchd: Option -v: Verbose output."); globalOptVerbose = 1; break; case 's': bblog(INFO, "Option -s: Won't fork for new connections"); searchd_config.optSingle = 1; break; case 'f': searchd_config.optFastStartup = 1; break; case 'c': searchd_config.optCacheIndexes = 0; break; case 'A': bblog_set_appenders(atoi(optarg)); break; case 'L': bblog_set_severity(atoi(optarg)); break; case 'S': spelling_min_freq = strtol(optarg, NULL, 10); break; case 'a': searchd_config.optAlarm = atoi(optarg); break; default: bblog(ERROR, "Unknown argument: %c", c); errx(1, "Unknown argument: %c", c); } } #ifdef BLACK_BOKS bblog(CLEAN, "Blackbox mode (searchdbb)"); time_t starttime; time(&starttime); if (searchd_config.optLog) { /* Only add file logging if syslog is disabled */ if ((bblog_get_appenders() & LOGGER_APPENDER_SYSLOG) == 0) bblog_set_appenders(LOGGER_APPENDER_FILE|bblog_get_appenders()); } /* Write pidfile */ FILE *pidfile = fopen(bfile("var/searchd.pid"), "w"); if (pidfile != NULL) { fprintf(pidfile, "%d", getpid()); fclose(pidfile); } else { bblog(WARN, "Unable to write to pidfile"); } bblog(CLEAN, "searchd: Starting. Time is %s",ctime(&starttime)); #endif #ifdef DEBUG bblog(DEBUGINFO, "searchd: Debug: argc %i, optind %i",argc,optind); #endif if (searchd_config.optrankfile == NULL) { searchd_config.optrankfile = "Brank"; } #ifdef WITH_SPELLING if (searchd_config.optFastStartup != 1) { if ((spelling = train(bfile("var/dictionarywords"))) == NULL) { bblog(ERROR, "Can't init spelling."); } cache_spelling_keepalive(&spelling); signal(SIGUSR1, cache_spelling_hup); } #endif if (argc > optind) { strncpy(servername,argv[optind], sizeof(servername) -1); } else { bblog(ERROR, "No hostname supplied"); errx(1, "You have to supply a hostname"); } lotPreOpenStartl(&searchd_config.lotPreOpen.DocumentIndex,"DocumentIndex","www",searchd_config.optPreOpen); lotPreOpenStartl(&searchd_config.lotPreOpen.Summary,"summary","www",searchd_config.optPreOpen); #ifdef BLACK_BOKS if (searchd_config.optCacheIndexes == 1) { if (searchd_config.optFastStartup != 1) { bblog(INFO, "Reading indexes"); cache_indexes(0); bblog(INFO, "Cached indexes: %dMB, cached indexes: %d", indexcachescached[0]/(1024*1024), indexcachescached[1]); preopen(); cache_fresh_lot_collection(); cache_indexes_keepalive(); signal(SIGUSR2, cache_indexes_hup); } else { signal(SIGUSR2, SIG_IGN); } } else { signal(SIGUSR2, SIG_IGN); } #endif maincfg = maincfgopen(); if (searchd_config.searchport == 0) { searchd_config.searchport = maincfg_get_int(&maincfg,"BSDPORT"); } searchd_config.cmc_port = maincfg_get_int(&maincfg,"CMDPORT"); maincfgclose(&maincfg); /***********************************************************************************/ //prøver å få fil lock. Bare en deamon kan kjøre avgangen /* #ifndef ALLOW_MULTIPLE_SEARCHD if ((LOCK = fopen("/tmp/searchd.loc","w")) == NULL) { perror("lock file"); exit(1); } if (flock(fileno(LOCK),LOCK_EX | LOCK_NB) != 0) { if (errno == EWOULDBLOCK) { printf("En annen prosses kjører allerede. Steng denne først.\n"); } else { perror("cant get lock file"); } exit(1); } #endif */ /***********************************************************************************/ //#ifndef BLACK_BOKS /* Initialize the configuration */ config_init(&cfg); /* Load the file */ #ifdef DEBUG bblog(DEBUGINFO, "searchd: Debug: Loading [%s] ...",bfile(cfg_searchd)); #endif if (!config_read_file(&cfg, bfile(cfg_searchd))) { bblog(ERROR, "config read failed: [%s]: %s at line %i",bfile(cfg_searchd),config_error_text(&cfg),config_error_line(&cfg)); exit(1); } //#endif html_parser_init(); /* #ifdef WITH_THREAD pthread_t chld_thr; printf("starting whth thread\n"); #else printf("starting single thread version\n"); #endif */ bblog(CLEAN, "Servername: %s", servername); //ToDo: må ha låsing her if ((LOGFILE = bfopen("config/query.log","a")) == NULL) { bblog_errno(ERROR, "%s", bfile("config/query.log")); } else { fprintf(LOGFILE,"starting server %s\n",servername); fclose(LOGFILE); } #ifdef BLACK_BOKS // Initialiser thesaurus med ouput-filene fra 'build_thesaurus_*': searchd_config.thesaurus_all = NULL; #ifndef WITHOUT_THESAURUS bblog(INFO, "init thesaurus"); searchd_config.thesaurus_all = NULL; if (searchd_config.optFastStartup != 1) { searchd_config.thesaurus_all = load_all_thesauruses(bfile("data/thesaurus/")); if (searchd_config.thesaurus_all == NULL) { bblog(ERROR, "Unable to open thesaurus. Disabling stemming"); } else { bblog(INFO, "init thesaurus done"); } } #endif bblog(INFO, "init file-extensions"); searchd_config.getfiletypep = fte_init(bfile("config/file_extensions.conf")); if (searchd_config.getfiletypep == NULL) { bblog(ERROR, "Unable to open file-extensions configuration file. Disabling file-extensions."); } bblog(INFO, "init attribute descriptions"); searchd_config.attrdescrp = adf_init(bfile("config/attribute_descriptions.conf")); if (searchd_config.attrdescrp == NULL) { bblog(ERROR, "Unable to open attribute descriptions configuration file. Disabling attribute descriptions."); } bblog(INFO, "init show-attributes"); char *warnings; /*searchd_config.showattrp = show_attributes_init(bfile("config/show_attributes.conf"), &warnings); if (searchd_config.showattrp == NULL) { fprintf(stderr, "searchd: ERROR!! Unable to open show-attributes configuration file. Disabling attributes.\n"); } else if (warnings[0]!='\0') { fprintf(stderr, "searchd: ******************* Warnings reading show-attributes config: ********************\n"); fprintf(stderr, "%s", warnings); fprintf(stderr, "searchd: *********************************************************************************\n"); }*/ #else //starter opp bblog(INFO, "Loading domain-ids..."); iintegerLoadMemArray2(&global_DomainIDs,"domainid",sizeof(unsigned short), "www"); //laster inn alle poprankene bblog(INFO, "Loading pop MemArray..."); popopenMemArray2("www",searchd_config.optrankfile); // ToDo: hardkoder subname her, da vi ikke vet siden vi ikke her får et inn enda bblog(INFO, "Loading adultWeight MemArray..."); adultWeightopenMemArray2("www"); // ToDo: hardkoder subname her, da vi ikke vet siden vi ikke her får et inn enda #endif IIndexInaliser(); #ifdef WITH_MEMINDEX IIndexLoad(); #endif if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { bblog(ERROR, "Server error! Can't open stream socket."); exit(1); } memset((char *) &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(searchd_config.searchport); bblog(INFO, "Will bind to port %i",searchd_config.searchport); //seter at sokket kan rebrukes int yes=1; if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { bblog_errno(ERROR, "setsockopt()"); exit(1); } if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { bblog_errno(ERROR, "Can't bind local address. Port %i", searchd_config.searchport); exit(1); } /* set the level of thread concurrency we desire */ //thr_setconcurrency(5); listen(sockfd, 5); runCount = 0; #ifndef NEW_CHILD_CATCHER signal(SIGCLD, SIG_IGN); /* now I don't have to wait() for forked children! */ #else { // runarb 28 juni 2009: // Hvis vi har verbose output så skal vi wait()e for våre barn, og vise prity print når de dør. // desverre har det vært mye kød, der hovedprosessen blir hengene i sigchild_handler() og ikke kan // fork'e flere barn. For å ungå dtte venter vi ikke på våre barn til vanlig. if (globalOptVerbose) { struct sigaction sa; int ret; sa.sa_sigaction = sigchild_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; ret = sigaction(SIGCHLD, &sa, 0); if (ret) { bblog_errno(ERROR, "sigaction()"); exit(1); } } else { signal(SIGCLD, SIG_IGN); /* now I don't have to wait() for forked children! */ } } #endif bblog(CLEAN, "|------------------------------------------------------------------------------------------------|"); bblog(CLEAN, "|%-40s | %-11s | %-11s | %-11s | %-11s|","query", "TotaltTreff", "showabal", "filtered", "total_usecs"); bblog(CLEAN, "|------------------------------------------------------------------------------------------------|"); for((clilen = sizeof(cli_addr));;) { searchd_config.newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if(searchd_config.newsockfd < 0) { /* Just restart */ if (errno == EINTR) continue; bblog(WARN, "searchd: Server warning! Accept error"); } else { if (searchd_config.optSingle) { do_chld((void *) &searchd_config); } else { #ifdef DEBUG bblog(DEBUGINFO, "Debug mode; will not fork to new process."); do_chld((void *) &searchd_config); #else /* #ifdef WITH_THREAD //create a new thread to process the incomming request //thr_create(NULL, 0, do_chld, (void *) searchd_config, THR_DETACHED, &chld_thr); pthread_create(&chld_thr, NULL, do_chld, (void *) &searchd_config); //the server is now free to accept another socket request #else do_chld((void *) &searchd_config); #endif */ bblog(DEBUGINFO, "Forking new prosess."); if (fork() == 0) { // this is the child process close(sockfd); // child doesn't need the listener do_chld((void *) &searchd_config); close(searchd_config.newsockfd); bblog(DEBUGINFO, "Terminating child."); exit(0); } else { close(searchd_config.newsockfd); // perent doesn't need the new socket } #endif } } ++runCount; if ((searchd_config.optMax != 0) && (runCount >= searchd_config.optMax)) { //venter på siste trå. Ikke helt optimalt dette, da vi kan ha flere tråer som kjører i paralell /* #ifdef WITH_THREAD pthread_join(chld_thr, NULL); #endif */ bblog(WARN, "have reached Max runs. Exiting..."); break; } } html_parser_exit(); free(searchd_config.lotPreOpen.Summary); free(searchd_config.lotPreOpen.DocumentIndex); adf_destroy(searchd_config.attrdescrp); fte_destroy(searchd_config.getfiletypep); if (searchd_config.optFastStartup != 1) { thesaurus_destroy(searchd_config.thesaurusp); } //freegjør spelling. Trekt, men kjekt av valgring kan finne ut om noe ikke her blirr frigjort. if (searchd_config.optFastStartup != 1) { untrain(&spelling); } return(0); }
uint16_t aout_write(FILE* out, bool relocatable, bool intermediate) { struct aout_byte* current_outer; struct aout_byte* current_inner; struct lprov_entry* linker_provided = NULL; struct lprov_entry* linker_required = NULL; struct lprov_entry* linker_adjustment = NULL; struct lprov_entry* linker_section = NULL; struct lprov_entry* linker_output = NULL; struct lprov_entry* linker_temp = NULL; uint32_t mem_index, out_index; uint16_t inst; BFILE* temp = NULL; bstring bname, ename; uint16_t eaddr; bool did_find; bool shown_expr_warning = false; bool has_output = false; // Initialize out our extension table. code_offset += textn_init(start); // If relocatable, initialize out our relocation table. if (relocatable) code_offset += treloc_init(start); // First go through and evaluate all expressions that need to be. current_outer = start; out_index = code_offset; while (current_outer != NULL) { if (current_outer->type == AOUT_TYPE_METADATA_ORIGIN) { // Adjust memory address. out_index = current_outer->opcode; } else if (current_outer->type == AOUT_TYPE_METADATA_SECTION) { assert(current_outer->label != NULL); // We're exporting the current address as the beginning // of a section. if (!intermediate) ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL); // Check to make sure outputs haven't previously been emitted. if (has_output) ahalt(ERR_OUTPUT_BEFORE_SECTION, NULL); // Create linker entry. linker_temp = lprov_create(current_outer->label, out_index); linker_temp->next = linker_section; linker_section = linker_temp; printd(LEVEL_VERBOSE, "LINK SECTION %s -> 0x%04X\n", current_outer->label, out_index); } else if (current_outer->type == AOUT_TYPE_METADATA_OUTPUT) { assert(current_outer->label != NULL); // We're exporting the current address as the beginning // of a section. if (!intermediate) ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL); // Create linker entry. has_output = true; linker_temp = lprov_create(current_outer->label, out_index); linker_temp->next = linker_output; linker_output = linker_temp; printd(LEVEL_VERBOSE, "LINK OUTPUT 0x%04X -> %s\n", out_index, current_outer->label); } else if (current_outer->type == AOUT_TYPE_METADATA_EXPORT) { assert(current_outer->label != NULL); // We're exporting the address of this label in the // object table. if (!intermediate) ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL); // Resolve label position. ename = bfromcstr(current_outer->label); eaddr = aout_get_label_address(ename); bdestroy(ename); // Create linker entry. linker_temp = lprov_create(current_outer->label, eaddr); linker_temp->next = linker_provided; linker_provided = linker_temp; printd(LEVEL_VERBOSE, "LINK REPLACE %s -> 0x%04X\n", current_outer->label, eaddr); } else if (current_outer->type == AOUT_TYPE_NORMAL && current_outer->expr != NULL) { if (current_outer->expr->type != EXPR_LABEL) { // This is either just a number or a more complicated expression, so // evaluate it using the preprocessor expression engine. if ((relocatable || intermediate) && !shown_expr_warning) { printd(LEVEL_WARNING, "warning: expressions will not be adjusted at link or relocation time.\n"); printd(LEVEL_WARNING, " ensure labels are not used as part of expressions.\n"); shown_expr_warning = true; } current_outer->raw_used = true; current_outer->raw = expr_evaluate(current_outer->expr, &aout_get_label_address, &ahalt_expression_exit_handler); expr_delete(current_outer->expr); current_outer->expr = NULL; } else { // If this is just a label, we can handle it directly (this allows // us to handle imported labels in intermediate code). current_inner = start; mem_index = code_offset; did_find = false; // Search for .IMPORT directives first. while (current_inner != NULL) { if (current_inner->type == AOUT_TYPE_METADATA_ORIGIN) { // Adjust memory address. mem_index = current_inner->opcode; } else if (current_inner->type == AOUT_TYPE_METADATA_IMPORT) { // An imported label (we don't need to adjust // memory index because the existance of this type // of entry doesn't affect executable size). if (!intermediate) ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL); assert(current_outer->expr->data != NULL); if (strcmp(current_inner->label, ((bstring)current_outer->expr->data)->data) == 0) { // We don't actually know our position yet; // that will be handled by the linker! current_outer->raw = 0xFFFF; expr_delete(current_outer->expr); current_outer->expr = NULL; linker_temp = lprov_create(current_inner->label, out_index); linker_temp->next = linker_required; linker_required = linker_temp; printd(LEVEL_VERBOSE, "LINK REPLACE 0x%04X -> %s\n", out_index, current_inner->label); did_find = true; break; } } // Goto next. current_inner = current_inner->next; } // If it wasn't found in the .IMPORT directives, try searching // labels directly using the expression engine. if (!did_find) { // Replace the label position. current_outer->raw_used = true; current_outer->raw = expr_evaluate(current_outer->expr, &aout_get_label_address, &ahalt_expression_exit_handler); expr_delete(current_outer->expr); current_outer->expr = NULL; did_find = true; // We also need to add this entry to the adjustment // table for the linker since it also needs to adjust // internal label jumps in files when it concatenates // all of the object code together. linker_temp = lprov_create(NULL, out_index); linker_temp->next = linker_adjustment; linker_adjustment = linker_temp; printd(LEVEL_VERBOSE, "LINK ADJUST 0x%04X\n", out_index); } } } if (current_outer->type == AOUT_TYPE_NORMAL && current_outer->label == NULL) out_index += 1; current_outer = current_outer->next; } // If intermediate, we need to write out our linker table // as the absolute first thing in the file. if (intermediate) { fwrite(ldata_objfmt, 1, strlen(ldata_objfmt) + 1, out); objfile_save(out, linker_provided, linker_required, linker_adjustment, linker_section, linker_output); // Adjust the "true origin" for .ORIGIN directivies because // the linker table won't exist in the final result when // linked. true_origin = (uint16_t)ftell(out); } // Write out our extension table. textn_write(out); // If relocatable, write out our relocation table. if (relocatable) treloc_write(out); // Now write to the file. current_outer = start; while (current_outer != NULL) { if (current_outer->type == AOUT_TYPE_METADATA_ORIGIN) { // Adjust origin. fseek(out, true_origin + current_outer->opcode * 2 /* double because the number is in words, not bytes */, SEEK_SET); } else if (current_outer->type == AOUT_TYPE_METADATA_INCBIN) { // Include binary file. bname = ppfind_locate(bautofree(bfromcstr(current_outer->label))); if (bname == NULL) ahalt(ERR_UNABLE_TO_INCBIN, current_outer->label); temp = bfopen((const char*)(bname->data), "rb"); if (temp == NULL) ahalt(ERR_UNABLE_TO_INCBIN, current_outer->label); // Copy binary data. while (!bfeof(temp)) { // TODO: This could be faster if we didn't do it character // by character. fputc(bfgetc(temp), out); } // Finalize. bfclose(temp); bdestroy(bname); } else if (current_outer->type == AOUT_TYPE_NORMAL) { // Update the debugging symbol. dbgfmt_update_symbol_list(¤t_outer->symbols, (uint16_t)((ftell(out) - true_origin) / 2)); // Normal output. if (current_outer->raw_used == true) { inst = current_outer->raw; iwrite(&inst, out); } else if (current_outer->label == NULL) { inst = INSTRUCTION_CREATE(current_outer->opcode, current_outer->a, current_outer->b); iwrite(&inst, out); } } // Goto next in linked list. current_outer = current_outer->next; } fflush(out); return (uint16_t)((ftell(out) - true_origin) / 2); }
int main(int argc, char* argv[]) { bstring ldargs = bfromcstr(""); int i, result; unsigned int match = 0, unmatch = 0; char ca, ce; BFILE* expect; BFILE* actual; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_lit* gen_relocatable = arg_lit0("r", "relocatable", "Generate relocatable code."); struct arg_lit* gen_intermediate = arg_lit0("i", "intermediate", "Generate intermediate code for use with the linker."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input assembly file."); struct arg_file* expect_file = arg_file0("e", "expect", "<file>", "The output file that contains expected output."); struct arg_file* actual_file = arg_file1("a", "actual", "<file>", "The output file where actual output will be placed."); struct arg_file* symbols_file = arg_file0("s", "debug-symbols", "<file>", "The debugging symbol output file."); struct arg_lit* fail_opt = arg_lit0("f", "fail", "The assembler is expected to fail and the actual output file should not exist on completion."); struct arg_file* path = arg_file1("p", NULL, "<path>", "The path to the assembler."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { show_help, gen_relocatable, gen_intermediate, little_endian_mode, symbols_file, input_file, expect_file, actual_file, fail_opt, path, verbose, quiet, end }; // Parse arguments. int nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Assembler Test Driver"))); if (nerrors != 0 || show_help->count != 0 || (fail_opt->count == 0 && (expect_file->count == 0 || actual_file->count == 0))) { if (show_help->count != 0 && fail_opt->count == 0 && (expect_file->count == 0 || actual_file->count == 0)) printd(LEVEL_ERROR, "error: you must provide either -f or -e and -a.\n"); if (show_help->count != 0) arg_print_errors(stderr, end, "testasm"); printd(LEVEL_DEFAULT, "syntax:\n testasm"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Generate the argument list for the assembler. ldargs = bfromcstr(path->filename[0]); binsertch(ldargs, 0, 1, '"'); bconchar(ldargs, '"'); bconchar(ldargs, ' '); // Verbosity options. if (verbose->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < verbose->count; i++) bconchar(ldargs, 'v'); bconchar(ldargs, ' '); } if (quiet->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < quiet->count; i++) bconchar(ldargs, 'q'); bconchar(ldargs, ' '); } // Literal options. if (gen_relocatable->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < gen_relocatable->count; i++) bconchar(ldargs, 'r'); bconchar(ldargs, ' '); } if (gen_intermediate->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < gen_intermediate->count; i++) bconchar(ldargs, 'i'); bconchar(ldargs, ' '); } if (little_endian_mode->count > 0) { for (i = 0; i < little_endian_mode->count; i++) bcatcstr(ldargs, "--little-endian "); } // Unlink the actual file so that if we are expecting // failure, we won't return incorrectly. unlink(actual_file->filename[0]); // Output file. bcatcstr(ldargs, "-o \""); bcatcstr(ldargs, actual_file->filename[0]); bcatcstr(ldargs, "\" "); // Input file. bcatcstr(ldargs, "\""); bcatcstr(ldargs, input_file->filename[0]); bcatcstr(ldargs, "\" "); // Windows needs the whole command wrapped in quotes and slashes to be correct. // See http://stackoverflow.com/questions/2642551/windows-c-system-call-with-spaces-in-command. #ifdef _WIN32 binsertch(ldargs, 0, 1, '"'); bconchar(ldargs, '"'); #endif // Now run the assembler! result = system(ldargs->data); if (result != 0 && fail_opt->count == 0) { // Assembler returned error exit code. printd(LEVEL_ERROR, "error: expected success but assembler returned non-zero exit code (%i).\n", result); return 1; } else if (result == 0 && fail_opt->count >= 1) { // Assembler returned zero when failure was expected. printd(LEVEL_ERROR, "error: expected failure but assembler returned zero exit code.\n"); return 1; } else if (result != 0 && fail_opt->count >= 1) { // Assembler failed and we expected it to. Return success only // if the output file does not exist. actual = bfopen(actual_file->filename[0], "rb"); if (actual != NULL) { printd(LEVEL_ERROR, "error: expected failure but actual output file exists.\n"); bfclose(actual); return 1; } return 0; } // Open expect data. expect = bfopen(expect_file->filename[0], "rb"); if (expect == NULL) { // The expect file was not provided. printd(LEVEL_ERROR, "error: path to expect file does not exist.\n"); return 1; } // Open actual data. actual = bfopen(actual_file->filename[0], "rb"); if (actual == NULL) { // The expect file was not provided. bfclose(expect); printd(LEVEL_ERROR, "error: expected data but actual output file does not exist after running assembler.\n"); return 1; } // Now compare raw bytes. while (true) { if (!bfeof(actual) && !bfeof(expect)) { ca = bfgetc(actual); ce = bfgetc(expect); if (ca == ce) match++; else { printd(LEVEL_WARNING, "warning: byte at 0x%04X is different (got 0x%02X, expected 0x%02X)!\n", bftell(actual), ca, ce); unmatch++; } } else if (!bfeof(actual)) { ca = bfgetc(actual); printd(LEVEL_ERROR, "error: actual output contained trailing byte 0x%02X.\n", (unsigned char)ca); unmatch++; } else if (!bfeof(expect)) { ce = bfgetc(expect); printd(LEVEL_ERROR, "error: expected actual output to contain 0x%02X.\n", (unsigned char)ce); unmatch++; } else break; } if (unmatch > 0) { printd(LEVEL_ERROR, "error: actual output differs from expected output in content (%f%%, %i bytes different).\n", 100.f / (unmatch + match) * unmatch, unmatch); if (bftell(actual) != bftell(expect)) printd(LEVEL_ERROR, "error: actual output differs from expected output in length (%i bytes larger).\n", bftell(actual) - bftell(expect)); bfclose(actual); bfclose(expect); return 1; } // Close files and delete actual because we have // succeeded. bfclose(actual); bfclose(expect); unlink(actual_file->filename[0]); return 0; }