1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-sysdeps.h Wrappers around system/libc features (internal to D-Bus implementation) 3 * 4 * Copyright (C) 2002, 2003 Red Hat, Inc. 5 * Copyright (C) 2003 CodeFactory AB 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #ifndef DBUS_SYSDEPS_H 26 #define DBUS_SYSDEPS_H 27 28 #include "config.h" 29 30 #ifdef HAVE_STDINT_H 31 #include <stdint.h> 32 #endif 33 34 #ifdef HAVE_INTTYPES_H 35 #include <inttypes.h> 36 #endif 37 38 #include <dbus/dbus-errors.h> 39 #include <dbus/dbus-file.h> 40 #include <dbus/dbus-string.h> 41 42 /* this is perhaps bogus, but strcmp() etc. are faster if we use the 43 * stuff straight out of string.h, so have this here for now. 44 */ 45 #include <string.h> 46 #include <stdarg.h> 47 48 /* AIX sys/poll.h does #define events reqevents, and other 49 * wonderousness, so must include sys/poll before declaring 50 * DBusPollFD 51 */ 52 #ifdef HAVE_POLL 53 #include <sys/poll.h> 54 #endif 55 56 #ifdef DBUS_WINCE 57 /* Windows CE lacks some system functions (such as errno and clock). 58 We bring them in here. */ 59 #include "dbus-sysdeps-wince-glue.h" 60 #endif 61 62 DBUS_BEGIN_DECLS 63 64 #ifdef DBUS_WIN 65 #define _DBUS_PATH_SEPARATOR ";" 66 #else 67 #define _DBUS_PATH_SEPARATOR ":" 68 #endif 69 70 /* Forward declarations */ 71 72 73 /** An opaque list type */ 74 typedef struct DBusList DBusList; 75 76 /** Object that contains a list of credentials such as UNIX or Windows user ID */ 77 typedef struct DBusCredentials DBusCredentials; 78 79 /** A wrapper around a pipe descriptor or handle */ 80 typedef struct DBusPipe DBusPipe; 81 82 /** 83 * @addtogroup DBusSysdeps 84 * 85 * @{ 86 */ 87 88 void _dbus_abort (void) _DBUS_GNUC_NORETURN; 89 90 dbus_bool_t _dbus_check_setuid (void); 91 const char* _dbus_getenv (const char *varname); 92 dbus_bool_t _dbus_setenv (const char *varname, 93 const char *value); 94 dbus_bool_t _dbus_clearenv (void); 95 char ** _dbus_get_environment (void); 96 97 /** A process ID */ 98 typedef unsigned long dbus_pid_t; 99 /** A user ID */ 100 typedef unsigned long dbus_uid_t; 101 /** A group ID */ 102 typedef unsigned long dbus_gid_t; 103 104 /** an invalid PID used to represent an uninitialized dbus_pid_t field */ 105 #define DBUS_PID_UNSET ((dbus_pid_t) -1) 106 /** an invalid UID used to represent an uninitialized dbus_uid_t field */ 107 #define DBUS_UID_UNSET ((dbus_uid_t) -1) 108 /** an invalid GID used to represent an uninitialized dbus_gid_t field */ 109 #define DBUS_GID_UNSET ((dbus_gid_t) -1) 110 111 /** an appropriate printf format for dbus_pid_t */ 112 #define DBUS_PID_FORMAT "%lu" 113 /** an appropriate printf format for dbus_uid_t */ 114 #define DBUS_UID_FORMAT "%lu" 115 /** an appropriate printf format for dbus_gid_t */ 116 #define DBUS_GID_FORMAT "%lu" 117 118 119 /** 120 * Socket interface 121 * 122 * @todo Use for the file descriptors a struct 123 * - struct DBusSocket{ int d; }; - 124 * instead of int to get type-safety which 125 * will be checked by the compiler. 126 * 127 */ 128 129 dbus_bool_t _dbus_close_socket (int fd, 130 DBusError *error); 131 int _dbus_read_socket (int fd, 132 DBusString *buffer, 133 int count); 134 int _dbus_write_socket (int fd, 135 const DBusString *buffer, 136 int start, 137 int len); 138 int _dbus_write_socket_two (int fd, 139 const DBusString *buffer1, 140 int start1, 141 int len1, 142 const DBusString *buffer2, 143 int start2, 144 int len2); 145 146 int _dbus_read_socket_with_unix_fds (int fd, 147 DBusString *buffer, 148 int count, 149 int *fds, 150 int *n_fds); 151 int _dbus_write_socket_with_unix_fds (int fd, 152 const DBusString *buffer, 153 int start, 154 int len, 155 const int *fds, 156 int n_fds); 157 int _dbus_write_socket_with_unix_fds_two (int fd, 158 const DBusString *buffer1, 159 int start1, 160 int len1, 161 const DBusString *buffer2, 162 int start2, 163 int len2, 164 const int *fds, 165 int n_fds); 166 167 dbus_bool_t _dbus_socket_is_invalid (int fd); 168 169 int _dbus_connect_tcp_socket (const char *host, 170 const char *port, 171 const char *family, 172 DBusError *error); 173 int _dbus_connect_tcp_socket_with_nonce (const char *host, 174 const char *port, 175 const char *family, 176 const char *noncefile, 177 DBusError *error); 178 int _dbus_listen_tcp_socket (const char *host, 179 const char *port, 180 const char *family, 181 DBusString *retport, 182 int **fds_p, 183 DBusError *error); 184 int _dbus_accept (int listen_fd); 185 186 187 dbus_bool_t _dbus_read_credentials_socket (int client_fd, 188 DBusCredentials *credentials, 189 DBusError *error); 190 dbus_bool_t _dbus_send_credentials_socket (int server_fd, 191 DBusError *error); 192 193 dbus_bool_t _dbus_credentials_add_from_user (DBusCredentials *credentials, 194 const DBusString *username); 195 dbus_bool_t _dbus_credentials_add_from_current_process (DBusCredentials *credentials); 196 dbus_bool_t _dbus_append_user_from_current_process (DBusString *str); 197 198 dbus_bool_t _dbus_parse_unix_user_from_config (const DBusString *username, 199 dbus_uid_t *uid_p); 200 dbus_bool_t _dbus_parse_unix_group_from_config (const DBusString *groupname, 201 dbus_gid_t *gid_p); 202 dbus_bool_t _dbus_unix_groups_from_uid (dbus_uid_t uid, 203 dbus_gid_t **group_ids, 204 int *n_group_ids); 205 dbus_bool_t _dbus_unix_user_is_at_console (dbus_uid_t uid, 206 DBusError *error); 207 dbus_bool_t _dbus_unix_user_is_process_owner (dbus_uid_t uid); 208 dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid); 209 210 dbus_bool_t _dbus_append_keyring_directory_for_credentials (DBusString *directory, 211 DBusCredentials *credentials); 212 213 dbus_bool_t _dbus_daemon_is_session_bus_address_published (const char *scope); 214 215 dbus_bool_t _dbus_daemon_publish_session_bus_address (const char* address, const char* shm_name); 216 217 void _dbus_daemon_unpublish_session_bus_address (void); 218 219 dbus_bool_t _dbus_socket_can_pass_unix_fd(int fd); 220 221 /** Opaque type representing an atomically-modifiable integer 222 * that can be used from multiple threads. 223 */ 224 typedef struct DBusAtomic DBusAtomic; 225 226 /** 227 * An atomic integer safe to increment or decrement from multiple threads. 228 */ 229 struct DBusAtomic 230 { 231 #ifdef DBUS_WIN 232 volatile long value; /**< Value of the atomic integer. */ 233 #else 234 volatile dbus_int32_t value; /**< Value of the atomic integer. */ 235 #endif 236 }; 237 238 /* The value we get from autofoo is in the form of a cpp expression; 239 * convert that to a conventional defined/undef switch. (We can't get 240 * the conventional defined/undef because of multiarch builds only running 241 * ./configure once, on Darwin.) */ 242 #if DBUS_HAVE_ATOMIC_INT_COND 243 # define DBUS_HAVE_ATOMIC_INT 1 244 #else 245 # undef DBUS_HAVE_ATOMIC_INT 246 #endif 247 248 dbus_int32_t _dbus_atomic_inc (DBusAtomic *atomic); 249 dbus_int32_t _dbus_atomic_dec (DBusAtomic *atomic); 250 dbus_int32_t _dbus_atomic_get (DBusAtomic *atomic); 251 252 253 /* AIX uses different values for poll */ 254 255 #ifdef _AIX 256 /** There is data to read */ 257 #define _DBUS_POLLIN 0x0001 258 /** There is urgent data to read */ 259 #define _DBUS_POLLPRI 0x0004 260 /** Writing now will not block */ 261 #define _DBUS_POLLOUT 0x0002 262 /** Error condition */ 263 #define _DBUS_POLLERR 0x4000 264 /** Hung up */ 265 #define _DBUS_POLLHUP 0x2000 266 /** Invalid request: fd not open */ 267 #define _DBUS_POLLNVAL 0x8000 268 #elif defined(__HAIKU__) 269 /** There is data to read */ 270 #define _DBUS_POLLIN 0x0001 271 /** Writing now will not block */ 272 #define _DBUS_POLLOUT 0x0002 273 /** Error condition */ 274 #define _DBUS_POLLERR 0x0004 275 /** There is urgent data to read */ 276 #define _DBUS_POLLPRI 0x0020 277 /** Hung up */ 278 #define _DBUS_POLLHUP 0x0080 279 /** Invalid request: fd not open */ 280 #define _DBUS_POLLNVAL 0x1000 281 #else 282 /** There is data to read */ 283 #define _DBUS_POLLIN 0x0001 284 /** There is urgent data to read */ 285 #define _DBUS_POLLPRI 0x0002 286 /** Writing now will not block */ 287 #define _DBUS_POLLOUT 0x0004 288 /** Error condition */ 289 #define _DBUS_POLLERR 0x0008 290 /** Hung up */ 291 #define _DBUS_POLLHUP 0x0010 292 /** Invalid request: fd not open */ 293 #define _DBUS_POLLNVAL 0x0020 294 #endif 295 296 /** 297 * A portable struct pollfd wrapper. 298 */ 299 typedef struct 300 { 301 int fd; /**< File descriptor */ 302 short events; /**< Events to poll for */ 303 short revents; /**< Events that occurred */ 304 } DBusPollFD; 305 306 int _dbus_poll (DBusPollFD *fds, 307 int n_fds, 308 int timeout_milliseconds); 309 310 void _dbus_sleep_milliseconds (int milliseconds); 311 312 void _dbus_get_monotonic_time (long *tv_sec, 313 long *tv_usec); 314 315 void _dbus_get_real_time (long *tv_sec, 316 long *tv_usec); 317 318 /** 319 * directory interface 320 */ 321 dbus_bool_t _dbus_create_directory (const DBusString *filename, 322 DBusError *error); 323 dbus_bool_t _dbus_delete_directory (const DBusString *filename, 324 DBusError *error); 325 326 dbus_bool_t _dbus_concat_dir_and_file (DBusString *dir, 327 const DBusString *next_component); 328 dbus_bool_t _dbus_string_get_dirname (const DBusString *filename, 329 DBusString *dirname); 330 dbus_bool_t _dbus_path_is_absolute (const DBusString *filename); 331 332 dbus_bool_t _dbus_get_standard_session_servicedirs (DBusList **dirs); 333 dbus_bool_t _dbus_get_standard_system_servicedirs (DBusList **dirs); 334 335 dbus_bool_t _dbus_append_system_config_file (DBusString *str); 336 dbus_bool_t _dbus_append_session_config_file (DBusString *str); 337 338 /** Opaque type for reading a directory listing */ 339 typedef struct DBusDirIter DBusDirIter; 340 341 DBusDirIter* _dbus_directory_open (const DBusString *filename, 342 DBusError *error); 343 dbus_bool_t _dbus_directory_get_next_file (DBusDirIter *iter, 344 DBusString *filename, 345 DBusError *error); 346 void _dbus_directory_close (DBusDirIter *iter); 347 348 dbus_bool_t _dbus_check_dir_is_private_to_user (DBusString *dir, 349 DBusError *error); 350 351 void _dbus_fd_set_close_on_exec (intptr_t fd); 352 353 const char* _dbus_get_tmpdir (void); 354 355 /** 356 * Random numbers 357 */ 358 void _dbus_generate_pseudorandom_bytes_buffer (char *buffer, 359 int n_bytes); 360 void _dbus_generate_random_bytes_buffer (char *buffer, 361 int n_bytes); 362 dbus_bool_t _dbus_generate_random_bytes (DBusString *str, 363 int n_bytes); 364 dbus_bool_t _dbus_generate_random_ascii (DBusString *str, 365 int n_bytes); 366 367 const char* _dbus_error_from_errno (int error_number); 368 const char* _dbus_error_from_system_errno (void); 369 370 void _dbus_set_errno_to_zero (void); 371 dbus_bool_t _dbus_get_is_errno_nonzero (void); 372 dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock (void); 373 dbus_bool_t _dbus_get_is_errno_enomem (void); 374 dbus_bool_t _dbus_get_is_errno_eintr (void); 375 dbus_bool_t _dbus_get_is_errno_epipe (void); 376 const char* _dbus_strerror_from_errno (void); 377 378 void _dbus_disable_sigpipe (void); 379 380 381 void _dbus_exit (int code) _DBUS_GNUC_NORETURN; 382 383 int _dbus_printf_string_upper_bound (const char *format, 384 va_list args); 385 386 387 /** 388 * Portable struct with stat() results 389 */ 390 typedef struct 391 { 392 unsigned long mode; /**< File mode */ 393 unsigned long nlink; /**< Number of hard links */ 394 dbus_uid_t uid; /**< User owning file */ 395 dbus_gid_t gid; /**< Group owning file */ 396 unsigned long size; /**< Size of file */ 397 unsigned long atime; /**< Access time */ 398 unsigned long mtime; /**< Modify time */ 399 unsigned long ctime; /**< Creation time */ 400 } DBusStat; 401 402 dbus_bool_t _dbus_stat (const DBusString *filename, 403 DBusStat *statbuf, 404 DBusError *error); 405 dbus_bool_t _dbus_full_duplex_pipe (int *fd1, 406 int *fd2, 407 dbus_bool_t blocking, 408 DBusError *error); 409 410 void _dbus_print_backtrace (void); 411 412 dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, 413 DBusPipe *print_pid_pipe, 414 DBusError *error, 415 dbus_bool_t keep_umask); 416 417 dbus_bool_t _dbus_verify_daemon_user (const char *user); 418 dbus_bool_t _dbus_change_to_daemon_user (const char *user, 419 DBusError *error); 420 421 dbus_bool_t _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile, 422 DBusPipe *print_pid_pipe, 423 dbus_pid_t pid_to_write, 424 DBusError *error); 425 426 dbus_bool_t _dbus_command_for_pid (unsigned long pid, 427 DBusString *str, 428 int max_len, 429 DBusError *error); 430 431 /** A UNIX signal handler */ 432 typedef void (* DBusSignalHandler) (int sig); 433 434 void _dbus_set_signal_handler (int sig, 435 DBusSignalHandler handler); 436 437 dbus_bool_t _dbus_user_at_console (const char *username, 438 DBusError *error); 439 440 void _dbus_init_system_log (void); 441 442 typedef enum { 443 DBUS_SYSTEM_LOG_INFO, 444 DBUS_SYSTEM_LOG_SECURITY, 445 DBUS_SYSTEM_LOG_FATAL 446 } DBusSystemLogSeverity; 447 448 void _dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...) _DBUS_GNUC_PRINTF (2, 3); 449 void _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args); 450 451 /* Define DBUS_VA_COPY() to do the right thing for copying va_list variables. 452 * config.h may have already defined DBUS_VA_COPY as va_copy or __va_copy. 453 */ 454 #if !defined (DBUS_VA_COPY) 455 # if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32)) 456 # define DBUS_VA_COPY(ap1, ap2) (*(ap1) = *(ap2)) 457 # elif defined (DBUS_VA_COPY_AS_ARRAY) 458 # define DBUS_VA_COPY(ap1, ap2) memcpy ((ap1), (ap2), sizeof (va_list)) 459 # else /* va_list is a pointer */ 460 # define DBUS_VA_COPY(ap1, ap2) ((ap1) = (ap2)) 461 # endif /* va_list is a pointer */ 462 #endif /* !DBUS_VA_COPY */ 463 464 465 /** 466 * Casts a primitive C type to a byte array and then indexes 467 * a particular byte of the array. 468 */ 469 #define _DBUS_BYTE_OF_PRIMITIVE(p, i) \ 470 (((const char*)&(p))[(i)]) 471 /** On x86 there is an 80-bit FPU, and if you do "a == b" it may have a 472 * or b in an 80-bit register, thus failing to compare the two 64-bit 473 * doubles for bitwise equality. So this macro compares the two doubles 474 * bitwise. 475 */ 476 #define _DBUS_DOUBLES_BITWISE_EQUAL(a, b) \ 477 (_DBUS_BYTE_OF_PRIMITIVE (a, 0) == _DBUS_BYTE_OF_PRIMITIVE (b, 0) && \ 478 _DBUS_BYTE_OF_PRIMITIVE (a, 1) == _DBUS_BYTE_OF_PRIMITIVE (b, 1) && \ 479 _DBUS_BYTE_OF_PRIMITIVE (a, 2) == _DBUS_BYTE_OF_PRIMITIVE (b, 2) && \ 480 _DBUS_BYTE_OF_PRIMITIVE (a, 3) == _DBUS_BYTE_OF_PRIMITIVE (b, 3) && \ 481 _DBUS_BYTE_OF_PRIMITIVE (a, 4) == _DBUS_BYTE_OF_PRIMITIVE (b, 4) && \ 482 _DBUS_BYTE_OF_PRIMITIVE (a, 5) == _DBUS_BYTE_OF_PRIMITIVE (b, 5) && \ 483 _DBUS_BYTE_OF_PRIMITIVE (a, 6) == _DBUS_BYTE_OF_PRIMITIVE (b, 6) && \ 484 _DBUS_BYTE_OF_PRIMITIVE (a, 7) == _DBUS_BYTE_OF_PRIMITIVE (b, 7)) 485 486 dbus_bool_t _dbus_get_autolaunch_address (const char *scope, 487 DBusString *address, 488 DBusError *error); 489 490 dbus_bool_t _dbus_lookup_session_address (dbus_bool_t *supported, 491 DBusString *address, 492 DBusError *error); 493 494 /** Type representing a universally unique ID 495 * @todo rename to UUID instead of GUID 496 */ 497 typedef union DBusGUID DBusGUID; 498 499 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id, 500 dbus_bool_t create_if_not_found, 501 DBusError *error); 502 503 /** 504 * Initialize threads as in dbus_threads_init_default(), appropriately 505 * for the platform. 506 * @returns #FALSE if no memory 507 */ 508 dbus_bool_t _dbus_threads_init_platform_specific (void); 509 510 dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs, 511 const char *suffix, 512 DBusList **dir_list); 513 514 unsigned long _dbus_pid_for_log (void); 515 516 /* FIXME move back to dbus-sysdeps-unix.h probably - 517 * the PID file handling just needs a little more abstraction 518 * in the bus daemon first. 519 */ 520 dbus_pid_t _dbus_getpid (void); 521 522 dbus_bool_t _dbus_change_to_daemon_user (const char *user, 523 DBusError *error); 524 525 void _dbus_flush_caches (void); 526 527 void _dbus_request_file_descriptor_limit (unsigned int limit); 528 529 /* 530 * replaces the term DBUS_PREFIX in configure_time_path by the 531 * current dbus installation directory. On unix this function is a noop 532 * 533 * @param configure_time_path 534 * @return real path 535 */ 536 const char * 537 _dbus_replace_install_prefix (const char *configure_time_path); 538 539 /** @} */ 540 541 DBUS_END_DECLS 542 543 544 #ifdef DBUS_WIN 545 #include "dbus-sysdeps-win.h" 546 #endif 547 548 #endif /* DBUS_SYSDEPS_H */ 549