This is sequence.c in view mode; [Download] [Up]
/* * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved. * * Read presentation sequence file */ #include "config.h" #include "debug.h" export group_header *group_sequence; export char *read_mail = NULL; export int also_subgroups = 1; export int hex_group_args = 0; static int seq_break_enabled = 1; /* !! enabled */ static int ignore_done_flag = 0; /* % toggle */ static group_header *tail_sequence = NULL; static group_header *final_sequence = NULL; static int gs_more_groups; only_folder_args(args) char **args; { register char *arg; while (arg = *args++) { if (*arg == '+' || *arg == '~' || *arg == '/') continue; if (file_exist(arg, "fr")) continue; return 0; } return 1; } #define SHOW_NORMAL 0 /* : put this in at current pos */ #define SHOW_FIRST 1 /* < : show these groups first */ #define SHOW_LAST 2 /* > : show this as late as possible */ #define IGNORE_ALWAYS 3 /* ! : ignore these groups completely */ #define IGN_UNLESS_RC 4 /* !:X ignore these groups unless in rc */ #define IGN_UNLESS_NEW 5 /* !:O ignore these groups unless new */ #define IGN_UNL_RC_NEW 6 /* !:U ignore unsubscribed */ #define IGN_IF_NEW 7 /* !:N ignore these groups if new */ #define SHOW_MODES " <>!-?*" static enter_sequence(mode, gh) int mode; group_header *gh; { #ifdef SEQ_TEST if (Debug & SEQ_TEST && mode != SHOW_NORMAL) printf("SEQ(%c), %s\n", SHOW_MODES[mode], gh->group_name); #endif if (gh->master_flag & M_IGNORE_GROUP) return 0; if (ignore_done_flag) { if (gh->group_flag & G_SEQUENCE) return 0; } else if (gh->group_flag & G_DONE) return 0; switch (mode) { case IGN_UNLESS_NEW: if ((gh->group_flag & G_NEW) == 0) gh->group_flag |= G_DONE; return 0; case IGN_IF_NEW: if (gh->group_flag & G_NEW) gh->group_flag |= G_DONE; return 0; case IGN_UNL_RC_NEW: if (gh->group_flag & G_NEW) return 0; if (gh->newsrc_line == NULL || (gh->group_flag & G_UNSUBSCRIBED)) gh->group_flag |= G_DONE; return 0; case IGN_UNLESS_RC: if (gh->newsrc_line == NULL || (gh->group_flag & (G_UNSUBSCRIBED|G_NEW))) gh->group_flag |= G_DONE; return 0; case IGNORE_ALWAYS: gh->group_flag |= G_DONE; return 0; default: gh->group_flag |= G_DONE; break; } gh->group_flag |= G_SEQUENCE; if (gh->master_flag & M_NO_DIRECTORY) return 0; /* for nntidy -s */ switch (mode) { case SHOW_FIRST: if (tail_sequence) { gh->next_group = group_sequence; group_sequence = gh; break; } /* fall thru */ case SHOW_NORMAL: if (tail_sequence) tail_sequence->next_group = gh; else group_sequence = gh; tail_sequence = gh; break; case SHOW_LAST: gh->next_group = final_sequence; final_sequence = gh; break; } return 1; } static faked_entry(name, flag) char *name; flag_type flag; { group_header *gh; gh = newobj(group_header, 1); gh->group_name = name; gh->group_flag = flag | G_FAKED; gh->master_flag = 0; /* "invent" an unread article for read_news */ gh->last_article = 1; gh->last_db_article = 2; enter_sequence(SHOW_NORMAL, gh); } static end_sequence() { register group_header *gh, *backp; register int seq_ix; if (tail_sequence) tail_sequence->next_group = NULL; /* set up backward pointers */ backp = NULL; seq_ix = 0; Loop_Groups_Sequence(gh) { gh->preseq_index = ++seq_ix; gh->prev_group = backp; backp = gh; } #ifdef SEQ_DUMP if (Debug & SEQ_DUMP) { for (gh = group_sequence; gh; gh = gh->next_group) printf("%s\t", gh->group_name); putchar(NL); nn_exit(0); } #endif } #ifdef MAIL_READING static mail_check() { static group_header mail_group; struct stat st; if (read_mail == NULL) return; if (stat(read_mail, &st) < 0) return; if (st.st_size == 0 || st.st_mtime < st.st_atime) return; mail_group.group_name = read_mail; gh->group_flag = G_FOLDER | G_MAILBOX | G_FAKED; gh->master_flag = 0; /* "invent" an unread article for read_news */ gh->last_article = 1; gh->last_db_article = 2; if (tail_sequence) { mail_group.next_group = group_sequence; group_sequence = mail_group; } else enter_sequence(SHOW_NORMAL, &mail_group); } #endif static visit_presentation_file(directory, seqfile, hook) char *directory, *seqfile; FILE *hook; { import int group_name_args; register FILE *sf; register c; register group_header *gh; group_header *mp_group, *get_group_search(); char group[FILENAME], *gname; char savefile[FILENAME], *dflt_save, *enter_macro; extern char *parse_enter_macro(); register char *gp; int mode, merge_groups; if (gs_more_groups == 0) return 0; if (hook != NULL) sf = hook; /* hook to init file */ else if ((sf = open_file(relative(directory, seqfile), OPEN_READ)) == NULL) return 0; #ifdef SEQ_TEST if (Debug & SEQ_TEST) printf("Sequence file %s/%s\n", directory, seqfile); #endif mode = SHOW_NORMAL; savefile[0] = NUL; while (gs_more_groups) { if ((c = getc(sf)) == EOF) break; if (!isascii(c) || isspace(c)) continue; switch (c) { case '!': mode = IGNORE_ALWAYS; if ((c = getc(sf)) == EOF) continue; if (c == '!') { if (seq_break_enabled) { fclose(sf); return 1; } mode = SHOW_NORMAL; continue; } if (c == ':') { if ((c = getc(sf)) == EOF) continue; if (!isascii(c) || isspace(c) || !isupper(c)) continue; switch (c) { case 'O': mode = IGN_UNLESS_NEW; continue; case 'N': mode = IGN_IF_NEW; continue; case 'U': mode = IGN_UNL_RC_NEW; continue; case 'X': mode = IGN_UNLESS_RC; continue; default: /*should give error here*/ mode = SHOW_NORMAL; continue; } } ungetc(c, sf); continue; case '<': mode = SHOW_FIRST; continue; case '>': mode = SHOW_LAST; continue; case '%': ignore_done_flag = ! ignore_done_flag; continue; case '@': seq_break_enabled = 0; mode = SHOW_NORMAL; continue; case '#': do c = getc(sf); while (c != EOF && c != NL); mode = SHOW_NORMAL; continue; } gp = group; merge_groups = 0; do { *gp++ = c; if (c == ',') merge_groups = 1; c = getc(sf); } while (c != EOF && isascii(c) && !isspace(c)); *gp = NUL; while (c != EOF && (!isascii(c) || isspace(c))) c = getc(sf); if (c == '+' || c == '~' || c == '/') { gp = savefile; if (c == '+') { c = getc(sf); if (c == EOF || (isascii(c) && isspace(c))) goto use_same_savefile; *gp++ = '+'; } do { *gp++ = c; c = getc(sf); } while (c != EOF && isascii(c) && !isspace(c)); *gp = NUL; dflt_save = savefile[0] ? copy_str(savefile) : NULL; } else dflt_save = NULL; use_same_savefile: while (c != EOF && (!isascii(c) || isspace(c))) c = getc(sf); if (c == '(') { enter_macro = parse_enter_macro(sf, getc(sf)); } else { enter_macro = NULL; if (c != EOF) ungetc(c, sf); } mp_group = NULL; for (gp = group; *gp;) { gname = gp; if (merge_groups) { while (*gp && *gp != ',') gp++; if (*gp) *gp++ = NUL; } start_group_search(gname); while (gh = get_group_search()) { if (merge_groups && gh->group_flag & G_UNSUBSCRIBED) continue; if (!enter_sequence(mode, gh)) continue; if (merge_groups) { if (mp_group == NULL) { gh->group_flag |= G_MERGE_HEAD; } else { mp_group->merge_with = gh; gh->group_flag |= G_MERGE_SUB; } mp_group = gh; } if (gh->save_file == NULL) /* not set by "save-files" */ gh->save_file = dflt_save; if (gh->enter_macro == NULL) /* not set by "on entry" */ gh->enter_macro = enter_macro; } if (!merge_groups) *gp = NUL; } if (merge_groups && mp_group != NULL) mp_group->merge_with = NULL; mode = SHOW_NORMAL; } fclose(sf); return 0; } parse_save_files(sf) register FILE *sf; { register c; register group_header *gh; group_header *get_group_search(); char group[FILENAME]; char *savefile = NULL; char namebuf[FILENAME]; register char *gp; for (;;) { if ((c = getc(sf)) == EOF) break; if (!isascii(c) || isspace(c)) continue; if (c == '#') { do c = getc(sf); while (c != EOF && c != NL); continue; } gp = group; do { *gp++ = c; c = getc(sf); } while (c != EOF && isascii(c) && !isspace(c)); *gp = NUL; if (strcmp(group, "end") == 0) break; while (c != EOF && (!isascii(c) || isspace(c))) c = getc(sf); gp = namebuf; do { *gp++ = c; c = getc(sf); } while (c != EOF && isascii(c) && !isspace(c)); *gp = NUL; if (namebuf[0] == NUL) break; if (strcmp(namebuf, "+")) savefile = copy_str(namebuf); start_group_search(group); while (gh = get_group_search()) gh->save_file = savefile; } } named_group_sequence(groups) char **groups; { register group_header *gh; group_header *get_group_search(); register char *group; register char *value; int non_vars; int found, any, errors, gnum; group_sequence = NULL; also_subgroups = 0; any = errors = 0; non_vars = 0; while (group = *groups++) { non_vars++; if (hex_group_args) { sscanf(group, "%x", &gnum); if (gnum < 0 || gnum >= master.number_of_groups) continue; gh = ACTIVE_GROUP(gnum); if (enter_sequence(SHOW_NORMAL, gh)) any++; continue; } if (gh = lookup(group)) { if (enter_sequence(SHOW_NORMAL, gh)) any++; continue; } if (value = strchr(group, '=')) { *value++ = NUL; set_variable(group, 1, value); non_vars--; continue; } if (*group == '+' || *group == '~' || file_exist(group, "fr")) { faked_entry(group, G_FOLDER); any++; continue; } #ifdef NOT_DEF if (*group == '+' || *group == '~') { char exp_file[FILENAME]; group_header fake_group; current_group = &fake_group; fake_group.group_name = group; group_file_name = NULL; if (expand_file_name(exp_file, group, 1) && file_exist(exp_file, "fr")) { faked_entry(copy_str(exp_file), G_FOLDER); any++; continue; } printf("Folder %s not found\n", group); fl; errors++; continue; } #endif found = 0; start_group_search(group); while (gh = get_group_search()) { found++; enter_sequence(SHOW_NORMAL, gh); } if (!found) { printf("Group %s not found\n", group); fl; errors++; } else any++; } if (non_vars == 0) return normal_group_sequence(); end_sequence(); if (errors) user_delay(2); return any; } FILE *loc_seq_hook = NULL; /* sequence in local "init" file */ FILE *glob_seq_hook = NULL; /* sequence in global "init" file */ normal_group_sequence() { register group_header *gh; group_sequence = NULL; gs_more_groups = 1; /* visit_p_f returns non-zero if terminated by !! */ if (visit_presentation_file(nn_directory, "seq", loc_seq_hook)) goto final; if (visit_presentation_file(lib_directory, "sequence", glob_seq_hook)) goto final; Loop_Groups_Sorted(gh) { enter_sequence(SHOW_NORMAL, gh); } final: if (final_sequence) if (tail_sequence) { tail_sequence->next_group = final_sequence; tail_sequence = NULL; } else group_sequence = final_sequence; #ifdef MAIL_READING mail_check(); #endif end_sequence(); } static char *gs_group; static int gs_length, gs_index, gs_mode; static group_header *gs_only_group = NULL; #define GS_PREFIX0 0 /* group (or group*) */ #define GS_PREFIX 1 /* group. */ #define GS_SUFFIX 2 /* .group */ #define GS_INFIX 3 /* .group. */ #define GS_NEW_GROUP 4 /* new group */ #define GS_ALL 5 /* all / . */ #define GS_NEWSRC 6 /* RC */ start_group_search(group) char *group; { char *dot; int last; import group_header *rc_sequence; gs_index = master.number_of_groups; /* loop will fail */ if ((last = strlen(group) - 1) < 0) return; if (group[last] == '*') group[last] = NUL; else if (!also_subgroups && (gs_only_group = lookup(group)) != NULL) return; gs_index = 0; gs_more_groups = 0; gs_length = 0; gs_group = NULL; if (strcmp(group, "NEW") == 0) { gs_mode = GS_NEW_GROUP; return; } if (strncmp(group, "RC", 2) == 0) { gs_mode = GS_NEWSRC; gs_only_group = rc_sequence; gs_more_groups = 1; /* we just can't know! */ if (group[2] != ':') return; if (isdigit(group[3])) gs_index = atoi(group+3); else { gs_group = group+3; gs_length = strlen(gs_group); } return; } if (strcmp(group, "all") == 0 || strcmp(group, ".") == 0) { gs_mode = GS_ALL; return; } gs_mode = GS_PREFIX0; if (strncmp(group, "all.", 4) == 0) group += 3; if (*group == '.') gs_mode = GS_SUFFIX; if ((dot = strrchr(group, '.')) != NULL && dot != group) { if (dot[1] == NUL || strcmp(dot+1, "all") == 0) { dot[1] = NUL; gs_mode = (gs_mode == GS_SUFFIX) ? GS_INFIX : GS_PREFIX; } } gs_length = strlen(group); gs_group = group; } group_header *get_group_search() { register group_header *gh; register int c, tail; if (gs_mode == GS_NEWSRC) { do { gh = gs_only_group; if (gh == NULL) return NULL; if (gs_index && --gs_index == 0) { gs_only_group = NULL; } else if (gs_group && gh->group_name_length >= gs_length && strncmp(gh->group_name, gs_group, gs_length) == 0) { gs_only_group = NULL; } else gs_only_group = gh->newsrc_seq; } while ((!ignore_done_flag && (gh->group_flag & G_DONE)) || (gh->master_flag & M_IGNORE_GROUP)); return gh; } if (gs_only_group != NULL) { gh = gs_only_group; gs_only_group = NULL; if (!ignore_done_flag && gh->group_flag & G_DONE) return NULL; if (gh->master_flag & M_IGNORE_GROUP) return NULL; return gh; } while (gs_index < master.number_of_groups) { gh = sorted_groups[gs_index++]; if (!ignore_done_flag && gh->group_flag & G_DONE) continue; if (gh->master_flag & M_IGNORE_GROUP) continue; gs_more_groups++; if ((tail = gh->group_name_length - gs_length) < 0) continue; switch (gs_mode) { case GS_NEW_GROUP: if ((gh->group_flag & G_NEW) == 0) continue; if (gh->group_flag & G_UNSUBSCRIBED) continue; break; case GS_PREFIX0: if ((c = (gh->group_name)[gs_length]) != NUL && c != '.') continue; case GS_PREFIX: if (strncmp(gh->group_name, gs_group, gs_length)) continue; break; case GS_SUFFIX: if (strcmp(gh->group_name + tail, gs_group)) continue; break; case GS_INFIX: user_error(".name. notation not supported (yet)"); break; case GS_ALL: break; } gs_more_groups--; return gh; } return NULL; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.