+-+-+-+ Beginning of part 12 +-+-+-+
X`009`009/* Nothing else to do right now */
X
X`009`009break;
X`009`125
X    `125
X
X    /* Did we fall off the end or did we have an error? */
X
X    if (ferror(in)) `123
X`009sprintf(temp, "Error: %s", strerror(errno, vaxc$errno));
X`009inter_error("F ", temp, node, user);
X`009return(FALSE);
X    `125
X
X    /* Save the current count, please */
X
X    if (cur_section) `123
X`009cur->ctl->n_count = item_cnt;
X    `125
X
X    /* Do we have lines for the mandatory sections? */
X
X    if (!item_cnt && (cur_section & LOAD_MANDATORY) &&
X`009    !(cur_section && LOAD_SINGULAR)) `123
X`009sprintf(temp, "'%s' section must have at least one line.", cur->string);
X`009inter_error("F ", temp, node, user);
X`009return(FALSE);
X    `125
X
X    /* Do we have all of the mandatory sections? */
X
X    if (sections_seen & LOAD_MANDATORY != LOAD_MANDATORY) `123
X`009sprintf(temp, "Not all control file sections present. Status: %d",
X`009`009sections_seen);
X`009inter_error("F ", temp, node, user);
X`009return(FALSE);
X    `125
X
X    /* It all worked. Yay! */
X
X    return (TRUE);
X`125
X
X/* Read and store the information from the control file */
X
Xstatic void parse_ctl_file(FILE * in)
X`123
X    char line[200];`009`009`009/* Buffer for the lines */
X    struct rule_ctl * cur;`009`009/* Current section */
X    int item_cnt;`009`009`009/* Where in the buffer? */
X
X    /* Go through the entire file (again) */
X
X    while (TRUE) `123
X
X`009/* Get the next line until EOF */
X
X`009if (!fgets_lcl(line, 200, in)) `123
X`009    break;
X`009`125
X
X`009/* Do stuff based on the first character of the line */
X
X`009switch (line[0]) `123
X
X`009/* Comment character, ignore the line */
X`009    case '!':
X`009`009continue;
X
X`009/* Section change, set up for it */
X`009    case ':':
X
X#ifdef DEBUG
X`009`009printf("parse_ctl_file: new section header\n");
X#endif
X
X`009`009for (cur = rule_control; cur->string; cur++) `123
X`009`009    if (strncmp(line, cur->string, strlen(cur->string))) `123
X`009`009`009continue;
X`009`009    `125
X`009`009    break;
X`009`009`125
X
X`009`009/* First off, is this singular or multiple? */
X
X`009`009if (cur->section & LOAD_SINGULAR) `123
X`009`009    parse_control_line(cur, line, 0);
X`009`009    break;
X`009`009`125
X
X`009`009/* Reset the item count once we've found a new section */
X
X`009`009item_cnt = 0;
X`009`009break;
X
X`009/* Data line, so just parse it out */
X`009    default:
X`009`009parse_control_line(cur, line, item_cnt++);
X`009`009break;
X`009`125
X    `125
X
X    singular_cleanup();
X
X    return;
X`125
X
X/* Make sure that all the singular pieces of information make sense */
X
Xstatic void singular_cleanup(void)
X`123
X    struct dsc$descriptor temp_interval;
X    unsigned int t_cnt;
X
X    send_log_file("I Singular rules set as follows:");
X
X    if (s_log.count) `123
X`009str_desc(&log_file, s_log.p);
X    `125 else `123
X`009str_desc(&log_file, DEF_LOG_FILE);
X    `125
X    sprintf(temp, "I NOTELOG file: %s", log_file.dsc$a_pointer);
X    send_log_file(temp);
X
X    if (s_err.count) `123
X`009str_desc(&error_conf, s_err.p);
X    `125 else `123
X`009str_desc(&error_conf, DEF_ERR_CONF);
X    `125
X    sprintf(temp, "I Error Conference: %s", error_conf.dsc$a_pointer);
X    send_log_file(temp);
X
X    if (s_tim.count) `123
X`009str_desc(&temp_interval, s_tim.p);
X    `125 else `123
X`009str_desc(&temp_interval, DEF_TIME_INTERVAL);
X    `125
X    sys$bintim(&temp_interval, bboard_time_interval);
X    sprintf(temp, "I Time Interval: %s", temp_interval.dsc$a_pointer);
X    send_log_file(temp);
X
X    t_cnt = 0;
X    if (s_cou.count) `123
X`009t_cnt = atoi(s_cou.p);
X    `125
X    if (t_cnt) `123
X`009bboard_count_interval = t_cnt;
X    `125 else `123
X`009bboard_count_interval = DEF_COUNT_INTERVAL;
X    `125
X    sprintf(temp, "I Count Interval: %d", bboard_count_interval);
X    send_log_file(temp);
X
X    if (s_ctct.count) `123
X`009str_desc(&local_contact, s_ctct.p);
X`009sprintf(temp, "I Local Contact: %s", local_contact.dsc$a_pointer);
X    `125 else `123
X`009str_desc(&local_contact, "");
X`009sprintf(temp, "I Local Contact: <none>");
X    `125
X    send_log_file(temp);
X`125
X
X/* Split a control line into its control buffer */
X
Xstatic void parse_control_line(struct rule_ctl * cur_ctl, char * in_line,
X`009int item)
X`123
X    struct list_info * c_lst;`009`009/* Temporary pointers for all these */
X    struct source_info * c_src;
X    struct rule_info * c_rul;
X    struct digest_def * c_dig;
X    struct manager_list * c_man;
X    struct link_info * c_lnk;
X    struct ignore_list * c_ign;
X    struct ctl_base * c_sing;
X    struct dsc$descriptor interval_text;
X    SYSTIM interval_check;
X
X    /* Which type are we working on? */
X
X#ifdef DEBUG
X    printf("parse_control_line: Processing data type: ");
X#endif
X
X    switch (cur_ctl->section) `123
X`009case LOAD_LIST:
X#ifdef DEBUG
X`009    printf("LIST\n");
X#endif
X`009    c_lst = cur_ctl->ctl->p;`009/* Grab a pointer */
X
X`009    /* Parse out the info */
X
X`009    load_text(c_lst[item].scan_data, in_line, 10);
X`009    load_text(c_lst[item].conf_hdr, in_line+11, 20);
X`009    load_text(c_lst[item].conf_user, in_line+32, 12);
X
X`009    c_lst[item].flag_digest = FALSE;
X`009    c_lst[item].flag_keyword = FALSE;
X
X`009    switch(in_line[45]) `123
X`009`009case 'Y':
X`009`009case 'y':
X`009`009    c_lst[item].flag_digest = TRUE;
X`009`009    break;
X`009`009case 'K':
X`009`009case 'k':
X`009`009    c_lst[item].flag_keyword = TRUE;
X`009`009    break;
X`009    `125
X
X`009    c_lst[item].new_topic_interval = in_line[47];
X`009    load_text(c_lst[item].conf_name, in_line+49, 39);
X`009    break;
X
X`009case LOAD_SOURCE:
X#ifdef DEBUG
X`009    printf("SOURCE\n");
X#endif
X`009    c_src = cur_ctl->ctl->p;`009/* Grab a pointer */
X
X`009    /* Parse out the info */
X
X`009    load_text(c_src[item].id, in_line, 2);
X`009    strupr(c_src[item].id);
X`009    load_text(c_src[item].scan_text, in_line+3, 20);
X`009    strlwr(c_src[item].scan_text);
X`009    c_src[item].reg_text_length = atoi(in_line+24);
X
X`009    /* Allocate some space for the header */
X
X`009    c_src[item].header_text = xmalloc(c_src[item].reg_text_length + 2);
X`009    break;
X
X`009case LOAD_RULE:
X#ifdef DEBUG
X`009    printf("RULE\n");
X#endif
X`009    c_rul = cur_ctl->ctl->p;`009/* Grab a pointer */
X
X`009    /* Parse out the info */
X
X`009    load_text(c_rul[item].ids[0], in_line, 2);
X`009    strupr(c_rul[item].ids[0]);
X`009    load_text(c_rul[item].comparison, in_line+3, 2);
X`009    strlwr(c_rul[item].comparison);`009/* Keep this lower case */
X`009    load_text(c_rul[item].ids[1], in_line+6, 2);
X`009    strupr(c_rul[item].ids[1]);
X`009    load_text(c_rul[item].action, in_line+9, 2);
X`009    load_text(c_rul[item].id_from, in_line+12, 2);
X`009    strupr(c_rul[item].id_from);
X`009    load_text(c_rul[item].id_subj, in_line+15, 2);
X`009    strupr(c_rul[item].id_subj);
X`009    break;
X
X`009case LOAD_DIGEST:
X#ifdef DEBUG
X`009    printf("DIGEST\n");
X#endif
X`009    c_dig = cur_ctl->ctl->p;`009/* Grab a pointer */
X
X`009    /* Parse out the info */
X
X`009    c_dig[item].digest_id = in_line[0];
X`009    c_dig[item].split_len = atoi(in_line+2);
X`009    c_dig[item].split_error = atoi(in_line+6);
X`009    break;
X
X`009case LOAD_MANAGER:
X#ifdef DEBUG
X`009    printf("MANAGER\n");
X#endif
X`009    c_man = cur_ctl->ctl->p;`009/* Grab a pointer */
X
X`009    /* Parse out the info */
X
X`009    load_text(c_man[item].user, in_line, 8);
X`009    strupr(c_man[item].user);`009/* Keep this upper case */
X`009    break;
X
X`009case LOAD_LINKS:
X#ifdef DEBUG
X`009    printf("LINKS\n");
X#endif
X`009    c_lnk = cur_ctl->ctl->p;`009/* Grab a pointer */
X
X`009    /* Parse out the info */
X
X`009    load_text(c_lnk[item].link, in_line, 8);
X`009    strupr(c_lnk[item].link);`009/* Keep this upper case */
X`009    break;
X
X`009case LOAD_IGNORE:
X#ifdef DEBUG
X`009    printf("IGNORE\n");
X#endif
X`009    c_ign = cur_ctl->ctl->p;`009/* Grab a pointer */
X
X`009    load_text(c_ign[item].node, in_line, 8);
X`009    load_text(c_ign[item].user, in_line+9, 8);
X
X`009    /* Want both to be upper case */
X
X`009    strupr(c_ign[item].node);
X`009    strupr(c_ign[item].user);
X`009    break;
X
X`009case LOAD_LOG:
X#ifdef DEBUG
X`009    printf("LOG\n");
X#endif
X    singular_common:
X`009    c_sing = cur_ctl->ctl;
X
X`009    load_text(c_sing->p, in_line+strlen(cur_ctl->string),
X`009`009    cur_ctl->size);
X`009    break;
X
X`009case LOAD_ERR:
X#ifdef DEBUG
X`009    printf("ERR\n");
X#endif
X`009    goto singular_common;
X`009    break;
X
X`009case LOAD_TIMER:
X#ifdef DEBUG
X`009    printf("TIMER\n");
X#endif
X`009    c_sing = cur_ctl->ctl;
X
X`009    load_text(c_sing->p, in_line+strlen(cur_ctl->string),
X`009`009    cur_ctl->size);
X
X`009    str_desc(&interval_text, c_sing->p);
X`009    status = sys$bintim(&interval_text, interval_check);
X
X`009    if (!(status & 1)) `123`009/* Bad time given */
X`009`009send_log_file("I Invalid time field selected");
X`009`009send_log_file("I Using default value instead");
X
X`009`009xfree(c_sing->p);`009/* And we never saw this... */
X`009`009c_sing->count = 0;
X`009`009break;
X`009    `125
X`009    break;
X
X`009case LOAD_COUNT:
X#ifdef DEBUG
X`009    printf("COUNT\n");
X#endif
X`009    goto singular_common;
X`009    break;
X
X`009case LOAD_CONTACT:
X#ifdef DEBUG
X`009    printf("CONTACT\n");
X#endif
X`009    goto singular_common;
X`009    break;
X    `125
X    return;
X`125
X
X/* Load a field, terminate it, then trim it down */
X
Xstatic void load_text(char * so, char * si, int len)
X`123
X    strncpy(so, si, len);
X    so[len] = '\0';
X    trim_end(so);
X`125
X
X/* Go through and throw away the memory we had */
X
Xstatic void release_control_memory(void)
X`123
X    struct source_info * c_src;
X
X    xfree(lst.p);
X    for (c_src = src.p; c_src->id[0]; c_src++) `123
X`009xfree(c_src->header_text);
X    `125
X    xfree(src.p);
X    xfree(rul.p);
X    xfree(dig.p);
X    xfree(man.p);
X    if (lnk.count) `123
X`009xfree(lnk.p);
X    `125
X    if (ign.count) `123
X`009xfree(ign.p);
X    `125
X    if (s_log.count) `123
X`009xfree(s_log.p);
X    `125
X    if (s_err.count) `123
X`009xfree(s_err.p);
X    `125
X    if (s_tim.count) `123
X`009xfree(s_tim.p);
X    `125
X    if (s_cou.count) `123
X`009xfree(s_cou.p);
X    `125
X    if (s_ctct.count) `123
X`009xfree(s_ctct.p);
X    `125
X
X    return;
X`125
X
X/* After we've loaded the headers, figure out what we should do with it */
X
Xvoid do_rules(FILE * note)
X`123
X    struct rule_info * cur;`009`009/* Look at all the rules */
X    int id_present[2];`009`009`009/* Are the IDs there? */
X    int ids_equal;`009`009`009/* Are they equal */
X    int fulfilled;`009`009`009/* And did we fulfill the comparison */
X
X    char * id1; `009`009`009/* What's the info */
X    char * id2;
X
X    /* Go through all the rules until we get a match or fall off the end */
X
X#ifdef DEBUG
X    printf("do_rules: about to scan for rule match\n");
X#endif
X
X    for (cur = rul.p; cur->comparison[0]; cur++) `123
X
X`009/* Start off without anything being set */
X
X`009id_present[1] = id_present[0] = FALSE;
X
X`009/* Get the first ID */
X
X`009id1 = find_source(cur->ids[0]);
X`009id_present[0] = (id1 != NULL);
X
X`009/* If we need to, get the second ID */
X
X`009if (cur->ids[1][0]) `123
X`009    id2 = find_source(cur->ids[1]);
X`009    id_present[1] = (id2 != NULL);
X`009`125
X
X`009/* If they're both there, are they equal? */
X
X`009if (id_present[0] && id_present[1]) `123
X`009    ids_equal = (!strcmp(id1, id2));
X`009`125 else `123
X`009    ids_equal = FALSE;
X`009`125
X
X`009/* Now let's figure out what this all means... */
X
X`009fulfilled = FALSE;
X
X`009if (!strcmp(cur->comparison, "eq")) `123
X`009    fulfilled = ids_equal;
X`009`125 else if (!strcmp(cur->comparison, "ne")) `123
X`009    fulfilled = !ids_equal;
X`009`125 else if (!strcmp(cur->comparison, "pr")) `123
X`009    fulfilled = id_present[0];
X`009`125 else if (!strcmp(cur->comparison, "np")) `123
X`009    fulfilled = !id_present[0];
X`009`125
X
X`009/* Did we get a match? */
X
X#ifdef DEBUG
X`009printf("do_rules: %smatch\n", (fulfilled ? "" : "no "));
X#endif
X
X`009if (!fulfilled) `123
X`009    continue;
X`009`125
X
X`009/* If so, try seeing if it has a match for the lists */
X
X`009if (search_lists(note, cur)) `123
X`009    break;
X`009`125
X    `125
X
X    /* If we fell off the end, it's an unknown/error note */
X
X    if (!cur->comparison[0]) `123
X`009put_note(note, NULL, NULL, TRUE);
X    `125
X
X    /* Go back home */
X
X    return;
X`125
X
X/* Use the search-ID to see if we can get a match for a list */
X
Xstatic int search_lists(FILE * note, struct rule_info * rule)
X`123
X    struct list_info * cur;`009`009/* Scan through the list tags */
X    char * source;`009`009`009/* ID text to scan into */
X    char * t_text;`009`009`009/* List scan text to use */
X    char s_text[11];`009`009`009/* Copy of the scan text */
X
X    /* Get the search-ID */
X
X    source = find_source(rule->action);
X    if (!source) `123
X`009return(FALSE);
X    `125
X
X#ifdef DEBUG
X    printf("search_lists: searching in %s\n", source);
X#endif
X
X    /* Now get an uppercase version of the text to search in */
X
X    t_text = xmalloc(strlen(source)+1);
X    strcpy(t_text, source);
X    strupr(t_text);
X
X    /* Test for presence of the list scan text */
X
X    for (cur = lst.p; cur->scan_data[0]; cur++) `123
X`009strcpy(s_text, cur->scan_data);
X`009strupr(s_text);
X`009if (strstr(t_text, s_text)) `123`009/* found it */
X`009    break;
X`009`125
X    `125
X
X    /* Lose the temporary copy of the header line */
X
X    xfree(t_text);
X
X    /* Did we find it? */
X
X    if (!cur->scan_data[0]) `123
X`009return(FALSE);
X    `125
X
X    /* Yes, so stuff the note */
X
X#ifdef DEBUG
X    printf("search_lists: got match. Adding note\n");
X#endif
X
X    put_note(note, rule, cur, FALSE);
X
X    return(TRUE);
X`125
X
X/* Get a pointer to a source ID */
X
Xchar * find_source(char * id)
X`123
X    struct source_info * cur;`009`009/* We need to scan through looking */
X
X    for (cur = src.p; cur->id[0]; cur++) `123
X`009if (!strcmp(id, cur->id)) `123
X`009    break;
X`009`125
X    `125
X
X    if (!cur->id[0]) `123`009`009`009/* No ID found */
X`009return (NULL);
X    `125 else if (!cur->header_text[0]) `123`009/* No text for ID */
X`009return (NULL);
X    `125 else `123
X`009return (cur->header_text);
X    `125
X`125
X
X/* Fill out the source ID text sections */
X
Xvoid scan_header(FILE * note, struct source_info * p)
X`123
X    struct source_info * cur;`009`009/* Need to scan through */
X    char line[256];`009`009`009/* Place to stuff incoming info */
-+-+-+-+-+ End of part 12 +-+-+-+-+-