Purpose

Creating a library to parse the samba config file under Linux. This tool should do all of the following :
  1. Open the samba config file, put it in memory, and close the file definitively. It works on memory only with double chained list, and many pointers.
  2. Switch or define a property value. This should be specified within a section, example: [printers].
  3. Delete a property from a specified section.
  4. Check for conflicts, or syntax error to be fixed. (not implemented yet)
  5. Print the whole list of properties to the user, from the memory. And save the list to a file. It should also preserve comments line from the original file.

More details

Load and parse.

Status: Implemented.

Set a property value.

Status: You can set or change a property value in any section, by providing it. When section is null, the result is not indetermined.

Delete a property.

Status: working when specifying the section from where the property should be removed. Same as Load and parse if section is null.

Check for errors.

Status: may be implemented in the future.
Don't know what to do with this, but I have some ideas.
A) It should scan for duplicate properties.
Example: If "guest ok" is present two times in the [global] section, the last should be keeped but the first be deleted.
B) If we found some property which is not a section "[text]" nor a "property = value" syntax, should inform the user and ask him if he want to delete it.

List and save.

Status: Implemented. By now it asks where you want to save the resulting file. In fact it should overwrite the existing file, probably after making a backup.

Code documentation

Structure

 struct ligne
 {
         char var[MAX_LENGTH_LINE];
         char value[MAX_LENGTH_VALUES];
         int is_section;
         struct ligne *suivant;
         struct ligne *precedent;
 };
Section is 0 when it represents a new [section], 1 is a property "name = Yes", and negative number is a comment.

Constant

 #define MAX_LENGTH_OPTION 50
 #define MAX_LENGTH_VALUES 80
 #define MAX_LENGTH_LINE 256
 

Functions

struct ligne * find_last(struct ligne **p_arg,char *section_where);

Find the last entry from a section in the config file.
*p_arg is the address to the First element in the double chained list. section_where is the char[] containing the name of the section; identified by [brackets]; from where it should return the last element.

struct ligne * search_var(struct ligne *list_arg, char *look_for, char *shouldbe_section);

Compare all var to the look_for char, and return a pointer, null if not found.
list_arg is the address to the First element in the double chained list.
look_for contains the string to be found.
shouldbe_section is the place where look_for should be.

void print_all(struct ligne *list_arg);

Show the entire list containing the whole smb.conf file in memory. Only not commented or null parts are displayed.
list_arg is the address to the First element in the double chained list.

int test_line_value(struct ligne *list_arg);

Parse line by line, and do what needs to be done. This mean only one operation, which should be done only if a property is detected. A property is a "name = value" syntax. If detected, this value is set to ligne->value and the ligne->var is overwrited with the only "name" part.
list_arg is the address to the element to be scanned in the double chained list.

struct ligne* goto_end(struct ligne *list_arg);

Scan the whole list and return the pointer from the last item.
list_arg is the address to the First element in the double chained list.

struct ligne* create_line(struct ligne **p_arg);

Create a new property in the list, at the *p_arg position. If the p_arg argument is NULL, create_line will create the first item.
*p_arg is the address to the element in the double chained list from where element->suivant should be created. In other words, the new element will be inserted after this one.

void file_open(struct ligne **p_arg);

Ask the user to enter the path and filename to find the samba configuration file, open it, create a new item with create_line() function, fill the item with a line readed from the file, call test_line_value() function and then close the file.
*p_arg is the address to the First element in the double chained list.

void liberate_memory(struct ligne **p_arg);

This function free all malloc done by create_line().
*p_arg is the address to the First element in the double chained list.

void set_value(struct ligne **p_arg,char *param,char *val_set,char *where_section);

set_value() will search for the param in the p_arg list, check if it is present in the where_section, and set his value to val_set if it is. If it's not, a new item should be added to the list. In the case of a new entry, one should consider multiple cases:
  • The section where_section exist, is present, and we need to get the pointer from the last entry in this section. Then should add a new item after this one, and let the new point to the next if it exists. In this case the last item from the section may be the section item itself. It doesn't matter at all.
  • Or maybe the section is not present. In this case, the file could be empty or not. If it is, easy, create new item. If it's not, then look if we need to add a [global] section. Because if the global section needs to be added, we couldn't add it to the end of the file, as if it was another section. The global section should preferably be added to the first entry. And then the new property should follow.

*p_arg is the address to the First element in the double chained list.
param is the char[] containing the property's name to be set.
val_set is the char[] containing the property's value.
where_section is the name of the section; between [brackets]; where you want to set the param to val_set.

struct ligne * move_last_to_first(struct ligne **p_arg);

This is used when the global section needs to be added. In a way, everything is added in the end of the chained list. Thus, on the bottom of the file. But the global section should be presented on the top. Then after adding the global section, move_last_to_first will move it to the top.
*p_arg is the address to the First element in the double chained list.

void delete_item(struct ligne **p_arg,char *param,char *where_section);

Will scan the full list to find the param property and then will delete it, only if it is defined in the where_section.
*p_arg is the address to the First element in the double chained list.
param is the property to be deleted.
where_section points the [section] from where it should be deleted.

int save_all(struct ligne *list_arg, char *save_to);

Will save the entire list, with comments line, to a newly created file or any existing one. Don't forget, it is run on root so it will overwrite anything you want.
*p_arg is the address to the First element in the double chained list.
save_to is the file full path where you want to save the config.
Returns 0 if the save was successfull.

void test_look(struct ligne **p_arg);

Dumb function to test the set_value() function.
*p_arg is the address to the First element in the double chained list.

Download

Source 20060621
Magic-Samba i386 binary

Wishes

Next step: create a GUI to configure samba as a PDC, a Workstation, a member server, etc.