summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Lipovsky <janlipovsky@gmail.com>2010-02-23 20:27:05 +0100
committerJan Lipovsky <janlipovsky@gmail.com>2010-02-23 20:27:05 +0100
commitc6c9c8a731c7b2d521685e0f4f36e2cbb81b7876 (patch)
tree06736821679193aded9b565277e82b9b75f68d60
parent507ef00d1e80737221190e409d9e534091efe006 (diff)
downloadsfshare-c6c9c8a731c7b2d521685e0f4f36e2cbb81b7876.tar.gz
sfshare-c6c9c8a731c7b2d521685e0f4f36e2cbb81b7876.tar.xz
sfshare-c6c9c8a731c7b2d521685e0f4f36e2cbb81b7876.zip
Daemon functions, Create, Change and Delete share
-rw-r--r--sfshare-daemon/src/samba_share.c650
-rw-r--r--sfshare-daemon/src/samba_share.h67
-rw-r--r--sfshare-daemon/src/sfshared.c37
3 files changed, 754 insertions, 0 deletions
diff --git a/sfshare-daemon/src/samba_share.c b/sfshare-daemon/src/samba_share.c
new file mode 100644
index 0000000..873460a
--- /dev/null
+++ b/sfshare-daemon/src/samba_share.c
@@ -0,0 +1,650 @@
+#include <string.h> //strlen
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "samba_share.h"
+
+
+#define SECTIONS_COUNT 3 //Count of special sections in smb.conf
+#define KEYWORDS_COUNT 6 //Count of keywords used for setup share in smb.conf
+
+// [share name], "path =", "commennt =", "read only =", "writable =, writeable =, write ok =", "guest ok ="
+const gchar *keywords[KEYWORDS_COUNT] = {"[" ,"path", "comment", "read only", "writ", "guest"};
+
+typedef enum keywords_id
+{
+ SHARE_NAME_ID = 0,
+ PATH_ID,
+ COMMENT_ID,
+ READ_ONLY_ID,
+ WRTITABLE_ID,
+ GUEST_OK_ID
+} TKeywords_id;
+
+gchar *smb_conf_path = "/etc/samba/smb.conf";
+const gchar *smb_special_section[SECTIONS_COUNT] = {"global", "homes", "printers"};
+
+
+/*
+* Function changes path to smb.conf to path
+*/
+void ChangeSmbConfPath(const gchar *path)
+{
+ g_free(smb_conf_path);
+
+ smb_conf_path = g_strdup(path);
+}
+
+
+/*
+* Save string str as new smb.conf
+*/
+gint WriteSmbConf(const gchar *content)
+{
+ FILE *smb_file;
+
+ //smb.conf - File exist test
+ if(!g_file_test(smb_conf_path, G_FILE_TEST_EXISTS))
+ {
+ g_error("Config file \"%s\" does not exist!", smb_conf_path);
+ return 1;
+ }
+
+ //Try open smb.conf - rewrite all
+ smb_file = fopen(smb_conf_path, "w");
+ if(smb_file == NULL)
+ {
+ g_error("Can not open file \"%s\"! Maybe, you dont have rights for change smb.conf", smb_conf_path);
+ return 1;
+ }
+
+ //Write to smb.conf
+ if(fputs(content,smb_file) == EOF)
+ {
+ g_error("Can not write to file \"%s\"!", smb_conf_path);
+ return 1;
+ }
+
+ fclose(smb_file);
+
+ return 0;
+}
+
+
+
+/*
+* Function free TSmbConfItem from memmory
+*/
+void SmbConfItem_free(TSmbConfItem *item)
+{
+ g_string_free(item->guest_ok, TRUE);
+ g_string_free(item->writable, TRUE);
+ g_string_free(item->read_only, TRUE);
+ g_string_free(item->comment, TRUE);
+ g_string_free(item->path, TRUE);
+ g_string_free(item->name, TRUE);
+
+ g_free(item);
+}
+
+
+/*
+* Function allocs memory for TSmbConfItem
+*/
+TSmbConfItem* SmbConfItem_new0()
+{
+ TSmbConfItem *ret;
+ ret = g_malloc(sizeof(struct smb_conf_item));
+
+ ret->name = g_string_new("");
+ ret->path = g_string_new("");
+ ret->comment = g_string_new("");
+ ret->read_only = g_string_new("");
+ ret->writable = g_string_new("");
+ ret->guest_ok = g_string_new("");
+
+ return ret;
+}
+
+/*
+* Function allocs memory for TSmbConfItem
+*/
+TSmbConfItem* SmbConfItem_new(gchar *name, gchar *path, gchar *comment, gchar *read_only, gchar *writable, gchar *guest_ok)
+{
+ TSmbConfItem *ret;
+ ret = g_malloc(sizeof(struct smb_conf_item));
+
+ ret->name = g_string_new(name);
+ ret->path = g_string_new(path);
+ ret->comment = g_string_new(comment);
+ ret->read_only = g_string_new(read_only);
+ ret->writable = g_string_new(writable);
+ ret->guest_ok = g_string_new(guest_ok);
+
+ return ret;
+}
+
+/*
+* Function returns new array
+*/
+GPtrArray* SharedItemsArray_new()
+{
+ GPtrArray *ret = g_ptr_array_new();
+ return ret;
+}
+
+
+/*
+* Destroy array
+*/
+void SharedItemsArray_free(GPtrArray *array)
+{
+ TSmbConfItem *tmp;
+ for(int i = 0; i < array->len; i++)
+ {
+ tmp = g_ptr_array_index(array,i);
+ SmbConfItem_free(tmp);
+ }
+
+ g_ptr_array_free(array, TRUE);
+}
+
+
+/*
+* Parse line of smb.conf and fill competent field of item structure
+* return id of keyword found on line (txt)
+*/
+void ParseShareItem(gchar *txt, TSmbConfItem *item)
+{
+ gchar *lower = g_ascii_strdown(txt, strlen(txt));
+
+ //Find keywords on line *txt
+ gint i;
+ for(i = 0; i < KEYWORDS_COUNT; i++)
+ {
+ gchar *point;
+ if((point = g_strrstr(lower,keywords[i])) != NULL)
+ {
+ //Keywords must be at begining of line
+ if(point == lower)
+ break;
+ }
+ }
+
+ //Save atributes - Boolean variables case-insensitive - yes, no, true, false, 1, or 0
+ switch(i)
+ {
+ // [share name]
+ case SHARE_NAME_ID:
+ {
+ g_string_append_len(item->name, txt + 1, strlen(txt)-2);
+ }
+ break;
+
+ // path =
+ case PATH_ID:
+ {
+ gchar *tmp;
+ if((tmp = g_strrstr(txt,"=")) != NULL)
+ {
+ g_string_assign(item->path, g_strstrip(tmp + 1));
+ }
+ }
+ break;
+
+ // comment =
+ case COMMENT_ID:
+ {
+ gchar *tmp;
+ if((tmp = g_strrstr(txt,"=")) != NULL)
+ {
+ g_string_assign(item->comment, g_strstrip(tmp + 1));
+ }
+ }
+ break;
+
+ // read only =
+ case READ_ONLY_ID:
+ {
+ gchar *tmp;
+ if((tmp = g_strrstr(lower,"=")) != NULL)
+ {
+ g_strstrip(++tmp);
+
+ if(g_strcmp0(tmp, "yes") && g_strcmp0(tmp, "true") && g_strcmp0(tmp, "1"))
+ g_string_assign(item->read_only,"no");
+ else
+ g_string_assign(item->read_only,"yes");
+ }
+ }
+
+ // writ = writable, writeable, write ok =
+ case WRTITABLE_ID:
+ {
+ gchar *tmp;
+ if((tmp = g_strrstr(lower,"=")) != NULL)
+ {
+ g_strstrip(++tmp);
+
+ if(g_strcmp0(tmp, "yes") && g_strcmp0(tmp, "true") && g_strcmp0(tmp, "1"))
+ g_string_assign(item->read_only,"no");
+ else
+ g_string_assign(item->read_only,"yes");
+ }
+ }
+ break;
+
+ // guest ok =
+ case GUEST_OK_ID:
+ {
+ gchar *tmp;
+ if((tmp = g_strrstr(lower,"=")) != NULL)
+ {
+ g_strstrip(++tmp);
+
+ if(g_strcmp0(tmp, "yes") && g_strcmp0(tmp, "true") && g_strcmp0(tmp, "1"))
+ g_string_assign(item->guest_ok,"no");
+ else
+ g_string_assign(item->guest_ok,"yes");
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ g_free(lower);
+}
+
+
+
+/*
+* Funciton loads all share section to array
+*/
+gint LoadSmbConf(GPtrArray *shared_items)
+{
+
+ FILE *smb_file; //Samba config file
+ gchar *line; //Line buffer
+ gboolean skip = FALSE; //Skip lines of special sections
+
+ gint arr_index = shared_items->len - 1; //Count of items in shared_items array - 1;
+
+ //smb.conf - File exist test
+ if(!g_file_test(smb_conf_path, G_FILE_TEST_EXISTS))
+ {
+ g_error("Config file \"%s\" not exist!", smb_conf_path);
+ return 1;
+ }
+
+ //Try open smb.conf
+ smb_file = fopen(smb_conf_path, "r");
+ if(smb_file == NULL)
+ {
+ g_error("Can not open file \"%s\"!", smb_conf_path);
+ return 1;
+ }
+
+ //Inicialize buffers
+ line = g_strnfill(BUFSIZ, '\0');
+
+ //Parse smb.conf file and load shared folders setings
+ while(fgets(line, BUFSIZ, smb_file))
+ {
+ //Remove white space
+ g_strstrip(line);
+
+ //Skip comments and empty lines
+ if(line[0] == ';' || line[0] == '#' || line[0] == '\0')
+ continue;
+
+ if(line[0] == '[')
+ {
+ skip = FALSE;
+
+ //Test special sections
+ for(int i = 0; i < SECTIONS_COUNT; i++)
+ {
+ if(g_strrstr(line,smb_special_section[i]) != NULL)
+ {
+ skip = TRUE;
+ break;
+ }
+ }
+
+ if(!skip)
+ {
+ //Start of share section - alloc new item of array
+ TSmbConfItem *tmp_item = SmbConfItem_new0();
+
+ //Add item to array
+ g_ptr_array_add(shared_items, (gpointer) tmp_item);
+ arr_index++;
+
+ //Print error if pointers are different
+ if (g_ptr_array_index (shared_items, arr_index) != (gpointer) tmp_item)
+ g_error("LoadSmbConf(GPtrArray **shared_items): got %p instead of %p\n",
+ g_ptr_array_index(shared_items, arr_index), tmp_item);
+ }
+ }
+
+ //Skip special sections (global, homes, printers)
+ if(skip)
+ continue;
+
+ TSmbConfItem *tmp = g_ptr_array_index(shared_items, arr_index);
+
+ //Recognize parameters and fill in item
+ ParseShareItem(line, tmp);
+
+ //g_print("%s\n", line);
+
+ }
+
+ //Free
+ g_free(line);
+
+ //SmbConfItem_free(&tmp_item);
+ fclose(smb_file);
+
+ return 0;
+}
+
+
+/*
+* Returns share imte if directory [path] is shared,
+* if not return NULL;
+*/
+TSmbConfItem *IsShared(GPtrArray *shared_items, const gchar *path)
+{
+ TSmbConfItem *ret = NULL;
+ TSmbConfItem *tmp;
+ for(int i = 0; i < shared_items->len; i++)
+ {
+ tmp = g_ptr_array_index(shared_items,i);
+ if(g_strrstr(tmp->path->str,path))
+ {
+ ret = tmp;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+/*
+* Write ne share section or change chare section defined by share parameter
+*/
+gint WriteShare(GPtrArray *shared_items, TSmbConfItem *share)
+{
+
+ TSmbConfItem *item; //Shared item
+ FILE *smb_file; //Samba config file
+ GString *smb_conf_new; //Content of smb.conf
+ gchar *line; //Line buffer
+ gchar *tmp; //Temp
+
+ gboolean new_share = FALSE;
+ gboolean change = FALSE;
+
+
+ item = IsShared(shared_items, share->path->str);
+
+ //If item is not shared we just append it to end of smb.conf
+ if(!item)
+ new_share = TRUE;
+
+
+ //smb.conf - File exist test
+ if(!g_file_test(smb_conf_path, G_FILE_TEST_EXISTS))
+ {
+ g_error("Config file \"%s\" does not exist!", smb_conf_path);
+ return 1;
+ }
+
+ //Try open smb.conf - rewrite all
+ smb_file = fopen(smb_conf_path, "r");
+ if(smb_file == NULL)
+ {
+ g_error("Can not open file \"%s\"!", smb_conf_path);
+ return 1;
+ }
+
+ //Inicialize buffers
+ smb_conf_new = g_string_new("");
+ line = g_strnfill(BUFSIZ, '\0');
+ tmp = g_strnfill(BUFSIZ, '\0');
+
+
+ //Load smb.conf, change or add share section share
+ while(fgets(line, BUFSIZ, smb_file))
+ {
+ gchar *orig = g_strdup(line);
+
+ //Remove white space
+ g_strstrip(line);
+
+ if(!new_share) //Find section to change
+ if(line[0] == '[')
+ {
+ change = FALSE;
+
+ //Is this section to change?
+ if(g_strrstr(line,item->name->str))
+ {
+ change = TRUE;
+ }
+ }
+
+ if(!change || new_share)
+ {
+ //Just copy text from smb.conf
+ g_string_append(smb_conf_new,orig);
+ }
+ else
+ {
+ //Change this line
+
+ gchar *lower = g_ascii_strdown(line, strlen(line)); //lower line
+
+ //Find keywords on line *txt
+ gint i;
+ for(i = 0; i < KEYWORDS_COUNT; i++)
+ {
+ gchar *point;
+ if((point = g_strrstr(lower,keywords[i])) != NULL)
+ {
+ //Keywords must be at begining of line
+ if(point == lower)
+ break;
+ }
+ }
+
+ //Change atributes - Boolean variables case-insensitive - yes, no, true, false, 1, or 0
+ switch(i)
+ {
+ // [share name]
+ case SHARE_NAME_ID:
+ {
+ g_sprintf(tmp,"[%s]\n",share->name->str);
+ g_string_append(smb_conf_new,tmp);
+ }
+ break;
+
+
+ // path =
+ case PATH_ID:
+ {
+ //no change
+ }
+ break;
+
+
+ // comment =
+ case COMMENT_ID:
+ {
+ g_sprintf(tmp,"\tcomment = %s\n",share->comment->str);
+ g_string_append(smb_conf_new,tmp);
+ }
+ break;
+
+
+ // read only =
+ case READ_ONLY_ID:
+ {
+ g_sprintf(tmp,"\tread only = %s\n",share->read_only->str);
+ g_string_append(smb_conf_new,tmp);
+ }
+
+
+ // writ = writable, writeable, write ok =
+ case WRTITABLE_ID:
+ {
+ g_sprintf(tmp,"\twritable = %s\n",share->writable->str);
+ g_string_append(smb_conf_new,tmp);
+ }
+ break;
+
+
+ // guest ok =
+ case GUEST_OK_ID:
+ {
+ g_sprintf(tmp,"\tguest ok = %s\n",share->guest_ok->str);
+ g_string_append(smb_conf_new,tmp);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ g_free(lower);
+ }
+
+ g_free(orig);
+ }
+
+
+ if(new_share)
+ {
+ g_sprintf(tmp,"\n[%s]\n",share->name->str);
+ g_string_append(smb_conf_new,tmp);
+
+ g_sprintf(tmp,"\tpath = %s\n",share->path->str);
+ g_string_append(smb_conf_new,tmp);
+
+ g_sprintf(tmp,"\tcomment = %s\n",share->comment->str);
+ g_string_append(smb_conf_new,tmp);
+
+ g_sprintf(tmp,"\tread only = %s\n",share->read_only->str);
+ g_string_append(smb_conf_new,tmp);
+
+ g_sprintf(tmp,"\twritable = %s\n",share->writable->str);
+ g_string_append(smb_conf_new,tmp);
+
+ g_sprintf(tmp,"\tguest ok = %s\n",share->guest_ok->str);
+ g_string_append(smb_conf_new,tmp);
+
+ }
+
+ //Write deleted share to smb.conf
+ WriteSmbConf(smb_conf_new->str);
+
+ fclose(smb_file);
+
+ g_free(line);
+ g_free(tmp);
+
+ g_string_free(smb_conf_new,TRUE);
+
+ return 0;
+}
+
+
+
+/*
+* Function erase shared section containing path from smb.conf
+* shared_items must by actual!
+*/
+gint DeleteShare(GPtrArray *shared_items, const gchar *path)
+{
+ FILE *smb_file; //Samba config file
+ GString *smb_conf_new; //Content of smb.conf
+ gchar *line; //Line buffer
+ gchar *orig; //Original line
+ TSmbConfItem *skip_item; //Skip this share
+ gboolean skip = FALSE; //Skip lines (erase from config)
+
+ skip_item = IsShared(shared_items, path);
+
+ if(!skip_item)
+ {
+ g_warning("Directory \"%s\" is NOT shared",path);
+ return -1;
+ }
+
+
+ //smb.conf - File exist test
+ if(!g_file_test(smb_conf_path, G_FILE_TEST_EXISTS))
+ {
+ g_error("Config file \"%s\" does not exist!", smb_conf_path);
+ return -1;
+ }
+
+ //Try open smb.conf - rewrite all
+ smb_file = fopen(smb_conf_path, "r");
+ if(smb_file == NULL)
+ {
+ g_error("Can not open file \"%s\"!", smb_conf_path);
+ return -1;
+ }
+
+ //Inicialize buffers
+ smb_conf_new = g_string_new("");
+ line = g_strnfill(BUFSIZ, '\0');
+ orig = g_strnfill(BUFSIZ, '\0');
+
+
+ //Load smb.conf WITHOUT section skip_name (section containing path)
+ while(fgets(line, BUFSIZ, smb_file))
+ {
+ g_stpcpy(orig, line);
+
+ //Remove white space
+ g_strstrip(line);
+
+ if(line[0] == '[')
+ {
+ skip = FALSE;
+
+ //Test special sections
+ if(g_strrstr(line,skip_item->name->str))
+ {
+ skip = TRUE;
+ }
+ }
+
+ if(!skip)
+ {
+ g_string_append(smb_conf_new,orig);
+ }
+ }
+
+ //Write deleted share to smb.conf
+ WriteSmbConf(smb_conf_new->str);
+
+ fclose(smb_file);
+
+ g_free(line);
+ g_free(orig);
+
+ g_string_free(smb_conf_new,TRUE);
+
+ return 0;
+}
+
+
+
diff --git a/sfshare-daemon/src/samba_share.h b/sfshare-daemon/src/samba_share.h
new file mode 100644
index 0000000..2100565
--- /dev/null
+++ b/sfshare-daemon/src/samba_share.h
@@ -0,0 +1,67 @@
+#ifndef SAMBA_SHARE_H
+#define SAMBA_SHARE_H
+
+#include <glib.h>
+
+/*
+config path
+load config
+parse config
+write share
+delete share
+reload service
+*/
+
+
+//
+// int WriteShare();
+//
+// int DeleteShare();
+//
+// void ReloadService();
+//
+//
+// std::string LoadConfig();
+// std::string ParseConfig();
+//
+// std::string smb_conf_path;
+// std::string smb_conf;
+
+typedef struct smb_conf_item
+{
+ GString *name; // [share name]
+ GString *path; // path = /path/to/folder
+ GString *comment; // comment = Some text comment
+ GString *read_only; // read only = yes | no
+ GString *writable; // writable = yes | no ... writeable, write ok
+ GString *guest_ok; // guest ok = yes | no
+} TSmbConfItem;
+
+
+//Funciton loads all share section to array
+gint LoadSmbConf(GPtrArray *shared_items);
+
+//Function erase shared section containing path from smb.conf
+gint DeleteShare(GPtrArray *shared_items, const gchar *path);
+
+
+gint WriteShare(GPtrArray *shared_items, TSmbConfItem *share);
+
+
+//Function changes path to smb.conf to path
+void ChangeSmbConfPath(const gchar *path);
+
+
+//Function returns new array
+GPtrArray* SharedItemsArray_new();
+
+//Function destroy Share Items Array
+void SharedItemsArray_free(GPtrArray *array);
+
+
+TSmbConfItem* SmbConfItem_new(gchar *name, gchar *path, gchar *comment, gchar *read_only, gchar *writable, gchar *guest_ok);
+TSmbConfItem* SmbConfItem_new0();
+
+
+void SmbConfItem_free(TSmbConfItem *item);
+#endif
diff --git a/sfshare-daemon/src/sfshared.c b/sfshare-daemon/src/sfshared.c
new file mode 100644
index 0000000..9a0cdc1
--- /dev/null
+++ b/sfshare-daemon/src/sfshared.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "samba_share.h"
+
+int main()
+{
+ GPtrArray *shared_items = SharedItemsArray_new();
+ LoadSmbConf(shared_items);
+
+ DeleteShare(shared_items,"/test");
+
+ TSmbConfItem *test;
+ for(int i = 0; i < shared_items->len; i++)
+ {
+ test = g_ptr_array_index(shared_items, i);
+ g_print("%s\n", test->path->str);
+
+ }
+ SharedItemsArray_free(shared_items);
+
+
+ shared_items = SharedItemsArray_new();
+ LoadSmbConf(shared_items);
+
+ test = SmbConfItem_new("testik", "/test", "Commentar", "no", "yes", "yes");
+
+ WriteShare(shared_items, test);
+
+ SmbConfItem_free(test);
+
+ SharedItemsArray_free(shared_items);
+
+ return 0;
+}