Library routines for manipulating ADV data
authorH. Peter Anvin <hpa@zytor.com>
Thu, 13 Dec 2007 22:46:04 +0000 (14:46 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 13 Dec 2007 22:46:04 +0000 (14:46 -0800)
com32/include/syslinux/adv.h
com32/include/syslinux/advconst.h [new file with mode: 0644]
com32/lib/Makefile
com32/lib/syslinux/adv.c
com32/lib/syslinux/getadv.c [new file with mode: 0644]
com32/lib/syslinux/setadv.c [new file with mode: 0644]

index 9af80ba..a31712b 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <klibc/extern.h>
 #include <stddef.h>
+#include <syslinux/advconst.h>
 
 __extern void *__syslinux_adv_ptr;
 __extern size_t __syslinux_adv_size;
@@ -50,4 +51,7 @@ static inline size_t syslinux_adv_size(void)
 
 __extern int syslinux_adv_write(void);
 
+__extern int syslinux_setadv(int, size_t, const void *);
+__extern const void *syslinux_getadv(int, size_t *);
+
 #endif /* _SYSLINUX_ADV_H */
diff --git a/com32/include/syslinux/advconst.h b/com32/include/syslinux/advconst.h
new file mode 100644 (file)
index 0000000..f9d55aa
--- /dev/null
@@ -0,0 +1,43 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2007 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/advconst.h
+ *
+ * ADV defined constants
+ *
+ * Defined in a separate file so it can be used by non-COM32 code.
+ * Some of these constants are also defined in adv.inc, they better match...
+ */
+
+#ifndef _SYSLINUX_ADVCONST_H
+#define _SYSLINUX_ADVCONST_H
+
+#define ADV_END                0
+#define ADV_BOOTONCE   1
+
+#endif /* _SYSLINUX_ADVCONST_H */
index 314b847..6540f9f 100644 (file)
@@ -83,7 +83,8 @@ LIBOBJS = \
        \
        syslinux/pxe_get_cached.o                                       \
        \
-       syslinux/adv.o syslinux/advwrite.o
+       syslinux/adv.o syslinux/advwrite.o syslinux/getadv.o            \
+       syslinux/setadv.o
 
 BINDIR   = /usr/bin
 LIBDIR   = /usr/lib
index 75aab2c..a4e74ab 100644 (file)
@@ -26,7 +26,7 @@
  * ----------------------------------------------------------------------- */
 
 /*
- * syslinux/adv.h
+ * syslinux/adv.c
  *
  * Access the syslinux auxilliary data vector
  */
diff --git a/com32/lib/syslinux/getadv.c b/com32/lib/syslinux/getadv.c
new file mode 100644 (file)
index 0000000..416f5f9
--- /dev/null
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2007 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/getadv.c
+ *
+ * Get a data item from the auxilliary data vector.  Returns a pointer
+ * and sets *size on success; NULL on failure.
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <inttypes.h>
+
+const void *syslinux_getadv(int tag, size_t *size)
+{
+  const uint8_t *p;
+  size_t left, len;
+
+  p = syslinux_adv_ptr();
+  left = syslinux_adv_size();
+
+  while (left >= 2) {
+    uint8_t ptag = *p++;
+    size_t  plen = *p++;
+    left -= 2;
+
+    if (ptag == ADV_END)
+      return NULL;             /* Not found */
+
+    if (left < plen)
+      return NULL;             /* Item overrun */
+
+    if (ptag == tag) {
+      *size = plen;
+      return p;
+    }
+
+    p    += plen;
+    left -= plen;
+  }
+
+  return NULL;
+}
diff --git a/com32/lib/syslinux/setadv.c b/com32/lib/syslinux/setadv.c
new file mode 100644 (file)
index 0000000..1e1f122
--- /dev/null
@@ -0,0 +1,106 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2007 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/setadv.c
+ *
+ * (Over)write a data item in the auxilliary data vector.  To
+ * delete an item, set its length to zero.
+ *
+ * Return 0 on success, -1 on error, and set errno.
+ *
+ * NOTE: Data is not written to disk unless
+ * syslinux_adv_write() is called.
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <inttypes.h>
+#include <string.h>
+#include <errno.h>
+#include <alloca.h>
+
+int syslinux_setadv(int tag, size_t size, const void *data)
+{
+  uint8_t *p, *advtmp;
+  size_t left;
+
+  if ((unsigned)tag-1 > 254) {
+    errno = EINVAL;
+    return -1;                 /* Impossible tag value */
+  }
+
+  left = syslinux_adv_size();
+  p = advtmp = alloca(left);
+  memcpy(p, syslinux_adv_ptr(), left); /* Make working copy */
+
+  while (left >= 2) {
+    uint8_t ptag = p[0];
+    size_t  plen = p[1]+2;
+
+    if (ptag == ADV_END)
+      break;
+
+    if (ptag == tag) {
+      /* Found our tag.  Delete it. */
+
+      if (plen >= left) {
+       /* Entire remainder is our tag */
+       break;
+      }
+      memmove(p, p+plen, left-plen);
+    } else {
+      /* Not our tag */
+      if (plen > left)
+       break;                  /* Corrupt tag (overrun) - overwrite it */
+
+      left -= plen;
+      p += plen;
+    }
+  }
+
+  /* Now (p, left) reflects the position to write in and how much space
+     we have for our data. */
+
+  if (left < size+2) {
+    errno = ENOSPC;            /* Not enough space for data */
+    return -1;
+  }
+
+  *p++ = tag;
+  *p++ = size;
+  memcpy(p, data, size);
+  left -= size+2;
+      
+  memset(p, 0, left);
+
+  /* If we got here, everything went OK, commit the write to low memory */
+  memcpy(syslinux_adv_ptr(), advtmp, syslinux_adv_size());
+
+  return 0;
+}
+