// get arch offset in file bool get_arch_off(int fd, cpu_type_t cputype, off_t *offset) { struct fat_header fatheader; struct fat_arch fatarch; off_t img_start = 0; off_t pos = ltell(fd); if (read(fd, (void *)&fatheader, sizeof(struct fat_header)) != sizeof(struct fat_header)) { return false; } if (fatheader.magic == FAT_CIGAM) { int i; for (i = 0; i < ntohl(fatheader.nfat_arch); i++) { if (read(fd, (void *)&fatarch, sizeof(struct fat_arch)) != sizeof(struct fat_arch)) { return false; } if (ntohl(fatarch.cputype) == cputype) { print_debug("fat offset=%x\n", ntohl(fatarch.offset)); img_start = ntohl(fatarch.offset); break; } } if (img_start == 0) { return false; } } lseek(fd, pos, SEEK_SET); *offset = img_start; return true; }
/* This is the first stream in the pipeline, so pr is irrelevant. */ static int s_fileno_read_process(stream_state * st, stream_cursor_read * ignore_pr, stream_cursor_write * pw, bool last) { stream *s = (stream *)st; /* no separate state */ int fd = sfileno(s); uint max_count; int nread, status; again: max_count = pw->limit - pw->ptr; status = 1; if (s->file_limit < max_long) { long limit_count = s->file_offset + s->file_limit - ltell(fd); if (max_count > limit_count) max_count = limit_count, status = EOFC; } /* * In the Mac MetroWerks compiler, the prototype for read incorrectly * declares the second argument of read as char * rather than void *. * Work around this here. */ nread = read(fd, (void *)(pw->ptr + 1), max_count); if (nread > 0) pw->ptr += nread; else if (nread == 0) status = EOFC; else if (errno_is_retry(errno)) /* Handle System V interrupts */ goto again; else status = ERRC; process_interrupts(s->memory); return status; }
/* Procedures for reading from a file */ static int s_fileno_available(register stream * s, long *pl) { long max_avail = s->file_limit - stell(s); long buf_avail = sbufavailable(s); int fd = sfileno(s); *pl = min(max_avail, buf_avail); if (sseekable(s)) { long pos, end; pos = ltell(fd); if (pos < 0) return ERRC; end = lseek(fd, 0L, SEEK_END); if (lseek(fd, pos, SEEK_SET) < 0 || end < 0) return ERRC; buf_avail += end - pos; *pl = min(max_avail, buf_avail); if (*pl == 0) *pl = -1; /* EOF */ } else { if (*pl == 0) *pl = -1; /* EOF */ } return 0; }
/* Initialize a stream for reading an OS file. */ void sread_fileno(register stream * s, FILE * file, byte * buf, uint len) { static const stream_procs p = { s_fileno_available, s_fileno_read_seek, s_std_read_reset, s_std_read_flush, s_fileno_read_close, s_fileno_read_process, s_fileno_switch }; /* * There is no really portable way to test seekability, * but this should work on most systems. */ int fd = fileno(file); long curpos = ltell(fd); bool seekable = (curpos != -1L && lseek(fd, curpos, SEEK_SET) != -1L); s_std_init(s, buf, len, &p, (seekable ? s_mode_read + s_mode_seek : s_mode_read)); if_debug2('s', "[s]read file=0x%lx, fd=%d\n", (ulong) file, fileno(file)); s->file = file; s->file_modes = s->modes; s->file_offset = 0; s->file_limit = max_long; }
bool is_macho_file(int fd) { mach_header_64 fhdr; off_t x86_64_off; if (fd < 0) { print_debug("Invalid file handle passed to is_macho_file\n"); return false; } off_t pos = ltell(fd); // check fat header if (!get_arch_off(fd, CPU_TYPE_X86_64, &x86_64_off)) { print_debug("failed to get fat header\n"); return false; } lseek(fd, x86_64_off, SEEK_SET); if (read(fd, (void *)&fhdr, sizeof(mach_header_64)) != sizeof(mach_header_64)) { return false; } lseek(fd, pos, SEEK_SET); // restore print_debug("fhdr.magic %x\n", fhdr.magic); return (fhdr.magic == MH_MAGIC_64 || fhdr.magic == MH_CIGAM_64); }
int mbtransfer (char *ziel) //************************************************************************* // // TRANSFER-Prozedur // (wird fuer jedes transferierte File einzeln aufgerufen) // //************************************************************************* { char name[20]; strcpy(name, "mbtransfer"); lastfunc(name); char *line = b->line; int findex; FILE *oldf, *newf; char usermail = 0; int retwert = NO; int nocp; //no-copy flag char oldsubject[101]; unsigned long int oldfpos; char oldmsgty; char oldmailfname[10]; time_t oldmsgtime; char old_ziel[DIRLEN+1]; int old_usermail; char oldboardname[10]; char oldmailpath[FNAMELEN+1]; char zielcall[CALLEN+1]; char newcall[CALLEN+1]; int gleichesboard = NO; unsigned long nummer; #ifdef USERLT short int old_lt; #endif #ifdef DEBUG_FWD trace(report, "mbtransfer", "ziel: %s", ziel); #endif strupr(ziel); nexttoken(ziel, zielcall, CALLEN); strcpy(oldmailpath, b->mailpath); if (sema_test("sendlock") || m.disable) { putf(ms(m_sendnotpossible)); return NO; } if (mbcallok(zielcall)) { // Use newcall if (get_newcall(zielcall, newcall)) { strcpy(zielcall, newcall); putf(ms(m_usingnewcall), newcall); } } char *bbuf = (char *) t_malloc(sizeof(tvar_t) - sizeof(task_t), "tran"); char *oldfname; oldfname = (char *) t_malloc(sizeof(char) * (FNAMELEN+1), "tra2"); if (! bbuf || ! oldfname) return NO; memcpy(bbuf, (char *) b + sizeof(task_t), sizeof(tvar_t) - sizeof(task_t)); strlwr(b->mailpath); strcpy(oldfname, b->mailpath); strcpy(oldmailfname, b->mailfname); oldmsgtime = filename2time(b->mailfname); if ((oldf = s_fopen(oldfname, "srt")) != NULL) { fgets(b->line, BUFLEN - 1, oldf); // Befehlszeile einlesen mbsend_parse(line, 0); if (b->mailtype == 'A' || (b->mailtype == 'B' && b->eraseinfo == 'T')) { retwert = NIL; s_fclose(oldf); goto error_exit; } oldmsgty = b->conttype; // save mailflags ...(conttype) fgets(b->line, BUFLEN - 1, oldf); // Forwardzeile vernichten fgets(b->line, BUFLEN - 1, oldf); // Read-Zeile fgets(oldsubject, BETREFFLEN, oldf); // Betreff cut_blank(oldsubject); // Newline entfernen if (mbcallok(zielcall)) *b->at = 0; // Verteiler loeschen -> Neubestimmen strcpy(old_ziel, b->ziel); #ifdef USERLT old_lt = b->lifetime; b->lifetime = 0; #endif old_usermail = b->usermail; mbsend_parse(ziel, 2); if (! stricmp(b->ziel, b->mailpath+strlen(b->mailpath)-strlen(b->ziel)-8)) { retwert = NIL; s_fclose(oldf); goto error_exit; } b->conttype = oldmsgty; // set mailflags again.. (conttype) if (b->mailtype == 'B' && ! old_usermail) strcpy(b->ziel, old_ziel); weiterleiten(1, b->zielboard); waitfor(e_ticsfull); findex = finddir(b->zielboard, b->sysop); if (findex && !(strlen(b->zielboard)==1 && !b->sysop)) { if (xmkdir(b->boardpath)) { trace(serious, name, "mkdir %s error", b->boardpath); s_fclose(oldf); goto error_exit; } nocp = ! strcmp(b->herkunft, b->logincall) || b->sysop; //kein "CP " wenn Sysop! if (nocp || b->mailtype == 'B') strcpy(b->betreff, oldsubject); else sprintf(b->betreff, "CP %s: %.67s", b->logincall, oldsubject); //Bei Nicht-Bulletin BID neu generieren bzw. wenn BID fehlt if (b->mailtype != 'B'|| ! *b->bid) strcpy(b->bid, newbid()); make_mask(b->mailpath, b->boardfullname); strcpy(b->mask, b->mailpath); // Ursprungsboardnamen aus b->mailpath holen und mit ziel vergleichen strcpy(oldboardname, b->boardname); oldmailpath[strlen(oldmailpath)-8] = 0; if (finddir(oldmailpath,0) > 0) { if (! strcmp(ziel, b->boardname)) gleichesboard = YES; } else gleichesboard = NO; strcpy(b->boardname,oldboardname); // b->boardname wieder herstellen // bei Usermail oder gleichem Board zum Sortieren // Filezeit/-namen neu setzen if (mbcallok(zielcall) || gleichesboard) { strcpy(b->mailfname, time2filename(0)); } else strcpy(b->mailfname, oldmailfname); if (! strstr(b->mailpath, "*.*")) trace(fatal, name, "mask %s", b->mailpath); strcpy(strstr(b->mailpath, "*.*"), b->mailfname); strlwr(b->mailpath); if ((newf = s_fopen(b->mailpath, "sw+t")) != NULL) { s_fsetopt(newf, 1); #ifdef USERLT set_boardlife_max(old_lt); b->lifetime = old_lt; #endif writeheader(newf, 1); if (b->mailtype != 'B') { if (fgets(b->line, BUFLEN - 1, oldf)) { do { // fputs(line,f); skip old R-lines waitfor(e_ticsfull); fgets(b->line, BUFLEN - 1, oldf); } while (! feof(oldf) && *line == 'R' && line[1] == ':'); } fprintf(newf, "%s\n", makeheader(1)); fprintf(newf, "X-Transfer: %s by %s @ %s\n", datestr(ad_time(), 12), b->logincall, m.boxadress); fprintf(newf, "X-Original-Date: %s\n", datestr(oldmsgtime, 10)); do { if(( ! strncasecmp(line, "from", 4) || ! strncmp(line, "de: ", 4) || ! strncmp(line, "de ", 3) || ! strncmp(line, "fm ", 3)) && ! nocp) fprintf(newf, "X-Originally %s", line); else if (( ! strncasecmp(line, "to: ", 4) || ! strncasecmp(line, "to ", 3)) && ! nocp) fprintf(newf, "X-Originally %s", line); else if (! strncmp(line, "X-MID: ", 7)) fprintf(newf, "X-Old-MID: %s", line + 7); else if (! strncmp(line, "X-BID: ", 7)) fprintf(newf, "X-Old-BID: %s", line + 7); else fputs(line, newf); waitfor(e_ticsfull); fgets(b->line, BUFLEN - 1, oldf); } while (! feof(oldf) && *line != LF); fputc(LF, newf); } //Files binaer behandeln oldfpos = ftell(oldf); s_fclose(oldf); s_fclose(newf); writemailflags(); if ((oldf = s_fopen(oldfname, "srb")) != NULL) { if ((newf = s_fopen(b->mailpath, "sab")) != NULL) //append to file { fseek(oldf, oldfpos, SEEK_SET); do { //oe3dzw: Transferroutine transparent int len; len = fread(line, 1, 255, oldf); if (len) fwrite(line, 1, len, newf); waitfor(e_ticsfull); } while (! feof(oldf)); if (b->binstart) //bei binaeren Mails offset neu berechnen { b->binstart += ftell(newf) - ftell(oldf); if (b->binstart < 0) trace(serious, name, "offset %ld in %s", b->binstart, b->mailpath); } s_fclose(newf); if (b->binstart) writelines(); //Neuen Binstart speichern if (b->bytes) { if (old_usermail || gleichesboard) nummer = appenddirlist(1); else nummer = appenddirlist(0); //change old CHECKLINE if (b->usermail) { add_fwdfile("", get_fdelay(b->herkunft), 0); sprintf(b->line, "%s %lu", b->herkunft, nummer); mbtalk("\001", b->zielboard, b->line); trigger_ufwd(b->zielboard); } else { handle fh; char found; if (old_usermail) add_fwdfile("", get_fdelay(b->herkunft), 0); else add_fwdfile("", get_fdelay(b->herkunft), 1); if (findex > 0) tree[findex - 1].newestmail = oldmsgtime; if ((fh = s_open(CHECKNAME, "sr+b")) != EOF) { seek_fname(fh, b->mailfname, &found, 1); long pos = ltell(fh); if (found) { _read(fh, b->line, BLEN); sprintf(b->line + 15, "%-8s", b->boardname); b->line[23] = '~'; #ifdef USERLT char nlt[4]; sprintf(nlt, "%3.3d", b->boardlife_max); memcpy(b->line + 51, nlt, 3); #endif lseek(fh, -(LBLEN), SEEK_CUR); _write(fh, b->line, BLEN); } s_close(fh); if (found && (fh = s_open(CHECKNUMNAME, "sr+b")) != EOF) { lseek(fh, 2*(pos >> 6), SEEK_SET); //2* da 32bit! _write(fh, &nummer, 4); // 4Byte=32 bit s_close(fh); } } else trace(serious, name, "check"); } inc_mailgot(b->boardname); writemailflags(); retwert = OK;
// read symbol table from given fd. struct symtab* build_symtab(int fd) { symtab_t* symtab = NULL; int i; mach_header_64 header; off_t image_start; if (!get_arch_off(fd, CPU_TYPE_X86_64, &image_start)) { print_debug("failed in get fat header\n"); return NULL; } lseek(fd, image_start, SEEK_SET); if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) { print_debug("reading header failed!\n"); return NULL; } // header if (header.magic != MH_MAGIC_64) { print_debug("not a valid .dylib file\n"); return NULL; } load_command lcmd; symtab_command symtabcmd; nlist_64 lentry; bool lcsymtab_exist = false; long filepos = ltell(fd); for (i = 0; i < header.ncmds; i++) { lseek(fd, filepos, SEEK_SET); if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) { print_debug("read load_command failed for file\n"); return NULL; } filepos += lcmd.cmdsize; // next command position if (lcmd.cmd == LC_SYMTAB) { lseek(fd, -sizeof(load_command), SEEK_CUR); lcsymtab_exist = true; break; } } if (!lcsymtab_exist) { print_debug("No symtab command found!\n"); return NULL; } if (read(fd, (void *)&symtabcmd, sizeof(symtab_command)) != sizeof(symtab_command)) { print_debug("read symtab_command failed for file"); return NULL; } symtab = (symtab_t *)malloc(sizeof(symtab_t)); if (symtab == NULL) { print_debug("out of memory: allocating symtab\n"); return NULL; } // create hash table, we use berkeley db to // manipulate the hash table. symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL); if (symtab->hash_table == NULL) goto quit; symtab->num_symbols = symtabcmd.nsyms; symtab->symbols = (symtab_symbol *)malloc(sizeof(symtab_symbol) * symtab->num_symbols); symtab->strs = (char *)malloc(sizeof(char) * symtabcmd.strsize); if (symtab->symbols == NULL || symtab->strs == NULL) { print_debug("out of memory: allocating symtab.symbol or symtab.strs\n"); goto quit; } lseek(fd, image_start + symtabcmd.symoff, SEEK_SET); for (i = 0; i < symtab->num_symbols; i++) { if (read(fd, (void *)&lentry, sizeof(nlist_64)) != sizeof(nlist_64)) { print_debug("read nlist_64 failed at %i\n", i); goto quit; } symtab->symbols[i].offset = lentry.n_value; symtab->symbols[i].size = lentry.n_un.n_strx; // index } // string table lseek(fd, image_start + symtabcmd.stroff, SEEK_SET); int size = read(fd, (void *)(symtab->strs), symtabcmd.strsize * sizeof(char)); if (size != symtabcmd.strsize * sizeof(char)) { print_debug("reading string table failed\n"); goto quit; } for (i = 0; i < symtab->num_symbols; i++) { symtab->symbols[i].name = symtab->strs + symtab->symbols[i].size; if (i > 0) { // fix size symtab->symbols[i - 1].size = symtab->symbols[i].size - symtab->symbols[i - 1].size; print_debug("%s size = %d\n", symtab->symbols[i - 1].name, symtab->symbols[i - 1].size); } if (i == symtab->num_symbols - 1) { // last index symtab->symbols[i].size = symtabcmd.strsize - symtab->symbols[i].size; print_debug("%s size = %d\n", symtab->symbols[i].name, symtab->symbols[i].size); } } // build a hashtable for fast query build_search_table(symtab); return symtab; quit: if (symtab) destroy_symtab(symtab); return NULL; }