void write_directory_file (void) { FILE *fp = listed_incremental_stream; char buf[UINTMAX_STRSIZE_BOUND]; char *s; if (! fp) return; if (fseeko (fp, 0L, SEEK_SET) != 0) seek_error (listed_incremental_option); if (sys_truncate (fileno (fp)) != 0) truncate_error (listed_incremental_option); fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION, TAR_INCREMENTAL_VERSION); s = (TYPE_SIGNED (time_t) ? imaxtostr (start_time.tv_sec, buf) : umaxtostr (start_time.tv_sec, buf)); fwrite (s, strlen (s) + 1, 1, fp); s = umaxtostr (start_time.tv_nsec, buf); fwrite (s, strlen (s) + 1, 1, fp); if (! ferror (fp) && directory_table) hash_do_for_each (directory_table, write_directory_file_entry, fp); if (ferror (fp)) write_error (listed_incremental_option); if (fclose (fp) != 0) close_error (listed_incremental_option); }
/* Reads in a value from the constant pool. */ void skip_constant(FILE *classfile, u_int16_t *cur) { u_int16_t len; int seekerr = 1; pool[*cur] = ftell(classfile); switch(read_8(classfile)) { case CP_UTF8: len = read_16(classfile); seekerr = fseek(classfile, len, SEEK_CUR); break; case CP_CLASS: case CP_STRING: seekerr = fseek(classfile, 2, SEEK_CUR); break; case CP_INTEGER: case CP_FLOAT: case CP_FIELDREF: case CP_METHODREF: case CP_INTERFACEMETHODREF: case CP_NAMEANDTYPE: seekerr = fseek(classfile, 4, SEEK_CUR); break; case CP_LONG: case CP_DOUBLE: seekerr = fseek(classfile, 8, SEEK_CUR); ++(*cur); break; default: corrupt_error(); } if(seekerr) seek_error(); }
void seg::seekg(stream::delta off, seek_from from) { // Calculate stream size stream::pos lenFirst = this->off_endparent - this->off_parent; stream::pos lenTotal = lenFirst; lenTotal += this->vcSecond.size(); stream::pos offSecondEnd = lenTotal; if (this->psegThird) lenTotal += this->psegThird->size(); stream::pos baseOffset; switch (from) { case cur: baseOffset = this->offset; break; case end: baseOffset = lenTotal; break; default: baseOffset = 0; break; } if ((off < 0) && (baseOffset < (unsigned)(off * -1))) { throw seek_error("Cannot seek back past start of segstream"); } baseOffset += off; if (baseOffset > lenTotal) { throw seek_error(createString("Cannot seek beyond end of segstream (offset " << baseOffset << " > length " << lenTotal << ")")); } this->offset = baseOffset; // The seek pointer can't be updated here, because it's shared by all the // descendent psegThird elements. // But we can let the third source know where we'll come in when we read // straight through later. if (this->psegThird) { if (this->offset >= offSecondEnd) { this->psegThird->seekg(this->offset - offSecondEnd, stream::start); } else { this->psegThird->seekg(0, stream::start); } } return; }
int main(int argc, char **argv) { FILE *classfile; u_int16_t cp_count, i, this_class, classinfo_ptr; u_int8_t length; program = argv[0]; if(!argv[1]) error("%s: Missing input file\n", program); classfile = fopen(argv[1], "rb"); if(!classfile) error("%s: Error opening %s\n", program, argv[1]); if(fseek(classfile, 8, SEEK_SET)) /* skip magic and version numbers */ seek_error(); cp_count = read_16(classfile); pool = calloc(cp_count, sizeof(long)); if(!pool) error("%s: Out of memory for constant pool\n", program); for(i = 1; i < cp_count; ++i) skip_constant(classfile, &i); if(fseek(classfile, 2, SEEK_CUR)) /* skip access flags */ seek_error(); this_class = read_16(classfile); if(this_class < 1 || this_class >= cp_count) corrupt_error(); if(!pool[this_class] || pool[this_class] == -1) corrupt_error(); if(fseek(classfile, pool[this_class] + 1, SEEK_SET)) seek_error(); classinfo_ptr = read_16(classfile); if(classinfo_ptr < 1 || classinfo_ptr >= cp_count) corrupt_error(); if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1) corrupt_error(); if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET)) seek_error(); length = read_16(classfile); for(i = 0; i < length; ++i) { u_int8_t x = read_8(classfile); if((x & 0x80) || !x) { if((x & 0xE0) == 0xC0) { u_int8_t y = read_8(classfile); if((y & 0xC0) == 0x80) { int c = ((x & 0x1f) << 6) + (y & 0x3f); if(c) putchar(c); else utf8_error(); } else utf8_error(); } else utf8_error(); } else if(x == '/') putchar('.'); else putchar(x); } putchar('\n'); free(pool); fclose(classfile); return 0; }