00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00171 if (is_initialized) {
00172 fprintf(stderr, "libmnt is already initialized!\n");
00173 goto cleanup;
00174 }
00175
00176
00177 functions = cb_functions;
00178 if (cb_functions==NULL) {
00179 functions = &dummy_functions;
00180 }
00181
00182
00183 user_data = data;
00184
00185
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
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
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
00211 if (functions->main_loop!=NULL) {
00212 functions->main_loop(connection, user_data);
00213 }
00214
00215
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
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
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
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
00309 res = (char **) malloc(sizeof(char*)*data_length);
00310 if (res == NULL) {
00311 goto error;
00312 }
00313
00314
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
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
00359 dbus_message_iter_init(message, &iter);
00360 dbus_message_iter_append_string(&iter, udi);
00361
00362
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
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
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
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
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 }