#include #include #include "arraylen.h" /* Thanks to u/smcameron on Reddit. */ #define TAB_WIDTH 8 /* Changing ENUM to DEFINE will make this output the traditional BSD header * verbatim, without copyright notice. I don't have any idea if that's a * copyright violation, but let's keep this as ENUM to skirt by that little * technicality. * I implemented sysexits(3) in the enum method before reading the BSD 4.0 * source to see how they did it. */ #define ENUM 1 static char *program_name = "sysexits"; static const char comment_prefix[] = "/* "; static const char comment_prefix_ongoing[] = " * "; static const char comment_suffix[] = " */\n"; static const char header_prefix[] = "#ifndef _SYSEXITS_H\n" "#\tdefine _SYSEXITS_H\n" "enum{\n" ; /* ASSUMPTIONS: * - This array is always organized. * - All characters in descriptions are one space wide. * - The only whitespace in descriptions is ASCII_SP. */ static const struct { char *desc; char *name; int status; }sysexits[] = { /* sysexit descriptions copied from FreeBSD's sysexits(3). */ { "All is well.", /* except this one */ "EX_OK", 0 }, { "The command was used incorrectly, e.g., with the wrong number of" " arguments, a bad flag, a bad syntax in a parameter, or whatever.", "EX_USAGE", 64 }, { "The input data was incorrect in some way. This should only be used" " for user's data and not system files.", "EX_DATAERR", 65 }, { "An input file (not a system file) did not exist or was not readable." " This could also include errors like \"No message\" to a mailer (if it" " cared to catch it).", "EX_NOINPUT", 66 }, { "The user specified did not exist. This might be used for mail" " addresses or remote logins.", "EX_NOUSER", 67 }, { "The host specified did not exist. This is used in mail addresses or" " network requests.", "EX_NOHOST", 68 }, { "A service is unavailable. This can occur if a support program or" " file does not exist. This can also be used as a catchall message" " when something you wanted to do does not work, but you do not know" " why.", "EX_UNAVAILABLE", 69 }, { "An internal software error has been detected. This should be limited" " to non-operating system related errors as possible.", "EX_SOFTWARE", 70 }, { "An operating system error has been detected. This is intended to be" " used for such things as \"cannot fork\", \"cannot create pipe\", or" " the like. It includes things like getuid returning a user that does" " not exist in the passwd file.", "EX_OSERR", 71 }, { "Some system file (e.g., /etc/passwd, /var/run/utx.active, etc.) does" " not exist, cannot be opened, or has some sort of error (e.g., syntax" " error).", "EX_OSFILE", 72 }, { "A (user specified) output file cannot be created.", "EX_CANTCREAT", 73 }, { "An error occurred while doing I/O on some file.", "EX_IOERR", 74 }, { "Temporary failure, indicating something that is not really an error." " In sendmail, this means that a mailer (e.g.) could not create a" " connection, and the request should be reattempted later.", "EX_TEMPFAIL", 75 }, { "The remote system returned something that was \"not possible\" during a" " protocol exchange.", "EX_PROTOCOL", 76 }, { "You did not have sufficient permission to perform the operation." " This is not intended for file system problems, which should use" " EX_NOINPUT or EX_CANTCREAT, but rather for higher level" " permissions.", "EX_NOPERM", 77 }, { "Something was found in an unconfigured or misconfigured state.", "EX_CONFIG", 78 } }; static const char header_suffix[] = "};\n" "#endif /* ifndef _SYSEXITS_H */\n" ; static size_t i; static int findbyint(int status){ for(i = 0; i < ARRAYLEN(sysexits); ++i) if(sysexits[i].status == status) return i; return -1; } static void output_comment(int fd, int indentation, int width, char *comment){ size_t word_start; size_t line_start; for(i = 0, line_start = 0, word_start = 0; ; ++i) switch(comment[i]){ case '\0': while( i - line_start + ARRAYLEN(comment_suffix) + indentation * TAB_WIDTH > width){ i = word_start - 2; /* - current char, - space */ write( fd, comment_prefix_ongoing, ARRAYLEN(comment_prefix_ongoing) ); write(fd, comment + line_start, i - line_start); i += 2; /* + space, + next word char */ write(fd, "\n", 1); } write(fd, comment + line_start, i - line_start); write(fd, comment_suffix, ARRAYLEN(comment_suffix)); break; } return; } static void output_header(void){ write(1, header_prefix, ARRAYLEN(header_prefix) - 1); for(i = 0; i < ARRAYLEN(sysexits); ++i){ //output_comment(1, 1 * TAB_WIDTH, 80, sysexits[i].desc); #ifdef ENUM fprintf(stdout, "\t%s = %d%s", sysexits[i].name, sysexits[i].status, i < ARRAYLEN(sysexits) - 1 ? ",\n" : "\n" ); #endif /* ifdef ENUM */ #ifdef DEFINE fprintf(stdout, "#\tdefine %s %d\n", sysexits[i].name, sysexits[i].status ); #endif /* ifdef DEFINE */ } fflush(stdout); write(1, header_suffix, ARRAYLEN(header_suffix) - 1); } int main(int argc, char *argv[]){ if(argv[0] == NULL){ argv[0] = program_name; ++argc; } output_header(); return 0; }