Skip to content

Commit 0c1f815

Browse files
authored
Added ncopy util which is interactive nget & nput (#26)
1 parent 602d3af commit 0c1f815

File tree

10 files changed

+881
-206
lines changed

10 files changed

+881
-206
lines changed

fujicom/fujicom.h

Lines changed: 201 additions & 203 deletions
Large diffs are not rendered by default.

ncopy/GNUmakefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
WMAKE=wmake -h
2+
3+
all:
4+
@$(WMAKE) -e CPPFLAGS=-DVERSION='\"$(shell git rev-parse --short HEAD)$(shell git status --porcelain | grep -q '^[ MADRCU]' && echo '*')\"'
5+
6+
clean:
7+
@$(WMAKE) clean

ncopy/fujifs.c

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
/* Contributed by [email protected]
2+
*/
3+
4+
#include "fujifs.h"
5+
#include "fujicom.h"
6+
#include <string.h>
7+
#include <strings.h>
8+
#include <ctype.h>
9+
#include <stdio.h>
10+
#include <dos.h>
11+
#include <stdlib.h>
12+
13+
// FIXME - find available network device
14+
#define NETDEV DEVICEID_FN_NETWORK
15+
#define OPEN_SIZE 256
16+
#define DIR_DELIM " \r\n"
17+
18+
struct {
19+
unsigned short length;
20+
unsigned char connected;
21+
unsigned char errcode;
22+
} status;
23+
24+
typedef struct {
25+
size_t position, length;
26+
} FN_DIR;
27+
28+
static uint8_t fujifs_buf[256];
29+
static FN_DIR cur_dir;
30+
static struct tm ftm;
31+
32+
// Copy path to fujifs_buf and make sure it has N: prefix
33+
void ennify(const char *path)
34+
{
35+
fujifs_buf[0] = 0;
36+
if (toupper(path[0]) != 'N' || path[1] != ':')
37+
strcat(fujifs_buf, "N:");
38+
strncat(fujifs_buf, path, OPEN_SIZE - 1 - strlen(fujifs_buf));
39+
return;
40+
}
41+
42+
errcode fujifs_open_url(const char *url, const char *user, const char *password)
43+
{
44+
int reply;
45+
46+
47+
// User/pass is "sticky" and needs to be set/reset on open
48+
memset(fujifs_buf, 0, sizeof(fujifs_buf));
49+
if (user)
50+
strcpy(fujifs_buf, user);
51+
reply = fujiF5_write(NETDEV, CMD_USERNAME, 0, 0, &fujifs_buf, OPEN_SIZE);
52+
// FIXME - check err
53+
memset(fujifs_buf, 0, sizeof(fujifs_buf));
54+
if (password)
55+
strcpy(fujifs_buf, password);
56+
reply = fujiF5_write(NETDEV, CMD_PASSWORD, 0, 0, &fujifs_buf, OPEN_SIZE);
57+
// FIXME - check err
58+
59+
return fujifs_open(url, FUJIFS_DIRECTORY);
60+
}
61+
62+
errcode fujifs_close_url()
63+
{
64+
return fujifs_close();
65+
}
66+
67+
errcode fujifs_open(const char *path, uint16_t mode)
68+
{
69+
int reply;
70+
71+
72+
ennify(path);
73+
reply = fujiF5_write(NETDEV, CMD_OPEN, mode, 0, &fujifs_buf, OPEN_SIZE);
74+
if (reply != REPLY_COMPLETE)
75+
printf("FN OPEN REPLY: 0x%02x\n", reply);
76+
// FIXME - check err
77+
78+
reply = fujiF5_read(NETDEV, CMD_STATUS, 0, 0, &status, sizeof(status));
79+
if (reply != REPLY_COMPLETE)
80+
printf("FN STATUS REPLY: 0x%02x\n", reply);
81+
// FIXME - check err
82+
83+
#if 0
84+
printf("FN STATUS: len %i con %i err %i\n",
85+
status.length, status.connected, status.errcode);
86+
#endif
87+
// FIXME - apparently the error returned when opening in write mode should be ignored?
88+
if (mode == FUJIFS_WRITE)
89+
return 0;
90+
91+
if (status.errcode > NETWORK_SUCCESS && !status.length)
92+
return status.errcode;
93+
#if 0
94+
// FIXME - field doesn't work
95+
if (!status.connected)
96+
return -1;
97+
#endif
98+
99+
return 0;
100+
}
101+
102+
103+
errcode fujifs_close()
104+
{
105+
fujiF5_none(NETDEV, CMD_CLOSE, 0, 0, NULL, 0);
106+
return 0;
107+
}
108+
109+
// Returns number of bytes read
110+
size_t fujifs_read(uint8_t *buf, size_t length)
111+
{
112+
int reply;
113+
114+
115+
// Check how many bytes are available
116+
reply = fujiF5_read(NETDEV, CMD_STATUS, 0, 0, &status, sizeof(status));
117+
if (reply != REPLY_COMPLETE)
118+
printf("FN STATUS REPLY: 0x%02x\n", reply);
119+
// FIXME - check err
120+
121+
#if 0
122+
printf("FN STATUS: len %i con %i err %i\n",
123+
status.length, status.connected, status.errcode);
124+
#endif
125+
if ((status.errcode > NETWORK_SUCCESS && !status.length)
126+
/* || !status.connected // status.connected doesn't work */)
127+
return 0;
128+
129+
if (length > status.length)
130+
length = status.length;
131+
132+
reply = fujiF5_read(DEVICEID_FN_NETWORK, CMD_READ, length, 0, buf, length);
133+
if (reply != REPLY_COMPLETE)
134+
return 0;
135+
return length;
136+
}
137+
138+
// Returns number of bytes written
139+
size_t fujifs_write(uint8_t *buf, size_t length)
140+
{
141+
int reply;
142+
143+
144+
reply = fujiF5_write(DEVICEID_FN_NETWORK, CMD_WRITE, length, 0, buf, length);
145+
if (reply != REPLY_COMPLETE)
146+
return 0;
147+
return length;
148+
}
149+
150+
errcode fujifs_opendir()
151+
{
152+
errcode err;
153+
154+
155+
cur_dir.position = cur_dir.length = 0;
156+
return fujifs_open("", FUJIFS_DIRECTORY);
157+
}
158+
159+
errcode fujifs_closedir()
160+
{
161+
fujiF5_none(NETDEV, CMD_CLOSE, 0, 0, NULL, 0);
162+
return 0;
163+
}
164+
165+
FN_DIRENT *fujifs_readdir()
166+
{
167+
size_t len;
168+
static FN_DIRENT ent;
169+
size_t idx;
170+
char *cptr1, *cptr2, *cptr3;
171+
int v1, v2, v3;
172+
173+
174+
// Refill buffer if it's empty
175+
if (cur_dir.position >= cur_dir.length) {
176+
cur_dir.length = fujifs_read(fujifs_buf, sizeof(fujifs_buf));
177+
cur_dir.position = 0;
178+
}
179+
180+
for (idx = cur_dir.position;
181+
idx < cur_dir.length &&
182+
(fujifs_buf[idx] == ' ' || fujifs_buf[idx] == '\r' || fujifs_buf[idx] == '\n');
183+
idx++)
184+
;
185+
cur_dir.position = idx;
186+
187+
// make sure there's an END-OF-RECORD, if not refill buffer
188+
for (; idx < cur_dir.length && fujifs_buf[idx] != '\r' && fujifs_buf[idx] != '\n';
189+
idx++)
190+
;
191+
if (idx == cur_dir.length) {
192+
v1 = cur_dir.length - cur_dir.position;
193+
memmove(fujifs_buf, &fujifs_buf[cur_dir.position], v1);
194+
v2 = fujifs_read(&fujifs_buf[v1], sizeof(fujifs_buf) - v1);
195+
if (!v2)
196+
return NULL;
197+
cur_dir.position = 0;
198+
cur_dir.length = v1 + v2;
199+
}
200+
201+
memset(&ent, 0, sizeof(ent));
202+
203+
// get filename
204+
cptr1 = strtok(&fujifs_buf[cur_dir.position], DIR_DELIM);
205+
ent.name = cptr1;
206+
207+
// get extension
208+
cptr2 = strtok(NULL, DIR_DELIM);
209+
if (cptr2 - cptr1 < 10) {
210+
v1 = strlen(cptr1);
211+
cptr1[v1] = '.';
212+
memmove(&cptr1[v1 + 1], cptr2, strlen(cptr2) + 1);
213+
214+
// get size or dir
215+
cptr1 = strtok(NULL, DIR_DELIM);
216+
}
217+
else {
218+
// extension is too far away, it must be the size
219+
cptr1 = cptr2;
220+
}
221+
222+
if (strcasecmp(cptr1, "<DIR>") == 0)
223+
ent.isdir = 1;
224+
else
225+
ent.size = atol(cptr1);
226+
227+
// get date
228+
cptr1 = strtok(NULL, DIR_DELIM);
229+
230+
// get time
231+
cptr2 = strtok(NULL, DIR_DELIM);
232+
233+
// done parsing record, parse date & time now
234+
cptr3 = strtok(cptr1, "-");
235+
ftm.tm_mon = atoi(cptr3) - 1;
236+
cptr3 = strtok(NULL, "-");
237+
ftm.tm_mday = atoi(cptr3);
238+
cptr3 = strtok(NULL, "-");
239+
ftm.tm_year = atoi(cptr3) + 1900;
240+
if (ftm.tm_year < 1975)
241+
ftm.tm_year += 100;
242+
ftm.tm_year -= 1900;
243+
244+
cptr3 = strtok(cptr2, ":");
245+
ftm.tm_hour = atoi(cptr3);
246+
cptr3 = strtok(NULL, " ");
247+
ftm.tm_min = atoi(cptr3);
248+
ftm.tm_hour = ftm.tm_hour % 12 + (tolower(cptr3[2]) == 'p' ? 12 : 0);
249+
250+
ent.mtime = mktime(&ftm);
251+
252+
v1 = (cptr3 - fujifs_buf) + 4;
253+
cur_dir.position = v1;
254+
255+
return &ent;
256+
}
257+
258+
errcode fujifs_chdir(const char *path)
259+
{
260+
int reply;
261+
262+
263+
ennify(path);
264+
reply = fujiF5_write(NETDEV, CMD_CHDIR, 0x0000, 0, &fujifs_buf, OPEN_SIZE);
265+
if (reply != REPLY_COMPLETE)
266+
printf("FN OPEN REPLY: 0x%02x\n", reply);
267+
// FIXME - check err
268+
return 0;
269+
}

ncopy/fujifs.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* Contributed by [email protected]
2+
*/
3+
4+
#ifndef _NET_H
5+
#define _NET_H
6+
7+
#include <stddef.h>
8+
#include <stdint.h>
9+
#include <fcntl.h>
10+
#include <time.h>
11+
12+
typedef int errcode;
13+
typedef struct {
14+
const char *name;
15+
off_t size;
16+
time_t ctime, mtime;
17+
unsigned char isdir:1;
18+
} FN_DIRENT;
19+
20+
enum {
21+
FUJIFS_READ = 4,
22+
FUJIFS_DIRECTORY = 6,
23+
FUJIFS_WRITE = 8,
24+
};
25+
26+
// FIXME - this should probably return a handle to point to the network device which was used?
27+
extern errcode fujifs_open_url(const char *url, const char *user, const char *password);
28+
extern errcode fujifs_close_url();
29+
extern errcode fujifs_open(const char *path, uint16_t mode);
30+
extern errcode fujifs_close();
31+
extern size_t fujifs_read(uint8_t *buf, size_t length);
32+
extern size_t fujifs_write(uint8_t *buf, size_t length);
33+
extern errcode fujifs_opendir();
34+
extern errcode fujifs_closedir();
35+
extern FN_DIRENT *fujifs_readdir();
36+
extern errcode fujifs_chdir();
37+
38+
#endif /* _NET_H */

ncopy/makefile

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
TARGET = ncopy.exe
2+
AS = wasm -q
3+
ASFLAGS = -0 -mt -bt=DOS
4+
CC = wcc -q
5+
CFLAGS = -0 -bt=dos -ms -I../fujicom -s -osh -zu $(CPPFLAGS)
6+
LD = wlink OPTION quiet
7+
LDFLAGS = &
8+
SYSTEM dos &
9+
OPTION MAP &
10+
LIBPATH ../fujicom
11+
12+
CFILES = ncopy.c parser.c fujifs.c
13+
OBJS = $(CFILES:.c=.obj) $(AFILES:.asm=.obj)
14+
15+
$(TARGET): $(OBJS)
16+
$(LD) $(LDFLAGS) &
17+
disable 1014 &
18+
name $@ &
19+
file {$(OBJS) ../sys/print.obj} &
20+
library {fujicoms.lib clibs.lib}
21+
22+
.c.obj: .AUTODEPEND
23+
$(CC) $(CFLAGS) -fo=$@ $<
24+
.asm.obj: .AUTODEPEND
25+
$(AS) $(ASFLAGS) -fo=$@ $<
26+
27+
clean : .SYMBOLIC
28+
rm -f $(TARGET) *.obj *.map *.err *.sys *.com *.exe *.o

0 commit comments

Comments
 (0)