diff rvinterf/etmsync/symlink.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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/etmsync/symlink.c	Sat Jun 11 00:13:35 2016 +0000
@@ -0,0 +1,141 @@
+/*
+ * Commands for experimenting with FFS symlinks
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "etm.h"
+#include "ffs.h"
+#include "tmffs2.h"
+#include "limits.h"
+#include "ffslimits.h"
+#include "localtypes.h"
+#include "localstruct.h"
+#include "exitcodes.h"
+
+extern u_char rvi_msg[];
+extern int rvi_msg_len;
+
+do_symlink(target, realobj)
+	char *target, *realobj;
+{
+	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
+	int rc, targlen, reallen;
+
+	reallen = strlen(realobj);
+	if (reallen >= TMFFS_STRING_SIZE) {
+		printf("error: pathname arg exceeds string length limit\n");
+		return(ERROR_USAGE);
+	}
+	targlen = strlen(target);
+	if (3 + (reallen+2) + (targlen+2) + 1 > MAX_PKT_TO_TARGET) {
+		printf("error: symlink request fails to fit into packet\n");
+		return(ERROR_USAGE);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_SYMLINK;
+	*dp++ = reallen + 1;
+	strcpy(dp, realobj);
+	dp += reallen + 1;
+	*dp++ = targlen + 1;
+	strcpy(dp, target);
+	dp += targlen + 1;
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg_len != 5) {
+		printf("error: TMFFS_SYMLINK response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	if (rvi_msg[3]) {
+		report_ffs_err("symlink", rvi_msg[3]);
+		return(ERROR_TARGET);
+	}
+	return(0);
+}
+
+cmd_symlink(argc, argv)
+	char **argv;
+{
+	return do_symlink(argv[1], argv[2]);
+}
+
+do_readlink(pathname, databuf, rdret)
+	char *pathname;
+	u_char *databuf;
+	int *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);
+	}
+	dp = cmdpkt + 1;
+	*dp++ = ETM_FFS2;
+	*dp++ = TMFFS_READLINK;
+	*dp++ = slen + 1;
+	strcpy(dp, pathname);
+	dp += slen + 1;
+	*dp++ = 0;	/* dummy 2nd buffer */
+	rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1);
+	if (rc)
+		return(rc);
+	if (rvi_msg[3]) {
+		report_ffs_err("readlink", 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) {
+		printf("error: readlink response has wrong length\n");
+		return(ERROR_TARGET);
+	}
+	bcopy(rvi_msg + 5, databuf, sz);
+	*rdret = sz;
+	return(0);
+}
+
+cmd_readlink(argc, argv)
+	char **argv;
+{
+	u_char databuf[256];
+	int rc, sz, off, l;
+
+	rc = do_readlink(argv[1], databuf, &sz);
+	if (rc)
+		return(rc);
+	printf("%d bytes read\n", sz);
+	for (off = 0; off < sz; off += 16) {
+		l = sz - off;
+		if (l > 16)
+			l = 16;
+		hexdump_line(off, databuf + off, l);
+	}
+	return(0);
+}
+
+do_readlink_sancheck(pathname, databuf)
+	char *pathname;
+	u_char *databuf;
+{
+	int rc, sz;
+
+	rc = do_readlink(pathname, databuf, &sz);
+	if (rc)
+		return(rc);
+	if (sz < 2 || databuf[sz-1]) {
+		printf("error: readlink on %s returned garbage\n", pathname);
+		return(ERROR_TARGET);
+	}
+	return(0);
+}