/* * Copyright (c) Alex Holden 2000, 2001. * * This code is public domain; you can do whatever you want with it, though I * would prefer you to contribute any bug fixes back to me if possible. * This software comes with NO WARRANTY WHATSOEVER, not even the implied * warranties of merchantability and fitness for a particular purpose. * * util.c: Various utility functions. */ #include #include #include #include #include #include #include "arch.h" #include "util.h" struct termios origtermattr; /* * Used to restore the terminal attributes to those which were in place before * we switched to non canonical and non echo mode. */ void restore_termattr(void) { tcsetattr(STDIN_FILENO, TCSANOW, &origtermattr); } /* Converts a hex character to an integer */ static int h2i(char c) { int ret; if((c >= '0') && (c <= '9')) ret = (c - '0'); else if((c >= 'a') && (c <= 'f')) ret = (c - 'a' + 10); else if((c >= 'A') & (c <= 'F')) ret = (c - 'A' + 10); else ret = -1; return ret; } /* * Converts a pair of ascii hex characters to an 8 bit number or -1 if they are * not valid a valid hex number. */ int hextoint(char *p) { int i, ret; if((i = h2i(p[0])) == -1) return -1; if((ret = h2i(p[1])) == -1) return -1; ret |= i << 4; return ret; } /* Converts an integer between 0 and 15 to a lower case ascii hex character */ static u8 i2h(int i) { if(i < 10) return('0' + i); else return('a' + i - 10); } /* * Converts an 8 bit number to a two character ASCII hex string. */ void inttohex(u8 i, char *p) { p[0] = i2h(i >> 4); p[1] = i2h(i & 0xf); } /* * Converts an unsigned 32 bit value between big and little endian formats. */ u32 swapu32(u32 n) { return(((n & 0xff000000) >> 24) | ((n & 0x000000ff) << 24) | ((n & 0x00ff0000) >> 8) | ((n & 0x0000ff00) << 8)); } /* Write an error string to stderr and exit */ void die(char *msg) { safe_write(STDERR_FILENO, msg, strlen(msg)); #ifdef DOS_LINE_ENDINGS safe_write(STDERR_FILENO, "\r\n", 2); #else safe_write(STDERR_FILENO, "\n", 1); #endif exit(1); } /* Allocate a block of memory and exit if it fails */ void *safe_malloc(size_t size) { void *ret; if(!(ret = malloc(size))) die("Out of memory"); return ret; } /* Copy a string to a newly allocated buffer */ char *safe_strdup(const char *s) { char *ret; size_t len; len = strlen(s) + 1; ret = safe_malloc(len); memcpy(ret, s, len); return ret; } /* * Read or write the specified amount of data, even if it requires multiple * system calls to achieve. * safe_read() and safe_write() are also provided as convenience macros. */ long safe_readwrite(int fd, void *buf, long len, int r) { long pos = 0, bytes; while(pos < len) { if(r) bytes = read(fd, (char *)buf + pos, len - pos); else bytes = write(fd, (char *)buf + pos, len - pos); if(bytes == -1) { if(errno == EINTR) continue; else return -1; } else if(bytes == 0) break; else pos += bytes; } return pos; } /* * Opens the file with the specified path for writing and returns the file * descriptor, or if the path is NULL, returns the file descriptor of stdout. */ int openwrite(char *path) { int fd; if(!path) return STDOUT_FILENO; if((unlink(path) == -1) && errno != ENOENT) die("Couldn't remove previous output file"); if(!(fd = open(path, O_WRONLY | O_CREAT, 0644))) die("Output file open failed"); return fd; }