/* * hotlist.c: Routines to deal with the list of favourite VTX-pages * * $Id: hotlist.c,v 1.4 1997/09/14 01:43:03 mb Exp mb $ * * Copyright (c) 1994-96 Martin Buck * Read COPYING for more information * */ #include #include #include #include #include #include "safe_malloc.h" #include "tilde.h" #include "misc.h" #include "config.h" #include "vtxtools.h" #include "vtxqueue.h" #include "toptext.h" #include "search.h" #include "hotlist.h" #define TIMEOUT_DEFAULT 60 #define INTERLEAVE_DEFAULT 25 #define LOOKAHEAD_DEFAULT 2 #define EXPIRE_DEFAULT (7 * 24) #define HOTLIST_FNAME "vtx-hotlist" #define TOKEN_MAXLEN 500 typedef struct { char name[STATIONNAME_MAXLEN + 1], header[STATIONNAME_MAXLEN + 1]; char *inc_list, *ex_list, *channel; int count, *pages, page_timeout, top_interleave, lookahead, index_page, expire, freq, prog; int search_count; tt_pageclass_t search_level; search_data_t *search_data; unsigned top_disable : 1; unsigned fast_disable : 1; unsigned readspool : 1; unsigned writespool : 1; } hotlist_t; static int hotlist_count, station_changed = TRUE; static hotlist_t *hotlist, *current; static char sp_list[800]; static int parse_spool_list(char *list, const char *str, int newval) { char *tmp_str, *tokarg, *token, tmp_chr; unsigned int page1, page2; if (newval && list) { if (strpbrk(str, "0123456789,-")) { memset(list, FALSE, 800); /* If include-list is empty, the default is to */ } else { /* spool all pages, otherwise only spool pages */ memset(list, TRUE, 800); /* in include-list */ } } tokarg = tmp_str = sstrdup(str); while ((token = strtok(tokarg, ","))) { tokarg = NULL; if (sscanf(token, " %u - %u ", &page1, &page2) != 2) { if (sscanf(token, " %u %c", &page1, &tmp_chr) != 1) { page1 = 0; } else { page2 = page1; } } if (page1 < 100 || page1 > 899 || page2 < 100 || page2 > 899 || page1 > page2) { return FALSE; } if (list) { memset(list + page1 - 100, newval, page2 - page1 + 1); } } free(tmp_str); return TRUE; } static int hotlist_load(const char *fname) { char line[256], token[TOKEN_MAXLEN + 1], valstr[HOTLIST_VALUE_MAXLEN + 1]; char tmpstr[HOTLIST_VALUE_MAXLEN + 1], sep[2]; int err, entry, stfound = 0, lcount = 0, ssfound = FALSE, tmpval, invalid, syntax; FILE *file; hotlist_t *newentry = NULL; if (!(file = fopen(fname, "r"))) return -1; while (1) { if (!fgets(line, sizeof(line), file)) { if (feof(file)) break; err = errno; fclose(file); errno = err; return -1; } lcount++; tmpstr[0] = valstr[0] = '\0'; invalid = syntax = FALSE; if (line[0] == '#' || sscanf(line, " %c ", token) <= 0) { /* Skip comments or empty lines */ continue; } else if (sscanf(line, " station %" STRINGIFY(STATIONNAME_MAXLEN) "[^\n\r] ", tmpstr) == 1) { stfound = 2; ssfound = FALSE; newentry = NULL; for (entry = 0; entry < hotlist_count; entry++) { if (!strcmp(tmpstr, hotlist[entry].name)) { newentry = hotlist + entry; break; } } if (newentry) continue; hotlist_count++; hotlist = current = srealloc(hotlist, hotlist_count * sizeof(hotlist_t)); newentry = hotlist + hotlist_count - 1; *newentry = hotlist[0]; strcpy(newentry->name, tmpstr); strcpy(newentry->header, tmpstr); newentry->pages = smalloc(sizeof(int)); newentry->count = 0; newentry->inc_list = sstrdup(hotlist[0].inc_list); newentry->ex_list = sstrdup(hotlist[0].ex_list); newentry->channel = sstrdup(hotlist[0].channel); if (hotlist[0].search_count) { newentry->search_data = smalloc(hotlist[0].search_count * sizeof(search_data_t)); memcpy(newentry->search_data, hotlist[0].search_data, hotlist[0].search_count * sizeof(search_data_t)); } } else if (stfound != 2) { /* Ignore line if no station was given, but print warning only once */ if (!stfound) { fprintf(stderr, "%s:%d: Warning: Missing station-name, succeeding entries ignored.\n", fname, lcount); stfound = 1; } } else if (sscanf(line, " %" STRINGIFY(TOKEN_MAXLEN) "[^\1- =] %1[=] %" STRINGIFY(HOTLIST_VALUE_MAXLEN) "[^\1-\37] ", token, sep, valstr) >= 2) { if (config_parse_int(token, valstr, "page_timeout", 10, 180, 10, &tmpval, &invalid)) { newentry->page_timeout = tmpval; } else if (config_parse_int(token, valstr, "top_interleave", -100, 100, 10, &tmpval, &invalid)) { newentry->top_interleave = tmpval; } else if (config_parse_int(token, valstr, "page_lookahead", 0, 5, 10, &tmpval, &invalid)) { newentry->lookahead = tmpval; } else if (config_parse_bool(token, valstr, "top_disable", &tmpval, &invalid)) { newentry->top_disable = tmpval; } else if (config_parse_bool(token, valstr, "fast_disable", &tmpval, &invalid)) { newentry->fast_disable = tmpval; } else if (config_parse_int(token, valstr, "index_page", 0x100, 0x8ff, 16, &tmpval, &invalid)) { if (!vtx_chkpgnum(tmpval, TRUE)) { invalid = TRUE; } else { newentry->index_page = tmpval; } } else if (config_parse_int(token, valstr, "expire", 0, 99 * 24 + 23, 10, &tmpval, &invalid)) { newentry->expire = tmpval; } else if (config_parse_int(token, valstr, "frequency", 0, INT_MAX, 10, &tmpval, &invalid)) { newentry->freq = tmpval; } else if (config_parse_int(token, valstr, "program", 0, INT_MAX, 10, &tmpval, &invalid)) { newentry->prog = tmpval; } else if (config_parse_bool(token, valstr, "read_spooldir", &tmpval, &invalid)) { newentry->readspool = tmpval; } else if (config_parse_bool(token, valstr, "write_spooldir", &tmpval, &invalid)) { newentry->writespool = tmpval; } else if (!strcasecmp(token, "header")) { if (strlen(valstr) > STATIONNAME_MAXLEN) { valstr[STATIONNAME_MAXLEN] = '\0'; fprintf(stderr, "%s:%d: Warning: Entry too long, header name truncated.\n", fname, lcount); } strcpy(newentry->header, valstr); } else if (!strcasecmp(token, "channel")) { free(newentry->channel); newentry->channel = sstrdup(valstr); } else if (!strcasecmp(token, "auto_search_pages")) { for (entry = TT_NONE; entry < TT_COUNT; entry++) { if (!strcasecmp(valstr, tt_pageclass_str[entry])) { newentry->search_level = entry; break; } } if (entry >= TT_COUNT) { invalid = TRUE; } } else if (!strcasecmp(token, "include_pages")) { if (parse_spool_list(NULL, valstr, TRUE)) { free(newentry->inc_list); newentry->inc_list = sstrdup(valstr); } else { invalid = TRUE; } } else if (!strcasecmp(token, "exclude_pages")) { if (parse_spool_list(NULL, valstr, FALSE)) { free(newentry->ex_list); newentry->ex_list = sstrdup(valstr); } else { invalid = TRUE; } } else if (!strcasecmp(token, "search_str")) { search_data_t *dat; ssfound = TRUE; newentry->search_data = srealloc(newentry->search_data, (++newentry->search_count * sizeof(search_data_t))); dat = &newentry->search_data[newentry->search_count - 1]; dat->str = sstrdup(valstr); dat->case_sens = FALSE; dat->is_regexp = FALSE; dat->whole_words = FALSE; dat->multi_line = FALSE; dat->bell = FALSE; } else if (!strcasecmp(token, "search_flags")) { if (!ssfound) { invalid = TRUE; } else { search_data_t *dat; char *flagstr; dat = &newentry->search_data[newentry->search_count - 1]; strcpy(tmpstr, valstr); flagstr = strtok(tmpstr, ", \t"); while (flagstr) { if (!strcasecmp(flagstr, "case_sens")) { dat->case_sens = TRUE; } else if (!strcasecmp(flagstr, "is_regexp")) { dat->is_regexp = TRUE; } else if (!strcasecmp(flagstr, "whole_words")) { dat->whole_words = TRUE; } else if (!strcasecmp(flagstr, "multi_line")) { dat->multi_line = TRUE; } else if (!strcasecmp(flagstr, "bell")) { dat->bell = TRUE; } else { invalid = TRUE; } flagstr = strtok(NULL, ", \t"); } } } else { syntax = TRUE; } } else if (sscanf(line, " %x ", &tmpval) == 1) { if (!vtx_chkpgnum(tmpval, TRUE)) { invalid = TRUE; } else { newentry->pages = srealloc(newentry->pages, (newentry->count + 2) * sizeof(int)); newentry->pages[newentry->count++] = tmpval; } } else { syntax = TRUE; } if (syntax) { fprintf(stderr, "%s:%d: Warning: Syntax error, line ignored:\n%s\n", fname, lcount, line); } else if (invalid) { fprintf(stderr, "%s:%d: Warning: Invalid value, line ignored:\n%s\n", fname, lcount, line); } } return fclose(file); } void hotlist_init(void) { char *hl_fname; hotlist = current = smalloc(1 * sizeof(hotlist_t)); strcpy(hotlist[0].name, "Unknown"); strcpy(hotlist[0].header, ""); hotlist[0].pages = smalloc(sizeof(int)); hotlist[0].count = 0; hotlist[0].page_timeout = TIMEOUT_DEFAULT; hotlist[0].top_interleave = INTERLEAVE_DEFAULT; hotlist[0].lookahead = LOOKAHEAD_DEFAULT; hotlist[0].top_disable = FALSE; hotlist[0].fast_disable = TRUE; hotlist[0].index_page = 0x100; hotlist[0].search_level = TT_NORM; hotlist[0].readspool = hotlist[0].writespool = TRUE; hotlist[0].expire = EXPIRE_DEFAULT; hotlist[0].channel = sstrdup(""); hotlist[0].freq = 0; hotlist[0].prog = 0; hotlist[0].inc_list = sstrdup(""); hotlist[0].ex_list = sstrdup(""); hotlist[0].search_count = 0; hotlist[0].search_data = NULL; hotlist_count = 1; memset(sp_list, TRUE, sizeof(sp_list)); if (hotlist_load(VTX_LIBDIR "/" HOTLIST_FNAME) && errno != ENOENT) { fprintf(stderr, "%s: " VTX_LIBDIR "/" HOTLIST_FNAME ": %s\n", smalloc_progname, strerror(errno)); exit(1); } hl_fname = sstrdup("~/." HOTLIST_FNAME); if (tilde_expand_realloc(&hl_fname) >= 0) { if (hotlist_load(hl_fname) && errno != ENOENT) { fprintf(stderr, "%s: %s: %s\n", smalloc_progname, hl_fname, strerror(errno)); exit(1); } } else { fprintf(stderr, "%s: Warning: Can't load user-hotlist: No home directory found.\n", smalloc_progname); } free(hl_fname); } void hotlist_exit(void) { int entry, page; char *hl_fname, *hl_tmpfname; FILE *file; hl_fname = sstrdup("~/." HOTLIST_FNAME); if (tilde_expand_realloc(&hl_fname) >= 0) { hl_tmpfname = sstrdup(hl_fname); hl_tmpfname = sstrapp(hl_tmpfname, "_vtx_tmp"); remove(hl_tmpfname); if ((file = fopen(hl_tmpfname, "w"))) { fprintf(file, "# This file was created by " VTXWINNAME ", Version " VTXVERSION "\n" "# DO NOT EDIT while VideoteXt is running -- it will be overwritten on exit.\n\n"); for (entry = 0; entry < hotlist_count; entry++) { fprintf(file, "station %s\n" "header=%s\n" "page_timeout=%d\n" "top_interleave=%d\n" "page_lookahead=%d\n" "top_disable=%s\n" "fast_disable=%s\n" "index_page=%X\n" "auto_search_pages=%s\n" "read_spooldir=%s\n" "write_spooldir=%s\n" "expire=%d\n" "channel=%s\n" "frequency=%d\n" "program=%d\n", hotlist[entry].name, hotlist[entry].header, hotlist[entry].page_timeout, hotlist[entry].top_interleave, hotlist[entry].lookahead, (hotlist[entry].top_disable ? "true" : "false"), (hotlist[entry].fast_disable ? "true" : "false"), hotlist[entry].index_page, tt_pageclass_str[hotlist[entry].search_level], (hotlist[entry].readspool ? "true" : "false"), (hotlist[entry].writespool ? "true" : "false"), hotlist[entry].expire, hotlist[entry].channel, hotlist[entry].freq, hotlist[entry].prog); /* Save exclude-list, include-list and hotlist only if station != Unknown */ if (entry) { fprintf(file, "include_pages=%s\nexclude_pages=%s\n", hotlist[entry].inc_list, hotlist[entry].ex_list); } if (hotlist[entry].search_count) { int loop; char flagstr[sizeof("case_sens,is_regexp,whole_words,multi_line,bell,")]; for (loop = 0; loop < hotlist[entry].search_count; loop++) { flagstr[0] = '\0'; if (hotlist[entry].search_data[loop].case_sens) { strcpy(flagstr + strlen(flagstr), "case_sens,"); } if (hotlist[entry].search_data[loop].is_regexp) { strcpy(flagstr + strlen(flagstr), "is_regexp,"); } if (hotlist[entry].search_data[loop].whole_words) { strcpy(flagstr + strlen(flagstr), "whole_words,"); } if (hotlist[entry].search_data[loop].multi_line) { strcpy(flagstr + strlen(flagstr), "multi_line,"); } if (hotlist[entry].search_data[loop].bell) { strcpy(flagstr + strlen(flagstr), "bell,"); } if (flagstr[0]) { flagstr[strlen(flagstr) - 1] = '\0'; } fprintf(file, "search_str=%s\n" "search_flags=%s\n", hotlist[entry].search_data[loop].str, flagstr); } } if (entry) { for (page = 0; page < hotlist[entry].count; page++) { fprintf(file, "%3x\n", hotlist[entry].pages[page]); } } fprintf(file, "\n"); } } if (!file || ferror(file) || fclose(file) || (remove(hl_fname) < 0 && errno != ENOENT) || rename(hl_tmpfname, hl_fname) < 0) { fprintf(stderr, "%s: Warning: Couldn't write %s: %s\n", smalloc_progname, hl_fname, strerror(errno)); if (file) { fclose(file); } } remove(hl_tmpfname); free(hl_tmpfname); } else { fprintf(stderr, "%s: Warning: Can't save user-hotlist: No home directory found.\n", smalloc_progname); } free(hl_fname); } void hotlist_add(int page, int pos) { current->pages = srealloc(current->pages, (current->count + 1) * sizeof(int)); if (pos >= current->count) pos = current->count; memmove(current->pages + pos + 1, current->pages + pos, (current->count - pos) * sizeof(int)); current->count++; current->pages[pos] = page; } int hotlist_remove(int pos) { int retval; retval = current->pages[pos]; memmove(current->pages + pos, current->pages + pos + 1, (current->count - pos - 1) * sizeof(int)); /* Kluge to avoid getting a NULL pointer when alloc'ing 0 bytes: */ current->pages = srealloc(current->pages, ((current->count - 1) > 0 ? (current->count - 1) : 1) * sizeof(int)); current->count--; return retval; } int hotlist_get(int pos) { return current->pages[pos]; } int hotlist_get_hotlist(int **list) { *list = current->pages; return current->count; } void hotlist_set_hotlist(int *list, int count) { free(current->pages); if (count) { current->pages = smalloc(count * sizeof(int)); memcpy(current->pages, list, count * sizeof(int)); } else { current->pages = smalloc(sizeof(int)); } current->count = count; } int hotlist_get_count(int station) { return hotlist[station].count; } int hotlist_get_stcount(void) { return hotlist_count; } void hotlist_set_current(int station) { station_changed = TRUE; current = hotlist + station; parse_spool_list(sp_list, current->inc_list, TRUE); parse_spool_list(sp_list, current->ex_list, FALSE); } int hotlist_get_current(void) { return current - hotlist; } void hotlist_put_queue(void) { int page; for (page = 0; page < current->count; page++) { get_page(PRI_MED, current->pages[page], 0, 0, NULL, NULL); history_insert(current->pages[page], FALSE); } } char** hotlist_mkstr(int *count) { static char **hotlist_str, *hotlist_pgstr; int entry; *count = current->count; if (hotlist_str) { hotlist_str = srealloc(hotlist_str, (*count + 1) * sizeof(char*)); /* Kluge to avoid getting a NULL pointer when alloc'ing 0 bytes: */ hotlist_pgstr = srealloc(hotlist_pgstr, (*count > 0 ? *count : 1) * 4 * sizeof(char)); } else { hotlist_str = smalloc((*count + 1) * sizeof(char*)); /* Kluge to avoid getting a NULL pointer when alloc'ing 0 bytes: */ hotlist_pgstr = smalloc((*count > 0 ? *count : 1) * 4 * sizeof(char)); } for (entry = 0; entry < *count; entry++) { hotlist_str[entry] = hotlist_pgstr + 4 * entry * sizeof(char); sprintf(hotlist_str[entry], "%3X", current->pages[entry]); } hotlist_str[*count] = NULL; return hotlist_str; } char* hotlist_get_name(void) { return current->name; } char* hotlist_get_name_n(int entry) { return hotlist[entry].name; } char* hotlist_get_header_n(int entry) { return hotlist[entry].header; } static int station_cmp(const byte_t header[STATIONNAME_MAXLEN], const byte_t *name) { int count, offset, len; const byte_t *header_chr, *name_chr; len = strlen(name); for (offset = 0; offset <= STATIONNAME_MAXLEN - len; offset++) { header_chr = header + offset; name_chr = name; for (count = 0; count <= STATIONNAME_MAXLEN - 1; count++) { if (!*name_chr) return TRUE; if (*header_chr && *header_chr != *name_chr) break; header_chr++; name_chr++; } if (!*name_chr) { return TRUE; } } return FALSE; } int hotlist_search(const byte_t *vtx_name, int hint) { char name[STATIONNAME_MAXLEN]; int pos, station, station_len = 0, station_num = 0; for (pos = 0; pos <= STATIONNAME_MAXLEN - 1; pos++) { name[pos] = vtx_name[pos]; /* Don't match chars with parity-errors */ if (!vtx_chkparity(&name[pos])) { name[pos] = '\1'; } if (name[pos] < ' ') { name[pos] = ' '; } /* Ignore chars from national charsets when comparing station names, because the charset is * unknown until a page was found */ switch (name[pos]) { case 0x23: case 0x24: case 0x40: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: case 0x60: case 0x7b: case 0x7c: case 0x7d: case 0x7e: name[pos] = '\0'; break; } } if (hint && station_cmp(name, hotlist[hint].header)) { return hint; } for (station = 1; station < hotlist_count; station++) { int lastlen; if (station != hint && station_cmp(name, hotlist[station].header) && (lastlen = strlen(hotlist[station].header)) > station_len) { station_num = station; station_len = lastlen; } } return station_num; } void hotlist_new_name(const char *name, const char *header, int station) { int old_station; /* When changing 'Unknown', create entry for new station and copy options from 'Unknown' */ if (!station) { old_station = current - hotlist; hotlist = srealloc(hotlist, ++hotlist_count * sizeof(hotlist_t)); hotlist[hotlist_count - 1] = hotlist[0]; hotlist[0].pages = smalloc(sizeof(int)); hotlist[0].count = 0; hotlist[0].channel = sstrdup(""); hotlist[0].inc_list = sstrdup(""); hotlist[0].ex_list = sstrdup(""); hotlist[0].search_count = 0; hotlist[0].search_data = NULL; if (old_station) { current = hotlist + old_station; } else { current = hotlist + hotlist_count - 1; } strcpy(hotlist[hotlist_count - 1].name, name); strcpy(hotlist[hotlist_count - 1].header, header); } else { strcpy(hotlist[station].name, name); strcpy(hotlist[station].header, header); } station_changed = TRUE; } int hotlist_station_changed(void) { int retval; retval = station_changed; station_changed = FALSE; return retval; } int hotlist_get_timeout(void) { return current->page_timeout; } void hotlist_set_timeout(int timeout) { current->page_timeout = timeout; } int hotlist_get_interleave(void) { return current->top_interleave; } void hotlist_set_interleave(int interleave) { current->top_interleave = interleave; } int hotlist_get_lookahead(void) { return current->lookahead; } void hotlist_set_lookahead(int lookahead) { current->lookahead = lookahead; } int hotlist_get_topdisable(void) { return current->top_disable; } void hotlist_set_topdisable(int disable) { current->top_disable = !!disable; } int hotlist_get_fastdisable(void) { return current->fast_disable; } void hotlist_set_fastdisable(int disable) { current->fast_disable = !!disable; } int hotlist_get_index_page(void) { return current->index_page; } void hotlist_set_index_page(int page) { current->index_page = page; } tt_pageclass_t hotlist_get_searchlevel(void) { return current->search_level; } void hotlist_set_searchlevel(tt_pageclass_t level) { current->search_level = level; } int hotlist_get_spoolflag(int private, int read) { /*FIXME*/ return read ? current->readspool : current->writespool; } void hotlist_set_spoolflag(int read, int flag) { if (read) { current->readspool = !!flag; } else { current->writespool = !!flag; } } int hotlist_get_expire(void) { return current->expire; } void hotlist_set_expire(int expire) { current->expire = expire; } const char* hotlist_get_includelist(void) { return current->inc_list; } int hotlist_set_includelist(const char *str) { if (!parse_spool_list(NULL, str, TRUE)) { return FALSE; } free(current->inc_list); current->inc_list = sstrdup(str); parse_spool_list(sp_list, current->inc_list, TRUE); parse_spool_list(sp_list, current->ex_list, FALSE); return TRUE; } const char* hotlist_get_excludelist(void) { return current->ex_list; } int hotlist_set_excludelist(const char *str) { if (!parse_spool_list(NULL, str, FALSE)) { return FALSE; } free(current->ex_list); current->ex_list = sstrdup(str); parse_spool_list(sp_list, current->inc_list, TRUE); parse_spool_list(sp_list, current->ex_list, FALSE); return TRUE; } const char * hotlist_get_channel(void) { return current->channel; } void hotlist_set_channel(const char *channel) { free(current->channel); current->channel = sstrdup(channel); } int hotlist_get_freq(void) { return current->freq; } void hotlist_set_freq(int freq) { current->freq = freq; } int hotlist_get_prog(void) { return current->prog; } void hotlist_set_prog(int prog) { current->prog = prog; } int hotlist_get_tunset_n(int entry) { return strcmp("", hotlist[entry].channel) || hotlist[entry].freq || hotlist[entry].prog; } void hotlist_clear_searchdata(void) { int loop; if (!current->search_data) { return; } for (loop = current->search_count - 1; loop >= 0; loop--) { free(current->search_data[loop].str); } free(current->search_data); current->search_data = NULL; current->search_count = 0; } void hotlist_add_searchdata(search_data_t *data) { current->search_data = srealloc(current->search_data, ++current->search_count * sizeof(search_data_t)); current->search_data[current->search_count - 1] = *data; current->search_data[current->search_count - 1].str = sstrdup(data->str); } search_data_t * hotlist_get_searchdata(int num) { return (num >= current->search_count) ? NULL : current->search_data + num; } int hotlist_check_spool(int page) { page = vtx_hex2dec(page) - 100; return (page >= 0 && page <= 799 && sp_list[page]); } void hotlist_copy(int station, int flags) { hotlist_t *old_current; /* Use initializers to make gcc happy */ int timeout = 0, interleave = 0, topdisable = 0, fastdisable = 0, lookahead = 0; int index_page = 0, readspool = 0, writespool = 0, expire = 0, freq = 0, prog = 0; int search_count = 0, hl_count = 0; int *hl_list = NULL; tt_pageclass_t searchlevel = TT_NONE; search_data_t **search_data = NULL; const char *includelist = NULL, *excludelist = NULL, *channel = NULL; if (current == hotlist + station) { return; } if (flags & HL_HOTLIST) { hl_count = hotlist_get_hotlist(&hl_list); } if (flags & HL_TIMEOUT) { timeout = hotlist_get_timeout(); } if (flags & HL_INTERLEAVE) { interleave = hotlist_get_interleave(); } if (flags & HL_TOPDISABLE) { topdisable = hotlist_get_topdisable(); } if (flags & HL_FASTDISABLE) { fastdisable = hotlist_get_fastdisable(); } if (flags & HL_SEARCHLEVEL) { searchlevel = hotlist_get_searchlevel(); } if (flags & HL_LOOKAHEAD) { lookahead = hotlist_get_lookahead(); } if (flags & HL_INDEXPAGE) { index_page = hotlist_get_index_page(); } if (flags & HL_READSPOOL) { readspool = hotlist_get_spoolflag(TRUE, TRUE); } if (flags & HL_WRITESPOOL) { writespool = hotlist_get_spoolflag(TRUE, FALSE); } if (flags & HL_EXINCLIST) { includelist = hotlist_get_includelist(); excludelist = hotlist_get_excludelist(); } if (flags & HL_EXPIRE) { expire = hotlist_get_expire(); } if (flags & HL_CHANNEL) { channel = hotlist_get_channel(); } if (flags & HL_FREQUENCY) { freq = hotlist_get_freq(); } if (flags & HL_PROG) { prog = hotlist_get_prog(); } if (flags & HL_SEARCHREQ) { int loop; search_data_t *data; search_count = 0; for (loop = 0; (data = hotlist_get_searchdata(loop)); loop++) { search_data = srealloc(search_data, ++search_count * sizeof(search_data_t *)); search_data[loop] = data; } } old_current = current; current = hotlist + station; if (flags & HL_HOTLIST) { hotlist_set_hotlist(hl_list, hl_count); } if (flags & HL_TIMEOUT) { hotlist_set_timeout(timeout); } if (flags & HL_INTERLEAVE) { hotlist_set_interleave(interleave); } if (flags & HL_TOPDISABLE) { hotlist_set_topdisable(topdisable); } if (flags & HL_FASTDISABLE) { hotlist_set_fastdisable(fastdisable); } if (flags & HL_SEARCHLEVEL) { hotlist_set_searchlevel(searchlevel); } if (flags & HL_LOOKAHEAD) { hotlist_set_lookahead(lookahead); } if (flags & HL_INDEXPAGE) { hotlist_set_index_page(index_page); } if (flags & HL_READSPOOL) { hotlist_set_spoolflag(TRUE, readspool); } if (flags & HL_WRITESPOOL) { hotlist_set_spoolflag(FALSE, writespool); } if (flags & HL_EXINCLIST) { hotlist_set_includelist(includelist); hotlist_set_excludelist(excludelist); } if (flags & HL_EXPIRE) { hotlist_set_expire(expire); } if (flags & HL_CHANNEL) { hotlist_set_channel(channel); } if (flags & HL_FREQUENCY) { hotlist_set_freq(freq); } if (flags & HL_PROG) { hotlist_set_prog(prog); } if (flags & HL_SEARCHREQ) { int loop; hotlist_clear_searchdata(); for (loop = 0; loop < search_count; loop++) { hotlist_add_searchdata(search_data[loop]); } free(search_data); } current = old_current; parse_spool_list(sp_list, current->inc_list, TRUE); parse_spool_list(sp_list, current->ex_list, FALSE); }