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

enum ArStatus ArchiveLynx ( const struct Archive archive,
const char *  filename 
)

Write an archive in Lynx format

Parameters:
archive the archive to be written
filename host file name of the archive file
Returns:
status of the operation

Definition at line 309 of file lynx.c.

References ArFail, ArNoSpace, ArOK, ArchiveEntry::data, Archive::first, ArchiveEntry::length, Filename::name, ArchiveEntry::name, ArchiveEntry::next, Filename::recordLength, REL, rounddiv, and Filename::type.

{
  FILE* f;
  struct ArchiveEntry* ae;
  int blockcounter;

  static const byte_t basichdr[] = {
    0x01, 0x08, 0x5b, 0x08, 0x0a, 0x00, 0x97, 0x35,
    0x33, 0x32, 0x38, 0x30, 0x2c, 0x30, 0x3a, 0x97,
    0x35, 0x33, 0x32, 0x38, 0x31, 0x2c, 0x30, 0x3a,
    0x97, 0x36, 0x34, 0x36, 0x2c, 0xc2, 0x28, 0x31,
    0x36, 0x32, 0x29, 0x3a, 0x99, 0x22, 0x93, 0x11,
    0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22,
    0x3a, 0x99, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
    0x55, 0x53, 0x45, 0x20, 0x4c, 0x59, 0x4e, 0x58,
    0x20, 0x54, 0x4f, 0x20, 0x44, 0x49, 0x53, 0x53,
    0x4f, 0x4c, 0x56, 0x45, 0x20, 0x54, 0x48, 0x49,
    0x53, 0x20, 0x46, 0x49, 0x4c, 0x45, 0x22, 0x3a,
    0x89, 0x31, 0x30, 0x00, 0x00, 0x00, 0x0d
  };

  static const byte_t lynxhdr[] = "*LYNX BY CBMCONVERT 2.0*";

  {
    unsigned filecnt;
    /* Count the files. */
    for (filecnt = 0, ae = archive->first; ae; filecnt++)
      ae = ae->next;
    if (!filecnt)
      return ArFail;

    /* Write the Lynx header. */

    if (!(f = fopen (filename, "wb")))
      return errno == ENOSPC ? ArNoSpace : ArFail;

    if (1 != fwrite (basichdr, sizeof basichdr, 1, f)) {
      fclose (f);
      return errno == ENOSPC ? ArNoSpace : ArFail;
    }

    /* This is a bit overestimating the header size. */
    blockcounter = rounddiv(sizeof basichdr + 20 + sizeof lynxhdr +
                      36 * filecnt, 254);

    fprintf (f, " %u  %s\15 %u \15", blockcounter, lynxhdr, filecnt);
  }

  if (ferror (f))
    return errno == ENOSPC ? ArNoSpace : ArFail;

  /* Write the Lynx directory. */
  for (ae = archive->first; ae; ae = ae->next) {
    int i;
    /* Write the file name.  Replace CRs with periods. */
    for (i = 0; i < sizeof(ae->name.name) && i < 16; i++)
      putc (ae->name.name[i] == 13 ? '.' : ae->name.name[i], f);

    i = rounddiv(ae->length, 254);

    fprintf (f, "\15 %u\15%c\15",
           ae->name.type == REL ? i + rounddiv(i, 120) : i,
           "DSPUR"[ae->name.type & 7]);
    if (ae->name.type == REL)
      fprintf (f, " %u \15", ae->name.recordLength);

    fprintf (f, " %u \15",
           (unsigned)(ae->length % 254 ?
                  (ae->length - 254 * (i - 1) + 1) : 255));
  }

  if (ferror (f))
    return errno == ENOSPC ? ArNoSpace : ArFail;

  /* Write the files. */

  for (ae = archive->first; ae; ae = ae->next) {
    unsigned blocks = rounddiv(ae->length, 254);

    /* Reserve space for the side sectors. */
    if (ae->name.type == REL)
      blockcounter += (blocks + 119) / 121;

    /* Write the file. */
    if (fseek (f, blockcounter * 254, SEEK_SET) ||
      ae->length != fwrite (ae->data, 1, ae->length, f)) {
      fclose (f);
      return ArFail;
    }

    blockcounter += blocks;
  }

  fclose (f);
  return ArOK;
}


Generated by  Doxygen 1.6.0   Back to index