Logo Search packages:      
Sourcecode: cbmlink version File versions  Download package

static int rdfile_do ( const struct comm comm,
FILE *  file,
char *  buf,
unsigned  directory 
) [static]

read a file either as raw or decoded as a directory listing

Parameters:
comm the communication primitives
file output file (0=none)
buf at least 256-byte transfer buffer
directory flag: decode the file as a directory
Returns:
zero on success, nonzero on error

command for requesting next block

command for aborting the transfer

checksum

EOF flag and status, or length and checksum of available data

Definition at line 158 of file rdfile.c.

References comm::comm_read, comm::comm_rs, comm::comm_sr, comm::comm_write, and writedir().

Referenced by rdfile_copy(), and rdfile_raw().

{
  /** command for requesting next block */
  static const char cmd_next[2] = { (char) 0x80, 0 };
  /** command for aborting the transfer */
  static const char cmd_abort[2] = { (char) 0x82, 0 };
  if ((*comm->comm_write) (buf, ((unsigned) (unsigned char) *buf) + 2))
    return 3;
  (*comm->comm_sr) ();
  for (;;) {
    /** checksum */
    unsigned check;
    /** EOF flag and status, or length and checksum of available data */
    char reply[2];
    unsigned i;
    if ((*comm->comm_read) (reply, sizeof reply))
      return 3;
    if (!(i = (unsigned char) *reply)) {
      if (reply[1])
      fprintf (stderr, "rdfile failed with %u\n",
             (unsigned char) reply[1]);
      (*comm->comm_rs) ();
      return reply[1] || 0;
    }

    check = (unsigned char) reply[1];

    if ((*comm->comm_read) (buf, i))
      return 3;
    else {
      register const char* b = buf + i;
      while (b-- > buf)
      check -= (unsigned char) *b;
    }

    (*comm->comm_rs) ();

    if ((check -= i) & 0xff) {
      fputs ("rdfile: checksum mismatch; retrying\n", stderr);
      *buf = (char) 0x81;
      if ((*comm->comm_write) (buf, 1))
      return 3;
      (*comm->comm_sr) ();
      continue;
    }

    if (!file);
    else if (directory)
      writedir (buf, i, file);
    else if (i != fwrite (buf, 1, i, file)) {
      perror ("rdfile: fwrite");
      if ((*comm->comm_write) (cmd_abort, sizeof cmd_abort) ||
        ((*comm->comm_sr) (), (*comm->comm_read) (buf, 2)))
      return 3;
      if (*buf || buf[1])
      return 4;
      (*comm->comm_rs) ();
      return 1;
    }

    /* request next block */
    if ((*comm->comm_write) (cmd_next, sizeof cmd_next))
      return 3;
    (*comm->comm_sr) ();
  }
}


Generated by  Doxygen 1.6.0   Back to index