/* dblinkfs: stores some file's attributes of whole file system (like inodes, file names, file sizes, etc.) in small database.
* Copyright (C) 2012 by alexus (alexus.o.1982@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
//sudo blkid -o list -c /dev/null
//df | grep /dev/sda1 from cat /proc/partitions
//ls -l /dev/disk/by-uuid/
//sudo blkid
//+Add user fs_user with password to mysql database;
//+device label - karakuli;
//+in add_devices_and_partitions_to_db: event - if partition exists in db, but various label, uuid, fstype;
//+where device=XXX in check_times("SELECT file_name FROM file_table WHERE d_name=%s").
//+glob_str use only in two strokes. In functions use local ch_temp.
//+Add in bIsDatabaseInTheSystemExists tables exists.
//LIMITATIONS:
// 1)Max length of file_path=_POSIX_PATH_MAX(256) and 512 in db;
// 2)В б.д. сохраняются пути относительно корня устройства (не моунт поинт).
//DEPENDENCIES: blkid, glib, libblkid-dev (package),
/*
* Compile with:
* gcc -o dblinkfs dblinkfs.c -L/usr/lib/mysql -lmysqlclient `pkg-config blkid --cflags --libs gtk+-2.0` && sudo ./dblinkfs
*
*/
// #include
//#include
#include
#include
#include
#include
#include
#include //file read
// #include
// #include
//#include
//#include
#include
#include //Glist
#include
#include
// const gchar *list_item_data_key="list_item_data";
//
// /* Command-line args */
// //#define GETTEXT_PACKAGE "help"
// static char* directory=NULL;
// static gint expand_level = 1;
// static gboolean b_dirs_selected = FALSE;
// static gboolean b_quite = FALSE;
//
//
//
// static GOptionEntry entries[] =
// {
// {"dir", 'd', 0, G_OPTION_ARG_FILENAME, &directory, "Top level directory D.", "D"},
// {"expand level", 'e', 0, G_OPTION_ARG_INT, &expand_level, "Directory expanding level N.", "[0..N]"},
// {"ns", 0, 0, G_OPTION_ARG_NONE, &b_dirs_selected, "Don't select dirs on start.", NULL},
// {"quite", 'q', 0, G_OPTION_ARG_NONE, &b_quite, "Don't show any #Warnings.", NULL},
// {NULL}
// };
/* END OF Command-line args */
/*void bt_clicked( GtkWidget *widget, GtkTreeView *treeview)
{
// GtkTreeModel *model;
// GtkTreeIter iter;
// char *path;
//
// model=gtk_tree_view_get_model(treeview);
// print_iters(model, &iter, TRUE);
// gtk_main_quit();
}*/
///////////////////////////////////END SLOTS////////////////////////////////////////
// enum DBLINKFS_STATE = {
// ThingMask = 0x0000,
// READY = 1 << 0,
// CREATING_DB = 1 << 1,
// ACTUALIZING_LOCAL_DB = 1 << 2,
// ACTUALIZING_DEVICE_DB = 1 << 3,
// SEARCHING = 1 << 4,
// CHANGING_UPLEVEL_DIR_SIZES = 1 << 5,
// ERROR = 1 << 6,
// }
//thingstate |= READY;
//thingstate &= ~CREATING_DB;
//if (thing | ThingError) {...}
enum DBLINKFS_STATE {READY=1, CREATING_DB=2, ACTUALIZING_LOCAL_DB=4, ACTUALIZING_DEVICE_DB=8, SEARCHING=16,
CHANGING_UPLEVEL_DIR_SIZES=32, ERROR=64, CALCULATING_MD5SUM=128, CALCULATING_SHASUM=256} stata;
typedef struct device_struct{
char ch_device_name[25];
} DEVICE_STRUCT;
typedef struct partition_struct{
char ch_partition_name[512];
char ch_uuid[37];
char ch_label[32];
char ch_fs_type[8];
} PARTITION_STRUCT;
int i_dbl_state=READY;
//c.ClientState = (ClientStates.HasDiscount|ClientStates.IsSupplier|ClientStates.IsOverdr);
GtkWidget *main_menu;
static char glob_str[1028], glob_str2[300], glob_str3[300];
//DBLINKFS_STATE glob_state;
// !!!LOCAL FS рассматривается как принадлежащая device!!!
MYSQL *connect_to_db(char *host, char *user, char *passwd); //COMPLETED
int bIsDatabaseInTheSystemExists(MYSQL *conn); //COMPLETED
int bIsDatabaseFileInTheDeviceExists(MYSQL *conn, char *path_to_device);
void get_list_of_devices_in_the_system(char **ch_dev_list);
void device_has_just_been_mounted(MYSQL *conn, char *path_to_device);
void device_has_just_been_unmounted(MYSQL *conn, char *path_to_device);
int i_check_times_for_files_in_the_root_dir_of_the_partition(MYSQL *conn, char *path_to_device);
void actualize_db_for_device(MYSQL *conn, char *path_to_device); //Includes creating db for device from zero.
void actualize_db_for_devices_and_partitions(MYSQL *conn); //Includes creating db for device from zero.
void actualize_file_db_for_devices_and_partitions(MYSQL *conn);
void create_file_db_of_partition_from_zero(MYSQL *conn, char *ch_partition);
void get_paths_for_mounted_devices();
void fs_changed_slot(MYSQL *conn);
void change_uplevel_dir_sizes_recursivelly(MYSQL *conn);
void search(MYSQL *conn);
void backup_db_to_device(MYSQL *conn, char *path_to_device);
void delete_db_structure(MYSQL *conn);
void create_db_structure(MYSQL *conn);
int is_db_structure_exists(MYSQL *conn);
void add_devices_and_partitions_to_db(MYSQL *conn);
//Additional functions
int sql_query(MYSQL *conn, char *ch_query, char *ch_error_msg);
void del_leading_spaces(char *s);
char *ch_get_device_uuid(char *ch_device_partition); //ssize_t readlink(const char *restrict path, char *restrict buf,size_t bufsize);
char *ch_get_device_label(char *ch_device_partition);
char *ch_get_device_fstype(char *ch_device_partition);
int is_equal_time(time_t t1, char *t2);
int i_get_device_id_from_db(MYSQL *conn, char *path_to_device);
int i_get_partition_id_from_db(MYSQL *conn, char *ch_partition);
char *ch_get_st_mode(mode_t st_mode);
char *ch_convert_time_to_char(time_t time);
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
void del_leading_spaces(char *s)
{
gint i=0, j=0, k=0, i_length;
i_length=strlen(s);
k=i_length-1;
while(isspace(s[k])) {
k--; j++;
if(k==0) {break;}
}
while(isspace(s[i])) {
i++;
if(i==i_length-1) {break;}
}
k=j;
//g_print("i=%d, k=%d, i_length=%d\n", i, k, i_length);
for(j=0;j0) || (k>0)) s[i_length-i-k]='\0';
else s[i_length-i-k-1]='\0';
}
//-----------------------------------------------------------------------------------------------------
char *ch_get_device_uuid(char *ch_device_partition)
{
blkid_probe pr;
const char *ch_uuid;
char *ch_ret=NULL;
memset(glob_str2, '\0', sizeof(glob_str2) );
if(strstr(ch_device_partition, "/")==NULL) {
strcpy(glob_str2, "/dev/");
strcat(glob_str2, ch_device_partition);
}
else {
strcpy(glob_str2, ch_device_partition);
}
pr = blkid_new_probe_from_filename(glob_str2);
if (!pr) {
err(2, "Failed to open %s", glob_str2);
return "";
}
blkid_do_probe(pr);
blkid_probe_lookup_value(pr, "UUID", &ch_uuid, NULL);
ch_ret=malloc(strlen(ch_uuid)*sizeof(char));
memset(ch_ret, '\0', strlen(ch_uuid)*sizeof(char));
strcpy(ch_ret, ch_uuid);
blkid_free_probe(pr);
return ch_ret;
}
//-----------------------------------------------------------------------------------------------------
char *ch_get_device_label(char *ch_device_partition)
{
blkid_probe pr;
const char *ch_label;
char *ch_ret=NULL;
memset(glob_str2, '\0', sizeof(glob_str2) );
if(strstr(ch_device_partition, "/")==NULL) {
strcpy(glob_str2, "/dev/");
strcat(glob_str2, ch_device_partition);
}
else {
strcpy(glob_str2, ch_device_partition);
}
pr = blkid_new_probe_from_filename(glob_str2);
if (!pr) {
err(2, "Failed to open %s", glob_str2);
return "";
}
blkid_do_probe(pr);
blkid_probe_lookup_value(pr, "LABEL", &ch_label, NULL);
ch_ret=malloc(strlen(ch_label)*sizeof(char));
memset(ch_ret, '\0', strlen(ch_label)*sizeof(char));
strcpy(ch_ret, ch_label);
blkid_free_probe(pr);
return ch_ret;
}
//-----------------------------------------------------------------------------------------------------
char *ch_get_device_fstype(char *ch_device_partition)
{
blkid_probe pr;
const char *ch_fstype;
char *ch_ret=NULL;
memset(glob_str2, '\0', sizeof(glob_str2) );
if(strstr(ch_device_partition, "/")==NULL) {
strcpy(glob_str2, "/dev/");
strcat(glob_str2, ch_device_partition);
}
else {
strcpy(glob_str2, ch_device_partition);
}
pr = blkid_new_probe_from_filename(glob_str2);
if (!pr) {
err(2, "Failed to open %s", glob_str2);
return "";
}
blkid_do_probe(pr);
blkid_probe_lookup_value(pr, "TYPE", &ch_fstype, NULL);
ch_ret=malloc(strlen(ch_fstype)*sizeof(char));
memset(ch_ret, '\0', strlen(ch_fstype)*sizeof(char));
strcpy(ch_ret, ch_fstype);
blkid_free_probe(pr);
return ch_ret;
}
//-----------------------------------------------------------------------------------------------------
int sql_query(MYSQL *conn, char *ch_query, char *ch_error_msg)
{
if (!mysql_query(conn, ch_query)) {
return 1;
}
printf("%s. Query: %s. %u: %s\n", ch_error_msg, ch_query, mysql_errno(conn), mysql_error(conn));
return 0;
}
//-----------------------------------------------------------------------------------------------------
int is_equal_time(time_t t1, char *t2)
{
char ch_time[19];
struct tm* clock;
clock = gmtime(&(t1));
sprintf(ch_time, " %04d-%02d-%02d %02d:%02d:%02d", 1900+clock->tm_year, clock->tm_mon, clock->tm_mday, clock->tm_hour, clock->tm_min, clock->tm_sec);
if(strcmp(ch_time, t2)!=0) return 0;
return 1;
}
//-----------------------------------------------------------------------------------------------------
int i_get_device_id_from_db(MYSQL *conn, char *path_to_device)
{
MYSQL_RES *result;
MYSQL_ROW row;
memset(glob_str2, '\0', sizeof(glob_str2) );
if(strstr(path_to_device, "/")==NULL) {
strcpy(glob_str2, "/dev/");
strcat(glob_str2, path_to_device);
}
else {
strcpy(glob_str2, path_to_device);
}
sprintf(glob_str, "select i_device_id from device_table where device_name='%s'", glob_str2);
if(sql_query(conn, glob_str, "Error")) {
result = mysql_store_result(conn);
if(result!=NULL) {
row=mysql_fetch_row(result);
return atoi(row[0]);
}
}
return 0;
}
//-----------------------------------------------------------------------------------------------------
int i_get_partition_id_from_db(MYSQL *conn, char *ch_partition)
{
MYSQL_RES *result;
MYSQL_ROW row;
char *ch_temp=NULL, *ch_temp2=NULL;
int i=0;
ch_temp=malloc((70)*sizeof(char));
if(!ch_temp) printf("Error! Not enough memory!");
memset(ch_temp, '\0', sizeof(70) );
ch_temp2=malloc((140)*sizeof(char));
if(!ch_temp2) printf("Error! Not enough memory!");
memset(ch_temp2, '\0', sizeof(140) );
//printf("ch_partition=%s, strlen(ch_partition)=%d\n", ch_partition, strlen(ch_partition));
if(strstr(ch_partition, "/dev/")!=NULL) {
for(i=0;i<(strlen(ch_partition)-4);i++) {
ch_temp[i]=ch_partition[i+5];
}
}
else {
strcpy(ch_temp, ch_partition);
}
//printf("ch_temp=%s, strlen(ch_temp)=%d\n", ch_temp, strlen(ch_temp));
sprintf(ch_temp2, "select i_partition_id from device_partitions_table where partition_name='%s'", ch_temp);
free(ch_temp); ch_temp=NULL;
//printf("ch_temp2=%s\n", ch_temp2);
if(sql_query(conn, ch_temp2, "Error")) {
result = mysql_store_result(conn);
if(result!=NULL) {
row=mysql_fetch_row(result);
free(ch_temp2); ch_temp2=NULL;
return atoi(row[0]);
}
}
free(ch_temp2); ch_temp2=NULL;
return 0;
}
//-----------------------------------------------------------------------------------------------------
char *ch_get_st_mode(mode_t st_mode)
{
switch (st_mode & S_IFMT) {
case S_IFBLK: return "S_IFBLK"; break;
case S_IFCHR: return "S_IFCH"; break;
case S_IFDIR: return "S_IFDIR"; break;
case S_IFIFO: return "S_IFIFO"; break;
case S_IFLNK: return "S_IFLNK"; break;
case S_IFREG: return "S_IFREG"; break;
case S_IFSOCK: return "S_IFSOCK"; break;
default: return ""; break;
}
return "";
}
//-----------------------------------------------------------------------------------------------------
char *ch_convert_time_to_char(time_t time)
{
static char ch_time[19];
struct tm* clock;
clock = gmtime(&(time));
sprintf(ch_time, "%04d-%02d-%02d %02d:%02d:%02d", 1900+clock->tm_year, clock->tm_mon, clock->tm_mday, clock->tm_hour, clock->tm_min, clock->tm_sec);
return ch_time;
}
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
int i_check_times_for_files_in_the_root_dir_of_the_partition(MYSQL *conn, char *path_to_device)
{
//!!!strcpy to glob_str2 mount_point
// struct mntent
// {
// char * mnt_fsname; /* The name of this file system */
// char * mnt_dir; /* The root directory of this file system */
// char * mnt_type; /* Filesystem type */
// char * mnt_opts; /* Options, see below */
// int mnt_freq; /* -1 */
// int mnt_passno; /* -1 */
// long mnt_time; /* -1 */
// };
char *ch_temp=NULL, *ch_mount_point=NULL;
int i_count_of_db_files=0, i_count_of_the_root_partition_files=0, i_exist=0;
ch_temp=malloc((30)*sizeof(char));
memset( ch_temp, '\0', 30);
ch_mount_point=malloc((_POSIX_PATH_MAX + 1)*sizeof(char));
memset( ch_mount_point, '\0', _POSIX_PATH_MAX + 1);
//path_to_device like "/mount_point/sdaX" or simple "sdaX"
if(strstr(path_to_device, "/")==NULL) {
strcpy(ch_temp, "/dev/");
strcat(ch_temp, path_to_device);
}
else {
strcpy(ch_temp, path_to_device);
}
struct mntent *m;
FILE *f;
f = setmntent("/etc/mtab", "r");
while ((m = getmntent(f))) {
//printf("Drive %s, name %s\n", (*m).mnt_dir, (*m).mnt_fsname);
if(strcmp(ch_temp, (*m).mnt_fsname)==0) {
strcpy(ch_mount_point, (*m).mnt_dir);
break;
}
}
endmntent(f);
//strcat(ch_mount_point, "/");
size_t path_len;
DIR *dir=NULL, *dir2;
struct dirent *entry;
struct stat attribut;
struct tm* clock;
int i_result=0;
MYSQL_RES *result;
MYSQL_ROW row;
printf("ch_mount_point=%s\n", ch_mount_point);
dir = opendir(ch_mount_point);
if (dir == NULL) {
g_print ("#Error! Cannont open dir: %s \n", ch_mount_point);
return;
}
memset( glob_str, '\0', sizeof(glob_str) );
//printf("i_get_partition_id_from_db(conn, ch_temp)=%d, ch_temp=%s\n", i_get_partition_id_from_db(conn, ch_temp), ch_temp);
sprintf(glob_str, "SELECT d_name, st_size, st_atime, st_mtime, st_ctime FROM file_table WHERE "
"i_partition_id=%d AND (SELECT LENGTH(d_name)-LENGTH(REPLACE(d_name, '/', '')))=1", i_get_partition_id_from_db(conn, ch_temp));
if(sql_query(conn, glob_str, "Error")) {
result = mysql_store_result(conn);
}
while((entry = readdir(dir)) != NULL ) {
if( (!(((*entry).d_name[strlen((*entry).d_name)-2]=='/') || ((*entry).d_name[strlen((*entry).d_name)-1]=='.'))) && strstr(entry->d_name, ".wh.")==NULL) {
memset( glob_str, '\0', sizeof(glob_str) );
sprintf(glob_str, "%s/%s", ch_mount_point, (*entry).d_name);
if(stat(glob_str, &attribut) == 0) {
i_count_of_the_root_partition_files++;
clock = gmtime(&(attribut.st_ctime));
//printf("(*entry).d_name=%s\n", (*entry).d_name);
i_exist=0;
while((row=mysql_fetch_row(result))) {
//field = mysql_fetch_field(result);
//printf("(*entry).d_name=%s, row[0]=%s, row[1]=%s, row[2]=%s\n", (*entry).d_name, row[0], row[1], row[2]);
// printf("ch_convert_time_to_char(attribut.st_atime)=%s\n", ch_convert_time_to_char(attribut.st_atime));
if((strcmp(row[0]+1, (*entry).d_name)==0) && (attribut.st_size==atoi(row[1])) &&
(strcmp(ch_convert_time_to_char(attribut.st_atime), row[2])==0) ){//&&
//(strcmp(ch_convert_time_to_char(attribut.st_mtime), row[3])==0) ){//&&
//(strcmp(ch_convert_time_to_char(attribut.st_ctime), row[4])==0)) { //+1 because in (*entry).d_name absent first "/"
i_exist=1;
printf("(*entry).d_name=%s, row[0]=%s, row[1]=%s, row[3]=%s\n", (*entry).d_name, row[0], row[1], row[3]);
printf("ch_convert_time_to_char(attribut.st_mtime)=%s\n", ch_convert_time_to_char(attribut.st_mtime));
printf("ch_convert_time_to_char(attribut.st_ctime)=%s\n", ch_convert_time_to_char(attribut.st_ctime));
break;
}
}
mysql_data_seek(result, 0);
if(i_exist==0) {
i_result=0;
break;
}
}
}
}
mysql_free_result(result);
closedir( dir );
free(ch_temp); ch_temp=NULL;
free(ch_mount_point); ch_mount_point=NULL;
//!!! Check count of files in db and on the partition.
return i_result;
}
//-----------------------------------------------------------------------------------------------------
MYSQL *connect_to_db(char *host, char *user, char *passwd) //COMPLETED
{
MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
return NULL;
}
if (mysql_real_connect(conn, host, user,
passwd, NULL, 0, NULL, 0) == NULL) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
return NULL;
}
return conn;
}
//-----------------------------------------------------------------------------------------------------
int bIsDatabaseInTheSystemExists(MYSQL *conn) //COMPLETED
{
MYSQL_RES *result;
MYSQL_ROW row;
int i_result=0;
if (mysql_query(conn, "SHOW DATABASES")) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
return 0;
}
result = mysql_store_result(conn);
while ((row = mysql_fetch_row(result)))
{
if(strcmp(row[0], "dblinkfs")==0) {
i_result=1;
break;
}
}
mysql_free_result(result);
if(i_result==0) return 0;
if (mysql_query(conn, "use dblinkfs")) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
return;
}
if (!sql_query(conn, "show tables", "Error")) {return;}
result = mysql_store_result(conn);
if(result!=NULL) {
while ((row = mysql_fetch_row(result)))
{
if (strcmp(row[0], "version_table")==0) {
continue;
}
else if (strcmp(row[0], "device_table")==0) {
continue;
}
else if (strcmp(row[0], "device_partitions_table")==0) {
continue;
}
else if (strcmp(row[0], "file_table")==0) {
continue;
}
else if (strcmp(row[0], "file_metadata_table")==0) {
continue;
}
else {
mysql_free_result(result);
return 0;
}
}
mysql_free_result(result);
}
return 1;
}
//-----------------------------------------------------------------------------------------------------
int bIsDatabaseInTheDeviceExists(MYSQL *conn)
{
}
//-----------------------------------------------------------------------------------------------------
void device_has_just_been_mounted(MYSQL *conn, char *path_to_device)
{
//check uuid and files in the root. checktimes();
}
//-----------------------------------------------------------------------------------------------------
void device_has_just_been_unmounted(MYSQL *conn, char *path_to_device)
{
}
//-----------------------------------------------------------------------------------------------------
void create_file_db_of_partition_from_zero(MYSQL *conn, char *ch_partition)
{
int i_partition_id;
char *ch_temp_partition=NULL, *ch_mount_point=NULL;
ch_temp_partition=malloc((70)*sizeof(char));
memset(ch_temp_partition, '\0', sizeof(ch_temp_partition) );
ch_mount_point=malloc((140)*sizeof(char));
memset(ch_mount_point, '\0', sizeof(ch_mount_point) );
if(strstr(ch_partition, "/")==NULL) {
strcpy(ch_temp_partition, "/dev/");
strcat(ch_temp_partition, ch_partition);
}
else {
strcpy(ch_temp_partition, ch_partition);
}
//printf("glob_str2=%s\n", glob_str2);
struct mntent *m;
FILE *f;
f = setmntent("/etc/mtab", "r");
while ((m = getmntent(f))) {
//printf("Drive %s, name %s\n", (*m).mnt_dir, (*m).mnt_fsname);
if(strcmp(ch_temp_partition, (*m).mnt_fsname)==0) {
strcpy(ch_mount_point, (*m).mnt_dir);
break;
}
}
endmntent(f);
char *apath=NULL;
char ch_st_mode[7];
size_t path_len;
DIR *dir=NULL, *dir2;
struct dirent *entry;
struct stat attribut;
//struct tm* clock;
int i_result=0;
MYSQL_RES *result;
MYSQL_ROW row;
apath=malloc((_POSIX_PATH_MAX + 1)*sizeof(char));
memset( apath, '\0', sizeof( apath ) );
if((apath==NULL)) {g_print ("#Error! Not enough memory! \n"); return;}
dir = opendir(ch_mount_point);
if (dir == NULL) {
g_print ("#Error! Cannont open dir: %s \n", ch_mount_point);
return;
}
//printf("glob_str2=%s\n", glob_str2);
//setgid(0);
i_partition_id=i_get_partition_id_from_db(conn, ch_partition);
while((entry = readdir(dir)) != NULL ) {
//printf("(*entry).d_name=%s\n", (*entry).d_name);
if( (!(((*entry).d_name[strlen((*entry).d_name)-2]=='/') || ((*entry).d_name[strlen((*entry).d_name)-1]=='.'))) && strstr(entry->d_name, ".wh.")==NULL) {
memset( apath, '\0', sizeof( apath ) );
sprintf(apath, "%s/%s", ch_mount_point, (*entry).d_name);
//printf("apath=%s, (*entry).d_name=%s, stat=%d\n", apath, (*entry).d_name, stat((*entry).d_name, &attribut));
if(stat(apath, &attribut) == 0) {
//printf("apath=%s, stat=1\n", apath);
memset(glob_str, '\0', sizeof(glob_str) );
sprintf(glob_str, "INSERT INTO file_table (i_inode, i_partition_id, d_name, d_namelen, d_type, st_mode, st_nlink, st_uid, st_gid, st_rdev, st_size, "
"st_blksize, st_blocks, st_atime, st_mtime, st_ctime) " //15
"VALUES(%lu, %d, '/%s', %lu, %d, '%s', %lu, "
"'%d', '%d', %lu, %lu, %lu, "
"%lu, '%s', '%s', "
"'%s')", (*entry).d_fileno, i_partition_id, (*entry).d_name,
strlen((*entry).d_name), (*entry).d_type, ch_get_st_mode(attribut.st_mode), attribut.st_nlink,
attribut.st_uid, attribut.st_gid, attribut.st_rdev, attribut.st_size, attribut.st_blksize,
attribut.st_blocks, ch_convert_time_to_char(attribut.st_atime), ch_convert_time_to_char(attribut.st_mtime),
ch_convert_time_to_char(attribut.st_ctime));
sql_query(conn, glob_str, "Error");
if((attribut.st_mode & S_IFDIR)) {
}
}
}
}
free(apath); apath=NULL;
free(ch_temp_partition); ch_temp_partition=NULL;
free(ch_mount_point); ch_mount_point=NULL;
closedir( dir );
}
//-----------------------------------------------------------------------------------------------------
void actualize_db_for_device(MYSQL *conn, char *path_to_device)
{
//если нет записи об устр-ве в б.д., то создать
//иначе
// if(i_check_times()==TRUE) return;
// else получить список корневых файлов на устройстве и по каждому i-ому сравнить времена (call i_check_times()) и имеющиеся файлы с б.д.
// В случае расхождения - удалить все записи в б.д. для данного файла (каталога) и создать новые записи в б.д. (call create_records_for_file())
// !!!В ДАЛЬНЕЙШЕМ!!! В случае расхождения - спускаться на уровень ниже и снова сравнивать.
MYSQL_RES *result;
MYSQL_ROW row;
int i_result=0, i=0;
//Проверка наличия записи об устройстве в б.д.
// sprintf(str, "SELECT * FROM device_table WHERE ", uuid)
// mysql_query(mysql_connection, glob_str);
result = mysql_store_result(conn);
while ((row = mysql_fetch_row(result)))
{
}
mysql_free_result(result);
// END Проверка наличия записи об устройстве в б.д.
}
//-----------------------------------------------------------------------------------------------------
void actualize_db_for_devices_and_partitions(MYSQL *conn)
{
gchar *output;
GError *error = NULL;
int i=0, j=0, i_length=0, i_exist=0;
char *p=NULL, *ch_p=NULL, *ch_p2=NULL, *ch_p3=NULL;
int i_condition=0;
FILE *file;
MYSQL_RES *result, *result2;
MYSQL_ROW row;
DEVICE_STRUCT *device=NULL, *p_dev=NULL, devc;
PARTITION_STRUCT *partition=NULL, *p_part=NULL;
int i_partition_num=0;
int i_device_num=0;
fpos_t file_pos;
GList* device_list=NULL, *p_list = NULL;
GList* partition_list = NULL;
//1) get all devices and partitions;
//2) read /proc/partitions and compare. If exist in db and not exist in /proc/partitions - continue (т.к. м.б. записи по флэшкам).
// Else if exists in /proc/partitions and absent in db - add to db.
// Else - continue;
//3) if exists but various labels, uuids, fstypes
//Читаем /proc/partitions и заносим данные в device и partition.
if((file = fopen ("/proc/partitions", "r")) != (FILE *)0) {
fgetpos(file, &file_pos);
fgets(glob_str, 512, file);
fgets(glob_str, 512, file);
i=0, j=0;
while (fgets(glob_str, 512, file)!=NULL) {
p=glob_str+25;
if((isspace(glob_str[28]))) {
del_leading_spaces(p);
device=malloc(sizeof(DEVICE_STRUCT));
strcpy((*device).ch_device_name, p);
device_list = g_list_append(device_list, (DEVICE_STRUCT*)device);
}
else {
del_leading_spaces(p);
partition=malloc(sizeof(PARTITION_STRUCT));
strcpy((*partition).ch_partition_name, p);
partition_list = g_list_append(partition_list, (PARTITION_STRUCT*)partition);
}
//printf("p=%s\n", p);
//printf("ch_device_name[%d]=%s, ch_partition_name[%d]=%s, p=%s\n", i-1, device[i-1].ch_device_name, j, partition[j].ch_partition_name, p);
}
}
for(j=0;jname);
// }
// printf("\n");
// }
// printf("%s ", row[i] ? row[i] : "NULL");
// }
// }
// printf("\n");
//
// mysql_free_result(result);
//1. Del all records for file_path;
//2. Create new records for files in the file_path.
char *apath=NULL;
size_t path_len;
DIR *dir=NULL, *dir2;
struct dirent *entry;
struct stat attribut;
struct tm* clock;
int result;
apath=malloc((_POSIX_PATH_MAX + 1)*sizeof(char));
if((apath==NULL)) {g_print ("#Error! Not enough memory! \n"); return;}
if (!file_path) {g_print ("#Error! Directory=NULL! \n"); return;}
path_len = strlen(file_path);
if (!path_len || (path_len > _POSIX_PATH_MAX)) {g_print ("#Error! Problems with directory length determination! \n"); return;}
dir = opendir(file_path);
if (dir == NULL) {
g_print ("#Error! Cannont open dir: %s \n", file_path);
return;
}
if(i_First) {
memset( apath, '\0', sizeof( apath ) );
strcpy( apath, file_path );
strcat( apath, "/" );
if(stat(apath, &attribut) == 0) {
clock = gmtime(&(attribut.st_ctime));
//g_sprintf(ch_time, "%02d:%02d:%02d %02d.%02d.%04d", clock->tm_hour, clock->tm_min, clock->tm_sec, clock->tm_mday, clock->tm_mon, 1900+clock->tm_year);
}
//gtk_tree_store_append(treestore, &(*iter), NULL);
//gtk_tree_store_set(treestore, &(*iter), MODIFIED, ch_time, TYPE, chType, COLUMN, path, CHECKED_COLUMN, b_select_dirs, -1);
sprintf(glob_str, "DELETE file_table VALUES(0, 'v.1.0.0', %s)", apath); //Deletes records for
mysql_query(conn, glob_str);
sprintf(glob_str, "INSERT INTO file_table VALUES(0, 'v.1.0.0', %s)", apath);
mysql_query(conn, glob_str);
}
while((entry = readdir(dir)) != NULL ) {
memset( apath, '\0', sizeof( apath ) );
strcpy( apath, file_path );
strcat( apath, "/" );
strcat( apath, entry->d_name );
if( (!((apath[strlen(apath)-2]=='/') || (apath[strlen(apath)-1]=='.'))) && strstr(entry->d_name, ".wh.")==NULL) {
//gtk_tree_store_append(treestore, &child, &(*iter));
if(stat(apath, &attribut) == 0) {
clock = gmtime(&(attribut.st_ctime));
//g_sprintf(ch_time, "%02d:%02d:%02d %02d.%02d.%04d", clock->tm_hour, clock->tm_min, clock->tm_sec, clock->tm_mday, clock->tm_mon, 1900+clock->tm_year);
if((attribut.st_mode & S_IFDIR)) {
//gtk_tree_store_set(treestore, &child, MODIFIED, ch_time, TYPE, chType, COLUMN, apath, CHECKED_COLUMN, b_select_dirs, -1);
create_records_for_file_recursive(conn, apath, FALSE);
}
else {
//gtk_tree_store_set(treestore, &child, MODIFIED, ch_time, SIZE, ch_size, TYPE, "", COLUMN, apath, CHECKED_COLUMN, b_select_dirs, -1);
}
}
}
}
free(apath); apath=NULL;
closedir( dir );
}
//-----------------------------------------------------------------------------------------------------
void delete_db_structure(MYSQL *conn)
{
MYSQL_RES *result;
MYSQL_ROW row;
int i_result=0;
if(sql_query(conn, "SHOW DATABASES", "Error")) {
result = mysql_store_result(conn);
while ((row = mysql_fetch_row(result)))
{
if(strcmp(row[0], "dblinkfs")==0) {
i_result=1;
break;
}
}
mysql_free_result(result);
if(i_result==1) mysql_query(conn, "DROP DATABASE dblinkfs");
}
}
//-----------------------------------------------------------------------------------------------------
void create_db_structure(MYSQL *conn)
{
i_dbl_state &= ~READY;
i_dbl_state=CREATING_DB;
if (mysql_query(conn, "CREATE DATABASE IF NOT EXISTS dblinkfs")) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
return;
}
if (mysql_query(conn, "USE dblinkfs")) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
return;
}
// !!! CREATE TABLE IF NOT EXISTS !!!
if(mysql_query(conn, "CREATE TABLE version_table(i_id int not null auto_increment, name VARCHAR(25) not null, PRIMARY KEY (i_id))")) {
printf("Error on creating table version_table. %u: %s\n", mysql_errno(conn), mysql_error(conn));
return;
}
mysql_query(conn, "INSERT INTO version_table VALUES(0, 'v.1.0.0')");
mysql_query(conn, "CREATE TABLE device_table(i_device_id int not null auto_increment, "
"device_name VARCHAR(25) UNIQUE, "
"PRIMARY KEY (i_device_id))");
mysql_query(conn, "CREATE TABLE device_partitions_table(i_partition_id int not null auto_increment, "
"i_device_id int not null, "
"partition_name VARCHAR(512) not null, "
"partition_label VARCHAR(32), "
"partition_fs_type VARCHAR(8) not null, "
"uuid VARCHAR(37) not null UNIQUE, "
"PRIMARY KEY (i_partition_id), FOREIGN KEY(i_device_id) "
"REFERENCES device_table(i_device_id))");
sql_query(conn, "CREATE TABLE file_table(i_inode int unsigned not null, "
"i_partition_id int not null, "
"d_name VARCHAR(512) not null UNIQUE, "
"d_namelen char not null, "
"d_type char not null, "
"st_mode ENUM('S_ISREG', 'S_ISDIR', 'S_ISCHR', 'S_ISBLK', 'S_ISFIFO', 'S_ISLNK', 'S_ISSOCK') not null, "
"st_nlink int not null, " /* number of hard links */
"st_uid int not null, " /* user ID of owner */
"st_gid int not null, " /* group ID of owner */
"st_rdev int not null, " /* device ID (if special file) */
"st_size int not null, " /* total size, in bytes */
"st_blksize int not null, " /* blocksize for file system I/O */
"st_blocks int not null, " /* number of 512B blocks allocated */
"st_atime DATETIME not null, " /* time of last access. Format like: 2004-12-01 20:38:55. */
"st_mtime DATETIME not null, " /* time of last modification */
"st_ctime DATETIME not null, " /* time of last status change */
"INDEX (d_name),"
"PRIMARY KEY (i_inode), FOREIGN KEY(i_partition_id) "
"REFERENCES device_partitions_table(i_partition_id))", "Error");
mysql_query(conn, "CREATE TABLE file_metadata_table(i_inode int unsigned not null, "
"md5sum VARCHAR(32), "
"shasum VARCHAR(40), "
"description VARCHAR(25), "
"PRIMARY KEY (i_inode), FOREIGN KEY(i_inode) REFERENCES file_table(i_inode))");
i_dbl_state &= ~CREATING_DB;
i_dbl_state |= READY;
}
//-----------------------------------------------------------------------------------------------------
void backup_db_to_device(MYSQL *conn, char *path_to_device)
{
}
//-----------------------------------------------------------------------------------------------------
void add_devices_and_partitions_to_db(MYSQL *conn) //Includes synchronization with existing records in tables
{
gchar *output;
GError *error = NULL;
int i=0, j=0, i_length=0, i_exist=0;
char *p=NULL, *ch_p=NULL, *ch_p2=NULL, *ch_p3=NULL;
int i_condition=0;
FILE *file;
MYSQL_RES *result, *result2;
MYSQL_ROW row;
MYSQL_FIELD *field;
int num_fields=0;
DEVICE_STRUCT *device=NULL, *p_dev=NULL, devc;
PARTITION_STRUCT *partition=NULL, *p_part=NULL;
int i_partition_num=0;
int i_device_num=0;
fpos_t file_pos;
GList* device_list=NULL, *p_list = NULL;
GList* partition_list = NULL;
//1) get all devices and partitions;
//2) read /proc/partitions and compare. If exist in db and not exist in /proc/partitions - continue (т.к. м.б. записи по флэшкам).
// Else if exists in /proc/partitions and absent in db - add to db.
// Else - continue;
//3) if exists but various labels, uuids, fstypes
//Читаем /proc/partitions и заносим данные в device и partition.
if((file = fopen ("/proc/partitions", "r")) != (FILE *)0) {
fgetpos(file, &file_pos);
fgets(glob_str, 512, file);
fgets(glob_str, 512, file);
i=0, j=0;
while (fgets(glob_str, 512, file)!=NULL) {
p=glob_str+25;
if((isspace(glob_str[28]))) {
del_leading_spaces(p);
device=malloc(sizeof(DEVICE_STRUCT));
strcpy((*device).ch_device_name, "/dev/");
strcat((*device).ch_device_name, p);
device_list = g_list_append(device_list, (DEVICE_STRUCT*)device);
}
else {
del_leading_spaces(p);
partition=malloc(sizeof(PARTITION_STRUCT));
strcpy((*partition).ch_partition_name, "/dev/");
strcat((*partition).ch_partition_name, p);
partition_list = g_list_append(partition_list, (PARTITION_STRUCT*)partition);
}
//printf("p=%s\n", p);
//printf("ch_device_name[%d]=%s, ch_partition_name[%d]=%s, p=%s\n", i-1, device[i-1].ch_device_name, j, partition[j].ch_partition_name, p);
}
}
for(j=0;jname);
// }
// printf("\n");
// }
// printf("%s ", row[i] ? row[i] : "NULL");
// }
// }
// printf("\n");
//
// mysql_free_result(result);
// }
mysql_close(mysql_connection);
//gtk_main();
return 0;
}