Fix package upgrade and fix FUSE multi-threaded issues.

This commit is contained in:
dschmenk 2013-10-08 15:02:52 -07:00
parent fbe5e5b83e
commit 145659578c
5 changed files with 113 additions and 90 deletions

View File

@ -1,5 +1,5 @@
PACKAGE=a2pi PACKAGE=a2pi
VERSION=0.1.1 VERSION=0.1.3
DIST=$(PACKAGE)-$(VERSION) DIST=$(PACKAGE)-$(VERSION)
DISTDIR=./$(DIST) DISTDIR=./$(DIST)

12
debian/changelog vendored
View File

@ -1,8 +1,14 @@
a2pi (0.1.1-4) unstable; urgency=low a2pi (0.1.3-1) unstable; urgency=low
* Fix update to /boot/cmdline.txt (again) - thanks Ivan Drucker! * Fix multi-thread locking in FUSE driver
-- David Schmenk <dschmenk@gmail.com> Sun, 6 Oct 2013 14:31:35 -0700 -- David Schmenk <dschmenk@gmail.com> Tue, 8 Oct 2013 11:23:34 -0700
a2pi (0.1.2-1) unstable; urgency=low
* Stop and start a2pid server before and after upgrade
-- David Schmenk <dschmenk@gmail.com> Mon, 7 Oct 2013 15:43:53 -0700
a2pi (0.1.1-3) unstable; urgency=low a2pi (0.1.1-3) unstable; urgency=low

6
debian/init.d vendored
View File

@ -17,7 +17,8 @@
# PATH should only include /usr/* if it runs after the mountnfs.sh script # PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC=a2pid # Introduce a short description here DESC=a2pid # Introduce a short description here
NAME=a2pid # Introduce the short server's name here NAME=a2pi # Introduce the short server's name here
NAMED=a2pid
DAEMON=/sbin/a2pid # Introduce the server's location here DAEMON=/sbin/a2pid # Introduce the server's location here
DAEMON_ARGS="--daemon" # Arguments to run the daemon with DAEMON_ARGS="--daemon" # Arguments to run the daemon with
PIDFILE=/var/run/$NAME.pid PIDFILE=/var/run/$NAME.pid
@ -47,6 +48,7 @@ do_start()
# 2 if daemon could not be started # 2 if daemon could not be started
#start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1 #start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1
#start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 #start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2
killall -HUP $NAMED
$DAEMON $DAEMON_ARGS $DAEMON_OPTS || return 2 $DAEMON $DAEMON_ARGS $DAEMON_OPTS || return 2
# Add code here, if necessary, that waits for the process to be ready # Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend # to handle requests from services started subsequently which depend
@ -77,7 +79,7 @@ do_stop()
# Many daemons don't delete their pidfiles when they exit. # Many daemons don't delete their pidfiles when they exit.
#rm -f $PIDFILE #rm -f $PIDFILE
#return "$RETVAL" #return "$RETVAL"
killall $NAME killall -HUP $NAMED
} }
# #

View File

@ -764,7 +764,6 @@ void main(int argc, char **argv)
prlog("a2pid: Connected.\n"); prlog("a2pid: Connected.\n");
iopkt[0] = 0x81; /* acknowledge */ iopkt[0] = 0x81; /* acknowledge */
write(a2fd, iopkt, 1); write(a2fd, iopkt, 1);
tcflush(a2fd, TCIFLUSH);
} }
else if (iopkt[0] == 0x9F) /* bad request from Apple II */ else if (iopkt[0] == 0x9F) /* bad request from Apple II */
{ {

View File

@ -272,9 +272,7 @@ static unsigned int prodos_update_time(void)
time_buff[1] = (unsigned char) (ptime >> 8); time_buff[1] = (unsigned char) (ptime >> 8);
time_buff[2] = (unsigned char) (ptime >> 16); time_buff[2] = (unsigned char) (ptime >> 16);
time_buff[3] = (unsigned char) (ptime >> 24); time_buff[3] = (unsigned char) (ptime >> 24);
A2PI_WAIT;
result = a2write(pifd, 0xBF90, 4, time_buff); result = a2write(pifd, 0xBF90, 4, time_buff);
A2PI_RELEASE;
} }
static int prodos_open(unsigned char *prodos_path, int *io_buff) static int prodos_open(unsigned char *prodos_path, int *io_buff)
@ -282,7 +280,6 @@ static int prodos_open(unsigned char *prodos_path, int *io_buff)
unsigned char refnum; unsigned char refnum;
int result; int result;
A2PI_WAIT;
a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path); a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path);
if (*io_buff == 0) if (*io_buff == 0)
{ {
@ -302,7 +299,6 @@ static int prodos_open(unsigned char *prodos_path, int *io_buff)
if (result == 0) if (result == 0)
{ {
a2read(pifd, PRODOS_PARAM_BUFFER + 5, 1, &refnum); a2read(pifd, PRODOS_PARAM_BUFFER + 5, 1, &refnum);
A2PI_RELEASE;
return refnum; return refnum;
} }
prodos_free_io_buff(*io_buff); prodos_free_io_buff(*io_buff);
@ -311,7 +307,6 @@ static int prodos_open(unsigned char *prodos_path, int *io_buff)
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
prodos_free_io_buff(*io_buff); prodos_free_io_buff(*io_buff);
*io_buff = 0; *io_buff = 0;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_close(int refnum, int *io_buff) static int prodos_close(int refnum, int *io_buff)
@ -327,18 +322,15 @@ static int prodos_close(int refnum, int *io_buff)
prodos[PRODOS_CMD] = PRODOS_CLOSE; prodos[PRODOS_CMD] = PRODOS_CLOSE;
prodos[PRODOS_PARAM_CNT] = 1; prodos[PRODOS_PARAM_CNT] = 1;
prodos[PRODOS_PARAMS + 1] = refnum; prodos[PRODOS_PARAMS + 1] = refnum;
A2PI_WAIT;
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 1, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 1, prodos);
if (a2call(pifd, PRODOS_CALL, &result)) if (a2call(pifd, PRODOS_CALL, &result))
{ {
A2PI_RELEASE;
return -result; return -result;
} }
A2PI_RELEASE;
return -PRODOS_ERR_UNKNOWN; return -PRODOS_ERR_UNKNOWN;
} }
static int prodos_read(int refnum, char *data_buff, int req_xfer) static int prodos_read(int refnum, char *data_buff, int req_xfer)
{ {
int result, short_req, short_xfer, total_xfer = 0; int result, short_req, short_xfer, total_xfer = 0;
prodos[PRODOS_CMD] = PRODOS_READ; prodos[PRODOS_CMD] = PRODOS_READ;
@ -353,7 +345,6 @@ static int prodos_read(int refnum, char *data_buff, int req_xfer)
prodos[PRODOS_PARAMS + 5] = (unsigned char) (short_req >> 8); prodos[PRODOS_PARAMS + 5] = (unsigned char) (short_req >> 8);
prodos[PRODOS_PARAMS + 6] = 0; prodos[PRODOS_PARAMS + 6] = 0;
prodos[PRODOS_PARAMS + 7] = 0; prodos[PRODOS_PARAMS + 7] = 0;
A2PI_WAIT;
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 7, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 7, prodos);
if (a2call(pifd, PRODOS_CALL, &result)) if (a2call(pifd, PRODOS_CALL, &result))
{ {
@ -362,24 +353,20 @@ static int prodos_read(int refnum, char *data_buff, int req_xfer)
a2read(pifd, PRODOS_PARAM_BUFFER + 6, 2, prodos + PRODOS_PARAMS + 6); a2read(pifd, PRODOS_PARAM_BUFFER + 6, 2, prodos + PRODOS_PARAMS + 6);
if ((short_xfer = (unsigned char) prodos[PRODOS_PARAMS + 6] + (unsigned char)prodos[PRODOS_PARAMS + 7] * 256) > 0) if ((short_xfer = (unsigned char) prodos[PRODOS_PARAMS + 6] + (unsigned char)prodos[PRODOS_PARAMS + 7] * 256) > 0)
a2read(pifd, PRODOS_DATA_BUFFER, short_xfer, data_buff + total_xfer); a2read(pifd, PRODOS_DATA_BUFFER, short_xfer, data_buff + total_xfer);
A2PI_RELEASE;
req_xfer -= short_xfer; req_xfer -= short_xfer;
total_xfer += short_xfer; total_xfer += short_xfer;
} }
else else
{ {
A2PI_RELEASE;
return (result == PRODOS_ERR_EOF || total_xfer) ? total_xfer : -result; return (result == PRODOS_ERR_EOF || total_xfer) ? total_xfer : -result;
} }
} }
else else
{ {
A2PI_RELEASE;
return -PRODOS_ERR_UNKNOWN; return -PRODOS_ERR_UNKNOWN;
} }
} }
A2PI_RELEASE; return total_xfer;
return total_xfer;
} }
static int prodos_write(int refnum, const char *data_buff, int req_xfer) static int prodos_write(int refnum, const char *data_buff, int req_xfer)
{ {
@ -391,7 +378,6 @@ static int prodos_write(int refnum, const char *data_buff, int req_xfer)
while (req_xfer) while (req_xfer)
{ {
short_req = (req_xfer > PRODOS_DATA_BUFFER_LEN) ? PRODOS_DATA_BUFFER_LEN : req_xfer; short_req = (req_xfer > PRODOS_DATA_BUFFER_LEN) ? PRODOS_DATA_BUFFER_LEN : req_xfer;
A2PI_WAIT;
a2write(pifd, PRODOS_DATA_BUFFER, short_req, (char *)(data_buff + total_xfer)); a2write(pifd, PRODOS_DATA_BUFFER, short_req, (char *)(data_buff + total_xfer));
prodos[PRODOS_PARAMS + 2] = (unsigned char) PRODOS_DATA_BUFFER; prodos[PRODOS_PARAMS + 2] = (unsigned char) PRODOS_DATA_BUFFER;
prodos[PRODOS_PARAMS + 3] = (unsigned char) (PRODOS_DATA_BUFFER >> 8); prodos[PRODOS_PARAMS + 3] = (unsigned char) (PRODOS_DATA_BUFFER >> 8);
@ -406,19 +392,16 @@ static int prodos_write(int refnum, const char *data_buff, int req_xfer)
{ {
a2read(pifd, PRODOS_PARAM_BUFFER + 6, 2, prodos + PRODOS_PARAMS + 6); a2read(pifd, PRODOS_PARAM_BUFFER + 6, 2, prodos + PRODOS_PARAMS + 6);
short_xfer = (unsigned char) prodos[PRODOS_PARAMS + 6] + (unsigned char)prodos[PRODOS_PARAMS + 7] * 256; short_xfer = (unsigned char) prodos[PRODOS_PARAMS + 6] + (unsigned char)prodos[PRODOS_PARAMS + 7] * 256;
A2PI_RELEASE;
req_xfer -= short_xfer; req_xfer -= short_xfer;
total_xfer += short_xfer; total_xfer += short_xfer;
} }
else else
{ {
A2PI_RELEASE;
return -result; return -result;
} }
} }
else else
{ {
A2PI_RELEASE;
return -PRODOS_ERR_UNKNOWN; return -PRODOS_ERR_UNKNOWN;
} }
} }
@ -434,11 +417,9 @@ static int prodos_set_mark(int refnum, int position)
prodos[PRODOS_PARAMS + 2] = (unsigned char) position; prodos[PRODOS_PARAMS + 2] = (unsigned char) position;
prodos[PRODOS_PARAMS + 3] = (unsigned char) (position >> 8); prodos[PRODOS_PARAMS + 3] = (unsigned char) (position >> 8);
prodos[PRODOS_PARAMS + 4] = (unsigned char) (position >> 16); prodos[PRODOS_PARAMS + 4] = (unsigned char) (position >> 16);
A2PI_WAIT;
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 4, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 4, prodos);
if (!a2call(pifd, PRODOS_CALL, &result)) if (!a2call(pifd, PRODOS_CALL, &result))
result -PRODOS_ERR_UNKNOWN; result -PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_set_eof(int refnum, int position) static int prodos_set_eof(int refnum, int position)
@ -451,11 +432,9 @@ static int prodos_set_eof(int refnum, int position)
prodos[PRODOS_PARAMS + 2] = (unsigned char) position; prodos[PRODOS_PARAMS + 2] = (unsigned char) position;
prodos[PRODOS_PARAMS + 3] = (unsigned char) (position >> 8); prodos[PRODOS_PARAMS + 3] = (unsigned char) (position >> 8);
prodos[PRODOS_PARAMS + 4] = (unsigned char) (position >> 16); prodos[PRODOS_PARAMS + 4] = (unsigned char) (position >> 16);
A2PI_WAIT;
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 4, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 4, prodos);
if (!a2call(pifd, PRODOS_CALL, &result)) if (!a2call(pifd, PRODOS_CALL, &result))
result -PRODOS_ERR_UNKNOWN; result -PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_get_eof(int refnum) static int prodos_get_eof(int refnum)
@ -468,14 +447,12 @@ static int prodos_get_eof(int refnum)
prodos[PRODOS_PARAMS + 2] = 0; prodos[PRODOS_PARAMS + 2] = 0;
prodos[PRODOS_PARAMS + 3] = 0; prodos[PRODOS_PARAMS + 3] = 0;
prodos[PRODOS_PARAMS + 4] = 0; prodos[PRODOS_PARAMS + 4] = 0;
A2PI_WAIT;
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 4, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 4, prodos);
if (a2call(pifd, PRODOS_CALL, &result)) if (a2call(pifd, PRODOS_CALL, &result))
{ {
if (result == 0) if (result == 0)
{ {
a2read(pifd, PRODOS_PARAM_BUFFER + 2, 3, prodos + PRODOS_PARAMS + 2); a2read(pifd, PRODOS_PARAM_BUFFER + 2, 3, prodos + PRODOS_PARAMS + 2);
A2PI_RELEASE;
position = prodos[PRODOS_PARAMS + 2] position = prodos[PRODOS_PARAMS + 2]
+ (prodos[PRODOS_PARAMS + 3] << 8) + (prodos[PRODOS_PARAMS + 3] << 8)
+ (prodos[PRODOS_PARAMS + 4] << 16); + (prodos[PRODOS_PARAMS + 4] << 16);
@ -484,7 +461,6 @@ static int prodos_get_eof(int refnum)
} }
else else
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_on_line(int unit, char *data_buff) static int prodos_on_line(int unit, char *data_buff)
@ -497,7 +473,6 @@ static int prodos_on_line(int unit, char *data_buff)
prodos[PRODOS_PARAMS + 1] = (unsigned char) unit; prodos[PRODOS_PARAMS + 1] = (unsigned char) unit;
prodos[PRODOS_PARAMS + 2] = (unsigned char) PRODOS_DATA_BUFFER; prodos[PRODOS_PARAMS + 2] = (unsigned char) PRODOS_DATA_BUFFER;
prodos[PRODOS_PARAMS + 3] = (unsigned char) (PRODOS_DATA_BUFFER >> 8); prodos[PRODOS_PARAMS + 3] = (unsigned char) (PRODOS_DATA_BUFFER >> 8);
A2PI_WAIT;
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 3, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 3, prodos);
if (a2call(pifd, PRODOS_CALL, &result)) if (a2call(pifd, PRODOS_CALL, &result))
{ {
@ -506,7 +481,6 @@ static int prodos_on_line(int unit, char *data_buff)
} }
else else
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_set_file_info(unsigned char *prodos_path, int access, int type, int aux, int mod, int create) static int prodos_set_file_info(unsigned char *prodos_path, int access, int type, int aux, int mod, int create)
@ -514,7 +488,6 @@ static int prodos_set_file_info(unsigned char *prodos_path, int access, int type
int result; int result;
prodos_update_time(); prodos_update_time();
A2PI_WAIT;
a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path); a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path);
prodos[PRODOS_CMD] = PRODOS_SET_FILE_INFO; prodos[PRODOS_CMD] = PRODOS_SET_FILE_INFO;
prodos[PRODOS_PARAM_CNT] = 7; prodos[PRODOS_PARAM_CNT] = 7;
@ -534,14 +507,12 @@ static int prodos_set_file_info(unsigned char *prodos_path, int access, int type
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 13, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 13, prodos);
if (!a2call(pifd, PRODOS_CALL, &result)) if (!a2call(pifd, PRODOS_CALL, &result))
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_get_file_info(unsigned char *prodos_path, int *access, int *type, int *aux, int *storage, int *numblks, int *mod, int *create) static int prodos_get_file_info(unsigned char *prodos_path, int *access, int *type, int *aux, int *storage, int *numblks, int *mod, int *create)
{ {
int result; int result;
A2PI_WAIT;
a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path); a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path);
prodos[PRODOS_CMD] = PRODOS_GET_FILE_INFO; prodos[PRODOS_CMD] = PRODOS_GET_FILE_INFO;
prodos[PRODOS_PARAM_CNT] = 10; prodos[PRODOS_PARAM_CNT] = 10;
@ -587,7 +558,6 @@ static int prodos_get_file_info(unsigned char *prodos_path, int *access, int *ty
} }
else else
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_rename(unsigned char *from, unsigned char *to) static int prodos_rename(unsigned char *from, unsigned char *to)
@ -595,7 +565,6 @@ static int prodos_rename(unsigned char *from, unsigned char *to)
int result; int result;
prodos_update_time(); prodos_update_time();
A2PI_WAIT;
a2write(pifd, PRODOS_DATA_BUFFER, from[0] + 1, from); a2write(pifd, PRODOS_DATA_BUFFER, from[0] + 1, from);
a2write(pifd, PRODOS_DATA_BUFFER + 256, to[0] + 1, to); a2write(pifd, PRODOS_DATA_BUFFER + 256, to[0] + 1, to);
prodos[PRODOS_CMD] = PRODOS_RENAME; prodos[PRODOS_CMD] = PRODOS_RENAME;
@ -607,7 +576,6 @@ static int prodos_rename(unsigned char *from, unsigned char *to)
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 4, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 4, prodos);
if (!a2call(pifd, PRODOS_CALL, &result)) if (!a2call(pifd, PRODOS_CALL, &result))
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_destroy(unsigned char *prodos_path) static int prodos_destroy(unsigned char *prodos_path)
@ -615,7 +583,6 @@ static int prodos_destroy(unsigned char *prodos_path)
int result; int result;
prodos_update_time(); prodos_update_time();
A2PI_WAIT;
a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path); a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path);
prodos[PRODOS_CMD] = PRODOS_DESTROY; prodos[PRODOS_CMD] = PRODOS_DESTROY;
prodos[PRODOS_PARAM_CNT] = 1; prodos[PRODOS_PARAM_CNT] = 1;
@ -624,7 +591,6 @@ static int prodos_destroy(unsigned char *prodos_path)
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 2, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 2, prodos);
if (!a2call(pifd, PRODOS_CALL, &result)) if (!a2call(pifd, PRODOS_CALL, &result))
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_create(unsigned char *prodos_path, char access, char type, int aux, int create) static int prodos_create(unsigned char *prodos_path, char access, char type, int aux, int create)
@ -632,7 +598,6 @@ static int prodos_create(unsigned char *prodos_path, char access, char type, int
int result; int result;
prodos_update_time(); prodos_update_time();
A2PI_WAIT;
a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path); a2write(pifd, PRODOS_DATA_BUFFER, prodos_path[0] + 1, prodos_path);
prodos[PRODOS_CMD] = PRODOS_CREATE; prodos[PRODOS_CMD] = PRODOS_CREATE;
prodos[PRODOS_PARAM_CNT] = 7; prodos[PRODOS_PARAM_CNT] = 7;
@ -650,7 +615,6 @@ static int prodos_create(unsigned char *prodos_path, char access, char type, int
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 11, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 11, prodos);
if (!a2call(pifd, PRODOS_CALL, &result)) if (!a2call(pifd, PRODOS_CALL, &result))
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_read_block(int unit, char *data_buff, int block_num) static int prodos_read_block(int unit, char *data_buff, int block_num)
@ -664,7 +628,6 @@ static int prodos_read_block(int unit, char *data_buff, int block_num)
prodos[PRODOS_PARAMS + 3] = (unsigned char) (PRODOS_DATA_BUFFER >> 8); prodos[PRODOS_PARAMS + 3] = (unsigned char) (PRODOS_DATA_BUFFER >> 8);
prodos[PRODOS_PARAMS + 4] = (unsigned char) block_num; prodos[PRODOS_PARAMS + 4] = (unsigned char) block_num;
prodos[PRODOS_PARAMS + 5] = (unsigned char) (block_num >> 8); prodos[PRODOS_PARAMS + 5] = (unsigned char) (block_num >> 8);
A2PI_WAIT;
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 5, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 5, prodos);
if (a2call(pifd, PRODOS_CALL, &result)) if (a2call(pifd, PRODOS_CALL, &result))
{ {
@ -673,14 +636,12 @@ static int prodos_read_block(int unit, char *data_buff, int block_num)
} }
else else
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_write_block(int unit, const char *data_buff, int block_num) static int prodos_write_block(int unit, const char *data_buff, int block_num)
{ {
int result; int result;
A2PI_WAIT;
a2write(pifd, PRODOS_DATA_BUFFER, 512, (char *)data_buff); a2write(pifd, PRODOS_DATA_BUFFER, 512, (char *)data_buff);
prodos[PRODOS_CMD] = PRODOS_WRITE_BLOCK; prodos[PRODOS_CMD] = PRODOS_WRITE_BLOCK;
prodos[PRODOS_PARAM_CNT] = 3; prodos[PRODOS_PARAM_CNT] = 3;
@ -692,7 +653,6 @@ static int prodos_write_block(int unit, const char *data_buff, int block_num)
a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 5, prodos); a2write(pifd, PRODOS_CALL, PRODOS_CALL_LEN + 5, prodos);
if (!a2call(pifd, PRODOS_CALL, &result)) if (!a2call(pifd, PRODOS_CALL, &result))
result = PRODOS_ERR_UNKNOWN; result = PRODOS_ERR_UNKNOWN;
A2PI_RELEASE;
return -result; return -result;
} }
static int prodos_map_errno(int perr) static int prodos_map_errno(int perr)
@ -902,7 +862,7 @@ static int cache_get_file_info(const char *path, int *access, int *type, int *au
static int a2pi_getattr(const char *path, struct stat *stbuf) static int a2pi_getattr(const char *path, struct stat *stbuf)
{ {
int access, type, aux, storage, size, numblks, mod, create, refnum, io_buff = 0; int access, type, aux, storage, size, numblks, mod, create, refnum, err = 0, io_buff = 0;
if (strcmp(path, "/") == 0 || strcmp(path, ".") == 0 || strcmp(path, "..") == 0) if (strcmp(path, "/") == 0 || strcmp(path, ".") == 0 || strcmp(path, "..") == 0)
{ {
/* /*
@ -915,6 +875,7 @@ static int a2pi_getattr(const char *path, struct stat *stbuf)
/* /*
* Get file info. * Get file info.
*/ */
A2PI_WAIT;
if (cache_get_file_info(path, &access, &type, &aux, &storage, &numblks, &size, &mod, &create) == 0) if (cache_get_file_info(path, &access, &type, &aux, &storage, &numblks, &size, &mod, &create) == 0)
{ {
if (storage == 0x0F || storage == 0x0D) if (storage == 0x0F || storage == 0x0D)
@ -922,15 +883,17 @@ static int a2pi_getattr(const char *path, struct stat *stbuf)
unix_stat(stbuf, storage, access, numblks, size, mod, create); unix_stat(stbuf, storage, access, numblks, size, mod, create);
} }
else else
return -ENOENT; err = -ENOENT;
A2PI_RELEASE;
} }
return 0; return err;
} }
static int a2pi_access(const char *path, int mask) static int a2pi_access(const char *path, int mask)
{ {
int storage, access, type, numblks, size, aux, mod, create, access_ok = 0; int storage, access, type, numblks, size, aux, mod, create, access_ok = 0;
A2PI_WAIT;
if (cache_get_file_info(path, &access, &type, &aux, &storage, &numblks, &size, &mod, &create) == 0) if (cache_get_file_info(path, &access, &type, &aux, &storage, &numblks, &size, &mod, &create) == 0)
{ {
//printf("Check access bits $%02X to mask 0x%02X\n", access, mask); //printf("Check access bits $%02X to mask 0x%02X\n", access, mask);
@ -943,6 +906,7 @@ static int a2pi_access(const char *path, int mask)
} }
else else
access_ok = -1; access_ok = -1;
A2PI_RELEASE;
return access_ok; return access_ok;
} }
@ -950,7 +914,7 @@ static int a2pi_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi) off_t offset, struct fuse_file_info *fi)
{ {
unsigned char data_buff[512], filename[16], *entry; unsigned char data_buff[512], filename[16], *entry;
int storage, access, type, blocks, size, aux, mod, create; int storage, access, type, blocks, size, aux, mod, create, err = 0;
int i, l, iscached, slot, drive, refnum, iblk, entrylen, entriesblk, filecnt, io_buff = 0; int i, l, iscached, slot, drive, refnum, iblk, entrylen, entriesblk, filecnt, io_buff = 0;
struct stat stentry, straw; struct stat stentry, straw;
@ -999,6 +963,7 @@ static int a2pi_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
* Read ProDOS directory. * Read ProDOS directory.
*/ */
iscached = (strcmp(path, cachepath) == 0); iscached = (strcmp(path, cachepath) == 0);
A2PI_WAIT;
if (iscached || (refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0) if (iscached || (refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0)
{ {
unix_stat(&stentry, 0x0F, 0xC3, 0, 0, 0, 0); unix_stat(&stentry, 0x0F, 0xC3, 0, 0, 0, 0);
@ -1056,73 +1021,95 @@ static int a2pi_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
} }
} }
else else
return -ENOENT; err = -ENOENT;
A2PI_RELEASE;
} }
return 0; return err;
} }
static int a2pi_mkdir(const char *path, mode_t mode) static int a2pi_mkdir(const char *path, mode_t mode)
{ {
int err;
if (IS_ROOT_DIR(path)) if (IS_ROOT_DIR(path))
return -EACCES; return -EACCES;
A2PI_WAIT;
cachepath[0] = '\0'; cachepath[0] = '\0';
return prodos_map_errno(prodos_create(prodos_path(path, NULL, NULL, NULL), 0xE3, 0x0F, 0, 0)); err = prodos_map_errno(prodos_create(prodos_path(path, NULL, NULL, NULL), 0xE3, 0x0F, 0, 0));
A2PI_RELEASE;
return err;
} }
static int a2pi_remove(const char *path) static int a2pi_remove(const char *path)
{ {
int err;
if (IS_ROOT_DIR(path)) if (IS_ROOT_DIR(path))
return -EACCES; return -EACCES;
A2PI_WAIT;
cachepath[0] = '\0'; cachepath[0] = '\0';
return prodos_map_errno(prodos_destroy(prodos_path(path, NULL, NULL, NULL))); err = prodos_map_errno(prodos_destroy(prodos_path(path, NULL, NULL, NULL)));
A2PI_RELEASE;
return err;
} }
static int a2pi_rename(const char *from, const char *to) static int a2pi_rename(const char *from, const char *to)
{ {
unsigned char prodos_from[65], prodos_to[65]; unsigned char prodos_from[65], prodos_to[65], err;
if (IS_ROOT_DIR(from) || IS_ROOT_DIR(to)) if (IS_ROOT_DIR(from) || IS_ROOT_DIR(to))
return -EACCES; return -EACCES;
prodos_path(from, NULL, NULL, prodos_from); prodos_path(from, NULL, NULL, prodos_from);
prodos_path(to, NULL, NULL, prodos_to); prodos_path(to, NULL, NULL, prodos_to);
A2PI_WAIT;
cachepath[0] = '\0'; cachepath[0] = '\0';
return prodos_map_errno(prodos_rename(prodos_from, prodos_to)); err = prodos_map_errno(prodos_rename(prodos_from, prodos_to));
A2PI_RELEASE;
return err;
} }
static int a2pi_chmod(const char *path, mode_t mode) static int a2pi_chmod(const char *path, mode_t mode)
{ {
int access, type, aux, storage, size, numblks, mod, create; int access, type, aux, storage, size, numblks, mod, create, err;
if (IS_ROOT_DIR(path)) if (IS_ROOT_DIR(path))
return -EACCES; return -EACCES;
A2PI_WAIT;
if (cache_get_file_info(path, &access, &type, &aux, &storage, &numblks, &size, &mod, &create) == 0) if (cache_get_file_info(path, &access, &type, &aux, &storage, &numblks, &size, &mod, &create) == 0)
{ {
access = (mode & 0x04) ? 0x01 : 0x00; access = (mode & 0x04) ? 0x01 : 0x00;
access |= (mode & 0x02) ? 0xC2 : 0x00; access |= (mode & 0x02) ? 0xC2 : 0x00;
cachepath[0] = '\0'; cachepath[0] = '\0';
return prodos_map_errno(prodos_set_file_info(prodos_path(path, NULL, NULL, NULL), access, type, aux, 0, 0)); err = prodos_map_errno(prodos_set_file_info(prodos_path(path, NULL, NULL, NULL), access, type, aux, 0, 0));
} }
return -ENOENT; else
err = -ENOENT;
A2PI_RELEASE;
return err;
} }
static int a2pi_truncate(const char *path, off_t size) static int a2pi_truncate(const char *path, off_t size)
{ {
int refnum, io_buff = 0; int refnum, err, io_buff = 0;
if (IS_ROOT_DIR(path)) if (IS_ROOT_DIR(path))
return -EACCES; return -EACCES;
A2PI_WAIT;
cachepath[0] = '\0'; cachepath[0] = '\0';
if ((refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0) if ((refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0)
{ {
prodos_set_eof(refnum, size); prodos_set_eof(refnum, size);
return prodos_map_errno(prodos_close(refnum, &io_buff)); err = prodos_map_errno(prodos_close(refnum, &io_buff));
} }
return prodos_map_errno(refnum); else
err = prodos_map_errno(refnum);
A2PI_RELEASE;
return err;
} }
static int a2pi_open(const char *path, struct fuse_file_info *fi) static int a2pi_open(const char *path, struct fuse_file_info *fi)
{ {
int slot, drive, refnum, io_buff = 0; int slot, drive, refnum, err, io_buff = 0;
if (IS_ROOT_DIR(path)) if (IS_ROOT_DIR(path))
{ {
@ -1135,11 +1122,13 @@ static int a2pi_open(const char *path, struct fuse_file_info *fi)
} }
return -ENOENT; return -ENOENT;
} }
A2PI_WAIT;
if ((refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0) if ((refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0)
{ err = prodos_map_errno(prodos_close(refnum, &io_buff));
return prodos_map_errno(prodos_close(refnum, &io_buff)); else
} err = prodos_map_errno(refnum);
return prodos_map_errno(refnum); A2PI_RELEASE;
return err;
} }
static int a2pi_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) static int a2pi_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
@ -1166,7 +1155,10 @@ static int a2pi_read(const char *path, char *buf, size_t size, off_t offset, str
iblk = offset >> 9; iblk = offset >> 9;
while (blkcnt--) while (blkcnt--)
{ {
if ((refnum = prodos_read_block(unit, buf, iblk)) < 0) A2PI_WAIT;
refnum = prodos_read_block(unit, buf, iblk);
A2PI_RELEASE;
if (refnum < 0)
return prodos_map_errno(refnum); return prodos_map_errno(refnum);
buf += 512; buf += 512;
iblk++; iblk++;
@ -1175,6 +1167,7 @@ static int a2pi_read(const char *path, char *buf, size_t size, off_t offset, str
} }
return -ENOENT; return -ENOENT;
} }
A2PI_WAIT;
if ((refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0) if ((refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0)
{ {
if (offset && prodos_set_mark(refnum, offset) == -PRODOS_ERR_EOF) if (offset && prodos_set_mark(refnum, offset) == -PRODOS_ERR_EOF)
@ -1184,16 +1177,20 @@ static int a2pi_read(const char *path, char *buf, size_t size, off_t offset, str
if (size == -PRODOS_ERR_EOF) if (size == -PRODOS_ERR_EOF)
size = 0; size = 0;
prodos_close(refnum, &io_buff); prodos_close(refnum, &io_buff);
return size;
} }
return prodos_map_errno(refnum); else
size = prodos_map_errno(refnum);
A2PI_RELEASE;
return size;
} }
static int a2pi_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) static int a2pi_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
{ {
int slot, drive, unit, devsize, blkcnt, iblk, refnum, io_buff = 0; int slot, drive, unit, devsize, blkcnt, iblk, refnum, io_buff = 0;
A2PI_WAIT;
cachepath[0] = '\0'; cachepath[0] = '\0';
A2PI_RELEASE;
if (IS_ROOT_DIR(path)) if (IS_ROOT_DIR(path))
{ {
if (raw_dev_write) if (raw_dev_write)
@ -1216,7 +1213,10 @@ static int a2pi_write(const char *path, const char *buf, size_t size, off_t offs
iblk = offset >> 9; iblk = offset >> 9;
while (blkcnt--) while (blkcnt--)
{ {
if ((refnum = prodos_write_block(unit, buf, iblk)) < 0) A2PI_WAIT;
refnum = prodos_write_block(unit, buf, iblk);
A2PI_RELEASE;
if (refnum < 0)
return prodos_map_errno(refnum); return prodos_map_errno(refnum);
buf += 512; buf += 512;
iblk++; iblk++;
@ -1228,6 +1228,7 @@ static int a2pi_write(const char *path, const char *buf, size_t size, off_t offs
else else
return -EACCES; return -EACCES;
} }
A2PI_WAIT;
if ((refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0) if ((refnum = prodos_open(prodos_path(path, NULL, NULL, NULL), &io_buff)) > 0)
{ {
if (offset) if (offset)
@ -1235,9 +1236,11 @@ static int a2pi_write(const char *path, const char *buf, size_t size, off_t offs
if (size) if (size)
size = prodos_write(refnum, buf, size); size = prodos_write(refnum, buf, size);
prodos_close(refnum, &io_buff); prodos_close(refnum, &io_buff);
return size;
} }
return prodos_map_errno(refnum); else
size = prodos_map_errno(refnum);
A2PI_RELEASE;
return size;
} }
int a2pi_flush(const char *path, struct fuse_file_info *fi) int a2pi_flush(const char *path, struct fuse_file_info *fi)
@ -1248,25 +1251,31 @@ int a2pi_flush(const char *path, struct fuse_file_info *fi)
static int a2pi_create(const char * path, mode_t mode, struct fuse_file_info *fi) static int a2pi_create(const char * path, mode_t mode, struct fuse_file_info *fi)
{ {
unsigned char prodos_name[65]; unsigned char prodos_name[65];
int refnum, type, aux, io_buff = 0; int refnum, type, aux, err = 0, io_buff = 0;
if (IS_ROOT_DIR(path)) if (IS_ROOT_DIR(path))
return -EACCES; return -EACCES;
A2PI_WAIT;
cachepath[0] = '\0'; cachepath[0] = '\0';
if ((refnum = prodos_open(prodos_path(path, &type, &aux, prodos_name), &io_buff)) == -PRODOS_ERR_FILE_NOT_FND) if ((refnum = prodos_open(prodos_path(path, &type, &aux, prodos_name), &io_buff)) == -PRODOS_ERR_FILE_NOT_FND)
return prodos_map_errno(prodos_create(prodos_name, 0xC3, type, aux, 0)); {
err = prodos_map_errno(prodos_create(prodos_name, 0xC3, type, aux, 0));
}
if (refnum == 0) if (refnum == 0)
{ {
prodos_set_eof(refnum, 0); prodos_set_eof(refnum, 0);
prodos_close(refnum, &io_buff); prodos_close(refnum, &io_buff);
} }
return prodos_map_errno(refnum); else
err = prodos_map_errno(refnum);
A2PI_RELEASE;
return err;
} }
static int a2pi_statfs(const char *path, struct statvfs *stbuf) static int a2pi_statfs(const char *path, struct statvfs *stbuf)
{ {
unsigned char voldir[16], voldata[512]; unsigned char voldir[16], voldata[512];
int i, storage, access, type, numblks, aux, mod, create; int i, storage, access, type, numblks, aux, mod, create, err = 0;
memset(stbuf, 0, sizeof(struct statvfs)); memset(stbuf, 0, sizeof(struct statvfs));
/* /*
@ -1276,6 +1285,7 @@ static int a2pi_statfs(const char *path, struct statvfs *stbuf)
for (i = 1; path[i] && path[i] != '/'; i++) for (i = 1; path[i] && path[i] != '/'; i++)
voldir[i + 1] = path[i]; voldir[i + 1] = path[i];
voldir[0] = i; voldir[0] = i;
A2PI_WAIT;
if ((prodos_get_file_info(voldir, &access, &type, &aux, &storage, &numblks, &mod, &create)) > 0) if ((prodos_get_file_info(voldir, &access, &type, &aux, &storage, &numblks, &mod, &create)) > 0)
{ {
stbuf->f_bsize = 512; stbuf->f_bsize = 512;
@ -1284,27 +1294,33 @@ static int a2pi_statfs(const char *path, struct statvfs *stbuf)
stbuf->f_blocks = aux; stbuf->f_blocks = aux;
stbuf->f_bfree = stbuf->f_bfree =
stbuf->f_bavail = aux - numblks; stbuf->f_bavail = aux - numblks;
return 0;
} }
return -1; else
err = -1;
A2PI_RELEASE;
return err;
} }
int a2pi_utimens(const char *path, const struct timespec tv[2]) int a2pi_utimens(const char *path, const struct timespec tv[2])
{ {
int access, type, aux, storage, size, numblks, mod, create, refnum, io_buff = 0; int access, type, aux, storage, size, numblks, mod, create, refnum, err, io_buff = 0;
struct tm *tm = localtime(&tv[1].tv_sec); struct tm *tm = localtime(&tv[1].tv_sec);
cachepath[0] = '\0'; cachepath[0] = '\0';
/* /*
* Get file info. * Get file info.
*/ */
A2PI_WAIT;
if (cache_get_file_info(path, &access, &type, &aux, &storage, &numblks, &size, &mod, &create) == 0) if (cache_get_file_info(path, &access, &type, &aux, &storage, &numblks, &size, &mod, &create) == 0)
return prodos_map_errno(prodos_set_file_info(prodos_path(path, NULL, NULL, NULL), err = prodos_map_errno(prodos_set_file_info(prodos_path(path, NULL, NULL, NULL),
access, access,
type, type,
aux, aux,
prodos_time(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min), prodos_time(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min),
0)); 0));
return -ENOENT; else
err = -ENOENT;
A2PI_RELEASE;
return err;
} }
static struct fuse_operations a2pi_oper = { static struct fuse_operations a2pi_oper = {