Ejemplo n.º 1
0
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).");
	}
}
Ejemplo n.º 2
0
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);

}
Ejemplo n.º 4
0
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);

}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 8
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;
	}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
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(&current_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);
}
Ejemplo n.º 11
0
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;
}