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

wrfile.c

Go to the documentation of this file.
/**
 * @file wrfile.c
 * Extension for writing files to the remote host
 * @author Marko Mäkelä (msmakela@nic.funet.fi)
 */

/*
 * Copyright © 1994-1996 Marko Mäkelä and Olaf Seibert
 * Copyright © 2001,2002 Marko Mäkelä
 * Original Linux and Commodore 64/128/Vic-20 version by Marko Mäkelä
 * Ported to the PET and the Amiga series by Olaf Seibert
 * Restructured by Marko Mäkelä
 * 
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with this program; if not, write to the Free Software
 *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "comm.h"
#include "info.h"
#include "ext.h"
#include <stdio.h>
#include <string.h>
#include "wrfile.h"
#include "wrfile-o.h"

/** install the wrfile extension
 * @param comm          the communication primitives
 * @param hostinfo      information on the remote host
 * @param device  device number
 * @param secondary     secondary address
 * @return        zero on success, nonzero on error
 */
int
00045 wrfile_install (const struct comm* comm,
            const struct hostinfo* hostinfo,
            unsigned device,
            unsigned secondary)
{
  switch (hostinfo->host) {
  case PET:
    break;
  case PET3:
    return ext (comm, hostinfo, wrfile_pet3000, sizeof wrfile_pet3000,
            device, secondary) ? 2 : 0;
  case PET4:
    return ext (comm, hostinfo, wrfile_pet4000, sizeof wrfile_pet4000,
            device, secondary) ? 2 : 0;
  case Vic: case C64: case C128: case C264:
    return ext (comm, hostinfo, wrfile_cbm, sizeof wrfile_cbm,
            device, secondary) ? 2 : 0;
  case P500: case B128: case B256:
    return ext (comm, hostinfo, wrfile_cbm2, sizeof wrfile_cbm2,
            device, secondary) ? 2 : 0;
  }

  fprintf (stderr, "wrfile: unsupported server %u\n", hostinfo->host);
  return 1;
}

/** remove the wrfile extension
 * @param comm          the communication primitives
 * @return        zero on success, nonzero on error
 */
int
00076 wrfile_remove (const struct comm* comm)
{
  unsigned char ch = 0xff;
  return (*comm->comm_write) (&ch, 1);
}

/** copy a file
 * @param comm          the communication primitives
 * @param filename      file name (including drive unit number)
 * @param file          input file
 * @param buf           at least 258-byte transfer buffer
 * @return        zero on success, nonzero on error
 */
int
00090 wrfile (const struct comm* comm,
      const char* filename,
      FILE* file,
      char* buf)
{
  unsigned i;
  for (i = 0; filename[i]; i++);
  if (i > 127)
    return fputs ("wrfile: too long file name\n", stderr), 2;
  memcpy (buf + 1, filename, i + 1);
  *buf = i;
  if ((*comm->comm_write) (buf, i + 2))
    return 3;
  (*comm->comm_sr) ();
  if ((*comm->comm_read) (buf, 1))
    return 3;
  else if (*buf) {
  wrfile_fail:
    fprintf (stderr, "wrfile `%s': failed with %u\n",
           filename, (unsigned char) *buf);
    (*comm->comm_rs) ();
    return *buf || 0;
  }

  while ((i = fread (buf + 2, 1, 255, file))) {
    /* compute the checksum */
    {
      unsigned check = i;
      register char* b = buf + i + 2;
      *b = 0, *buf = i;
      while (--b > buf + 1)
      check += (unsigned char) *b;
      buf[1] = check;
    }

    for (;;) {
      if ((*comm->comm_write) (buf, i + 3))
      return 3;
      else {
      unsigned char c;
      (*comm->comm_sr) ();
      if ((*comm->comm_read) (&c, 1))
        return 3;
      (*comm->comm_rs) ();
      if (c == 0x80)
        break;
      else if (c == 0x81)
        continue;
      *buf = c;
      goto wrfile_fail;
      }
    }
  }

  *buf = 0;
  return ((*comm->comm_write) (buf, 1)) ? 3 : 0;
}

Generated by  Doxygen 1.6.0   Back to index