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 <dbus/dbus.h>
00034 #include <dbus/dbus-glib.h>
00035 #include <dbus/dbus-glib-lowlevel.h>
00036
00037 #include <libmnt/libmnt.h>
00038
00039 #include "mntd_dbus_error.h"
00040 #include "mntd_dbus_manager.h"
00041 #include "mntd_volume_manager.h"
00042 #include "mntd_volume.h"
00043 #include "errmanager.h"
00044 #include "main.h"
00045 #include "dbug_mem.h"
00046
00047
00048
00049 int cb_append_udi(void *data, void *userdata);
00050
00051
00052
00053
00054
00055
00065 DBusConnection* dbus_connection = NULL;
00066
00067
00073 int
00074 mntd_dbus_init(void *user_data)
00075 {
00076 DBusError error;
00077 int res = 0;
00078
00079 dbus_connection_set_change_sigpipe(TRUE);
00080
00081 dbus_error_init(&error);
00082 dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
00083 if (dbus_connection==NULL) {
00084 MSG_INF("dbus_bus_get(): '%s'", error.message);
00085 goto error;
00086 }
00087
00088
00089 dbus_bus_acquire_service(dbus_connection, DBUS_SERVICE_MNT, 0, &error);
00090 if (dbus_error_is_set(&error)) {
00091 MSG_INF("dbus_bus_acquire_service(): %s: %s", error.name, error.message);
00092 goto error;
00093 }
00094
00095
00096 dbus_connection_add_filter(dbus_connection, mntd_dbus_manager_filter_function,
00097 user_data, NULL);
00098
00099
00100 dbus_bus_add_match(dbus_connection,
00101 "type='signal',"
00102 "interface='" DBUS_INTERFACE_MNT_BLOCK "',"
00103 "path='" DBUS_PATH_MNT_BLOCK "'",
00104 &error);
00105 if (dbus_error_is_set(&error)) {
00106 MSG_INF("Couldn't register Block signal handler: %s: %s", error.name, error.message);
00107 goto error;
00108 }
00109
00110
00111 dbus_bus_add_match(dbus_connection,
00112 "type='signal',"
00113 "interface='" DBUS_INTERFACE_MNT_DISC "',"
00114 "path='" DBUS_PATH_MNT_DISC "'",
00115 &error);
00116 if (dbus_error_is_set(&error)) {
00117 MSG_INF("Couldn't register Disc signal handler: %s: %s", error.name, error.message);
00118 goto error;
00119 }
00120
00121
00122 dbus_bus_add_match(dbus_connection,
00123 "type='signal',"
00124 "interface='" DBUS_INTERFACE_UDEV "',"
00125 "path='" DBUS_PATH_UDEV "'",
00126 &error);
00127 if (dbus_error_is_set(&error)) {
00128 MSG_INF("Couldn't register udev signal handler: %s: %s", error.name, error.message);
00129 goto error;
00130 }
00131
00132
00133 dbus_bus_add_match(dbus_connection,
00134 "type='signal',"
00135 "interface='" DBUS_INTERFACE_MNT_TTY "',"
00136 "path='" DBUS_PATH_MNT_TTY "'",
00137 &error);
00138 if (dbus_error_is_set(&error)) {
00139 MSG_INF("Couldn't register Tty signal handler: %s: %s", error.name, error.message);
00140 goto error;
00141 }
00142
00143
00144 dbus_connection_set_exit_on_disconnect(dbus_connection, FALSE);
00145
00146
00147 dbus_connection_setup_with_g_main(dbus_connection, NULL);
00148
00149 goto cleanup;
00150
00151 error:
00152 res = -1;
00153 mntd_dbus_quit();
00154
00155 cleanup:
00156 if (dbus_error_is_set(&error)) {
00157 dbus_error_free(&error);
00158 }
00159
00160 return res;
00161 }
00162
00163
00168 int
00169 mntd_dbus_quit(void)
00170 {
00171 if (dbus_connection != NULL) {
00172
00173
00174
00175 }
00176
00177 return 0;
00178 }
00179
00180
00187 void mntd_dbus_raise_no_such_device(DBusConnection* connection,
00188 DBusMessage* in_reply_to,
00189 const char* udi)
00190 {
00191 char buf[512];
00192 DBusMessage *reply;
00193
00194 snprintf(buf, 511, "No device with id %s", udi);
00195
00196
00197 reply = dbus_message_new_error(in_reply_to,
00198 DBUS_ERROR_NO_SUCH_DEVICE,
00199 buf);
00200 if (reply==NULL) {
00201 MSG_EMERG("Out of memory");
00202 return;
00203 }
00204 if (!dbus_connection_send(connection, reply, NULL)) {
00205 MSG_EMERG("Out of memory");
00206 return;
00207 }
00208 dbus_message_unref(reply);
00209 }
00210
00211
00219 void mntd_dbus_raise_syntax(DBusConnection* connection,
00220 DBusMessage* in_reply_to,
00221 const char* method_name)
00222 {
00223 char buf[512];
00224 DBusMessage *reply;
00225
00226 snprintf(buf, 511,
00227 "There is a syntax error in the invocation of "
00228 "the method %s", method_name);
00229
00230
00231 reply = dbus_message_new_error(in_reply_to,
00232 DBUS_ERROR_SYNTAX,
00233 buf);
00234 if (reply==NULL) {
00235 MSG_EMERG("Out of memory");
00236 return;
00237 }
00238 if (!dbus_connection_send(connection, reply, NULL)) {
00239 MSG_EMERG("Out of memory");
00240 return;
00241 }
00242 dbus_message_unref(reply);
00243 }
00244
00245
00252 void mntd_dbus_raise_no_mntpnt(DBusConnection* connection,
00253 DBusMessage* in_reply_to,
00254 const char* udi)
00255 {
00256 char buf[512];
00257 DBusMessage *reply;
00258
00259 snprintf(buf, 511,
00260 "No mount point for '%s' found.", udi);
00261
00262
00263 reply = dbus_message_new_error(in_reply_to,
00264 DBUS_ERROR_NO_MNTPNT,
00265 buf);
00266 if (reply==NULL) {
00267 MSG_EMERG("Out of memory");
00268 return;
00269 }
00270 if (!dbus_connection_send(connection, reply, NULL)) {
00271 MSG_EMERG("Out of memory");
00272 return;
00273 }
00274 dbus_message_unref(reply);
00275 }
00276
00277
00287 DBusHandlerResult mntd_dbus_manager_filter_function(DBusConnection* connection,
00288 DBusMessage* message,
00289 void* user_data)
00290 {
00291 PMNTDDATA pdata = (PMNTDDATA) user_data;
00292 g_assert(pdata!=NULL);
00293
00294
00295
00296
00297 if (dbus_message_is_method_call(message,
00298 DBUS_INTERFACE_MNT_MANAGER,
00299 "GetAllVolumes")) {
00300 MSG_DEBUG("biz.bambach.Mnt.Manager::GetAllVolumes() called");
00301 g_assert(pdata->vols!=NULL);
00302 return mntd_dbus_manager_get_all_volumes(pdata->vols, connection, message);
00303
00304 } else if (dbus_message_is_method_call(message,
00305 DBUS_INTERFACE_MNT_MANAGER,
00306 "GetMntPnt")) {
00307 MSG_DEBUG("biz.bambach.Mnt.Manager::GetMntPnt() called");
00308 g_assert(pdata->vols!=NULL);
00309 return mntd_dbus_manager_get_mntpnt(pdata->vols, connection, message);
00310
00311 } else if (dbus_message_is_method_call(message,
00312 DBUS_INTERFACE_MNT_MANAGER,
00313 "Remount")) {
00314 MSG_DEBUG("biz.bambach.Mnt.Manager::Remount() called");
00315 g_assert(pdata->vols!=NULL);
00316 return mntd_dbus_manager_remount(pdata->vols, connection, message);
00317
00318
00319
00320
00321 } else if (dbus_message_is_signal(message,
00322 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
00323 "Disconnected")) {
00324 const char *path = NULL;
00325 path = dbus_message_get_path(message);
00326 if (path != NULL) {
00327 if (strcmp(DBUS_PATH_ORG_FREEDESKTOP_LOCAL, path) == 0) {
00328 if (pdata->disconnect != NULL) {
00329 pdata->disconnect(pdata);
00330 }
00331 }
00332 }
00333
00334 dbus_connection_unref(connection);
00335
00336 return DBUS_HANDLER_RESULT_HANDLED;
00337
00338
00339
00340
00341 } else if (dbus_message_is_signal(message,
00342 DBUS_INTERFACE_MNT_BLOCK,
00343 "Add")) {
00344 char *devname = NULL;
00345 DBusError error;
00346 dbus_error_init(&error);
00347 if (dbus_message_get_args(message, &error,
00348 DBUS_TYPE_STRING, &devname,
00349 DBUS_TYPE_INVALID)) {
00350 MSG_DEBUG("Add('%s') called.", devname);
00351 g_assert(pdata->vols!=NULL);
00352 pdata->vols->add_volume(pdata->vols, devname);
00353 dbus_free(devname);
00354 }
00355
00356 } else if (dbus_message_is_signal(message,
00357 DBUS_INTERFACE_MNT_BLOCK,
00358 "Remove")) {
00359 char *devname = NULL;
00360 DBusError error;
00361 dbus_error_init(&error);
00362 if (dbus_message_get_args(message, &error,
00363 DBUS_TYPE_STRING, &devname,
00364 DBUS_TYPE_INVALID)) {
00365
00366 MSG_DEBUG("Remove('%s') called.", devname);
00367 g_assert(pdata->vols!=NULL);
00368 pdata->vols->remove_volume(pdata->vols, devname);
00369 dbus_free(devname);
00370 }
00371
00372
00373
00374
00375 } else if (dbus_message_is_signal(message,
00376 DBUS_INTERFACE_MNT_DISC,
00377 "Add")) {
00378 char *devname = NULL;
00379 DBusError error;
00380 dbus_error_init(&error);
00381 if (dbus_message_get_args(message, &error,
00382 DBUS_TYPE_STRING, &devname,
00383 DBUS_TYPE_INVALID)) {
00384 MSG_DEBUG("Add('%s') called.", devname);
00385 g_assert(pdata->vols!=NULL);
00386 pdata->vols->add_volume(pdata->vols, devname);
00387 dbus_free(devname);
00388 }
00389
00390 } else if (dbus_message_is_signal(message,
00391 DBUS_INTERFACE_MNT_DISC,
00392 "Remove")) {
00393 char *devname = NULL;
00394 DBusError error;
00395 dbus_error_init(&error);
00396 if (dbus_message_get_args(message, &error,
00397 DBUS_TYPE_STRING, &devname,
00398 DBUS_TYPE_INVALID)) {
00399
00400 MSG_DEBUG("Remove('%s') called.", devname);
00401 g_assert(pdata->vols!=NULL);
00402 pdata->vols->remove_volume(pdata->vols, devname);
00403 dbus_free(devname);
00404 }
00405
00406
00407
00408
00409 } else if (dbus_message_is_signal(message,
00410 DBUS_INTERFACE_MNT_TTY,
00411 "Add")) {
00412 char *devname = NULL;
00413 DBusError error;
00414 dbus_error_init(&error);
00415 if (dbus_message_get_args(message, &error,
00416 DBUS_TYPE_STRING, &devname,
00417 DBUS_TYPE_INVALID)) {
00418 MSG_DEBUG("Add('%s') called.", devname);
00419 dbus_free(devname);
00420 }
00421
00422 } else if (dbus_message_is_signal(message,
00423 DBUS_INTERFACE_MNT_TTY,
00424 "Remove")) {
00425 char *devname = NULL;
00426 DBusError error;
00427 dbus_error_init(&error);
00428 if (dbus_message_get_args(message, &error,
00429 DBUS_TYPE_STRING, &devname,
00430 DBUS_TYPE_INVALID)) {
00431 MSG_DEBUG("Remove('%s') called.", devname);
00432 dbus_free(devname);
00433 }
00434
00435 #ifdef DEBUG
00436 } else {
00437 int type;
00438 type = dbus_message_get_type(message);
00439 switch(type) {
00440 case DBUS_MESSAGE_TYPE_METHOD_CALL:
00441 MSG_DEBUG("DBUS_MESSAGE_TYPE_METHOD_CALL");
00442 break;
00443 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
00444 MSG_DEBUG("DBUS_MESSAGE_TYPE_METHOD_RETURN");
00445 break;
00446 case DBUS_MESSAGE_TYPE_ERROR:
00447 MSG_DEBUG("DBUS_MESSAGE_TYPE_ERROR");
00448 break;
00449 case DBUS_MESSAGE_TYPE_SIGNAL:
00450 MSG_DEBUG("DBUS_MESSAGE_TYPE_SIGNAL");
00451 break;
00452 case DBUS_MESSAGE_TYPE_INVALID:
00453 MSG_DEBUG("DBUS_MESSAGE_TYPE_INVALID");
00454 break;
00455 default:
00456 MSG_DEBUG("DBUS_MESSAGE_TYPE_ .... UNKNOWN");
00457 break;
00458 }
00459
00460 MSG_DEBUG("obj_path=%s interface=%s method=%s destination=%s sender=%s",
00461 dbus_message_get_path(message),
00462 dbus_message_get_interface(message),
00463 dbus_message_get_member(message),
00464 dbus_message_get_destination(message),
00465 dbus_message_get_sender(message)
00466 );
00467 #endif
00468
00469 }
00470
00471 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00472 }
00473
00474
00480 void
00481 mntd_dbus_manager_send_signal_volume_mounted(PVOLUME pv)
00482 {
00483 DBusMessage* message;
00484 DBusMessageIter it;
00485
00486
00487
00488 g_assert(pv!=NULL);
00489
00490 message = dbus_message_new_signal(
00491 DBUS_PATH_MNT_MANAGER,
00492 DBUS_INTERFACE_MNT_MANAGER,
00493 "VolumeMounted");
00494 if (message==NULL) {
00495 MSG_EMERG("Out of memory");
00496 return;
00497 }
00498
00499 dbus_message_iter_init(message, &it);
00500 dbus_message_iter_append_string(&it, pv->udi);
00501 dbus_message_iter_append_string(&it, pv->mntpnt);
00502
00503 if (!dbus_connection_send(dbus_connection, message, NULL)) {
00504 MSG_EMERG("error broadcasting message");
00505 }
00506
00507 dbus_message_unref(message);
00508 }
00509
00510
00516 void
00517 mntd_dbus_manager_send_signal_volume_unmounted(PVOLUME pv)
00518 {
00519 DBusMessage* message;
00520 DBusMessageIter it;
00521
00522
00523
00524 g_assert(pv!=NULL);
00525
00526 message = dbus_message_new_signal(
00527 DBUS_PATH_MNT_MANAGER,
00528 DBUS_INTERFACE_MNT_MANAGER,
00529 "VolumeUnmounted");
00530 if (message==NULL) {
00531 MSG_EMERG("Out of memory");
00532 return;
00533 }
00534
00535 dbus_message_iter_init(message, &it);
00536 dbus_message_iter_append_string(&it, pv->udi);
00537 dbus_message_iter_append_string(&it, pv->mntpnt);
00538
00539 if (!dbus_connection_send(dbus_connection, message, NULL)) {
00540 MSG_EMERG("error broadcasting message");
00541 }
00542
00543 dbus_message_unref(message);
00544 }
00545
00546
00553 int cb_append_udi(void *data, void *userdata)
00554 {
00555 DBusMessageIter *itarr = NULL;
00556 PHASHMAPELEMENT phme = NULL;
00557 PHASHMAP phm = NULL;
00558 PVOLUME pv = NULL;
00559 char *udi = NULL;
00560 void *hashdata = NULL;
00561
00562 if ((data==NULL) || (userdata==NULL)) {
00563 return -1;
00564 }
00565
00566
00567 itarr = (DBusMessageIter *) userdata;
00568
00569 phme = (PHASHMAPELEMENT) data;
00570
00571 phm = phme->phm;
00572
00573 udi = phme->key;
00574
00575 if (phm->get(phm, udi, &hashdata) == 0) {
00576 pv = (PVOLUME) hashdata;
00577 if (pv != NULL) {
00578
00579 if (pv->is_in_mntpath(pv)) {
00580
00581 dbus_message_iter_append_string(itarr, udi);
00582 return 0;
00583 }
00584 }
00585 }
00586
00587 return -1;
00588 }
00589
00590
00602 DBusHandlerResult
00603 mntd_dbus_manager_get_all_volumes( PVOLUMEMANAGER pvm,
00604 DBusConnection* connection,
00605 DBusMessage* message)
00606 {
00607 DBusMessage* reply;
00608 DBusMessageIter it;
00609 DBusMessageIter itarr;
00610 DBusHandlerResult res = DBUS_HANDLER_RESULT_HANDLED;
00611
00612 g_assert(pvm!=NULL);
00613
00614
00615 reply = dbus_message_new_method_return(message);
00616 if (reply==NULL) {
00617 MSG_EMERG("Out of memory");
00618 goto error;
00619 }
00620
00621
00622 dbus_message_iter_init(reply, &it);
00623 dbus_message_iter_append_array(&it, &itarr, DBUS_TYPE_STRING);
00624 pvm->foreach_mounted(pvm, cb_append_udi, &itarr);
00625
00626
00627 if(!dbus_connection_send(connection, reply, NULL)) {
00628 MSG_EMERG("Out of memory");
00629 goto error;
00630 }
00631
00632 goto cleanup;
00633
00634 error:
00635 res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00636
00637 cleanup:
00638 if (reply!=NULL) {
00639 dbus_message_unref(reply);
00640 }
00641
00642 return res;
00643 }
00644
00645
00657 DBusHandlerResult
00658 mntd_dbus_manager_get_mntpnt( PVOLUMEMANAGER pvm,
00659 DBusConnection* connection,
00660 DBusMessage* message)
00661 {
00662 DBusMessage *reply = NULL;
00663 DBusMessageIter it;
00664 DBusError error;
00665 DBusHandlerResult res = DBUS_HANDLER_RESULT_HANDLED;
00666 char *udi = NULL;
00667 char *mntpnt = NULL;
00668
00669 g_assert(pvm!=NULL);
00670
00671
00672 dbus_error_init(&error);
00673 if (!dbus_message_get_args(message, &error,
00674 DBUS_TYPE_STRING, &udi,
00675 DBUS_TYPE_INVALID) )
00676 {
00677 mntd_dbus_raise_syntax(connection, message, "Manager.GetMntPnt");
00678 goto error;
00679 }
00680
00681
00682 reply = dbus_message_new_method_return(message);
00683 if (reply==NULL) {
00684 MSG_EMERG("Out of memory");
00685 goto error;
00686 }
00687
00688
00689 dbus_message_iter_init(reply, &it);
00690 if (pvm->contains(pvm, udi)) {
00691 mntpnt = pvm->get_mntpnt(pvm, udi);
00692 if (mntpnt==NULL) {
00693 mntd_dbus_raise_no_mntpnt(connection, message, udi);
00694 goto error;
00695 }
00696 dbus_message_iter_append_string(&it, mntpnt);
00697 } else {
00698 mntd_dbus_raise_no_such_device(connection, message, udi);
00699 goto error;
00700 }
00701
00702
00703 if(!dbus_connection_send(connection, reply, NULL)) {
00704 MSG_EMERG("Out of memory");
00705 goto error;
00706 }
00707
00708 goto cleanup;
00709
00710 error:
00711 res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00712
00713 cleanup:
00714 if (reply!=NULL) {
00715 dbus_message_unref(reply);
00716 }
00717 if (udi!=NULL) {
00718 dbus_free(udi);
00719 }
00720 if (mntpnt!=NULL) {
00721 free(mntpnt);
00722 }
00723
00724 return res;
00725 }
00726
00727
00735 DBusHandlerResult
00736 mntd_dbus_manager_remount( PVOLUMEMANAGER pvm,
00737 DBusConnection* connection,
00738 DBusMessage* message)
00739 {
00740 DBusMessage *reply = NULL;
00741 DBusMessageIter it;
00742 DBusError error;
00743 DBusHandlerResult res = DBUS_HANDLER_RESULT_HANDLED;
00744 char *udi = NULL;
00745 int flag = 0;
00746 int ret = -1;
00747
00748 g_assert(pvm!=NULL);
00749
00750
00751 dbus_error_init(&error);
00752 if (!dbus_message_get_args(message, &error,
00753 DBUS_TYPE_STRING, &udi,
00754 DBUS_TYPE_INT32, &flag,
00755 DBUS_TYPE_INVALID) )
00756 {
00757 mntd_dbus_raise_syntax(connection, message, "Manager.Remount");
00758 goto error;
00759 }
00760
00761
00762 reply = dbus_message_new_method_return(message);
00763 if (reply==NULL) {
00764 MSG_EMERG("Out of memory");
00765 goto error;
00766 }
00767
00768
00769 dbus_message_iter_init(reply, &it);
00770 if (pvm->contains(pvm, udi)) {
00771 ret = pvm->remount(pvm, udi, flag);
00772 if (ret == -1) {
00773 mntd_dbus_raise_no_mntpnt(connection, message, udi);
00774 goto error;
00775 }
00776 dbus_message_iter_append_int32(&it, ret);
00777 } else {
00778 mntd_dbus_raise_no_such_device(connection, message, udi);
00779 goto error;
00780 }
00781
00782
00783 if(!dbus_connection_send(connection, reply, NULL)) {
00784 MSG_EMERG("Out of memory");
00785 goto error;
00786 }
00787
00788 goto cleanup;
00789
00790 error:
00791 res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00792
00793 cleanup:
00794 if (reply!=NULL) {
00795 dbus_message_unref(reply);
00796 }
00797 if (udi!=NULL) {
00798 dbus_free(udi);
00799 }
00800
00801 return res;
00802 }
00803
00804
00808
00809
00810
00811