mirror of https://github.com/gungwald/copy.git
Some updates
This commit is contained in:
parent
670f41833e
commit
4b4e15da92
72
copy.c
72
copy.c
|
@ -1,59 +1,62 @@
|
||||||
#include <stdio.h> /* fopen, fread, fwrite, fclose */
|
#include <stdio.h> /* fopen, fread, fwrite, fclose, FILENAME_MAX */
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h> /* atexit */
|
#include <stdlib.h> /* atexit */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <apple2.h> /* _filetype, _auxtype */
|
||||||
#include "libgen.h" /* basename */
|
#include "libgen.h" /* basename */
|
||||||
|
|
||||||
#include "prodos.h"
|
#include "prodos.h"
|
||||||
#include "prodosext.h"
|
#include "prodosext.h"
|
||||||
#include "cui.h"
|
#include "io.h"
|
||||||
|
|
||||||
#define BF_SIZ 2048
|
#define COPY_BUF_SIZ 2048
|
||||||
|
|
||||||
void cleanup(void);
|
enum Status {SUCCESS, FAILURE};
|
||||||
FILE *openFile(const char *name, const char *mode);
|
|
||||||
void closeFile(FILE *f, const char *name);
|
|
||||||
void concatPath(char *dest, const char *src);
|
|
||||||
|
|
||||||
char srcName[PRODOS_PATH_MAX + 1];
|
static void cleanup(void);
|
||||||
char destName[PRODOS_PATH_MAX + 1];
|
static FILE *openFile(const char *name, const char *mode);
|
||||||
|
static void closeFile(FILE *f, const char *name);
|
||||||
|
static void concatPath(char *accum, const char *src);
|
||||||
|
static void copyFile(FILE *src, FILE *dest);
|
||||||
|
|
||||||
|
FilePath srcName;
|
||||||
|
FilePath destName;
|
||||||
FILE *src = NULL;
|
FILE *src = NULL;
|
||||||
FILE *dest = NULL;
|
FILE *dest = NULL;
|
||||||
struct GetFileInfoParams srcInfo;
|
struct GetFileInfoParams srcInfo;
|
||||||
struct GetFileInfoParams destInfo;
|
struct GetFileInfoParams destInfo;
|
||||||
size_t n;
|
size_t n;
|
||||||
char buf[BF_SIZ];
|
char buf[BUF_SIZ];
|
||||||
size_t bytesRead;
|
size_t bytesRead;
|
||||||
|
uint8_t result;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
|
|
||||||
if (! inputFileName("Source file or directory:", srcName,
|
if (! inputFileName("Source file:", srcName))
|
||||||
sizeof(srcName), &srcInfo))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (! inputFileName("Destination file or directory:", destName,
|
if (! inputFileName("Destination file or directory:", destName))
|
||||||
sizeof(destName), &destInfo))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
src = openFile(srcName, "r");
|
if ((result = getFileInfo(srcName, srcInfo)) != PRODOS_E_NONE) {
|
||||||
|
fprintf(stderr, "%s: %s (code %d)\n", srcName, getMessage(result), result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result = getFileInfo(destName, destInfo)) != PRODOS_E_NONE) {
|
||||||
|
fprintf(stderr, "%s: %s (code %d)\n", srcName, getMessage(result), result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isDirectory(&destInfo))
|
if (isDirectory(&destInfo))
|
||||||
concatPath(destName, basename(srcName));
|
concatPath(destName, basename(srcName));
|
||||||
|
|
||||||
dest = openFile(destName, "w");
|
_filetype = srcInfo->file_type;
|
||||||
|
_auxtype = srcInfo->aux_type;
|
||||||
while ((bytesRead = fread(buf, 1, sizeof(buf), src)) == BF_SIZ)
|
|
||||||
if (fwrite(buf, 1, bytesRead, dest) < bytesRead) {
|
|
||||||
perror(destName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytesRead > 0 && !feof(dest) && !ferror(dest))
|
|
||||||
if (fwrite(buf, 1, bytesRead, dest) < bytesRead)
|
|
||||||
perror(destName);
|
|
||||||
|
|
||||||
|
copyFile(openFile(srcName, "r"), openFile(destName, "w"));
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +66,6 @@ FILE *openFile(const char *name, const char *mode)
|
||||||
f = fopen(name, "r");
|
f = fopen(name, "r");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
perror(name);
|
perror(name);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
@ -92,3 +94,19 @@ void cleanup(void)
|
||||||
closeFile(src, srcName);
|
closeFile(src, srcName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void copyFile(FILE *src, FILE *dest)
|
||||||
|
{
|
||||||
|
if (src == NULL || dest == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while ((bytesRead = fread(buf, 1, sizeof(buf), src)) == COPY_BUF_SIZ)
|
||||||
|
if (fwrite(buf, 1, bytesRead, dest) < bytesRead) {
|
||||||
|
perror(destName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytesRead > 0 && !feof(dest) && !ferror(dest))
|
||||||
|
if (fwrite(buf, 1, bytesRead, dest) < bytesRead)
|
||||||
|
perror(destName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
8
cui.h
8
cui.h
|
@ -1,8 +0,0 @@
|
||||||
#ifndef CUI_H
|
|
||||||
#define CUI_H
|
|
||||||
|
|
||||||
extern bool inputFileName(const char *prompt, char *name, size_t capacity,
|
|
||||||
struct GetFileInfoParams *params);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
18
cui.c → io.c
18
cui.c → io.c
|
@ -1,8 +1,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h> /* strlen */
|
#include <string.h> /* strlen */
|
||||||
|
|
||||||
#include "cui.h"
|
#include "io.h"
|
||||||
#include "prodos.h"
|
#include "prodos.h"
|
||||||
#include "prodosext.h"
|
#include "prodosext.h"
|
||||||
|
|
||||||
|
@ -13,15 +12,13 @@ static void chomp(char *line);
|
||||||
static bool complete;
|
static bool complete;
|
||||||
static uint8_t result;
|
static uint8_t result;
|
||||||
|
|
||||||
bool inputFileName(const char *prompt, char *name,
|
bool inputFileName(const char *prompt, FilePath name)
|
||||||
size_t capacity,
|
|
||||||
struct GetFileInfoParams *params)
|
|
||||||
{
|
{
|
||||||
complete = false;
|
complete = false;
|
||||||
|
|
||||||
while (! complete) {
|
while (! complete) {
|
||||||
printf(prompt);
|
printf(prompt);
|
||||||
readLine(name, capacity);
|
readLine(name, sizeof(name));
|
||||||
if (strlen(name) == 0) {
|
if (strlen(name) == 0) {
|
||||||
puts("Aborting");
|
puts("Aborting");
|
||||||
break;
|
break;
|
||||||
|
@ -30,15 +27,6 @@ bool inputFileName(const char *prompt, char *name,
|
||||||
puts("Escaping");
|
puts("Escaping");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
params->param_count = GET_FILE_INFO_PARAM_COUNT;
|
|
||||||
params->pathname = name;
|
|
||||||
printf("params address = %x\n", &(params->param_count));
|
|
||||||
printf("params address = %x\n", params);
|
|
||||||
result = get_file_info(params);
|
|
||||||
if (result == PRODOS_E_NONE)
|
|
||||||
complete = true;
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s: %s (code %d)\n", name, getMessage(result), result);
|
|
||||||
}
|
}
|
||||||
return complete;
|
return complete;
|
||||||
}
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef CUI_H
|
||||||
|
#define CUI_H
|
||||||
|
|
||||||
|
#include <stdio.h> /* FILENAME_MAX */
|
||||||
|
/**
|
||||||
|
* FilePath is a cc65 platform independent type because the
|
||||||
|
* FILENAME_MAX constant is defined for each platform in
|
||||||
|
* stdio.h. It includes space for a string terminator.
|
||||||
|
*/
|
||||||
|
typedef char FilePath[FILENAME_MAX];
|
||||||
|
|
||||||
|
extern bool inputFileName(const char *prompt, FilePath name);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
5
prodos.h
5
prodos.h
|
@ -3,11 +3,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* PATH_MAX POSIX constant
|
|
||||||
ProDOS has a 64 char prefix that can be combined
|
|
||||||
with partial pathname of 64 characters. This is
|
|
||||||
a total of 128 characters. */
|
|
||||||
#define PRODOS_PATH_MAX 128
|
|
||||||
#define PRODOS_FILE_NAME_MAX 15
|
#define PRODOS_FILE_NAME_MAX 15
|
||||||
|
|
||||||
#define PRODOS_E_NONE 0x00
|
#define PRODOS_E_NONE 0x00
|
||||||
|
|
11
prodosext.c
11
prodosext.c
|
@ -1,7 +1,18 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <apple2_filetype.h>
|
#include <apple2_filetype.h>
|
||||||
#include "prodos.h"
|
#include "prodos.h"
|
||||||
#include "prodosext.h"
|
#include "prodosext.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
uint8_t getFileInfo(FilePath name, struct GetFileInfoParams *params)
|
||||||
|
{
|
||||||
|
params->param_count = GET_FILE_INFO_PARAM_COUNT;
|
||||||
|
params->pathname = name;
|
||||||
|
printf("params address = %x\n", &(params->param_count));
|
||||||
|
printf("params address = %x\n", params);
|
||||||
|
return get_file_info(params);
|
||||||
|
}
|
||||||
|
|
||||||
bool isDirectory(struct GetFileInfoParams *params)
|
bool isDirectory(struct GetFileInfoParams *params)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern bool getFileInfo(FileName name, struct GetFileInfoParams *params);
|
||||||
extern bool isDirectory(struct GetFileInfoParams *params);
|
extern bool isDirectory(struct GetFileInfoParams *params);
|
||||||
extern const char *getMessage(uint8_t errorCode);
|
extern const char *getMessage(uint8_t errorCode);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue