示例#1
0
文件: chat.c 项目: prodigeni/toxic
void kill_chat_window(ToxWindow *self)
{
    ChatContext *ctx = self->chatwin;
    StatusBar *statusbar = self->stb;

    log_disable(ctx->log);
    line_info_cleanup(ctx->hst);

#ifdef _AUDIO
    stop_current_call(self);
#endif

    delwin(ctx->linewin);
    delwin(ctx->history);
    delwin(statusbar->topline);

    free(ctx->log);
    free(ctx->hst);
    free(ctx);
    free(self->help);
    free(statusbar);

    disable_chatwin(self->num);
    del_window(self);
}
示例#2
0
文件: log.c 项目: privacee/toxic
void log_enable(char *name, const char *selfkey, const char *otherkey, struct chatlog *log, int logtype)
{
    log->log_on = true;

    if (log->file != NULL)
        return;

    if (init_logging_session(name, selfkey, otherkey, log, logtype) == -1)
        log_disable(log);
}
示例#3
0
文件: cpu.c 项目: jakubfi/em400
// -----------------------------------------------------------------------
int ectl_log_state_set(int state)
{
	int res = -1;
	LOG(L_ECTL, "ECTL log state set: %i", state);
	if (state == ECTL_OFF) {
		log_disable();
		res = 0;
	} else if (state == ECTL_ON) {
		res = log_enable();
	}
	return res;
}
示例#4
0
END_TEST

START_TEST (check_mail_headers_s) {

	log_disable();
	bool_t result = true;
	stringer_t *errmsg = MANAGEDBUF(1024);

	if (status()) result = check_mail_headers_sthread(errmsg);

	log_test("MAIL / HEADERS / SINGLE THREADED:", errmsg);
	ck_assert_msg(result, st_char_get(errmsg));
}
示例#5
0
文件: groupchat.c 项目: subliun/toxic
static void kill_groupchat_window(ToxWindow *self)
{
    ChatContext *ctx = self->chatwin;

    log_disable(ctx->log);
    line_info_cleanup(ctx->hst);
    delwin(ctx->linewin);
    delwin(ctx->history);
    delwin(ctx->sidebar);
    free(ctx->log);
    free(ctx);
    free(self->help);
    del_window(self);
}
示例#6
0
END_TEST

START_TEST (check_mail_store_s) {

	log_disable();
	bool_t result = true;
	stringer_t *errmsg = MANAGEDBUF(1024);

	if (status()) result = check_mail_store_plaintext_sthread(errmsg);
	if (status() && result) result = check_mail_store_encrypted_sthread(errmsg);

	log_test("MAIL / STORE / SINGLE THREADED:", errmsg);
	ck_assert_msg(result, st_char_get(errmsg));
}
示例#7
0
void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
    const char *msg;
    struct chatlog *log = self->chatwin->log;

    if (argc == 0) {
        if (log->log_on)
            msg = "Logging for this window is ON; type \"/log off\" to disable. (Logs are not encrypted)";
        else
            msg = "Logging for this window is OFF; type \"/log on\" to enable.";

        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
        return;
    }

    const char *swch = argv[1];

    if (!strcmp(swch, "1") || !strcmp(swch, "on")) {
        char myid[TOX_ADDRESS_SIZE];
        tox_self_get_address(m, (uint8_t *) myid);

        int log_ret = -1;

        if (self->is_chat) {
            Friends.list[self->num].logging_on = true;
            log_ret = log_enable(self->name, myid, Friends.list[self->num].pub_key, log, LOG_CHAT);
        } else if (self->is_prompt) {
            log_ret = log_enable(self->name, myid, NULL, log, LOG_PROMPT);
        } else if (self->is_groupchat) {
            log_ret = log_enable(self->name, myid, NULL, log, LOG_GROUP);
        }

        msg = log_ret == 0 ? "Logging enabled." : "Warning: Log failed to initialize.";
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
        return;
    } else if (!strcmp(swch, "0") || !strcmp(swch, "off")) {
        if (self->is_chat)
            Friends.list[self->num].logging_on = false;

        log_disable(log);

        msg = "Logging disabled.";
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
        return;
    }

    msg = "Invalid option. Use \"/log on\" and \"/log off\" to toggle logging.";
    line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
}
示例#8
0
文件: log.c 项目: saper/em400
// -----------------------------------------------------------------------
void log_shutdown()
{
	int i;

	if (!log_initialized) return;

	emdas_destroy(emd);

	for (i=0 ; i<L_ALL; i++) {
		atom_store_release(&log_components[i].thr, 0);
	}

	log_disable();
	log_crk_shutdown();
	free(log_file);
}
示例#9
0
void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
    char *msg;
    struct chatlog *log = self->chatwin->log;

    if (argc == 0) {
        if (log->log_on)
            msg = "Logging for this window is ON. Type \"/log off\" to disable.";
        else
            msg = "Logging for this window is OFF. Type \"/log on\" to enable.";

        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
        return;
    }

    char *swch = argv[1];

    if (!strcmp(swch, "1") || !strcmp(swch, "on")) {

        if (self->is_chat) {
            friends[self->num].logging_on = true;
            log_enable(self->name, friends[self->num].pub_key, log);
        } else if (self->is_prompt) {
            char myid[TOX_FRIEND_ADDRESS_SIZE];
            tox_get_address(m, (uint8_t *) myid);
            log_enable(self->name, myid, log);
        } else if (self->is_groupchat) {
            log_enable(self->name, NULL, log);
        }

        msg = "Logging enabled";
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
        return;
    } else if (!strcmp(swch, "0") || !strcmp(swch, "off")) {
        if (self->is_chat)
            friends[self->num].logging_on = false;

        log_disable(log);

        msg = "Logging disabled";
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
        return;
    }

    msg = "Invalid option. Use \"/log on\" and \"/log off\" to toggle logging.";
    line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
}
示例#10
0
文件: main.c 项目: Jman012/toxic
void exit_toxic(Tox *m)
{
    store_data(m, DATA_FILE);
    close_all_file_senders();
    kill_all_windows();
    log_disable(prompt->promptbuf->log);
    free(DATA_FILE);
    free(prompt->stb);
    free(prompt->promptbuf->log);
    free(prompt->promptbuf);
    tox_kill(m);
    #ifdef _SUPPORT_AUDIO
    terminate_audio(prompt, av);
    #endif /* _SUPPORT_AUDIO */
    endwin();
    exit(EXIT_SUCCESS);
}
示例#11
0
文件: prompt.c 项目: SmoothDude/toxic
void kill_prompt_window(ToxWindow *self)
{
    ChatContext *ctx = self->chatwin;
    StatusBar *statusbar = self->stb;

    log_disable(ctx->log);
    line_info_cleanup(ctx->hst);

    delwin(ctx->linewin);
    delwin(ctx->history);
    delwin(statusbar->topline);

    free(ctx->log);
    free(ctx);
    free(self->help);
    free(statusbar);

    del_window(self);
}
示例#12
0
文件: main.c 项目: stqism/toxic
void exit_toxic(Tox *m)
{
    store_data(m, DATA_FILE);
    close_all_file_senders();
    kill_all_windows();
    log_disable(prompt->chatwin->log);
    line_info_cleanup(prompt->chatwin->hst);
    free(DATA_FILE);
    free(prompt->stb);
    free(prompt->chatwin->log);
    free(prompt->chatwin->hst);
    free(prompt->chatwin);
    tox_kill(m);
    #ifdef _SUPPORT_AUDIO
    terminate_audio();
    #endif /* _SUPPORT_AUDIO */
    endwin();
    exit(EXIT_SUCCESS);
}
示例#13
0
文件: log.c 项目: cnhenry/toxic
/* renames chatlog file replacing src with dest.
   Returns 0 on success or if no log exists, -1 on failure. */
int rename_logfile(char *src, char *dest, const char *selfkey, const char *otherkey, int winnum)
{
    ToxWindow *toxwin = get_window_ptr(winnum);
    struct chatlog *log = NULL;
    bool log_on = false;

    /* disable log if necessary and save its state */
    if (toxwin != NULL) {
        log = toxwin->chatwin->log;
        log_on = log->log_on;
    }

    if (log_on)
        log_disable(log);

    char newpath[MAX_STR_SIZE];
    char oldpath[MAX_STR_SIZE];

    if (get_log_path(oldpath, sizeof(oldpath), src, selfkey, otherkey, LOG_CHAT) == -1)
        goto on_error;

    if (!file_exists(oldpath))
        return 0;

    if (get_log_path(newpath, sizeof(newpath), dest, selfkey, otherkey, LOG_CHAT) == -1)
        goto on_error;

    if (rename(oldpath, newpath) != 0)
        goto on_error;

    if (log_on)
        log_enable(dest, selfkey, otherkey, log, LOG_CHAT);

    return 0;

on_error:
    if (log_on)
        log_enable(src, selfkey, otherkey, log, LOG_CHAT);

    return -1;
}
示例#14
0
bool load_log_settings(const char *filename) {
    //this is a terrible algorithm, but im lazy today
    FILE *f = fopen(filename, "r");
    if(f == NULL)
        return false;
    char linebuf[512], type_name[256], value[256];
    while(!feof(f)) {
        if(fgets(linebuf, 512, f) == NULL)
            continue;
#ifdef WIN32
        if (sscanf(linebuf, "%[^=]=%[^\n]\n", type_name, value) != 2)
            continue;
#else
        if (sscanf(linebuf, "%[^=]=%[^\r\n]\n", type_name, value) != 2)
            continue;
#endif

        if(type_name[0] == '\0' || type_name[0] == '#')
            continue;

        //first make sure we understand the value
        bool enabled;
        if(!strcasecmp(value, "on") || !strcasecmp(value, "yes") || !strcasecmp(value, "enabled") || !strcmp(value, "1"))
            enabled = true;
        else if(!strcasecmp(value, "off") || !strcasecmp(value, "no") || !strcasecmp(value, "disabled") || !strcmp(value, "0"))
            enabled = false;
        else {
            printf("Unable to parse value '%s' from %s. Skipping line.", value, filename);
            continue;
        }

        int r;
        //first see if it is a category name
        for(r = 0; r < NUMBER_OF_LOG_CATEGORIES; r++) {
            if(!strcasecmp(log_category_names[r], type_name))
                break;
        }
        if(r != NUMBER_OF_LOG_CATEGORIES) {
            //matched a category.
            int k;
            for(k = 0; k < NUMBER_OF_LOG_TYPES; k++) {
                if(log_type_info[k].category != r)
                    continue;   //does not match this category.
                if(enabled)
                    log_enable(LogType(k));
                else
                    log_disable(LogType(k));
            }
            continue;
        }

        for(r = 0; r < NUMBER_OF_LOG_TYPES; r++) {
            if(!strcasecmp(log_type_info[r].name, type_name))
                break;
        }
        if(r == NUMBER_OF_LOG_TYPES) {
            printf("Unable to locate log type %s from file %s. Skipping line.", type_name, filename);
            continue;
        }

        //got it all figured out, do something now...
        if(enabled)
            log_enable(LogType(r));
        else
            log_disable(LogType(r));
    }
    fclose(f);
    return true;
}
示例#15
0
int main(void) {

	if (!mm_sec_start()) {

		log_print("Secure memory pool did not start correctly.");
		return 1;
	}

	else if (sizeof(stringer_t) != 4) {

		log_print("The string options variable should be 4 bytes/32 bits.");
		return 1;
	}

	/*chr_t *data = "Hello world.";
	size_t len = ns_length_get(data);
	stringer_t *place =
		PLACER(data, len);

	log_print("%.*s\n%.*s\n", st_length_int(PLACER(data, len)), st_char_get(PLACER(data, len)),	st_length_int((stringer_t *)place), st_char_get((stringer_t *)place));
	if (st_cmp_cs_eq(PLACER(st_data_get(constant), st_length_get(constant)), constant) || memcmp("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", st_data_get(constant), st_length_get(constant)))
		exit(1);*/

	// Since were intentionally going to trigger errors, disable standard out while doing so.
	log_disable();
	// Check that we can't specify a length greater than the available buffer.
	if (!check_string_logic(MANAGED_T | CONTIGUOUS | HEAP) || !check_string_logic(MANAGED_T | JOINTED | HEAP)	|| !check_string_logic(MAPPED_T | JOINTED | HEAP)) {
		log_print("--------------------------------------- LOGIC -------------------------------------------\n");
		log_print("String logic checks failed.");
		return 1;
	}
	log_enable();

	log_print("--------------------------------------- CONSTANT ----------------------------------------\n%28.28s = %.*s",
			"constant[fixed+contiguous]", st_length_int(constant), st_char_get(constant));

	log_print("--------------------------------------- IMPORT ------------------------------------------");
	if (!check_string_import()) {
		log_print("Import check failed.");
		return 1;
	}

	// Begin allocation checks.
	log_print("--------------------------------------- ALLOCATION --------------------------------------");

	if (!check_string_alloc("nuller[heap+contiguous]", NULLER_T | CONTIGUOUS | HEAP) || !check_string_alloc("block[heap+contiguous]", BLOCK_T | CONTIGUOUS | HEAP)
			|| !check_string_alloc("managed[heap+contiguous]", MANAGED_T | CONTIGUOUS | HEAP)) {
		log_print("Standard allocation checks failed.");
		return 1;
	}

	if (!check_string_alloc("nuller[heap+jointed]", NULLER_T | JOINTED | HEAP) || !check_string_alloc("block[heap+jointed]", BLOCK_T | JOINTED | HEAP)
			|| !check_string_alloc("managed[heap+jointed]", MANAGED_T | JOINTED | HEAP) || !check_string_alloc("mapped[heap+jointed]", MAPPED_T | JOINTED | HEAP)) {
		log_print("Jointed allocation checks failed.");
		return 1;
	}

	if (!check_string_alloc("nuller[secure+contiguous]", NULLER_T | CONTIGUOUS | SECURE) || !check_string_alloc("block[secure+contiguous]", BLOCK_T | CONTIGUOUS | SECURE)
			|| !check_string_alloc("managed[secure+contiguous]", MANAGED_T | CONTIGUOUS | SECURE)) {
		log_print("Secure allocation of contiguous types failed.");
		return 1;
	}

	if (!check_string_alloc("nuller[secure+jointed]", NULLER_T | JOINTED | SECURE) || !check_string_alloc("block[secure+jointed]", BLOCK_T | JOINTED | SECURE)
			|| !check_string_alloc("managed[secure+jointed]", MANAGED_T | JOINTED | SECURE) || !check_string_alloc("mapped[secure+jointed]", MAPPED_T | JOINTED | SECURE)) {
		log_print("Secure allocation of jointed types failed.");
		return 1;
	}

	// Begin reallocation checks.
	log_print("-------------------------------------- REALLOCATION -------------------------------------");

	if (!check_string_realloc("nuller[heap+contiguous]", NULLER_T | CONTIGUOUS | HEAP) || !check_string_realloc("block[heap+contiguous]", BLOCK_T | CONTIGUOUS | HEAP)
			|| !check_string_realloc("managed[heap+contiguous]", MANAGED_T | CONTIGUOUS | HEAP)) {
		log_print("Standard reallocation checks failed.");
		return 1;
	}

	if (!check_string_realloc("nuller[heap+jointed]", NULLER_T | JOINTED | HEAP) || !check_string_realloc("block[heap+jointed]", BLOCK_T | JOINTED | HEAP)
			|| !check_string_realloc("managed[heap+jointed]", MANAGED_T | JOINTED | HEAP) || !check_string_realloc("mapped[heap+jointed]", MAPPED_T | JOINTED | HEAP)) {
		log_print("Jointed reallocation checks failed.");
		return 1;
	}

	if (!check_string_realloc("nuller[secure+contiguous]", NULLER_T | CONTIGUOUS | SECURE) || !check_string_realloc("block[secure+contiguous]", BLOCK_T | CONTIGUOUS
			| SECURE) || !check_string_realloc("managed[secure+contiguous]", MANAGED_T | CONTIGUOUS | SECURE)) {
		log_print("Secure reallocation of contiguous types failed.");
		return 1;
	}

	if (!check_string_realloc("nuller[secure+jointed]", NULLER_T | JOINTED | SECURE) || !check_string_realloc("block[secure+jointed]", BLOCK_T | JOINTED | SECURE)
			|| !check_string_realloc("managed[secure+jointed]", MANAGED_T | JOINTED | SECURE) || !check_string_realloc("mapped[secure+jointed]", MAPPED_T | JOINTED | SECURE)) {
		log_print("Secure reallocation of jointed types failed.");
		return 1;
	}

	// Begin duplication checks.
	log_print("-------------------------------------- DUPLICATION --------------------------------------");

	if (!check_string_dupe("nuller[heap+contiguous]", NULLER_T | CONTIGUOUS | HEAP) || !check_string_dupe("block[heap+contiguous]", BLOCK_T | CONTIGUOUS | HEAP)
			|| !check_string_dupe("managed[heap+contiguous]", MANAGED_T | CONTIGUOUS | HEAP)) {
		log_print("Standard duplication checks failed.");
		return 1;
	}

	if (!check_string_dupe("nuller[heap+jointed]", NULLER_T | JOINTED | HEAP) || !check_string_dupe("block[heap+jointed]", BLOCK_T | JOINTED | HEAP) || !check_string_dupe(
			"managed[heap+jointed]", MANAGED_T | JOINTED | HEAP) || !check_string_dupe("mapped[heap+jointed]", MAPPED_T | JOINTED | HEAP)) {
		log_print("Jointed duplication checks failed.");
		return 1;
	}

	if (!check_string_dupe("nuller[secure+contiguous]", NULLER_T | CONTIGUOUS | SECURE) || !check_string_dupe("block[secure+contiguous]", BLOCK_T | CONTIGUOUS | SECURE)
			|| !check_string_dupe("managed[secure+contiguous]", MANAGED_T | CONTIGUOUS | SECURE)) {
		log_print("Secure duplication of contiguous types failed.");
		return 1;
	}

	if (!check_string_dupe("nuller[secure+jointed]", NULLER_T | JOINTED | SECURE) || !check_string_dupe("block[secure+jointed]", BLOCK_T | JOINTED | SECURE)
			|| !check_string_dupe("managed[secure+jointed]", MANAGED_T | JOINTED | SECURE) || !check_string_dupe("mapped[secure+jointed]", MAPPED_T | JOINTED | SECURE)) {
		log_print("Secure duplication of jointed types failed.");
		return 1;
	}

	log_print("-------------------------------------- MERGE --------------------------------------------");
	if (!check_string_merge()) {
		log_print("The merge function failed.");
		return 1;
	}

	log_print("-------------------------------------- PRINT --------------------------------------------");
	if (!check_string_print()) {
		log_print("The print function failed.");
		return 1;
	}

	mm_sec_stop();
	log_print("---------------------------------------- FINISHED ---------------------------------------");
	return 0;
}
int main (int argc, char **argv)
{
	int c, i;
	opterr = 0;
	bool iactive = false;
	
	strcpy (homedir, argv[0]);
	for (i = strlen (homedir)-1; i >= 0; i--)
	{
		bool ended = false;
		if (homedir[i] == '/') ended = true;
		homedir[i] = '\0';
		if (ended) break;
	}

	strcpy (demuxer, DEFAULT_DEMUXER);
	strcpy (provider, DEFAULT_OTV_PROVIDER);

	while ((c = getopt (argc, argv, "h:d:x:l:p:k:riyz")) != -1)
	{
		switch (c)
		{
			case 'd':
				db_root = optarg;
				break;
			case 'x':
				strcpy (demuxer, optarg);
				break;
			case 'l':
				strcpy (homedir, optarg);
				break;
			case 'i':
				printf ("WARNING! Option -i is deprecated\n");
				break;
			case 'p':
				strcpy (provider, optarg);
				break;
			case 'k':
				nice (atoi(optarg));
				break;
			case 'r':
				log_disable ();
				interactive_enable ();
				iactive = true;
				break;
			case 'y':
				huffman_debug_summaries = true;
				break;
			case 'z':
				huffman_debug_titles = true;
				break;
			case '?':
				printf ("Usage:\n");
				printf ("  ./crossepg_downloader [options]\n");
				printf ("Options:\n");
				printf ("  -d db_root    crossepg db root folder\n");
				printf ("                default: %s\n", db_root);
				printf ("  -x demuxer    dvb demuxer\n");
				printf ("                default: %s\n", demuxer);
				printf ("  -l homedir    home directory\n");
				printf ("                default: %s\n", homedir);
				printf ("  -p provider   opentv provider\n");
				printf ("                default: %s\n", provider);
				printf ("  -k nice       see \"man nice\"\n");
				printf ("  -r            interactive mode\n");
				printf ("  -y            debug mode for huffman dictionary (summaries)\n");
				printf ("  -z            debug mode for huffman dictionary (titles)\n");
				printf ("  -h            show this help\n");
				return 0;
		}
	}
	
	while (homedir[strlen (homedir) - 1] == '/') homedir[strlen (homedir) - 1] = '\0';
	while (db_root[strlen (db_root) - 1] == '/') db_root[strlen (db_root) - 1] = '\0';
	
	mkdir (db_root, S_IRWXU|S_IRWXG|S_IRWXO);
	
	log_open (db_root);
	log_banner ("CrossEPG Downloader");

	xmltv_encodings_init ();

	if (iactive) interactive_manager ();
	else
	{
		char opentv_file[256];

		sprintf (opentv_file, "%s/providers/%s.conf", homedir, provider);
		if (providers_read (opentv_file))
		{
			if (providers_get_protocol () == 1)
			{
				log_add ("Provider %s identified as opentv", provider);
				if (!db_load ())
					goto error;
				download_opentv ();
				if (epgdb_save (NULL)) log_add ("Data saved");
				else log_add ("Error saving data");
				db_close ();
			}
			else if (providers_get_protocol () == 2)
			{
				log_add ("Provider %s identified as xmltv", provider);
				log_add ("Preferred language: %s", providers_get_xmltv_plang ());
				if (!db_load ())
					goto error;

				xmltv_channels_init ();
				for (i=0; i<10; i++)
				{
					if (strlen(providers_get_xmltv_channels (i)) == 0)
					{
						log_add ("No more url available");
						log_add ("Error downloading/parsing channels file");
						goto error;
					}
					log_add ("Download channels from url: %s (%d)", providers_get_xmltv_channels (i), i);
					if (xmltv_downloader_channels (providers_get_xmltv_channels (i), db_root, NULL, NULL, &stop))
						break;
				}

				xmltv_parser_set_iso639 (providers_get_xmltv_plang ());
				for (i=0; i<10; i++)
				{
					if (strlen(providers_get_xmltv_url (i)) == 0)
					{
						log_add ("No more url available");
						log_add ("Error downloading/parsing events file");
						goto error;
					}
					log_add ("Download events from url: %s", providers_get_xmltv_url (i));
					if (xmltv_downloader_events (providers_get_xmltv_url (i), db_root, NULL, NULL, &stop))
					{
						if (epgdb_save (NULL)) log_add ("Data saved");
						else log_add ("Error saving data");
						break;
					}
				}
				xmltv_channels_cleanup ();
				db_close ();
			}
			else if (providers_get_protocol () == 3)
			{
				log_add ("Provider %s identified as xepgdb", provider);
				log_add ("Headers url: %s", providers_get_xepgdb_headers_url ());
				log_add ("Descriptors url: %s", providers_get_xepgdb_descriptors_url ());

				if (!db_load ())
					goto error;
				if (dbmerge_downloader (providers_get_xepgdb_headers_url (), providers_get_xepgdb_descriptors_url (), db_root, NULL, NULL, &stop))
				{
					if (epgdb_save (NULL)) log_add ("Data saved");
					else log_add ("Error saving data");
				}
				else
					log_add ("Error downloading/parsing xepgdb files");
				db_close ();
			}
			else if (providers_get_protocol () == 4)
			{
				char filename[1024], tmp[1024], *tmp2;
				log_add ("Provider %s identified as script", provider);
				log_add ("Script file name: %s", providers_get_script_filename ());

				tmp2 = replace_str (providers_get_script_arguments (), "%%dbroot%%", db_root);
				strcpy (tmp, tmp2);
				tmp2 = replace_str (tmp, "%%homedir%%", homedir);
				sprintf (filename, "LD_LIBRARY_PATH=%s %s/scripts/%s %s", homedir, homedir, providers_get_script_filename (), tmp2);

				log_add ("Executing script %s ...", filename);
				system (filename);
				log_add ("Script terminated");
			}
		}
		else
			log_add ("Cannot load provider configuration (%s)", opentv_file);
	}
	
	memory_stats ();
error:
	log_close ();
	return 0;
}
int main (int argc, char **argv)
{
	int c, i;
	opterr = 0;
	bool iactive = false;

	strcpy (homedir, argv[0]);
	for (i = strlen (homedir)-1; i >= 0; i--)
	{
		bool ended = false;
		if (homedir[i] == '/') ended = true;
		homedir[i] = '\0';
		if (ended) break;
	}
	
	sprintf (db_root, DEFAULT_DB_ROOT);
	sprintf (import_root, DEFAULT_IMPORT_ROOT);
	
	while ((c = getopt (argc, argv, "d:i:l:k:r")) != -1)
	{
		switch (c)
		{
			case 'd':
				strcpy (db_root, optarg);
				break;
			case 'l':
				strcpy (homedir, optarg);
				break;
			case 'i':
				strcpy (import_root, optarg);
				break;
			case 'k':
				nice (atoi(optarg));
				break;
			case 'r':
				log_disable ();
				interactive_enable ();
				iactive = true;
				break;
			case '?':
				printf ("Usage:\n");
				printf ("  ./crossepg_importer [options]\n");
				printf ("Options:\n");
				printf ("  -d db_root       crossepg db root folder\n");
				printf ("                   default: %s\n", db_root);
				printf ("  -l homedir       home directory\n");
				printf ("                   default: %s\n", homedir);
				printf ("  -i import_root   import root folder\n");
				printf ("                   default: %s\n", import_root);
				printf ("  -k nice          see \"man nice\"\n");
				printf ("  -r               interactive mode\n");
				printf ("  -h               show this help\n");
				return 0;
		}
	}
	
	while (homedir[strlen (homedir) - 1] == '/') homedir[strlen (homedir) - 1] = '\0';
	while (db_root[strlen (db_root) - 1] == '/') db_root[strlen (db_root) - 1] = '\0';
	while (import_root[strlen (import_root) - 1] == '/') import_root[strlen (import_root) - 1] = '\0';
	
	log_open (db_root);
	log_banner ("CrossEPG Importer");

	sprintf (import_homedir, "%s/import/", homedir);
	
	if (epgdb_open (db_root)) log_add ("EPGDB opened");
	else
	{
		log_add ("Error opening EPGDB");
		epgdb_close ();
		log_close ();
		return 0;
	}
	epgdb_load ();
	
	aliases_make (homedir);
	
	if (iactive) interactive_manager ();
	else
	{
		volatile bool useless = false;
		importer_parse_directory (import_root, db_root, NULL, NULL, NULL, &useless);
		importer_parse_directory (import_homedir, db_root, NULL, NULL, NULL, &useless);
		
		log_add ("Saving data...");
		if (epgdb_save (NULL)) log_add ("Data saved");
		else log_add ("Error saving data");
	}
	
	epgdb_clean ();
	memory_stats ();
	log_close ();
	return 0;
}