#include #include #include #include #include #include static void check (int test, const char * msg, ...) { if (test) { va_list vargs; va_start (vargs, msg); vfprintf (stderr, msg, vargs); va_end (vargs); fprintf (stderr, ".\n"); exit (EXIT_FAILURE); } } #define BUFSIZE 0x1000 static void readcommand (FILE * f, char ** results_ptr, int * rlen_ptr) { char buf[BUFSIZE]; char * results; int rlen; rlen = 0; results = 0; while (1) { /* Flag to stop the "while" loop. */ int finished = 0; /* How many bytes have been read. */ int bytes; bytes = fread (buf, sizeof (char), BUFSIZE, f); if (bytes < BUFSIZE) { check (! feof (f), "fread failed: %s", strerror (errno)); finished = 1; } /* Allocate memory to add bytes + nul terminator. */ results = realloc (results, rlen + bytes + 1); check (! results, "realloc failed"); memcpy (results + rlen, buf, bytes); rlen += bytes; /* Nul-terminate string. */ results[rlen] = '\0'; if (finished) { * rlen_ptr = rlen; * results_ptr = results; return; } } } typedef enum { unknown, no, yes } binary_data_t; typedef struct { binary_data_t stripped; binary_data_t staticlinked; } binary_t; static void parsecommand (char * results, int rlen, binary_t * binary) { int offset; offset = 0; while (1) { char * comma; int len; int finished = 0; char * section; comma = strchr (results + offset, ','); if (comma) { len = comma - results - offset; } else { finished = 1; len = strlen (results + offset); } while (isspace (results[offset])) { offset++; len--; } asprintf (& section, "%.*s\n", len, results + offset); if (strstr (section, "stripped")) { if (strstr (section, "not")) { binary->stripped = no; } else { binary->stripped = yes; } } if (strstr (section, "linked")) { if (strstr (section, "dynamically")) { binary->staticlinked = no; } else if (strstr (section, "static")) { binary->staticlinked = yes; } else { binary->staticlinked = unknown; } } free (section); if (finished) { return; } offset += len + 1; } } static void print_status (const char * what, binary_data_t s) { printf ("%s status: ", what); switch (s) { case yes: printf ("yes"); break; case no: printf ("no"); break; case unknown: printf ("unknown"); break; } printf ("\n"); } int main (int argc, char ** argv) { char * command; FILE * f; char * results; int rlen; binary_t binary = {0}; asprintf (& command, "file %s", argv[0]); check (! command, "asprintf failed: %s", strerror (errno)); f = popen (command, "r"); check (! f, "popen failed: %s", strerror (errno)); readcommand (f, & results, & rlen); printf ("%s\n", results); parsecommand (results, rlen, & binary); print_status ("stripped", binary.stripped); print_status ("static", binary.staticlinked); free (command); free (results); pclose (f); return 0; }