/* * conv.c - Convert values * (C) Copyright 2000,2005,2009 Matti 'ccr' Hämäläinen * This program is Public Domain, use as you wish. * * Compilation: * gcc -o conv conv.c * * If you have inttypes.h: * gcc -o conv conv.c -DHAVE_INTTYPES * * If you have Glib2: * gcc -o conv conv.c -DHAVE_GLIB `pkg-config --cflags --libs glib-2.0` */ #include #include #include #ifdef HAVE_INTTYPES # include # define VALTYPE int64_t # define VALDEF 1ULL # define VALBITS 64 #else # ifdef HAVE_GLIB # include # define VALTYPE gint64 # define VALDEF 1ULL # define VALBITS 64 # else # define VALTYPE unsigned long int # define VALDEF 1UL # define VALBITS 32 # endif #endif /* Emergency replacements for PRI*64 modifiers */ #if !defined(PRIu64) # if defined(HAVE_INTTYPES) || defined(HAVE_GLIB) /* If we have inttypes or glib, assume we have 64-bit long long int */ # define PRIu64 "llu" # define PRIi64 "lli" # define PRIx64 "llx" # define PRIX64 "llX" # define PRIo64 "llo" # else /* Assume that we don't have long long, so use long int modifiers */ # define PRIu64 "lu" # define PRIi64 "li" # define PRIx64 "lx" # define PRIX64 "lX" # define PRIo64 "lo" # endif #endif /* long int is assumed to be at least 32bit, * int is assumed to be at least 16bit * size_t is assumed to exist. */ int main(int argc, char *argv[]) { VALTYPE value; char *convStr, tmpStr[128]; size_t i, j; int result, b1, b2, b3, b4; /* Check the arguments */ if (argc < 2) { fprintf(stderr, "Convert v0.7 by ccr/TNSP (C) 2000, 2005, 2009 TNSP\n\n" "Usage: %s [prefix] [conversion format]\n\n" "Prefixes: N/A (decimal), 0x (hex), %% (binary), o/O (octal), = (IPv4)\n" "Conversion formats are prefixes plus: d/i (signed decimal), u (unsigned)\n" "Examples: %s =127.0.0.1\n" " %s 0x55d92241 =\n", argv[0], argv[0], argv[0]); return 0; } convStr = argv[1]; /* Parse value */ result = 0; value = 0; if (convStr[0] == '0' && convStr[1] == 'x') { if (strlen(convStr) > 2) { if (sscanf(&convStr[2], "%" PRIx64, (VALTYPE *) &value) != 1) result = -1; } else result = -1; } else if (convStr[0] == '=') { if (sscanf(&convStr[1], "%d.%d.%d.%d", &b1, &b2, &b3, &b4) == 4) value = (b1 << 24) + (b2 << 16) + (b3 << 8) + b4; else result = -1; } else if (convStr[0] == '%') { char *s = convStr + 1; while (*s && !result) { if (*s == '1' || *s == '0') value = (value << 1) | (*s - '0'); else result = -1; s++; } } else if (toupper(convStr[0]) == 'O') { if (sscanf(&convStr[1], "%" PRIo64, (VALTYPE *) &value) != 1) result = -1; } else if (isdigit(convStr[0])) { if (sscanf(convStr, "%" PRIu64, (VALTYPE *) &value) != 1) result = -1; } else if ((convStr[0] == '-' || convStr[0] == '+') && isdigit(convStr[1])) { if (sscanf(convStr, "%" PRIi64, (VALTYPE *) &value) != 1) result = -1; } else { /* Show error message */ fprintf(stderr, "%s: Not any recognized value type.\n", argv[0]); return 1; } /* Create binary string */ for (j = 0, i = VALBITS; i; i--, j++) tmpStr[j] = (value & (VALDEF << (i - 1))) ? '1' : '0'; tmpStr[j] = 0; /* Print out conversions */ if (result < 0) { fprintf(stderr, "%s: Invalid format/syntax error '%s'\n", argv[0], convStr); } else { if (argc >= 3) { convStr = argv[2]; switch (*convStr) { case '=': printf("%d.%d.%d.%d", (int) ((value >> 24) & 0xff), (int) ((value >> 16) & 0xff), (int) ((value >> 8) & 0xff), (int) ((value) & 0xff)); break; case '0': convStr++; switch (*convStr) { case 'x': printf("%" PRIx64, value); break; case 'X': printf("%" PRIX64, value); break; } break; case 'x': printf("%" PRIx64, value); break; case 'X': printf("%" PRIX64, value); break; case 'o': case 'O': printf("%" PRIo64, value); break; case '%': printf("%s", tmpStr); break; case 'd': case 'i': printf("%" PRIi64, value); break; case 'u': printf("%" PRIu64, value); break; case 'c': case 'C': for (i = 4; i; i--) { b1 = (value >> ((i - 1) << 3)) & 0xff; if (b1 > 0) fputc(b1, stdout); } break; default: fprintf(stderr, "%s: Invalid conversion type '%s'\n", argv[0], argv[2]); break; } } else { printf("decimal: %" PRIi64 " (signed), %" PRIu64 " (unsigned)\n" "hex : 0x%" PRIx64 "\n" "binary : %%%s\n" "octal : %" PRIo64 "\n" "IP : %i.%i.%i.%i\n" "ASCII : '%c'\n", value, value, value, tmpStr, value, (int) ((value >> 24) & 0xff), (int) ((value >> 16) & 0xff), (int) ((value >> 8) & 0xff), (int) ((value) & 0xff), (unsigned char) value); } } return 0; }