Compiling libmagic statically (c / C ++ file type definition)

Thanks to the guys who helped me with my previous question (related for reference only).

I can put the files fileTypeTest.cpp , libmagic.a and magic in a directory, and I can compile with g++ -lmagic fileTypeTest.cpp fileTypeTest . Later I will test whether it will work on Windows compiled with MinGW.

I plan to use libmagic in a small graphical application, and I would like to copy it for distribution. My problem is that libmagic requires an external magic file. (I actually use my shortened and compiled version of magic_short.mgc, but I'm distracted.)

The hacker solution should be to encode the file in the application, creating (and deleting) the external file as necessary. How can i avoid this?

added for clarity:

magic - a text file that describes the properties of different types of files. When asked to identify the file, libmagic searches through magic . There is a compiled version of magic.mgc that works faster. My application only needs to define several types of files before deciding what to do with them, so I will use my own magic_short file to create magic_short.mgc .

+3
c ++ compilation libmagic
source share
3 answers

It's complicated, I suppose you could do it like this ... By the way, I downloaded the libmagic source and looked at it ...

There is a function called magic_read_entries inside minifile.c (this is a pure source of vanilla, which I downloaded from sourceforge where it is read from an external file.

You can add the magic file (which is located in the / etc directory) to the end of the library code, for example cat magic >> libmagic.a . On my system, magic is 474443 bytes, libmagic.a is 38588 bytes.

In the magic.c file magic.c you will need to change the function magichandle_t* magic_init(unsigned flags) at the end of the function, add the line magic_read_entries and change the function itself to read the offset of the library itself, to pull it out, treat it as a pointer to a pointer to char (char ** ) and use this instead of reading from a file. Since you know where the bias of the library data is for reading, this should not be difficult.

Now the magic_read_entries function magic_read_entries no longer be used, since it will no longer be read from the file. The function `magichandle_t * magic_init (unsigned flags) 'will take care of loading the entries, and you should be fine.

If you need more help, let me know

Edit: I used the old libmagic from sourceforge.net, and here is what I did:

  • Extracting the downloaded archive into my home directory, ungzipping / untarring in the archive will create the libmagic folder.
  • Create a folder in libmagic and name it Test
  • Copy the original magic.c and minifile.c to Test
  • Using the supplied diff output, highlighting the difference, apply it to the source of magic.c.
 48a49.51
 > #define MAGIC_DATA_OFFSET 0x971C
 > #define MAGIC_STAT_LIB_NAME "libmagic.a"
 >
 125a129,130
 > / * magic_read_entries is obsolete ... * /
 > magic_read_entries (mh, MAGIC_STAT_LIB_NAME);
 251c256,262
 <
 ---
 >
 > if (! fseek (fp, MAGIC_DATA_OFFSET, SEEK_SET)) {
 > if (ftell (fp)! = MAGIC_DATA_OFFSET) return 0;
 >} else {
 > return 0;
 >}
 >
  • Then do make
  • The magic file (which I copied from / etc, in Slackware Linux 12.2) is merged with the libmagic.a file, i.e. cat magic >> libmagic.a . The SHA checksum for magic is (4abf536f2ada050ce945fbba796564342d6c9a61 magic), here is the exact data for magic (-rw-rr-- 1 root root 474443 2007-06-03 00: 52 / etc / file / magic) found on my system.
  • Here's the diff for the minifile.c source, apply it and rebuild the minifile executable by running make again.
 40c40
 <magic_read_entries (mh, "magic");
 ---
 > / * magic_read_entries (mh, "magic"); * /

Then it should work. If not, you will need to adjust the offset in the library for reading by changing MAGIC_DATA_OFFSET. If you want, I can commit the magic data file to pastebin. Let me know.

Hope this helps, Regards, Tom.

+5
source share

I can tell you how to compile the library statically - you just pass the path to the .a file at the end of your g ++ command .. A files are just archives of compiled objects (.o). Using "ldd fileTypeTest" will show you dynamically linked libraries - $ {libdir} /libmagic.so should not be in it.

As for linking in an external data file ... I don't know. Can you pack the application (.deb | .rpm | .tar.bz2)? On Windows, I would write an installer using NSIS.

+1
source share

In the past, I created self-extracting archives. Basically, this is a .exe file, consisting of a .zip archive and code to unpack it. download .exe, run it and poof! you can have as many files as you want.

http://en.wikipedia.org/wiki/Self-extracting_archive

0
source share

All Articles