Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

libmnt.c

00001 /***************************************************************************
00002  * CVSID: $Id: libmnt.c,v 1.33 2004/08/04 20:37:21 stefanb Exp $
00003  *
00004  * libmnt.c : main() for MNT daemon
00005  *
00006  * Copyright (C) 2004 Stefan Bambach, <sbambach@gmx.net>
00007  *
00008  * Licensed under the GNU Lesser General Public License 2.1
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  **************************************************************************/
00025  
00026 #ifdef HAVE_CONFIG_H
00027 #  include <config.h>
00028 #endif
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <glib.h>
00034 #include <dbus/dbus.h>
00035 #include <dbus/dbus-glib.h>
00036 
00037 #include "libmnt.h"
00038 #include <mntd/mntd_mount.h>
00039 
00040 
00041 static DBusConnection* connection = NULL;
00042 static int is_initialized = FALSE;
00043 static PLIBMNTFUNCS functions = NULL;
00044 static void *user_data = NULL;
00045 
00046 
00047 int _mnt_remount(char *udi, int flag);
00048 
00049 
00059 static DBusHandlerResult filter_func(DBusConnection* connection,
00060                                      DBusMessage*    message,
00061                                      void*           user_data)
00062 {
00063     DBusError error;
00064     
00065     g_assert(connection!=NULL);
00066     g_assert(message!=NULL);
00067     
00068     dbus_error_init(&error);
00069 
00070     if (dbus_message_is_signal( message, 
00071                                             DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, 
00072                                             "Disconnected"))
00073     {
00074         const char *path = NULL;
00075         path = dbus_message_get_path(message);
00076         if (path != NULL) {
00077             if (strcmp(DBUS_PATH_ORG_FREEDESKTOP_LOCAL, path) == 0) {
00078                 if (functions->dbus_disconnect!=NULL) {
00079                     functions->dbus_disconnect(user_data);
00080                 }
00081             }
00082         }
00083         
00084     } else if (dbus_message_is_signal(  message, 
00085                                                     DBUS_INTERFACE_MNT_MANAGER, 
00086                                                     "VolumeMounted"))
00087     {
00088         char *udi = NULL;
00089         char *mntpnt = NULL;
00090         if (dbus_message_get_args(message, &error, 
00091                                             DBUS_TYPE_STRING, &udi,
00092                                             DBUS_TYPE_STRING, &mntpnt,
00093                                             DBUS_TYPE_INVALID)) {
00094             if (functions->volume_mounted!=NULL) {
00095                 functions->volume_mounted(udi, mntpnt, user_data);
00096             }
00097             dbus_free(udi);
00098         }
00099         
00100     } else if (dbus_message_is_signal(  message, 
00101                                                     DBUS_INTERFACE_MNT_MANAGER, 
00102                                                     "VolumeUnmounted"))
00103     {
00104         char *udi = NULL;
00105         char *mntpnt = NULL;
00106         if (dbus_message_get_args(message, &error, 
00107                                             DBUS_TYPE_STRING, &udi,
00108                                             DBUS_TYPE_STRING, &mntpnt,
00109                                             DBUS_TYPE_INVALID)) {
00110             if (functions->volume_unmounted!=NULL) {
00111                 functions->volume_unmounted(udi, mntpnt, user_data);
00112             }
00113             dbus_free(udi);
00114         }
00115         
00116 #ifdef DEBUG
00117     } else {
00118         int type;
00119         type = dbus_message_get_type(message);
00120         switch(type) {
00121         case DBUS_MESSAGE_TYPE_METHOD_CALL:
00122             printf("DBUS_MESSAGE_TYPE_METHOD_CALL\n");
00123             break;
00124         case DBUS_MESSAGE_TYPE_METHOD_RETURN:
00125             printf("DBUS_MESSAGE_TYPE_METHOD_RETURN\n");
00126             break;
00127         case DBUS_MESSAGE_TYPE_ERROR:
00128             printf("DBUS_MESSAGE_TYPE_ERROR\n");
00129             break;
00130         case DBUS_MESSAGE_TYPE_SIGNAL:
00131             printf("DBUS_MESSAGE_TYPE_SIGNAL\n");
00132             break;
00133         case DBUS_MESSAGE_TYPE_INVALID:
00134             printf("DBUS_MESSAGE_TYPE_INVALID\n");
00135             break;
00136         default:
00137             printf("DBUS_MESSAGE_TYPE_ .... UNKNOWN\n");
00138             break;
00139         }
00140         
00141         printf("libmnt::filter_func(): obj_path=%s interface=%s method=%s destination=%s sender=%s\n", 
00142                     dbus_message_get_path(message), 
00143                     dbus_message_get_interface(message),
00144                     dbus_message_get_member(message),
00145                     dbus_message_get_destination(message),
00146                     dbus_message_get_sender(message)
00147         );
00148 #endif
00149 
00150     }
00151     
00152 
00153     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00154 }
00155 
00156 
00158 static LIBMNTFUNCS dummy_functions = {
00159     NULL, 
00160     NULL, 
00161     NULL  
00162 };
00163 
00164 
00165 int mnt_init(PLIBMNTFUNCS cb_functions, void *data)
00166 {
00167     DBusError error;
00168     int res = 0;
00169     
00170     // exit, if already initialized
00171     if (is_initialized) {
00172         fprintf(stderr, "libmnt is already initialized!\n");
00173         goto cleanup;
00174     }
00175 
00176     // initialize the callback functions
00177     functions = cb_functions;
00178     if (cb_functions==NULL) {
00179         functions = &dummy_functions;
00180     }
00181 
00182     // initialize user_data
00183     user_data = data;
00184     
00185     // connect to dbus daemon and register myself
00186     dbus_error_init(&error);
00187     connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
00188     if (connection==NULL) {
00189         fprintf(stderr, "Couldn't connect to DBUS, error %s: %s", 
00190             error.name, error.message);
00191         goto error;
00192     }
00193     
00194     // test for running service from mntd
00195     if (!dbus_bus_service_exists(connection, DBUS_SERVICE_MNT, &error)) {
00196         fprintf(stderr, "Service '%s' doesn't exist !\n", DBUS_SERVICE_MNT);
00197         goto error;
00198     }
00199     
00200     // acquire server
00201     if (dbus_bus_acquire_service(connection, DBUS_SERVICE_MNT, 0, &error) == -1) {
00202         fprintf(stderr, "Error Acquiring service '" DBUS_SERVICE_MNT "'\n");
00203         if (dbus_error_is_set(&error)) {
00204             fprintf(stderr, "Can't acquire '" DBUS_SERVICE_MNT "' service, error %s: %s'",
00205                 error.name, error.message);
00206         }
00207         goto error;
00208     }
00209     
00210     // call main_loop function, if needed
00211     if (functions->main_loop!=NULL) {
00212         functions->main_loop(connection, user_data);
00213     }
00214 
00215     // add filter functions to connection handler ....
00216     if (!dbus_connection_add_filter(connection, filter_func, user_data, NULL)) {
00217         fprintf(stderr, "Couldn't add filters to dbus connection handler");
00218         goto error;
00219     }
00220     
00221     // ..., but register only for signals from Manager
00222     dbus_bus_add_match(connection,
00223         "type='signal',"
00224         "interface='" DBUS_INTERFACE_MNT_MANAGER "',"
00225         "path='" DBUS_PATH_MNT_MANAGER "'",
00226         &error);
00227     if (dbus_error_is_set(&error)) {
00228         fprintf(stderr, "Couldn't register Manager signal handler: %s: %s", error.name, error.message);
00229         goto error;
00230     }
00231 
00232     // disable _exit() on disconnect signal
00233     dbus_connection_set_exit_on_disconnect(connection, FALSE);
00234     
00235     is_initialized = TRUE;
00236     
00237     goto cleanup;
00238     
00239 error:
00240     dbus_connection_disconnect(connection);
00241     is_initialized = FALSE;
00242     res = -1;
00243     
00244 cleanup:
00245     if (dbus_error_is_set(&error)) {
00246         dbus_error_free(&error);
00247     }
00248 
00249     return res;
00250 }
00251 
00252 
00253 void mnt_quit(void)
00254 {
00255     if (!is_initialized) {
00256         return;
00257     }
00258     
00259     if (connection!=NULL) {
00260         dbus_connection_disconnect(connection);
00261         connection = NULL;
00262     }
00263     
00264     is_initialized = FALSE;
00265     
00266     return;
00267 }
00268 
00269 
00270 char **mnt_get_all_volumes(int *num_volumes)
00271 {
00272     DBusError error;
00273     DBusMessage* message = NULL;
00274     DBusMessage* reply = NULL;
00275     DBusMessageIter iter;
00276     char **res = NULL;
00277     char **data_array;
00278     int data_length;
00279     int i=0;
00280     
00281     message = dbus_message_new_method_call(
00282                                             DBUS_SERVICE_MNT,
00283                                             DBUS_PATH_MNT_MANAGER,
00284                                             DBUS_INTERFACE_MNT_MANAGER,
00285                                             "GetAllVolumes");
00286     
00287     if (message==NULL) {
00288         goto error;
00289     }
00290     
00291     dbus_error_init(&error);
00292     
00293     reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
00294     if (dbus_error_is_set(&error)) {
00295         goto error;
00296     }
00297     if (reply==NULL) {
00298         goto error;
00299     }
00300     
00301     // get reply data
00302     dbus_message_iter_init(reply, &iter);
00303     if (!dbus_message_iter_get_string_array(&iter, &data_array, &data_length)) {
00304         fprintf(stderr, "wrong reply from mntd\n");
00305         goto error;
00306     }
00307     
00308     // handle data
00309     res = (char **) malloc(sizeof(char*)*data_length);
00310     if (res == NULL) {
00311         goto error;
00312     }
00313 
00314     // fill with data
00315     *num_volumes = 0;
00316     for(i=0; i<data_length; i++) {
00317         if ((data_array[i] != NULL) && (strlen(data_array[i])>0)) {
00318             res[i] = strdup(data_array[i]);
00319             (*num_volumes)++;
00320         }
00321     }
00322 
00323     // free dbus data array
00324     dbus_free_string_array(data_array);
00325     
00326     goto cleanup;
00327     
00328 error:
00329     res = NULL;
00330     
00331 cleanup:
00332     if (message!=NULL) dbus_message_unref(message);
00333     if (reply!=NULL) dbus_message_unref(reply);
00334     
00335     return res;
00336 }
00337 
00338 
00339 char *mnt_get_mntpnt(char *udi)
00340 {
00341     DBusError error;
00342     DBusMessage* message = NULL;
00343     DBusMessage* reply = NULL;
00344     DBusMessageIter iter;
00345     char *res = NULL;
00346     char *mntpnt = NULL;
00347     
00348     message = dbus_message_new_method_call(
00349                                             DBUS_SERVICE_MNT,
00350                                             DBUS_PATH_MNT_MANAGER,
00351                                             DBUS_INTERFACE_MNT_MANAGER,
00352                                             "GetMntPnt");
00353     
00354     if (message==NULL) {
00355         goto error;
00356     }
00357     
00358     // construct parameter
00359     dbus_message_iter_init(message, &iter);
00360     dbus_message_iter_append_string(&iter, udi);
00361     
00362     // method invocation
00363     dbus_error_init(&error);
00364     reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
00365     if (dbus_error_is_set(&error)) {
00366         fprintf(stderr, "Error calling GetMntPnt('%s'): %s : %s\n", udi, error.name, error.message);
00367         goto error;
00368     }
00369     if (reply==NULL) {
00370         goto error;
00371     }
00372     
00373     // get return value
00374     if (!dbus_message_get_args(reply, &error, 
00375                                         DBUS_TYPE_STRING, &mntpnt,
00376                                         DBUS_TYPE_INVALID)) {
00377         fprintf(stderr, "Error getting mntpnt from GetMntPnt() call (%s : %s)\n", error.name, error.message);
00378         goto error;
00379     }
00380     res = strdup(mntpnt);
00381     if (res == NULL) {
00382         goto error;
00383     }
00384     
00385     goto cleanup;
00386     
00387 error:
00388     res = NULL;
00389     
00390 cleanup:
00391     if (mntpnt!=NULL) dbus_free(mntpnt);
00392     if (message!=NULL) dbus_message_unref(message);
00393     if (reply!=NULL) dbus_message_unref(reply);
00394     
00395     return res;
00396 }
00397 
00398 
00399 int _mnt_remount(char *udi, int flag)
00400 {
00401     DBusError error;
00402     DBusMessage* message = NULL;
00403     DBusMessage* reply = NULL;
00404     DBusMessageIter iter;
00405     int res = -1;
00406     
00407     message = dbus_message_new_method_call(
00408                                             DBUS_SERVICE_MNT,
00409                                             DBUS_PATH_MNT_MANAGER,
00410                                             DBUS_INTERFACE_MNT_MANAGER,
00411                                             "Remount");
00412     
00413     if (message==NULL) {
00414         goto error;
00415     }
00416     
00417     // construct parameter
00418     dbus_message_iter_init(message, &iter);
00419     dbus_message_iter_append_string(&iter, udi);
00420     dbus_message_iter_append_int32(&iter, flag);
00421     
00422     // method invocation
00423     dbus_error_init(&error);
00424     reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
00425     if (dbus_error_is_set(&error)) {
00426         fprintf(stderr, "Error calling Remount('%s', %d): %s : %s\n", udi, flag, 
00427             error.name, error.message);
00428         goto error;
00429     }
00430     if (reply==NULL) {
00431         goto error;
00432     }
00433     
00434     // get return value
00435     if (!dbus_message_get_args(reply, &error, 
00436                                         DBUS_TYPE_INT32, &res,
00437                                         DBUS_TYPE_INVALID)) {
00438         fprintf(stderr, "Error from Remount() call (%s : %s)\n", error.name, error.message);
00439         goto error;
00440     }
00441     
00442     goto cleanup;
00443     
00444 error:
00445     res = -1;
00446     
00447 cleanup:
00448     if (message!=NULL) dbus_message_unref(message);
00449     if (reply!=NULL) dbus_message_unref(reply);
00450     
00451     return res;
00452 }
00453 
00454 
00455 int mnt_remount_rd(char *udi)
00456 {
00457     return _mnt_remount(udi, MOUNT_RD);
00458 }
00459 
00460 
00461 int mnt_remount_rw(char *udi)
00462 {
00463     return _mnt_remount(udi, MOUNT_RW);
00464 }
00465 
00466 
00467 DBusConnection *_mnt_get_connection(void)
00468 {
00469     return connection;
00470 }

Generated on Wed Mar 30 13:43:26 2005 for Mntd by  doxygen 1.3.9.1