23 September 2000 - previous September updates: 02 06 10 12 15 17 19 21 23 ; previous updates
1 - RAR_BK Archiver Project in ANSI C (Part 2)
|
RAR_BK has not graphical interface (230900), but it will be easy to give it a Microsoft Windows look. Expect such modification, soon. Click on the picture, for its original version - in this case, you will see that WinRAR achieved a superb compression ratio! |
RAR_BK - RAR Archiver Project in ANSI C (part 2) One of the reasons that would make it fun to write the RAR_BK Archiver in C, was / is the parsing code. Parsing strings (the folder's names) in C would never be dead easy, because of C string's nature (a string is the address of the 1st of its chars...). My option was to trust in the string library and its strdup function to many affairs, then build some generic parsing code, obeying a notation that tries to prefix each identifier name with its type first char, hence my string returning functions being called s-something... For example: char *sfile_read_word (FILE *f) reads and returns the next word in a text file, ie the sequence of chars until the first separator char (there is a boolean function that states which ones are separator chars); char *sfile_read_until_char (FILE *f, char cchar_stop) that reads the next word in a text file, until a specified stop char (cchar_stop); However, because I tried to write the whole software in less than 400 lines (much less, if you cut the many comments that exist in the source code), I made an option for some system dependent functions... BUT WAIT... In this case, "system dependent" doesn't mean the code won't compile with any C compiler - it will! - it means, that function's behavior is expecting something that might not happen in all operating systems. Straight to the point, if you are to port the code to other environment, than Windows 2000, than you'll have to pay attention to the "sdir_name_from_sys_dir_string" function. READ WHAT FOLLOWS. char *sdir_name_from_sys_dir_string (char *sdir) this function is 100% dependent on the (text) format of a system DIR command. For example, in Windows 2000, when you DIR a folder, you get the directories in lines with a format like: ... 09/20/2000 01:05p <DIR> Creative 07/15/2000 12:01a <DIR> Documents and Settings ... Since what we want to do is GETTING THE FOLDERS' NAMES, what is relevant in each of the above files are the strings that happen after the "<DIR> 8-white-spaces" string ("Creative" and "Documents and Settings"). The "sdir_name_from_sys_dir_string" function is doing nothing more than parsing those lines and grabbing what matters. In LINUX and so many other operating systems, the DIR command (or its equivalent, eg LS), can deliver listings with different formats, and you'll have to understand those formats and write your own parsing algorithms to get that important stuff. Of course there were alternatives to getting the folders' names, but such alternatives weren't as portable, in the perspective of compilation, and because I was wanting to develop the software in just 3, 4 hours, I didn't dare learning some of them. The important thing to retain is: if you are porting the code, the sdir_name_from_sys_dir_string" function is probably the only one you'll eventually need to re-write. The provided .EXE and source files, will work, with no mods, in Win9x, Win ME and Windows 2000. In order to store the strings, an option was made for a simple dynamic list, built over the following data types: typedef struct _tp_node_lstr{ char *s; struct _tp_node_lstr *next; } tp_node_lstr; typedef tp_node_lstr *tp_lstr; /*list of strings*/ Then there are some insertion and removal code, very much commented on the source file. After having the list of strings that corresponds to the list of available folders, it was a matter of building a SYSTEM COMMAND to call a selected ARCHIVER. As mentioned in the previous related update, I made an option for WinRAR. And - again - because this was 4 hours (max) project, I opted for some symbolic constants to speed things up: #define PATH_ARCHIVER "t:\\archivers\\winrar\\winrar.exe" #define OPTIONS_ARCHIVER "a -r -m5 -sfx" #define OUTPUT_PATH "d:\\rar_archives" #define TMP_FILE "~~~1~~~.txt" ...these symbolic constants are self explanatory. If you opt for another archiver, replace its path and its options. If you want another temp file (for doing the DIR), change the value for TMP_FILE. You'll probably want to set your own output path. In the end, the program is just /*will hold list of folders from caller's position*/ tp_lstr list_of_dirs=NULL; /*get caller's working position (working directory) and store it in buffer*/ _getcwd (sbuffer, MAX_CHARS); /*build list_of_dirs, from buffer directory*/ list_of_dirs=get_list_of_dirs (_getdrive(),sbuffer); /*cut the drive letter from the buffer string ("C:\folder" to "\folder")*/ sabs_path=sabs_to_relative_string (sbuffer); /*remove . and .. folders (current and previous) from the list of folders to process*/ lstr_remove_header (&list_of_dirs);/*get rid of .*/ lstr_remove_header (&list_of_dirs);/*get rid of ..*/ /*list is formed and clean to act on! ACT!*/ ct_on_list_of_dirs (list_of_dirs, _getdrive(), sabs_path,1); /*job is done, free memory*/ lstr_destroy (&list_of_dirs); free(sabs_path); OK: download the C source code [26 KB PDF] download the executable [56 KB win32 EXE] You might be interested in WinRAR, of course :) These contents are also available from the Tutorial Section, as a C tutorial. |
Though with no graphical interface, RAR_BK is very verbose :). It lists all the system calls it will do to WinRAR (or other archiver you can specify, as a Macro). Click on the picture, for its original version - beware that some files might weight over 100 K. |