diff rvinterf/etmsync/fileio.c @ 0:e7502631a0f9

initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 Jun 2016 00:13:35 +0000
parents
children a0754c98fc2b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/etmsync/fileio.c	Sat Jun 11 00:13:35 2016 +0000
@@ -0,0 +1,401 @@
+/*
+ * FFS2 file descriptor I/O operations
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "etm.h"
+#include "ffs.h"
+#include "ffserr.h"
+#include "tmffs2.h"
+#include "limits.h"
+#include "localtypes.h"
+#include "localstruct.h"
+#include "exitcodes.h"
+
+extern u_char rvi_msg[];
+extern int rvi_msg_len;
+
+fd_open(pathname, flags, fdrtn)
+	char *pathname;
+	int flags, *fdrtn;
+{
+	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
+	int rc, slen;
+
+	slen = strlen(pathname);
+	if (slen >= TMFFS_STRING_SIZE) {
+		printf("error: pathname arg exceeds string length limit\n");
+		return(ERROR_USAGE);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_OPEN;
+	*dp++ = slen + 1;
+	strcpy(dp, pathname);
+	dp += slen + 1;
+	*dp++ = flags;
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("open fd", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg_len != 6) {
+		printf("error: open fd response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	*fdrtn = rvi_msg[4];
+	return(0);
+}
+
+fd_read(fd, databuf, rdsize, rdret)
+	u_char *databuf;
+	int fd, rdsize, *rdret;
+{
+	u_char cmdpkt[6];
+	int rc, sz;
+
+	if (rdsize > MAX_READ_DATA) {
+		printf("error: # of bytes to read may not exceed %d\n",
+			MAX_READ_DATA);
+		return(ERROR_USAGE);
+	}
+	cmdpkt[1] = ETM_FFS2;
+	cmdpkt[2] = TMFFS_READ;
+	cmdpkt[3] = fd;
+	cmdpkt[4] = rdsize;
+	rc = etm_pkt_exch(cmdpkt, 4);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("read fd", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg_len < 6) {
+		*rdret = 0;
+		return(0);
+	}
+	sz = rvi_msg[4];
+	if (rvi_msg_len != sz + 6 || sz > rdsize) {
+		printf("error: read fd response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	bcopy(rvi_msg + 5, databuf, sz);
+	*rdret = sz;
+	return(0);
+}
+
+fd_write(fd, data, wrsize)
+	u_char *data;
+{
+	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
+	int rc;
+
+	if (wrsize > MAX_PKT_TO_TARGET - 6) {
+		printf("error: fd write data fails to fit in the packet\n");
+		return(ERROR_USAGE);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_WRITE;
+	*dp++ = fd;
+	*dp++ = wrsize;
+	bcopy(data, dp, wrsize);
+	dp += wrsize;
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("fd write", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg_len != 6) {
+		printf("error: TMFFS_WRITE response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg[4] != wrsize) {
+		printf("fd write error: # of bytes written != requested\n");
+		return(ERROR_TARGET);
+	}
+	return(0);
+}
+
+fd_close(fd)
+{
+	u_char cmdpkt[5];
+	int rc;
+
+	cmdpkt[1] = ETM_FFS2;
+	cmdpkt[2] = TMFFS_CLOSE;
+	cmdpkt[3] = fd;
+	rc = etm_pkt_exch(cmdpkt, 3);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("close fd", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg_len != 5) {
+		printf("error: close fd response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	return(0);
+}
+
+do_file_read(pathname, databuf, rdsize, rdret)
+	char *pathname;
+	u_char *databuf;
+	int rdsize, *rdret;
+{
+	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
+	int rc, slen, sz;
+
+	slen = strlen(pathname);
+	if (slen >= TMFFS_STRING_SIZE) {
+		printf("error: pathname arg exceeds string length limit\n");
+		return(ERROR_USAGE);
+	}
+	if (rdsize > MAX_READ_DATA) {
+		printf("error: # of bytes to read may not exceed %d\n",
+			MAX_READ_DATA);
+		return(ERROR_USAGE);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_FILE_READ;
+	*dp++ = slen + 1;
+	strcpy(dp, pathname);
+	dp += slen + 1;
+	*dp++ = rdsize;
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("read file", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg_len < 6) {
+		*rdret = 0;
+		return(0);
+	}
+	sz = rvi_msg[4];
+	if (rvi_msg_len != sz + 6 || sz > rdsize) {
+		printf("error: read file response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	bcopy(rvi_msg + 5, databuf, sz);
+	*rdret = sz;
+	return(0);
+}
+
+max_short_file_write(pathname)
+	char *pathname;
+{
+	return MAX_PKT_TO_TARGET - 3 - (strlen(pathname) + 2) - 3;
+}
+
+do_short_fwrite(pathname, data, datalen)
+	char *pathname;
+	u_char *data;
+{
+	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
+	int rc, slen;
+
+	slen = strlen(pathname);
+	if (slen >= TMFFS_STRING_SIZE) {
+		printf("error: pathname arg exceeds string length limit\n");
+		return(ERROR_USAGE);
+	}
+	if (datalen > max_short_file_write(pathname)) {
+		printf("error: short write data fails to fit in the packet\n");
+		return(ERROR_USAGE);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_FILE_WRITE;
+	*dp++ = slen + 1;
+	strcpy(dp, pathname);
+	dp += slen + 1;
+	*dp++ = datalen;
+	bcopy(data, dp, datalen);
+	dp += datalen;
+	*dp++ = FFS_O_CREATE | FFS_O_TRUNC;
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg_len != 5) {
+		printf("error: TMFFS_FILE_WRITE response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg[3]) {
+		report_ffs_err("short file write", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	return(0);
+}
+
+do_opendir(pathname, statertn, countrtn)
+	char *pathname;
+	u_char *statertn;
+	int *countrtn;
+{
+	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
+	int rc, slen;
+
+	slen = strlen(pathname);
+	if (slen >= TMFFS_STRING_SIZE) {
+		printf("error: pathname arg exceeds string length limit\n");
+		return(ERROR_USAGE);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_OPENDIR;
+	*dp++ = slen + 1;
+	strcpy(dp, pathname);
+	dp += slen + 1;
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("opendir", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg_len != 11 || rvi_msg[5] != 4) {
+		printf("error: opendir response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	*countrtn = rvi_msg[4];
+	bcopy(rvi_msg + 6, statertn, 4);
+	return(0);
+}
+
+do_readdir(state, namebuf, namebuflen)
+	u_char *state;
+	char *namebuf;
+{
+	u_char cmdpkt[10];
+	int rc, slen;
+
+	cmdpkt[1] = ETM_FFS2;
+	cmdpkt[2] = TMFFS_READDIR;
+	cmdpkt[3] = 4;
+	bcopy(state, cmdpkt+4, 4);
+	cmdpkt[8] = TMFFS_STRING_SIZE;
+	rc = etm_pkt_exch(cmdpkt, 8);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("readdir", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg_len < 14) {
+malformed:	printf("error: readdir response is malformed\n");
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg[5] != 4)
+		goto malformed;
+	slen = rvi_msg[10];
+	if (slen < 2 || rvi_msg_len != slen + 12)
+		goto malformed;
+	if (slen > namebuflen) {
+		printf("error: readdir response exceeds provided buffer\n");
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg[11 + slen - 1])	/* must be terminating NUL */
+		goto malformed;
+	bcopy(rvi_msg + 6, state, 4);
+	strcpy(namebuf, rvi_msg + 11);
+	return(0);
+}
+
+do_xlstat(pathname, result)
+	char *pathname;
+	struct stat_info *result;
+{
+	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
+	int rc, slen;
+
+	slen = strlen(pathname);
+	if (slen >= TMFFS_STRING_SIZE) {
+		printf("error: pathname arg exceeds string length limit\n");
+		return(ERROR_USAGE);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_XLSTAT;
+	*dp++ = slen + 1;
+	strcpy(dp, pathname);
+	dp += slen + 1;
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("xlstat", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg_len != 30 || rvi_msg[4] != 24) {
+		printf("error: xlstat response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	result->type = rvi_msg[5];
+	result->flags = rvi_msg[6];
+	result->inode = rvi_msg[7] | rvi_msg[8] << 8;
+	result->size = rvi_msg[9] | rvi_msg[10] << 8 | rvi_msg[11] << 16 |
+			rvi_msg[12] << 24;
+	result->space = rvi_msg[13] | rvi_msg[14] << 8 | rvi_msg[15] << 16 |
+			rvi_msg[16] << 24;
+	result->location = rvi_msg[17] | rvi_msg[18] << 8 | rvi_msg[19] << 16 |
+				rvi_msg[20] << 24;
+	result->block = rvi_msg[22];
+	result->sequence = rvi_msg[23] | rvi_msg[24] << 8;
+	result->updates = rvi_msg[25] | rvi_msg[26] << 8;
+	return(0);
+}
+
+do_mkdir_existok(pathname)
+	char *pathname;
+{
+	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
+	int rc, slen;
+	struct stat_info stat;
+
+	slen = strlen(pathname);
+	if (slen >= TMFFS_STRING_SIZE) {
+		printf("error: pathname arg exceeds string length limit\n");
+		return(ERROR_USAGE);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_MKDIR;
+	*dp++ = slen + 1;
+	strcpy(dp, pathname);
+	dp += slen + 1;
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg_len != 5) {
+		printf("error: mkdir response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	if (!rvi_msg[3])	/* success */
+		return(0);
+	if (rvi_msg[3] != TMFFS_ERR_EXISTS) {
+		report_ffs_err("mkdir", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	/* object already exists: OK if it's a directory, error otherwise */
+	rc = do_xlstat(pathname, &stat);
+	if (rc)
+		return(rc);
+	if (stat.type == OT_DIR)
+		return(0);
+	else {
+		printf("error: %s exists and is not a directory\n", pathname);
+		return(ERROR_TARGET);
+	}
+}