fsd_main.c

Go to the documentation of this file.
00001 
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include "fsd_mysql.h"
00023 #include "fsd_device.h"
00024 #include "fsd_defines.h"
00025 #include "../parser/parser.h"
00026 #include <mysql/mysql.h>
00027 #include <signal.h>
00028 
00029 
00037 MYSQL *conn;
00039 int fsc_device = 0;
00040 
00041 
00051 void exit_deamon(int sig) {
00052         /* release device */
00053         fsd_chardevice_close(fsc_device);
00054         /* close connection to database */
00055         fsd_db_close(conn);
00056 
00057         printf("MySQL filesystem deamon stopped.\n");
00058 
00059         exit(1);
00060 }
00061 
00062 
00075 int fsd_write_message(int fsc_device, const char *data, int len) {
00076         char message_out[MAX_MESSAGE_LENGTH]="";
00077         
00078         /* make up message */
00079         strcpy(message_out, FSD_VERSION);
00080         strcat(message_out, " ");
00081         memcpy(message_out + strlen(message_out), data, len);
00082         
00083         /* compute message len 
00084          * len plus length of version plus one for space and one for newline 
00085          */
00086         len = len + strlen(FSD_VERSION) + 1;
00087         /* trailing zero for easy debugging prints, there is always space to add
00088          * this trailing zero, we have sufficient size of output buffer
00089          */
00090         message_out[len] = '\0';        
00091         PINFO("Result: '%s'\n\n", message_out);
00092         
00093         return fsd_chardevice_write(fsc_device, message_out, len); 
00094 }
00095 
00108 int fsd_write_read_dir(rd_item **rd_list, int len, char *return_text) {
00109  
00110         /* pointer to previus item */
00111         rd_item *prev;
00112         
00113         /* length of item, its for computing message len */
00114         int item_length;
00115         
00116         strcpy(return_text, "");
00117         
00118         /* while we arent on the end of list */
00119         while (*rd_list) {
00120                 
00121                 /* compute item length = name + id + type + 3 x / */
00122                 item_length = strlen((*rd_list)->name) + strlen((*rd_list)->id) + strlen((*rd_list)->type) + 3;
00123                 if (item_length > len) {
00124                         /* message len with next item is longer then remaining message len. It must stop
00125                          * listing and return this message, remaining items will be return in next calling.
00126                          */
00127                         return 1;       
00128                 }
00129                 len -= item_length;
00130                 
00131                 /* make up item message part */
00132                 strcat(return_text, (*rd_list)->name);
00133                 strcat(return_text, "/");
00134                 strcat(return_text, (*rd_list)->id);
00135                 strcat(return_text, "/");
00136                 strcat(return_text, (*rd_list)->type);
00137                 strcat(return_text, "/");
00138                 
00139                 /* turn pointers to next item and release memory */
00140                 prev = (*rd_list);
00141                 (*rd_list) = (*rd_list)->next;
00142                 free(prev);
00143                 
00144         }
00145         
00146         /* if all list is read return 0 and the function wount be called */
00147         return 0;
00148  }
00149 
00150 
00163 int main() {
00164 
00165         /* structure for commands */
00166         struct_command command;
00167 
00168         /* strings for messages - both input and output message */
00169         char message[MAX_MESSAGE_LENGTH];
00170 
00171         /* buffer for return messages from db functions */
00172         char ret[MAX_MESSAGE_LENGTH] = "";
00173 
00174         /* pointer to rd_list - internal structure of MySQL */
00175         rd_item *rd_list = NULL;
00176 
00177         /* size of returned block of data */
00178         int block_size;
00179         
00180         /* buffer for block */
00181         char block[MAX_BLOCK_LENGTH];
00182         
00183         char offset[MAX_ID_LENGTH]; 
00184         char *data_pointer;
00185         int pos;
00186         
00187         
00188         /* signal handling */
00189         signal(SIGINT, exit_deamon);
00190         
00191         PINFO("MySQL filesystem deamon started.\n");
00192         
00193         /* iniciation, connect to database */
00194         if (!(conn = fsd_db_connect(server, user, password, database))) {
00195                 return EDB_CONNECT_ERROR;       
00196         }
00197 
00198         /* open FSC device - input and output device for communication between
00199          *  FS in kernel and FSD in user space
00200          */
00201         if ((fsc_device = fsd_chardevice_open()) <= 0) {
00202                 return EFSC_DEVICE_OPEN_ERROR;
00203         }
00204         
00205         /* deamon is prepared start infinite loop */
00206         while (1) {
00207                 
00208                 /* count of bytes read by char device */
00209                 int result;
00210                 result = fsd_chardevice_read(fsc_device, message);
00211                 
00212                 if (result == -1) { 
00213                         /* when reading is iterrupted by SIGINT signal, 
00214                          * the deamon should be terminated as well 
00215                          */
00216                     exit_deamon(SIGINT);
00217                 }
00218                 
00219                 
00220                 /* parse command */
00221                 switch (parse_message(message, result, &command)) {
00222                         case EPROTOKOL_VERSION_ERROR: { 
00223                                 PDEBUG("Command '%s', len=%d parsing failed.\n", message, result);
00224                         
00225                                 /* we need to write something to the FSC device, otherewise it will block */
00226                                 fsd_write_message(fsc_device, "ER VERSION_FAULT", 16); 
00227                         
00228                                 /* next loop in the infinite loop */
00229                                 continue;
00230                                 break;
00231                         }
00232                         case OK: {
00233                                 PINFO("Command: '%s' (ver:'%s', cmd:'%s', prm:'%s')\n", message, 
00234                                         command.version, command.command, command.param);
00235                                 break;
00236                         }
00237                 }
00238 
00239 
00240                 /* command branching */
00241                 switch (command.command_nr) {
00242                         case TEST_NR: {
00243                                 PINFO("Test database connection.\n");
00244                                 if (fsd_test(conn) == OK) {
00245                                         fsd_write_message(fsc_device, "OK", 2); 
00246                                 } 
00247                                 else {
00248                                         fsd_write_message(fsc_device, "ER TEST_FAILED", 14);
00249                                 }
00250                                 break;
00251                         }
00252 
00253                         case CREATE_NR: {
00254                                 PINFO("Create file '%s' in dir '%s'\n", command.data, command.param);
00255                                 fsd_create(conn, command.param, command.data, ret);
00256                                 strcpy(message, ret);
00257                                 fsd_write_message(fsc_device, message, strlen(message));
00258                                 break;
00259                         }
00260                 
00261                         case MKDIR_NR: {
00262                                 printf("Make dir %s in dir %s\n", command.data, command.param);
00263                                 fsd_mkdir(conn, command.param, command.data, ret);
00264                                 strcpy(message, ret);
00265                                 fsd_write_message(fsc_device, message, strlen(message));
00266                                 break;
00267                         }
00268                 
00269                         case CLEAR_FILE_NR: {
00270                                 printf("Clear file %s\n", command.param);
00271                                 fsd_clear_file(conn, command.param, ret);
00272                                 strcpy(message, ret);
00273                                 fsd_write_message(fsc_device, message, strlen(message));
00274                                 break;
00275                         }
00276                 
00277                         case ADD_BLOCK_NR: {
00278                                 printf("Add block to file %s, size of block: %i\n", command.param, command.data_len);
00279                                 fsd_add_block(conn, command.param, command.data_len, command.data, ret);
00280                                 strcpy(message, ret);
00281                                 fsd_write_message(fsc_device, message, strlen(message));
00282                                 break;
00283                         }
00284                 
00285                         case REMOVE_FILE_NR: {
00286                                 printf("Remove file %s\n", command.param);
00287                                 fsd_remove_file(conn, command.param, ret);
00288                                 strcpy(message, ret);
00289                                 fsd_write_message(fsc_device, message, strlen(message));
00290                                 break;
00291                         }
00292                 
00293                         case REMOVE_DIR_NR: {
00294                                 printf("Remove dir %s\n", command.param);
00295                                 fsd_remove_dir(conn, command.param, ret);
00296                                 strcpy(message, ret);
00297                                 fsd_write_message(fsc_device, message, strlen(message));
00298                                 break;
00299                         }
00300                 
00301                         case GET_BLOCK_NR: {
00302                                 printf("Get block from file %s, offset: %s \n", command.param, command.data);
00303                                 /* block readed succesfully, copy block to message */
00304                                 if (fsd_get_block(conn, command.param, command.data, &block_size, block, ret) == OK) {
00305                                   strcpy(message, ret);
00306                                   memcpy((message + strlen(message)), block, block_size);
00307                                   fsd_write_message(fsc_device, message, strlen(ret) + block_size);
00308                                 } 
00309                                 /* there was an error return error message (not copy block) */
00310                                 else {
00311                                     strcpy(message, ret);
00312                                     fsd_write_message(fsc_device, message, strlen(ret));
00313                                 }
00314                                 break;
00315                         }
00316                 
00317                         case LOOKUP_NR: {
00318                                 printf("Lookup for %s in dir %s \n", command.data, command.param);
00319                                 fsd_lookup(conn, command.param, command.data, ret);
00320                                 strcpy(message, ret);
00321                                 fsd_write_message(fsc_device, message, strlen(message));
00322                                 break;
00323                         }
00324 
00325                         case READ_INODE_NR: {
00326                                 printf("Read inode info for inode nr. %s\n", command.param);
00327                                 fsd_read_inode(conn, command.param, ret);
00328                                 strcpy(message, ret);
00329                                 fsd_write_message(fsc_device, message, strlen(message));
00330                                 break;
00331                         }
00332 
00333                         case FILE_INFO_NR: {
00334                                 printf("Info for file with inode number %s \n", command.param);
00335                                 fsd_file_info(conn, command.param, ret);
00336                                 strcpy(message, ret);
00337                                 fsd_write_message(fsc_device, message, strlen(message));
00338                                 break;
00339                         }
00340 
00341                         case DIR_INFO_NR: {
00342                                 printf("Info for dir with inode number %s \n", command.param);
00343                                 fsd_dir_info(conn, command.param, ret);
00344                                 strcpy(message, ret);
00345                                 fsd_write_message(fsc_device, message, strlen(message));
00346                                 break;
00347                         }
00348                 
00349                         case READ_DIR_NR: {
00350                                 printf("Read dir [id = %s]\n", command.param);
00351                                 
00352                                 /* if readdir returns items list send the list in loop */
00353                                 if (fsd_read_dir(conn, command.param, &rd_list, ret) == OK) {
00354                                         strcpy(message, ret);
00355                                         
00356                                         /* prepare message with len witch fit to message len, while there is item in list */
00357                                         while (fsd_write_read_dir(&rd_list, 
00358                                                         MAX_MESSAGE_LENGTH - strlen(message) - strlen(FSD_VERSION) - 1, ret)) {
00359                                                 strcat(message, ret);
00360                                                 
00361                                                 /* send message with part of a list */
00362                                                 fsd_write_message(fsc_device, message, strlen(message));        
00363                                                 result = fsd_chardevice_read(fsc_device, message);
00364                                                 
00365                                                 /* when reading is iterrupted by SIGINT signal, the deamon should be terminated as well */
00366                                                 if (result == -1) {
00367                                                         exit_deamon(SIGINT);
00368                                                 }
00369                                                 strcpy(message, "");
00370                                         }
00371                                         
00372                                         /* send the last message */
00373                                         strcat(message, ret);
00374                                         fsd_write_message(fsc_device, message, strlen(message));
00375                                         
00376                                 /* there was an error return error message (not send list) */
00377                                 } 
00378                                 else {
00379                                         strcpy(message, ret);
00380                                         fsd_write_message(fsc_device, message, strlen(message));
00381                                 }       
00382                                 break;
00383                         }
00384                 
00385                         case REPLACE_BLOCK_NR: {
00386                                 PDEBUG("command.data_len= '%d'\n", command.data_len);
00387                                 pos = 0;
00388                                 data_pointer = command.data;
00389                                 while ((command.data_len > 0) && ((*data_pointer) != ' ')) {
00390                                         offset[pos++] = *(data_pointer);
00391                                         data_pointer++; 
00392                                         (command.data_len)--;
00393                                 }
00394                                 data_pointer++;
00395                                 (command.data_len)--;
00396                                 offset[pos]='\0';
00397                                 printf("Replace block to file %s, size of block: %i, offset: %s\n", command.param, command.data_len, offset);
00398                                 fsd_replace_block(conn, command.param, offset, command.data_len, command.data, ret);
00399                                 strcpy(message, ret);
00400                                 fsd_write_message(fsc_device, message, strlen(message));
00401                                 break;
00402                         }
00403 
00404                         case MOVE_FILE_NR: {
00405                                 printf("Move file with inode number %s to dir %s \n", command.param, command.data);
00406                                 fsd_move_file(conn, command.param, command.data, ret);
00407                                 strcpy(message, ret);
00408                                 fsd_write_message(fsc_device, message, strlen(message));
00409                                 break;
00410                         }
00411 
00412                         case RENAME_FILE_NR: {
00413                                 printf("Rename file with inode number %s to name %s \n", command.param, command.data);
00414                                 fsd_rename_file(conn, command.param, command.data, ret);
00415                                 strcpy(message, ret);
00416                                 fsd_write_message(fsc_device, message, strlen(message));
00417                                 break;
00418                         }
00419 
00420                         case RENAME_DIR_NR: {
00421                                 printf("Rename dir with inode number %s to name %s \n", command.param, command.data);
00422                                 fsd_rename_dir(conn, command.param, command.data, ret);
00423                                 strcpy(message, ret);
00424                                 fsd_write_message(fsc_device, message, strlen(message));
00425                                 break;
00426                         }
00427 
00428                         case TRUNCATE_FILE_NR: {
00429                                 printf("Truncate file %s to length: %s\n", command.param, command.data);
00430                                 fsd_truncate_file(conn, command.param, command.data, ret);
00431                                 strcpy(message, ret);
00432                                 fsd_write_message(fsc_device, message, strlen(message));
00433                                 break;
00434                         }
00435         
00436                         default: {
00437                                 PINFO("Unknown command\n");     
00438                                 fsd_write_message(fsc_device, "UNKNOWN_COMMAND", 15);
00439                                 break;
00440                         }
00441                 }
00442         }
00443         
00444         /* normal case the code should never come here... */
00445         exit_deamon(SIGINT);    
00446     return 0;
00447 }
00448 

Generated on Mon May 28 13:33:08 2007 for MYSQLFS by  doxygen 1.5.0