static int view_fli(char *name, Vscreen *screen, int loop) { struct fli_head fh; FILE *fd; long clock; int i; long f1off; if ((fd = read_fli_head(name, &fh)) == 0) return(0); clock = get80hz(); mouse_on = 0; if (loop) { if (!read_next_frame(name,fd,screen,1)) goto OUT; f1off = jtell(fd); clock += fh.speed; if (!wait_til(clock)) goto OUT; if (clock > get80hz()) clock = get80hz(); } do { for (i=0; i<fh.frame_count; i++) { if (!read_next_frame(name,fd,screen,1)) goto OUT; clock += fh.speed; if (!wait_til(clock)) goto OUT; if (clock > get80hz()) clock = get80hz(); } if (loop) jseek(fd, f1off, 0); } while (loop); OUT: jclose(fd); mouse_on = 1; }
void *load_exe(char *filename, Exe_head *eh) { long retval; char *alligned_buf; char *alloc_buf = NULL; long (*rfunc)(); unsigned long code_offset; unsigned long init_size; unsigned long bss_size; unsigned long total_size; void *v; unsigned long fixup_offset; UWORD fixup[2]; UWORD *segpt; UWORD code_seg; int f; unsigned i; int ok = 0; if ((f = jopen(filename, JREADONLY)) == 0) { cant_find(filename); return(NULL); } if (!verify_exe_head(f, eh)) goto OUT; code_offset = eh->head_size; code_offset *= 16; /* make it a paragraph */ init_size = eh->blocks; init_size *= 512; init_size += eh->mod512; if (eh->mod512 != 0) init_size -= 512; init_size -= code_offset; bss_size = eh->min_data; bss_size *= 16; total_size = init_size + bss_size; if ((alloc_buf = begmem((unsigned)total_size+16)) == NULL) goto OUT; code_seg = ptr_seg(alloc_buf) + 1; alligned_buf = make_ptr(0, code_seg); zero_structure(alligned_buf, (unsigned)total_size); jseek(f, code_offset, JSEEK_START); if (jread(f, alligned_buf, init_size) < init_size) { truncated(filename); goto OUT; } v = alligned_buf; eh->entry_point = v; if (eh->reloc_count > 0) { fixup_offset = eh->reloc_list; jseek(f, fixup_offset, JSEEK_START); for (i=0; i<eh->reloc_count; i++) { if (jread(f, fixup, sizeof(fixup)) != sizeof(fixup)) { truncated(filename); goto OUT; } segpt = make_ptr(fixup[0], code_seg + fixup[1]); segpt[0] += code_seg; } } ok = 1; OUT: if (!ok) { gentle_freemem(alloc_buf); alloc_buf = NULL; } jclose(f); return(alloc_buf); }
int main(int ac, char **av) { const char *input_prefix = NULL; char *output_transid_file = NULL; char *mirror_transid_file = NULL; const char *mirror_directory = "."; char *record_prefix = NULL; char *record_transid_file = NULL; struct jsession jsdebug; struct jsession jsoutput; struct jsession jsmirror; char *ptr; int64_t mirror_transid; int64_t output_transid; int64_t record_transid; int64_t transid; int input_fd; struct stat st; struct jfile *jf; struct jdata *jd; int ch; while ((ch = getopt(ac, av, "2c:dfm:o:s:uvw:D:O:W:F")) != -1) { switch(ch) { case '2': jmodes |= JMODEF_INPUT_FULL; break; case 'c': trans_count = strtoll(optarg, &ptr, 0); switch(*ptr) { case 't': trans_count *= 1024; /* fall through */ case 'g': trans_count *= 1024; /* fall through */ case 'm': trans_count *= 1024; /* fall through */ case 'k': trans_count *= 1024; break; case 0: break; default: fprintf(stderr, "Bad suffix for value specified with -c, use 'k', 'm', 'g', 't', or nothing\n"); usage(av[0]); } break; case 'd': jmodes |= JMODEF_DEBUG; break; case 'f': jmodes |= JMODEF_LOOP_FOREVER; break; case 'v': ++verbose_opt; break; case 'm': jmodes |= JMODEF_MIRROR; if (strcmp(optarg, "none") != 0) mirror_transid_file = optarg; break; case 'O': jmodes |= JMODEF_OUTPUT_FULL; /* fall through */ case 'o': jmodes |= JMODEF_OUTPUT; if (strcmp(optarg, "none") != 0) output_transid_file = optarg; break; case 's': prefix_file_size = strtoll(optarg, &ptr, 0); switch(*ptr) { case 't': prefix_file_size *= 1024; /* fall through */ case 'g': prefix_file_size *= 1024; /* fall through */ case 'm': prefix_file_size *= 1024; /* fall through */ case 'k': prefix_file_size *= 1024; break; case 0: break; default: fprintf(stderr, "Bad suffix for value specified with -s, use 'k', 'm', 'g', 't', or nothing\n"); usage(av[0]); } break; case 'u': jdirection = JD_BACKWARDS; break; case 'W': jmodes |= JMODEF_RECORD_TMP; /* fall through */ case 'w': jmodes |= JMODEF_RECORD; record_prefix = optarg; asprintf(&record_transid_file, "%s.transid", record_prefix); break; case 'D': mirror_directory = optarg; break; case 'F': ++fsync_opt; break; default: fprintf(stderr, "unknown option: -%c\n", optopt); usage(av[0]); } } /* * Sanity checks */ if ((jmodes & JMODEF_COMMAND_MASK) == 0) usage(av[0]); if (optind > ac + 1) { fprintf(stderr, "Only one input file or prefix may be specified,\n" "or zero if stdin is to be the input.\n"); usage(av[0]); } if (strcmp(mirror_directory, ".") != 0) { struct stat sb; if (stat(mirror_directory, &sb) != 0) { perror ("Could not stat mirror directory"); usage(av[0]); } if (!S_ISDIR(sb.st_mode)) { fprintf (stderr, "Mirror directory '%s' is not a directory\n", mirror_directory); usage(av[0]); } } if (jdirection == JD_BACKWARDS && (jmodes & (JMODEF_RECORD|JMODEF_OUTPUT))) { fprintf(stderr, "Undo mode is only good in mirroring mode and " "cannot be mixed with other modes.\n"); exit(1); } /* * STEP1 - OPEN INPUT * * The input will either be a pipe, a regular file, or a journaling * file prefix. */ jf = NULL; if (optind == ac) { input_prefix = "<stdin>"; input_fd = 0; if (fstat(0, &st) < 0 || !S_ISREG(st.st_mode)) { jmodes |= JMODEF_INPUT_PIPE; if (jdirection == JD_BACKWARDS) { fprintf(stderr, "Cannot scan journals on pipes backwards\n"); usage(av[0]); } } jf = jopen_fd(input_fd); } else if (stat(av[optind], &st) == 0 && S_ISREG(st.st_mode)) { input_prefix = av[optind]; if ((input_fd = open(av[optind], O_RDONLY)) != 0) { jf = jopen_fd(input_fd); } else { jf = NULL; } } else { input_prefix = av[optind]; jf = jopen_prefix(input_prefix, 0); jmodes |= JMODEF_INPUT_PREFIX; } if (jf == NULL) { fprintf(stderr, "Unable to open input %s: %s\n", input_prefix, strerror(errno)); exit(1); } /* * STEP 1 - SYNCHRONIZING THE INPUT STREAM * * Figure out the starting point for our various output modes. Figure * out the earliest transaction id and try to seek to that point, * otherwise we might have to scan through terrabytes of data. * * Invalid transid's will be set to 0, but it should also be noted * that 0 is also a valid transid. */ get_transid_from_file(output_transid_file, &output_transid, JMODEF_OUTPUT_TRANSID_GOOD); get_transid_from_file(mirror_transid_file, &mirror_transid, JMODEF_MIRROR_TRANSID_GOOD); get_transid_from_file(record_transid_file, &record_transid, JMODEF_RECORD_TRANSID_GOOD); transid = LLONG_MAX; if ((jmodes & JMODEF_OUTPUT_TRANSID_GOOD) && output_transid < transid) transid = output_transid; if ((jmodes & JMODEF_MIRROR_TRANSID_GOOD) && mirror_transid < transid) transid = mirror_transid; if ((jmodes & JMODEF_RECORD_TRANSID_GOOD) && record_transid < transid) transid = record_transid; if ((jmodes & JMODEF_TRANSID_GOOD_MASK) == 0) transid = 0; if (verbose_opt) { if (jmodes & JMODEF_OUTPUT) { fprintf(stderr, "Starting transid for OUTPUT: %016jx\n", (uintmax_t)output_transid); } if (jmodes & JMODEF_MIRROR) { fprintf(stderr, "Starting transid for MIRROR: %016jx\n", (uintmax_t)mirror_transid); } if (jmodes & JMODEF_RECORD) { fprintf(stderr, "Starting transid for RECORD: %016jx\n", (uintmax_t)record_transid); } } if (strcmp(mirror_directory, ".") != 0) { if (chdir (mirror_directory) != 0) { perror ("Could not enter mirror directory"); exit (1); } } /* * Now it gets more difficult. If we are recording then the input * could be representative of continuing data and not have any * prior, older data that the output or mirror modes might need. Those * modes must work off the recording data even as we write to it. * In that case we fork and have the sub-processes work off the * record output. * * Then we take the input and start recording. */ if (jmodes & JMODEF_RECORD) { if (jrecord_init(record_prefix) < 0) { fprintf(stderr, "Unable to initialize file set for: %s\n", record_prefix); exit(1); } if (jmodes & JMODEF_MIRROR) { fork_subprocess(jf, jscan_do_mirror, record_prefix, mirror_transid_file, mirror_directory, mirror_transid); /* XXX ack stream for temporary record file removal */ } if (jmodes & JMODEF_OUTPUT) { fork_subprocess(jf, jscan_do_output, record_prefix, record_transid_file, NULL, output_transid); /* XXX ack stream for temporary record file removal */ } jscan_do_record(jf, record_transid_file, record_prefix, record_transid); exit(0); } /* * If the input is a prefix set we can just pass it to the appropriate * jscan_do_*() function. If we are doing both output and mirroring * we fork the mirror and do the output in the foreground since that * is going to stdout. */ if (jmodes & JMODEF_INPUT_PREFIX) { if ((jmodes & JMODEF_OUTPUT) && (jmodes & JMODEF_MIRROR)) { fork_subprocess(jf, jscan_do_mirror, input_prefix, mirror_transid_file, mirror_directory, mirror_transid); jscan_do_output(jf, output_transid_file, NULL, output_transid); } else if (jmodes & JMODEF_OUTPUT) { jscan_do_output(jf, output_transid_file, NULL, output_transid); } else if (jmodes & JMODEF_MIRROR) { jscan_do_mirror(jf, mirror_transid_file, mirror_directory, mirror_transid); } else if (jmodes & JMODEF_DEBUG) { jscan_do_debug(jf, NULL, NULL, 0); } exit(0); } /* * The input is not a prefix set and we are not recording, which means * we have to transfer the data on the input pipe to the output and * mirroring code on the fly. This also means that we must keep track * of meta-data records in-memory. However, if the input is a regular * file we *CAN* try to optimize where we start reading. * * NOTE: If the mirroring code encounters a transaction record that is * not marked begin, and it does not have the begin record, it will * attempt to locate the begin record if the input is not a pipe, then * seek back. */ if ((jmodes & JMODEF_TRANSID_GOOD_MASK) && !(jmodes & JMODEF_INPUT_PIPE)) jd = jseek(jf, transid, jdirection); else jd = jread(jf, NULL, jdirection); jmodes |= JMODEF_MEMORY_TRACKING; jsession_init(&jsdebug, jf, jdirection, NULL, 0); jsession_init(&jsoutput, jf, jdirection, output_transid_file, output_transid); jsession_init(&jsmirror, jf, jdirection, mirror_transid_file, mirror_transid); jsmirror.ss_mirror_directory = mirror_directory; while (jd != NULL) { if ((jmodes & JMODEF_DEBUG) && jsession_check(&jsdebug, jd)) dump_debug(&jsdebug, jd); if ((jmodes & JMODEF_OUTPUT) && jsession_check(&jsoutput, jd)) dump_output(&jsoutput, jd); if ((jmodes & JMODEF_MIRROR) && jsession_check(&jsmirror, jd)) dump_mirror(&jsmirror, jd); if (donecheck(jdirection, jd, transid)) { jfree(jf, jd); break; } jd = jread(jf, jd, jdirection); } jclose(jf); jsession_term(&jsdebug); jsession_term(&jsoutput); jsession_term(&jsmirror); return(0); }