After looking for a way to detect the filetype of a file stream, I found that the Unix file command uses libmagic and I'm trying to make use of the library myself, but I can't get it to work. I've rarely integrated 3rd party code in my own, so that's probably a big part of my problem as well.
Why:
I'm doing this because I have a portable gui image viewing app that will need to detect archive file types (rar, zip, more?) from given filename and then the image file types inside. I'm hoping that I can use libmagic for Windows and Linux (and Mac), so if this isn't the case, stop me now b/c I'll need to find something else.
Attempt:
I found somebody doing something similar, but I can't follow what they're doing, and I've no idea how compile/run anything at all to start messing around.
My first instinct was to do something like:
// fileTypeTest.cpp, placed in file-5.03/src/ (source from link above)
#include <stdio.h>
#include "magic.h"
int main() {
magic_t myt = magic_open(MAGIC_CONTINUE|MAGIC_ERROR/*|MAGIC_DEBUG*/|MAGIC_MIME);
magic_load(myt,NULL);
printf("magic output: '%s'\n",magic_file(myt,__FILE__));
magic_close(myt);
return 0;
}
then compile with something like:
$ gcc magic.c -o magic.o
$ g++ fileTypeTest.cpp -o fileTypeTest magic.o
which (obviously?) doesn't work. I don't even know where to start looking, what questions to ask, or if this is the right direction to go to solve my original problem in the first place.
Edit: Now I have
#include <stdio.h>
#include <magic.h>
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("bad arguments");
return 0;
}
magic_t myt = magic_open(MAGIC_CONTINUE|MAGIC_ERROR/*|MAGIC_DEBUG*/|MAGIC_MIME);
magic_load(myt,NULL);
printf("magic output: '%s'\n", magic_file(myt, argv[1]));
magic_close(myt);
return 0;
}
compiling with:
$ g++ -L/usr/lib -libmagic fileTypeTest.cpp -o fileTypeTest
works. I had to go to synaptic and install libmagic-dev though. I'll have to test to see if I can just copy /usr/lib/libmagic.a into my source directory when compiling my app on Windows's MingW, but that'll be for another question later, I suppose.
__FILE__
is a reserved pre-processing symbol macro used for debugging/logging purposes. Consider this as an example:
// This file is called test.c char *p = NULL; if (!(p = malloc((1 * sizeof(char) + 1)))){ printf("Error in file: %s @ line %d\n\tMalloc failed\n", __FILE__, __LINE__); exit(-1); }
If the call to malloc
failed you will see the output in the above example like this:
Error in file: test.c @ line 23 Malloc failed
Notice how the code picks up the original source code. The above example illustrates the usage of this.
I think your code should be something like this:
// fileTypeTest.cpp, placed in file-5.03/src/ (source from link above) #include <stdio.h> #include "magic.h" int main(int argc, char **argv) { if (argc > 1){ magic_t myt = magic_open(MAGIC_CONTINUE|MAGIC_ERROR/*|MAGIC_DEBUG*/|MAGIC_MIME); magic_load(myt,NULL); printf("magic output: '%s'\n",magic_file(myt,argv[1])); magic_close(myt); } return 0; }
The code above checks if there is a parameter that is passed into this program and the parameter would be a filename, i.e. argv[0]
points to the executable name (the compiled binary), argv[1]
points to the array of chars (a string) indicating the filename in question.
To compile it:
g++ -I/usr/include -L/usr/lib/libmagic.so fileTestType.cpp -o fileTestTypeg++ -L/usr/lib -lmagic fileTestType.cpp -o fileTestType
Edit: Thanks Alok for pointing out the error here...
If you are not sure where the libmagic reside, look for it in the /usr/local/lib, and /usr/local/include - this depends on your installation.
See this to find the predefined macros here.
Hope this helps, Best regards, Tom.