Created
April 9, 2019 03:42
-
-
Save danieloneill/492420111421047a6b926c81feb7ced7 to your computer and use it in GitHub Desktop.
Parse /etc/mime.types in C, produce a linked-list of all mimetypes and filetype associations.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#define MIMETYPE_MAX 32768*4 | |
#define MIMETYPE_EXT_MAX_LENGTH 16 | |
#define MIMETYPE_EXT_MAX_COUNT 16 | |
// Linked list of our mimetypes: | |
struct s_mimetype { | |
char mimetype[64]; | |
int extensioncount; | |
char *extensions[MIMETYPE_EXT_MAX_COUNT]; | |
struct s_mimetype *next; | |
}; | |
struct s_mimetype *mimes = NULL; | |
void read_mimetypes() | |
{ | |
FILE *fh = fopen("/etc/mime.types", "r"); | |
if( !fh ) | |
{ | |
fprintf(stderr, "Failed to read /etc/mime.types!\n"); | |
return; | |
} | |
// Slurp it into a big ol' buffer. If yours is larger than this, well, make this bigger. | |
char *mimeraw = (char*)malloc( MIMETYPE_MAX+1 ); | |
size_t rin = fread( mimeraw, 1, MIMETYPE_MAX, fh ); | |
fclose( fh ); | |
mimeraw[ rin ] = '\0'; | |
bool onext = false; | |
bool comment = false; | |
struct s_mimetype *mime = (struct s_mimetype *)malloc(sizeof(struct s_mimetype)); | |
memset( mime, 0, sizeof(struct s_mimetype) ); | |
for( int x=0; mime && x < rin; x++ ) | |
{ | |
char ch = mimeraw[x]; | |
if( ch == '#' ) | |
comment = true; | |
else if( ch == '\r' || ch == '\n' ) | |
{ | |
if( mime->mimetype[0] == '\0' ) | |
{ | |
// it's empty. | |
onext = false; | |
comment = false; | |
continue; | |
} | |
// done this entry, move along now. | |
mime->next = mimes; | |
mimes = mime; | |
mime = NULL; | |
mime = (struct s_mimetype *)malloc(sizeof(struct s_mimetype)); | |
memset( mime, 0, sizeof(struct s_mimetype) ); | |
onext = false; | |
comment = false; | |
continue; | |
} | |
else if( comment ) | |
continue; | |
else if( onext ) | |
{ | |
int extnum = mime->extensioncount - 1; | |
int extlen = strlen( mime->extensions[extnum] ); | |
if( ch == ' ' || ch == '\t' ) | |
{ | |
// next one, or we're in padding still.. | |
if( extlen == 0 ) | |
continue; | |
if( mime->extensioncount+1 >= MIMETYPE_EXT_MAX_COUNT ) | |
{ | |
// At our limit. | |
comment = true; | |
continue; | |
} | |
mime->extensioncount++; | |
extnum++; | |
mime->extensions[extnum] = (char *)malloc(MIMETYPE_EXT_MAX_LENGTH+1); | |
mime->extensions[extnum][0] = '\0'; | |
continue; | |
} | |
else if( extlen < MIMETYPE_EXT_MAX_LENGTH ) | |
{ | |
mime->extensions[extnum][extlen] = ch; | |
extlen++; | |
mime->extensions[extnum][extlen] = '\0'; | |
} | |
} | |
else | |
{ | |
int mlen = strlen( mime->mimetype ); | |
if( mlen >= sizeof(mime->mimetype) ) | |
{ | |
// At capacity! | |
comment = true; | |
continue; | |
} | |
else if( ch == ' ' || ch == '\t' ) | |
{ | |
onext = true; | |
int extnum = mime->extensioncount; | |
mime->extensions[extnum] = (char *)malloc(MIMETYPE_EXT_MAX_LENGTH+1); | |
mime->extensions[extnum][0] = '\0'; | |
mime->extensioncount++; | |
continue; | |
} | |
mime->mimetype[mlen] = ch; | |
mlen++; | |
mime->mimetype[mlen] = '\0'; | |
} | |
} | |
if( mime->mimetype[0] != '\0' ) | |
{ | |
mimes->next = mime; | |
mimes = mime; | |
} | |
else | |
free( mime ); | |
free( mimeraw ); | |
} | |
void free_mimetypes() | |
{ | |
struct s_mimetype *mnext; | |
for( struct s_mimetype *m=mimes; m; ) | |
{ | |
mnext = m->next; | |
for( int x=0; x < m->extensioncount; x++ ) | |
free( m->extensions[x] ); | |
free( m ); | |
m = mnext; | |
} | |
} | |
void spill_beans() | |
{ | |
for( struct s_mimetype *m=mimes; m; m=m->next ) | |
{ | |
printf("[%s] =>", m->mimetype); | |
for( int x=0; x < m->extensioncount; x++ ) | |
printf(" (%s)", m->extensions[x]); | |
printf("\n"); | |
} | |
} | |
int main(int argc, char **argv) | |
{ | |
read_mimetypes(); | |
spill_beans(); | |
free_mimetypes(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment