// 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;
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
/* 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;
}
Beispiel #4
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);
}
Beispiel #6
0
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;
Beispiel #7
0
// 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;
}