OpenCBM
pc64.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version
5  * 2 of the License, or (at your option) any later version.
6  *
7  * Copyright 2001 Michael Klein <michael(dot)klein(at)puffin(dot)lb(dot)shuttle(dot)de>
8 */
9 
10 #include <ctype.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "inputfiles.h"
15 
16 static int probe(FILE *file, const char *fname, cbmcopy_message_cb msg_cb)
17 {
18  char sig[8];
19 
20  msg_cb( sev_debug, "checking for pc64" );
21 
22  if(fread( sig, sizeof(sig), 1, file ) == 1 &&
23  strncmp( sig, "C64File", 8 ) == 0)
24  {
25  msg_cb( sev_debug, "PC64 file detected: %s", fname );
26  return 1;
27  }
28  rewind( file );
29  return 0;
30 }
31 
32 
33 static int read(FILE *file, const char *fname, int entry,
34  char *cbmname, char *type,
35  unsigned char **data, size_t *size,
36  cbmcopy_message_cb msg_cb)
37 {
38  const char *ext;
39 
40  struct
41  {
42  unsigned char sig[8];
43  unsigned char cbmname[16];
44  unsigned char zero;
45  unsigned char reclen;
46  } pc64header;
47 
48  rewind( file );
49 
50  if(entry != 0)
51  {
52  msg_cb( sev_warning, "invalid PC64 entry" );
53  return 1;
54  }
55 
56  if(fread( &pc64header, sizeof(pc64header), 1, file ) != 1)
57  {
58  msg_cb( sev_warning, "could not read PC64 header" );
59  return 1;
60  }
61 
62  if(strlen( fname ) > 4)
63  {
64  ext = fname + strlen(fname) - 3;
65  if(isdigit(ext[1]) && isdigit(ext[2]) &&
66  strchr("PSDU", toupper(*ext)))
67  {
68  *type = (char) toupper(*ext);
69  }
70  else
71  {
72  msg_cb( sev_warning, "could not guess PC64 filetype: %s", fname );
73  *type = 'P';
74  }
75  }
76  else
77  {
78  msg_cb( sev_warning,
79  "name too short to guess PC64 filetype: %s", fname );
80  *type = 'P';
81  }
82  memcpy(cbmname, pc64header.cbmname, 16 );
83 
84  *data = NULL;
85  if(fseek(file, 0L, SEEK_END) == 0)
86  {
87  *size = ftell(file) - sizeof(pc64header);
88  if(*size)
89  {
90  *data = malloc(*size);
91  if(*data)
92  {
93  if(fseek(file, sizeof(pc64header), SEEK_SET) == 0 &&
94  fread(*data, *size, 1, file) == 1)
95  {
96  return 0;
97  }
98  free(*data);
99  }
100  }
101  else
102  {
103  return 0;
104  }
105  }
106  return 1;
107 }
108 
109 DECLARE_INPUT_READER(pc64);