Added errno, strerror and the "%m" printf metacharacter. These will allow
authorMichael Brown <mcb30@etherboot.org>
Tue, 17 May 2005 18:26:41 +0000 (18:26 +0000)
committerMichael Brown <mcb30@etherboot.org>
Tue, 17 May 2005 18:26:41 +0000 (18:26 +0000)
us to return proper PXE status codes, while simultaneously allowing for
more consistent error reporting (complete with verbose error messages as a
build-time option).

src/core/errno.c [new file with mode: 0644]
src/core/vsprintf.c
src/include/errno.h [new file with mode: 0644]

diff --git a/src/core/errno.c b/src/core/errno.c
new file mode 100644 (file)
index 0000000..f0cf5a6
--- /dev/null
@@ -0,0 +1,29 @@
+#include "errno.h"
+#include "vsprintf.h"
+
+/* Global "last error" number */
+int errno;
+
+static struct errortab errortab_start[0] __table_start(errortab);
+static struct errortab errortab_end[0] __table_end(errortab);
+
+/*
+ * Retrieve string representation of error number.
+ *
+ * If error not found in the error table, generate a generic "Error
+ * 0x0000" message.
+ *
+ */
+const char * strerror ( int errno ) {
+       static char *generic_message = "Error 0x0000";
+       struct errortab *errortab;
+
+       for ( errortab = errortab_start ; errortab < errortab_end ;
+             errortab++ ) {
+               if ( errortab->errno == errno )
+                       return errortab->text;
+       }
+
+       sprintf ( generic_message + 8, "%hx", errno );
+       return generic_message;
+}
index 414b450..77373cc 100644 (file)
@@ -2,6 +2,7 @@
 #include "if_ether.h" /* for ETH_ALEN */
 #include "limits.h" /* for CHAR_BIT */
 #include "console.h"
+#include "errno.h"
 #include "vsprintf.h"
 
 #define LONG_SHIFT  ((int)((sizeof(unsigned long)*CHAR_BIT) - 4))
@@ -31,7 +32,8 @@ PRINTF and friends
 **************************************************************************/
 static int vsprintf(char *buf, const char *fmt, va_list args)
 {
-       char *p, *s;
+       const char *p;
+       char *s;
        s = buf;
        for ( ; *fmt != '\0'; ++fmt) {
                if (*fmt != '%') {
@@ -49,8 +51,10 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                if (*fmt == 's') {
                        for(p = va_arg(args, char *); *p != '\0'; p++) 
                                buf ? *s++ = *p : putchar(*p);
-               }
-               else {  /* Length of item is bounded */
+               } else if (*fmt == 'm') {
+                       for(p = strerror(errno); *p != '\0'; p++)
+                               buf ? *s++ = *p : putchar(*p);
+               } else {        /* Length of item is bounded */
                        char tmp[40], *q = tmp;
                        int alt = 0;
                        int shift = INT_SHIFT;
@@ -93,7 +97,7 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                        *q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
                        }
                        else if (*fmt == 'd') {
-                               char *r;
+                               char *r, *t;
                                long i;
                                if (shift > INT_SHIFT) {
                                        i = va_arg(args, long);
@@ -104,17 +108,17 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                        *q++ = '-';
                                        i = -i;
                                }
-                               p = q;          /* save beginning of digits */
+                               t = q;          /* save beginning of digits */
                                do {
                                        *q++ = '0' + (i % 10);
                                        i /= 10;
                                } while (i);
                                /* reverse digits, stop in middle */
                                r = q;          /* don't alter q */
-                               while (--r > p) {
+                               while (--r > t) {
                                        i = *r;
-                                       *r = *p;
-                                       *p++ = i;
+                                       *r = *t;
+                                       *t++ = i;
                                }
                        }
                        else if (*fmt == '@') {
@@ -129,7 +133,7 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                --q;
                        }
                        else if (*fmt == '!') {
-                               char *r;
+                               const char *r;
                                p = va_arg(args, char *);
                                for (r = p + ETH_ALEN; p < r; ++p)
                                        q += sprintf(q, "%hhX:", *p);
diff --git a/src/include/errno.h b/src/include/errno.h
new file mode 100644 (file)
index 0000000..7b34ce9
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef ERRNO_H
+#define ERRNO_H
+
+/*
+ * We define error codes that are a superset of those mentioned in the
+ * PXE specification.  Various error string tables may be compiled in
+ * if required; if not compiled in, strerror(errno) will produce the
+ * text "error 0x<errno>".
+ *
+ */
+
+/* PXE error codes are determined by the PXE specification */
+
+/* Generic errors */
+#define        PXENV_STATUS_SUCCESS                            0x00
+#define        PXENV_STATUS_FAILURE                            0x01
+#define        PXENV_STATUS_BAD_FUNC                           0x02
+#define        PXENV_STATUS_UNSUPPORTED                        0x03
+#define        PXENV_STATUS_KEEP_UNDI                          0x04
+#define        PXENV_STATUS_KEEP_ALL                           0x05
+#define        PXENV_STATUS_OUT_OF_RESOURCES                   0x06
+
+/* ARP errors (0x10 to 0x1f) */
+#define        PXENV_STATUS_ARP_TIMEOUT                        0x11
+
+/* Base-Code state errors */
+#define        PXENV_STATUS_UDP_CLOSED                         0x18
+#define        PXENV_STATUS_UDP_OPEN                           0x19
+#define        PXENV_STATUS_TFTP_CLOSED                        0x1a
+#define        PXENV_STATUS_TFTP_OPEN                          0x1b
+
+/* BIOS/system errors (0x20 to 0x2f) */
+#define        PXENV_STATUS_MCOPY_PROBLEM                      0x20
+#define        PXENV_STATUS_BIS_INTEGRITY_FAILURE              0x21
+#define        PXENV_STATUS_BIS_VALIDATE_FAILURE               0x22
+#define        PXENV_STATUS_BIS_INIT_FAILURE                   0x23
+#define        PXENV_STATUS_BIS_SHUTDOWN_FAILURE               0x24
+#define        PXENV_STATUS_BIS_GBOA_FAILURE                   0x25
+#define        PXENV_STATUS_BIS_FREE_FAILURE                   0x26
+#define        PXENV_STATUS_BIS_GSI_FAILURE                    0x27
+#define        PXENV_STATUS_BIS_BAD_CKSUM                      0x28
+
+/* TFTP/MTFTP errors (0x30 to 0x3f) */
+#define        PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS            0x30
+#define        PXENV_STATUS_TFTP_OPEN_TIMEOUT                  0x32
+#define        PXENV_STATUS_TFTP_UNKNOWN_OPCODE                0x33
+#define        PXENV_STATUS_TFTP_READ_TIMEOUT                  0x35
+#define        PXENV_STATUS_TFTP_ERROR_OPCODE                  0x36
+#define        PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION        0x38
+#define        PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION   0x39
+#define        PXENV_STATUS_TFTP_TOO_MANY_PACKAGES             0x3a
+#define        PXENV_STATUS_TFTP_FILE_NOT_FOUND                0x3b
+#define        PXENV_STATUS_TFTP_ACCESS_VIOLATION              0x3c
+#define        PXENV_STATUS_TFTP_NO_MCAST_ADDRESS              0x3d
+#define        PXENV_STATUS_TFTP_NO_FILESIZE                   0x3e
+#define        PXENV_STATUS_TFTP_INVALID_PACKET_SIZE           0x3f
+
+/* Reserved errors 0x40 to 0x4f) */
+
+/* DHCP/BOOTP errors (0x50 to 0x5f) */
+#define        PXENV_STATUS_DHCP_TIMEOUT                       0x51
+#define        PXENV_STATUS_DHCP_NO_IP_ADDRESS                 0x52
+#define        PXENV_STATUS_DHCP_NO_BOOTFILE_NAME              0x53
+#define        PXENV_STATUS_DHCP_BAD_IP_ADDRESS                0x54
+
+/* Driver errors (0x60 to 0x6f) */
+#define        PXENV_STATUS_UNDI_INVALID_FUNCTION              0x60
+#define        PXENV_STATUS_UNDI_MEDIATEST_FAILED              0x61
+#define        PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST     0x62
+#define        PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC         0x63
+#define        PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY         0x64
+#define        PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA       0x65
+#define        PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA         0x66
+#define        PXENV_STATUS_UNDI_BAD_MAC_ADDRESS               0x67
+#define        PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM           0x68
+#define        PXENV_STATUS_UNDI_ERROR_SETTING_ISR             0x69
+#define        PXENV_STATUS_UNDI_INVALID_STATE                 0x6a
+#define        PXENV_STATUS_UNDI_TRANSMIT_ERROR                0x6b
+#define        PXENV_STATUS_UNDI_INVALID_PARAMETER             0x6c
+
+/* ROM and NBP bootstrap errors (0x70 to 0x7f) */
+#define        PXENV_STATUS_BSTRAP_PROMPT_MENU                 0x74
+#define        PXENV_STATUS_BSTRAP_MCAST_ADDR                  0x76
+#define        PXENV_STATUS_BSTRAP_MISSING_LIST                0x77
+#define        PXENV_STATUS_BSTRAP_NO_RESPONSE                 0x78
+#define        PXENV_STATUS_BSTRAP_FILE_TOO_BIG                0x79
+
+/* Environment NBP errors (0x80 to 0x8f) */
+
+/* Reserved errors (0x90 to 0x9f) */
+
+/* Miscellaneous errors (0xa0 to 0xaf) */
+#define        PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE         0xa0
+#define        PXENV_STATUS_BINL_NO_PXE_SERVER                 0xa1
+#define        PXENV_STATUS_NOT_AVAILABLE_IN_PMODE             0xa2
+#define        PXENV_STATUS_NOT_AVAILABLE_IN_RMODE             0xa3
+
+/* BUSD errors (0xb0 to 0xbf) */
+#define        PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED          0xb0
+
+/* Loader errors (0xc0 to 0xcf) */
+#define        PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY         0xc0
+#define        PXENV_STATUS_LOADER_NO_BC_ROMID                 0xc1
+#define        PXENV_STATUS_LOADER_BAD_BC_ROMID                0xc2
+#define        PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE        0xc3
+#define        PXENV_STATUS_LOADER_NO_UNDI_ROMID               0xc4
+#define        PXENV_STATUS_LOADER_BAD_UNDI_ROMID              0xc5
+#define        PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE       0xc6
+#define        PXENV_STATUS_LOADER_NO_PXE_STRUCT               0xc8
+#define        PXENV_STATUS_LOADER_NO_PXENV_STRUCT             0xc9
+#define        PXENV_STATUS_LOADER_UNDI_START                  0xca
+#define        PXENV_STATUS_LOADER_BC_START                    0xcb
+
+/*
+ * The range 0xd0 to 0xff is defined as "Vendor errors" by the PXE
+ * spec.  We place all our Etherboot-specific errors in this range.
+ * We also define some generic errors as aliases to the PXE errors.
+ *
+ */
+
+#define ENOMEM PXENV_STATUS_OUT_OF_RESOURCES
+
+/* Data structures and declarations */
+
+#include "tables.h"
+
+extern int errno;
+
+extern const char * strerror ( int errno );
+
+struct errortab {
+       int errno;
+       const char *text;
+};
+
+#define __errortab __table(errortab,01)
+
+#endif /* ERRNO_H */