/* * Refer to file UPDNODES.H for copyright and version information */ #include #include #include #include #include "updnodes.h" #ifdef oldcc #include #endif /* oldcc */ #define ADD 1 #define DEL 2 #define REP 3 char deltaline[VALUE_STR_LEN]; char baseline[VALUE_STR_LEN]; NODE_ENTRY cur_base; /* Current entry from base */ NODE_ENTRY cur_delta; /* Current entry from delta */ int16u old_checksum; /* Old totcks, we calculate */ int16u old_checksum_verify; /* Old totcks, from base */ int16u new_checksum; /* New running totcks */ int16u new_checksum_verify; /* New totcks, from update file */ /* New from delta will be in cur_base */ #ifndef oldcc static int get_action_type(NODE_ENTRY * cur); static void get_major_tag(char * tag, char * s); static int process_prologue(void); static int have_act(char * s); #else static int get_action_type(); static void get_major_tag(); static int process_prologue(); static int have_act(); #endif /* oldcc */ #ifndef oldcc void merge_net(void) #else void merge_net() #endif /* oldcc */ { TAG_ENTRY * t; int cur_action; int cmp_result; int rd_delta, rd_base, wr_base; int base_eof_found; memset(deltaline, 0, 256); memset(baseline, 0, 256); old_checksum = new_checksum = 0; memset((char *) &cur_base, 0, sizeof(NODE_ENTRY)); memset((char *) &cur_delta, 0, sizeof(NODE_ENTRY)); if (!process_prologue()) { exit(SYSERROR); } if (feof(delta)) { error("Update file does not contain any known actions.\n"); exit(SYSERROR); } read_base_line(); get_major_tag(major_tag, baseline); get_base_tag(&cur_base); /* First one is definitely VERSnnnn */ t = min_find(&cur_base, "totcks"); if (!t) { error("No :totcks. tag in base %s entry.\n", cur_base.name); exit(SYSERROR); } old_checksum_verify = atoi(t->value); while (TRUE) { get_delta_tag(&cur_delta); if (!strncmp(cur_delta.name, "VERS", 4)) { if(strcmp(cur_delta.name, cur_base.name) && get_action_type(&cur_delta) > ADD) { error("Base file version is %s, delta is for %s.\n", cur_base.name, cur_delta.name); exit(SYSERROR); } apply_vers_delta(&cur_base, &cur_delta); } else break; } if (cur_base.name[0]) { write_node(&cur_base); } else { error("No resulting VERSnnnn entry.\n"); exit(SYSERROR); } t = min_find(&cur_base, "totcks"); if (!t) { error("No :totcks. tag in output %s entry.\n", cur_base.name); exit(SYSERROR); } else new_checksum_verify = atoi(t->value); get_base_tag(&cur_base); /* This may or may not be LINKSnnn */ while (TRUE) { if (!strncmp(cur_delta.name, "LINKS", 5)) { apply_links_delta(&cur_base, &cur_delta); get_delta_tag(&cur_delta); } else break; } if (cur_base.name[0]) { write_node(&cur_base); } get_base_tag(&cur_base); /* Load the first one to get ready */ base_eof_found = rd_delta = rd_base = wr_base = FALSE; while (TRUE) { if (wr_base) { write_node(&cur_base); rd_base = TRUE; } if (rd_base) { if (!get_base_tag(&cur_base)) { base_eof_found = TRUE; } } if (rd_delta) { if (!get_delta_tag(&cur_delta)) { break; } } rd_delta = rd_base = wr_base = FALSE; cur_action = get_action_type(&cur_delta); if (!cur_action) { error("Invalid action %s for %s.\n", cur_delta.action, cur_delta.name); rd_delta = TRUE; continue; /* Try again */ } if (base_eof_found) { cmp_result = 1; /* Pretend we're past everything */ } else { cmp_result = estrcmp(cur_delta.name, cur_base.name); } if (cur_action == ADD) { if (base_eof_found) { /* Special case. It figures */ cmp_result = -1; } if (!cmp_result) { /* existing node? */ error("Attempt to ADD existing node %s - ignored.\n", cur_delta.name); rd_delta = TRUE; } else if (cmp_result > 0) { /* early, keep looking */ wr_base = TRUE; } else { /* right on time. */ log_line(LOG_UPDATE, "%s added.\n", cur_delta.name); write_node(&cur_delta); /* Write the addition */ rd_delta = TRUE; } } else if (cur_action == DEL) { if (cmp_result < 0) { /* Missed it. */ error("Attempt to DEL nonexistent node %s - ignored.\n", cur_delta.name); rd_delta = TRUE; } else if (cmp_result > 0) { /* early, keep looking */ wr_base = TRUE; } else { /* Found it */ log_line(LOG_UPDATE, "%s deleted.\n", cur_delta.name); rd_delta = rd_base = TRUE; } } else if (cur_action == REP) { if (cmp_result < 0) { /* Missed it. */ error("Attempt to REP nonexistent node %s - ignored.\n", cur_delta.name); rd_delta = TRUE; } else if (cmp_result > 0) { /* early, keep looking */ wr_base = TRUE; } else { /* Found it */ min_incorporate(&cur_base, &cur_delta); log_line(LOG_UPDATE, "%s updated.\n", cur_base.name); wr_base = rd_delta = TRUE; } } } while (!base_eof_found) { write_node(&cur_base); if (!get_base_tag(&cur_base)) { base_eof_found = TRUE; } } log_line(LOG_UPDATE, "Checking input :totcks. calculation...\n"); if (old_checksum != old_checksum_verify) { error("Input :totcks. tag doesn't match calculated :totcks.\n"); error("Verification: %u/%x, Calculated: %u/%x\n", old_checksum_verify, old_checksum_verify, old_checksum, old_checksum); } else { log_line(LOG_UPDATE, "Input :totcks. matches.\n"); } log_line(LOG_UPDATE, "Checking output :totcks. calculation...\n"); if (new_checksum != (int16u) new_checksum_verify) { error("Updated :totcks. tag doesn't match calculated output :totcks.\n"); error("Verification: %u/%x, Calculated: %u/%x\n", new_checksum_verify, new_checksum_verify, new_checksum, new_checksum); } else { log_line(LOG_UPDATE, "Output :totcks. matches.\n"); } } #ifndef oldcc static int get_action_type(NODE_ENTRY * cur) #else static int get_action_type(cur) NODE_ENTRY * cur; #endif /* oldcc */ { if (!*cur->action) return (0); if (!strcmp(cur->action, "ADD")) return (ADD); if (!strcmp(cur->action, "DEL")) return (DEL); if (!strcmp(cur->action, "REP")) return (REP); return (0); } #ifndef oldcc static void get_major_tag(char * tag, char * s) #else static void get_major_tag(tag, s) char * tag; char * s; #endif /* oldcc */ { char * t; memset((char *) tag, 0, STD_STR_LEN); if (strlen(s) < 3 || s[0] != ':' || s[1] == '.' || s[1] == ' ') { error("No major-level tag in Nodes files.\n"); exit(SYSERROR); } /* Now let's get the tag... */ t = strchr(s, '.'); if (!t) { t = strchr(s, ' '); if (!t) { t = s + strlen(s); } } if (t - s > STD_STR_LEN) { error("Major-level tag too long.\n"); exit(SYSERROR); } strncpy(tag, s+1, t - s - 1); } #ifndef oldcc static int process_prologue(void) #else static int process_prologue() #endif /* oldcc */ { char * t; while (!feof(delta) && !have_act(deltaline)) { if (strlen(deltaline) > 11 && !strncmp(deltaline, "UPDNODES(", 9)) { strcpy(deltaline, deltaline+9); /* Move it over */ for (t = deltaline; *t && (isdigit(*t) || *t == '.'); t++); *t = '\0'; if (*deltaline && strcmp(deltaline, VERSION) > 0) { error("This version (%s) is not smart enough.\n", VERSION); error("You require at least version %s.\n", deltaline); return (FALSE); } } read_delta_line(); } return(TRUE); } #ifndef oldcc static int have_act(char * s) #else static int have_act(s) char * s; #endif /* oldcc */ { if (strlen(s) < 3) return (FALSE); if (!strncmp(s, "DEL", 3)) return (TRUE); if (!strncmp(s, "REP", 3)) return (TRUE); if (!strncmp(s, "ADD", 3)) return (TRUE); return (FALSE); }