FreeCalypso > hg > freecalypso-tools
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); + } +}