From 635192121c974189c8bfc759f473b88d291747f2 Mon Sep 17 00:00:00 2001 From: Thomas A Date: Sat, 23 Apr 2022 14:13:03 -0700 Subject: [PATCH 1/3] Remove `libnotify` From Main Repo The code will be transfered to a dedicated repo. --- src/libnotify/APPLE_LICENSE | 372 -- src/libnotify/CMakeLists.txt | 47 - .../Libnotify.xcodeproj/project.pbxproj | 1241 ----- .../xcshareddata/xcschemes/xctests.xcscheme | 72 - src/libnotify/libnotify.c | 1098 ----- src/libnotify/libnotify.h | 226 - src/libnotify/notify.3 | 472 -- src/libnotify/notify.h | 344 -- src/libnotify/notify_cancel.3 | 1 - src/libnotify/notify_check.3 | 1 - src/libnotify/notify_client.c | 4148 ----------------- src/libnotify/notify_get_state.3 | 1 - src/libnotify/notify_internal.h | 153 - src/libnotify/notify_ipc.defs | 261 -- src/libnotify/notify_is_valid_token.3 | 1 - src/libnotify/notify_keys.h | 83 - src/libnotify/notify_post.3 | 1 - src/libnotify/notify_private.h | 70 - src/libnotify/notify_probes.d | 7 - src/libnotify/notify_probes.h | 16 - src/libnotify/notify_register_check.3 | 1 - src/libnotify/notify_register_dispatch.3 | 1 - .../notify_register_file_descriptor.3 | 1 - src/libnotify/notify_register_mach_port.3 | 1 - src/libnotify/notify_register_signal.3 | 1 - src/libnotify/notify_set_state.3 | 1 - src/libnotify/notifybench/notify_bench.c | 451 -- src/libnotify/notifyd/CMakeLists.txt | 30 - src/libnotify/notifyd/com.apple.notifyd.plist | 33 - src/libnotify/notifyd/com.apple.notifyd.sb | 24 - src/libnotify/notifyd/notify.conf.MacOSX | 11 - .../notifyd/notify.conf.iOSSimulator | 5 - src/libnotify/notifyd/notify.conf.iPhone | 9 - src/libnotify/notifyd/notify.defs | 1 - src/libnotify/notifyd/notify_ipc.defs | 1 - src/libnotify/notifyd/notify_proc.c | 1350 ------ src/libnotify/notifyd/notifyd.8 | 68 - src/libnotify/notifyd/notifyd.c | 1436 ------ src/libnotify/notifyd/notifyd.h | 119 - src/libnotify/notifyd/pathwatch.c | 947 ---- src/libnotify/notifyd/pathwatch.h | 84 - src/libnotify/notifyd/service.c | 564 --- src/libnotify/notifyd/service.h | 50 - src/libnotify/notifyd/timer.c | 409 -- src/libnotify/notifyd/timer.h | 56 - .../notifyd/xcodescripts/mk_notify_conf.sh | 6 - src/libnotify/notifyutil/notifyutil.1 | 220 - src/libnotify/notifyutil/notifyutil.c | 755 --- .../notifyutil/notifyutil_entitlements.plist | 8 - src/libnotify/table.c | 124 - src/libnotify/table.h | 68 - src/libnotify/table.in.c | 209 - src/libnotify/xcodeconfig/base.xcconfig | 33 - src/libnotify/xcodeconfig/libnotify.xcconfig | 35 - src/libnotify/xcodeconfig/notifyd.xcconfig | 11 - src/libnotify/xcodeconfig/notifyutil.xcconfig | 4 - src/libnotify/xcodescripts/no-sim-man.sh | 5 - .../xcodescripts/sim-compat-symlink.sh | 5 - src/libnotify/xctests/Info.plist | 22 - src/libnotify/xctests/RegisterTests.m | 162 - 60 files changed, 15936 deletions(-) delete mode 100644 src/libnotify/APPLE_LICENSE delete mode 100644 src/libnotify/CMakeLists.txt delete mode 100644 src/libnotify/Libnotify.xcodeproj/project.pbxproj delete mode 100644 src/libnotify/Libnotify.xcodeproj/xcshareddata/xcschemes/xctests.xcscheme delete mode 100644 src/libnotify/libnotify.c delete mode 100644 src/libnotify/libnotify.h delete mode 100644 src/libnotify/notify.3 delete mode 100644 src/libnotify/notify.h delete mode 100644 src/libnotify/notify_cancel.3 delete mode 100644 src/libnotify/notify_check.3 delete mode 100644 src/libnotify/notify_client.c delete mode 100644 src/libnotify/notify_get_state.3 delete mode 100644 src/libnotify/notify_internal.h delete mode 100644 src/libnotify/notify_ipc.defs delete mode 100644 src/libnotify/notify_is_valid_token.3 delete mode 100644 src/libnotify/notify_keys.h delete mode 100644 src/libnotify/notify_post.3 delete mode 100644 src/libnotify/notify_private.h delete mode 100644 src/libnotify/notify_probes.d delete mode 100644 src/libnotify/notify_probes.h delete mode 100644 src/libnotify/notify_register_check.3 delete mode 100644 src/libnotify/notify_register_dispatch.3 delete mode 100644 src/libnotify/notify_register_file_descriptor.3 delete mode 100644 src/libnotify/notify_register_mach_port.3 delete mode 100644 src/libnotify/notify_register_signal.3 delete mode 100644 src/libnotify/notify_set_state.3 delete mode 100644 src/libnotify/notifybench/notify_bench.c delete mode 100644 src/libnotify/notifyd/CMakeLists.txt delete mode 100644 src/libnotify/notifyd/com.apple.notifyd.plist delete mode 100644 src/libnotify/notifyd/com.apple.notifyd.sb delete mode 100644 src/libnotify/notifyd/notify.conf.MacOSX delete mode 100644 src/libnotify/notifyd/notify.conf.iOSSimulator delete mode 100644 src/libnotify/notifyd/notify.conf.iPhone delete mode 120000 src/libnotify/notifyd/notify.defs delete mode 120000 src/libnotify/notifyd/notify_ipc.defs delete mode 100644 src/libnotify/notifyd/notify_proc.c delete mode 100644 src/libnotify/notifyd/notifyd.8 delete mode 100644 src/libnotify/notifyd/notifyd.c delete mode 100644 src/libnotify/notifyd/notifyd.h delete mode 100644 src/libnotify/notifyd/pathwatch.c delete mode 100644 src/libnotify/notifyd/pathwatch.h delete mode 100644 src/libnotify/notifyd/service.c delete mode 100644 src/libnotify/notifyd/service.h delete mode 100644 src/libnotify/notifyd/timer.c delete mode 100644 src/libnotify/notifyd/timer.h delete mode 100644 src/libnotify/notifyd/xcodescripts/mk_notify_conf.sh delete mode 100644 src/libnotify/notifyutil/notifyutil.1 delete mode 100644 src/libnotify/notifyutil/notifyutil.c delete mode 100644 src/libnotify/notifyutil/notifyutil_entitlements.plist delete mode 100644 src/libnotify/table.c delete mode 100644 src/libnotify/table.h delete mode 100644 src/libnotify/table.in.c delete mode 100644 src/libnotify/xcodeconfig/base.xcconfig delete mode 100644 src/libnotify/xcodeconfig/libnotify.xcconfig delete mode 100644 src/libnotify/xcodeconfig/notifyd.xcconfig delete mode 100644 src/libnotify/xcodeconfig/notifyutil.xcconfig delete mode 100644 src/libnotify/xcodescripts/no-sim-man.sh delete mode 100644 src/libnotify/xcodescripts/sim-compat-symlink.sh delete mode 100644 src/libnotify/xctests/Info.plist delete mode 100644 src/libnotify/xctests/RegisterTests.m diff --git a/src/libnotify/APPLE_LICENSE b/src/libnotify/APPLE_LICENSE deleted file mode 100644 index 84687a44b..000000000 --- a/src/libnotify/APPLE_LICENSE +++ /dev/null @@ -1,372 +0,0 @@ -APPLE PUBLIC SOURCE LICENSE -Version 1.1 - April 19,1999 - -Please read this License carefully before downloading this software. -By downloading and using this software, you are agreeing to be bound -by the terms of this License. If you do not or cannot agree to the -terms of this License, please do not download or use the software. - -1. General; Definitions. This License applies to any program or other -work which Apple Computer, Inc. ("Apple") publicly announces as -subject to this Apple Public Source License and which contains a -notice placed by Apple identifying such program or work as "Original -Code" and stating that it is subject to the terms of this Apple Public -Source License version 1.1 (or subsequent version thereof), as it may -be revised from time to time by Apple ("License"). As used in this -License: - -1.1 "Affected Original Code" means only those specific portions of -Original Code that allegedly infringe upon any party's intellectual -property rights or are otherwise the subject of a claim of -infringement. - -1.2 "Applicable Patent Rights" mean: (a) in the case where Apple is -the grantor of rights, (i) claims of patents that are now or hereafter -acquired, owned by or assigned to Apple and (ii) that cover subject -matter contained in the Original Code, but only to the extent -necessary to use, reproduce and/or distribute the Original Code -without infringement; and (b) in the case where You are the grantor of -rights, (i) claims of patents that are now or hereafter acquired, -owned by or assigned to You and (ii) that cover subject matter in Your -Modifications, taken alone or in combination with Original Code. - -1.3 "Covered Code" means the Original Code, Modifications, the -combination of Original Code and any Modifications, and/or any -respective portions thereof. - -1.4 "Deploy" means to use, sublicense or distribute Covered Code other -than for Your internal research and development (R&D), and includes -without limitation, any and all internal use or distribution of -Covered Code within Your business or organization except for R&D use, -as well as direct or indirect sublicensing or distribution of Covered -Code by You to any third party in any form or manner. - -1.5 "Larger Work" means a work which combines Covered Code or portions -thereof with code not governed by the terms of this License. - -1.6 "Modifications" mean any addition to, deletion from, and/or change -to, the substance and/or structure of Covered Code. When code is -released as a series of files, a Modification is: (a) any addition to -or deletion from the contents of a file containing Covered Code; -and/or (b) any new file or other representation of computer program -statements that contains any part of Covered Code. - -1.7 "Original Code" means (a) the Source Code of a program or other -work as originally made available by Apple under this License, -including the Source Code of any updates or upgrades to such programs -or works made available by Apple under this License, and that has been -expressly identified by Apple as such in the header file(s) of such -work; and (b) the object code compiled from such Source Code and -originally made available by Apple under this License. - -1.8 "Source Code" means the human readable form of a program or other -work that is suitable for making modifications to it, including all -modules it contains, plus any associated interface definition files, -scripts used to control compilation and installation of an executable -(object code). - -1.9 "You" or "Your" means an individual or a legal entity exercising -rights under this License. For legal entities, "You" or "Your" -includes any entity which controls, is controlled by, or is under -common control with, You, where "control" means (a) the power, direct -or indirect, to cause the direction or management of such entity, -whether by contract or otherwise, or (b) ownership of fifty percent -(50%) or more of the outstanding shares or beneficial ownership of -such entity. - -2. Permitted Uses; Conditions & Restrictions. Subject to the terms -and conditions of this License, Apple hereby grants You, effective on -the date You accept this License and download the Original Code, a -world-wide, royalty-free, non- exclusive license, to the extent of -Apple's Applicable Patent Rights and copyrights covering the Original -Code, to do the following: - -2.1 You may use, copy, modify and distribute Original Code, with or -without Modifications, solely for Your internal research and -development, provided that You must in each instance: - -(a) retain and reproduce in all copies of Original Code the copyright -and other proprietary notices and disclaimers of Apple as they appear -in the Original Code, and keep intact all notices in the Original Code -that refer to this License; - -(b) include a copy of this License with every copy of Source Code of -Covered Code and documentation You distribute, and You may not offer -or impose any terms on such Source Code that alter or restrict this -License or the recipients' rights hereunder, except as permitted under -Section 6; and - -(c) completely and accurately document all Modifications that you have -made and the date of each such Modification, designate the version of -the Original Code you used, prominently include a file carrying such -information with the Modifications, and duplicate the notice in -Exhibit A in each file of the Source Code of all such Modifications. - -2.2 You may Deploy Covered Code, provided that You must in each - instance: - -(a) satisfy all the conditions of Section 2.1 with respect to the -Source Code of the Covered Code; - -(b) make all Your Deployed Modifications publicly available in Source -Code form via electronic distribution (e.g. download from a web site) -under the terms of this License and subject to the license grants set -forth in Section 3 below, and any additional terms You may choose to -offer under Section 6. You must continue to make the Source Code of -Your Deployed Modifications available for as long as you Deploy the -Covered Code or twelve (12) months from the date of initial -Deployment, whichever is longer; - -(c) if You Deploy Covered Code containing Modifications made by You, -inform others of how to obtain those Modifications by filling out and -submitting the information found at -http://www.apple.com/publicsource/modifications.html, if available; -and - -(d) if You Deploy Covered Code in object code, executable form only, -include a prominent notice, in the code itself as well as in related -documentation, stating that Source Code of the Covered Code is -available under the terms of this License with information on how and -where to obtain such Source Code. - -3. Your Grants. In consideration of, and as a condition to, the -licenses granted to You under this License: - -(a) You hereby grant to Apple and all third parties a non-exclusive, -royalty-free license, under Your Applicable Patent Rights and other -intellectual property rights owned or controlled by You, to use, -reproduce, modify, distribute and Deploy Your Modifications of the -same scope and extent as Apple's licenses under Sections 2.1 and 2.2; -and - -(b) You hereby grant to Apple and its subsidiaries a non-exclusive, -worldwide, royalty-free, perpetual and irrevocable license, under Your -Applicable Patent Rights and other intellectual property rights owned -or controlled by You, to use, reproduce, execute, compile, display, -perform, modify or have modified (for Apple and/or its subsidiaries), -sublicense and distribute Your Modifications, in any form, through -multiple tiers of distribution. - -4. Larger Works. You may create a Larger Work by combining Covered -Code with other code not governed by the terms of this License and -distribute the Larger Work as a single product. In each such -instance, You must make sure the requirements of this License are -fulfilled for the Covered Code or any portion thereof. - -5. Limitations on Patent License. Except as expressly stated in -Section 2, no other patent rights, express or implied, are granted by -Apple herein. Modifications and/or Larger Works may require -additional patent licenses from Apple which Apple may grant in its -sole discretion. - -6. Additional Terms. You may choose to offer, and to charge a fee -for, warranty, support, indemnity or liability obligations and/or -other rights consistent with the scope of the license granted herein -("Additional Terms") to one or more recipients of Covered -Code. However, You may do so only on Your own behalf and as Your sole -responsibility, and not on behalf of Apple. You must obtain the -recipient's agreement that any such Additional Terms are offered by -You alone, and You hereby agree to indemnify, defend and hold Apple -harmless for any liability incurred by or claims asserted against -Apple by reason of any such Additional Terms. - -7. Versions of the License. Apple may publish revised and/or new -versions of this License from time to time. Each version will be -given a distinguishing version number. Once Original Code has been -published under a particular version of this License, You may continue -to use it under the terms of that version. You may also choose to use -such Original Code under the terms of any subsequent version of this -License published by Apple. No one other than Apple has the right to -modify the terms applicable to Covered Code created under this -License. - -8. NO WARRANTY OR SUPPORT. The Original Code may contain in whole or -in part pre-release, untested, or not fully tested works. The -Original Code may contain errors that could cause failures or loss of -data, and may be incomplete or contain inaccuracies. You expressly -acknowledge and agree that use of the Original Code, or any portion -thereof, is at Your sole and entire risk. THE ORIGINAL CODE IS -PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND -AND APPLE AND APPLE'S LICENSOR(S) (FOR THE PURPOSES OF SECTIONS 8 AND -9, APPLE AND APPLE'S LICENSOR(S) ARE COLLECTIVELY REFERRED TO AS -"APPLE") EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -AND/OR CONDITIONS OF MERCHANTABILITY OR SATISFACTORY QUALITY AND -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY -RIGHTS. APPLE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE -ORIGINAL CODE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF -THE ORIGINAL CODE WILL BE UNINTERRUPTED OR ERROR- FREE, OR THAT -DEFECTS IN THE ORIGINAL CODE WILL BE CORRECTED. NO ORAL OR WRITTEN -INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED -REPRESENTATIVE SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE -SCOPE OF THIS WARRANTY. You acknowledge that the Original Code is not -intended for use in the operation of nuclear facilities, aircraft -navigation, communication systems, or air traffic control machines in -which case the failure of the Original Code could lead to death, -personal injury, or severe physical or environmental damage. - -9. Liability. - -9.1 Infringement. If any portion of, or functionality implemented by, -the Original Code becomes the subject of a claim of infringement, -Apple may, at its option: (a) attempt to procure the rights necessary -for Apple and You to continue using the Affected Original Code; (b) -modify the Affected Original Code so that it is no longer infringing; -or (c) suspend Your rights to use, reproduce, modify, sublicense and -distribute the Affected Original Code until a final determination of -the claim is made by a court or governmental administrative agency of -competent jurisdiction and Apple lifts the suspension as set forth -below. Such suspension of rights will be effective immediately upon -Apple's posting of a notice to such effect on the Apple web site that -is used for implementation of this License. Upon such final -determination being made, if Apple is legally able, without the -payment of a fee or royalty, to resume use, reproduction, -modification, sublicensing and distribution of the Affected Original -Code, Apple will lift the suspension of rights to the Affected -Original Code by posting a notice to such effect on the Apple web site -that is used for implementation of this License. If Apple suspends -Your rights to Affected Original Code, nothing in this License shall -be construed to restrict You, at Your option and subject to applicable -law, from replacing the Affected Original Code with non-infringing -code or independently negotiating for necessary rights from such third -party. - -9.2 LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES SHALL APPLE BE -LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES -ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO -USE THE ORIGINAL CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY -OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY -OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF -ANY REMEDY. In no event shall Apple's total liability to You for all -damages under this License exceed the amount of fifty dollars -($50.00). - -10. Trademarks. This License does not grant any rights to use the -trademarks or trade names "Apple", "Apple Computer", "Mac OS X", "Mac -OS X Server" or any other trademarks or trade names belonging to Apple -(collectively "Apple Marks") and no Apple Marks may be used to endorse -or promote products derived from the Original Code other than as -permitted by and in strict compliance at all times with Apple's third -party trademark usage guidelines which are posted at -http://www.apple.com/legal/guidelinesfor3rdparties.html. - -11. Ownership. Apple retains all rights, title and interest in and to -the Original Code and any Modifications made by or on behalf of Apple -("Apple Modifications"), and such Apple Modifications will not be -automatically subject to this License. Apple may, at its sole -discretion, choose to license such Apple Modifications under this -License, or on different terms from those contained in this License or -may choose not to license them at all. Apple's development, use, -reproduction, modification, sublicensing and distribution of Covered -Code will not be subject to this License. - -12. Termination. - -12.1 Termination. This License and the rights granted hereunder will - terminate: - -(a) automatically without notice from Apple if You fail to comply with -any term(s) of this License and fail to cure such breach within 30 -days of becoming aware of such breach; (b) immediately in the event of -the circumstances described in Section 13.5(b); or (c) automatically -without notice from Apple if You, at any time during the term of this -License, commence an action for patent infringement against Apple. - -12.2 Effect of Termination. Upon termination, You agree to -immediately stop any further use, reproduction, modification, -sublicensing and distribution of the Covered Code and to destroy all -copies of the Covered Code that are in your possession or control. -All sublicenses to the Covered Code which have been properly granted -prior to termination shall survive any termination of this License. -Provisions which, by their nature, should remain in effect beyond the -termination of this License shall survive, including but not limited -to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. Neither party will be -liable to the other for compensation, indemnity or damages of any sort -solely as a result of terminating this License in accordance with its -terms, and termination of this License will be without prejudice to -any other right or remedy of either party. - -13. Miscellaneous. - -13.1 Government End Users. The Covered Code is a "commercial item" as -defined in FAR 2.101. Government software and technical data rights -in the Covered Code include only those rights customarily provided to -the public as defined in this License. This customary commercial -license in technical data and software is provided in accordance with -FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for -Department of Defense purchases, DFAR 252.227-7015 (Technical Data -- -Commercial Items) and 227.7202-3 (Rights in Commercial Computer -Software or Computer Software Documentation). Accordingly, all U.S. -Government End Users acquire Covered Code with only those rights set -forth herein. - -13.2 Relationship of Parties. This License will not be construed as -creating an agency, partnership, joint venture or any other form of -legal association between You and Apple, and You will not represent to -the contrary, whether expressly, by implication, appearance or -otherwise. - -13.3 Independent Development. Nothing in this License will impair -Apple's right to acquire, license, develop, have others develop for -it, market and/or distribute technology or products that perform the -same or similar functions as, or otherwise compete with, -Modifications, Larger Works, technology or products that You may -develop, produce, market or distribute. - -13.4 Waiver; Construction. Failure by Apple to enforce any provision -of this License will not be deemed a waiver of future enforcement of -that or any other provision. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -will not apply to this License. - -13.5 Severability. (a) If for any reason a court of competent -jurisdiction finds any provision of this License, or portion thereof, -to be unenforceable, that provision of the License will be enforced to -the maximum extent permissible so as to effect the economic benefits -and intent of the parties, and the remainder of this License will -continue in full force and effect. (b) Notwithstanding the foregoing, -if applicable law prohibits or restricts You from fully and/or -specifically complying with Sections 2 and/or 3 or prevents the -enforceability of either of those Sections, this License will -immediately terminate and You must immediately discontinue any use of -the Covered Code and destroy all copies of it that are in your -possession or control. - -13.6 Dispute Resolution. Any litigation or other dispute resolution -between You and Apple relating to this License shall take place in the -Northern District of California, and You and Apple hereby consent to -the personal jurisdiction of, and venue in, the state and federal -courts within that District with respect to this License. The -application of the United Nations Convention on Contracts for the -International Sale of Goods is expressly excluded. - -13.7 Entire Agreement; Governing Law. This License constitutes the -entire agreement between the parties with respect to the subject -matter hereof. This License shall be governed by the laws of the -United States and the State of California, except that body of -California law concerning conflicts of law. - -Where You are located in the province of Quebec, Canada, the following -clause applies: The parties hereby confirm that they have requested -that this License and all related documents be drafted in English. Les -parties ont exige que le present contrat et tous les documents -connexes soient rediges en anglais. - -EXHIBIT A. - -"Portions Copyright (c) 1999 Apple Computer, Inc. All Rights -Reserved. This file contains Original Code and/or Modifications of -Original Code as defined in and that are subject to the Apple Public -Source License Version 1.1 (the "License"). You may not use this file -except in compliance with the License. Please obtain a copy of the -License at http://www.apple.com/publicsource and read it before using -this file. - -The Original Code and all software distributed under the License are -distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the -License for the specific language governing rights and limitations -under the License." diff --git a/src/libnotify/CMakeLists.txt b/src/libnotify/CMakeLists.txt deleted file mode 100644 index 7d394cfc0..000000000 --- a/src/libnotify/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -project(libnotify) - -cmake_minimum_required(VERSION 3.10) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -add_definitions(-nostdinc -w) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fblocks -include ${CMAKE_SOURCE_DIR}/src/external/lkm/bsd/sys/fileport.h") -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib") - -mig(notify_ipc.defs) - -set(notify_sources - libnotify.c - notify_client.c - table.c - ${CMAKE_CURRENT_BINARY_DIR}/notify_ipcUser.c -) - -set(DYLIB_INSTALL_NAME "/usr/lib/system/libsystem_notify.dylib") -add_circular(system_notify FAT - SOURCES - ${notify_sources} - DEPENDENCIES - system_c - system_kernel - system_blocks - libdispatch_shared - launch - system_dyld - system_malloc - system_pthread - platform - system_asl - xpc -) -#target_link_libraries(system_notify system_c system_kernel system_blocks libdispatch_shared launch system_dyld system_malloc system_pthread) - -add_darling_executable(notifyutil notifyutil/notifyutil.c) - -install(TARGETS system_notify DESTINATION libexec/darling/usr/lib/system) -install(TARGETS notifyutil DESTINATION libexec/darling/usr/bin) -install(FILES notifyutil/notifyutil.1 DESTINATION libexec/darling/usr/share/man/man1) - -add_subdirectory(notifyd) diff --git a/src/libnotify/Libnotify.xcodeproj/project.pbxproj b/src/libnotify/Libnotify.xcodeproj/project.pbxproj deleted file mode 100644 index 0cdd356fb..000000000 --- a/src/libnotify/Libnotify.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1241 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 45; - objects = { - -/* Begin PBXAggregateTarget section */ - 3FA21AC7148AA93000099D2F /* cli_apps */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 3FA21AC8148AA93000099D2F /* Build configuration list for PBXAggregateTarget "cli_apps" */; - buildPhases = ( - 3F947784191C32DC00A93E8E /* No Simulator Man Pages */, - ); - dependencies = ( - 3FA21ACB148AA94A00099D2F /* PBXTargetDependency */, - 3FA21ACD148AA94A00099D2F /* PBXTargetDependency */, - ); - name = cli_apps; - productName = cli_apps; - }; - 72FA84FB1BD6EAB900A4CC6F /* tests */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 72FA84FC1BD6EAB900A4CC6F /* Build configuration list for PBXAggregateTarget "tests" */; - buildPhases = ( - ); - dependencies = ( - 72FA84FF1BD6EC2000A4CC6F /* PBXTargetDependency */, - ); - name = tests; - productName = tests; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 1886391920E1A2BF00C8BEA9 /* notify_bench.c in Sources */ = {isa = PBXBuildFile; fileRef = 727C90371B9A372700D5B754 /* notify_bench.c */; }; - 2D312B76102CA2E300F90022 /* libnotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B73102CA2E300F90022 /* libnotify.c */; }; - 2D312B77102CA2E300F90022 /* notify_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B74102CA2E300F90022 /* notify_client.c */; }; - 2D312B78102CA2E300F90022 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B75102CA2E300F90022 /* table.c */; }; - 2D312B7A102CA30200F90022 /* notify_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B79102CA30200F90022 /* notify_ipc.defs */; settings = {ATTRIBUTES = (Client, ); }; }; - 2D312B7E102CA32500F90022 /* notify_keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D312B7C102CA32500F90022 /* notify_keys.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2D312B7F102CA32500F90022 /* notify.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D312B7D102CA32500F90022 /* notify.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2D312B87102CA36C00F90022 /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D312B85102CA36C00F90022 /* table.h */; }; - 2D38AA0A102CD88300D3D622 /* notify.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B92102CA38F00F90022 /* notify.3 */; }; - 2D38AA0B102CD89B00D3D622 /* notify_cancel.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B88102CA38F00F90022 /* notify_cancel.3 */; }; - 2D38AA0C102CD89B00D3D622 /* notify_check.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B89102CA38F00F90022 /* notify_check.3 */; }; - 2D38AA0D102CD8B800D3D622 /* notify_get_state.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B8A102CA38F00F90022 /* notify_get_state.3 */; }; - 2D38AA0E102CD8B800D3D622 /* notify_is_valid_token.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D6D820D18DA602A0034E7B4 /* notify_is_valid_token.3 */; }; - 2D38AA0F102CD8B800D3D622 /* notify_post.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B8B102CA38F00F90022 /* notify_post.3 */; }; - 2D38AA10102CD8B800D3D622 /* notify_register_check.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B8C102CA38F00F90022 /* notify_register_check.3 */; }; - 2D38AA11102CD8B800D3D622 /* notify_register_dispatch.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B8D102CA38F00F90022 /* notify_register_dispatch.3 */; }; - 2D38AA12102CD8B800D3D622 /* notify_register_file_descriptor.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B8E102CA38F00F90022 /* notify_register_file_descriptor.3 */; }; - 2D38AA13102CD8B800D3D622 /* notify_register_mach_port.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B8F102CA38F00F90022 /* notify_register_mach_port.3 */; }; - 2D38AA14102CD8B800D3D622 /* notify_register_signal.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B90102CA38F00F90022 /* notify_register_signal.3 */; }; - 2D38AA15102CD8B800D3D622 /* notify_set_state.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B91102CA38F00F90022 /* notify_set_state.3 */; }; - 2D4F060B1B14E7DF00D59CEF /* com.apple.notifyd.sb in Install Sandbox profile */ = {isa = PBXBuildFile; fileRef = 2DD962061B14E6560040D341 /* com.apple.notifyd.sb */; }; - 2DCB287210D99ADA00DF3A8D /* notify_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DCB287110D99ADA00DF3A8D /* notify_private.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 3FA21ACF148AAA5000099D2F /* notify_proc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA21A9C148AA7FA00099D2F /* notify_proc.c */; }; - 3FA21AD0148AAA5000099D2F /* notifyd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA21A9E148AA7FA00099D2F /* notifyd.c */; }; - 3FA21AD1148AAA5000099D2F /* pathwatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA21AA0148AA7FA00099D2F /* pathwatch.c */; }; - 3FA21AD2148AAA5000099D2F /* service.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA21AA2148AA7FA00099D2F /* service.c */; }; - 3FA21AD3148AAA5000099D2F /* timer.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA21AA5148AA7FA00099D2F /* timer.c */; }; - 3FA21AD4148AAA5D00099D2F /* notifyd.8 in Install man page */ = {isa = PBXBuildFile; fileRef = 3FA21A9D148AA7FA00099D2F /* notifyd.8 */; }; - 3FA21AD5148AAA6E00099D2F /* notifyutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA21AA9148AA82700099D2F /* notifyutil.c */; }; - 3FA21AD6148AAA7500099D2F /* notifyutil.1 in Install man page */ = {isa = PBXBuildFile; fileRef = 3FA21AA8148AA82700099D2F /* notifyutil.1 */; }; - 3FA21AD8148AAABE00099D2F /* com.apple.notifyd.plist in Install launchd.plist */ = {isa = PBXBuildFile; fileRef = 3FA21A99148AA7FA00099D2F /* com.apple.notifyd.plist */; }; - 3FA21AE6148AAEAC00099D2F /* notify_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B79102CA30200F90022 /* notify_ipc.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; - 3FD0DBAD148AB12000C50811 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3FD0DBAC148AB12000C50811 /* libbsm.dylib */; }; - 6E8E6AD02282A7DA0084C085 /* notify.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6E8E6ACD2282A7DA0084C085 /* notify.defs */; settings = {ATTRIBUTES = (Server, ); }; }; - 6EC91ED52178FF7100F11587 /* libCrashReporterClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EC91ED42178FF7100F11587 /* libCrashReporterClient.a */; }; - 94099C762087E7D50004B6BC /* RegisterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 94099C752087E7D50004B6BC /* RegisterTests.m */; settings = {COMPILER_FLAGS = "-Wno-gnu-statement-expression -fobjc-exceptions"; }; }; - 9456B8522023CAB300CF7D27 /* libnotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B73102CA2E300F90022 /* libnotify.c */; }; - 9456B8532023CAB600CF7D27 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B75102CA2E300F90022 /* table.c */; }; - 9487BF2A2089A99A0043BF74 /* notify_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B74102CA2E300F90022 /* notify_client.c */; }; - 9487BF2B2089A9E30043BF74 /* notify_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B79102CA30200F90022 /* notify_ipc.defs */; }; - 9487BF2C2089BAA30043BF74 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B75102CA2E300F90022 /* table.c */; }; - 9487BF2D2089BAB20043BF74 /* libnotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B73102CA2E300F90022 /* libnotify.c */; }; - E6481E7F2165785F00C04412 /* notify_probes.d in Sources */ = {isa = PBXBuildFile; fileRef = E6481E7E2165785F00C04412 /* notify_probes.d */; }; - FC7B7A53155781930064D203 /* notify_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = FC7B7A52155781930064D203 /* notify_internal.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 3FA21ACA148AA94A00099D2F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3FA21AAF148AA8E300099D2F; - remoteInfo = notifyd; - }; - 3FA21ACC148AA94A00099D2F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3FA21ABD148AA8F000099D2F; - remoteInfo = notifyutil; - }; - 72FA84FE1BD6EC2000A4CC6F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 72FA84F61BD6E9DF00A4CC6F; - remoteInfo = darwintests; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 1886391220E1A22F00C8BEA9 /* Install man page */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1; - dstSubfolderSpec = 0; - files = ( - ); - name = "Install man page"; - runOnlyForDeploymentPostprocessing = 1; - }; - 2D38AA09102CD87C00D3D622 /* Copy man3 Files */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/share/man/man3; - dstSubfolderSpec = 0; - files = ( - 2D38AA0A102CD88300D3D622 /* notify.3 in Copy man3 Files */, - 2D38AA0B102CD89B00D3D622 /* notify_cancel.3 in Copy man3 Files */, - 2D38AA0C102CD89B00D3D622 /* notify_check.3 in Copy man3 Files */, - 2D38AA0D102CD8B800D3D622 /* notify_get_state.3 in Copy man3 Files */, - 2D38AA0E102CD8B800D3D622 /* notify_is_valid_token.3 in Copy man3 Files */, - 2D38AA0F102CD8B800D3D622 /* notify_post.3 in Copy man3 Files */, - 2D38AA10102CD8B800D3D622 /* notify_register_check.3 in Copy man3 Files */, - 2D38AA11102CD8B800D3D622 /* notify_register_dispatch.3 in Copy man3 Files */, - 2D38AA12102CD8B800D3D622 /* notify_register_file_descriptor.3 in Copy man3 Files */, - 2D38AA13102CD8B800D3D622 /* notify_register_mach_port.3 in Copy man3 Files */, - 2D38AA14102CD8B800D3D622 /* notify_register_signal.3 in Copy man3 Files */, - 2D38AA15102CD8B800D3D622 /* notify_set_state.3 in Copy man3 Files */, - ); - name = "Copy man3 Files"; - runOnlyForDeploymentPostprocessing = 1; - }; - 2D4F060A1B14E79900D59CEF /* Install Sandbox profile */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /System/Library/Sandbox/Profiles; - dstSubfolderSpec = 0; - files = ( - 2D4F060B1B14E7DF00D59CEF /* com.apple.notifyd.sb in Install Sandbox profile */, - ); - name = "Install Sandbox profile"; - runOnlyForDeploymentPostprocessing = 1; - }; - 3FA21AAE148AA8E300099D2F /* Install man page */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man8; - dstSubfolderSpec = 0; - files = ( - 3FA21AD4148AAA5D00099D2F /* notifyd.8 in Install man page */, - ); - name = "Install man page"; - runOnlyForDeploymentPostprocessing = 1; - }; - 3FA21ABC148AA8F000099D2F /* Install man page */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1; - dstSubfolderSpec = 0; - files = ( - 3FA21AD6148AAA7500099D2F /* notifyutil.1 in Install man page */, - ); - name = "Install man page"; - runOnlyForDeploymentPostprocessing = 1; - }; - 3FA21AD7148AAAA600099D2F /* Install launchd.plist */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /System/Library/LaunchDaemons; - dstSubfolderSpec = 0; - files = ( - 3FA21AD8148AAABE00099D2F /* com.apple.notifyd.plist in Install launchd.plist */, - ); - name = "Install launchd.plist"; - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 180F8D3E21136EBF009A472B /* notify_pathwatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notify_pathwatch.c; sourceTree = ""; }; - 182FD2C2210BB0F600BF263C /* notify_benchmark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_benchmark.c; sourceTree = ""; }; - 18314CC821FF867600FEB43D /* notifyutil_entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = notifyutil_entitlements.plist; sourceTree = ""; }; - 18383C6720F909A300D5C465 /* notify_regenerate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_regenerate.c; sourceTree = ""; }; - 18383C6820F909A300D5C465 /* notify_register_signal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_register_signal.c; sourceTree = ""; }; - 18383C6920F909A300D5C465 /* notify_sigusr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_sigusr.c; sourceTree = ""; }; - 1886391720E1A22F00C8BEA9 /* notifybench */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = notifybench; sourceTree = BUILT_PRODUCTS_DIR; }; - 2D312B73102CA2E300F90022 /* libnotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = libnotify.c; sourceTree = ""; usesTabs = 1; }; - 2D312B74102CA2E300F90022 /* notify_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_client.c; sourceTree = ""; usesTabs = 1; }; - 2D312B75102CA2E300F90022 /* table.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = table.c; sourceTree = ""; }; - 2D312B79102CA30200F90022 /* notify_ipc.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = notify_ipc.defs; sourceTree = ""; }; - 2D312B7C102CA32500F90022 /* notify_keys.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = notify_keys.h; sourceTree = ""; }; - 2D312B7D102CA32500F90022 /* notify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = notify.h; sourceTree = ""; }; - 2D312B81102CA34D00F90022 /* libnotify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libnotify.h; sourceTree = ""; usesTabs = 1; }; - 2D312B85102CA36C00F90022 /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = ""; usesTabs = 1; }; - 2D312B88102CA38F00F90022 /* notify_cancel.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_cancel.3; sourceTree = ""; }; - 2D312B89102CA38F00F90022 /* notify_check.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_check.3; sourceTree = ""; }; - 2D312B8A102CA38F00F90022 /* notify_get_state.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_get_state.3; sourceTree = ""; }; - 2D312B8B102CA38F00F90022 /* notify_post.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_post.3; sourceTree = ""; }; - 2D312B8C102CA38F00F90022 /* notify_register_check.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_register_check.3; sourceTree = ""; }; - 2D312B8D102CA38F00F90022 /* notify_register_dispatch.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_register_dispatch.3; sourceTree = ""; }; - 2D312B8E102CA38F00F90022 /* notify_register_file_descriptor.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_register_file_descriptor.3; sourceTree = ""; }; - 2D312B8F102CA38F00F90022 /* notify_register_mach_port.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_register_mach_port.3; sourceTree = ""; }; - 2D312B90102CA38F00F90022 /* notify_register_signal.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_register_signal.3; sourceTree = ""; }; - 2D312B91102CA38F00F90022 /* notify_set_state.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_set_state.3; sourceTree = ""; }; - 2D312B92102CA38F00F90022 /* notify.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify.3; sourceTree = ""; }; - 2D6D820D18DA602A0034E7B4 /* notify_is_valid_token.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_is_valid_token.3; sourceTree = ""; }; - 2DCB287110D99ADA00DF3A8D /* notify_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = notify_private.h; sourceTree = ""; }; - 2DD962061B14E6560040D341 /* com.apple.notifyd.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.notifyd.sb; sourceTree = ""; }; - 2DF9EA0B102CF33400DE9E8D /* APPLE_LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = APPLE_LICENSE; sourceTree = ""; }; - 3F82235D12B18551005DD509 /* libnotify.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = libnotify.xcconfig; sourceTree = ""; }; - 3F8223B412B18877005DD509 /* libsystem_notify.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_notify.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; - 3F947780191C322100A93E8E /* no-sim-man.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "no-sim-man.sh"; sourceTree = ""; }; - 3F947781191C322100A93E8E /* sim-compat-symlink.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "sim-compat-symlink.sh"; sourceTree = ""; }; - 3F999961185C474E00EAD3A0 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = ""; }; - 3F999963185C474E00EAD3A0 /* notifyd.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = notifyd.xcconfig; sourceTree = ""; }; - 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = notifyutil.xcconfig; sourceTree = ""; }; - 3FA21A99148AA7FA00099D2F /* com.apple.notifyd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.notifyd.plist; sourceTree = ""; }; - 3FA21A9A148AA7FA00099D2F /* notify.conf */ = {isa = PBXFileReference; lastKnownFileType = text; path = notify.conf; sourceTree = ""; }; - 3FA21A9B148AA7FA00099D2F /* notify.conf.iPhone */ = {isa = PBXFileReference; lastKnownFileType = text; name = notify.conf.iPhone; path = ../notify.conf.iPhone; sourceTree = ""; }; - 3FA21A9C148AA7FA00099D2F /* notify_proc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notify_proc.c; sourceTree = ""; usesTabs = 1; }; - 3FA21A9D148AA7FA00099D2F /* notifyd.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = notifyd.8; sourceTree = ""; }; - 3FA21A9E148AA7FA00099D2F /* notifyd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notifyd.c; sourceTree = ""; usesTabs = 1; }; - 3FA21A9F148AA7FA00099D2F /* notifyd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = notifyd.h; sourceTree = ""; usesTabs = 1; }; - 3FA21AA0148AA7FA00099D2F /* pathwatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pathwatch.c; sourceTree = ""; }; - 3FA21AA1148AA7FA00099D2F /* pathwatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pathwatch.h; sourceTree = ""; }; - 3FA21AA2148AA7FA00099D2F /* service.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = service.c; sourceTree = ""; usesTabs = 1; }; - 3FA21AA3148AA7FA00099D2F /* service.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = service.h; sourceTree = ""; }; - 3FA21AA5148AA7FA00099D2F /* timer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = timer.c; sourceTree = ""; }; - 3FA21AA6148AA7FA00099D2F /* timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = timer.h; sourceTree = ""; }; - 3FA21AA8148AA82700099D2F /* notifyutil.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = notifyutil.1; sourceTree = ""; }; - 3FA21AA9148AA82700099D2F /* notifyutil.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notifyutil.c; sourceTree = ""; }; - 3FA21AB0148AA8E300099D2F /* notifyd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = notifyd; sourceTree = BUILT_PRODUCTS_DIR; }; - 3FA21ABE148AA8F000099D2F /* notifyutil */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = notifyutil; sourceTree = BUILT_PRODUCTS_DIR; }; - 3FA21ADD148AABA900099D2F /* mk_notify_conf.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = mk_notify_conf.sh; sourceTree = ""; }; - 3FA21ADF148AACA000099D2F /* notify.conf.MacOSX */ = {isa = PBXFileReference; lastKnownFileType = text; name = notify.conf.MacOSX; path = notifyd/notify.conf.MacOSX; sourceTree = SOURCE_ROOT; }; - 3FD0DBAC148AB12000C50811 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = ""; }; - 6E8DAA2E2184283500A90CEA /* table.in.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = table.in.c; sourceTree = ""; usesTabs = 1; }; - 6E8E6ACC2282A7D30084C085 /* notify.defs */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.mig; name = notify.defs; path = usr/include/mach/notify.defs; sourceTree = SDKROOT; }; - 6E8E6ACD2282A7DA0084C085 /* notify.defs */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.mig; name = notify.defs; path = usr/include/mach/notify.defs; sourceTree = SDKROOT; }; - 6EC91ED42178FF7100F11587 /* libCrashReporterClient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libCrashReporterClient.a; path = /usr/local/lib/libCrashReporterClient.a; sourceTree = ""; }; - 727C90301B9A372700D5B754 /* dispatch_cancel_in_block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_cancel_in_block.c; sourceTree = ""; }; - 727C90341B9A372700D5B754 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; - 727C90371B9A372700D5B754 /* notify_bench.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_bench.c; sourceTree = ""; }; - 727C90381B9A372700D5B754 /* notify_control.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_control.c; sourceTree = ""; }; - 727C90391B9A372700D5B754 /* notify_disable_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_disable_test.c; sourceTree = ""; }; - 727C903A1B9A372700D5B754 /* notify_many_dups.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_many_dups.c; sourceTree = ""; }; - 727C903B1B9A372700D5B754 /* random_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = random_test.c; sourceTree = ""; }; - 94099C732087E7D50004B6BC /* xctests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = xctests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 94099C752087E7D50004B6BC /* RegisterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RegisterTests.m; sourceTree = ""; }; - 94099C772087E7D50004B6BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9487BF2820882DAD0043BF74 /* parallel_register_cancel.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = parallel_register_cancel.c; sourceTree = ""; }; - 9B71D22F206AB52200BB9574 /* notify_qos.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_qos.c; sourceTree = ""; }; - E6481E7E2165785F00C04412 /* notify_probes.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = notify_probes.d; sourceTree = ""; }; - FC7B7A52155781930064D203 /* notify_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = notify_internal.h; sourceTree = ""; usesTabs = 1; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 1886391120E1A22F00C8BEA9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3FA21AAD148AA8E300099D2F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 3FD0DBAD148AB12000C50811 /* libbsm.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3FA21ABB148AA8F000099D2F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 94099C702087E7D50004B6BC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D289987405E68DCB004EDB86 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6EC91ED52178FF7100F11587 /* libCrashReporterClient.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* Libnotify */ = { - isa = PBXGroup; - children = ( - 1886391820E1A24A00C8BEA9 /* notifybench */, - 3F94777F191C322100A93E8E /* xcodescripts */, - 3F999960185C474E00EAD3A0 /* xcodeconfig */, - 2D312B79102CA30200F90022 /* notify_ipc.defs */, - 6E8E6ACD2282A7DA0084C085 /* notify.defs */, - 3FA21A97148AA7CD00099D2F /* libsystem_notify */, - 3FA21AA7148AA82700099D2F /* notifyutil */, - 3FA21A98148AA7FA00099D2F /* notifyd */, - 2DF9EA0A102CF31700DE9E8D /* Additional Files */, - 94099C742087E7D50004B6BC /* xctests */, - 3FA21ACE148AAA0D00099D2F /* Products */, - 727C902F1B9A372700D5B754 /* tests */, - 94099C732087E7D50004B6BC /* xctests.xctest */, - 1886391720E1A22F00C8BEA9 /* notifybench */, - 6EC91ED32178FF7100F11587 /* Frameworks */, - ); - name = Libnotify; - sourceTree = ""; - }; - 1886391820E1A24A00C8BEA9 /* notifybench */ = { - isa = PBXGroup; - children = ( - 727C90371B9A372700D5B754 /* notify_bench.c */, - ); - path = notifybench; - sourceTree = ""; - }; - 2D312B72102CA2C400F90022 /* Source */ = { - isa = PBXGroup; - children = ( - E6481E7E2165785F00C04412 /* notify_probes.d */, - 2D312B73102CA2E300F90022 /* libnotify.c */, - 2D312B74102CA2E300F90022 /* notify_client.c */, - 2D312B75102CA2E300F90022 /* table.c */, - 6E8DAA2E2184283500A90CEA /* table.in.c */, - ); - name = Source; - sourceTree = ""; - }; - 2D312B7B102CA30600F90022 /* Public Headers */ = { - isa = PBXGroup; - children = ( - 2D312B7C102CA32500F90022 /* notify_keys.h */, - 2D312B7D102CA32500F90022 /* notify.h */, - ); - name = "Public Headers"; - sourceTree = ""; - }; - 2D312B80102CA33600F90022 /* Private Headers */ = { - isa = PBXGroup; - children = ( - 2DCB287110D99ADA00DF3A8D /* notify_private.h */, - 2D312B81102CA34D00F90022 /* libnotify.h */, - ); - name = "Private Headers"; - sourceTree = ""; - }; - 2D312B83102CA35300F90022 /* Project Headers */ = { - isa = PBXGroup; - children = ( - FC7B7A52155781930064D203 /* notify_internal.h */, - 2D312B85102CA36C00F90022 /* table.h */, - ); - name = "Project Headers"; - sourceTree = ""; - }; - 2DF9EA0A102CF31700DE9E8D /* Additional Files */ = { - isa = PBXGroup; - children = ( - 2DF9EA0B102CF33400DE9E8D /* APPLE_LICENSE */, - ); - name = "Additional Files"; - sourceTree = ""; - }; - 3F94777F191C322100A93E8E /* xcodescripts */ = { - isa = PBXGroup; - children = ( - 3F947780191C322100A93E8E /* no-sim-man.sh */, - 3F947781191C322100A93E8E /* sim-compat-symlink.sh */, - ); - path = xcodescripts; - sourceTree = ""; - }; - 3F999960185C474E00EAD3A0 /* xcodeconfig */ = { - isa = PBXGroup; - children = ( - 6E8E6ACC2282A7D30084C085 /* notify.defs */, - 3F999961185C474E00EAD3A0 /* base.xcconfig */, - 3F82235D12B18551005DD509 /* libnotify.xcconfig */, - 3F999963185C474E00EAD3A0 /* notifyd.xcconfig */, - 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */, - ); - path = xcodeconfig; - sourceTree = ""; - }; - 3FA21A97148AA7CD00099D2F /* libsystem_notify */ = { - isa = PBXGroup; - children = ( - 2D312B83102CA35300F90022 /* Project Headers */, - 2D312B80102CA33600F90022 /* Private Headers */, - 2D312B7B102CA30600F90022 /* Public Headers */, - 2D312B72102CA2C400F90022 /* Source */, - C6A0FF2B0290797F04C91782 /* Documentation */, - ); - name = libsystem_notify; - sourceTree = ""; - }; - 3FA21A98148AA7FA00099D2F /* notifyd */ = { - isa = PBXGroup; - children = ( - 2DD962061B14E6560040D341 /* com.apple.notifyd.sb */, - 3FA21ADC148AABA900099D2F /* Build Support */, - 3FA21A99148AA7FA00099D2F /* com.apple.notifyd.plist */, - 3FA21A9A148AA7FA00099D2F /* notify.conf */, - 3FA21AAA148AA85300099D2F /* Source */, - 3FA21A9D148AA7FA00099D2F /* notifyd.8 */, - 3FA21AAB148AA86600099D2F /* Private Headers */, - ); - path = notifyd; - sourceTree = ""; - }; - 3FA21AA7148AA82700099D2F /* notifyutil */ = { - isa = PBXGroup; - children = ( - 3FA21AA8148AA82700099D2F /* notifyutil.1 */, - 3FA21AA9148AA82700099D2F /* notifyutil.c */, - 18314CC821FF867600FEB43D /* notifyutil_entitlements.plist */, - ); - path = notifyutil; - sourceTree = ""; - }; - 3FA21AAA148AA85300099D2F /* Source */ = { - isa = PBXGroup; - children = ( - 3FA21A9C148AA7FA00099D2F /* notify_proc.c */, - 3FA21A9E148AA7FA00099D2F /* notifyd.c */, - 3FA21AA0148AA7FA00099D2F /* pathwatch.c */, - 3FA21AA2148AA7FA00099D2F /* service.c */, - 3FA21AA5148AA7FA00099D2F /* timer.c */, - ); - name = Source; - sourceTree = ""; - }; - 3FA21AAB148AA86600099D2F /* Private Headers */ = { - isa = PBXGroup; - children = ( - 3FA21A9F148AA7FA00099D2F /* notifyd.h */, - 3FA21AA1148AA7FA00099D2F /* pathwatch.h */, - 3FA21AA3148AA7FA00099D2F /* service.h */, - 3FA21AA6148AA7FA00099D2F /* timer.h */, - ); - name = "Private Headers"; - sourceTree = ""; - }; - 3FA21ACE148AAA0D00099D2F /* Products */ = { - isa = PBXGroup; - children = ( - 3F8223B412B18877005DD509 /* libsystem_notify.dylib */, - 3FA21AB0148AA8E300099D2F /* notifyd */, - 3FA21ABE148AA8F000099D2F /* notifyutil */, - ); - name = Products; - sourceTree = ""; - }; - 3FA21ADC148AABA900099D2F /* Build Support */ = { - isa = PBXGroup; - children = ( - 3FD0DBAC148AB12000C50811 /* libbsm.dylib */, - 3FA21ADF148AACA000099D2F /* notify.conf.MacOSX */, - 3FA21A9B148AA7FA00099D2F /* notify.conf.iPhone */, - 3FA21ADD148AABA900099D2F /* mk_notify_conf.sh */, - ); - name = "Build Support"; - path = xcodescripts; - sourceTree = ""; - }; - 6EC91ED32178FF7100F11587 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6EC91ED42178FF7100F11587 /* libCrashReporterClient.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - 727C902F1B9A372700D5B754 /* tests */ = { - isa = PBXGroup; - children = ( - 18383C6720F909A300D5C465 /* notify_regenerate.c */, - 18383C6820F909A300D5C465 /* notify_register_signal.c */, - 18383C6920F909A300D5C465 /* notify_sigusr.c */, - 727C90341B9A372700D5B754 /* Makefile */, - 9B71D22F206AB52200BB9574 /* notify_qos.c */, - 727C90301B9A372700D5B754 /* dispatch_cancel_in_block.c */, - 727C90381B9A372700D5B754 /* notify_control.c */, - 727C90391B9A372700D5B754 /* notify_disable_test.c */, - 727C903A1B9A372700D5B754 /* notify_many_dups.c */, - 727C903B1B9A372700D5B754 /* random_test.c */, - 9487BF2820882DAD0043BF74 /* parallel_register_cancel.c */, - 182FD2C2210BB0F600BF263C /* notify_benchmark.c */, - 180F8D3E21136EBF009A472B /* notify_pathwatch.c */, - ); - path = tests; - sourceTree = ""; - }; - 94099C742087E7D50004B6BC /* xctests */ = { - isa = PBXGroup; - children = ( - 94099C752087E7D50004B6BC /* RegisterTests.m */, - 94099C772087E7D50004B6BC /* Info.plist */, - ); - path = xctests; - sourceTree = ""; - }; - C6A0FF2B0290797F04C91782 /* Documentation */ = { - isa = PBXGroup; - children = ( - 2D312B88102CA38F00F90022 /* notify_cancel.3 */, - 2D312B89102CA38F00F90022 /* notify_check.3 */, - 2D312B8A102CA38F00F90022 /* notify_get_state.3 */, - 2D6D820D18DA602A0034E7B4 /* notify_is_valid_token.3 */, - 2D312B8B102CA38F00F90022 /* notify_post.3 */, - 2D312B8C102CA38F00F90022 /* notify_register_check.3 */, - 2D312B8D102CA38F00F90022 /* notify_register_dispatch.3 */, - 2D312B8E102CA38F00F90022 /* notify_register_file_descriptor.3 */, - 2D312B8F102CA38F00F90022 /* notify_register_mach_port.3 */, - 2D312B90102CA38F00F90022 /* notify_register_signal.3 */, - 2D312B91102CA38F00F90022 /* notify_set_state.3 */, - 2D312B92102CA38F00F90022 /* notify.3 */, - ); - name = Documentation; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - D2AAC043055464E500DB518D /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D312B7E102CA32500F90022 /* notify_keys.h in Headers */, - 2D312B7F102CA32500F90022 /* notify.h in Headers */, - 2D312B87102CA36C00F90022 /* table.h in Headers */, - 2DCB287210D99ADA00DF3A8D /* notify_private.h in Headers */, - FC7B7A53155781930064D203 /* notify_internal.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXLegacyTarget section */ - 72FA84F61BD6E9DF00A4CC6F /* darwintests */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "$(ACTION)"; - buildConfigurationList = 72FA84F71BD6E9DF00A4CC6F /* Build configuration list for PBXLegacyTarget "darwintests" */; - buildPhases = ( - ); - buildToolPath = /usr/bin/make; - buildWorkingDirectory = tests; - dependencies = ( - ); - name = darwintests; - passBuildSettingsInEnvironment = 1; - productName = darwintests; - }; -/* End PBXLegacyTarget section */ - -/* Begin PBXNativeTarget section */ - 1886390E20E1A22F00C8BEA9 /* notifybench */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1886391420E1A22F00C8BEA9 /* Build configuration list for PBXNativeTarget "notifybench" */; - buildPhases = ( - 1886390F20E1A22F00C8BEA9 /* Sources */, - 1886391120E1A22F00C8BEA9 /* Frameworks */, - 1886391220E1A22F00C8BEA9 /* Install man page */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = notifybench; - productName = notifyutil; - productReference = 1886391720E1A22F00C8BEA9 /* notifybench */; - productType = "com.apple.product-type.tool"; - }; - 3FA21AAF148AA8E300099D2F /* notifyd */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3FA21AB8148AA8E300099D2F /* Build configuration list for PBXNativeTarget "notifyd" */; - buildPhases = ( - 3FA21AAC148AA8E300099D2F /* Sources */, - 3FA21AAD148AA8E300099D2F /* Frameworks */, - 3FA21AAE148AA8E300099D2F /* Install man page */, - 3FA21AD7148AAAA600099D2F /* Install launchd.plist */, - 3FA21ADB148AAB1C00099D2F /* Install notify.conf */, - 2D4F060A1B14E79900D59CEF /* Install Sandbox profile */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = notifyd; - productName = notifyd; - productReference = 3FA21AB0148AA8E300099D2F /* notifyd */; - productType = "com.apple.product-type.tool"; - }; - 3FA21ABD148AA8F000099D2F /* notifyutil */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3FA21AC5148AA8F000099D2F /* Build configuration list for PBXNativeTarget "notifyutil" */; - buildPhases = ( - 3FA21ABA148AA8F000099D2F /* Sources */, - 3FA21ABB148AA8F000099D2F /* Frameworks */, - 3FA21ABC148AA8F000099D2F /* Install man page */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = notifyutil; - productName = notifyutil; - productReference = 3FA21ABE148AA8F000099D2F /* notifyutil */; - productType = "com.apple.product-type.tool"; - }; - 94099C722087E7D50004B6BC /* xctests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 94099C792087E7D50004B6BC /* Build configuration list for PBXNativeTarget "xctests" */; - buildPhases = ( - 94099C6F2087E7D50004B6BC /* Sources */, - 94099C702087E7D50004B6BC /* Frameworks */, - 94099C712087E7D50004B6BC /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = xctests; - productName = xctests; - productReference = 94099C732087E7D50004B6BC /* xctests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - D2AAC045055464E500DB518D /* libnotify */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "libnotify" */; - buildPhases = ( - D2AAC043055464E500DB518D /* Headers */, - D2AAC044055464E500DB518D /* Sources */, - D289987405E68DCB004EDB86 /* Frameworks */, - 2D38AA09102CD87C00D3D622 /* Copy man3 Files */, - 3F947782191C324900A93E8E /* No Simulator Man Pages */, - 3F947783191C327700A93E8E /* Sim compat symlink */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = libnotify; - productName = Libnotify; - productReference = 3F8223B412B18877005DD509 /* libsystem_notify.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - attributes = { - TargetAttributes = { - 72FA84F61BD6E9DF00A4CC6F = { - CreatedOnToolsVersion = 7.1; - }; - 72FA84FB1BD6EAB900A4CC6F = { - CreatedOnToolsVersion = 7.1; - }; - 94099C722087E7D50004B6BC = { - CreatedOnToolsVersion = 10.0; - }; - }; - }; - buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "Libnotify" */; - compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 08FB7794FE84155DC02AAC07 /* Libnotify */; - productRefGroup = 08FB7794FE84155DC02AAC07 /* Libnotify */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - D2AAC045055464E500DB518D /* libnotify */, - 3FA21AAF148AA8E300099D2F /* notifyd */, - 3FA21ABD148AA8F000099D2F /* notifyutil */, - 1886390E20E1A22F00C8BEA9 /* notifybench */, - 3FA21AC7148AA93000099D2F /* cli_apps */, - 72FA84F61BD6E9DF00A4CC6F /* darwintests */, - 72FA84FB1BD6EAB900A4CC6F /* tests */, - 94099C722087E7D50004B6BC /* xctests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 94099C712087E7D50004B6BC /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3F947782191C324900A93E8E /* No Simulator Man Pages */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/xcodescripts/no-sim-man.sh", - ); - name = "No Simulator Man Pages"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = "/bin/bash -e -x"; - shellScript = "exec \"${SCRIPT_INPUT_FILE_0}\""; - }; - 3F947783191C327700A93E8E /* Sim compat symlink */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/xcodescripts/sim-compat-symlink.sh", - ); - name = "Sim compat symlink"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = "/bin/bash -e -x"; - shellScript = "exec \"${SCRIPT_INPUT_FILE_0}\""; - }; - 3F947784191C32DC00A93E8E /* No Simulator Man Pages */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/xcodescripts/no-sim-man.sh", - ); - name = "No Simulator Man Pages"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = "/bin/bash -e -x"; - shellScript = "exec \"${SCRIPT_INPUT_FILE_0}\""; - }; - 3FA21ADB148AAB1C00099D2F /* Install notify.conf */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/notifyd/xcodescripts/mk_notify_conf.sh", - ); - name = "Install notify.conf"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = "/bin/bash -e -x"; - shellScript = "if [ $(id -u) != 0 ]; then\n\tosascript -e \"do shell script quoted form of \\\"${SRCROOT}/notifyd/xcodescripts/mk_notify_conf.sh\\\" with administrator privileges\"\nelse\n\texec \"${SCRIPT_INPUT_FILE_0}\"\nfi\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 1886390F20E1A22F00C8BEA9 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1886391920E1A2BF00C8BEA9 /* notify_bench.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3FA21AAC148AA8E300099D2F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6E8E6AD02282A7DA0084C085 /* notify.defs in Sources */, - 9456B8532023CAB600CF7D27 /* table.c in Sources */, - 3FA21AE6148AAEAC00099D2F /* notify_ipc.defs in Sources */, - 3FA21ACF148AAA5000099D2F /* notify_proc.c in Sources */, - 3FA21AD0148AAA5000099D2F /* notifyd.c in Sources */, - 9456B8522023CAB300CF7D27 /* libnotify.c in Sources */, - 3FA21AD1148AAA5000099D2F /* pathwatch.c in Sources */, - 3FA21AD2148AAA5000099D2F /* service.c in Sources */, - 3FA21AD3148AAA5000099D2F /* timer.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3FA21ABA148AA8F000099D2F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3FA21AD5148AAA6E00099D2F /* notifyutil.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 94099C6F2087E7D50004B6BC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9487BF2C2089BAA30043BF74 /* table.c in Sources */, - 9487BF2A2089A99A0043BF74 /* notify_client.c in Sources */, - 94099C762087E7D50004B6BC /* RegisterTests.m in Sources */, - 9487BF2B2089A9E30043BF74 /* notify_ipc.defs in Sources */, - 9487BF2D2089BAB20043BF74 /* libnotify.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D2AAC044055464E500DB518D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D312B7A102CA30200F90022 /* notify_ipc.defs in Sources */, - 2D312B76102CA2E300F90022 /* libnotify.c in Sources */, - 2D312B77102CA2E300F90022 /* notify_client.c in Sources */, - E6481E7F2165785F00C04412 /* notify_probes.d in Sources */, - 2D312B78102CA2E300F90022 /* table.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 3FA21ACB148AA94A00099D2F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3FA21AAF148AA8E300099D2F /* notifyd */; - targetProxy = 3FA21ACA148AA94A00099D2F /* PBXContainerItemProxy */; - }; - 3FA21ACD148AA94A00099D2F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3FA21ABD148AA8F000099D2F /* notifyutil */; - targetProxy = 3FA21ACC148AA94A00099D2F /* PBXContainerItemProxy */; - }; - 72FA84FF1BD6EC2000A4CC6F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 72FA84F61BD6E9DF00A4CC6F /* darwintests */; - targetProxy = 72FA84FE1BD6EC2000A4CC6F /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 1886391520E1A22F00C8BEA9 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */; - buildSettings = { - INSTALL_PATH = /usr/local/bin; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 1886391620E1A22F00C8BEA9 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */; - buildSettings = { - INSTALL_PATH = /usr/local/bin; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 1DEB91ED08733DB70010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F82235D12B18551005DD509 /* libnotify.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 1DEB91F108733DB70010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLY_RULES_IN_COPY_FILES = ""; - CLANG_WARN_ASSIGN_ENUM = YES; - CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - LLVM_LTO = YES; - SUPPORTED_PLATFORMS = "watchsimulator watchos iphonesimulator iphoneos macosx bridgeos appletvsimulator appletvos"; - WARNING_CFLAGS = "-Wno-dollar-in-identifier-extension"; - }; - name = Release; - }; - 3FA21AB9148AA8E300099D2F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F999963185C474E00EAD3A0 /* notifyd.xcconfig */; - buildSettings = { - OTHER_CFLAGS = ( - "$(inherited)", - "-DSINGLE_THREADED_NOTIFY_STATE=1", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 3FA21AC6148AA8F000099D2F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */; - buildSettings = { - CODE_SIGN_ENTITLEMENTS = notifyutil/notifyutil_entitlements.plist; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 3FA21AC9148AA93000099D2F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F999961185C474E00EAD3A0 /* base.xcconfig */; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 72FA84F81BD6E9DF00A4CC6F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; - SUPPORTED_PLATFORMS = "iphoneos macosx watchos appletvos bridgeos"; - }; - name = Release; - }; - 72FA84FD1BD6EAB900A4CC6F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "macosx iphoneos watchos appletvos"; - }; - name = Release; - }; - 94099C782087E7D50004B6BC /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F82235D12B18551005DD509 /* libnotify.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = NO; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = NO; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - INFOPLIST_FILE = xctests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LINK_WITH_STANDARD_LIBRARIES = YES; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_CFLAGS = ( - "$(inherited)", - "-DBUILDING_TESTS=1", - "-fno-lto", - ); - OTHER_MIGFLAGS = "-DBUILDING_TESTS=1"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.xctests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 949B783D208BE1F2002AD6AF /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLY_RULES_IN_COPY_FILES = ""; - CLANG_WARN_ASSIGN_ENUM = YES; - CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - LLVM_LTO = YES; - SUPPORTED_PLATFORMS = "watchsimulator watchos iphonesimulator iphoneos macosx bridgeos appletvsimulator appletvos"; - WARNING_CFLAGS = "-Wno-dollar-in-identifier-extension"; - }; - name = Debug; - }; - 949B783E208BE1F2002AD6AF /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F82235D12B18551005DD509 /* libnotify.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 949B783F208BE1F2002AD6AF /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F999963185C474E00EAD3A0 /* notifyd.xcconfig */; - buildSettings = { - OTHER_CFLAGS = ( - "$(inherited)", - "-DSINGLE_THREADED_NOTIFY_STATE=1", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 949B7840208BE1F2002AD6AF /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */; - buildSettings = { - CODE_SIGN_ENTITLEMENTS = notifyutil/notifyutil_entitlements.plist; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 949B7841208BE1F2002AD6AF /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F999961185C474E00EAD3A0 /* base.xcconfig */; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 949B7842208BE1F2002AD6AF /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; - SUPPORTED_PLATFORMS = "iphoneos macosx watchos appletvos bridgeos"; - }; - name = Debug; - }; - 949B7843208BE1F2002AD6AF /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "macosx iphoneos watchos appletvos"; - }; - name = Debug; - }; - 949B7844208BE1F2002AD6AF /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F82235D12B18551005DD509 /* libnotify.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = NO; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = NO; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - INFOPLIST_FILE = xctests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LINK_WITH_STANDARD_LIBRARIES = YES; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_CFLAGS = ( - "$(inherited)", - "-DDEBUG=1", - "-O0", - "-DBUILDING_TESTS=1", - "-fno-lto", - ); - OTHER_MIGFLAGS = "-DBUILDING_TESTS=1"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.xctests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Debug; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1886391420E1A22F00C8BEA9 /* Build configuration list for PBXNativeTarget "notifybench" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1886391520E1A22F00C8BEA9 /* Release */, - 1886391620E1A22F00C8BEA9 /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "libnotify" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB91ED08733DB70010E9CD /* Release */, - 949B783E208BE1F2002AD6AF /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "Libnotify" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB91F108733DB70010E9CD /* Release */, - 949B783D208BE1F2002AD6AF /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3FA21AB8148AA8E300099D2F /* Build configuration list for PBXNativeTarget "notifyd" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3FA21AB9148AA8E300099D2F /* Release */, - 949B783F208BE1F2002AD6AF /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3FA21AC5148AA8F000099D2F /* Build configuration list for PBXNativeTarget "notifyutil" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3FA21AC6148AA8F000099D2F /* Release */, - 949B7840208BE1F2002AD6AF /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3FA21AC8148AA93000099D2F /* Build configuration list for PBXAggregateTarget "cli_apps" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3FA21AC9148AA93000099D2F /* Release */, - 949B7841208BE1F2002AD6AF /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 72FA84F71BD6E9DF00A4CC6F /* Build configuration list for PBXLegacyTarget "darwintests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 72FA84F81BD6E9DF00A4CC6F /* Release */, - 949B7842208BE1F2002AD6AF /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 72FA84FC1BD6EAB900A4CC6F /* Build configuration list for PBXAggregateTarget "tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 72FA84FD1BD6EAB900A4CC6F /* Release */, - 949B7843208BE1F2002AD6AF /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 94099C792087E7D50004B6BC /* Build configuration list for PBXNativeTarget "xctests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 94099C782087E7D50004B6BC /* Release */, - 949B7844208BE1F2002AD6AF /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/src/libnotify/Libnotify.xcodeproj/xcshareddata/xcschemes/xctests.xcscheme b/src/libnotify/Libnotify.xcodeproj/xcshareddata/xcschemes/xctests.xcscheme deleted file mode 100644 index 3bdcd8937..000000000 --- a/src/libnotify/Libnotify.xcodeproj/xcshareddata/xcschemes/xctests.xcscheme +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libnotify/libnotify.c b/src/libnotify/libnotify.c deleted file mode 100644 index fa1e618ca..000000000 --- a/src/libnotify/libnotify.c +++ /dev/null @@ -1,1098 +0,0 @@ -/* - * Copyright (c) 2003-2012 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libnotify.h" -#include "notify.h" -#include "notify_internal.h" - - -#pragma mark - -const char * -_notify_shm_id(void) -{ -#if TARGET_OS_SIMULATOR - static dispatch_once_t once; - static char *shm_id; - - dispatch_once(&once, ^{ - /* - * According to documentation, our shm_id must be no more than 31 characters long - * but in practice, even 31 characters is too long (), - * so we jump through some hoops to make a smaller string based on our UDID. - */ - const char *udid = getenv("SIMULATOR_UDID"); - if (udid && strlen(udid) == 36) { - char scratch[34]; // 32 characters, 2 NUL - - /* 01234567890123456789012345678901234567890 */ - /* UUUUUUUU-UUUU-UUUU-LLLL-LLLLLLLLLLLL */ - memcpy(scratch, udid, 8); - memcpy(scratch+8, udid+9, 4); - memcpy(scratch+12, udid+14, 4); - scratch[16] = '\0'; - - memcpy(scratch+17, udid+19, 4); - memcpy(scratch+21, udid+24, 12); - scratch[33] = '\0'; - - /* - * If the input is invalid, these will end up being undefined - * values, but they'll still be values we can use. - */ - uint64_t upper = strtoull(scratch, NULL, 16); - uint64_t lower = strtoull(scratch + 17, NULL, 16); - - const char *c64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - scratch[0] = c64[(upper >> 57) & 0xf]; - scratch[1] = c64[(upper >> 50) & 0xf]; - scratch[2] = c64[(upper >> 43) & 0xf]; - scratch[3] = c64[(upper >> 36) & 0xf]; - scratch[4] = c64[(upper >> 29) & 0xf]; - scratch[5] = c64[(upper >> 22) & 0xf]; - scratch[6] = c64[(upper >> 15) & 0xf]; - scratch[7] = c64[(upper >> 8) & 0xf]; - scratch[8] = c64[(upper >> 1) & 0xf]; - /* Drop a bit on the floor, but that probably doesn't matter. It does not need to be reversible */ - - scratch[10] = c64[(lower >> 57) & 0xf]; - scratch[11] = c64[(lower >> 50) & 0xf]; - scratch[12] = c64[(lower >> 43) & 0xf]; - scratch[13] = c64[(lower >> 36) & 0xf]; - scratch[14] = c64[(lower >> 29) & 0xf]; - scratch[15] = c64[(lower >> 22) & 0xf]; - scratch[16] = c64[(lower >> 15) & 0xf]; - scratch[17] = c64[(lower >> 8) & 0xf]; - scratch[18] = c64[(lower >> 1) & 0xf]; - /* Drop a bit on the floor, but that probably doesn't matter. It does not need to be reversible */ - - scratch[19] = '\0'; - - asprintf(&shm_id, "sim.not.%s", scratch); - assert(shm_id); - } - - if (shm_id == NULL) - { - shm_id = "apple.shm.notification_center"; - } - }); - - return shm_id; -#else - return "apple.shm.notification_center"; -#endif -} - -inline uint64_t -make_client_id(pid_t pid, int token) -{ - union client_id cid = { - .pid = pid, - .token = token, - }; - return cid.hash_key; -} - -void -_notify_lib_notify_state_init(notify_state_t * ns, uint32_t flags) -{ -#ifdef SINGLE_THREADED_NOTIFY_STATE - assert((flags & NOTIFY_STATE_USE_LOCKS) == 0); -#endif - ns->flags = flags; - ns->sock = -1; - ns->lock = OS_UNFAIR_LOCK_INIT; - _nc_table_init(&ns->name_table, offsetof(name_info_t, name)); - _nc_table_init_64(&ns->name_id_table, offsetof(name_info_t, name_id)); - _nc_table_init_64(&ns->client_table, offsetof(client_t, cid.hash_key)); - _nc_table_init_n(&ns->port_table, offsetof(port_data_t, port)); - _nc_table_init_n(&ns->proc_table, offsetof(proc_data_t, pid)); -} - -// We only need to lock in the client -inline static void -_notify_state_lock(os_unfair_lock_t lock) -{ -#ifndef SINGLE_THREADED_NOTIFY_STATE - os_unfair_lock_lock_with_options(lock, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); -#endif -} - -inline static void -_notify_state_unlock(os_unfair_lock_t lock) -{ -#ifndef SINGLE_THREADED_NOTIFY_STATE - os_unfair_lock_unlock(lock); -#endif -} - -static client_t * -_internal_client_new(notify_state_t *ns, pid_t pid, int token, name_info_t *n) -{ - client_t *c; - uint64_t cid = make_client_id(pid, token); - - /* detect duplicates - should never happen, but it would be bad */ - c = _nc_table_find_64(&ns->client_table, cid); - if (c != NULL) return NULL; - - c = calloc(1, sizeof(client_t)); - if (c == NULL) return NULL; - - ns->stat_client_alloc++; - c->cid.hash_key = cid; - c->name_info = n; - - LIST_INSERT_HEAD(&n->subscriptions, c, client_subscription_entry); - n->refcount++; - - _nc_table_insert_64(&ns->client_table, &c->cid.hash_key); - return c; -} - -static void -_internal_client_release(notify_state_t *ns, client_t *c) -{ - _nc_table_delete_64(&ns->client_table, c->cid.hash_key); - - if (c->state_and_type & NOTIFY_TYPE_FILE) { - if (c->deliver.fd >= 0) close(c->deliver.fd); - } else if (c->state_and_type & NOTIFY_TYPE_PORT) { - /* release my send right to the port */ - mach_port_deallocate(mach_task_self(), c->deliver.port); - } - - free(c); - ns->stat_client_free++; -} - -static name_info_t * -_internal_new_name(notify_state_t *ns, const char *name) -{ - name_info_t *n; - size_t namelen; - - if (name == NULL) return NULL; - - namelen = strlen(name) + 1; - - n = (name_info_t *)calloc(1, sizeof(name_info_t) + namelen); - if (n == NULL) return NULL; - - ns->stat_name_alloc++; - - n->name = (char *)n + sizeof(name_info_t); - memcpy(n->name, name, namelen); - - n->name_id = ns->name_id++; - n->access = NOTIFY_ACCESS_DEFAULT; - n->slot = (uint32_t)-1; - n->val = 1; - - LIST_INIT(&n->subscriptions); - - _nc_table_insert(&ns->name_table, &n->name); - _nc_table_insert_64(&ns->name_id_table, &n->name_id); - - return n; -} - -static void -_internal_insert_controlled_name(notify_state_t *ns, name_info_t *n) -{ - int i, j; - - if (n == NULL) return; - - if (ns->controlled_name == NULL) ns->controlled_name_count = 0; - - for (i = 0; i < ns->controlled_name_count; i++) - { - if (ns->controlled_name[i] == n) return; - } - - ns->controlled_name = (name_info_t **)reallocf(ns->controlled_name, (ns->controlled_name_count + 1) * sizeof(name_info_t *)); - - /* - * Insert name in reverse sorted order (longer names preceed shorter names). - * this means that in _internal_check_access, we check subspaces from the bottom up - * i.e. we check access for the "deepest" controlled subspace. - */ - - for (i = 0; i < ns->controlled_name_count; i++) - { - if (strcmp(n->name, ns->controlled_name[i]->name) > 0) break; - } - - for (j = ns->controlled_name_count; j > i; j--) - { - ns->controlled_name[j] = ns->controlled_name[j-1]; - } - - ns->controlled_name[i] = n; - ns->controlled_name_count++; -} - -static void -_internal_remove_controlled_name(notify_state_t *ns, name_info_t *n) -{ - uint32_t i, j; - - for (i = 0; i < ns->controlled_name_count; i++) - { - if (ns->controlled_name[i] == n) - { - for (j = i + 1; j < ns->controlled_name_count; j++) - { - ns->controlled_name[j-1] = ns->controlled_name[j]; - } - - ns->controlled_name_count--; - if (ns->controlled_name_count == 0) - { - free(ns->controlled_name); - ns->controlled_name = NULL; - } - else - { - ns->controlled_name = (name_info_t **)reallocf(ns->controlled_name, ns->controlled_name_count * sizeof(name_info_t *)); - } - - return; - } - } -} - -static uint32_t -_internal_check_access(notify_state_t *ns, const char *name, uid_t uid, gid_t gid, int req) -{ - uint32_t i; - size_t len, plen; - name_info_t *p; - char str[64]; - - if (name == NULL) return NOTIFY_STATUS_NULL_INPUT; - - /* root may do anything */ - if (uid == 0) return NOTIFY_STATUS_OK; - - /* if name has "user.uid." as a prefix, it is a user-protected namespace */ - if (!strncmp(name, USER_PROTECTED_UID_PREFIX, USER_PROTECTED_UID_PREFIX_LEN)) - { - snprintf(str, sizeof(str) - 1, "%s%d", USER_PROTECTED_UID_PREFIX, uid); - len = strlen(str); - - /* user may access user.uid. or a subtree name */ - if ((!strncmp(name, str, len)) && ((name[len] == '\0') || (name[len] == '.'))) return NOTIFY_STATUS_OK; - return NOTIFY_STATUS_NOT_AUTHORIZED; - } - - len = strlen(name); - - if (ns->controlled_name == NULL) ns->controlled_name_count = 0; - for (i = 0; i < ns->controlled_name_count; i++) - { - p = ns->controlled_name[i]; - if (p == NULL) break; - if (p->name == NULL) continue; - - plen = strlen(p->name); - if (plen > len) continue; - if (strncmp(p->name, name, plen)) continue; - - /* Found a match or a prefix, check if restrictions apply to this uid/gid */ - if ((p->uid == uid) && (p->access & (req << NOTIFY_ACCESS_USER_SHIFT))) break; - if ((p->gid == gid) && (p->access & (req << NOTIFY_ACCESS_GROUP_SHIFT))) break; - if (p->access & (req << NOTIFY_ACCESS_OTHER_SHIFT)) break; - - return NOTIFY_STATUS_NOT_AUTHORIZED; - } - - return NOTIFY_STATUS_OK; -} - -uint32_t -_notify_lib_check_controlled_access(notify_state_t *ns, char *name, uid_t uid, gid_t gid, int req) -{ - uint32_t status; - - _notify_state_lock(&ns->lock); - status = _internal_check_access(ns, name, uid, gid, req); - _notify_state_unlock(&ns->lock); - - return status; -} - -/* - * Send notification to a subscriber - */ -static uint32_t -_internal_send(notify_state_t *ns, client_t *c, - proc_data_t *proc_data, port_data_t *port_data) -{ - uint32_t send; - - if (c->state_and_type & NOTIFY_CLIENT_STATE_SUSPENDED) - { - c->state_and_type |= NOTIFY_CLIENT_STATE_PENDING; - return NOTIFY_STATUS_OK; - } - - if (proc_data == NULL) - { - proc_data = _nc_table_find_n(&ns->proc_table, c->cid.pid); - } - if ((proc_data != NULL) && (proc_data->flags & NOTIFY_PORT_PROC_STATE_SUSPENDED)) - { - c->suspend_count++; - c->state_and_type |= NOTIFY_CLIENT_STATE_SUSPENDED; - c->state_and_type |= NOTIFY_CLIENT_STATE_PENDING; - return NOTIFY_STATUS_OK; - } - - send = c->cid.token; - - switch (c->state_and_type & NOTIFY_TYPE_MASK) - { - case NOTIFY_TYPE_SIGNAL: - { - int rc = 0; - - if (c->cid.pid == NOTIFY_CLIENT_SELF) rc = kill(getpid(), c->deliver.sig); - else rc = kill(c->cid.pid, c->deliver.sig); - - if (rc != 0) return NOTIFY_STATUS_KILL_FAILED; - - c->state_and_type &= ~NOTIFY_CLIENT_STATE_PENDING; - c->state_and_type &= ~NOTIFY_CLIENT_STATE_TIMEOUT; - - return NOTIFY_STATUS_OK; - } - - case NOTIFY_TYPE_FILE: - { - ssize_t len; - - if (c->deliver.fd >= 0) - { - send = htonl(send); - len = write(c->deliver.fd, &send, sizeof(uint32_t)); - if (len != sizeof(uint32_t)) - { - close(c->deliver.fd); - c->deliver.fd = -1; - return NOTIFY_STATUS_WRITE_FAILED; - } - } - - c->state_and_type &= ~NOTIFY_CLIENT_STATE_PENDING; - c->state_and_type &= ~NOTIFY_CLIENT_STATE_TIMEOUT; - - return NOTIFY_STATUS_OK; - } - - case NOTIFY_TYPE_PORT: - { - kern_return_t kstatus; - mach_msg_empty_send_t msg; - mach_msg_option_t opts = MACH_SEND_MSG | MACH_SEND_TIMEOUT; - - if (port_data == NULL) - { - port_data = _nc_table_find_n(&ns->port_table, c->deliver.port); - } - if ((port_data != NULL) && (port_data->flags & NOTIFY_PORT_PROC_STATE_SUSPENDED)) - { - c->suspend_count++; - c->state_and_type |= NOTIFY_CLIENT_STATE_SUSPENDED; - c->state_and_type |= NOTIFY_CLIENT_STATE_PENDING; - return NOTIFY_STATUS_OK; - } - - if (ns->flags & NOTIFY_STATE_ENABLE_RESEND) opts |= MACH_SEND_NOTIFY; - - memset(&msg, 0, sizeof(mach_msg_empty_send_t)); - msg.header.msgh_size = sizeof(mach_msg_empty_send_t); - msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSGH_BITS_ZERO); - msg.header.msgh_local_port = MACH_PORT_NULL; - msg.header.msgh_remote_port = c->deliver.port; - msg.header.msgh_id = (mach_msg_id_t)send; - - kstatus = mach_msg(&msg.header, opts, msg.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - if (kstatus == MACH_SEND_TIMED_OUT) - { - /* deallocate port rights obtained via pseudo-receive after failed mach_msg() send */ - mach_msg_destroy(&msg.header); - if (ns->flags & NOTIFY_STATE_ENABLE_RESEND) - { - /* - * Suspend on timeout. - * notifyd will get a MACH_NOTIFY_SEND_POSSIBLE and trigger a retry. - * c->suspend_count must be zero, or we would not be trying to send. - */ - c->suspend_count++; - c->state_and_type |= NOTIFY_CLIENT_STATE_SUSPENDED; - c->state_and_type |= NOTIFY_CLIENT_STATE_PENDING; - c->state_and_type |= NOTIFY_CLIENT_STATE_TIMEOUT; - - if (port_data) { - /* - * If we failed to send, stop trying on this port - * and just wait for the send-possible notification - */ - port_data->flags |= NOTIFY_PORT_PROC_STATE_SUSPENDED; - } - return NOTIFY_STATUS_OK; - } - - return NOTIFY_STATUS_MACH_MSG_TIMEOUT; - } - else if (kstatus != KERN_SUCCESS) return NOTIFY_STATUS_MACH_MSG_FAILED; - - c->state_and_type &= ~NOTIFY_CLIENT_STATE_PENDING; - c->state_and_type &= ~NOTIFY_CLIENT_STATE_TIMEOUT; - - return NOTIFY_STATUS_OK; - } - - default: - { - break; - } - } - - c->state_and_type &= ~NOTIFY_CLIENT_STATE_PENDING; - c->state_and_type &= ~NOTIFY_CLIENT_STATE_TIMEOUT; - - return NOTIFY_STATUS_OK; -} - -uint32_t -_notify_lib_post_client(notify_state_t *ns, client_t *c) -{ - uint32_t status; - - if (c == NULL) return NOTIFY_STATUS_NULL_INPUT; - - _notify_state_lock(&ns->lock); - status = _internal_send(ns, c, NULL, NULL); - _notify_state_unlock(&ns->lock); - - return status; -} - -static uint32_t -_internal_post_name(notify_state_t *ns, name_info_t *n, uid_t uid, gid_t gid) -{ - int auth; - client_t *c; - - if (n == NULL) return NOTIFY_STATUS_INVALID_NAME; - - auth = _internal_check_access(ns, n->name, uid, gid, NOTIFY_ACCESS_WRITE); - if (auth != 0) return NOTIFY_STATUS_NOT_AUTHORIZED; - - n->val++; - - LIST_FOREACH(c, &n->subscriptions, client_subscription_entry) { - _internal_send(ns, c, NULL, NULL); - } - - return NOTIFY_STATUS_OK; -} - -/* - * Notify subscribers of this name. - */ -uint32_t -_notify_lib_post(notify_state_t *ns, const char *name, uid_t uid, gid_t gid) -{ - name_info_t *n; - uint32_t status; - - _notify_state_lock(&ns->lock); - - n = _nc_table_find(&ns->name_table, name); - if (n == NULL) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_INVALID_NAME; - } - - status = _internal_post_name(ns, n, uid, gid); - - _notify_state_unlock(&ns->lock); - return status; -} - -uint32_t -_notify_lib_post_nid(notify_state_t *ns, uint64_t nid, uid_t uid, gid_t gid) -{ - name_info_t *n; - uint32_t status; - - _notify_state_lock(&ns->lock); - - n = _nc_table_find_64(&ns->name_id_table, nid); - if (n == NULL) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_INVALID_NAME; - } - - status = _internal_post_name(ns, n, uid, gid); - - _notify_state_unlock(&ns->lock); - return status; -} - -static void -_internal_release_name_info(notify_state_t *ns, name_info_t *n) -{ - if (n == NULL) return; - - if (n->refcount > 0) n->refcount--; - if (n->refcount == 0) - { - _internal_remove_controlled_name(ns, n); - _nc_table_delete(&ns->name_table, n->name); - _nc_table_delete_64(&ns->name_id_table, n->name_id); - free(n); - ns->stat_name_free++; - } -} - -/* - * Cancel (delete) a client - */ -static void -_internal_cancel(notify_state_t *ns, client_t *c) -{ - name_info_t *n = c->name_info; - - LIST_REMOVE(c, client_subscription_entry); - _internal_client_release(ns, c); - _internal_release_name_info(ns, n); -} - -void -_notify_lib_cancel_client(notify_state_t *ns, client_t *c) -{ - _notify_state_lock(&ns->lock); - _internal_cancel(ns, c); - _notify_state_unlock(&ns->lock); -} - -void -_notify_lib_cancel(notify_state_t *ns, pid_t pid, int token) -{ - uint64_t cid = make_client_id(pid, token); - client_t *c; - - _notify_state_lock(&ns->lock); - c = _nc_table_find_64(&ns->client_table, cid); - if (c) { - _internal_cancel(ns, c); - } - _notify_state_unlock(&ns->lock); -} - -uint32_t -_notify_lib_suspend(notify_state_t *ns, pid_t pid, int token) -{ - uint64_t cid = make_client_id(pid, token); - uint32_t result = NOTIFY_STATUS_OK; - client_t *c; - - _notify_state_lock(&ns->lock); - - c = _nc_table_find_64(&ns->client_table, cid); - if (c != NULL) { - c->state_and_type |= NOTIFY_CLIENT_STATE_SUSPENDED; - if (c->suspend_count < UINT8_MAX) c->suspend_count++; - } else { - result = NOTIFY_STATUS_CLIENT_NOT_FOUND; - } - - _notify_state_unlock(&ns->lock); - - return result; -} - -static void -_internal_resume(notify_state_t *ns, client_t *c, - proc_data_t *proc_data, port_data_t *port_data) -{ - if (c->suspend_count > 0) c->suspend_count--; - if (c->suspend_count == 0) { - c->state_and_type &= ~NOTIFY_CLIENT_STATE_SUSPENDED; - c->state_and_type &= ~NOTIFY_CLIENT_STATE_TIMEOUT; - - if (c->state_and_type & NOTIFY_CLIENT_STATE_PENDING) { - _internal_send(ns, c, proc_data, port_data); - } - } -} - -void -_notify_lib_resume_client(notify_state_t *ns, client_t *c, - proc_data_t *proc_data, port_data_t *port_data) -{ - _notify_state_lock(&ns->lock); - _internal_resume(ns, c, proc_data, port_data); - _notify_state_unlock(&ns->lock); -} - -uint32_t -_notify_lib_resume(notify_state_t *ns, pid_t pid, int token) -{ - uint32_t status = NOTIFY_STATUS_OK; - uint64_t cid = make_client_id(pid, token); - client_t *c; - - _notify_state_lock(&ns->lock); - - c = _nc_table_find_64(&ns->client_table, cid); - if (c != NULL) { - _internal_resume(ns, c, NULL, NULL); - } else { - status = NOTIFY_STATUS_CLIENT_NOT_FOUND; - } - - _notify_state_unlock(&ns->lock); - - return status; -} - -/* - * Check if a name has changed since the last time this client checked. - * Returns true, false, or error. - */ -uint32_t -_notify_lib_check(notify_state_t *ns, pid_t pid, int token, int *check) -{ - client_t *c; - uint64_t cid; - - if (check == NULL) return NOTIFY_STATUS_NULL_INPUT; - - cid = make_client_id(pid, token); - - _notify_state_lock(&ns->lock); - - c = _nc_table_find_64(&ns->client_table, cid); - - if (c == NULL) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (c->name_info->val == c->lastval) - { - *check = 0; - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; - } - - c->lastval = c->name_info->val; - *check = 1; - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -/* - * SPI: get value for a name. - */ -__private_extern__ uint32_t -_notify_lib_peek(notify_state_t *ns, pid_t pid, int token, int *val) -{ - client_t *c; - uint64_t cid; - - if (val == NULL) return NOTIFY_STATUS_NULL_INPUT; - - cid = make_client_id(pid, token); - - _notify_state_lock(&ns->lock); - - c = _nc_table_find_64(&ns->client_table, cid); - - if (c == NULL) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_INVALID_TOKEN; - } - - *val = c->name_info->val; - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -/* - * Get state value for a name. - */ -uint32_t -_notify_lib_get_state(notify_state_t *ns, uint64_t nid, uint64_t *state, uid_t uid, gid_t gid) -{ - name_info_t *n; - - if (state == NULL) return NOTIFY_STATUS_NULL_INPUT; - - *state = 0; - - _notify_state_lock(&ns->lock); - - n = _nc_table_find_64(&ns->name_id_table, nid); - - if (n == NULL) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_INVALID_NAME; - } - -#ifdef GET_STATE_AUTH_CHECK - int auth = _internal_check_access(ns, n->name, uid, gid, NOTIFY_ACCESS_READ); - if (auth != 0) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_NOT_AUTHORIZED; - } -#endif - - *state = n->state; - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -/* - * Set state value for a name. - */ -uint32_t -_notify_lib_set_state(notify_state_t *ns, uint64_t nid, uint64_t state, uid_t uid, gid_t gid) -{ - name_info_t *n; - int auth; - - _notify_state_lock(&ns->lock); - - n = _nc_table_find_64(&ns->name_id_table, nid); - - if (n == NULL) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_INVALID_NAME; - } - - auth = _internal_check_access(ns, n->name, uid, gid, NOTIFY_ACCESS_WRITE); - if (auth != 0) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_NOT_AUTHORIZED; - } - - n->state = state; - n->state_time = mach_absolute_time(); - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -static uint32_t -_internal_register_common(notify_state_t *ns, const char *name, pid_t pid, int token, uid_t uid, gid_t gid, client_t **outc) -{ - client_t *c; - name_info_t *n; - int is_new_name; - uint32_t status; - - if (name == NULL) return NOTIFY_STATUS_INVALID_NAME; - if (outc == NULL) return NOTIFY_STATUS_OK; - - status = _internal_check_access(ns, name, uid, gid, NOTIFY_ACCESS_READ); - if (status != NOTIFY_STATUS_OK) return NOTIFY_STATUS_NOT_AUTHORIZED; - - *outc = NULL; - is_new_name = 0; - - n = _nc_table_find(&ns->name_table, name); - if (n == NULL) - { - is_new_name = 1; - - n = _internal_new_name(ns, name); - if (n == NULL) return NOTIFY_STATUS_NEW_NAME_FAILED; - } - - c = _internal_client_new(ns, pid, token, n); - if (c == NULL) - { - if (is_new_name == 1) - { - _nc_table_delete(&ns->name_table, n->name); - free(n); - ns->stat_name_free++; - } - - return NOTIFY_STATUS_NEW_CLIENT_FAILED; - } - - *outc = c; - - return NOTIFY_STATUS_OK; -} - -/* - * Register for signal. - * Returns the client_id; - */ -uint32_t -_notify_lib_register_signal(notify_state_t *ns, const char *name, pid_t pid, int token, uint32_t sig, uid_t uid, gid_t gid, uint64_t *out_nid) -{ - client_t *c; - uint32_t status; - - if (name == NULL) return NOTIFY_STATUS_INVALID_NAME; - - c = NULL; - - _notify_state_lock(&ns->lock); - - status = _internal_register_common(ns, name, pid, token, uid, gid, &c); - if (status != NOTIFY_STATUS_OK) - { - _notify_state_unlock(&ns->lock); - return status; - } - - c->state_and_type &= ~NOTIFY_TYPE_MASK; - c->state_and_type |= NOTIFY_TYPE_SIGNAL; - c->cid.pid = pid; - c->deliver.sig = sig; - *out_nid = c->name_info->name_id; - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -/* - * Register for notification on a file descriptor. - * Returns the client_id; - */ -uint32_t -_notify_lib_register_file_descriptor(notify_state_t *ns, const char *name, pid_t pid, int token, int fd, uid_t uid, gid_t gid, uint64_t *out_nid) -{ - client_t *c; - uint32_t status; - - if (name == NULL) return NOTIFY_STATUS_INVALID_NAME; - - c = NULL; - - _notify_state_lock(&ns->lock); - - status = _internal_register_common(ns, name, pid, token, uid, gid, &c); - if (status != NOTIFY_STATUS_OK) - { - _notify_state_unlock(&ns->lock); - return status; - } - - c->state_and_type &= ~NOTIFY_TYPE_MASK; - c->state_and_type |= NOTIFY_TYPE_FILE; - - c->deliver.fd = fd; - *out_nid = c->name_info->name_id; - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -/* - * Register for notification on a mach port. - * Returns the client_id; - */ -uint32_t -_notify_lib_register_mach_port(notify_state_t *ns, const char *name, pid_t pid, int token, mach_port_t port, uid_t uid, gid_t gid, uint64_t *out_nid) -{ - client_t *c; - uint32_t status; - - if (name == NULL) return NOTIFY_STATUS_INVALID_NAME; - if (!MACH_PORT_VALID(port)) return NOTIFY_STATUS_INVALID_PORT; - - c = NULL; - - _notify_state_lock(&ns->lock); - - status = _internal_register_common(ns, name, pid, token, uid, gid, &c); - if (status != NOTIFY_STATUS_OK) - { - _notify_state_unlock(&ns->lock); - return status; - } - - c->state_and_type &= ~NOTIFY_TYPE_MASK; - c->state_and_type |= NOTIFY_TYPE_PORT; - c->deliver.port = port; - *out_nid = c->name_info->name_id; - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -/* - * Plain registration - only for notify_check() - * Returns the client_id. - */ -uint32_t -_notify_lib_register_plain(notify_state_t *ns, const char *name, pid_t pid, int token, uint32_t slot, uint32_t uid, uint32_t gid, uint64_t *out_nid) -{ - client_t *c; - uint32_t status; - - if (name == NULL) return NOTIFY_STATUS_INVALID_NAME; - - c = NULL; - - _notify_state_lock(&ns->lock); - - status = _internal_register_common(ns, name, pid, token, uid, gid, &c); - if (status != NOTIFY_STATUS_OK) - { - _notify_state_unlock(&ns->lock); - return status; - } - - if (slot == SLOT_NONE) - { - c->state_and_type &= ~NOTIFY_TYPE_MASK; - c->state_and_type |= NOTIFY_TYPE_PLAIN; - } - else - { - c->state_and_type &= ~NOTIFY_TYPE_MASK; - c->state_and_type |= NOTIFY_TYPE_MEMORY; - c->name_info->slot = slot; - } - - *out_nid = c->name_info->name_id; - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -uint32_t -_notify_lib_set_owner(notify_state_t *ns, const char *name, uid_t uid, gid_t gid) -{ - name_info_t *n; - - if (name == NULL) return NOTIFY_STATUS_INVALID_NAME; - - _notify_state_lock(&ns->lock); - - n = _nc_table_find(&ns->name_table, name); - if (n == NULL) - { - /* create new name */ - n = _internal_new_name(ns, name); - if (n == NULL) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_NEW_NAME_FAILED; - } - - /* - * Setting the refcount here allows the namespace to be "pre-populated" - * with controlled names. notifyd does this for reserved names in - * its configuration file. - */ - n->refcount++; - } - - n->uid = uid; - n->gid = gid; - - _internal_insert_controlled_name(ns, n); - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} - -uint32_t -_notify_lib_set_access(notify_state_t *ns, const char *name, uint32_t mode) -{ - name_info_t *n; - - if (name == NULL) return NOTIFY_STATUS_INVALID_NAME; - - _notify_state_lock(&ns->lock); - - n = _nc_table_find(&ns->name_table, name); - if (n == NULL) - { - /* create new name */ - n = _internal_new_name(ns, name); - if (n == NULL) - { - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_NEW_NAME_FAILED; - } - - /* - * Setting the refcount here allows the namespace to be "pre-populated" - * with controlled names. notifyd does this for reserved names in - * its configuration file. - */ - n->refcount++; - } - - n->access = mode; - - _internal_insert_controlled_name(ns, n); - - _notify_state_unlock(&ns->lock); - return NOTIFY_STATUS_OK; -} diff --git a/src/libnotify/libnotify.h b/src/libnotify/libnotify.h deleted file mode 100644 index 96bbd8a7e..000000000 --- a/src/libnotify/libnotify.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2003-2012 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _LIBNOTIFY_H_ -#define _LIBNOTIFY_H_ - -#include -#include -#include -#include -#include -#include "table.h" - -#include - -extern const char *_notify_shm_id(void); -#define SHM_ID _notify_shm_id() - -#define NOTIFY_IPC_VERSION_NAME "com.apple.system.notify.ipc_version" -#define NOTIFY_IPC_VERSION_NAME_LEN 35 -#define NOTIFY_SERVICE_NAME "com.apple.system.notification_center" -#define NOTIFY_SERVICE_NAME_LEN 36 -#define NOTIFY_IPC_VERSION_MIN_SUPPORTED 3 -#define NOTIFY_IPC_VERSION 3 - -/* extra internal flags to notify_register_mach_port */ -/* Make sure this doesn't conflict with any flags in notify.h or notify_private.h */ -#define _NOTIFY_COMMON_PORT 0x40000000 - -/* Notification types */ -#define NOTIFY_TYPE_NONE 0x00000000 -#define NOTIFY_TYPE_MEMORY 0x00000001 -#define NOTIFY_TYPE_PLAIN 0x00000002 -#define NOTIFY_TYPE_PORT 0x00000004 -#define NOTIFY_TYPE_FILE 0x00000008 -#define NOTIFY_TYPE_SIGNAL 0x00000010 -#define NOTIFY_TYPE_MASK 0x0000001f // If this is changed, make sure it doesn't muck with struct client_s -#define NOTIFY_FLAG_SELF 0x80000000 -#define NOTIFY_FLAG_REGEN 0x40000000 -#define NOTIFY_FLAG_RELEASE_SEND 0x20000000 -#define NOTIFY_FLAG_DISPATCH 0x10000000 -#define NOTIFY_TYPE_COALESCE_BASE 0x08000000 -#define NOTIFY_TYPE_COALESCED 0x04000000 -#define NOTIFY_FLAG_RETAINED 0x02000000 -#define NOTIFY_FLAG_CANCELED 0x01000000 - -/* Used to check for a polled or delivered types */ -#define NOTIFY_TYPE_POLLED (NOTIFY_TYPE_MEMORY | NOTIFY_TYPE_PLAIN) -#define NOTIFY_TYPE_DELIVERED (NOTIFY_TYPE_PORT | NOTIFY_TYPE_FILE | NOTIFY_TYPE_SIGNAL) - -/* Return values for notify_check() */ -#define NOTIFY_CHECK_FALSE 0 -#define NOTIFY_CHECK_TRUE 1 -#define NOTIFY_CHECK_ERROR 2 - -/* Access control */ -#define NOTIFY_ACCESS_READ 1 -#define NOTIFY_ACCESS_WRITE 2 - -#define NOTIFY_ACCESS_OTHER_SHIFT 8 -#define NOTIFY_ACCESS_GROUP_SHIFT 4 -#define NOTIFY_ACCESS_USER_SHIFT 0 - -#define NOTIFY_ACCESS_DEFAULT 0x00000333 -#define NOTIFY_ACCESS_USER_RW 0x00000003 - -/* Filesystem Services */ -#define NOTIFY_SERVICE_FILE_STATUS_QUO 0x00 -#define NOTIFY_SERVICE_FILE_ADD 0x01 -#define NOTIFY_SERVICE_FILE_DELETE 0x02 -#define NOTIFY_SERVICE_FILE_MODIFY 0x04 -#define NOTIFY_SERVICE_FILE_ATTR 0x08 - -#define NOTIFY_SERVICE_DIR_FILE_ADD 0x10 -#define NOTIFY_SERVICE_DIR_FILE_DELETE 0x20 - -#define NOTIFY_CLIENT_STATE_SUSPENDED 0x00000020 -#define NOTIFY_CLIENT_STATE_PENDING 0x00000040 -#define NOTIFY_CLIENT_STATE_TIMEOUT 0x00000080 - -/* port_data_t::flags and proc_data_t::flags */ -#define PORT_PROC_FLAGS_NONE 0x00000000 -#define NOTIFY_PORT_PROC_STATE_SUSPENDED 0x00000001 - -/* notify state flags */ -#define NOTIFY_STATE_USE_LOCKS 0x00000001 -#define NOTIFY_STATE_ENABLE_RESEND 0x00000002 - -#define NOTIFY_CLIENT_SELF 0 -#define SIGNAL_NONE -1 -#define FD_NONE -1 -#define SLOT_NONE -1 - -typedef struct -{ - LIST_HEAD(, client_s) subscriptions; - char *name; - void *private; - uint64_t name_id; - uint64_t state; - uint64_t state_time; - uint32_t uid; - uint32_t gid; - uint32_t access; - uint32_t slot; - uint32_t refcount; - uint32_t val; - uint32_t postcount; - uint32_t last_hour_postcount; -} name_info_t; - -typedef union client_delivery_u -{ - int fd; - mach_port_t port; - uint32_t sig; -} client_delivery_t; - -typedef struct client_s -{ - LIST_ENTRY(client_s) client_subscription_entry; - LIST_ENTRY(client_s) client_pid_entry; - LIST_ENTRY(client_s) client_port_entry; - name_info_t *name_info; - client_delivery_t deliver; - union client_id { - struct { - uint32_t token; - uint32_t pid; - }; - uint64_t hash_key; - } cid; - uint32_t lastval; - uint16_t service_index; - uint8_t suspend_count; - uint8_t state_and_type; -} client_t; - -typedef struct -{ - LIST_HEAD(, client_s) clients; - uint32_t port; - uint32_t flags; -} port_data_t; - -typedef struct -{ - LIST_HEAD(, client_s) clients; - dispatch_source_t src; - uint32_t pid; - uint32_t flags; -} proc_data_t; - -typedef struct -{ - /* last allocated name id */ - uint64_t name_id; - table_t name_table; - table_64_t name_id_table; - table_64_t client_table; - table_n_t port_table; - table_n_t proc_table; - name_info_t **controlled_name; - uint32_t flags; - uint32_t controlled_name_count; - os_unfair_lock lock; - int sock; - uint32_t stat_name_alloc; - uint32_t stat_name_free; - uint32_t stat_client_alloc; - uint32_t stat_client_free; - uint32_t stat_portproc_alloc; - uint32_t stat_portproc_free; -} notify_state_t; - -void _notify_lib_notify_state_init(notify_state_t * ns, uint32_t flags); - -uint32_t _notify_lib_post(notify_state_t *ns, const char *name, uint32_t uid, uint32_t gid); -uint32_t _notify_lib_post_nid(notify_state_t *ns, uint64_t nid, uid_t uid, gid_t gid); -uint32_t _notify_lib_post_client(notify_state_t *ns, client_t *c); - -uint32_t _notify_lib_check(notify_state_t *ns, pid_t pid, int token, int *check); -uint32_t _notify_lib_get_state(notify_state_t *ns, uint64_t nid, uint64_t *state, uint32_t uid, uint32_t gid); -uint32_t _notify_lib_set_state(notify_state_t *ns, uint64_t nid, uint64_t state, uint32_t uid, uint32_t gid); - -uint32_t _notify_lib_register_plain(notify_state_t *ns, const char *name, pid_t pid, int token, uint32_t slot, uint32_t uid, uint32_t gid, uint64_t *out_nid); -uint32_t _notify_lib_register_signal(notify_state_t *ns, const char *name, pid_t pid, int token, uint32_t sig, uint32_t uid, uint32_t gid, uint64_t *out_nid); -uint32_t _notify_lib_register_mach_port(notify_state_t *ns, const char *name, pid_t pid, int token, mach_port_t port, uint32_t uid, uint32_t gid, uint64_t *out_nid); -uint32_t _notify_lib_register_file_descriptor(notify_state_t *ns, const char *name, pid_t pid, int token, int fd, uint32_t uid, uint32_t gid, uint64_t *out_nid); - -uint32_t _notify_lib_set_owner(notify_state_t *ns, const char *name, uint32_t uid, uint32_t gid); -uint32_t _notify_lib_set_access(notify_state_t *ns, const char *name, uint32_t access); - -void _notify_lib_resume_client(notify_state_t *ns, client_t *c, proc_data_t *proc_data, port_data_t *port_data); -void _notify_lib_cancel_client(notify_state_t *ns, client_t *c); - -void _notify_lib_cancel(notify_state_t *ns, pid_t pid, int token); -uint32_t _notify_lib_suspend(notify_state_t *ns, pid_t pid, int token); -uint32_t _notify_lib_resume(notify_state_t *ns, pid_t pid, int token); - -uint32_t _notify_lib_check_controlled_access(notify_state_t *ns, char *name, uid_t uid, gid_t gid, int req); - -uint64_t make_client_id(pid_t pid, int token); - - -#endif /* _LIBNOTIFY_H_ */ diff --git a/src/libnotify/notify.3 b/src/libnotify/notify.3 deleted file mode 100644 index 259f0944d..000000000 --- a/src/libnotify/notify.3 +++ /dev/null @@ -1,472 +0,0 @@ -.\" Copyright (c) 2003-2014 Apple Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" Portions Copyright (c) 2003-2010 Apple Inc. All Rights Reserved. -.\" -.\" This file contains Original Code and/or Modifications of Original Code -.\" as defined in and that are subject to the Apple Public Source License -.\" Version 2.0 (the 'License'). You may not use this file except in -.\" compliance with the License. Please obtain a copy of the License at -.\" http://www.opensource.apple.com/apsl/ and read it before using this -.\" file. -.\" -.\" The Original Code and all software distributed under the License are -.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. -.\" Please see the License for the specific language governing rights and -.\" limitations under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.\" -.Dd September 3, 2008 -.Dt notify 3 -.Os "Mac OS X" -.Sh NAME -.Nm notify_post , -.Nm notify_register_check , -.Nm notify_register_dispatch , -.Nm notify_register_signal , -.Nm notify_register_mach_port , -.Nm notify_register_file_descriptor , -.Nm notify_check , -.Nm notify_get_state , -.Nm notify_set_state , -.Nm notify_suspend , -.Nm notify_resume , -.Nm notify_cancel , -.Nm notify_is_valid_token -.Nd event distribution functions -.Sh SYNOPSIS -.Fd #include -.Ft uint32_t -.Fn notify_post "const char *name" -.Ft uint32_t -.Fn notify_register_check "const char *name, int *out_token" -.Ft void -.Fn (^notify_handler_t) "int token" -.Ft uint32_t -.Fn notify_register_dispatch "const char *name, int *out_token" "dispatch_queue_t queue" "notify_handler_t handler" -.Ft uint32_t -.Fn notify_register_signal "const char *name, int sig, int *out_token" -.Ft uint32_t -.Fn notify_register_mach_port "const char *name, mach_port_t *notify_port, int flags, int *out_token" -.Ft uint32_t -.Fn notify_register_file_descriptor "const char *name, int *notify_fd, int flags, int *out_token" -.Ft uint32_t -.Fn notify_check "int token, int *check" -.Ft uint32_t -.Fn notify_set_state "int token, uint64_t state" -.Ft uint32_t -.Fn notify_get_state "int token, uint64_t *state" -.Ft uint32_t -.Fn notify_suspend "int token" -.Ft uint32_t -.Fn notify_resume "int token" -.Ft uint32_t -.Fn notify_cancel "int token" -.Ft bool -.Fn notify_is_valid_token "int val" -.Sh DESCRIPTION -These routines allow processes to exchange stateless notification events. -Processes post notifications to a single system-wide notification server, -which then distributes notifications to client processes that have -registered to receive those notifications, including processes run by -other users. -.Pp -Notifications are associated with names in a namespace shared by all -clients of the system. -Clients may post notifications for names, and -may monitor names for posted notifications. -Clients may request -notification delivery by a number of different methods. -.Pp -Clients desiring to monitor names in the notification system must -register with the system, providing a name and other information -required for the desired notification delivery method. -Clients are -given an integer token representing the registration. -Token values are zero or positive integers. -.Pp -The kernel provides limited queues for mach message and file descriptor messages. -It is important to make sure that clients read mach ports and file descriptors frequently -to prevent messages from being lost due to resource limitations. -Clients that use signal-based notification should be aware that signals -are not delivered to a process while it is running in a signal handler. -This may affect the delivery of signals in close succession. -.Pp -Notifications may be coalesced in some cases. -Multiple events posted -for a name in rapid succession may result in a single notification sent -to clients registered for notification for that name. -Clients checking -for changes using the notify_check() routine cannot determine if -more than one event has been posted since a previous call to -notify_check() for that name. -.Pp -"False positives" may occur in notify_check() when used with a token -generated by notify_register_check() due to implementation constraints. -This behavior may vary in future releases. -.Ss notify_post -This routine causes the system to send a notification for the given -name to all clients that have registered for notifications of this name. -This is the only API required for an application that only produces -notifications. -.Ss notify_register_check -Registers for passive notification for the given name. -The routine generates -a token that may be used with the -.Fn notify_check -routine to check if any notifications have been posted for the name. -The check is implemented using a shared memory scheme, making the check -very fast and efficient. -The implementation has a limited amount -of shared memory, so developers are encouraged to use this mechanism -sparingly. -It is also important to release the resources consumed -by a registration with -.Fn notify_cancel -when they are no longer required by the application. -.Ss notify_register_dispatch -registers a callback handler in the form of a block which will be -dispatched to the queue when a notification for the given name is -received. This is a convenient way to register callbacks without any -management of file descriptors, mach ports, or signals on the part of -the application. The given queue is retained by the system for the -lifetime of the notification. Use -.Fn notify_cancel -to release the notification and its reference to the queue. -.Ss notify_register_signal -registers a client for notification delivery via a signal. -This fits -well with the design of many UNIX daemons that use a signal such as SIGHUP -to reinitialize of reset internal state information. -.Ss notify_register_mach_port -registers a client for notification delivery via mach messaging. -Notifications are delivered by an empty message sent to a mach port. -By default, a new port is created by a call to this routine. -A mach port -previously created by a call to this routine may be used for notifications -if a pointer to that port is passed in to the routine and NOTIFY_REUSE is -set in the flags parameter. -The notification service must be able to extract -send rights to the port. -.Pp -Values for the flags parameter may only be 0 (zero) or NOTIFY_REUSE. -.Pp -Note that the kernel limits the size of the message queue for any port. -If it is important that notifications should not be lost due to queue -overflow, clients should service messages quickly, and be cautious in -using the same port for notifications for more than one name. -.Pp -A notification message has an empty message body. -The msgh_id field -in the mach message header will have the value of the notification -token. -If a port is reused for multiple notification registrations, -the msgh_id value may be used to determine which name generated -the notification. -.Ss notify_register_file_descriptor -Register for notification by a write to a file descriptor. -.Pp -By default, a new file descriptor is created and a pointer to it -is returned as the value of the "notify_fd" parameter. -A file descriptor -created by a previous call to this routine may be used for notifications -if a pointer to that file descriptor is passed in to the routine and -NOTIFY_REUSE is set in the flags parameter. -.Pp -Values for the flags parameter may only be 0 (zero) or NOTIFY_REUSE. -.Pp -Note that the kernel limits the buffer space for queued writes on a -file descriptor. -If it is important that notifications should not be -lost due to queue overflow, clients should service messages quickly, -and be cautious in using the same file descriptor for notifications -for more than one name. -.Pp -Notifications are delivered by an integer value written to the -file descriptor. -The value is sent in network byte order. -When converted to host byte order, for example by using -.Fn ntohl , -it will match the notification token -for which the notification was generated. -.Ss notify_check -Checks if any notifications have been posted for a name. -The output -parameter "check" is set to 0 for false, 1 for true. -A true indication is -returned the first time notify_check is called for a token. -Subsequent calls -give a true indication when notifications have been posted for the name -associated with the notification token. -.Pp -.Fn notify_check -may be used with any notification token produced by any of the notification -registration routines. -A fast check based on a shared memory implementation -is used when the token was generated by -.Fn notify_register_check . -Other tokens are checked by a call to the notification server. -.Ss notify_set_state -Set a 64-bit unsigned integer variable associated with a token. -.Pp -Each registered notification key has an associated 64-bit integer variable, -which may be set using this routine and examined using the -.Fn notify_get_state -routine. -The state variable is free to be used by clients of the notification API. -It may be used to synchronize state information between cooperating processes or threads. -(Available in Mac OS X 10.5 or later.) -.Ss notify_get_state -Get the 64-bit unsigned integer value associated with a token. -The default value of a state variable is zero. -(Available in Mac OS X 10.5 or later.) -.Ss notify_suspend -Suspends delivery of notifications for a notification token. -Any notifications corresponding to a token that are posted while it is suspended -will be coalesced, and pended until notifications are resumed using -.Fn notify_resume . -.Pp -Calls to -.Fn notify_suspend -may be nested. -Notifications will resume only when a matching number of calls are made to -.Fn notify_resume . -.Ss notify_resume -Removes one level of suspension for a token previously suspended by a call to -.Fn notify_suspend . -When resumed, notifications will be delivered normally. -A single notification will be generated if any notifications were pended while the token was suspended. -.Ss notify_cancel -Cancel notification and free resources associated with a notification -token. -Mach ports and file descriptor associated with a token are released -(deallocated or closed) when all registration tokens associated with -the port or file descriptor have been cancelled. -.Pp -.Ss notify_is_valid_token -Determines if an integer value is valid for a current registration. -Negative integers are never valid. -A positive or zero value is valid if the current process has a registration associated with the given value. - -.Sh RETURN VALUES -Many notify functions return status (uint32_t) to indicate success or failure. -This will always be one of the following: - -.Ss NOTIFY_STATUS_OK -The function did not encounter any issues. - -.Ss NOTIFY_STATUS_INVALID_NAME -Name argument is not valid. -Often this will indicate that the name passed to the function is NULL. - -.Ss NOTIFY_STATUS_INVALID_TOKEN -The function expected a valid token, given by a notify_register_* function, and was passed an invalid token. -Token validity can by checked with -.Fn notify_is_valid_token . - -.Ss NOTIFY_STATUS_INVALID_PORT -The function is not able to use the port passed. -This may be because the port is NULL, MACH_PORT_NULL, MACH_PORT_DEAD, or the calling process does not have the -correct rights to the port. - -.Ss NOTIFY_STATUS_INVALID_FILE -The function was passed NULL, or something that is not a file descriptor generated by notify_register_file_descriptor. - -.Ss NOTIFY_STATUS_INVALID_SIGNAL -Legacy, currently unused. - -.Ss NOTIFY_STATUS_INVALID_REQUEST -An internal error occurred. - -.Ss NOTIFY_STATUS_NOT_AUTHORIZED -The calling process is not authorized to take this action. -Usually this indicates that the calling process may not act on the name given. - -.Ss NOTIFY_STATUS_OPT_DISABLE -An internal error occurred. - -.Ss NOTIFY_STATUS_SERVER_NOT_FOUND -The server could not be found. -This usually indicates that sandboxing is preventing the calling process from accessing notifyd. - -.Ss NOTIFY_STATUS_NULL_INPUT -One of the inputs was called with NULL when it must not be NULL. -For legacy support, if name, token, port, or file descriptor is NULL, the respective NOTIFY_STATUS_INVALID_* return code -will be used instead. - -.Ss NOTIFY_STATUS_FAILED -Indicates an internal failure of the library. -The caller may try again; another attempt may be successful. -Please report any instances where this is returned. - - - -.Sh NAMESPACE CONVENTIONS -Names in the namespace must be NULL-terminated. -Names should be encoded as UTF-8 strings. -.Pp -The namespace supported by the system is unstructured, but users of -this API are highly encouraged to follow the reverse-ICANN domain -name convention used for Java package names and for System Preferences -on Mac OS X. -For example, "com.mydomain.example.event". -.Pp -Apple reserves the portion -of the namespace prefixed by "com.apple.". -This policy is not -enforced in the current implementation, but may be in the future. -.Pp -Names in the space "user.uid.UID", where UID is a numeric user ID number -are reserved for processes with that UID. -Names in this protected space may only be accessed or modified by processes -with the effective UID specified as the UID in the name. -The name "user.uid.UID" is protected for the given UID, as are any -names of the form "user.uid.UID.". -In the latter case, the name must have a dot character following the UID. -.Pp -Third party developers are encouraged to choose a prefix for names -that will avoid conflicts in the shared namespace. -.Pp -The portion of the namespace prefixed by the string "self." is set aside -for private use by applications. -That is, each client may use that part -of the namespace for intra-process notifications. -These notifications -are private to each individual process and are not propagated between -processes. -.Sh USAGE EXAMPLES -A notification producer. -.Pp - #include - ... -.Pp - notify_post("com.eg.random.event"); -.Pp -A client using notify_check() to determine when to invalidate a cache. -.Pp - #include - #include - #include -.Pp - int - main(int argc, char *argv[]) - { - uint32_t status; - int token, check; -.Pp - status = notify_register_check("com.eg.update", &token); - if (status != NOTIFY_STATUS_OK) - { - fprintf(stderr, "registration failed (%u)\\n", status); - exit(status); - } -.Pp - build_my_cache(); -.Pp - ... -.Pp - status = notify_check(token, &check); - if ((status == NOTIFY_STATUS_OK) && (check != 0)) - { - /* An update has occurred - invalidate the cache */ - reset_my_cache(); - } -.Pp - ... -.Pp -A client using file descriptor notifications. -.Pp - #include - #include - #include - #include - #include - #include - #include - #include -.Pp - int - main(int argc, char *argv[]) - { - uint32_t status; - int nf, rtoken, qtoken, t, ret; - fd_set readfds; -.Pp - status = notify_register_file_descriptor("com.eg.random.event", - &nf, 0, &rtoken); - if (status != NOTIFY_STATUS_OK) - { - fprintf(stderr, "registration failed (%u)\\n", status); - exit(status); - } -.Pp - status = notify_register_file_descriptor("com.eg.random.quit", - &nf, NOTIFY_REUSE, &qtoken); - if (status != NOTIFY_STATUS_OK) - { - fprintf(stderr, "registration failed (%u)\\n", status); - exit(status); - } -.Pp - FD_ZERO(&readfds); - FD_SET(nf, &readfds); -.Pp - for (;;) - { - ret = select(nf+1, &readfds, NULL, NULL, NULL); - if (ret <= 0) continue; - if (!FD_ISSET(nf, &readfds)) continue; -.Pp - status = read(nf, &t, sizeof(int)); - if (status < 0) - { - perror("read"); - break; - } -.Pp - t = ntohl(t); -.Pp - if (t == rtoken) printf("random event\\n"); - else if (t == qtoken) break; - } -.Pp - printf("shutting down\\n"); - notify_cancel(rtoken); - notify_cancel(qtoken); - exit(0); - } -.Pp -A client using dispatch notifications. -.Pp - #include - #include - #include - #include -.Pp - int - main(void) - { - uint32_t status; - int token; -.Pp - status = notify_register_dispatch("com.eg.random.event", &token, - dispatch_get_main_queue(), ^(int t) { - printf("com.eg.random.event received!\\n"); }); -.Pp - dispatch_main(); - exit(0); - } -.Sh HISTORY -These functions first appeared in -Mac OS X 10.3. -.Sh SEE ALSO -.Xr ntohl 3 , -.Xr read 2 , -.Xr select 2 , -.Xr signal 3 diff --git a/src/libnotify/notify.h b/src/libnotify/notify.h deleted file mode 100644 index 275c0b7d8..000000000 --- a/src/libnotify/notify.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2003-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Portions Copyright (c) 2003-2010 Apple Inc. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __NOTIFICATION_H__ -#define __NOTIFICATION_H__ - -#include -#include -#include -#include -#include -#ifdef __BLOCKS__ -#include -#endif /* __BLOCKS__ */ - -/*! @header - * These routines allow processes to exchange stateless notification events. - * Processes post notifications to a single system-wide notification server, - * which then distributes notifications to client processes that have - * registered to receive those notifications, including processes run by - * other users. - * - * Notifications are associated with names in a namespace shared by all - * clients of the system. Clients may post notifications for names, and - * may monitor names for posted notifications. Clients may request - * notification delivery by a number of different methods. - * - * Clients desiring to monitor names in the notification system must - * register with the system, providing a name and other information - * required for the desired notification delivery method. Clients are - * given an integer token representing the registration. - * - * Note that the kernel provides limited queues for mach message and file - * descriptor messages. It is important to make sure that clients read - * mach ports and file descriptors frequently to prevent messages from - * being lost due to resource limitations. Clients that use signal-based - * notification should be aware that signals are not delivered to - * a process while it is running in a signal handler. This may affect - * the delivery of signals in close succession. - * - * Notifications may be coalesced in some cases. Multiple events posted - * for a name in rapid succession may result in a single notification sent - * to clients registered for notification for that name. Clients checking - * for changes using the notify_check() routine cannot determine if - * more than one event pas been posted since a previous call to - * notify_check() for that name. - * - * "False positives" may occur in notify_check() when used with a token - * generated by notify_register_check() due to implementation constraints. - * This behavior may vary in future releases. - * - * Synchronization between two processes may be achieved using the - * notify_set_state() and notify_get_state() routines. - */ - -/*! @defineblock Status Codes - * Status codes returned by the API. See notify(3) for detailed description. - */ -#define NOTIFY_STATUS_OK 0 -#define NOTIFY_STATUS_INVALID_NAME 1 -#define NOTIFY_STATUS_INVALID_TOKEN 2 -#define NOTIFY_STATUS_INVALID_PORT 3 -#define NOTIFY_STATUS_INVALID_FILE 4 -#define NOTIFY_STATUS_INVALID_SIGNAL 5 -#define NOTIFY_STATUS_INVALID_REQUEST 6 -#define NOTIFY_STATUS_NOT_AUTHORIZED 7 -#define NOTIFY_STATUS_OPT_DISABLE 8 -#define NOTIFY_STATUS_SERVER_NOT_FOUND 9 -#define NOTIFY_STATUS_NULL_INPUT 10 - -#define NOTIFY_STATUS_FAILED 1000000 - -/*! @/defineblock */ - -/*! - * Flag bits used for registration. - */ -#define NOTIFY_REUSE 0x00000001 - - -/*! - * Token values are zero or positive integers. - * NOTIFY_TOKEN_INVALID is useful as an initial value for - * a token value passed as an in/out parameter to one of - * the registration routines below. - */ -#define NOTIFY_TOKEN_INVALID -1 - -__BEGIN_DECLS - -/*! - * Post a notification for a name. - * - * This is the only call that is required for a notification producer. - * Returns status. - */ -OS_EXPORT uint32_t notify_post(const char *name); - - -#ifdef __BLOCKS__ -typedef void (^notify_handler_t)(int token); - -/*! - * @function notify_register - * @abstract Request notification delivery to a dispatch queue. - * @discussion When notifications are received by the process, the notify - * subsystem will deliver the registered Block to the target - * dispatch queue. Notification blocks are not re-entrant, - * and subsequent notification Blocks will not be delivered - * for the same registration until the previous Block has - * returned. - * @param name (input) The notification name. - * @param out_token (output) The registration token. - * @param queue (input) The dispatch queue to which the Block is submitted. - * The dispatch queue is retained by the notify subsystem while - * the notification is registered, and will be released when - * notification is canceled. - * @param handler (input) The Block to invoke on the dispatch queue in response - * to a notification. The notification token is passed to the - * Block as an argument so that the callee can modify the state - * of the notification or cancel the registration. - * @result Returns status. - */ -OS_EXPORT uint32_t notify_register_dispatch(const char *name, int *out_token, dispatch_queue_t queue, notify_handler_t handler) -__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_2); -#endif /* __BLOCKS__ */ - -/*! - * Creates a registration token be used with notify_check(), - * but no active notifications will be delivered. - * - * @param name - * (input) notification name - * @param out_token - * (output) registration token - * @result Returns status. - */ -OS_EXPORT uint32_t notify_register_check(const char *name, int *out_token); - -/*! - * Request notification delivery by UNIX signal. - * - * A client may request signal notification for multiple names. After a signal - * is delivered, the notify_check() routine may be called with each notification - * token to determine which name (if any) generated the signal notification. - * - * @param name (input) notification name - * @param sig (input) signal number (see signal(3)) - * @param out_token (output) notification token - * @result Returns status. - */ -OS_EXPORT uint32_t notify_register_signal(const char *name, int sig, int *out_token); - -/*! - * Request notification by mach message. - * - * Notifications are delivered by an empty message sent to a mach port. - * By default, a new port is allocated and a pointer to it is returned - * as the value of "notify_port". A mach port previously returned by a - * call to this routine may be used for notifications if a pointer to that - * port is passed in to the routine and NOTIFY_REUSE is set in the flags - * parameter. The notification service must be able to extract send - * rights to the port. - * - * Note that the kernel limits the size of the message queue for any port. - * If it is important that notifications should not be lost due to queue - * overflow, clients should service messages quickly, and be careful about - * using the same port for notifications for more than one name. - * - * A notification message has an empty message body. The msgh_id field - * in the mach message header will have the value of the notification - * token. If a port is reused for multiple notification registrations, - * the msgh_id value may be used to determine which name generated - * the notification. - * - * @param name - * (input) notification name - * @param out_token - * (output) notification token - * @param notify_port - * (input/output) pointer to a mach port - * @result Returns status. - */ -OS_EXPORT uint32_t notify_register_mach_port(const char *name, mach_port_t *notify_port, int flags, int *out_token); - -/*! - * Request notification by a write to a file descriptor. - * - * Notifications are delivered by a write to a file descriptor. - * By default, a new file descriptor is created and a pointer to it - * is returned as the value of "notify_fd". A file descriptor created - * by a previous call to this routine may be used for notifications if - * a pointer to that file descriptor is passed in to the routine and - * NOTIFY_REUSE is set in the flags parameter. - * - * Note that the kernel limits the buffer space for queued writes on a - * file descriptor. If it is important that notifications should not be - * lost due to queue overflow, clients should service messages quickly, - * and be careful about using the same file descriptor for notifications - * for more than one name. - * - * Notifications are delivered by an integer value written to the - * file descriptor. The value will match the notification token - * for which the notification was generated. - * - * @param name - * (input) notification name - * @param out_token - * (output) notification token - * @param notify_fd - * (input/output) pointer to a file descriptor - * @result Returns status. - */ -OS_EXPORT uint32_t notify_register_file_descriptor(const char *name, int *notify_fd, int flags, int *out_token); - -/*! - * Check if any notifications have been posted. - * - * Output parameter check is set to 0 for false, 1 for true. Returns status. - * check is set to true the first time notify_check is called for a token. - * Subsequent calls set check to true when notifications have been posted for - * the name associated with the notification token. This routine is independent - * of notify_post(). That is, check will be true if an application calls - * notify_post() for a name and then calls notify_check() for a token associated - * with that name. - * - * @param token - * (input)notification token - * @param check - * (output) true/false indication - * @result Returns status. - */ -OS_EXPORT uint32_t notify_check(int token, int *check); - -/*! - * Cancel notification and free resources associated with a notification - * token. Mach ports and file descriptor associated with a token are released - * (deallocated or closed) when all registration tokens associated with - * the port or file descriptor have been cancelled. - * - * @param token - * (input) notification token - * @result Returns status. - */ -OS_EXPORT uint32_t notify_cancel(int token); - -/*! - * Suspend delivery of notifications for a token. Notifications for this token will be - * pended and coalesced, then delivered following a matching call to notify_resume. - * Calls to notify_suspend may be nested. Notifications remain suspended until - * an equal number of calls have been made to notify_resume. - * - * @param token - * (input) notification token - * @result Returns status. - */ -OS_EXPORT uint32_t notify_suspend(int token) -__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0); - -/*! - * Removes one level of suspension for a token previously suspended - * by a call to notify_suspend. Notifications will resume when a matching - * call to notify_resume is made for each previous call to notify_suspend. - * Notifications posted while a token is suspended are coalesced into - * a single notification sent following a resumption. - * - * @param token - * (input) notification token - * @result Returns status. - */ -OS_EXPORT uint32_t notify_resume(int token) -__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0); - -/*! - * Set or get a state value associated with a notification token. - * Each key in the notification namespace has an associated integer value available - * for use by clients as for application-specific purposes. A common usage is to - * allow two processes or threads to synchronize their activities. For example, a - * server process may need send a notification when a resource becomes available. - * A client process can register for the notification, but when it starts up it will - * not know whether the resource is available. The server can set the state value, - * and the client can check the value at startup time to synchronize with the server. - * - * Set the 64-bit integer state value. - * - * @param token - * (input) notification token - * @param state64 - * (input) 64-bit unsigned integer value - * @result Returns status. - */ -OS_EXPORT uint32_t notify_set_state(int token, uint64_t state64) -__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0); - -/*! - * Get the 64-bit integer state value. - * - * @param token - * (input) notification token - * @param state64 - * (output) 64-bit unsigned integer value - * @result Returns status. - */ -OS_EXPORT uint32_t notify_get_state(int token, uint64_t *state64) -__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0); - -/*! - * Determine if a token is valid (currently registered). - * Negative integer values are always invalid. Positive or - * zero values are valid only if they are associated with an - * existing registration. - * - * @param val - * (input) integer value - * @result Returns true if the value is a valid token, false otherwise. - */ -OS_EXPORT bool notify_is_valid_token(int val) -__OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0); - -__END_DECLS - -#endif /* __NOTIFICATION_H__ */ diff --git a/src/libnotify/notify_cancel.3 b/src/libnotify/notify_cancel.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_cancel.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_check.3 b/src/libnotify/notify_check.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_check.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_client.c b/src/libnotify/notify_client.c deleted file mode 100644 index 5d4ce65da..000000000 --- a/src/libnotify/notify_client.c +++ /dev/null @@ -1,4148 +0,0 @@ -/* - * Copyright (c) 2003-2012 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include <_simple.h> - -#include // _dyld_is_memory_immutable - -#include "libnotify.h" - -#include "notify.h" -#include "notify_internal.h" -#include "notify_ipc.h" -#include "notify_private.h" -#include "notify_probes.h" - -#ifdef DEBUG -#define DEBUG_REGISTRATION 0x00000001 -#define DEBUG_NOTIFICATION 0x00000002 -#define DEBUG_RETAIN_RELEASE 0x00000004 -#define DEBUG_CANCEL 0x00000008 -#define DEBUG_GET_STATE 0x00000010 -#define DEBUG_SEND_NO_BLOCK 0x00000020 -#define DEBUG_NODES 0x00000040 -#define DEBUG_API 0x00000080 -#define DEBUG_USER 0x80000000 -#define DEBUG_ALL 0xffffffff -static uint32_t _libnotify_debug = DEBUG_ALL; -#endif /* DEBUG */ - -#define EVENT_INIT 0 -#define EVENT_REGEN 1 - -#define SELF_PREFIX "self." -#define SELF_PREFIX_LEN 5 - -#define COMMON_SELF_PORT_KEY "self.com.apple.system.notify.common" - -#define MULTIPLE_REGISTRATION_WARNING_TRIGGER 500 - -#define NID_UNSET 0xffffffffffffffffL -#define NID_CALLED_ONCE 0xfffffffffffffffeL - -/* - * Details about registrations, tokens, dispatch (NOTIFY_OPT_DISPATCH), IPC versions, and etc. - * - * In the first versions of the client/server protocol (ipc versions 0 and 1), the integer - * token representing a registration was generated by notifyd and returned to the client - * as an out parameter in the MIG registration call. - * - * If a client uses the old protocols, then each registration in the client goes straight to - * the server. If the client registers for signals, file descriptor writes, or whatever, - * that's all handled by the server. - * - * The current version (ipc version 2) has better performance. The client now generates - * a unique token (simply incremented by 1 for each new registration) and sends it to - * notifyd in a MIG simpleroutine. notifyd internally uses a 64 bit ID for each registration - * that's formed from the client's PID (high-order 32 bits) and the client-provided integer - * (low-order 32 bits). - * - * With the advent of libdispatch, there was an opportunity to further improve performance - * and reduce the load on notifyd. The client library (this source file) checks if the - * client process is multithreaded, or at least can be multithreaded, with a call to the - * _dispatch_is_multithreaded() routine. This tells us if we can use dispatch in the client. - * - * If the client can use dispatch (NOTIFY_OPT_DISPATCH gets set in globals->client_opts), - * then all registrations use a single shared mach port (globals->notify_common_port). - * The client creates a dispatch source (globals->notify_dispatch_source) that handles all - * notifications from the server. The handler routine looks up the client's registration - * for the received notification and sends a signal, writes on a file descriptor, or sends - * a mach message as required. It's all done locally in the client process. - * - * Many clients register several times for the same notification name. That's sometimes - * due to bad code, but it may be legitimate as well. For example, different libraries or - * frameworks may register independently, or different threads in a client process may - * each require a registration for the same name. When dispatch is available, client - * registrations for the same name are coalesced. The library still generates a new - * token (and an underlying token data structure) for each registration, but only the - * first registration is actually sent to notifyd. Subsequent registrations are simply - * chained to the first in a linked list. When the globals->notify_dispatch_source - * handler processes a notification from the server, it traverses the linked list and - * forwards the notification to each. - * - * Note that it is possible for the client to still have multiple registrations with - * notifyd, even when coalescing. Polled registrations (memory or plain) must be handled - * by notifyd, so these registration types are not coalesced. Also, a client might start - * out single threaded and appear not to be dispatch-safe, but them become multi-threaded - * later on. Early registrations would go individually to notifyd, while later - * registrations would be coalesced. - * - * The library uses both locking and refcounting of data structures. A mutex in the - * library globals (globals->notify_lock) is used when accessing mutable values, hash - * tables, and lists that are found in the global data (returned by _notify_globals()). - * Data structure instances (name_node_t and registration_node_t types) are refcounted. - * name_node_t instances have locks to protect their data. registration_node_t - * instances do not, mostly to save memory. Most operations on them can either be done - * atomically, or are within the scope of some other lock. - */ - -typedef struct -{ - uint64_t name_id; - TAILQ_HEAD(, __registration_node_s) coalesced; - struct __registration_node_s *coalesce_base; - char *name; - os_unfair_lock lock; - atomic_uint_fast32_t refcount; - uint32_t coalesce_base_token; - bool has_been_warned; - bool needs_free; -} name_node_t; - -/* - * Data structure behind a client's token. - * The library exports tokens (integers) to users of the library, so - * notify_register_...() gives the client an int value that represents - * a registration. - * - * If the client registers multiple times for the same name and we can - * use dispatch in the library, then the duplicate registration creates - * a new client-side registration, but not a new registration with the - * server. Multiple registrations are chained in a linked list. The - * base registration is retained for each coalesced registration. - */ -typedef struct __registration_node_s -{ - TAILQ_ENTRY(__registration_node_s) registration_coalesced_entry; - - atomic_uint_fast32_t refcount; - uint32_t token; - uint32_t flags; - - /* shared memory slot and value at that location when we last did notify_check() */ - uint32_t slot; - uint32_t val; - - /* client-facing parts of a notification */ - int fd; - int signal; - mach_port_t mp; - dispatch_queue_t queue; - notify_handler_t block; - - /* client_id is the value returned from notifyd for registrations using IPC version 0 */ - uint32_t client_id; - - /* state value and timestamp when we set it - used to regenerate if notifyd restarts */ - uint64_t set_state_val; - uint64_t set_state_time; - - /* path monitoring */ - char *path; - int path_flags; - - /* name table node for this registration */ - name_node_t *name_node; -} registration_node_t; - - -/* FORWARD */ -static void _notify_lib_server_restart_handler(void *ctxt); -static void notify_retain_mach_port(notify_globals_t globals, mach_port_t mp, int flags); -static void _notify_dispatch_handle(void *context); -static void registration_node_release(registration_node_t *r); -static void registration_node_release_locked(notify_globals_t globals, registration_node_t *r); -static void notify_release_file_descriptor_locked(notify_globals_t globals, int fd); -static void notify_release_mach_port_locked(notify_globals_t globals, mach_port_t mp, uint32_t flags); - -// TSAN doesn't know about os_unfair_lock_with_options -#if defined(__has_feature) -#if __has_feature(thread_sanitizer) -#define TSAN_SAFE_LOCK(x) os_unfair_lock_lock(x) -#else -#define TSAN_SAFE_LOCK(x) os_unfair_lock_lock_with_options(x, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION) -#endif // __has_feature(thread_sanitizer) -#else -#define TSAN_SAFE_LOCK(x) os_unfair_lock_lock(x) -#endif // defined(__clang__) - -#ifdef DEBUG_MUTEX -#define mutex_lock(s,x,f,l) \ -_notify_client_log(ASL_LEVEL_NOTICE, "attempting mutex lock %s %p from %s:%u", s, x, f, l); \ -TSAN_SAFE_LOCK(x); \ -_notify_client_log(ASL_LEVEL_NOTICE, "acquired mutex lock %s %p from %s:%u", s, x, f, l); -#define mutex_unlock(s,x,f,l) \ -_notify_client_log(ASL_LEVEL_NOTICE, "dropping mutex lock %s %p from %s:%u", s, x, f, l); \ -os_unfair_lock_unlock(x); -#else -#define mutex_lock(s,x,f,l) TSAN_SAFE_LOCK(x) -#define mutex_unlock(s,x,f,l) os_unfair_lock_unlock(x) -#endif - -// returns the result after the decrement -inline static int32_t -atomic_refcount_release(atomic_uint_fast32_t *val) -{ - int32_t result = atomic_fetch_sub_explicit(val, 1, memory_order_release); - // Crash right away if we underrun our refcounts - // as this indicates a bug in our logic - assert(result > 0); - // result == 1 means that this was the last reference so any changes - // made to the refcounted object need to be visible to all threads - // at this point. c.f. "Release-Acquire ordering" at - // http://en.cppreference.com/w/cpp/atomic/memory_order - if (result == 1) atomic_thread_fence(memory_order_acquire); - return result - 1; -} - -// returns the result after the increment -inline static int32_t -atomic_increment32(atomic_uint_fast32_t *val) -{ - int32_t result = atomic_fetch_add_explicit(val, 1, memory_order_relaxed); - return result + 1; -} - -inline static void -name_node_retain(name_node_t *node) -{ - atomic_increment32(&node->refcount); -} - -inline static void -registration_node_retain(registration_node_t *reg) -{ - atomic_increment32(®->refcount); -} - -__printflike(2, 3) -static void -_notify_client_log(int level, const char *fmt, ...) -{ - va_list ap; - char *msg = NULL; - - va_start(ap, fmt); - vasprintf(&msg, fmt, ap); - va_end(ap); - - if (msg != NULL) - { - _simple_asl_log(level, "com.apple.notify", msg); -#ifdef DEBUG_VERBOSE - fprintf(stderr, "thread %p: %s\n", (void *)pthread_self(), msg); -#endif - } - - free(msg); -} - - -#if !TARGET_OS_SIMULATOR && !TARGET_OS_OSX - -static const uint32_t LAUNCHD_PID = 1; - -// do this so we don't have to link against libtrace -__printflike(1, 2) -static void -simulate_crash(char *fmt, ...) -{ - char *desc = NULL; - va_list ap; - int len; - - if (getpid() == LAUNCHD_PID) { - return; - } - - va_start(ap, fmt); - len = vasprintf(&desc, fmt, ap); - va_end(ap); - - if (desc == NULL) { - return; - } - - os_fault_with_payload(OS_REASON_LIBSYSTEM, OS_REASON_LIBSYSTEM_CODE_FAULT, - desc, len + 1, desc, 0); - free(desc); -} - -#define REPORT_BAD_BEHAVIOR(...) \ - if(os_variant_has_internal_diagnostics("libnotify.simulate_crash")) \ - { \ - simulate_crash(__VA_ARGS__); \ - } else { \ - _notify_client_log(ASL_LEVEL_ERR, __VA_ARGS__); \ - } - -#else /* !TARGET_OS_SIMULATOR && !TARGET_OS_OSX */ - -#define REPORT_BAD_BEHAVIOR(...) _notify_client_log(ASL_LEVEL_ERR, __VA_ARGS__) - -#endif /* !TARGET_OS_SIMULATOR && !TARGET_OS_OSX */ - -static char * -_notify_strdup_if_mutable(const char *str, bool *needs_free) -{ - size_t size = strlen(str) + 1; - if (!_dyld_is_memory_immutable(str, size)) { - char *clone = (char *)malloc(size); - if (clone) { - memcpy(clone, str, size); - if (needs_free) *needs_free = true; - } - return clone; - } - if (needs_free) *needs_free = false; - return (char *)str; -} - -#pragma mark - -#pragma mark globals - -#define INITIAL_TOKEN_ID 1 - -/* - * Initialization of global variables. Called once per process. - */ -static void -_notify_init_globals(void * /* notify_globals_t */ _globals) -{ - notify_globals_t globals = _globals; - - globals->notify_lock = OS_UNFAIR_LOCK_INIT; - globals->token_id = INITIAL_TOKEN_ID; - globals->notify_common_token = -1; - globals->check_lock = OS_UNFAIR_LOCK_INIT; - _nc_table_init(&globals->name_node_table, offsetof(name_node_t, name)); - _nc_table_init_n(&globals->registration_table, offsetof(registration_node_t, token)); - - _notify_lib_notify_state_init(&globals->self_state, NOTIFY_STATE_USE_LOCKS); -} - -__attribute__((__pure__)) -static inline notify_globals_t -_notify_globals(void) -{ - return (notify_globals_t)os_alloc_once(OS_ALLOC_ONCE_KEY_LIBSYSTEM_NOTIFY, - sizeof(struct notify_globals_s), &_notify_init_globals); -} - -#pragma mark - -#pragma mark name_node_t - -#ifdef NOTDEF -static void -name_node_dump(int level, name_node_t *n) -{ - if (n == NULL) - { - _notify_client_log(level, "name_node_t NULL\n"); - return; - } - - _notify_client_log(level, "name_node_t %p name=%s name_id=%llu refcount=%d coalesce_base_token=%u coalesce_base=%p\n", (n->name == NULL) ? "NULL" : n->name, n->name_id, n->refcount, n->coalesce_base_token, n->coalesce_base); -} -#endif - -// must be called with the global lock held -static name_node_t * -name_node_for_name_locked(notify_globals_t globals, const char *name, uint64_t nid, bool create) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - if (name == NULL) return NULL; - - name_node_t *n = _nc_table_find(&globals->name_node_table, name); - if (n != NULL) - { - name_node_retain(n); - } - else if (create) - { - n = (name_node_t *)calloc(1, sizeof(name_node_t)); - if (n == NULL) - { -#ifdef DEBUG - _notify_client_log(ASL_LEVEL_ERR, "name_node_for_name name %s calloc failed errno %d [%s]\n", name, errno, strerror(errno)); -#endif - goto done; - } - - n->name = _notify_strdup_if_mutable(name, &n->needs_free); - if (n->name == NULL) - { - free(n); - n = NULL; - goto done; - } - - n->refcount = 1; - n->name_id = nid; - TAILQ_INIT(&n->coalesced); - n->coalesce_base_token = NOTIFY_TOKEN_INVALID; - n->lock = OS_UNFAIR_LOCK_INIT; - n->has_been_warned = false; - - _nc_table_insert(&globals->name_node_table, &n->name); - } - -done: - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NODES) - { - if (n == NULL) _notify_client_log(ASL_LEVEL_NOTICE, "name_node_for_name name %s returning NULL\n", name); - else _notify_client_log(ASL_LEVEL_NOTICE, "name_node_for_name name %s refcount %d %p\n", n->name, n->refcount, n); - } -#endif - - return n; -} - -static name_node_t * -name_node_for_name(const char *name, uint64_t nid, bool create) -{ - notify_globals_t globals = _notify_globals(); - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - name_node_t *node = name_node_for_name_locked(globals, name, nid, create); - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return node; -} - -// must be called with the global lock held -static void -name_node_delete_locked(notify_globals_t globals, name_node_t *n) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - /* refcount is zero, free the node */ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NODES) _notify_client_log(ASL_LEVEL_NOTICE, "name_node_release name %s refcount %d %p FREE", n->name, n->refcount, n); -#endif - - _nc_table_delete(&globals->name_node_table, n->name); - if (n->needs_free) { - free(n->name); - } - n->name = NULL; - free(n); -} - -// must be called with the global lock held -static void -name_node_release_locked(notify_globals_t globals, name_node_t *n) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - if (n == NULL) return; - - if (atomic_refcount_release(&n->refcount) > 0) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NODES) _notify_client_log(ASL_LEVEL_NOTICE, "%s name %s refcount %d %p", __func__, n->name, n->refcount, n); -#endif - return; - } - name_node_delete_locked(globals, n); -} - -static void -name_node_unlock_and_release(name_node_t *n) -{ - if (n == NULL) return; - - mutex_unlock(n->name, &n->lock, __func__, __LINE__); - notify_globals_t globals = _notify_globals(); - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - if (atomic_refcount_release(&n->refcount) > 0) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NODES) _notify_client_log(ASL_LEVEL_NOTICE, "%s name %s refcount %d %p", __func__, n->name, n->refcount, n); -#endif - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return; - } - name_node_delete_locked(globals, n); - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); -} - -// We avoid an extra retain here if the base registration was just created -static void -name_node_add_coalesced_registration_locked(name_node_t *n, registration_node_t *r, bool skip_retain) -{ - if (n == NULL) return; - if (r == NULL) return; - - os_unfair_lock_assert_owner(&n->lock); - - if (!skip_retain && n->coalesce_base) registration_node_retain(n->coalesce_base); - TAILQ_INSERT_TAIL(&n->coalesced, r, registration_coalesced_entry); -} - -// must be called with the global lock held -static void -name_node_remove_coalesced_registration_locked(notify_globals_t globals, name_node_t *n, registration_node_t *r) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - if (n == NULL) return; - if (r == NULL) return; - - mutex_lock(n->name, &n->lock, __func__, __LINE__); - TAILQ_REMOVE(&n->coalesced, r, registration_coalesced_entry); - mutex_unlock(n->name, &n->lock, __func__, __LINE__); - - registration_node_release_locked(globals, n->coalesce_base); -} - -static void -name_node_set_nid_locked(name_node_t *n, uint64_t nid) -{ - os_unfair_lock_assert_owner(&n->lock); - n->name_id = nid; -} - -static void -name_node_set_nid(name_node_t *n, uint64_t nid) -{ - if (n == NULL) return; - - mutex_lock(n->name, &n->lock, __func__, __LINE__); - name_node_set_nid_locked(n, nid); - mutex_unlock(n->name, &n->lock, __func__, __LINE__); -} - -#pragma mark - -#pragma mark registration_node_t - -static registration_node_t * -registration_node_find(uint32_t token) -{ - notify_globals_t globals = _notify_globals(); - - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - registration_node_t *r = _nc_table_find_n(&globals->registration_table, token); - if (r != NULL) registration_node_retain(r); - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NODES) _notify_client_log(ASL_LEVEL_NOTICE, "registration_node_find token %u refcount %d -> %p", token, r ? r->refcount : -1, r); -#endif - - return r; -} - -/* - * Tells the caller if a value is a valid token number. - * Internal coalesce_base registration tokens are reported as invalid, - * since clients should not be mucking around with them. - */ -bool -notify_is_valid_token(int val) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - bool valid = true; - notify_globals_t globals = _notify_globals(); - - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - registration_node_t *r = _nc_table_find_n(&globals->registration_table, val); - if (r == NULL) valid = false; - else if (r->flags & NOTIFY_TYPE_COALESCE_BASE) valid = false; - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return valid; -} - -// must be called with the global lock held -static void -registration_node_free_locked(notify_globals_t globals, registration_node_t *r) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - name_node_t *n = r->name_node; - - if (r->flags & NOTIFY_TYPE_COALESCED) - { - name_node_remove_coalesced_registration_locked(globals, n, r); - } - else if (r->flags & NOTIFY_TYPE_COALESCE_BASE) - { - mutex_lock(n->name, &n->lock, __func__, __LINE__); - n->coalesce_base_token = NOTIFY_TOKEN_INVALID; - n->coalesce_base = NULL; - mutex_unlock(n->name, &n->lock, __func__, __LINE__); - - /* cancel the registration with notifyd */ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_CANCEL) _notify_client_log(ASL_LEVEL_NOTICE, "_notify_server_cancel_2 token %u", r->token); -#endif - // hold lock across async server call - (void)_notify_server_cancel_2(globals->notify_server_port, r->token); - } - - notify_release_file_descriptor_locked(globals, r->fd); - notify_release_mach_port_locked(globals, r->mp, r->flags); - free(r->path); - - if (r->block != NULL) dispatch_async_f(r->queue, r->block, (dispatch_function_t)_Block_release); - r->block = NULL; - - if (r->queue != NULL) dispatch_release(r->queue); - r->queue = NULL; - - free(r); - - name_node_release_locked(globals, n); -} - -// must be called with the global lock held -static void -registration_node_delete_locked(notify_globals_t globals, registration_node_t *r) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - /* refcount is zero, free the node */ - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NODES) _notify_client_log(ASL_LEVEL_NOTICE, "%s token %u refcount %d flags 0x%08x %p FREE", __func__, r->token, r->refcount, r->flags, r); -#endif - - _nc_table_delete_n(&globals->registration_table, r->token); - - uint32_t reg_token = r->token; - uint32_t reg_flags = r->flags; - registration_node_free_locked(globals, r); - - if (reg_flags & NOTIFY_FLAG_SELF) - { - /* - * _notify_lib_cancel fails quietly if self_state is NULL - * We let it fail quietly. - */ - _notify_lib_cancel(&globals->self_state, NOTIFY_CLIENT_SELF, reg_token); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return; - } - - if (reg_flags & NOTIFY_TYPE_COALESCE_BASE) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_CANCEL) _notify_client_log(ASL_LEVEL_NOTICE, "notify_cancel token %d NOTIFY_TYPE_COALESCE_BASE", reg_token); -#endif -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return; - } - kern_return_t kstatus = KERN_SUCCESS; - if ((reg_flags & NOTIFY_TYPE_COALESCED) == 0) - { - // hold lock across async server call - kstatus = _notify_server_cancel_2(globals->notify_server_port, reg_token); - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_CANCEL) _notify_client_log(ASL_LEVEL_NOTICE, "notify_cancel token %d reg_node %p has been cancelled", reg_token, r); -#endif - - if ((kstatus == MIG_SERVER_DIED) || (kstatus == MACH_SEND_INVALID_DEST)) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return; - } - else if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - _notify_client_log(ASL_LEVEL_ERR, "<- %s [%d] _notify_server_cancel_2 failed: 0x%08x\n", __func__, __LINE__ + 2, kstatus); - return; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif -} - -static void -registration_node_release(registration_node_t *r) -{ - notify_globals_t globals = _notify_globals(); - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - registration_node_release_locked(globals, r); - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); -} - -static void -registration_node_release_locked(notify_globals_t globals, registration_node_t *r) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - if (r == NULL) return; - - if (atomic_refcount_release(&r->refcount) > 0) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NODES) _notify_client_log(ASL_LEVEL_NOTICE, "%s token %u refcount %d flags 0x%08x %p", __func__, r->token, r->refcount, r->flags, r); -#endif - - return; - } - registration_node_delete_locked(globals, r); -} - -#if !TARGET_OS_SIMULATOR -static bool -shm_attach(uint32_t size) -{ - int32_t shmfd; - notify_globals_t globals = _notify_globals(); - void *shm_base = NULL; - bool result = true; - - shmfd = shm_open(SHM_ID, O_RDONLY, 0); - if (shmfd == -1) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed on line %d with errno %d", __func__, __LINE__, errno); - return false; - } - - shm_base = mmap(NULL, size, PROT_READ, MAP_SHARED, shmfd, 0); - if (shm_base == MAP_FAILED) { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed on line %d with errno %d", __func__, __LINE__, errno); - result = false; - } else { - globals->shm_base = shm_base; - result = true; - } - - close(shmfd); - - return result; -} -#endif /* TARGET_OS_SIMULATOR */ - -#ifdef NOTDEF -static void -shm_detach(void) -{ - if (shm_base != NULL) - { - shmdt(shm_base); - shm_base = NULL; - } -} -#endif - -/* - * _notify_lib_init is called for each new registration (event = EVENT_INIT). - * It is also called to re-initialize when the library has detected that - * notifyd has restarted (event = EVENT_REGEN). - */ -static uint32_t -_notify_lib_init_locked(notify_globals_t globals, uint32_t event) -{ - __block kern_return_t kstatus; - int status; - - /* notifyd sets NOTIFY_OPT_DISABLE to avoid re-entrancy issues */ - if (globals->client_opts & NOTIFY_OPT_DISABLE) return NOTIFY_STATUS_OPT_DISABLE; - - /* We need to hold the global lock here otherwise "first" is racy */ - /* But then we don't need dispatch_once -- clean this up in 39829810 */ - os_unfair_lock_assert_owner(&globals->notify_lock); - - /* Look up the notifyd server port just once. */ - kstatus = KERN_SUCCESS; - dispatch_once(&globals->notify_server_port_once, ^{ - kstatus = bootstrap_look_up2(bootstrap_port, NOTIFY_SERVICE_NAME, &globals->notify_server_port, 0, BOOTSTRAP_PRIVILEGED_SERVER); - }); - - if ((kstatus != KERN_SUCCESS) || !(MACH_PORT_VALID(globals->notify_server_port))) - { - return NOTIFY_STATUS_SERVER_NOT_FOUND; - } - - /* - * _dispatch_is_multithreaded() tells us if it is safe to use dispatch queues for - * a shared port for all registrations (NOTIFY_OPT_DISPATCH), and to watch for notifyd - * exiting / restarting (NOTIFY_OPT_REGEN). - */ - if (_dispatch_is_multithreaded()) { - globals->client_opts |= (NOTIFY_OPT_DISPATCH | NOTIFY_OPT_REGEN); - } - - /* - * Look up the server's PID and supported IPC version on the first call, - * and on a regeneration event (when the server has restarted). - */ - pid_t last_pid = globals->notify_server_pid; - if ((last_pid == 0) || (event == EVENT_REGEN)) - { - uint32_t version, new_pid; - - globals->notify_server_pid = 0; - - kstatus = _notify_server_checkin(globals->notify_server_port, &version, &new_pid, &status); - if (kstatus != KERN_SUCCESS) - { - status = NOTIFY_STATUS_SERVER_CHECKIN_FAILED; - } - if (status != NOTIFY_STATUS_OK) - { - return status; - } - - /* - * protocol versions below 3 aren't supported anymore - */ - if (version < NOTIFY_IPC_VERSION_MIN_SUPPORTED) { - NOTIFY_INTERNAL_CRASH(version, "Unsupported protocol version"); - } - globals->notify_server_pid = new_pid; - - if ((new_pid == last_pid) && (event == EVENT_REGEN)) - { - return NOTIFY_STATUS_NO_REGEN_NEEDED; - } - - if (globals->server_proc_source != NULL) - { - dispatch_source_cancel(globals->server_proc_source); - dispatch_release(globals->server_proc_source); - globals->server_proc_source = NULL; - } - } - - - /* - * Create a source (DISPATCH_SOURCE_TYPE_PROC) to invoke _notify_lib_regenerate if notifyd restarts. - * Available in IPC version 2. - */ - if ((globals->server_proc_source == NULL) && (globals->client_opts & NOTIFY_OPT_REGEN) && (globals->notify_server_pid != 0)) - { - globals->server_proc_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, (uintptr_t)globals->notify_server_pid, DISPATCH_PROC_EXIT, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)); - dispatch_source_set_event_handler_f(globals->server_proc_source, _notify_lib_server_restart_handler); - dispatch_resume(globals->server_proc_source); - } - - /* - * Create the shared multiplex port if NOTIFY_OPT_DISPATCH is set. - */ - if (((globals->client_opts & NOTIFY_OPT_DISPATCH) && (globals->notify_common_port == MACH_PORT_NULL)) || - ((globals->client_opts & NOTIFY_OPT_DISPATCH) && (globals->notify_common_port == MACH_PORT_DEAD))) - { - mach_port_options_t opts = { - .flags = MPO_CONTEXT_AS_GUARD | MPO_STRICT | MPO_QLIMIT, - .mpl.mpl_qlimit = 16, - }; - mach_port_context_t guard = (uintptr_t)globals; - kern_return_t kr; - mach_port_t mp; - - kr = mach_port_construct(mach_task_self(), &opts, guard, &mp); - if (kr != KERN_SUCCESS) { - NOTIFY_CLIENT_CRASH(kr, "mach_port_construct() failed: possible port leak"); - } - globals->notify_common_port = mp; - - globals->notify_dispatch_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, mp, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)); - dispatch_set_context(globals->notify_dispatch_source, globals); - dispatch_source_set_event_handler_f(globals->notify_dispatch_source, _notify_dispatch_handle); - dispatch_resume(globals->notify_dispatch_source); - } - - return NOTIFY_STATUS_OK; -} - -static uint32_t -_notify_lib_init(notify_globals_t globals, uint32_t event) { - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - uint32_t ret = _notify_lib_init_locked(globals, event); - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return ret; -} - -/* Reset all internal state at fork */ -/* Used in Libsystem without header declaration */ -void -_notify_fork_child(void) -{ - notify_globals_t globals = _notify_globals(); - - _notify_init_globals(globals); - - /* - * Expressly disable notify in the child side of a fork if it had - * been initialized in the parent. Using notify in the child process - * can lead to deadlock (see ). - * - * Also disable notify in the forked child of a multi-threaded parent that - * used dispatch, since notify will use dispatch, and that will blow up. - */ - if (globals->notify_server_port != MACH_PORT_NULL) globals->client_opts = NOTIFY_OPT_DISABLE; - if (_dispatch_is_fork_of_multithreaded_parent()) globals->client_opts = NOTIFY_OPT_DISABLE; - - _notify_lib_notify_state_init(&globals->self_state, NOTIFY_STATE_USE_LOCKS); - globals->notify_server_port = MACH_PORT_NULL; - globals->notify_server_pid = 0; - - globals->fd_count = 0; - globals->fd_clnt = NULL; - globals->fd_srv = NULL; - globals->fd_refcount = NULL; - - globals->mp_size = 0; - globals->mp_count = 0; - globals->mp_list = NULL; - - globals->shm_base = NULL; -} - -/* - * Create the registration structure associated with a client's token. - * Will create a name_node_t structure for the name if one does not exist. - * Note that this routine is NOT used to create the "base" for non-polled - * coalesced registrations. That's done by base_registration_create(). - */ -static uint32_t -client_registration_create_base( __attribute__((nonnull)) const char * name, uint64_t nid, uint32_t token, uint32_t cid, uint32_t slot, uint32_t flags, int sig, int fd, mach_port_t mp, bool create_base) -{ - name_node_t *name_node = NULL; - registration_node_t *reg_node; - uint32_t warn_count = 0; - notify_globals_t globals = _notify_globals(); - - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - - /* should never happen, but check if the registration exists */ - reg_node = _nc_table_find_n(&globals->registration_table, token); - if (reg_node != NULL) goto client_registration_create_fail; - - name_node = name_node_for_name_locked(globals, name, nid, true); - if (name_node == NULL) goto client_registration_create_fail; - mutex_lock(name_node->name, &name_node->lock, __func__, __LINE__); - - reg_node = (registration_node_t *)calloc(1, sizeof(registration_node_t)); - if (reg_node == NULL) - { -#ifdef DEBUG - _notify_client_log(ASL_LEVEL_ERR, "client_registration_create name %s calloc failed errno %d [%s]\n", name, errno, strerror(errno)); -#endif - name_node_unlock_and_release(name_node); - goto client_registration_create_fail; - } - - reg_node->refcount = 1; - reg_node->token = token; - _nc_table_insert_n(&globals->registration_table, ®_node->token); - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NODES) _notify_client_log(ASL_LEVEL_NOTICE, "client_registration_create token %u refcount %d -> %p", token, reg_node->refcount, reg_node); -#endif - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_REGISTRATION) - { - if (nid == NID_UNSET) _notify_client_log(ASL_LEVEL_NOTICE, "client_registration_create reg_node %p name %s name_node %p nid NID_UNSET token %u flags 0x%08x", reg_node, name, name_node, token, flags); - else if (nid == NID_CALLED_ONCE) _notify_client_log(ASL_LEVEL_NOTICE, "client_registration_create reg_node %p name %s name_node %p nid NID_CALLED_ONCE token %u flags 0x%08x", reg_node, name, name_node, token, flags); - else _notify_client_log(ASL_LEVEL_NOTICE, "client_registration_create reg_node %p name %s name_node %p nid %llu token %u flags 0x%08x", reg_node, name, name_node, nid, token, flags); - } -#endif - - /* no need to regenerate a coalesced registration */ - if (flags & NOTIFY_TYPE_COALESCED) flags &= ~NOTIFY_FLAG_REGEN; - - reg_node->flags = flags; - reg_node->slot = slot; - reg_node->val = 0; - reg_node->fd = fd; - reg_node->mp = mp; - reg_node->signal = sig; - reg_node->client_id = cid; - - /* - * Registration nodes retain their name node, so in theory we should - * retain name_node here. However, name_node_for_name() retains - * the name node, so we just make the assignment here and skip - * calling name_node_release() before returning from this routine. - */ - reg_node->name_node = name_node; - - /* - * If dispatch is available, add this registration to the name node's dispatch list. - * Doesn't apply to polled types (memory and plain). - */ - if ((globals->client_opts & NOTIFY_OPT_DISPATCH) && (flags & NOTIFY_TYPE_DELIVERED) && (flags & NOTIFY_TYPE_COALESCED)) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_REGISTRATION) _notify_client_log(ASL_LEVEL_NOTICE, "Add coalesced registration %p to name %s name node %p base %p", reg_node, name, name_node, name_node->coalesce_base); -#endif - name_node_add_coalesced_registration_locked(name_node, reg_node, create_base); - } - - warn_count = name_node->refcount; - - if ((!name_node->has_been_warned) && (warn_count == MULTIPLE_REGISTRATION_WARNING_TRIGGER)) - { - name_node->has_been_warned = true; - REPORT_BAD_BEHAVIOR("notify name \"%s\" has been registered %d times - this may be a leak", name, warn_count); - } - - mutex_unlock(name_node->name, &name_node->lock, __func__, __LINE__); - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return NOTIFY_STATUS_OK; - -client_registration_create_fail: - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return NOTIFY_STATUS_CLIENT_REG_FAILED; -} - -static uint32_t -client_registration_create(const char *name, uint64_t nid, uint32_t token, uint32_t cid, uint32_t slot, uint32_t flags, int sig, int fd, mach_port_t mp) -{ - return client_registration_create_base(name, nid, token, cid, slot, flags, sig, fd, mp, false); -} - -/* - * N.B. base_registration_create is called from notify_register_mach_port(), which holds the global lock - */ -static uint32_t -base_registration_create_locked(notify_globals_t globals, __attribute__((nonnull)) const char *name, uint64_t nid, uint32_t token, uint32_t flags, mach_port_t mp) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - name_node_t *name_node = NULL; - registration_node_t *reg_node; - - /* should never happen, but check if the registration exists */ - reg_node = _nc_table_find_n(&globals->registration_table, token); - if (reg_node != NULL) return NOTIFY_STATUS_DOUBLE_REG; - - reg_node = (registration_node_t *)calloc(1, sizeof(registration_node_t)); - if (reg_node == NULL) - { -#ifdef DEBUG - _notify_client_log(ASL_LEVEL_ERR, "base_registration_create name %s calloc failed errno %d [%s]\n", name, errno, strerror(errno)); -#endif - return NOTIFY_STATUS_ALLOC_FAILED; - } - - name_node = name_node_for_name_locked(globals, name, nid, true); - if (name_node == NULL) - { - free(reg_node); - return NOTIFY_STATUS_NEW_NAME_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_REGISTRATION) - { - if (nid == NID_UNSET) _notify_client_log(ASL_LEVEL_NOTICE, "%s reg_node %p name %s name_node %p nid NID_UNSET token %u flags 0x%08x", __func__, reg_node, name, name_node, token, flags); - else if (nid == NID_CALLED_ONCE) _notify_client_log(ASL_LEVEL_NOTICE, "%s reg_node %p name %s name_node %p nid NID_CALLED_ONCE token %u flags 0x%08x", __func__, reg_node, name, name_node, token, flags); - else _notify_client_log(ASL_LEVEL_NOTICE, "%s reg_node %p name %s name_node %p nid %llu token %u flags 0x%08x", __func__, reg_node, name, name_node, nid, token, flags); - } -#endif - - reg_node->refcount = 1; - reg_node->token = token; - reg_node->client_id = token; - reg_node->flags = flags | NOTIFY_TYPE_COALESCE_BASE; - reg_node->mp = mp; - reg_node->val = 0; - reg_node->slot = SLOT_NONE; - reg_node->fd = FD_NONE; - reg_node->signal = SIGNAL_NONE; - reg_node->name_node = name_node; - - /* - * Registration nodes retain their name node, so in theory we should - * retain name_node here. However, name_node_for_name() retains - * the name node, so we just make the assignment here and skip - * calling name_node_release() before returning from this routine. - */ - name_node->coalesce_base = reg_node; - name_node->coalesce_base_token = token; - - _nc_table_insert_n(&globals->registration_table, ®_node->token); - return NOTIFY_STATUS_OK; -} - -static bool -check_name_access(char *name, uid_t uid) -{ - char str[64]; - size_t len; - - /* root may do anything */ - if (uid == 0) return true; - - /* if name does not have "user.uid." as a prefix, it is not a user-protected namespace */ - if (strncmp(name, USER_PROTECTED_UID_PREFIX, USER_PROTECTED_UID_PREFIX_LEN)) - { - return true; - } - - snprintf(str, sizeof(str) - 1, "%s%d", USER_PROTECTED_UID_PREFIX, uid); - len = strlen(str); - - /* user may access user.uid. or a subtree name */ - return ((!strncmp(name, str, len)) && ((name[len] == '\0') || (name[len] == '.'))); - -} - -static void -_notify_lib_regenerate_registration(registration_node_t *r) -{ - uint32_t type; - int status; - int new_slot = SLOT_NONE; - kern_return_t kstatus; - mach_port_t port; - uint64_t new_nid = NID_UNSET; - size_t pathlen; - char *name = r->name_node->name; - - notify_globals_t globals = _notify_globals(); - - if (r->flags & NOTIFY_FLAG_SELF) return; - if ((r->flags & NOTIFY_FLAG_REGEN) == 0) return; - - port = MACH_PORT_NULL; - if (r->flags & NOTIFY_TYPE_PORT) - { - if(r->flags & NOTIFY_TYPE_COALESCED || r->flags & NOTIFY_TYPE_COALESCE_BASE) - { - port = globals->notify_common_port; - } - else - { - port = r->mp; - } - } - - if(!check_name_access(name, geteuid())) - { - REPORT_BAD_BEHAVIOR("BUG IN LIBNOTIFY CLIENT: registration held for restricted name %s with process uid %d", - name, geteuid()); - } - - pathlen = 0; - if (r->path != NULL) pathlen = strlen(r->path) + 1; - type = r->flags & 0x000000ff; - - kstatus = _notify_server_regenerate(globals->notify_server_port, (caddr_t)name, r->token, type, port, r->signal, - r->slot, r->set_state_val, r->set_state_time, r->path, (mach_msg_type_number_t)pathlen, - r->path_flags, &new_slot, &new_nid, &status); - - assert(kstatus == KERN_SUCCESS); - - if(status != NOTIFY_STATUS_OK && status != NOTIFY_STATUS_DUP_CLIENT && - status != NOTIFY_STATUS_NO_REGEN_NEEDED) - { - REPORT_BAD_BEHAVIOR("Libnotify: _notify_server_regnerate failed for name %s", name); - } - - - r->slot = new_slot; - r->name_node->name_id = new_nid; -} - -/* - * Invoked when server has died. - * Regenerates all registrations and state. - */ -static uint32_t -_notify_lib_regenerate_locked(notify_globals_t globals) -{ - uint32_t result; - - if ((globals->client_opts & NOTIFY_OPT_REGEN) == 0) return NOTIFY_STATUS_OK; - - /* if _notify_lib_init_lockec returns an error, regeneration is unnecessary */ - result = _notify_lib_init_locked(globals, EVENT_REGEN); - - if (result == NOTIFY_STATUS_NO_REGEN_NEEDED) { - return NOTIFY_STATUS_OK; - } - - if (result == NOTIFY_STATUS_OK) { - _nc_table_foreach_n(&globals->registration_table, ^bool(void *reg) { - _notify_lib_regenerate_registration(reg); - return true; - }); - } - - return result; -} - -/* - * Invoked when server has died. - * Regenerates all registrations and state. - */ -static void -_notify_lib_server_restart_handler(void *ctxt __unused) -{ - notify_globals_t globals = _notify_globals(); - - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - (void)_notify_lib_regenerate_locked(globals); - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - - return; -} - -/* - * Get the up to date shm_base if the server PID (shared memory slot 0) - * has changed. - */ -static inline uint32_t -regenerate_check(notify_globals_t globals) -{ - uint32_t result = NOTIFY_STATUS_OK; - - if ((globals->client_opts & NOTIFY_OPT_REGEN) == 0) return NOTIFY_STATUS_OK; - - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - if ((globals->shm_base != NULL) && (globals->shm_base[0] != globals->notify_server_pid)) - { - result = _notify_lib_regenerate_locked(globals); - } - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - - return result; -} - -/* notify_lock is required in notify_retain_file_descriptor */ -static void -notify_retain_file_descriptor(int clnt, int srv) -{ - int x, i; - notify_globals_t globals = _notify_globals(); - - if (clnt < 0) return; - if (srv < 0) return; - - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - - x = -1; - for (i = 0; (i < globals->fd_count) && (x < 0); i++) - { - if (globals->fd_clnt[i] == clnt) x = i; - } - - if (x >= 0) - { - globals->fd_refcount[x]++; - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return; - } - - x = globals->fd_count; - globals->fd_count++; - - globals->fd_clnt = (int *)reallocf(globals->fd_clnt, globals->fd_count * sizeof(int)); - globals->fd_srv = (int *)reallocf(globals->fd_srv, globals->fd_count * sizeof(int)); - globals->fd_refcount = (int *)reallocf(globals->fd_refcount, globals->fd_count * sizeof(int)); - - if ((globals->fd_clnt == NULL) || (globals->fd_srv == NULL) || (globals->fd_refcount == NULL)) - { -#ifdef DEBUG - _notify_client_log(ASL_LEVEL_ERR, "notify_retain_file_descriptor reallocf failed errno %d [%s]\n", errno, strerror(errno)); -#endif - free(globals->fd_clnt); - globals->fd_clnt = NULL; - free(globals->fd_srv); - globals->fd_srv = NULL; - free(globals->fd_refcount); - globals->fd_refcount = NULL; - globals->fd_count = 0; - } - else - { - globals->fd_clnt[x] = clnt; - globals->fd_srv[x] = srv; - globals->fd_refcount[x] = 1; - } - - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); -} - -// must be called with the global lock held -static void -notify_release_file_descriptor_locked(notify_globals_t globals, int fd) -{ - os_unfair_lock_assert_owner(&globals->notify_lock); - - int x, i, j; - - if (fd < 0) return; - - x = -1; - for (i = 0; (i < globals->fd_count) && (x < 0); i++) - { - if (globals->fd_clnt[i] == fd) x = i; - } - - if (x < 0) - { - return; - } - - if (globals->fd_refcount[x] > 0) globals->fd_refcount[x]--; - if (globals->fd_refcount[x] > 0) - { - return; - } - - close(globals->fd_clnt[x]); - close(globals->fd_srv[x]); - - if (globals->fd_count == 1) - { - free(globals->fd_clnt); - globals->fd_clnt = NULL; - free(globals->fd_srv); - globals->fd_srv = NULL; - free(globals->fd_refcount); - globals->fd_refcount = NULL; - globals->fd_count = 0; - return; - } - - for (i = x + 1, j = x; i < globals->fd_count; i++, j++) - { - globals->fd_clnt[j] = globals->fd_clnt[i]; - globals->fd_srv[j] = globals->fd_srv[i]; - globals->fd_refcount[j] = globals->fd_refcount[i]; - } - - globals->fd_count--; - - globals->fd_clnt = (int *)reallocf(globals->fd_clnt, globals->fd_count * sizeof(int)); - globals->fd_srv = (int *)reallocf(globals->fd_srv, globals->fd_count * sizeof(int)); - globals->fd_refcount = (int *)reallocf(globals->fd_refcount, globals->fd_count * sizeof(int)); - - if ((globals->fd_clnt == NULL) || (globals->fd_srv == NULL) || (globals->fd_refcount == NULL)) - { -#ifdef DEBUG - _notify_client_log(ASL_LEVEL_ERR, "notify_release_file_descriptor reallocf failed errno %d [%s]\n", errno, strerror(errno)); -#endif - free(globals->fd_clnt); - globals->fd_clnt = NULL; - free(globals->fd_srv); - globals->fd_srv = NULL; - free(globals->fd_refcount); - globals->fd_refcount = NULL; - globals->fd_count = 0; - } - -} - -/* notify_lock is required in notify_retain_mach_port */ -static void -notify_retain_mach_port(notify_globals_t globals, mach_port_t mp, int flags) -{ - if (mp == MACH_PORT_NULL) return; - if (flags & _NOTIFY_COMMON_PORT) return; - - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - - struct mp_entry *entries = globals->mp_list; - - for (int i = 0; i < globals->mp_count; i++) - { - if (entries[i].mpl_port_name == mp) { - entries[i].mpl_refs++; - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return; - } - } - - int x = globals->mp_count; - globals->mp_count++; - - if (x >= globals->mp_size) { - if (globals->mp_size < 4) { - globals->mp_size = 4; - } else { - globals->mp_size *= 2; - } - entries = reallocf(entries, globals->mp_size * sizeof(struct mp_entry)); - globals->mp_list = entries; - if (os_unlikely(entries == NULL)) { - NOTIFY_CLIENT_CRASH(0, "Unable to allocate port array: " - "possible notification registration leak"); - } - } - - entries[x].mpl_port_name = mp; - entries[x].mpl_refs = 1; - entries[x].mpl_mine = ((flags & NOTIFY_REUSE) == 0); - - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); -} - -// must be called with the global lock held -static void -notify_release_mach_port_locked(notify_globals_t globals, mach_port_t mp, uint32_t flags) -{ - struct mp_entry *entries = globals->mp_list; - int x = -1; - - os_unfair_lock_assert_owner(&globals->notify_lock); - - if (mp == MACH_PORT_NULL) return; - if (mp == globals->notify_common_port) return; - - for (int i = 0; i < globals->mp_count; i++) - { - if (entries[i].mpl_port_name == mp) { - x = i; - break; - } - } - - if (x < 0) - { - return; - } - - if (entries[x].mpl_refs > 1) { - entries[x].mpl_refs--; - return; - } - - if (entries[x].mpl_mine) - { - int uref_mod = 0; - if (flags & NOTIFY_FLAG_RELEASE_SEND) uref_mod = -1; - mach_port_destruct(mach_task_self(), mp, uref_mod, 0); - } - else if (flags & NOTIFY_FLAG_RELEASE_SEND) - { - /* multiplexed registration holds a send right in Libnotify */ - mach_port_deallocate(mach_task_self(), mp); - } - - // swap removed element with the last one in the array - globals->mp_count--; - if (x != globals->mp_count) { - entries[x] = entries[globals->mp_count]; - } - - if (globals->mp_count == 0) - { - free(entries); - globals->mp_count = globals->mp_size = 0; - globals->mp_list = NULL; - } - else if (globals->mp_size > 4 && globals->mp_count <= globals->mp_size / 4) - { - entries = realloc(entries, sizeof(struct mp_entry) * globals->mp_size / 2); - if (entries) { - globals->mp_list = entries; - globals->mp_size /= 2; - } - } -} - -/* SPI */ -void -notify_set_options(uint32_t opts) -{ - notify_globals_t globals = _notify_globals(); - - /* NOTIFY_OPT_DISABLE can be unset with NOTIFY_OPT_ENABLE */ - if (globals->client_opts & NOTIFY_OPT_DISABLE) - { - if ((opts & NOTIFY_OPT_ENABLE) == 0) return; - - /* re-enable by swapping in the saved server port and saved opts*/ - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - - globals->client_opts = globals->saved_opts; - globals->notify_server_port = globals->saved_server_port; - - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return; - } - - /* - * A client can disable the library even if the server port has already been fetched. - * Note that this could race with another thread making a Libnotify call. - */ - if (opts & NOTIFY_OPT_DISABLE) - { - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - - globals->saved_opts = globals->client_opts; - globals->client_opts = NOTIFY_OPT_DISABLE; - - globals->saved_server_port = globals->notify_server_port; - globals->notify_server_port = MACH_PORT_NULL; - - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return; - } - - globals->client_opts = opts; - - /* call _notify_lib_init to create ports / dispatch sources as required */ - _notify_lib_init(globals, EVENT_INIT); -} - -/** - * Check if process has root access entitlement and should claim root access - * from notifyd. - */ -static bool -should_claim_root_access(void) -{ - static dispatch_once_t once; - static bool has_root_entitlement; - dispatch_once(&once, ^{ - xpc_object_t entitlement = xpc_copy_entitlement_for_token(ROOT_ENTITLEMENT_KEY, NULL); - if (entitlement == XPC_BOOL_TRUE) has_root_entitlement = true; - if (entitlement) xpc_release(entitlement); - }); - return has_root_entitlement; -} - -/* - * PUBLIC API - */ - - - -/* - * notify_post is a very simple API, but the implementation is - * more complex to try to optimize the time it takes. - * - * The server - notifyd - keeps a unique ID number for each key - * in the namespace. Although it's reasonably fast to call - * _notify_server_post_4 (a MIG simpleroutine), the MIG call - * allocates VM and copies the name string. It's much faster to - * call using the ID number. The problem is mapping from name to - * ID number. The name table keeps track of all registered names - * (in the client), but the registration calls are simpleroutines, - * except for notify_register_check. notify_register_check saves - * the name ID in the name table, but the other routines set it - * to NID_UNSET. - * - * In notify_post, we check if the name is known. If it is not, - * then the client is doing a "cold call". There may be no - * clients for this name anywhere on the system. In this case - * we simply send the name. We take the allocate/copy cost, but - * the latency is still not too bad since we use a simpleroutine. - * - * If the name in registered and the ID number is known, we send - * the ID using a simpleroutine. This is very fast. - * - * If the name is registered but the ID number is NID_UNSET, we - * send the name (as in a "cold call". It *might* just be that - * this client process just posts once, and we don't want to incur - * any addition cost. The ID number is reset to NID_CALLED_ONCE. - * - * If the client posts the same name again (the ID number is - * NID_CALLED_ONCE) we do a synchronous call to notifyd, sending - * the name string and getting back the name ID, whcih we save - * in the name table. This is simply a zero/one/many heuristic: - * If the client posts the same name more than once, we make the - * guess that it's going to do it more frequently, and it's worth - * the time it takes to fetch the ID from notifyd. - */ -uint32_t -notify_post(const char *name) -{ - NOTIFY_POST(name); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status; - name_node_t *n; - uint64_t nid = UINT64_MAX; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - - if (name == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_NAME; - } - - if (!strncmp(name, SELF_PREFIX, SELF_PREFIX_LEN)) - { - _notify_lib_post(&globals->self_state, name, 0, 0); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - /* See if we have a name ID for this name. */ - n = name_node_for_name(name, NID_UNSET, false); - if (n != NULL) - { - mutex_lock(n->name, &n->lock, __func__, __LINE__); - if (n->name_id == NID_UNSET) - { - /* First post goes using the name string. */ - kstatus = _notify_server_post_4(globals->notify_server_port, (caddr_t)name, should_claim_root_access()); - if (kstatus != KERN_SUCCESS) - { - name_node_unlock_and_release(n); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_SERVER_POST_4_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - name_node_set_nid_locked(n, NID_CALLED_ONCE); - } - else if (n->name_id == NID_CALLED_ONCE) - { - /* Post and fetch the name ID. Slow, but subsequent posts will be very fast. */ - kstatus = _notify_server_post_2(globals->notify_server_port, (caddr_t)name, &nid, (int32_t *)&status, should_claim_root_access()); - if (kstatus != KERN_SUCCESS) - { - name_node_unlock_and_release(n); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_SERVER_POST_2_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - name_node_set_nid_locked(n, nid); - } - else - { - /* We have the name ID. Do an async post using the name ID. Very fast. */ - kstatus = _notify_server_post_3(globals->notify_server_port, n->name_id, should_claim_root_access()); - if (kstatus != KERN_SUCCESS) - { - name_node_unlock_and_release(n); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_SERVER_POST_3_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - } - - name_node_unlock_and_release(n); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - /* Do an async post using the name string. Fast (but not as fast as using name ID). */ - kstatus = _notify_server_post_4(globals->notify_server_port, (caddr_t)name, should_claim_root_access()); - if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_SERVER_POST_4_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - - - -static void -_notify_dispatch_local_notification(registration_node_t *r) -{ - if (r == NULL) return; - if (r->queue == NULL) return; - if (r->block == NULL) return; - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NOTIFICATION) - { - if (r->flags & NOTIFY_TYPE_COALESCED) _notify_client_log(ASL_LEVEL_NOTICE, "coalesced notification for token %d (name %s)", r->token, r->name_node->name); - else if (r->flags & NOTIFY_TYPE_COALESCE_BASE) _notify_client_log(ASL_LEVEL_NOTICE, "coalesced base notification for token %d (name %s)", r->token, r->name_node->name); - else _notify_client_log(ASL_LEVEL_NOTICE, "dispatch notification for token %d (name %s)", r->token, r->name_node->name); - } -#endif - - /* - * If the block calls notify_cancel, the node can get trashed, so - * we keep anything we need from the block (properly retained and released) - * in local variables. Concurrent notify_cancel() calls in the block are safe. - */ - int token = r->token; - notify_handler_t theblock = Block_copy(r->block); - dispatch_queue_t thequeue = r->queue; - dispatch_retain(thequeue); - - /* - * If DTrace probes are currently active that deal with the delivery of a - * notification, then the name needs to live until the end of the delivery. - * It is freed after delivery. - */ - char *name = NULL; - if ((NOTIFY_DELIVER_START_ENABLED() || NOTIFY_DELIVER_END_ENABLED()) && r && r->name_node && r->name_node->name) - { - name = strdup(r->name_node->name); - } - - // notify_dispatch_source runs on a DISPATCH_QUEUE_PRIORITY_HIGH queue (IN - // QoS). Dispatching directly from that queue to the client queue taints the - // block with IN qos. Instead we create a detached wrapper and let the block - // run with the priority of the target queue hierachy. This is the same - // behaviour as with dispatch sources. - // - dispatch_block_t detached_block = dispatch_block_create(DISPATCH_BLOCK_DETACHED, ^{ - bool valid = notify_is_valid_token(token); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NOTIFICATION) _notify_client_log(ASL_LEVEL_NOTICE, "-> dispatch_async token %d (%svalid) registration node %p", token, valid ? "" : "in", r); -#endif - /* check if the token is still valid: it may have been cancelled */ - if (name) NOTIFY_DELIVER_START(name); - if (valid) theblock(token); - if (name) NOTIFY_DELIVER_END(name); - _Block_release(theblock); - dispatch_release(thequeue); - - if (name) free(name); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NOTIFICATION) _notify_client_log(ASL_LEVEL_NOTICE, "<- dispatch_async token %d", token); -#endif - }); - - dispatch_async(thequeue, detached_block); - Block_release(detached_block); -} - -static void -_notify_dispatch_handle(void *context) -{ - notify_globals_t globals = context; - mach_port_t port = globals->notify_common_port; - name_node_t *n; - registration_node_t *r; - int token; - mach_msg_empty_rcv_t msg; - kern_return_t status; - - if (port == MACH_PORT_NULL) return; - - for (int retries = 5; retries-- > 0; ) { - memset(&msg, 0, sizeof(msg)); - - /* - * The dispatch source watching our multiplexed mach port has fired. - * Read the message that is waiting and get the token ID from the mach header. - */ - status = mach_msg(&msg.header, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg), port, 0, MACH_PORT_NULL); - if (status != KERN_SUCCESS) return; - - token = msg.header.msgh_id; - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_NOTIFICATION) _notify_client_log(ASL_LEVEL_NOTICE, "_notify_dispatch_handle token %d", token); -#endif - - r = registration_node_find(token); - if (r == NULL) continue; - - n = r->name_node; - if (n == NULL) - { - /* should not happen */ - registration_node_release(r); - continue; - } - - mutex_lock(n->name, &n->lock, __func__, __LINE__); - - if (r->flags & NOTIFY_TYPE_COALESCE_BASE) - { - registration_node_t *x; - TAILQ_FOREACH(x, &n->coalesced, registration_coalesced_entry) - { - if (x != r) _notify_dispatch_local_notification(x); - } - } - else - { - _notify_dispatch_local_notification(r); - } - - mutex_unlock(n->name, &n->lock, __func__, __LINE__); - - registration_node_release(r); - } -} - -#pragma mark - -#pragma mark registration - -uint32_t -notify_register_dispatch(const char *name, int *out_token, dispatch_queue_t queue, notify_handler_t handler) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - uint32_t status; - registration_node_t *r; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (queue == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_NULL_INPUT; - } - - if (handler == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_NULL_INPUT; - } - - /* client is using dispatch: enable local demux / dispatch and regeneration */ - notify_set_options(NOTIFY_OPT_DISPATCH | NOTIFY_OPT_REGEN); - - status = notify_register_mach_port(name, &globals->notify_common_port, NOTIFY_REUSE | _NOTIFY_COMMON_PORT, out_token); - if (status != NOTIFY_STATUS_OK) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - r = registration_node_find(*out_token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, NOTIFY_STATUS_TOKEN_NOT_FOUND, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - r->queue = queue; - dispatch_retain(r->queue); - r->block = Block_copy(handler); - - registration_node_release(r); - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - -/* note this does not get self names */ -static uint32_t -notify_register_mux_fd(const char *name, int *out_token, int rfd, int wfd) -{ - uint32_t status; - registration_node_t *r; - int val; - notify_globals_t globals = _notify_globals(); - - status = NOTIFY_STATUS_OK; - - if (globals->notify_common_port == MACH_PORT_NULL) return NOTIFY_STATUS_COMMON_PORT_NULL; - - status = notify_register_mach_port(name, &globals->notify_common_port, NOTIFY_REUSE | _NOTIFY_COMMON_PORT, out_token); - - r = registration_node_find(*out_token); - if (r == NULL) return NOTIFY_STATUS_TOKEN_NOT_FOUND; - - r->token = *out_token; - r->fd = rfd; - r->queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); - dispatch_retain(r->queue); - val = htonl(r->token); - r->block = (notify_handler_t)Block_copy(^(int unused){ write(wfd, &val, sizeof(val)); }); - - registration_node_release(r); - - return NOTIFY_STATUS_OK; -} - -uint32_t -notify_register_check(const char *name, int *out_token) -{ -#if TARGET_OS_SIMULATOR - return notify_register_plain(name, out_token); -#else -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status, token; - uint64_t nid; - int slot; - int32_t shmsize; - uint32_t cid; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (name == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_NAME; - } - - if (out_token == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_NULL_INPUT; - } - - *out_token = -1; - - if (!strncmp(name, SELF_PREFIX, SELF_PREFIX_LEN)) - { - token = atomic_increment32(&globals->token_id); - status = _notify_lib_register_plain(&globals->self_state, name, NOTIFY_CLIENT_SELF, token, SLOT_NONE, 0, 0, &nid); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - cid = token; - - status = client_registration_create(name, nid, token, cid, SLOT_NONE, - NOTIFY_FLAG_SELF | NOTIFY_TYPE_PLAIN, SIGNAL_NONE, FD_NONE, MACH_PORT_NULL); - - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - token = atomic_increment32(&globals->token_id); - kstatus = KERN_SUCCESS; - cid = token; - kstatus = _notify_server_register_check_2(globals->notify_server_port, (caddr_t)name, token, &shmsize, &slot, &nid, (int32_t *)&status); - - if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (kstatus: %d)", __func__, - NOTIFY_STATUS_REG_CHECK_2_FAILED, __LINE__, kstatus); - return NOTIFY_STATUS_FAILED; - } - - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (shmsize != -1) - { - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - if (globals->shm_base == NULL) - { - if (!shm_attach(shmsize)) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - if (globals->shm_base == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_SHM_BASE_REMAINS_NULL, __LINE__); - return NOTIFY_STATUS_FAILED; - } - } - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - - status = client_registration_create(name, nid, token, cid, slot, - NOTIFY_TYPE_MEMORY | NOTIFY_FLAG_REGEN, SIGNAL_NONE, FD_NONE, MACH_PORT_NULL); - } - else - { - status = client_registration_create(name, nid, token, cid, SLOT_NONE, - NOTIFY_TYPE_PLAIN | NOTIFY_FLAG_REGEN, SIGNAL_NONE, FD_NONE, MACH_PORT_NULL); - } - - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -#endif /* TARGET_OS_SIMULATOR */ -} - -uint32_t -notify_register_plain(const char *name, int *out_token) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status; - uint64_t nid; - int token; - uint32_t cid; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (name == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_NAME; - } - - if (!strncmp(name, SELF_PREFIX, SELF_PREFIX_LEN)) - { - token = atomic_increment32(&globals->token_id); - status = _notify_lib_register_plain(&globals->self_state, name, NOTIFY_CLIENT_SELF, token, SLOT_NONE, 0, 0, &nid); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - cid = token; - - status = client_registration_create(name, nid, token, cid, SLOT_NONE, - NOTIFY_FLAG_SELF | NOTIFY_TYPE_PLAIN, SIGNAL_NONE, FD_NONE, MACH_PORT_NULL); - - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, - "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - token = atomic_increment32(&globals->token_id); - cid = token; - kstatus = _notify_server_register_plain_2(globals->notify_server_port, (caddr_t)name, token); - if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, NOTIFY_STATUS_REG_PLAIN_2_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - - status = client_registration_create(name, NID_UNSET, token, cid, SLOT_NONE, - NOTIFY_TYPE_PLAIN | NOTIFY_FLAG_REGEN, SIGNAL_NONE, FD_NONE, MACH_PORT_NULL); - - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, - "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - -uint32_t -notify_register_signal(const char *name, int sig, int *out_token) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status; - uint64_t nid; - int token; - uint32_t cid; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (name == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_NAME; - } - - if (!strncmp(name, SELF_PREFIX, SELF_PREFIX_LEN)) - { - token = atomic_increment32(&globals->token_id); - status = _notify_lib_register_signal(&globals->self_state, name, NOTIFY_CLIENT_SELF, token, sig, 0, 0, &nid); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - cid = token; - status = client_registration_create(name, nid, token, cid, SLOT_NONE, - NOTIFY_FLAG_SELF | NOTIFY_TYPE_SIGNAL, sig, FD_NONE, MACH_PORT_NULL); - - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, - "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - if (globals->client_opts & NOTIFY_OPT_DISPATCH) - { - status = notify_register_dispatch(name, out_token, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(int unused){ kill(getpid(), sig); }); - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - token = atomic_increment32(&globals->token_id); - cid = token; - kstatus = _notify_server_register_signal_2(globals->notify_server_port, (caddr_t)name, token, sig); - if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (kstatus: %d)", __func__, NOTIFY_STATUS_REG_SIGNAL_2_FAILED, __LINE__, kstatus); - return NOTIFY_STATUS_FAILED; - } - - status = client_registration_create(name, NID_UNSET, token, cid, SLOT_NONE, - NOTIFY_TYPE_SIGNAL | NOTIFY_FLAG_REGEN, sig, FD_NONE, MACH_PORT_NULL); - - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - - -/* - * Port ownership rules: - * - notify common port is a pure receive right, with no send rights in our space - * - * - if the client doesn't pass NOTIFY_REUSE then we make a receive right that - * we track in the mach port references (notify_retain_mach_port, mpl_mine). - * - * - if we forward notifications to a local port, the library owns a send right - * tracked in the the registration with NOTIFY_FLAG_RELEASE_SEND - * - * - self notifications own a send right, tracked by the client_t structure - */ -uint32_t -notify_register_mach_port(const char *name, mach_port_name_t *notify_port, int flags, int *out_token) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status; - uint64_t nid; - task_t task; - int token, mine; - uint32_t cid, tflags; - registration_node_t *r; - name_node_t *n = NULL; - mach_port_name_t port; - notify_globals_t globals = _notify_globals(); - bool create_base = false; - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (name == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_NAME; - } - - if (notify_port == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_PORT; - } - - mine = 0; - task = mach_task_self(); - - if ((flags & NOTIFY_REUSE) == 0) - { - /* caller wants a new port: create a new port with a receive right */ - mine = 1; - kstatus = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, notify_port); - if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_MACH_PORT_ALLOC_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - } - else if (!MACH_PORT_VALID(*notify_port)) - { - return NOTIFY_STATUS_INVALID_PORT; - } - - if (!strncmp(name, SELF_PREFIX, SELF_PREFIX_LEN)) - { - /* we need to donate a Send right to the client */ - kstatus = mach_port_insert_right(mach_task_self(), *notify_port, *notify_port, MACH_MSG_TYPE_MAKE_SEND); - if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_PORT; - } - - token = atomic_increment32(&globals->token_id); - status = _notify_lib_register_mach_port(&globals->self_state, name, NOTIFY_CLIENT_SELF, token, *notify_port, 0, 0, &nid); - if (status != NOTIFY_STATUS_OK) - { - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, -1, 0); - if (IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - - return status; - } - - cid = token; - status = client_registration_create(name, nid, token, cid, SLOT_NONE, - NOTIFY_FLAG_SELF | NOTIFY_TYPE_PORT, SIGNAL_NONE, FD_NONE, *notify_port); - - if (status != NOTIFY_STATUS_OK) - { - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, 0, 0); - _notify_lib_cancel(&globals->self_state, NOTIFY_CLIENT_SELF, token); - if (IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, - "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; - notify_retain_mach_port(globals, *notify_port, flags); - NOTIFY_REGISTER_MACH_PORT(name, *notify_port, flags, token); - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - /* initialize if necessary */ - if ((globals->notify_server_port == MACH_PORT_NULL) || - ((globals->client_opts & NOTIFY_OPT_DISPATCH) && !MACH_PORT_VALID(globals->notify_common_port))) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - /* error occurred: release receive right (if a new one was allocated) and the send right we added */ - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, 0, 0); - if (IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - if (globals->client_opts & NOTIFY_OPT_DISPATCH) - { - /* - * If it is a notify_register_mach_port(), we'll receive the - * notification on notify_common_port anyway, - * and forward it to the caller's port. - */ - port = globals->notify_common_port; - } - else - { - /* we'll register to receive the notification on the caller's port */ - port = *notify_port; - } - - tflags = NOTIFY_TYPE_PORT | NOTIFY_FLAG_REGEN; - - token = -1; - cid = -1; - - if ((globals->client_opts & NOTIFY_OPT_DISPATCH) && ((flags & NOTIFY_NO_DISPATCH) == 0)) - { - /* - * Dance to protect n->coalesce_base. - * - * We take globals->notify_lock here. That prevents any other thread - * from looking up and/or creating a name node. We hold the lock - * until the name_node (n) is created if necessary, and n->coalesce_base - * has been set if it was NULL. The code below is the only code that - * assigns a value to n->coalesce_base, so even if some other thread has - * the name node, they won't clobber the value. - */ - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - - n = _nc_table_find(&globals->name_node_table, name); - if (n == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_REGISTRATION) _notify_client_log(ASL_LEVEL_NOTICE, "%s [%d]: name table find %s -> NULL", __func__, __LINE__, name); -#endif - create_base = true; - } - else if (n->coalesce_base == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_REGISTRATION) _notify_client_log(ASL_LEVEL_NOTICE, "%s [%d]: name table find %s -> %p, coalesce_base = NULL", __func__, __LINE__, name, n); -#endif - create_base = true; - } -#ifdef DEBUG - else - { - if (_libnotify_debug & DEBUG_REGISTRATION) _notify_client_log(ASL_LEVEL_NOTICE, "%s [%d]: name table find %s -> %p, coalesce_base = %p", __func__, __LINE__, name, n, n->coalesce_base); - } -#endif - - if (create_base) - { - /* base of coalesced registrations gets a private token */ - token = atomic_increment32(&globals->token_id); - cid = token; - - kstatus = _notify_server_register_mach_port_2(globals->notify_server_port, (caddr_t)name, token, globals->notify_common_port); - if (kstatus != KERN_SUCCESS) - { - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, 0, 0); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (kstatus: %d)", __func__, - NOTIFY_STATUS_REG_MACH_PORT_2_FAILED, __LINE__, kstatus); - return NOTIFY_STATUS_FAILED; - } - - status = base_registration_create_locked(globals, name, NID_UNSET, token, tflags, - globals->notify_common_port); - if (status != NOTIFY_STATUS_OK) - { - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, 0, 0); - if (IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - - return status; - } - - } - - /* we will need a pointer to the name node below - look it up while we still have the global lock */ - n = _nc_table_find(&globals->name_node_table, name); - - if(!create_base){ - registration_node_retain(n->coalesce_base); - } - - /* release globals->notify_lock here */ - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - - /* caller's token */ - token = atomic_increment32(&globals->token_id); - cid = token; - tflags |= NOTIFY_TYPE_COALESCED; - - /* - * If this call to notify_register_mach_port created the coalesce_base registration, - * we avoid an extra retain here. It is created with a refcount of 1, and it would get retained - * by the coalesced registration created in client_registration_create_base below. We - * want the refcount to be equal to the number of registrations in the coalesce list. - * We pass create_base down to client_registration_create_base to indicate that it should avoid - * the extra retain -- see name_node_add_coalesced_registration() - */ - status = client_registration_create_base(name, NID_UNSET, token, cid, SLOT_NONE, - tflags, SIGNAL_NONE, FD_NONE, *notify_port, create_base); - - if(!create_base){ - registration_node_release(n->coalesce_base); - } - - if(status != NOTIFY_STATUS_OK){ - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, 0, 0); - if (IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - } - else - { - token = atomic_increment32(&globals->token_id); - cid = token; - - kstatus = _notify_server_register_mach_port_2(globals->notify_server_port, (caddr_t)name, token, port); - if (kstatus != KERN_SUCCESS) - { - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, 0, 0); - mach_port_deallocate(task, *notify_port); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (kstatus: %d)", __func__, - NOTIFY_STATUS_REG_MACH_PORT_2_FAILED, __LINE__, kstatus); - return NOTIFY_STATUS_FAILED; - } - - status = client_registration_create_base(name, NID_UNSET, token, cid, SLOT_NONE, - tflags, SIGNAL_NONE, FD_NONE, *notify_port, false); - - if(status != NOTIFY_STATUS_OK) - { - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, 0, 0); - if (IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - if ((globals->client_opts & NOTIFY_OPT_DISPATCH) && (flags & _NOTIFY_COMMON_PORT) == 0) - { - /* - * If we use dispatch to forward notifications to this port, the the library needs the send right. - */ - kstatus = mach_port_insert_right(task, *notify_port, *notify_port, MACH_MSG_TYPE_MAKE_SEND); - if (kstatus != KERN_SUCCESS) - { - if (mine == 1) mach_port_destruct(mach_task_self(), *notify_port, 0, 0); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_PORT; - } - - r = registration_node_find(token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_TOKEN_NOT_FOUND, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - /* remember to release the send right when this gets cancelled */ - r->flags |= NOTIFY_FLAG_RELEASE_SEND; - - port = *notify_port; - r->queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); - dispatch_retain(r->queue); - r->block = (notify_handler_t)Block_copy(^(int unused){ - mach_msg_empty_send_t msg; - kern_return_t kstatus; - - /* send empty message to the port with msgh_id = token; */ - memset(&msg, 0, sizeof(msg)); - msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSGH_BITS_ZERO); - msg.header.msgh_remote_port = port; - msg.header.msgh_local_port = MACH_PORT_NULL; - msg.header.msgh_size = sizeof(mach_msg_empty_send_t); - msg.header.msgh_id = token; - - kstatus = mach_msg(&msg.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, msg.header.msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL); - if (kstatus == MACH_SEND_TIMED_OUT) - { - dispatch_once(&globals->make_background_send_queue_once, ^{ - globals->background_send_queue = dispatch_queue_create("com.apple.notify.background.local.notification", NULL); - }); - - if (globals->background_send_queue != NULL) dispatch_async(globals->background_send_queue, ^{ - mach_msg_empty_send_t msg; - kern_return_t kstatus; - - /* send empty message to the port with msgh_id = token; */ - memset(&msg, 0, sizeof(msg)); - msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSGH_BITS_ZERO); - msg.header.msgh_remote_port = port; - msg.header.msgh_local_port = MACH_PORT_NULL; - msg.header.msgh_size = sizeof(mach_msg_empty_send_t); - msg.header.msgh_id = token; - - kstatus = mach_msg(&msg.header, MACH_SEND_MSG, msg.header.msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL); - }); - } - }); - - registration_node_release(r); - } - - *out_token = token; - notify_retain_mach_port(globals, *notify_port, flags); - NOTIFY_REGISTER_MACH_PORT(name, *notify_port, flags, token); - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - -uint32_t -notify_register_file_descriptor(const char *name, int *notify_fd, int flags, int *out_token) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - uint32_t i, status; - uint64_t nid; - int token, mine, fdpair[2]; - fileport_t fileport; - kern_return_t kstatus; - uint32_t cid = -1; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - mine = 0; - - if (name == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor name=NULL\n"); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_NAME; - } - - if (notify_fd == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor notify_fd=NULL\n"); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_FILE; - } - - if ((flags & NOTIFY_REUSE) == 0) - { - if (pipe(fdpair) < 0) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor %s [non-reused[ pipe failed errno=%d [%s]\n, name, errno, strerror(errno)"); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_PIPE_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - mine = 1; - *notify_fd = fdpair[0]; - } - else - { - /* check the file descriptor - it must be one of "ours" */ - for (i = 0; i < globals->fd_count; i++) - { - if (globals->fd_clnt[i] == *notify_fd) break; - } - - if (i >= globals->fd_count) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor %s [reused] file not found\n", name); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_FILE; - } - - fdpair[0] = globals->fd_clnt[i]; - fdpair[1] = globals->fd_srv[i]; - } - - if (!strncmp(name, SELF_PREFIX, SELF_PREFIX_LEN)) - { - token = atomic_increment32(&globals->token_id); - status = _notify_lib_register_file_descriptor(&globals->self_state, name, NOTIFY_CLIENT_SELF, token, fdpair[1], 0, 0, &nid); - if (status != NOTIFY_STATUS_OK) - { - if (mine == 1) - { - close(fdpair[0]); - close(fdpair[1]); - } - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor %s [self] _notify_lib_register_file_descriptor failed status=%u\n", name, status); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - cid = token; - status = client_registration_create(name, nid, token, cid, SLOT_NONE, - NOTIFY_FLAG_SELF | NOTIFY_TYPE_FILE, SIGNAL_NONE, *notify_fd, MACH_PORT_NULL); - - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, - "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; - notify_retain_file_descriptor(fdpair[0], fdpair[1]); - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - if (globals->client_opts & NOTIFY_OPT_DISPATCH) - { - /* - * Use dispatch to do a write() on fdpair[1] when notified. - */ - status = notify_register_mux_fd(name, out_token, fdpair[0], fdpair[1]); - if (status != NOTIFY_STATUS_OK) - { - if (mine == 1) - { - close(fdpair[0]); - close(fdpair[1]); - } - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor %s notify_register_mux_fd failed status=%u\n", name, status); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - notify_retain_file_descriptor(fdpair[0], fdpair[1]); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - if (mine == 1) - { - close(fdpair[0]); - close(fdpair[1]); - } - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor %s _notify_lib_init failed status=%u\n", name, status); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - /* send fdpair[1] (the sender's fd) to notifyd using a fileport */ - fileport = MACH_PORT_NULL; - if (fileport_makeport(fdpair[1], (fileport_t *)&fileport) < 0) - { - if (mine == 1) - { - close(fdpair[0]); - close(fdpair[1]); - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor %s fileport_makeport failed errno=%d [%s]\n", name, errno, strerror(errno)); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_FILEPORT_MAKEPORT_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - token = atomic_increment32(&globals->token_id); - kstatus = _notify_server_register_file_descriptor_2(globals->notify_server_port, (caddr_t)name, token, (mach_port_t)fileport); - if (kstatus != KERN_SUCCESS) - { - if (mine == 1) - { - close(fdpair[0]); - close(fdpair[1]); - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_register_file_descriptor %s _notify_server_register_file_descriptor[_2] failed status=0x%08xu\n", name, kstatus); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (kstatus: %d)", __func__, - NOTIFY_STATUS_REG_FD_2_FAILED, __LINE__, kstatus); - return NOTIFY_STATUS_FAILED; - } - - status = client_registration_create(name, NID_UNSET, token, cid, SLOT_NONE, NOTIFY_TYPE_FILE, - SIGNAL_NONE, *notify_fd, MACH_PORT_NULL); - - if (status != NOTIFY_STATUS_OK) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, - "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - *out_token = token; - notify_retain_file_descriptor(fdpair[0], fdpair[1]); - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - -uint32_t -notify_check(int token, int *check) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status = NOTIFY_STATUS_OK; - registration_node_t *r; - uint32_t tid; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (check == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check check=NULL\n", token); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_NULL_INPUT; - } - - r = registration_node_find(token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d registration node not found\n", token); - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->flags & NOTIFY_FLAG_SELF) - { - /* _notify_lib_check returns NOTIFY_STATUS_NULL_INPUT if self_state is NULL */ - status = _notify_lib_check(&globals->self_state, NOTIFY_CLIENT_SELF, token, check); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d self registration _notify_lib_check status %u check %d\n", token, status, *check); - if ((_libnotify_debug & DEBUG_USER) && (status != NOTIFY_STATUS_NULL_INPUT)) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d [self] _notify_lib_check failed status=%u\n", token, status); -#endif - goto release_and_return; - } - - if (r->flags & NOTIFY_TYPE_MEMORY) - { - if (globals->shm_base == NULL) - { - status = NOTIFY_STATUS_SHM_BASE_NULL; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d [memory] globals->shm_base is NULL\n", token); -#endif - goto release_and_return; - } - - *check = 0; - - mutex_lock("check_lock", &globals->check_lock, __func__, __LINE__); - if (r->val != globals->shm_base[r->slot]) - { - *check = 1; - r->val = globals->shm_base[r->slot]; - } - mutex_unlock("check_lock", &globals->check_lock, __func__, __LINE__); - - - status = NOTIFY_STATUS_OK; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d shared memory check status %u check %d\n", token, status, *check); -#endif - goto release_and_return; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d in not a shared memory registration\n", token); -#endif - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != 0) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d [non-memory] _notify_lib_init failed status=%u\n", token, status); -#endif - goto release_and_return; - } - } - - tid = token; - if (r->flags & NOTIFY_TYPE_COALESCED) tid = r->name_node->coalesce_base_token; - - kstatus = _notify_server_check(globals->notify_server_port, tid, check, (int32_t *)&status); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d [%d] _notify_server_check kstatus 0x%08x status %u check %d\n", token, tid, kstatus, status, *check); -#endif - if (kstatus != KERN_SUCCESS) - { - status = NOTIFY_STATUS_SERVER_CHECK_FAILED; -#ifdef DEBUG - if (_libnotify_debug & DEBUG_USER) _notify_client_log(ASL_LEVEL_ERR, "notify_check token %d [non-memory] _notify_server_check failed kstatus=0x%08x status=%u\n", token, kstatus, status); -#endif - } - -release_and_return: - - NOTIFY_CHECK(token, *check); - - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d] status %u check %d\n", __func__, __LINE__ + 2, status, *check); -#endif - return status; -} - -/* Used in Libinfo without header declaration */ -uint32_t -notify_peek(int token, uint32_t *val) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - registration_node_t *r; - uint32_t status; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - r = registration_node_find(token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->flags & NOTIFY_FLAG_SELF) - { - /* _notify_lib_peek returns NOTIFY_STATUS_NULL_INPUT if self_state is NULL */ - status = _notify_lib_peek(&globals->self_state, NOTIFY_CLIENT_SELF, token, (int *)val); - goto release_and_return; - } - - status = NOTIFY_STATUS_INVALID_REQUEST; - - if (r->flags & NOTIFY_TYPE_MEMORY) - { - if (globals->shm_base == NULL) - { - status = NOTIFY_STATUS_SHM_BASE_NULL; - goto release_and_return; - } - - *val = globals->shm_base[r->slot]; - status = NOTIFY_STATUS_OK; - } - -release_and_return: - - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; -} - -/* Used by Libc, cctools, configd, kext_tools, Libnotify, and libresolv without header declaration */ -uint32_t -notify_monitor_file(int token, char *path, int flags) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status; - registration_node_t *r; - char *dup; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (path == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_REQUEST; - } - - r = registration_node_find(token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->flags & NOTIFY_FLAG_SELF) - { - registration_node_release(r); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_REQUEST; - } - - /* can only monitor one path with a token */ - if (r->path != NULL) - { - registration_node_release(r); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_REQUEST; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - dup = strdup(path); - if (dup == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_STRDUP_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - - { - int xtoken = token; - int len = (uint32_t)(strlen(path) + 1); - if (r->flags & NOTIFY_TYPE_COALESCED) xtoken = r->name_node->coalesce_base_token; - - kstatus = _notify_server_monitor_file_2(globals->notify_server_port, xtoken, path, len, flags); - } - - r->path = dup; - r->path_flags = flags; - - registration_node_release(r); - - if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (kstatus: %d)", __func__, - NOTIFY_STATUS_STRDUP_FAILED, __LINE__, kstatus); - return NOTIFY_STATUS_SERVER_MONITOR_FILE_2_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - -/* Used by kext_tools without header declaration */ -uint32_t -notify_get_event(int token, int *ev, char *buf, int *len) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - static bool report_deprecated_once = true; - - if(report_deprecated_once) - { - REPORT_BAD_BEHAVIOR("Libnotify client using deprecated function notify_get_event; this function does nothing"); - report_deprecated_once = false; - } - - if (ev != NULL) *ev = 0; - if (len != NULL) *len = 0; - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - -uint32_t -notify_get_state(int token, uint64_t *state) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status; - registration_node_t *r; - uint64_t nid; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - r = registration_node_find(token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->name_node == NULL) - { - registration_node_release(r); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->flags & NOTIFY_FLAG_SELF) - { - /* _notify_lib_get_state returns NOTIFY_STATUS_NULL_INPUT if self_state is NULL */ - status = _notify_lib_get_state(&globals->self_state, r->name_node->name_id, state, 0, 0); - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - { - name_node_t *name_node = r->name_node; - int xtoken = token; - if (r->flags & NOTIFY_TYPE_COALESCED) xtoken = name_node->coalesce_base_token; - - // This is a race, but it is safe. The worst case is that nid is looked-up and set twice. - mutex_lock(name_node->name, &name_node->lock, __func__, __LINE__); - nid = name_node->name_id; - mutex_unlock(name_node->name, &name_node->lock, __func__, __LINE__); - - if ((nid == NID_UNSET) || (nid == NID_CALLED_ONCE)) - { - kstatus = _notify_server_get_state_3(globals->notify_server_port, xtoken, state, (uint64_t *)&nid, (int32_t *)&status); - if ((kstatus == KERN_SUCCESS) && (status == NOTIFY_STATUS_OK)) name_node_set_nid(name_node, nid); - } - else - { - kstatus = _notify_server_get_state_2(globals->notify_server_port, nid, state, (int32_t *)&status); - } - } - - registration_node_release(r); - - if (kstatus != KERN_SUCCESS) - { - status = NOTIFY_STATUS_SERVER_GET_STATE_2_FAILED; - } - - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; -} - -uint32_t -notify_set_state(int token, uint64_t state) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - kern_return_t kstatus; - uint32_t status; - registration_node_t *r; - uint64_t nid; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - r = registration_node_find(token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->name_node == NULL) - { - registration_node_release(r); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->flags & NOTIFY_FLAG_SELF) - { - /* _notify_lib_set_state returns NOTIFY_STATUS_NULL_INPUT if self_state is NULL */ - status = _notify_lib_set_state(&globals->self_state, r->name_node->name_id, state, 0, 0); - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - status = NOTIFY_STATUS_OK; - - { - name_node_t *name_node = r->name_node; - int xtoken = token; - if (r->flags & NOTIFY_TYPE_COALESCED) xtoken = name_node->coalesce_base_token; - - // This is a race, but it is safe. The worst case is that nid is looked-up and set twice. - mutex_lock(name_node->name, &name_node->lock, __func__, __LINE__); - nid = name_node->name_id; - mutex_unlock(name_node->name, &name_node->lock, __func__, __LINE__); - - if ((nid == NID_UNSET) || (nid == NID_CALLED_ONCE)) - { - kstatus = _notify_server_set_state_3(globals->notify_server_port, xtoken, state, (uint64_t *)&nid, (int32_t *)&status, should_claim_root_access()); - if ((kstatus == KERN_SUCCESS) && (status == NOTIFY_STATUS_OK)) name_node_set_nid(name_node, nid); - } - else - { - status = NOTIFY_STATUS_OK; - kstatus = _notify_server_set_state_2(globals->notify_server_port, nid, state, should_claim_root_access()); - } - } - - if ((kstatus == KERN_SUCCESS) && (status == NOTIFY_STATUS_OK)) - { - r->set_state_time = mach_absolute_time(); - r->set_state_val = state; - } - - registration_node_release(r); - if (kstatus != KERN_SUCCESS) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, - NOTIFY_STATUS_SERVER_SET_STATE_2_FAILED, __LINE__); - return NOTIFY_STATUS_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; -} - -uint32_t -notify_cancel(int token) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - registration_node_t *r; - notify_globals_t globals = _notify_globals(); - uint32_t status; - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - mutex_lock("global", &globals->notify_lock, __func__, __LINE__); - - r = _nc_table_find_n(&globals->registration_table, token); - if (r == NULL) - { - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (!(r->flags & NOTIFY_FLAG_CANCELED)) { - r->flags |= NOTIFY_FLAG_CANCELED; - registration_node_release_locked(globals, r); - } - mutex_unlock("global", &globals->notify_lock, __func__, __LINE__); - // Always return OK here as there's nothing a client can do if the server call failed - return NOTIFY_STATUS_OK; -} - -uint32_t -notify_suspend(int token) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - registration_node_t *r; - uint32_t status, tid; - kern_return_t kstatus; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - r = registration_node_find(token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->flags & NOTIFY_FLAG_SELF) - { - _notify_lib_suspend(&globals->self_state, NOTIFY_CLIENT_SELF, r->token); - registration_node_release(r); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - int xtoken = token; - if (r->flags & NOTIFY_TYPE_COALESCED) xtoken = r->name_node->coalesce_base_token; - - tid = xtoken; - if (r->flags & NOTIFY_TYPE_COALESCED) tid = r->name_node->coalesce_base_token; - - kstatus = _notify_server_suspend(globals->notify_server_port, tid, (int32_t *)&status); - - registration_node_release(r); - - if (kstatus != KERN_SUCCESS) status = NOTIFY_STATUS_SERVER_SUSPEND_FAILED; - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; -} - -uint32_t -notify_resume(int token) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - registration_node_t *r; - uint32_t status, tid; - kern_return_t kstatus; - notify_globals_t globals = _notify_globals(); - - status = regenerate_check(globals); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - - r = registration_node_find(token); - if (r == NULL) - { -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_INVALID_TOKEN; - } - - if (r->flags & NOTIFY_FLAG_SELF) - { - _notify_lib_resume(&globals->self_state, NOTIFY_CLIENT_SELF, r->token); - registration_node_release(r); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return NOTIFY_STATUS_OK; - } - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - registration_node_release(r); - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - int xtoken = token; - if (r->flags & NOTIFY_TYPE_COALESCED) xtoken = r->name_node->coalesce_base_token; - - tid = xtoken; - if (r->flags & NOTIFY_TYPE_COALESCED) tid = r->name_node->coalesce_base_token; - - kstatus = _notify_server_resume(globals->notify_server_port, tid, (int32_t *)&status); - - registration_node_release(r); - - if (kstatus != KERN_SUCCESS) status = NOTIFY_STATUS_SERVER_RESUME_FAILED; - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; -} - -uint32_t -notify_suspend_pid(pid_t pid) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - uint32_t status = NOTIFY_STATUS_OK; - kern_return_t kstatus; - notify_globals_t globals = _notify_globals(); - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - kstatus = _notify_server_suspend_pid(globals->notify_server_port, pid); - - if(kstatus != KERN_SUCCESS) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, kstatus, __LINE__); - status = NOTIFY_STATUS_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; -} - -uint32_t -notify_resume_pid(pid_t pid) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - uint32_t status = NOTIFY_STATUS_OK; - kern_return_t kstatus; - notify_globals_t globals = _notify_globals(); - - if (globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; - } - } - - kstatus = _notify_server_resume_pid(globals->notify_server_port, pid); - - if(kstatus != KERN_SUCCESS) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, kstatus, __LINE__); - status = NOTIFY_STATUS_FAILED; - } - -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; -} - -/* Deprecated SPI */ -uint32_t -notify_simple_post(const char *name) -{ -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "-> %s\n", __func__); -#endif - - static bool report_deprecated_once = true; - - if(report_deprecated_once) - { - REPORT_BAD_BEHAVIOR("Libnotify client using deprecated function notify_simple_post, use notify_post instead"); - report_deprecated_once = false; - } - - uint32_t status = notify_post(name); -#ifdef DEBUG - if (_libnotify_debug & DEBUG_API) _notify_client_log(ASL_LEVEL_NOTICE, "<- %s [%d]\n", __func__, __LINE__ + 2); -#endif - return status; -} - - -uint32_t -notify_dump_status(const char *filepath) -{ - notify_globals_t globals; - uint32_t status; - uint32_t kstatus; - int fileport_status; - int file_descriptor; - fileport_t fileport; - - globals = _notify_globals(); - - if(globals->notify_server_port == MACH_PORT_NULL) - { - status = _notify_lib_init(globals, EVENT_INIT); - if (status != NOTIFY_STATUS_OK) - { - if(IS_INTERNAL_ERROR(status)) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d", __func__, status, __LINE__); - status = NOTIFY_STATUS_FAILED; - } - - return status; - } - } - - - file_descriptor = creat(filepath, S_IWUSR); - if(file_descriptor < 0) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (errno: %d)", __func__, NOTIFY_STATUS_FAILED, __LINE__, errno); - return NOTIFY_STATUS_FAILED; - } - - - fileport = FILEPORT_NULL; - fileport_status = fileport_makeport(file_descriptor, &fileport); - if(fileport_status < 0) - { - close(file_descriptor); - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (fileport_status: %d)", __func__, NOTIFY_STATUS_FAILED, __LINE__, fileport_status); - return NOTIFY_STATUS_FAILED; - } - - - kstatus = _notify_server_dump(globals->notify_server_port, (mach_port_t)fileport); - close(file_descriptor); - if(kstatus != KERN_SUCCESS) - { - REPORT_BAD_BEHAVIOR("Libnotify: %s failed with code %d on line %d (kstatus: %d)", __func__, NOTIFY_STATUS_FAILED, __LINE__, kstatus); - return NOTIFY_STATUS_FAILED; - } - - - return NOTIFY_STATUS_OK; -} - - diff --git a/src/libnotify/notify_get_state.3 b/src/libnotify/notify_get_state.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_get_state.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_internal.h b/src/libnotify/notify_internal.h deleted file mode 100644 index 4d6d8e8bd..000000000 --- a/src/libnotify/notify_internal.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2012 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#define __OS_EXPOSE_INTERNALS__ 1 -#include - -#include -#include -#include -#include -#include -#include - -#include "libnotify.h" - -#define NOTIFY_INTERNAL_CRASH(c, x) __extension__({ \ - _os_set_crash_log_cause_and_message(c, "BUG IN LIBNOTIFY: " x); \ - __builtin_trap(); \ - }) - -#define NOTIFY_CLIENT_CRASH(c, x) __extension__({ \ - _os_set_crash_log_cause_and_message(c, \ - "BUG IN CLIENT OF LIBNOTIFY: " x); \ - __builtin_trap(); \ - }) - -#define NOTIFY_STATUS_SERVER_CHECKIN_FAILED 11 -// was NOTIFY_STATUS_LIB_SELF_STATE_FAILED 12 -#define NOTIFY_STATUS_SERVER_REGEN_FAILED 13 -#define NOTIFY_STATUS_CLIENT_REG_FAILED 14 -#define NOTIFY_STATUS_SERVER_POST_4_FAILED 15 -#define NOTIFY_STATUS_SERVER_POST_2_FAILED 16 -#define NOTIFY_STATUS_SERVER_POST_3_FAILED 17 -#define NOTIFY_STATUS_TOKEN_NOT_FOUND 18 -#define NOTIFY_STATUS_COMMON_PORT_NULL 19 -#define NOTIFY_STATUS_SERVER_PORT_NULL 20 -#define NOTIFY_STATUS_REG_CHECK_2_FAILED 21 -#define NOTIFY_STATUS_SHM_ATTACH_FAILED 22 -#define NOTIFY_STATUS_SHM_BASE_REMAINS_NULL 23 -#define NOTIFY_STATUS_REG_PLAIN_2_FAILED 24 -#define NOTIFY_STATUS_REG_SIGNAL_2_FAILED 25 -#define NOTIFY_STATUS_MACH_PORT_ALLOC_FAILED 26 -#define NOTIFY_STATUS_MACH_PORT_INSERT_RIGHT_FAILED 27 -#define NOTIFY_STATUS_REG_MACH_PORT_2_FAILED 28 -#define NOTIFY_STATUS_PIPE_FAILED 29 -#define NOTIFY_STATUS_FILEPORT_MAKEPORT_FAILED 30 -#define NOTIFY_STATUS_REG_FD_2_FAILED 31 -#define NOTIFY_STATUS_SHM_BASE_NULL 32 -#define NOTIFY_STATUS_SERVER_CHECK_FAILED 33 -#define NOTIFY_STATUS_STRDUP_FAILED 34 -#define NOTIFY_STATUS_SERVER_MONITOR_FILE_2_FAILED 35 -#define NOTIFY_STATUS_SERVER_GET_STATE_2_FAILED 36 -#define NOTIFY_STATUS_SERVER_SET_STATE_2_FAILED 37 -#define NOTIFY_STATUS_SERVER_SUSPEND_FAILED 38 -#define NOTIFY_STATUS_SERVER_RESUME_FAILED 39 -#define NOTIFY_STATUS_SERVER_SUSPEND_PID_FAILED 40 -#define NOTIFY_STATUS_SERVER_RESUME_PID_FAILED 41 -#define NOTIFY_STATUS_ALLOC_FAILED 42 -#define NOTIFY_STATUS_KILL_FAILED 43 -#define NOTIFY_STATUS_WRITE_FAILED 44 -#define NOTIFY_STATUS_MACH_MSG_TIMEOUT 45 -#define NOTIFY_STATUS_MACH_MSG_FAILED 46 -#define NOTIFY_STATUS_NEW_NAME_FAILED 47 -#define NOTIFY_STATUS_NEW_CLIENT_FAILED 48 -#define NOTIFY_STATUS_STATE_NULL 49 -#define NOTIFY_STATUS_CLIENT_NOT_FOUND 50 -#define NOTIFY_STATUS_DUP_CLIENT 51 -#define NOTIFY_STATUS_TYPE_ISSUE 52 -#define NOTIFY_STATUS_PATH_NODE_CREATE_FAILED 53 -#define NOTIFY_STATUS_INVALID_TIME_EVENT 54 -#define NOTIFY_STATUS_TIMER_FAILED 55 -#define NOTIFY_STATUS_DOUBLE_REG 56 -#define NOTIFY_STATUS_NO_REGEN_NEEDED 57 - -#define IS_INTERNAL_ERROR(X) (X >= 11) - -#define USER_PROTECTED_UID_PREFIX "user.uid." -#define USER_PROTECTED_UID_PREFIX_LEN 9 - -struct notify_globals_s -{ - /* global lock */ - os_unfair_lock notify_lock; - - /* notify_check() lock */ - os_unfair_lock check_lock; - pid_t notify_server_pid; - - atomic_uint_fast32_t client_opts; - uint32_t saved_opts; - - notify_state_t self_state; - - dispatch_once_t notify_server_port_once; - mach_port_t notify_server_port; - mach_port_t saved_server_port; - - mach_port_t notify_common_port; - int notify_common_token; - dispatch_source_t notify_dispatch_source; - dispatch_source_t server_proc_source; - - dispatch_once_t internal_once; - table_n_t registration_table; - table_t name_node_table; - atomic_uint_fast32_t token_id; - - dispatch_once_t make_background_send_queue_once; - dispatch_queue_t background_send_queue; - - /* file descriptor list */ - uint32_t fd_count; - int *fd_clnt; - int *fd_srv; - int *fd_refcount; - - /* mach port list */ - uint32_t mp_count; - uint32_t mp_size; - struct mp_entry { - mach_port_t mpl_port_name; - int mpl_refs; - bool mpl_mine; - } *mp_list; - - /* shared memory base address */ - uint32_t *shm_base; -}; - -typedef struct notify_globals_s *notify_globals_t; - -__private_extern__ uint32_t _notify_lib_peek(notify_state_t *ns, pid_t pid, int token, int *val); - diff --git a/src/libnotify/notify_ipc.defs b/src/libnotify/notify_ipc.defs deleted file mode 100644 index 1a732cb15..000000000 --- a/src/libnotify/notify_ipc.defs +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2003-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -subsystem notify_ipc 78945000; -serverprefix _; - -import ; - -type notify_name = c_string[*:512] - ctype : caddr_t; - -type notify_path = array[] of char - ctype : caddr_t; - -UseSpecialReplyPort 1; - -skip; // was _notify_server_register_plain -skip; // was _notify_server_cancel - -routine _notify_server_check -( - server : mach_port_t; - token : int; - out check : int; - out status : int; - ServerAuditToken audit : audit_token_t -); - -routine _notify_server_get_state -( - server : mach_port_t; - token : int; - out state : uint64_t; - out status : int; - ServerAuditToken audit : audit_token_t -); - - -routine _notify_server_suspend -( - server : mach_port_t; - token : int; - out status : int; - ServerAuditToken audit : audit_token_t -); - -routine _notify_server_resume -( - server : mach_port_t; - token : int; - out status : int; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_suspend_pid -( - server : mach_port_t; - pid : int; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_resume_pid -( - server : mach_port_t; - pid : int; - ServerAuditToken audit : audit_token_t -); - - - -MsgOption MACH_SEND_PROPAGATE_QOS; - -routine _notify_server_post_2 -( - server : mach_port_t; - name : notify_name; - out name_id : uint64_t; - out status : int; - claim_root_access : boolean_t; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_post_3 -( - server : mach_port_t; - name_id : uint64_t; - claim_root_access : boolean_t; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_post_4 -( - server : mach_port_t; - name : notify_name; - claim_root_access : boolean_t; - ServerAuditToken audit : audit_token_t -); - -MsgOption MACH_MSG_OPTION_NONE; - -simpleroutine _notify_server_register_plain_2 -( - server : mach_port_t; - name : notify_name; - token : int; - ServerAuditToken audit : audit_token_t -); - -routine _notify_server_register_check_2 -( - server : mach_port_t; - name : notify_name; - token: int; - out size : int; - out slot : int; - out name_id : uint64_t; - out status : int; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_register_signal_2 -( - server : mach_port_t; - name : notify_name; - token : int; - sig: int; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_register_file_descriptor_2 -( - server : mach_port_t; - name : notify_name; - token: int; - fileport : mach_port_move_send_t; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_register_mach_port_2 -( - server : mach_port_t; - name : notify_name; - token: int; - port : mach_port_make_send_t; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_cancel_2 -( - server : mach_port_t; - token : int; - ServerAuditToken audit : audit_token_t -); - -routine _notify_server_get_state_2 -( - server : mach_port_t; - name_id : uint64_t; - out state : uint64_t; - out status : int; - ServerAuditToken audit : audit_token_t -); - -routine _notify_server_get_state_3 -( - server : mach_port_t; - token : int; - out state : uint64_t; - out nid : uint64_t; - out status : int; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_set_state_2 -( - server : mach_port_t; - name_id : uint64_t; - state : uint64_t; - claim_root_access : boolean_t; - ServerAuditToken audit : audit_token_t -); - -routine _notify_server_set_state_3 -( - server : mach_port_t; - token : int; - state : uint64_t; - out nid : uint64_t; - out status : int; - claim_root_access : boolean_t; - ServerAuditToken audit : audit_token_t -); - -simpleroutine _notify_server_monitor_file_2 -( - server : mach_port_t; - token : int; - path : notify_path; - flags : int; - ServerAuditToken audit : audit_token_t -); - -routine _notify_server_regenerate -( - server : mach_port_t; - name : notify_name; - token : int; - reg_type : uint32_t; - port : mach_port_make_send_t; - sig: int; - prev_slot: int; - prev_state : uint64_t; - prev_time : uint64_t; - path : notify_path; - path_flags: int; - out new_slot : int; - out new_name_id : uint64_t; - out status : int; - ServerAuditToken audit : audit_token_t -); - - -routine _notify_server_checkin -( - server : mach_port_t; - out version: uint32_t; - out server_pid : uint32_t; - out status : int; - ServerAuditToken audit : audit_token_t -); - - -routine _notify_server_dump -( - server : mach_port_t; - fileport : mach_port_move_send_t; - ServerAuditToken audit : audit_token_t -); diff --git a/src/libnotify/notify_is_valid_token.3 b/src/libnotify/notify_is_valid_token.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_is_valid_token.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_keys.h b/src/libnotify/notify_keys.h deleted file mode 100644 index 528417f97..000000000 --- a/src/libnotify/notify_keys.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2007-2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Portions Copyright (c) 2007-2009 Apple Inc. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * This file lists notification keys that are posted using the - * notify_post() API by various Mac OS X system services. - * The exact circumstances under which services post these - * notifications is controlled by those services, and may change - * in future software releases. - */ - -/* - * Directory Service notifications - * These are posted by the DirectoryService daemon to advise clients that - * cached data should be invalidated. - */ -#define kNotifyDSCacheInvalidation "com.apple.system.DirectoryService.InvalidateCache" -#define kNotifyDSCacheInvalidationGroup "com.apple.system.DirectoryService.InvalidateCache.group" -#define kNotifyDSCacheInvalidationHost "com.apple.system.DirectoryService.InvalidateCache.host" -#define kNotifyDSCacheInvalidationService "com.apple.system.DirectoryService.InvalidateCache.service" -#define kNotifyDSCacheInvalidationUser "com.apple.system.DirectoryService.InvalidateCache.user" - -/* - * File System notifications - * These advise clients of various filesystem events. - */ -#define kNotifyVFSMount "com.apple.system.kernel.mount" -#define kNotifyVFSUnmount "com.apple.system.kernel.unmount" -#define kNotifyVFSUpdate "com.apple.system.kernel.mountupdate" -#define kNotifyVFSLowDiskSpace "com.apple.system.lowdiskspace" -#define kNotifyVFSLowDiskSpaceRootFS "com.apple.system.lowdiskspace.system" -#define kNotifyVFSLowDiskSpaceOtherFS "com.apple.system.lowdiskspace.user" - -/* - * System Configuration notifications - * These advise clients of changes in the system configuration - * managed by the system configuration server (configd). - * Note that a much richer set of notifications are available to - * clients using the SCDynamicStore API. - */ -#define kNotifySCHostNameChange "com.apple.system.hostname" -#define kNotifySCNetworkChange "com.apple.system.config.network_change" - -/* - * ASL notifications - * Sent by syslogd to advise clients that new log messages have been - * added to the ASL database. - */ -#define kNotifyASLDBUpdate "com.apple.system.logger.message" - -/* - * Time Zone change notification - * Sent by notifyd when the system's timezone changes. - */ -#define kNotifyTimeZoneChange "com.apple.system.timezone" - -/* - * System clock change notification - * Sent when a process modifies the system clock using the settimeofday system call. - */ -#define kNotifyClockSet "com.apple.system.clock_set" diff --git a/src/libnotify/notify_post.3 b/src/libnotify/notify_post.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_post.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_private.h b/src/libnotify/notify_private.h deleted file mode 100644 index 7f1b4de32..000000000 --- a/src/libnotify/notify_private.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2009-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __NOTIFY_PRIVATE_H__ -#define __NOTIFY_PRIVATE_H__ - -#include -#include -#include -#include - -#define NOTIFY_OPT_DISPATCH 0x00000001 -#define NOTIFY_OPT_REGEN 0x00000002 -#define NOTIFY_OPT_ENABLE 0x04000000 -#define NOTIFY_OPT_DISABLE 0x08000000 - -#define NOTIFY_NO_DISPATCH 0x80000000 - -#define ROOT_ENTITLEMENT_KEY "com.apple.notify.root_access" - -OS_EXPORT uint32_t notify_suspend_pid(pid_t pid) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0); - -OS_EXPORT uint32_t notify_resume_pid(pid_t pid) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0); - -OS_EXPORT uint32_t notify_simple_post(const char *name) -__API_DEPRECATED("No longer supported, use notify_post", macos(10.7, 10.15), ios(4.3, 13.0), watchos(1.0, 6.0), tvos(1.0, 13.0)); - -OS_EXPORT void notify_set_options(uint32_t opts) -__OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0); - -OS_EXPORT void _notify_fork_child(void) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3); - -OS_EXPORT uint32_t notify_peek(int token, uint32_t *val) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3); - -OS_EXPORT uint32_t notify_monitor_file(int token, char *path, int flags) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3); - -OS_EXPORT uint32_t notify_get_event(int token, int *ev, char *buf, int *len) -__API_DEPRECATED("No longer supported", macos(10.7, 10.15), ios(4.3, 13.0), watchos(1.0, 6.0), tvos(1.0, 13.0)); - -OS_EXPORT uint32_t notify_register_plain(const char *name, int *out_token) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3); - -OS_EXPORT uint32_t notify_dump_status(const char *filepath); - -#endif /* __NOTIFY_PRIVATE_H__ */ diff --git a/src/libnotify/notify_probes.d b/src/libnotify/notify_probes.d deleted file mode 100644 index 6669c1caf..000000000 --- a/src/libnotify/notify_probes.d +++ /dev/null @@ -1,7 +0,0 @@ -provider notify { - probe register_mach_port(const char *name, mach_port_name_t notify_port, int flags, int token); - probe post(const char *name); - probe check(int token, int check); - probe deliver_start(const char *name); - probe deliver_end(const char *name); -}; diff --git a/src/libnotify/notify_probes.h b/src/libnotify/notify_probes.h deleted file mode 100644 index 55fe8e3ca..000000000 --- a/src/libnotify/notify_probes.h +++ /dev/null @@ -1,16 +0,0 @@ -// fake DTrace probes for libnotify - -#define NOTIFY_REGISTER_MACH_PORT(...) (0) -#define NOTIFY_REGISTER_MACH_PORT_ENABLED(...) (0) - -#define NOTIFY_POST(...) (0) -#define NOTIFY_POST_ENABLED(...) (0) - -#define NOTIFY_CHECK(...) (0) -#define NOTIFY_CHECK_ENABLED(...) (0) - -#define NOTIFY_DELIVER_START(...) (0) -#define NOTIFY_DELIVER_START_ENABLED(...) (0) - -#define NOTIFY_DELIVER_END(...) (0) -#define NOTIFY_DELIVER_END_ENABLED(...) (0) diff --git a/src/libnotify/notify_register_check.3 b/src/libnotify/notify_register_check.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_register_check.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_register_dispatch.3 b/src/libnotify/notify_register_dispatch.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_register_dispatch.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_register_file_descriptor.3 b/src/libnotify/notify_register_file_descriptor.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_register_file_descriptor.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_register_mach_port.3 b/src/libnotify/notify_register_mach_port.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_register_mach_port.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_register_signal.3 b/src/libnotify/notify_register_signal.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_register_signal.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notify_set_state.3 b/src/libnotify/notify_set_state.3 deleted file mode 100644 index 2d3019baa..000000000 --- a/src/libnotify/notify_set_state.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/notify.3 diff --git a/src/libnotify/notifybench/notify_bench.c b/src/libnotify/notifybench/notify_bench.c deleted file mode 100644 index a645f941b..000000000 --- a/src/libnotify/notifybench/notify_bench.c +++ /dev/null @@ -1,451 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "notify_private.h" - -#ifdef NO_OP_TESTS -extern uint32_t notify_no_op_str_sync(const char *name, size_t len); -extern uint32_t notify_no_op_str_async(const char *name, size_t len); -extern uint32_t notify_no_op_int_sync(int n); -extern uint32_t notify_no_op_int_async(int n); -#endif - -#define MAX_CNT 100 -#define MAX_SPL 10000 - -#define DEFAULT_CNT 50 -#if defined(__arm__) -#define DEFAULT_SPL 501 -#else -#define DEFAULT_SPL 1001 -#endif - -static uint32_t cnt = DEFAULT_CNT; -static uint32_t spl = DEFAULT_SPL; - -static long double time_round_to = (long double)200.0; - -static long double loop_cost; -static mach_timebase_info_data_t tbi; -static uint64_t dmy[MAX_SPL], reg_plain[MAX_SPL], cancel_plain[MAX_SPL], reg_port[MAX_SPL], cancel_port[MAX_SPL]; -static uint64_t post_plain1[MAX_SPL], post_plain2[MAX_SPL], post_plain3[MAX_SPL]; -static uint64_t set_state1[MAX_SPL], set_state2[MAX_SPL], get_state[MAX_SPL]; -static uint64_t reg_check[MAX_SPL], cancel_check[MAX_SPL]; -static uint64_t check1[MAX_SPL], check2[MAX_SPL], check3[MAX_SPL], check4[MAX_SPL], check5[MAX_SPL]; -static uint64_t reg_disp1[MAX_SPL], reg_disp2[MAX_SPL], cancel_disp[MAX_SPL]; - -volatile static int dispatch_changer = 0; - -#ifdef NO_OP_TESTS -static uint64_t nss[MAX_SPL], nsa[MAX_SPL], nis[MAX_SPL], nia[MAX_SPL]; -#endif - -static void __attribute__((noinline)) -print_result(uint64_t *s, const char *str) -{ - unsigned j; - uint64_t m; - long double dd = 0, mm, sd = 0; - - for (j = 0 ; j < spl; j++) { - dd += (long double)s[j]/(long double)cnt; - } - dd = dd/(long double)spl; - - for (j = 0 ; j < spl; j++) { - long double tmp = (long double)s[j]/(long double)cnt - dd; - sd += tmp * tmp; - } - sd = sqrtl(sd/(long double)spl); - - qsort_b(s, spl, sizeof(uint64_t), - ^(const void *a, const void *b){ - const uint64_t l = *(const uint64_t*)a; - const uint64_t r = *(const uint64_t*)b; - return l == r ? 0 : (l < r ? -1 : 1); - }); - m = s[spl/2]; - mm = (long double)m / (long double)cnt; - - if (tbi.numer != tbi.denom) { - dd *= tbi.numer; - dd /= tbi.denom; - mm *= tbi.numer; - mm /= tbi.denom; - sd *= tbi.numer; - sd /= tbi.denom; - } - - if (str) { - dd -= loop_cost; - mm -= loop_cost; - } else { - loop_cost = mm; - } - - dd /= NSEC_PER_USEC; - dd = roundl(dd * time_round_to) / time_round_to; - mm /= NSEC_PER_USEC; - mm = roundl(mm * time_round_to) / time_round_to; - sd /= NSEC_PER_USEC; - sd = roundl(sd * time_round_to) / time_round_to; - - if (!str) { - printf("%-40s %-8s %-8s %-8s\n", - "Symbol", "Median", "Average", "StdDev"); - } - printf("%-36s%8.3Lf us %8.3Lf us %8.3Lf us\n", - str ? str : "Empty loop:", mm, dd, sd); -} - -static void -notify_fence() -{ - int fence_token; - notify_register_check("com.apple.notify.test", &fence_token); - notify_cancel(fence_token); -} - -int -main(int argc, char *argv[]) -{ - uint32_t r; - kern_return_t kr; - unsigned i, j; - - kr = mach_timebase_info(&tbi); - assert(!kr); - - int tok; - r = notify_register_check("dummy.test", &tok); - assert(r == 0); - r = notify_cancel(tok); - assert(r == 0); - - int t[MAX_CNT]; - int t_2[MAX_CNT]; - mach_port_t p[MAX_CNT]; - char *n[MAX_CNT]; - size_t l[MAX_CNT]; - uint64_t s; - int check; - - volatile uint32_t spin = 0; - - dispatch_queue_t disp_q = dispatch_queue_create("Notify.Test", NULL); - - for (i = 1; i < argc; i++) - { - if (!strcmp(argv[i], "-c")) cnt = atoi(argv[++i]); - else if (!strcmp(argv[i], "-s")) spl = atoi(argv[++i]) + 1; - } - - if (cnt > MAX_CNT) cnt = MAX_CNT; - if (spl > MAX_SPL) spl = MAX_SPL + 1; - - for (j = 0 ; j < spl; j++) - { - for (i = 0; i < cnt; i++) - { - r = asprintf(&n[i], "dummy.test.%d", i); - assert(r != -1); - l[i] = strlen(n[i]); - kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &p[i]); - assert(kr == 0); - } - - /* Empty Loop */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - spin++; - } - dmy[j] = mach_absolute_time() - s; - -#ifdef NO_OP_TESTS - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_no_op_str_sync(n[i], l[i]); - assert(r == 0); - } - nss[j] = mach_absolute_time() - s; - - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_no_op_str_async(n[i], l[i]); - assert(r == 0); - } - nsa[j] = mach_absolute_time() - s; - - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_no_op_int_sync(i); - assert(r == 0); - } - nis[j] = mach_absolute_time() - s; - - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_no_op_int_async(i); - assert(r == 0); - } - nia[j] = mach_absolute_time() - s; -#endif - - - - - - /* Register Plain */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_register_plain(n[i], &t[i]); - assert(r == 0); - } - reg_plain[j] = mach_absolute_time() - s; - - /* Post 1 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_post(n[i]); - assert(r == 0); - } - post_plain1[j] = mach_absolute_time() - s; - - /* Post 2 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_post(n[i]); - assert(r == 0); - } - post_plain2[j] = mach_absolute_time() - s; - - /* Post 3 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_post(n[i]); - assert(r == 0); - } - post_plain3[j] = mach_absolute_time() - s; - - /* Cancel Plain */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_cancel(t[i]); - assert(r == 0); - } - cancel_plain[j] = mach_absolute_time() - s; - - /* Register Mach Port */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_register_mach_port(n[i], &p[i], NOTIFY_REUSE, &t[i]); - assert(r == 0); - } - reg_port[j] = mach_absolute_time() - s; - - - /* Set State 1 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_set_state(t[i], 1); - assert(r == 0); - } - set_state1[j] = mach_absolute_time() - s; - - /* Get State */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - uint64_t dummy; - r = notify_get_state(t[i], &dummy); - assert(r == 0); - } - get_state[j] = mach_absolute_time() - s; - - /* Set State 2 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_set_state(t[i], 2); - assert(r == 0); - } - set_state2[j] = mach_absolute_time() - s; - - /* Cancel Port */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_cancel(t[i]); - assert(r == 0); - } - cancel_port[j] = mach_absolute_time() - s; - - - - /* Register Check */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_register_check("com.apple.notify.test.check", &t[i]); - assert(r == 0); - } - reg_check[j] = mach_absolute_time() - s; - - /* Check 1 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_check(t[i], &check); - assert(r == 0); - assert(check == 1); - } - check1[j] = mach_absolute_time() - s; - - /* Check 2 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_check(t[i], &check); - assert(r == 0); - assert(check == 0); - } - check2[j] = mach_absolute_time() - s; - - /* Check 3 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_check(t[i], &check); - assert(r == 0); - assert(check == 0); - } - check3[j] = mach_absolute_time() - s; - - notify_post("com.apple.notify.test.check"); - - notify_fence(); - - /* Check 4 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_check(t[i], &check); - assert(r == 0); - assert(check == 1); - } - check4[j] = mach_absolute_time() - s; - - /* Check 5 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_check(t[i], &check); - assert(r == 0); - assert(check == 0); - } - check5[j] = mach_absolute_time() - s; - - /* Cancel Check */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_cancel(t[i]); - assert(r == 0); - } - cancel_check[j] = mach_absolute_time() - s; - - /* Register Dispatch 1 */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_register_dispatch(n[i], &t[i], disp_q, ^(int x){ - dispatch_changer = x; - }); - assert(r == 0); - } - reg_disp1[j] = mach_absolute_time() - s; - - /* Register Dispatch 2 (Coalesced) */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_register_dispatch(n[i], &t_2[i], disp_q, ^(int x){ - dispatch_changer = x; - - }); - assert(r == 0); - } - reg_disp2[j] = mach_absolute_time() - s; - - /* Cancel Dispatch */ - s = mach_absolute_time(); - for (i = 0; i < cnt; i++) - { - r = notify_cancel(t[i]); - assert(r == 0); - r = notify_cancel(t_2[i]); - assert(r == 0); - } - cancel_disp[j] = mach_absolute_time() - s; - - for (i = 0; i < cnt; i++) - { - free(n[i]); - kr = mach_port_mod_refs(mach_task_self(), p[i], MACH_PORT_RIGHT_RECEIVE, -1); - assert(kr == 0); - } - - } - - print_result(dmy, NULL); -#ifdef NO_OP_TESTS - print_result(nss, "notify_no_op_str_sync:"); - print_result(nsa, "notify_no_op_str_async:"); - print_result(nis, "notify_no_op_int_sync:"); - print_result(nia, "notify_no_op_int_async:"); -#endif - - - print_result(reg_plain, "notify_register_plain:"); - print_result(post_plain1, "notify_post [plain 1]:"); - print_result(post_plain2, "notify_post [plain 2]:"); - print_result(post_plain3, "notify_post [plain 3]:"); - print_result(cancel_plain, "notify_cancel [plain]:"); - print_result(reg_port, "notify_register_mach_port:"); - print_result(set_state1, "notify_set_state [1]:"); - print_result(set_state2, "notify_set_state [2]:"); - print_result(get_state, "notify_get_state:"); - print_result(cancel_port, "notify_cancel [port]"); - - print_result(reg_check, "notify_register_check:"); - print_result(check1, "notify_check [1]:"); - print_result(check2, "notify_check [2]:"); - print_result(check3, "notify_check [3]:"); - print_result(check4, "notify_check [4]:"); - print_result(check5, "notify_check [5]:"); - print_result(cancel_check, "notfiy_cancel [check]:"); - - print_result(reg_disp1, "notify_register_dispatch [1]:"); - print_result(reg_disp2, "notify_register_dispatch [2]:"); - print_result(cancel_disp, "notify_cancel [both disp]:"); - - return 0; -} diff --git a/src/libnotify/notifyd/CMakeLists.txt b/src/libnotify/notifyd/CMakeLists.txt deleted file mode 100644 index 304957f26..000000000 --- a/src/libnotify/notifyd/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -project(notifyd) - -add_compile_definitions( - SINGLE_THREADED_NOTIFY_STATE=1 - MACH_NOTIFY_SEND_POSSIBLE_EXPECTED=1 -) - -mig(notify_ipc.defs) -mig(notify.defs) - -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -set(notifyd_sources - notifyd.c - notify_proc.c - pathwatch.c - service.c - timer.c - ${CMAKE_CURRENT_BINARY_DIR}/notify_ipcServer.c - ${CMAKE_CURRENT_BINARY_DIR}/notifyServer.c -) - -add_darling_executable(notifyd ${notifyd_sources}) -target_link_libraries(notifyd system bsm.0) - -install(TARGETS notifyd DESTINATION libexec/darling/usr/sbin) -install(FILES com.apple.notifyd.plist DESTINATION libexec/darling/System/Library/LaunchDaemons) -install(FILES notifyd.8 DESTINATION libexec/darling/usr/share/man/man8) -install(FILES notify.conf.MacOSX RENAME notify.conf DESTINATION libexec/darling/etc) - diff --git a/src/libnotify/notifyd/com.apple.notifyd.plist b/src/libnotify/notifyd/com.apple.notifyd.plist deleted file mode 100644 index ac07b7337..000000000 --- a/src/libnotify/notifyd/com.apple.notifyd.plist +++ /dev/null @@ -1,33 +0,0 @@ - - - - - EnablePressuredExit - - EnableTransactions - - Label - com.apple.notifyd - EnvironmentVariables - - ASL_DISABLE - 1 - - MachServices - - com.apple.system.notification_center - - - ProgramArguments - - /usr/sbin/notifyd - - JetsamProperties - - JetsamPriority - -1000 - - POSIXSpawnType - Interactive - - diff --git a/src/libnotify/notifyd/com.apple.notifyd.sb b/src/libnotify/notifyd/com.apple.notifyd.sb deleted file mode 100644 index 4aa3173bb..000000000 --- a/src/libnotify/notifyd/com.apple.notifyd.sb +++ /dev/null @@ -1,24 +0,0 @@ -;; Copyright (c) 2015 Apple Inc. All Rights reserved. -;; -;; WARNING: The sandbox rules in this file currently constitute -;; Apple System Private Interface and are subject to change at any time and -;; without notice. -;; - -(version 1) -(deny default) -(import "system.sb") - -;; Allow files to be read -(allow file-read*) - -;; Allow debug status files to be written -(allow file-write* - (regex #"^/private/var/run/notifyd") -) - -;; Allow UNIX signals -(allow signal) - -;; Allow shared memory -(allow ipc-posix-shm) diff --git a/src/libnotify/notifyd/notify.conf.MacOSX b/src/libnotify/notifyd/notify.conf.MacOSX deleted file mode 100644 index 9311a7d7c..000000000 --- a/src/libnotify/notifyd/notify.conf.MacOSX +++ /dev/null @@ -1,11 +0,0 @@ -# -# Notification Center configuration file -# - -reserve com.apple.system. 0 0 rwr-r- -reserve com.apple.system.clock_set 0 266 rwrwr- -monitor com.apple.system.timezone /etc/localtime -monitor com.apple.system.info:/etc/hosts /etc/hosts -monitor com.apple.system.info:/etc/services /etc/services -monitor com.apple.system.info:/etc/protocols /etc/protocols - diff --git a/src/libnotify/notifyd/notify.conf.iOSSimulator b/src/libnotify/notifyd/notify.conf.iOSSimulator deleted file mode 100644 index 9070e3a3b..000000000 --- a/src/libnotify/notifyd/notify.conf.iOSSimulator +++ /dev/null @@ -1,5 +0,0 @@ -# -# Notification Center configuration file -# - -monitor com.apple.system.timezone /etc/localtime diff --git a/src/libnotify/notifyd/notify.conf.iPhone b/src/libnotify/notifyd/notify.conf.iPhone deleted file mode 100644 index c40e4e281..000000000 --- a/src/libnotify/notifyd/notify.conf.iPhone +++ /dev/null @@ -1,9 +0,0 @@ -# -# Notification Center configuration file -# - -reserve com.apple.system. 0 0 rwr-r- -reserve com.apple.system.clock_set 0 266 rwrwr- -monitor com.apple.system.timezone /var/db/timezone/localtime -set com.apple.system.batterysavermode -set com.apple.system.batterysavermode.discretionary diff --git a/src/libnotify/notifyd/notify.defs b/src/libnotify/notifyd/notify.defs deleted file mode 120000 index c0b6ab909..000000000 --- a/src/libnotify/notifyd/notify.defs +++ /dev/null @@ -1 +0,0 @@ -../../../Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/mach/notify.defs \ No newline at end of file diff --git a/src/libnotify/notifyd/notify_ipc.defs b/src/libnotify/notifyd/notify_ipc.defs deleted file mode 120000 index 51c2d6a8f..000000000 --- a/src/libnotify/notifyd/notify_ipc.defs +++ /dev/null @@ -1 +0,0 @@ -../notify_ipc.defs \ No newline at end of file diff --git a/src/libnotify/notifyd/notify_proc.c b/src/libnotify/notifyd/notify_proc.c deleted file mode 100644 index 82121133d..000000000 --- a/src/libnotify/notifyd/notify_proc.c +++ /dev/null @@ -1,1350 +0,0 @@ -/* - * Copyright (c) 2003-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "notifyd.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "notify.h" -#include "service.h" -#include "notify_ipc.h" -#include "notify_ipcServer.h" -#include "notify_internal.h" -#include "notifyServer.h" -#include - -static void -port_arm_mach_notifications(mach_port_t port) -{ - kern_return_t kr; - mach_port_t previous; - - /* arm both DEAD_NAME & SEND_POSSIBLE */ - kr = mach_port_request_notification(mach_task_self(), port, - MACH_NOTIFY_SEND_POSSIBLE, 0, global.mach_notify_port, - MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous); - if (kr != KERN_SUCCESS) { - NOTIFY_INTERNAL_CRASH(kr, "Unable to arm send-possible"); - } - if (previous != MACH_PORT_NULL) { - NOTIFY_INTERNAL_CRASH(kr, "send-possible already armed??"); - } -} - -static void -port_free(void *_pp) -{ - notify_state_t *ns = &global.notify_state; - port_data_t *pdata = _pp; - - if (!LIST_EMPTY(&pdata->clients)) { - NOTIFY_INTERNAL_CRASH(0, "port_proc still had clients"); - } - - _nc_table_delete_n(&ns->port_table, pdata->port); - mach_port_deallocate(mach_task_self(), pdata->port); - - ns->stat_portproc_free++; - free(pdata); -} - -static void -proc_free(void *_pp) -{ - notify_state_t *ns = &global.notify_state; - proc_data_t *pdata = _pp; - - if (!LIST_EMPTY(&pdata->clients)) { - NOTIFY_INTERNAL_CRASH(0, "port_proc still had clients"); - } - - _nc_table_delete_n(&ns->proc_table, pdata->pid); - - ns->stat_portproc_free++; - - dispatch_release(pdata->src); - free(pdata); -} - -static void -proc_create(notify_state_t *ns, client_t *c, pid_t proc, dispatch_source_t src) -{ - proc_data_t *pdata = malloc(sizeof(proc_data_t)); - - if (pdata == NULL) { - // failing here is not an option, and our malloc will never fail - // for such a small allocation - NOTIFY_INTERNAL_CRASH(0, "Unable to allocate portproc"); - } - - ns->stat_portproc_alloc++; - - LIST_INIT(&pdata->clients); - pdata->src = src; - pdata->flags = PORT_PROC_FLAGS_NONE; - pdata->pid = proc; - _nc_table_insert_n(&ns->proc_table, &pdata->pid); - LIST_INSERT_HEAD(&pdata->clients, c, client_pid_entry); - - dispatch_set_context(src, pdata); - dispatch_source_set_cancel_handler_f(src, proc_free); - dispatch_activate(src); -} - -static void -port_create(notify_state_t *ns, client_t *c, mach_port_t port) -{ - port_data_t *pdata = calloc(1, sizeof(port_data_t)); - - if (pdata == NULL) { - // failing here is not an option, and our malloc will never fail - // for such a small allocation - NOTIFY_INTERNAL_CRASH(0, "Unable to allocate portproc"); - } - - ns->stat_portproc_alloc++; - - LIST_INIT(&pdata->clients); - pdata->port = port; - _nc_table_insert_n(&ns->port_table, &pdata->port); - LIST_INSERT_HEAD(&pdata->clients, c, client_port_entry); - - mach_port_insert_right(mach_task_self(), port, port, - MACH_MSG_TYPE_COPY_SEND); - /* arming SEND_POSSIBLE must be done before we attempt any send */ - port_arm_mach_notifications(port); -} - -static bool -proc_register(notify_state_t *ns, client_t *c, pid_t pid) -{ - proc_data_t *pdata = _nc_table_find_n(&ns->proc_table, pid); - if (pdata) { - LIST_INSERT_HEAD(&pdata->clients, c, client_pid_entry); - } - return pdata != NULL; -} - -static bool -port_register(notify_state_t *ns, client_t *c, mach_port_t port) -{ - port_data_t *pdata = _nc_table_find_n(&ns->port_table, port); - if (pdata) { - LIST_INSERT_HEAD(&pdata->clients, c, client_port_entry); - } - return pdata != NULL; -} - -static void -proc_resume(void *_pp) -{ - proc_data_t *pdata = _pp; - client_t *c; - - pdata->flags &= ~NOTIFY_PORT_PROC_STATE_SUSPENDED; - - LIST_FOREACH(c, &pdata->clients, client_pid_entry) { - _notify_lib_resume_client(&global.notify_state, c, pdata, NULL); - } -} - -/* - * a.k.a. port_resume - * - * receiving a send-possible on a port - * causes us to resume sending to it. - */ -kern_return_t -do_mach_notify_send_possible(mach_port_t notify, mach_port_name_t port) -{ - port_data_t *pdata; - client_t *c; - - /* the notification was consumed, re-arm it */ - port_arm_mach_notifications(port); - - pdata = _nc_table_find_n(&global.notify_state.port_table, port); - pdata->flags &= ~NOTIFY_PORT_PROC_STATE_SUSPENDED; - - LIST_FOREACH(c, &pdata->clients, client_port_entry) { - _notify_lib_resume_client(&global.notify_state, c, NULL, pdata); - /* - * If a send failed again, there's not point to keep trying, - * just wait for the send-possible to be issued. - */ - if (pdata->flags & NOTIFY_PORT_PROC_STATE_SUSPENDED) { - break; - } - } - - return KERN_SUCCESS; -} - - -static void -port_proc_cancel_client(client_t *c) -{ - name_info_t *n; - - call_statistics.cleanup++; - - if (c->service_index != 0) - { - service_close(c->service_index); - c->service_index = 0; - } - - n = c->name_info; - assert(n != NULL); - if ((n->refcount == 1) && (n->private != NULL)) - { - service_close(n->private); - n->private = NULL; - } - - if (c->state_and_type & NOTIFY_TYPE_MEMORY) - { - global.shared_memory_refcount[n->slot]--; - } - else if (c->state_and_type & NOTIFY_TYPE_PORT) - { - LIST_REMOVE(c, client_port_entry); - } - LIST_REMOVE(c, client_pid_entry); - - _notify_lib_cancel_client(&global.notify_state, c); -} - -static inline void -proc_cancel(proc_data_t *pdata) -{ - client_t *c, *tmp; - - LIST_FOREACH_SAFE(c, &pdata->clients, client_pid_entry, tmp) { - port_proc_cancel_client(c); - } - - dispatch_source_cancel(pdata->src); -} - -/* - * a.k.a. port_cancel - * - * receiving a dead-name for a port causes us canceling it - */ -kern_return_t -do_mach_notify_dead_name(mach_port_t notify, mach_port_name_t port) -{ - port_data_t *pdata; - client_t *c, *tmp; - - pdata = _nc_table_find_n(&global.notify_state.port_table, port); - LIST_FOREACH_SAFE(c, &pdata->clients, client_port_entry, tmp) { - port_proc_cancel_client(c); - } - port_free(pdata); - - // the act of receiving a dead name notification allocates a dead-name - // right that must be deallocated - mach_port_deallocate(mach_task_self(), port); - return KERN_SUCCESS; -} - - -static void -proc_event(void *_pp) -{ - proc_data_t *pdata = _pp; - - proc_cancel(pdata); -} - -static void -register_proc(client_t *c, pid_t pid) -{ - dispatch_source_t src; - - if (pid <= 0) return; - - if (proc_register(&global.notify_state, c, pid)) { - return; - } - - src = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, pid, - DISPATCH_PROC_EXIT, global.workloop); - dispatch_source_set_event_handler_f(src, proc_event); - - proc_create(&global.notify_state, c, pid, src); -} - -static void -register_port(client_t *c, mach_port_t port) -{ - if (port_register(&global.notify_state, c, port)) { - return; - } - - port_create(&global.notify_state, c, port); -} - - -static uint32_t -string_validate(caddr_t path, mach_msg_type_number_t pathCnt) -{ - if (path == NULL && pathCnt != 0) { - return NOTIFY_STATUS_INVALID_REQUEST; - } - if (path && (pathCnt == 0 || path[pathCnt - 1] != '\0')) { - return NOTIFY_STATUS_INVALID_REQUEST; - } - return NOTIFY_STATUS_OK; -} - -static void -server_preflight(audit_token_t audit, int token, uid_t *uid, gid_t *gid, pid_t *pid, uint64_t *cid) -{ - pid_t xpid; - - if(uid != NULL) - { - *uid = audit_token_to_euid(audit); - } - - if(gid != NULL) - { - *gid = audit_token_to_egid(audit); - } - - xpid = audit_token_to_pid(audit); - if (pid != NULL) - { - *pid = xpid; - } - - if (token > 0) - { - client_t *c; - uint64_t xcid = make_client_id(xpid, token); - if (cid != NULL) *cid = xcid; - - c = _nc_table_find_64(&global.notify_state.client_table, xcid); - if (c != NULL) - { - /* duplicate tokens can occur if a process exec()s */ - log_message(ASL_LEVEL_DEBUG, "duplicate token %d sent from PID %d\n", token, xpid); - port_proc_cancel_client(c); - } - } -} - -kern_return_t __notify_server_post_3 -( - mach_port_t server, - uint64_t name_id, - boolean_t claim_root_access, - audit_token_t audit -) -{ - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - int status; - name_info_t *n; - - n = _nc_table_find_64(&global.notify_state.name_id_table, name_id); - if (n == NULL) - { - return KERN_SUCCESS; // No one is registered for the name - } - - n->postcount++; - - server_preflight(audit, -1, &uid, &gid, &pid, NULL); - - if ((uid != 0) && claim_root_access && has_root_entitlement(audit)) - { - uid = 0; - } - - status = _notify_lib_check_controlled_access(&global.notify_state, n->name, uid, gid, NOTIFY_ACCESS_WRITE); - assert(status != NOTIFY_STATUS_NULL_INPUT); - if (status != NOTIFY_STATUS_OK){ - return KERN_SUCCESS; // The poster does not have permission to post - } - - call_statistics.post++; - call_statistics.post_by_id++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_post %s %d by nameid: %llu \n", n->name, pid, name_id); - - status = daemon_post_nid(name_id, uid, gid); - assert(status == NOTIFY_STATUS_OK); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_post_2 -( - mach_port_t server, - caddr_t name, - uint64_t *name_id, - int *status, - boolean_t claim_root_access, - audit_token_t audit -) -{ - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - name_info_t *n; - - *name_id = 0; - - server_preflight(audit, -1, &uid, &gid, &pid, NULL); - - if ((uid != 0) && claim_root_access && has_root_entitlement(audit)) - { - uid = 0; - } - - *status = _notify_lib_check_controlled_access(&global.notify_state, name, uid, gid, NOTIFY_ACCESS_WRITE); - if (*status != NOTIFY_STATUS_OK) - { - return KERN_SUCCESS; - } - - call_statistics.post++; - call_statistics.post_by_name_and_fetch_id++; - - n = NULL; - *status = daemon_post(name, uid, gid); - assert(*status != NOTIFY_STATUS_NULL_INPUT); - - n = _nc_table_find(&global.notify_state.name_table, name); - - if (n == NULL) - { - *status = NOTIFY_STATUS_INVALID_NAME; - *name_id = UINT64_MAX; - call_statistics.post_no_op++; - } - else - { - n->postcount++; - *name_id = n->name_id; - } - - if (*name_id == UINT64_MAX) log_message(ASL_LEVEL_DEBUG, "__notify_server_post %s %d\n", name, pid); - else log_message(ASL_LEVEL_DEBUG, "__notify_server_post %s %d [%llu]\n", name, pid, *name_id); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_post_4 -( - mach_port_t server, - caddr_t name, - boolean_t claim_root_access, - audit_token_t audit -) -{ - uint64_t ignored_name_id; - int ignored_status; - kern_return_t kstatus; - - kstatus = __notify_server_post_2(server, name, &ignored_name_id, &ignored_status, claim_root_access, audit); - - call_statistics.post_by_name_and_fetch_id--; - call_statistics.post_by_name++; - - return kstatus; -} - -kern_return_t __notify_server_register_plain_2 -( - mach_port_t server, - caddr_t name, - int token, - audit_token_t audit -) -{ - client_t *c; - uint64_t nid, cid; - uint32_t status; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - - call_statistics.reg++; - call_statistics.reg_plain++; - - server_preflight(audit, token, &uid, &gid, &pid, &cid); - - log_message(ASL_LEVEL_DEBUG, "__notify_server_register_plain %s %d %d\n", name, pid, token); - - status = _notify_lib_register_plain(&global.notify_state, name, pid, token, -1, uid, gid, &nid); - if (status != NOTIFY_STATUS_OK) - { - return KERN_SUCCESS; - } - - c = _nc_table_find_64(&global.notify_state.client_table, cid); - - if (!strncmp(name, SERVICE_PREFIX, SERVICE_PREFIX_LEN)) service_open(name, c, audit); - - register_proc(c, pid); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_register_check_2 -( - mach_port_t server, - caddr_t name, - int token, - int *size, - int *slot, - uint64_t *name_id, - int *status, - audit_token_t audit -) -{ - name_info_t *n; - uint32_t i, j, x, new_slot; - uint64_t cid; - client_t *c; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - - *size = 0; - *slot = 0; - *name_id = 0; - *status = NOTIFY_STATUS_OK; - - server_preflight(audit, token, &uid, &gid, &pid, &cid); - - call_statistics.reg++; - call_statistics.reg_check++; - - if (global.nslots == 0) - { - *size = -1; - *slot = -1; - return __notify_server_register_plain_2(server, name, token, audit); - } - - x = (uint32_t)-1; - - n = _nc_table_find(&global.notify_state.name_table, name); - if (n != NULL) x = n->slot; - - new_slot = 0; - if (x == (uint32_t)-1) - { - /* find a slot */ - new_slot = 1; - - /* - * Check slots beginning at the current slot_id + 1, since it's likely that the - * next slot will be available. Keep looking until we have examined all the - * slots (skipping slot 0, which is reserved for notifyd). Stop if we find - * an unused (refcount == 0) slot. - */ - for (i = 1, j = global.slot_id + 1; i < global.nslots; i++, j++) - { - if (j >= global.nslots) j = 1; - if (global.shared_memory_refcount[j] == 0) - { - x = j; - break; - } - } - - if (x == (uint32_t)-1) - { - /* - * We did not find an unused slot. At this point, the shared - * memory table is full, so we start re-using slots, beginning at - * global.slot_id + 1. - */ - global.slot_id++; - - /* wrap around to slot 1 (slot 0 is reserved for notifyd) */ - if (global.slot_id >= global.nslots) global.slot_id = 1; - log_message(ASL_LEVEL_DEBUG, "reused shared memory slot %u\n", global.slot_id); - x = global.slot_id; - } - else - { - /* found a free slot */ - global.slot_id = x; - } - } - - if (new_slot == 1) global.shared_memory_base[x] = 1; - global.shared_memory_refcount[x]++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_register_check %s %d %d\n", name, pid, token); - - *size = global.nslots * sizeof(uint32_t); - *slot = x; - *status = _notify_lib_register_plain(&global.notify_state, name, pid, token, x, uid, gid, name_id); - if (*status != NOTIFY_STATUS_OK) - { - return KERN_SUCCESS; - } - - c = _nc_table_find_64(&global.notify_state.client_table, cid); - - if (!strncmp(name, SERVICE_PREFIX, SERVICE_PREFIX_LEN)) service_open(name, c, audit); - - register_proc(c, pid); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_register_signal_2 -( - mach_port_t server, - caddr_t name, - int token, - int sig, - audit_token_t audit -) -{ - client_t *c; - uint64_t name_id, cid; - uint32_t status; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - - server_preflight(audit, token, &uid, &gid, &pid, &cid); - - call_statistics.reg++; - call_statistics.reg_signal++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_register_signal %s %d %d %d\n", name, pid, token, sig); - - status = _notify_lib_register_signal(&global.notify_state, name, pid, token, sig, uid, gid, &name_id); - if (status != NOTIFY_STATUS_OK) - { - return KERN_SUCCESS; - } - - c = _nc_table_find_64(&global.notify_state.client_table, cid); - - if (!strncmp(name, SERVICE_PREFIX, SERVICE_PREFIX_LEN)) service_open(name, c, audit); - - register_proc(c, pid); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_register_file_descriptor_2 -( - mach_port_t server, - caddr_t name, - int token, - fileport_t fileport, - audit_token_t audit -) -{ - client_t *c; - int fd, flags; - uint32_t status; - uint64_t name_id, cid; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - - server_preflight(audit, token, &uid, &gid, &pid, &cid); - - call_statistics.reg++; - call_statistics.reg_file++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_register_file_descriptor %s %d %d\n", name, pid, token); - - fd = fileport_makefd(fileport); - mach_port_deallocate(mach_task_self(), fileport); - if (fd < 0) - { - return KERN_SUCCESS; - } - - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) - { - return KERN_SUCCESS; - } - - flags |= O_NONBLOCK; - if (fcntl(fd, F_SETFL, flags) < 0) - { - return KERN_SUCCESS; - } - - status = _notify_lib_register_file_descriptor(&global.notify_state, name, pid, token, fd, uid, gid, &name_id); - if (status != NOTIFY_STATUS_OK) - { - return KERN_SUCCESS; - } - - c = _nc_table_find_64(&global.notify_state.client_table, cid); - - if (!strncmp(name, SERVICE_PREFIX, SERVICE_PREFIX_LEN)) service_open(name, c, audit); - - register_proc(c, pid); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_register_mach_port_2 -( - mach_port_t server, - caddr_t name, - int token, - mach_port_t port, - audit_token_t audit -) -{ - client_t *c; - uint64_t name_id, cid; - uint32_t status; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - - if (port == MACH_PORT_DEAD || port == MACH_PORT_NULL) - { - return KERN_SUCCESS; - } - - server_preflight(audit, token, &uid, &gid, &pid, &cid); - - call_statistics.reg++; - call_statistics.reg_port++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_register_mach_port %s %d %d\n", name, pid, token); - - status = _notify_lib_register_mach_port(&global.notify_state, name, pid, token, port, uid, gid, &name_id); - if (status != NOTIFY_STATUS_OK) - { - mach_port_deallocate(mach_task_self(), port); - return KERN_SUCCESS; - } - - c = _nc_table_find_64(&global.notify_state.client_table,cid); - - if (!strncmp(name, SERVICE_PREFIX, SERVICE_PREFIX_LEN)) service_open(name, c, audit); - - register_proc(c, pid); - register_port(c, port); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_cancel_2 -( - mach_port_t server, - int token, - audit_token_t audit -) -{ - client_t *c; - uid_t uid = (uid_t)-1; - pid_t pid = (pid_t)-1; - - server_preflight(audit, -1, &uid, NULL, &pid, NULL); - - call_statistics.cancel++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_cancel %d %d\n", pid, token); - - c = _nc_table_find_64(&global.notify_state.client_table, make_client_id(pid, token)); - if (c != NULL) { - port_proc_cancel_client(c); - } - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_suspend -( - mach_port_t server, - int token, - int *status, - audit_token_t audit -) -{ - pid_t pid = (pid_t)-1; - - server_preflight(audit, -1, NULL, NULL, &pid, NULL); - - call_statistics.suspend++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_suspend %d %d\n", pid, token); - - *status = _notify_lib_suspend(&global.notify_state, pid, token); - assert(*status != NOTIFY_STATUS_NULL_INPUT); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_resume -( - mach_port_t server, - int token, - int *status, - audit_token_t audit -) -{ - pid_t pid = (pid_t)-1; - - server_preflight(audit, -1, NULL, NULL, &pid, NULL); - - call_statistics.resume++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_resume %d %d\n", pid, token); - - *status = _notify_lib_resume(&global.notify_state, pid, token); - assert(*status != NOTIFY_STATUS_NULL_INPUT); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_suspend_pid -( - mach_port_t server, - int pid, - audit_token_t audit -) -{ - uid_t uid; - proc_data_t *pdata; - - uid = audit_token_to_euid(audit); - - call_statistics.suspend_pid++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_suspend_pid %d\n", pid); - - if (uid != 0) - { - log_message(ASL_LEVEL_WARNING, "__notify_server_suspend_pid %d permission denied for caller %d \n", pid, audit_token_to_pid(audit)); - return KERN_SUCCESS; - } - - pdata = _nc_table_find_n(&global.notify_state.proc_table, pid); - if (pdata) { - pdata->flags |= NOTIFY_PORT_PROC_STATE_SUSPENDED; - } - return KERN_SUCCESS; -} - -kern_return_t __notify_server_resume_pid -( - mach_port_t server, - int pid, - audit_token_t audit -) -{ - uid_t uid; - proc_data_t *pdata; - - uid = audit_token_to_euid(audit); - - call_statistics.resume_pid++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_resume_pid %d\n", pid); - - if (uid != 0) - { - log_message(ASL_LEVEL_WARNING, "__notify_server_resume_pid %d permission denied for caller %d \n", pid, audit_token_to_pid(audit)); - return KERN_SUCCESS; - } - - pdata = _nc_table_find_n(&global.notify_state.proc_table, pid); - if (pdata) { - proc_resume(pdata); - } - return KERN_SUCCESS; -} - -kern_return_t __notify_server_check -( - mach_port_t server, - int token, - int *check, - int *status, - audit_token_t audit -) -{ - pid_t pid = (gid_t)-1; - - *check = 0; - - call_statistics.check++; - - audit_token_to_au32(audit, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL); - - log_message(ASL_LEVEL_DEBUG, "__notify_server_check %d %d\n", pid, token); - - *status = _notify_lib_check(&global.notify_state, pid, token, check); - assert(*status != NOTIFY_STATUS_NULL_INPUT); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_get_state -( - mach_port_t server, - int token, - uint64_t *state, - int *status, - audit_token_t audit -) -{ - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - client_t *c; - - *state = 0; - - server_preflight(audit, -1, &uid, &gid, &pid, NULL); - - call_statistics.get_state++; - call_statistics.get_state_by_client++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_get_state %d %d\n", pid, token); - - c = _nc_table_find_64(&global.notify_state.client_table, make_client_id(pid, token)); - if (c == NULL) - { - *status = NOTIFY_STATUS_CLIENT_NOT_FOUND; - } - else - { - *status = _notify_lib_get_state(&global.notify_state, c->name_info->name_id, state, uid, gid); - assert(*status == NOTIFY_STATUS_OK || *status == NOTIFY_STATUS_NOT_AUTHORIZED); - } - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_get_state_2 -( - mach_port_t server, - uint64_t name_id, - uint64_t *state, - int *status, - audit_token_t audit -) -{ - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - - *state = 0; - - server_preflight(audit, -1, &uid, &gid, NULL, NULL); - - log_message(ASL_LEVEL_DEBUG, "__notify_server_get_state_2 %llu\n", name_id); - - *status = _notify_lib_get_state(&global.notify_state, name_id, state, uid, gid); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_get_state_3 -( - mach_port_t server, - int token, - uint64_t *state, - uint64_t *name_id, - int *status, - audit_token_t audit -) -{ - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - client_t *c; - - *state = 0; - *name_id = 0; - - server_preflight(audit, -1, &uid, &gid, &pid, NULL); - - call_statistics.get_state++; - call_statistics.get_state_by_client_and_fetch_id++; - - c = _nc_table_find_64(&global.notify_state.client_table, make_client_id(pid, token)); - if (c == NULL) - { - *status = NOTIFY_STATUS_CLIENT_NOT_FOUND; - *name_id = UINT64_MAX; - } - else - { - *status = _notify_lib_get_state(&global.notify_state, c->name_info->name_id, state, uid, gid); - assert(*status == NOTIFY_STATUS_OK || *status == NOTIFY_STATUS_NOT_AUTHORIZED); - - *name_id = c->name_info->name_id; - } - - if (*name_id == UINT64_MAX) log_message(ASL_LEVEL_DEBUG, "__notify_server_get_state_3 %d %d\n", pid, token); - else log_message(ASL_LEVEL_DEBUG, "__notify_server_get_state_3 %d %d [%llu]\n", pid, token, *name_id); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_set_state_3 -( - mach_port_t server, - int token, - uint64_t state, - uint64_t *name_id, - int *status, - boolean_t claim_root_access, - audit_token_t audit -) -{ - client_t *c; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - - *name_id = 0; - - server_preflight(audit, -1, &uid, &gid, &pid, NULL); - - bool root_entitlement = uid != 0 && claim_root_access && has_root_entitlement(audit); - if (root_entitlement) uid = 0; - - call_statistics.set_state++; - call_statistics.set_state_by_client_and_fetch_id++; - - c = _nc_table_find_64(&global.notify_state.client_table, make_client_id(pid, token)); - if (c == NULL) - { - *status = NOTIFY_STATUS_CLIENT_NOT_FOUND; - *name_id = UINT64_MAX; - } - else - { - assert(c->name_info != NULL); - *status = _notify_lib_set_state(&global.notify_state, c->name_info->name_id, state, uid, gid); - assert(*status == NOTIFY_STATUS_OK || *status == NOTIFY_STATUS_NOT_AUTHORIZED); - - *name_id = c->name_info->name_id; - } - - if (*name_id == UINT64_MAX) log_message(ASL_LEVEL_DEBUG, "__notify_server_set_state_3 %d %d %llu [uid %d%s gid %d]\n", pid, token, state, uid, root_entitlement ? " (entitlement)" : "", gid); - else log_message(ASL_LEVEL_DEBUG, "__notify_server_set_state_3 %d %d %llu [%llu] [uid %d%s gid %d]\n", pid, token, state, *name_id, uid, root_entitlement ? " (entitlement)" : "", gid); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_set_state_2 -( - mach_port_t server, - uint64_t name_id, - uint64_t state, - boolean_t claim_root_access, - audit_token_t audit -) -{ - uint32_t status; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - - call_statistics.set_state++; - call_statistics.set_state_by_id++; - - audit_token_to_au32(audit, NULL, &uid, &gid, NULL, NULL, &pid, NULL, NULL); - - bool root_entitlement = (uid != 0) && claim_root_access && has_root_entitlement(audit); - if (root_entitlement) uid = 0; - - status = _notify_lib_set_state(&global.notify_state, name_id, state, uid, gid); - - if(status == NOTIFY_STATUS_OK){ - log_message(ASL_LEVEL_DEBUG, "__notify_server_set_state_2 %d %llu %llu [uid %d%s gid %d]\n", pid, name_id, state, uid, root_entitlement ? " (entitlement)" : "", gid); - } - - assert(status == NOTIFY_STATUS_OK || status == NOTIFY_STATUS_NOT_AUTHORIZED || - status == NOTIFY_STATUS_INVALID_NAME); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_monitor_file_2 -( - mach_port_t server, - int token, - caddr_t path, - mach_msg_type_number_t pathCnt, - int flags, - audit_token_t audit -) -{ - client_t *c; - name_info_t *n; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - pid_t pid = (pid_t)-1; - uint32_t ubits = (uint32_t)flags; - int status; - - status = string_validate(path, pathCnt); - if (status != NOTIFY_STATUS_OK) return KERN_SUCCESS; - - server_preflight(audit, -1, &uid, &gid, &pid, NULL); - - call_statistics.monitor_file++; - - log_message(ASL_LEVEL_DEBUG, "__notify_server_monitor_file %d %d %s 0x%08x\n", pid, token, path, ubits); - - c = _nc_table_find_64(&global.notify_state.client_table, make_client_id(pid, token)); - if (c == NULL) - { - return KERN_SUCCESS; - } - - n = c->name_info; - assert(n != NULL); - - service_open_path_private(n->name, c, path, audit, ubits); - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_regenerate -( - mach_port_t server, - caddr_t name, - int token, - uint32_t reg_type, - mach_port_t port, - int sig, - int prev_slot, - uint64_t prev_state, - uint64_t prev_time, - caddr_t path, - mach_msg_type_number_t pathCnt, - int path_flags, - int *new_slot, - uint64_t *new_nid, - int *status, - audit_token_t audit -) -{ - kern_return_t kstatus; - pid_t pid = (pid_t)-1; - int size; - name_info_t *n; - client_t *c; - uint64_t cid; - - *new_slot = 0; - *new_nid = 0; - *status = NOTIFY_STATUS_OK; - - *status = string_validate(path, pathCnt); - if (*status != NOTIFY_STATUS_OK) return KERN_SUCCESS; - - call_statistics.regenerate++; - - audit_token_to_au32(audit, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL); - - log_message(ASL_LEVEL_DEBUG, "__notify_server_regenerate %s %d %d %d %u %d %d %llu %s %d\n", name, pid, token, reg_type, port, sig, prev_slot, prev_state, path, path_flags); - - cid = make_client_id(pid, token); - c = _nc_table_find_64(&global.notify_state.client_table, cid); - if (c != NULL) - { - /* duplicate client - this means that a registration interleaved with regeneration; no need to regen */ - *status = NOTIFY_STATUS_DUP_CLIENT; - return KERN_SUCCESS; - } - - switch (reg_type) - { - case NOTIFY_TYPE_MEMORY: - { - /* prev_slot must be between 0 and global.nslots */ - if ((prev_slot < 0) || (prev_slot >= global.nslots)) - { - *status = NOTIFY_STATUS_INVALID_REQUEST; - return KERN_SUCCESS; - } - - kstatus = __notify_server_register_check_2(server, name, token, &size, new_slot, new_nid, status, audit); - if (*status == NOTIFY_STATUS_OK) - { - if ((*new_slot != UINT32_MAX) && (global.last_shm_base != NULL)) - { - global.shared_memory_base[*new_slot] = global.shared_memory_base[*new_slot] + global.last_shm_base[prev_slot] - 1; - global.last_shm_base[prev_slot] = 0; - } - } - break; - } - case NOTIFY_TYPE_PLAIN: - { - kstatus = __notify_server_register_plain_2(server, name, token, audit); - break; - } - case NOTIFY_TYPE_PORT: - { - kstatus = __notify_server_register_mach_port_2(server, name, token, port, audit); - break; - } - case NOTIFY_TYPE_SIGNAL: - { - kstatus = __notify_server_register_signal_2(server, name, token, sig, audit); - break; - } - case NOTIFY_TYPE_FILE: /* fall through */ - default: - { - /* can not regenerate this type */ - *status = NOTIFY_STATUS_TYPE_ISSUE; - return KERN_SUCCESS; - } - } - - if (path != NULL) - { - __notify_server_monitor_file_2(server, token, path, pathCnt, path_flags, audit); - } - - c = _nc_table_find_64(&global.notify_state.client_table, cid); - if (c == NULL) - { - *status = NOTIFY_STATUS_CLIENT_NOT_FOUND; - } - else - { - *status = NOTIFY_STATUS_OK; - n = c->name_info; - *new_nid = n->name_id; - if (prev_time > n->state_time) n->state = prev_state; - } - - return KERN_SUCCESS; -} - -kern_return_t __notify_server_checkin -( - mach_port_t server, - uint32_t *version, - uint32_t *server_pid, - int *status, - audit_token_t audit -) -{ - pid_t pid = (pid_t)-1; - - call_statistics.checkin++; - - audit_token_to_au32(audit, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL); - - log_message(ASL_LEVEL_DEBUG, "__notify_server_checkin %d\n", pid); - *version = NOTIFY_IPC_VERSION; - *server_pid = getpid(); - *status = NOTIFY_STATUS_OK; - return KERN_SUCCESS; -} - - -kern_return_t __notify_server_dump -( - mach_port_t server, - fileport_t fileport, - audit_token_t audit -) -{ - int fd; - int flags; - - // Only processes with euid 0 can use this spi - if (audit_token_to_euid(audit) != 0) - { - mach_port_deallocate(mach_task_self(), fileport); - return KERN_SUCCESS; - } - - // Things starting with "forbidden-" will be automatically denied for any - // sandboxed process, so if this returns non-zero, then that means the - // process is in a sandbox and thus can't use this api - if (sandbox_check_by_audit_token(audit, "forbidden-remote-device-admin", SANDBOX_FILTER_NONE)) { - mach_port_deallocate(mach_task_self(), fileport); - return KERN_SUCCESS; - } - - if (!has_entitlement(audit, NOTIFY_STATE_ENTITLEMENT)) { - mach_port_deallocate(mach_task_self(), fileport); - return KERN_SUCCESS; - } - - fd = fileport_makefd(fileport); - mach_port_deallocate(mach_task_self(), fileport); - if (fd < 0) - { - return KERN_SUCCESS; - } - - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) - { - close(fd); - return KERN_SUCCESS; - } - - flags |= O_NONBLOCK; - if (fcntl(fd, F_SETFL, flags) < 0) - { - close(fd); - return KERN_SUCCESS; - } - - dump_status(STATUS_REQUEST_SHORT, fd); - - close(fd); - - return KERN_SUCCESS; -} diff --git a/src/libnotify/notifyd/notifyd.8 b/src/libnotify/notifyd/notifyd.8 deleted file mode 100644 index af44803bb..000000000 --- a/src/libnotify/notifyd/notifyd.8 +++ /dev/null @@ -1,68 +0,0 @@ -.\" Copyright (c) 2003-2013 Apple Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" Portions Copyright (c) 2003-2010 Apple Inc. All Rights Reserved. -.\" -.\" This file contains Original Code and/or Modifications of Original Code -.\" as defined in and that are subject to the Apple Public Source License -.\" Version 2.0 (the 'License'). You may not use this file except in -.\" compliance with the License. Please obtain a copy of the License at -.\" http://www.opensource.apple.com/apsl/ and read it before using this -.\" file. -.\" -.\" The Original Code and all software distributed under the License are -.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. -.\" Please see the License for the specific language governing rights and -.\" limitations under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.\" -.Dd March 24, 2003 -.Dt notifyd 8 -.Os "Mac OS X" -.Sh NAME -.Nm notifyd -.Nd notification server -.Sh SYNOPSIS -.Nm -.Op Fl d -.Op Fl log_file Ar path -.Op Fl shm_pages Ar npages -.Sh DESCRIPTION -.Nm -is the server for the Mac OS X notification system described in -.Xr notify 3 . -The server is started automatically by -.Nm launchd -during system startup. -.Pp -The -.Fl d -option causes -.Nm notifyd -to log debugging messages to a log file. -Messages are not logged to ASL to avoid potential deadlocks, -since the ASL system makes use of the -.Xr notify 3 -system. -.Pp -The default log file is -.Pa /var/log/notifyd.log . -An alternate log file path may be specified following the -.Fl log_file -flag. -.Pp -The -.Fl shm_pages Ar npages -option sets the number of shared memory pages used for passive notification. -The default is one page. -If a value of zero is specified, -shared memory is disabled and passive notifications are performed -using IPC between the client and the server. -.Sh SEE ALSO -.Xr notify 3 . diff --git a/src/libnotify/notifyd/notifyd.c b/src/libnotify/notifyd/notifyd.c deleted file mode 100644 index a51099fe0..000000000 --- a/src/libnotify/notifyd/notifyd.c +++ /dev/null @@ -1,1436 +0,0 @@ -/* - * Copyright (c) 2003-2012 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "notifyd.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pathwatch.h" -#include "service.h" -#include "pathwatch.h" -#include "timer.h" - -#include "notify_internal.h" -#include "notify.h" -#include "notify_ipc.h" -#include "notify_ipcServer.h" -#include "notify_private.h" -#include "notifyServer.h" - -#define CRSetCrashLogMessage(msg) /**/ - -#define forever for(;;) -#define IndexNull -1 - -/* Compile flags */ -#define RUN_TIME_CHECKS - -#if TARGET_OS_SIMULATOR -static char *_config_file_path; -#define CONFIG_FILE_PATH _config_file_path - -static char *_debug_log_path; -#define DEBUG_LOG_PATH _debug_log_path -#else -#define CONFIG_FILE_PATH "/etc/notify.conf" -#define DEBUG_LOG_PATH "/var/log/notifyd.log" -#endif - - - -#define N_NOTIFY_TYPES 6 - -static int notifyd_token; - -static char *status_file = NULL; - -struct global_s global; -struct call_statistics_s call_statistics; - -static void -notify_reset_stats(void) -{ - _nc_table_foreach(&global.notify_state.name_table, ^bool (void *_n){ - name_info_t *n = _n; - - n->last_hour_postcount = n->postcount; - n->postcount = 0; - return true; - }); - - global.last_reset_time = time(NULL); -} - -dispatch_queue_t -get_notifyd_workloop(void) -{ - return global.workloop; -} - -static const char * -notify_type_name(uint32_t t) -{ - switch (t) - { - case NOTIFY_TYPE_NONE: return "none "; - case NOTIFY_TYPE_MEMORY: return "memory"; - case NOTIFY_TYPE_PLAIN: return "plain "; - case NOTIFY_TYPE_PORT: return "port "; - case NOTIFY_TYPE_FILE: return "file "; - case NOTIFY_TYPE_SIGNAL: return "signal"; - default: return "unknown"; - } - -} - -static void -fprint_client(FILE *f, client_t *c) -{ - if (c == NULL) - { - fprintf(f, "NULL client\n"); - return; - } - - fprintf(f, "client_id: %llu\n", c->cid.hash_key); - fprintf(f, "pid: %d\n", c->cid.pid); - fprintf(f, "token: %d\n", c->cid.token); - fprintf(f, "lastval: %u\n", c->lastval); - fprintf(f, "suspend_count: %u\n", c->suspend_count); - fprintf(f, "type: %s\n", notify_type_name(c->state_and_type & NOTIFY_TYPE_MASK)); - switch(c->state_and_type & NOTIFY_TYPE_MASK) - { - case NOTIFY_TYPE_NONE: - break; - - case NOTIFY_TYPE_PLAIN: - break; - - case NOTIFY_TYPE_MEMORY: - break; - - case NOTIFY_TYPE_PORT: - fprintf(f, "mach port: 0x%08x\n", c->deliver.port); - break; - - case NOTIFY_TYPE_FILE: - fprintf(f, "fd: %d\n", c->deliver.fd); - break; - - case NOTIFY_TYPE_SIGNAL: - fprintf(f, "signal: %d\n", c->deliver.sig); - break; - - default: break; - } -} - -static void -fprint_quick_client(FILE *f, client_t *c) -{ - if (c == NULL) return; - - //client_id,pid,token,lastval,suspend_count,0,type,type-info - fprintf(f, "%llu,%d,%d,%u,%u,%u,", c->cid.hash_key, c->cid.pid, c->cid.token, - c->lastval, c->suspend_count, 0); - - switch(c->state_and_type & NOTIFY_TYPE_MASK) - { - case NOTIFY_TYPE_PORT: - fprintf(f, "port,0x%08x\n", c->deliver.port); - break; - - case NOTIFY_TYPE_FILE: - fprintf(f, "fd,%d\n", c->deliver.fd); - break; - - case NOTIFY_TYPE_SIGNAL: - fprintf(f, "signal,%d\n", c->deliver.sig); - break; - - case NOTIFY_TYPE_MEMORY: - fprintf(f, "check,0\n"); - break; - - case NOTIFY_TYPE_NONE: - case NOTIFY_TYPE_PLAIN: - default: - fprintf(f, "other,0\n"); - break; - } -} - -static void -fprint_quick_name_info(FILE *f, name_info_t *n) -{ - client_t *c; - - if (n == NULL) return; - - // name:name\n - // info:id,uid,gid,access,refcount,postcount,lh_postcount,slot,val,state\n - // clients:\n - // - // - // ... - fprintf(f, "name:%s\n", n->name); - fprintf(f, "info:%llu,%u,%u,%03x,%u,%u,%u,", n->name_id, n->uid, n->gid, n->access, n->refcount, n->postcount, - n->last_hour_postcount); - if (n->slot == -1) - { - fprintf(f, "-1,"); - } - else - { - fprintf(f, "%u,", n->slot); - } - - fprintf(f, "%u,%llu\n", n->val, n->state); - - fprintf(f, "clients:\n"); - - LIST_FOREACH(c, &n->subscriptions, client_subscription_entry) - { - fprint_quick_client(f, c); - } - - fprintf(f, "\n"); - -} - -static void -fprint_name_info(FILE *f, const char *name, name_info_t *n, pid_t *max_pid) -{ - client_t *c; - uint32_t i, reg[N_NOTIFY_TYPES]; - - if (n == NULL) - { - fprintf(f, "%s unknown\n", name); - return; - } - - fprintf(f, "name: %s\n", n->name); - fprintf(f, "id: %llu\n", n->name_id); - fprintf(f, "uid: %u\n", n->uid); - fprintf(f, "gid: %u\n", n->gid); - fprintf(f, "access: %03x\n", n->access); - fprintf(f, "refcount: %u\n", n->refcount); - fprintf(f, "postcount: %u\n", n->postcount); - fprintf(f, "last hour postcount: %u\n", n->last_hour_postcount); - if (n->slot == -1) fprintf(f, "slot: -unassigned-"); - else - { - fprintf(f, "slot: %u", n->slot); - if (global.shared_memory_refcount[n->slot] != -1) - fprintf(f, " = %u (%u)", global.shared_memory_base[n->slot], global.shared_memory_refcount[n->slot]); - } - fprintf(f, "\n"); - fprintf(f, "val: %u\n", n->val); - fprintf(f, "state: %llu\n", n->state); - - for (i = 0; i < N_NOTIFY_TYPES; i++) reg[i] = 0; - - LIST_FOREACH(c, &n->subscriptions, client_subscription_entry) - { - if ((c->cid.pid != (pid_t)-1) && (c->cid.pid > *max_pid)) *max_pid = c->cid.pid; - - switch (c->state_and_type & NOTIFY_TYPE_MASK) - { - case NOTIFY_TYPE_MEMORY: reg[1]++; break; - case NOTIFY_TYPE_PLAIN: reg[2]++; break; - case NOTIFY_TYPE_PORT: reg[3]++; break; - case NOTIFY_TYPE_FILE: reg[4]++; break; - case NOTIFY_TYPE_SIGNAL: reg[5]++; break; - default: reg[0]++; - } - } - - fprintf(f, "types: none %u memory %u plain %u port %u file %u signal %u\n", reg[0], reg[1], reg[2], reg[3], reg[4], reg[5]); - - LIST_FOREACH(c, &n->subscriptions, client_subscription_entry) - { - fprintf(f, "\n"); - fprint_client(f, c); - } -} - -static void -fprint_quick_status(FILE *f) -{ - int32_t i; - - fprintf(f, "--- GLOBALS ---\n"); - fprintf(f, "%u slots (current id %u)\n", global.nslots, global.slot_id); - fprintf(f, "%u log_cutoff (default %u)\n", global.log_cutoff, global.log_default); - fprintf(f, "\n"); - - fprintf(f, "--- STATISTICS ---\n"); - fprintf(f, "post %llu\n", call_statistics.post); - fprintf(f, " id %llu\n", call_statistics.post_by_id); - fprintf(f, " name %llu\n", call_statistics.post_by_name); - fprintf(f, " fetch %llu\n", call_statistics.post_by_name_and_fetch_id); - fprintf(f, " no_op %llu\n", call_statistics.post_no_op); - fprintf(f, "\n"); - fprintf(f, "register %llu\n", call_statistics.reg); - fprintf(f, " plain %llu\n", call_statistics.reg_plain); - fprintf(f, " check %llu\n", call_statistics.reg_check); - fprintf(f, " signal %llu\n", call_statistics.reg_signal); - fprintf(f, " file %llu\n", call_statistics.reg_file); - fprintf(f, " port %llu\n", call_statistics.reg_port); - fprintf(f, "\n"); - fprintf(f, "check %llu\n", call_statistics.check); - fprintf(f, "cancel %llu\n", call_statistics.cancel); - fprintf(f, "cleanup %llu\n", call_statistics.cleanup); - fprintf(f, "regenerate %llu\n", call_statistics.regenerate); - fprintf(f, "checkin %llu\n", call_statistics.checkin); - fprintf(f, "\n"); - fprintf(f, "suspend %llu\n", call_statistics.suspend); - fprintf(f, "resume %llu\n", call_statistics.resume); - fprintf(f, "suspend_pid %llu\n", call_statistics.suspend_pid); - fprintf(f, "resume_pid %llu\n", call_statistics.resume_pid); - fprintf(f, "\n"); - fprintf(f, "get_state %llu\n", call_statistics.get_state); - fprintf(f, " id %llu\n", call_statistics.get_state_by_id); - fprintf(f, " client %llu\n", call_statistics.get_state_by_client); - fprintf(f, " fetch %llu\n", call_statistics.get_state_by_client_and_fetch_id); - fprintf(f, "\n"); - fprintf(f, "set_state %llu\n", call_statistics.set_state); - fprintf(f, " id %llu\n", call_statistics.set_state_by_id); - fprintf(f, " client %llu\n", call_statistics.set_state_by_client); - fprintf(f, " fetch %llu\n", call_statistics.set_state_by_client_and_fetch_id); - fprintf(f, "\n"); - fprintf(f, "set_owner %llu\n", call_statistics.set_owner); - fprintf(f, "\n"); - fprintf(f, "set_access %llu\n", call_statistics.set_access); - fprintf(f, "\n"); - fprintf(f, "monitor %llu\n", call_statistics.monitor_file); - fprintf(f, "svc_path %llu\n", call_statistics.service_path); - fprintf(f, "svc_timer %llu\n", call_statistics.service_timer); - - { - char buf[128]; - strftime(buf, 128, "%a, %d %b %Y %T %z", localtime(&global.last_reset_time)); - fprintf(f, "last reset time was %s\n", buf); - } - - fprintf(f, "\n"); - fprintf(f, "name alloc %9u free %9u extant %9u\n", global.notify_state.stat_name_alloc , global.notify_state.stat_name_free, global.notify_state.stat_name_alloc - global.notify_state.stat_name_free); - fprintf(f, "subscription alloc %9u free %9u extant %9u\n", global.notify_state.stat_client_alloc , global.notify_state.stat_client_free, global.notify_state.stat_client_alloc - global.notify_state.stat_client_free); - fprintf(f, "portproc alloc %9u free %9u extant %9u\n", global.notify_state.stat_portproc_alloc , global.notify_state.stat_portproc_free, global.notify_state.stat_portproc_alloc - global.notify_state.stat_portproc_free); - fprintf(f, "\n"); - - fprintf(f, "port count %u\n", global.notify_state.port_table.count); - fprintf(f, "proc count %u\n", global.notify_state.proc_table.count); - fprintf(f, "\n"); - - fprintf(f, "--- NAME TABLE ---\n"); - fprintf(f, "Name Info: id, uid, gid, access, refcount, postcount, last hour postcount, slot, val, state\n"); - fprintf(f, "Client Info: client_id, pid,token, lastval, suspend_count, 0, 0, type, type-info\n\n\n"); - - _nc_table_foreach(&global.notify_state.name_table, ^bool(void *n) { - fprint_quick_name_info(f, n); - fprintf(f, "\n"); - return true; - }); - - fprintf(f, "--- NAME COUNT %u ---\n", global.notify_state.name_table.count); - fprintf(f, "\n"); - - fprintf(f, "--- CONTROLLED NAME ---\n"); - for (i = 0; i < global.notify_state.controlled_name_count; i++) - { - fprintf(f, "%s %u %u %03x\n", global.notify_state.controlled_name[i]->name, global.notify_state.controlled_name[i]->uid, global.notify_state.controlled_name[i]->gid, global.notify_state.controlled_name[i]->access); - } - fprintf(f, "--- CONTROLLED NAME COUNT %u ---\n", global.notify_state.controlled_name_count); - fprintf(f, "\n"); - - fprintf(f, "--- PUBLIC SERVICE ---\n"); - - _nc_table_foreach(&global.notify_state.name_table, ^bool(void *_n) { - name_info_t *n = _n; - svc_info_t *info; - path_node_t *node; - timer_t *timer; - - if (n->private == NULL) return true; - - info = (svc_info_t *)n->private; - - if (info->type == 0) - { - fprintf(f, "Null service: %s\n", n->name); - } - if (info->type == SERVICE_TYPE_PATH_PUBLIC) - { - node = (path_node_t *)info->private; - fprintf(f, "Path Service: %s <- %s\n", n->name, node->path); - } - else if (info->type == SERVICE_TYPE_TIMER_PUBLIC) - { - timer = (timer_t *)info->private; - switch (timer->type) - { - case TIME_EVENT_ONESHOT: - { - fprintf(f, "Time Service: %s <- Oneshot %llu\n", n->name, timer->start); - break; - } - case TIME_EVENT_CLOCK: - { - fprintf(f, "Time Service: %s <- Clock start %lld freq %u end %lld\n", n->name, timer->start, timer->freq, timer->end); - break; - } - case TIME_EVENT_CAL: - { - fprintf(f, "Time Service: %s <- Calendar start %lld freq %u end %lld day %d\n", n->name, timer->start, timer->freq, timer->end, timer->day); - break; - } - } - } - else - { - fprintf(f, "Unknown service: %s (%u)\n", n->name, info->type); - } - return true; - }); - - fprintf(f, "--- PUBLIC SERVICE COUNT %u ---\n", global.notify_state.name_table.count); - fprintf(f, "\n"); - - fprintf(f, "--- PRIVATE SERVICE ---\n"); - _nc_table_foreach_64(&global.notify_state.client_table, ^bool(void *_c) { - client_t *c = _c; - svc_info_t *info; - name_info_t *n; - path_node_t *node; - timer_t *timer; - - if (c->service_index == 0) return true; - - info = (svc_info_t *)service_info_get(c->service_index); - n = c->name_info; - - if (info->type == 0) - { - fprintf(f, "PID %u Null service: %s\n", c->cid.pid, n->name); - } - if (info->type == SERVICE_TYPE_PATH_PRIVATE) - { - node = (path_node_t *)info->private; - fprintf(f, "PID %u Path Service: %s <- %s\n", c->cid.pid, n->name, node->path); - } - else if (info->type == SERVICE_TYPE_TIMER_PRIVATE) - { - timer = (timer_t *)info->private; - switch (timer->type) - { - case TIME_EVENT_ONESHOT: - { - fprintf(f, "PID %u Time Service: %s <- Oneshot %"PRId64"\n", c->cid.pid, n->name, timer->start); - break; - } - case TIME_EVENT_CLOCK: - { - fprintf(f, "PID %u Time Service: %s <- Clock start %"PRId64" freq %"PRIu32" end %"PRId64"\n", c->cid.pid, n->name, timer->start, timer->freq, timer->end); - break; - } - case TIME_EVENT_CAL: - { - fprintf(f, "PID %u Time Service: %s <- Calendar start %"PRId64" freq %"PRIu32" end %"PRId64" day %"PRId32"\n", c->cid.pid, n->name, timer->start, timer->freq, timer->end, timer->day); - break; - } - } - } - return true; - }); - - fprintf(f, "--- PRIVATE SERVICE COUNT %u ---\n", global.notify_state.client_table.count); - fprintf(f, "\n"); - -} - -static void -fprint_status(FILE *f) -{ - __block pid_t pid, max_pid; - int32_t i; - - max_pid = 0; - - fprintf(f, "--- GLOBALS ---\n"); - fprintf(f, "%u slots (current id %u)\n", global.nslots, global.slot_id); - fprintf(f, "%u log_cutoff (default %u)\n", global.log_cutoff, global.log_default); - fprintf(f, "\n"); - - fprintf(f, "--- STATISTICS ---\n"); - fprintf(f, "post %llu\n", call_statistics.post); - fprintf(f, " id %llu\n", call_statistics.post_by_id); - fprintf(f, " name %llu\n", call_statistics.post_by_name); - fprintf(f, " fetch %llu\n", call_statistics.post_by_name_and_fetch_id); - fprintf(f, " no_op %llu\n", call_statistics.post_no_op); - fprintf(f, "\n"); - fprintf(f, "register %llu\n", call_statistics.reg); - fprintf(f, " plain %llu\n", call_statistics.reg_plain); - fprintf(f, " check %llu\n", call_statistics.reg_check); - fprintf(f, " signal %llu\n", call_statistics.reg_signal); - fprintf(f, " file %llu\n", call_statistics.reg_file); - fprintf(f, " port %llu\n", call_statistics.reg_port); - fprintf(f, "\n"); - fprintf(f, "check %llu\n", call_statistics.check); - fprintf(f, "cancel %llu\n", call_statistics.cancel); - fprintf(f, "cleanup %llu\n", call_statistics.cleanup); - fprintf(f, "regenerate %llu\n", call_statistics.regenerate); - fprintf(f, "checkin %llu\n", call_statistics.checkin); - fprintf(f, "\n"); - fprintf(f, "suspend %llu\n", call_statistics.suspend); - fprintf(f, "resume %llu\n", call_statistics.resume); - fprintf(f, "suspend_pid %llu\n", call_statistics.suspend_pid); - fprintf(f, "resume_pid %llu\n", call_statistics.resume_pid); - fprintf(f, "\n"); - fprintf(f, "get_state %llu\n", call_statistics.get_state); - fprintf(f, " id %llu\n", call_statistics.get_state_by_id); - fprintf(f, " client %llu\n", call_statistics.get_state_by_client); - fprintf(f, " fetch %llu\n", call_statistics.get_state_by_client_and_fetch_id); - fprintf(f, "\n"); - fprintf(f, "set_state %llu\n", call_statistics.set_state); - fprintf(f, " id %llu\n", call_statistics.set_state_by_id); - fprintf(f, " client %llu\n", call_statistics.set_state_by_client); - fprintf(f, " fetch %llu\n", call_statistics.set_state_by_client_and_fetch_id); - fprintf(f, "\n"); - fprintf(f, "set_owner %llu\n", call_statistics.set_owner); - fprintf(f, "\n"); - fprintf(f, "set_access %llu\n", call_statistics.set_access); - fprintf(f, "\n"); - fprintf(f, "monitor %llu\n", call_statistics.monitor_file); - fprintf(f, "svc_path %llu\n", call_statistics.service_path); - fprintf(f, "svc_timer %llu\n", call_statistics.service_timer); - - - { - char buf[128]; - strftime(buf, 128, "%a, %d %b %Y %T %z", localtime(&global.last_reset_time)); - fprintf(f, "last reset time was %s\n", buf); - } - - fprintf(f, "\n"); - fprintf(f, "name alloc %9u free %9u extant %9u\n", global.notify_state.stat_name_alloc , global.notify_state.stat_name_free, global.notify_state.stat_name_alloc - global.notify_state.stat_name_free); - fprintf(f, "subscription alloc %9u free %9u extant %9u\n", global.notify_state.stat_client_alloc , global.notify_state.stat_client_free, global.notify_state.stat_client_alloc - global.notify_state.stat_client_free); - fprintf(f, "portproc alloc %9u free %9u extant %9u\n", global.notify_state.stat_portproc_alloc , global.notify_state.stat_portproc_free, global.notify_state.stat_portproc_alloc - global.notify_state.stat_portproc_free); - fprintf(f, "\n"); - - fprintf(f, "port count %u\n", global.notify_state.port_table.count); - fprintf(f, "proc count %u\n", global.notify_state.proc_table.count); - fprintf(f, "\n"); - - fprintf(f, "--- NAME TABLE ---\n"); - - _nc_table_foreach(&global.notify_state.name_table, ^bool(void *_n) { - name_info_t *n = _n; - fprint_name_info(f, n->name, n, &max_pid); - fprintf(f, "\n"); - return true; - }); - - fprintf(f, "--- NAME COUNT %u ---\n", global.notify_state.name_table.count); - fprintf(f, "\n"); - - fprintf(f, "--- SUBSCRIPTION TABLE ---\n"); - - _nc_table_foreach_64(&global.notify_state.client_table, ^bool (void *_c) { - client_t *c = _c; - fprintf(f, "%d\n", c->cid.pid); - return true; - }); - - fprintf(f, "--- SUBSCRIPTION COUNT %u ---\n", global.notify_state.client_table.count); - fprintf(f, "\n"); - - fprintf(f, "--- CONTROLLED NAME ---\n"); - for (i = 0; i < global.notify_state.controlled_name_count; i++) - { - fprintf(f, "%s %u %u %03x\n", global.notify_state.controlled_name[i]->name, global.notify_state.controlled_name[i]->uid, global.notify_state.controlled_name[i]->gid, global.notify_state.controlled_name[i]->access); - } - fprintf(f, "--- CONTROLLED NAME COUNT %u ---\n", global.notify_state.controlled_name_count); - fprintf(f, "\n"); - - fprintf(f, "--- PUBLIC SERVICE ---\n"); - - _nc_table_foreach(&global.notify_state.name_table, ^bool(void *_n) { - name_info_t *n = _n; - svc_info_t *info; - path_node_t *node; - timer_t *timer; - - if (n->private == NULL) return true; - - info = (svc_info_t *)n->private; - - if (info->type == 0) - { - fprintf(f, "Null service: %s\n", n->name); - } - if (info->type == SERVICE_TYPE_PATH_PUBLIC) - { - node = (path_node_t *)info->private; - fprintf(f, "Path Service: %s <- %s\n", n->name, node->path); - } - else if (info->type == SERVICE_TYPE_TIMER_PUBLIC) - { - timer = (timer_t *)info->private; - switch (timer->type) - { - case TIME_EVENT_ONESHOT: - { - fprintf(f, "Time Service: %s <- Oneshot %llu\n", n->name, timer->start); - break; - } - case TIME_EVENT_CLOCK: - { - fprintf(f, "Time Service: %s <- Clock start %lld freq %u end %lld\n", n->name, timer->start, timer->freq, timer->end); - break; - } - case TIME_EVENT_CAL: - { - fprintf(f, "Time Service: %s <- Calendar start %lld freq %u end %lld day %d\n", n->name, timer->start, timer->freq, timer->end, timer->day); - break; - } - } - } - else - { - fprintf(f, "Unknown service: %s (%u)\n", n->name, info->type); - } - return true; - }); - - fprintf(f, "--- PUBLIC SERVICE COUNT %u ---\n", global.notify_state.name_table.count); - fprintf(f, "\n"); - - fprintf(f, "--- PRIVATE SERVICE ---\n"); - - _nc_table_foreach_64(&global.notify_state.client_table, ^bool (void *_c) { - client_t *c = _c; - name_info_t *n; - svc_info_t *info; - path_node_t *node; - timer_t *timer; - - if (c->service_index == 0) return true; - - info = (svc_info_t *)service_info_get(c->service_index); - n = c->name_info; - - if (info->type == 0) - { - fprintf(f, "PID %u Null service: %s\n", c->cid.pid, n->name); - } - if (info->type == SERVICE_TYPE_PATH_PRIVATE) - { - node = (path_node_t *)info->private; - fprintf(f, "PID %u Path Service: %s <- %s\n", c->cid.pid, n->name, node->path); - } - else if (info->type == SERVICE_TYPE_TIMER_PRIVATE) - { - timer = (timer_t *)info->private; - switch (timer->type) - { - case TIME_EVENT_ONESHOT: - { - fprintf(f, "PID %u Time Service: %s <- Oneshot %"PRId64"\n", c->cid.pid, n->name, timer->start); - break; - } - case TIME_EVENT_CLOCK: - { - fprintf(f, "PID %u Time Service: %s <- Clock start %"PRId64" freq %"PRIu32" end %"PRId64"\n", c->cid.pid, n->name, timer->start, timer->freq, timer->end); - break; - } - case TIME_EVENT_CAL: - { - fprintf(f, "PID %u Time Service: %s <- Calendar start %"PRId64" freq %"PRIu32" end %"PRId64" day %"PRId32"\n", c->cid.pid, n->name, timer->start, timer->freq, timer->end, timer->day); - break; - } - } - } - return true; - }); - - fprintf(f, "--- PRIVATE SERVICE COUNT %u ---\n", global.notify_state.client_table.count); - fprintf(f, "\n"); - - fprintf(f, "--- PROCESSES ---\n"); - for (pid = 0; pid <= max_pid; pid++) - { - int mem_count, plain_count, file_count, port_count, sig_count; - proc_data_t *pdata; - client_t *c; - - pdata = _nc_table_find_n(&global.notify_state.proc_table, pid); - if (pdata == NULL) continue; - - mem_count = 0; - plain_count = 0; - file_count = 0; - port_count = 0; - sig_count = 0; - - LIST_FOREACH(c, &pdata->clients, client_pid_entry) { - switch(c->state_and_type & NOTIFY_TYPE_MASK) { - case NOTIFY_TYPE_NONE: - break; - - case NOTIFY_TYPE_PLAIN: - plain_count++; - break; - - case NOTIFY_TYPE_MEMORY: - mem_count++; - break; - - case NOTIFY_TYPE_PORT: - port_count++; - break; - - case NOTIFY_TYPE_FILE: - file_count++; - break; - - case NOTIFY_TYPE_SIGNAL: - sig_count++; - break; - - default: - break; - } - } - - fprintf(f, "pid: %u ", pid); - - fprintf(f, "memory %u plain %u port %u file %u signal %u\n", - mem_count, plain_count, port_count, file_count, sig_count); - LIST_FOREACH(c, &pdata->clients, client_pid_entry) { - fprintf(f, " %s: %s\n", notify_type_name(c->state_and_type & NOTIFY_TYPE_MASK), c->name_info->name); - } - - fprintf(f, "\n"); - } - fprintf(f, "\n"); -} - -void -dump_status(uint32_t level, int fd) -{ - FILE *f; - - if(fd < 0) - { - if (status_file == NULL) - { - asprintf(&status_file, "/var/run/notifyd_%u.status", getpid()); - if (status_file == NULL) return; - } - - unlink(status_file); - f = fopen(status_file, "w"); - } - else - { - f = fdopen(fd, "w"); - } - - if (f == NULL) return; - - if (level == STATUS_REQUEST_SHORT) fprint_quick_status(f); - else if (level == STATUS_REQUEST_LONG) fprint_status(f); - - fclose(f); -} - -static void -dump_status_handler(void *level) -{ - dump_status((uint32_t)level, -1); -} - - -void -log_message(int priority, const char *str, ...) -{ - time_t t; - char now[32]; - va_list ap; - FILE *lfp; - - if (priority > global.log_cutoff) return; - if (global.log_path == NULL) return; - - lfp = fopen(global.log_path, "a"); - if (lfp == NULL) return; - - va_start(ap, str); - - t = time(NULL); - memset(now, 0, 32); - strftime(now, 32, "%b %e %T", localtime(&t)); - - fprintf(lfp, "%s: ", now); - vfprintf(lfp, str, ap); - fflush(lfp); - - va_end(ap); - fclose(lfp); -} - -bool -has_entitlement(audit_token_t audit, const char *entitlement) -{ - xpc_object_t edata; - bool result = false; - - pid_t pid = audit_token_to_pid(audit); - - log_message(ASL_LEVEL_NOTICE, "-> has_root_entitlement (PID %d)\n", pid); - - edata = xpc_copy_entitlement_for_token(entitlement, &audit); - - if(edata != NULL){ - result = xpc_bool_get_value(edata); - xpc_release(edata); - } - - log_message(ASL_LEVEL_NOTICE, "<- has_root_entitlement (PID %d) = %s\n", pid, result ? "OK" : "FAIL"); - return result; -} - -inline bool -has_root_entitlement(audit_token_t audit) -{ - return has_entitlement(audit, ROOT_ENTITLEMENT_KEY); -} - -uint32_t -daemon_post(const char *name, uint32_t u, uint32_t g) -{ - name_info_t *n; - uint32_t status; - - if (name == NULL) return NOTIFY_STATUS_NULL_INPUT; - - n = _nc_table_find(&global.notify_state.name_table, name); - if (n == NULL) return NOTIFY_STATUS_OK; - - if (n->slot != (uint32_t)-1) global.shared_memory_base[n->slot]++; - - status = _notify_lib_post(&global.notify_state, name, u, g); - return status; -} - -uint32_t -daemon_post_nid(uint64_t nid, uint32_t u, uint32_t g) -{ - name_info_t *n; - uint32_t status; - - n = _nc_table_find_64(&global.notify_state.name_id_table, nid); - if (n == NULL) return NOTIFY_STATUS_OK; - - if (n->slot != (uint32_t)-1) global.shared_memory_base[n->slot]++; - - status = _notify_lib_post_nid(&global.notify_state, nid, u, g); - return status; -} - -void -daemon_post_client(uint64_t cid) -{ - client_t *c; - - c = _nc_table_find_64(&global.notify_state.client_table, cid); - if (c == NULL) return; - - if ((c->state_and_type & NOTIFY_TYPE_MEMORY) && (c->name_info != NULL) && (c->name_info->slot != (uint32_t)-1)) - { - global.shared_memory_base[c->name_info->slot]++; - } - - _notify_lib_post_client(&global.notify_state, c); -} - -void -daemon_set_state(const char *name, uint64_t val) -{ - name_info_t *n; - - if (name == NULL) return; - - n = _nc_table_find(&global.notify_state.name_table, name); - if (n == NULL) return; - - n->state = val; -} - -static void -init_launch_config(const char *name) -{ - kern_return_t kr; - - kr = bootstrap_check_in(bootstrap_port, name, &global.server_port); - - if(kr != KERN_SUCCESS) - { - { - fprintf(stderr, "%d bootstrap_check_in failed (%d)\n", getpid(), kr); - exit(1); - } - } - - /* - * Notifyd uses its port for communication, system wide. - * Up our queue length as most of our traffic is made of simpleroutines - */ - struct mach_port_limits limits = { - .mpl_qlimit = 32, - }; - - mach_port_set_attributes(mach_task_self(), global.server_port, - MACH_PORT_LIMITS_INFO, (mach_port_info_t)&limits, sizeof(limits)); -} - -static void -string_list_free(char **l) -{ - int i; - - if (l == NULL) return; - for (i = 0; l[i] != NULL; i++) - { - if (l[i] != NULL) free(l[i]); - l[i] = NULL; - } - free(l); -} - -static char ** -string_insert(char *s, char **l, unsigned int x) -{ - int i, len; - - if (s == NULL) return l; - if (l == NULL) - { - l = (char **)malloc(2 * sizeof(char *)); - l[0] = strdup(s); - l[1] = NULL; - return l; - } - - for (i = 0; l[i] != NULL; i++); - len = i + 1; /* count the NULL on the end of the list too! */ - - l = (char **)realloc(l, (len + 1) * sizeof(char *)); - - if ((x >= (len - 1)) || (x == IndexNull)) - { - l[len - 1] = strdup(s); - l[len] = NULL; - return l; - } - - for (i = len; i > x; i--) l[i] = l[i - 1]; - l[x] = strdup(s); - return l; -} - -static char ** -string_append(char *s, char **l) -{ - return string_insert(s, l, IndexNull); -} - -static unsigned int -string_list_length(char **l) -{ - int i; - - if (l == NULL) return 0; - for (i = 0; l[i] != NULL; i++); - return i; -} - -static unsigned int -string_index(char c, char *s) -{ - int i; - char *p; - - if (s == NULL) return IndexNull; - - for (i = 0, p = s; p[0] != '\0'; p++, i++) - { - if (p[0] == c) return i; - } - - return IndexNull; -} - -static char ** -explode(char *s, char *delim) -{ - char **l = NULL; - char *p, *t; - int i, n; - - if (s == NULL) return NULL; - - p = s; - while (p[0] != '\0') - { - for (i = 0; ((p[i] != '\0') && (string_index(p[i], delim) == IndexNull)); i++); - n = i; - t = malloc(n + 1); - for (i = 0; i < n; i++) t[i] = p[i]; - t[n] = '\0'; - l = string_append(t, l); - free(t); - t = NULL; - if (p[i] == '\0') return l; - if (p[i + 1] == '\0') l = string_append("", l); - p = p + i + 1; - } - return l; -} - -static uint32_t -atoaccess(char *s) -{ - uint32_t a; - - if (s == NULL) return 0; - if (strlen(s) != 6) return 0; - - a = 0; - if (s[0] == 'r') a |= (NOTIFY_ACCESS_READ << NOTIFY_ACCESS_USER_SHIFT); - if (s[1] == 'w') a |= (NOTIFY_ACCESS_WRITE << NOTIFY_ACCESS_USER_SHIFT); - - if (s[2] == 'r') a |= (NOTIFY_ACCESS_READ << NOTIFY_ACCESS_GROUP_SHIFT); - if (s[3] == 'w') a |= (NOTIFY_ACCESS_WRITE << NOTIFY_ACCESS_GROUP_SHIFT); - - if (s[4] == 'r') a |= (NOTIFY_ACCESS_READ << NOTIFY_ACCESS_OTHER_SHIFT); - if (s[5] == 'w') a |= (NOTIFY_ACCESS_WRITE << NOTIFY_ACCESS_OTHER_SHIFT); - - return a; -} - -static void -init_config(void) -{ - FILE *f; - struct stat sb; - char line[1024]; - char **args; - uint32_t argslen; - uint32_t uid, gid, access; - uint64_t nid, val64; - - /* - * Set IPC Version Number & PID - */ - val64 = getpid(); - val64 <<= 32; - val64 |= NOTIFY_IPC_VERSION; - - _notify_lib_register_plain(&global.notify_state, NOTIFY_IPC_VERSION_NAME, -1, notifyd_token++, -1, 0, 0, &nid); - _notify_lib_set_state(&global.notify_state, nid, val64, 0, 0); - - /* Check config file */ - if (stat(CONFIG_FILE_PATH, &sb) != 0) return; - - if (sb.st_uid != 0) - { - log_message(ASL_LEVEL_ERR, "config file %s not owned by root: ignored\n", CONFIG_FILE_PATH); - return; - } - - if (sb.st_mode & 02) - { - log_message(ASL_LEVEL_ERR, "config file %s is world-writable: ignored\n", CONFIG_FILE_PATH); - return; - } - - /* Read config file */ - f = fopen(CONFIG_FILE_PATH, "r"); - if (f == NULL) return; - - forever - { - if (fgets(line, 1024, f) == NULL) break; - if (line[0] == '\0') continue; - if (line[0] == '#') continue; - - line[strlen(line) - 1] = '\0'; - args = explode(line, "\t "); - argslen = string_list_length(args); - if (argslen == 0) continue; - - if (!strcasecmp(args[0], "monitor")) { - if (argslen < 3) - { - string_list_free(args); - continue; - } - _notify_lib_register_plain(&global.notify_state, args[1], -1, notifyd_token++, -1, 0, 0, &nid); - - dispatch_async(global.workloop, ^{ - service_open_path(args[1], args[2], 0, 0); - string_list_free(args); - }); - } else if (!strcasecmp(args[0], "timer")) { - if (argslen < 3) - { - string_list_free(args); - continue; - } - _notify_lib_register_plain(&global.notify_state, args[1], -1, notifyd_token++, -1, 0, 0, &nid); - - dispatch_async(global.workloop, ^{ - service_open_timer(args[1], args[2]); - string_list_free(args); - }); - } else if (!strcasecmp(args[0], "set")) { - if (argslen == 1 || argslen > 3) - { - string_list_free(args); - continue; - } - - _notify_lib_register_plain(&global.notify_state, args[1], -1, notifyd_token++, -1, 0, 0, &nid); - if (argslen == 3) - { - val64 = atoll(args[2]); - _notify_lib_set_state(&global.notify_state, nid, val64, 0, 0); - } - - string_list_free(args); - } else if (!strcasecmp(args[0], "reserve")) { - if (argslen == 1) - { - string_list_free(args); - continue; - } - - uid = 0; - gid = 0; - access = NOTIFY_ACCESS_DEFAULT; - - if (argslen > 2) uid = atoi(args[2]); - if (argslen > 3) gid = atoi(args[3]); - if (argslen > 4) access = atoaccess(args[4]); - - if ((uid != 0) || (gid != 0)) _notify_lib_set_owner(&global.notify_state, args[1], uid, gid); - if (access != NOTIFY_ACCESS_DEFAULT) _notify_lib_set_access(&global.notify_state, args[1], access); - - string_list_free(args); - } else if (!strcasecmp(args[0], "quit")) { - string_list_free(args); - break; - } - - } - - fclose(f); -} - -static void -notifyd_mach_channel_handler(void *context, dispatch_mach_reason_t reason, - dispatch_mach_msg_t message, mach_error_t error) -{ - static const struct mig_subsystem *subsystems[] = { - (mig_subsystem_t)&_notify_ipc_subsystem, - }; - if (reason == DISPATCH_MACH_MESSAGE_RECEIVED) { - if (!dispatch_mach_mig_demux(context, subsystems, 1, message)) { - mach_msg_destroy(dispatch_mach_msg_get_msg(message, NULL)); - } - } -} - -kern_return_t -do_mach_notify_port_deleted(mach_port_t notify, mach_port_name_t name) -{ - NOTIFY_INTERNAL_CRASH(0, "notifyd never requests port-deleted"); -} - -kern_return_t -do_mach_notify_port_destroyed(mach_port_t notify, mach_port_t rights) -{ - NOTIFY_INTERNAL_CRASH(0, "notifyd never requests port-destroyed"); -} - -kern_return_t -do_mach_notify_no_senders(mach_port_t notify, mach_port_mscount_t mscount) -{ - NOTIFY_INTERNAL_CRASH(0, "notifyd never requests no-senders"); -} - -kern_return_t -do_mach_notify_send_once(mach_port_t notify) -{ - NOTIFY_INTERNAL_CRASH(0, "someone destroyed our send-possible notification"); -} - -static void -mach_notifs_handle(void *context, dispatch_mach_reason_t reason, - dispatch_mach_msg_t msg, mach_error_t error) -{ - static const struct mig_subsystem *const subsystems[] = { - (mig_subsystem_t)&do_notify_subsystem, - }; - - if (reason == DISPATCH_MACH_MESSAGE_RECEIVED) { - if (!dispatch_mach_mig_demux(context, subsystems, 1, msg)) { - mach_msg_destroy(dispatch_mach_msg_get_msg(msg, NULL)); - } - } -} - -static int32_t -open_shared_memory(const char *name) -{ - int32_t shmfd, isnew; - uint32_t size; - - size = global.nslots * sizeof(uint32_t); - - isnew = 1; - shmfd = shm_open(name, O_RDWR, 0644); - if (shmfd != -1) - { - isnew = 0; - } - else - { - shmfd = shm_open(name, O_RDWR | O_CREAT, 0644); - } - - if (shmfd == -1) - { - char error_message[1024]; - snprintf(error_message, sizeof(error_message), "shm_open %s failed: %s\n", name, strerror(errno)); - - CRSetCrashLogMessage(error_message); - log_message(ASL_LEVEL_NOTICE, "%s", error_message); - return -1; - } - - ftruncate(shmfd, size); - global.shared_memory_base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); - close(shmfd); - - if (isnew == 0) - { - global.last_shm_base = malloc(size); - if (global.last_shm_base != NULL) memcpy(global.last_shm_base, global.shared_memory_base, size); - } - - memset(global.shared_memory_base, 0, size); - global.shared_memory_refcount = (uint32_t *)malloc(size); - if (global.shared_memory_refcount == NULL) return -1; - - memset(global.shared_memory_refcount, 0, size); - - /* slot 0 is notifyd's pid */ - global.shared_memory_base[0] = getpid(); - global.shared_memory_refcount[0] = 1; - global.slot_id = 0; - - return 0; -} - -int -main(int argc, const char *argv[]) -{ - const char *service_name; - const char *shm_name; - uint32_t i, status; - struct rlimit rlim; - kern_return_t kr; - -#if TARGET_OS_SIMULATOR - asprintf(&_config_file_path, "%s/private/etc/notify.conf", getenv("SIMULATOR_ROOT")); - asprintf(&_debug_log_path, "%s/var/log/notifyd.log", getenv("SIMULATOR_LOG_ROOT")); -#endif - - service_name = NOTIFY_SERVICE_NAME; - shm_name = SHM_ID; - - notify_set_options(NOTIFY_OPT_DISABLE); - - /* remove limit of number of file descriptors */ - rlim.rlim_max = RLIM_INFINITY; - rlim.rlim_cur = MIN(OPEN_MAX, rlim.rlim_max); - setrlimit(RLIMIT_NOFILE, &rlim); - - signal(SIGPIPE, SIG_IGN); - signal(SIGHUP, SIG_IGN); - signal(SIGUSR1, SIG_IGN); - signal(SIGUSR2, SIG_IGN); - signal(SIGWINCH, SIG_IGN); - - memset(&call_statistics, 0, sizeof(struct call_statistics_s)); - - global.nslots = getpagesize() / sizeof(uint32_t); - _notify_lib_notify_state_init(&global.notify_state, NOTIFY_STATE_ENABLE_RESEND); - - global.log_cutoff = ASL_LEVEL_ERR; - global.log_path = strdup(DEBUG_LOG_PATH); - global.slot_id = (uint32_t)-1; - - for (i = 1; i < argc; i++) - { - if (!strcmp(argv[i], "-d")) - { - global.log_cutoff = ASL_LEVEL_DEBUG; - } - else if (!strcmp(argv[i], "-log_cutoff")) - { - global.log_cutoff = atoi(argv[++i]); - } - else if (!strcmp(argv[i], "-log_file")) - { - free(global.log_path); - global.log_path = strdup(argv[++i]); - } - else if (!strcmp(argv[i], "-service")) - { - service_name = argv[++i]; - } - else if (!strcmp(argv[i], "-shm")) - { - shm_name = argv[++i]; - } - else if (!strcmp(argv[i], "-shm_pages")) - { - global.nslots = atoi(argv[++i]) * (getpagesize() / sizeof(uint32_t)); - } - } - - global.log_default = global.log_cutoff; - - log_message(ASL_LEVEL_DEBUG, "--------------------\nnotifyd start PID %u\n", getpid()); - - init_launch_config(service_name); - - if (global.nslots > 0) - { - status = open_shared_memory(shm_name); - assert(status == 0); - } - - global.workloop = dispatch_workloop_create_inactive("com.apple.notifyd.main"); - dispatch_set_qos_class_fallback(global.workloop, QOS_CLASS_UTILITY); - dispatch_activate(global.workloop); - - /* init from config file before starting the listener */ - init_config(); - - mach_port_options_t opts = { - .flags = MPO_STRICT | MPO_CONTEXT_AS_GUARD, - }; - kr = mach_port_construct(current_task(), &opts, &global, &global.mach_notify_port); - if (kr != KERN_SUCCESS) { - NOTIFY_INTERNAL_CRASH(kr, "Unable to allocate Mach notification port"); - } - global.mach_notifs_channel = dispatch_mach_create_f("com.apple.notifyd.mach-notifs", - global.workloop, NULL, mach_notifs_handle); - dispatch_set_qos_class_fallback(global.mach_notifs_channel, QOS_CLASS_USER_INITIATED); - dispatch_mach_connect(global.mach_notifs_channel, global.mach_notify_port, - MACH_PORT_NULL, NULL); - - global.mach_channel = dispatch_mach_create_f("com.apple.notifyd.channel", - global.workloop, NULL, notifyd_mach_channel_handler); -#if TARGET_OS_SIMULATOR - // simulators don't support MiG QoS propagation yet - dispatch_set_qos_class_fallback(global.mach_channel, QOS_CLASS_USER_INITIATED); -#else - dispatch_set_qos_class_fallback(global.mach_channel, QOS_CLASS_BACKGROUND); -#endif - dispatch_mach_connect(global.mach_channel, global.server_port, MACH_PORT_NULL, NULL); - - /* Set up SIGUSR1 */ - global.sig_usr1_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, - (uintptr_t)SIGUSR1, 0, global.workloop); - assert(global.sig_usr1_src != NULL); - dispatch_set_context(global.sig_usr1_src, (void *)STATUS_REQUEST_SHORT); - dispatch_source_set_event_handler_f(global.sig_usr1_src, dump_status_handler); - dispatch_activate(global.sig_usr1_src); - - /* Set up SIGUSR2 */ - global.sig_usr2_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, - (uintptr_t)SIGUSR2, 0, global.workloop); - assert(global.sig_usr2_src != NULL); - dispatch_set_context(global.sig_usr2_src, (void *)STATUS_REQUEST_LONG); - dispatch_source_set_event_handler_f(global.sig_usr2_src, dump_status_handler); - dispatch_activate(global.sig_usr2_src); - - /* Set up SIGWINCH */ - global.sig_winch_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, - (uintptr_t)SIGWINCH, 0, global.workloop); - assert(global.sig_winch_src != NULL); - dispatch_source_set_event_handler(global.sig_winch_src, ^{ - if (global.log_cutoff == ASL_LEVEL_DEBUG) global.log_cutoff = global.log_default; - else global.log_cutoff = ASL_LEVEL_DEBUG; - }); - dispatch_activate(global.sig_winch_src); - - global.stat_reset_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, global.workloop); - { - dispatch_time_t trigger = dispatch_walltime(NULL, 0); - dispatch_source_set_timer(global.stat_reset_src, trigger, 60 * 60 * NSEC_PER_SEC, 0); - } - dispatch_source_set_event_handler(global.stat_reset_src, ^{ - notify_reset_stats(); - }); - dispatch_activate(global.stat_reset_src); - notify_reset_stats(); - - dispatch_main(); -} diff --git a/src/libnotify/notifyd/notifyd.h b/src/libnotify/notifyd/notifyd.h deleted file mode 100644 index 04385f046..000000000 --- a/src/libnotify/notifyd/notifyd.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2003-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _NOTIFY_DAEMON_H_ -#define _NOTIFY_DAEMON_H_ - -#define DISPATCH_MACH_SPI 1 - -#include -#include -#include -#include -#include - - -#define STATUS_REQUEST_SHORT 0 -#define STATUS_REQUEST_LONG 1 - -#define NOTIFY_STATE_ENTITLEMENT "com.apple.private.libnotify.statecapture" - - -struct global_s -{ - notify_state_t notify_state; - dispatch_mach_t mach_notifs_channel; - mach_port_t mach_notify_port; - mach_port_t server_port; - void **service_info_list; - dispatch_workloop_t workloop; - dispatch_mach_t mach_channel; - dispatch_source_t sig_usr1_src; - dispatch_source_t sig_usr2_src; - dispatch_source_t sig_winch_src; - dispatch_source_t stat_reset_src; - time_t last_reset_time; - uint32_t nslots; - uint32_t slot_id; - uint32_t *shared_memory_base; - uint32_t *shared_memory_refcount; - uint32_t *last_shm_base; - uint32_t log_cutoff; - uint32_t log_default; - uint16_t service_info_count; - char *log_path; -}; - -extern struct global_s global; - -struct call_statistics_s -{ - uint64_t post; - uint64_t post_no_op; - uint64_t post_by_id; - uint64_t post_by_name; - uint64_t post_by_name_and_fetch_id; - uint64_t reg; - uint64_t reg_plain; - uint64_t reg_check; - uint64_t reg_signal; - uint64_t reg_file; - uint64_t reg_port; - uint64_t cancel; - uint64_t suspend; - uint64_t resume; - uint64_t suspend_pid; - uint64_t resume_pid; - uint64_t check; - uint64_t get_state; - uint64_t get_state_by_client; - uint64_t get_state_by_id; - uint64_t get_state_by_client_and_fetch_id; - uint64_t set_state; - uint64_t set_state_by_client; - uint64_t set_state_by_id; - uint64_t set_state_by_client_and_fetch_id; - uint64_t set_owner; - uint64_t set_access; - uint64_t monitor_file; - uint64_t service_timer; - uint64_t service_path; - uint64_t cleanup; - uint64_t regenerate; - uint64_t checkin; -}; - -extern struct call_statistics_s call_statistics; - -extern void log_message(int priority, const char *str, ...) __printflike(2, 3); -extern uint32_t daemon_post(const char *name, uint32_t u, uint32_t g); -extern uint32_t daemon_post_nid(uint64_t nid, uint32_t u, uint32_t g); -extern void daemon_post_client(uint64_t cid); -extern void daemon_set_state(const char *name, uint64_t val); -extern void dump_status(uint32_t level, int fd); -extern bool has_entitlement(audit_token_t audit, const char *entitlement); -extern bool has_root_entitlement(audit_token_t audit); - -dispatch_queue_t get_notifyd_workloop(void); - -#endif /* _NOTIFY_DAEMON_H_ */ diff --git a/src/libnotify/notifyd/pathwatch.c b/src/libnotify/notifyd/pathwatch.c deleted file mode 100644 index e45853dd7..000000000 --- a/src/libnotify/notifyd/pathwatch.c +++ /dev/null @@ -1,947 +0,0 @@ -/* - * Copyright (c) 2009-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * These routines, accessed through path_node_create() and path_node_release(), - * provide an API for monitoring a path in the filesystem. The path may contain - * directories and symbolic links. The path may not even exist! If the path - * does exist, this code will respond to path deletions, component renaming, and - * access control changes that either delete the path or make it inaccessible to a - * target user/group. A notification will be provided if the path comes back into - * existance or again becomes accessible. - * - * path_node_create() returns a path_node_t object, which contains a dispatch_source_t. - * This source behaves very much like a DISPATCH_SOURCE_TYPE_VNODE, except that it also - * triggers on the creation of a path. - * - * Internally, the work of monitoring a path is done by a set of helper vnode_t - * objects. A vnode_t contains a dispatch_source_t (of type DISPATCH_SOURCE_TYPE_VNODE) - * for a particular vnode. When a path_node_t is created, it creates (or shares) - * vnode_t objects for each component of the desired path. For example, a path_node_t - * for "/a/b/c" will create (or share, if some other path_node_t has already created) a - * dispatch_source_t for "/", "/a", "/a/b", and "/a/b/c". If any of these sources is - * notified of a change, the vnode_t will trigger an update for all path_node_t - * objects that contain that path component. - * - * When a path_node_t update is triggered by a vnode_t component, the node re-evaluates - * the target path that it is charged with monitoring. If the path exists and the end-point - * vnode changed, then the update operation will trigger its dispatch_source_t to notify the - * end-user of the change. If an intermediate path component is removed, renamed, or becomes - * blocked by an access-control change, then the end-point dispatch_source_t is triggered to - * indicate that the path has been deleted. However, the path_node_t remains active and - * monitors the path components that still exist. Eventually, if the path is recreated or - * if access controls change so that the path becomes visible to the target user, then the - * end-point dispatch_source_t is triggered with a PATH_NODE_CREATE bit set in its data flags. - * - * path_node_releases() releases a path_node_t object and all of the vnode_t objects - * that were monitoring components of its target path. - * - * All of the code in this file is to be run on the workloop in order to maintain internal - * datastructures. This is asserted in every non-static function and thus can be safely - * assumed by all static functions. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pathwatch.h" -#include "notifyd.h" - -#define forever for(;;) -#define streq(A,B) (strcmp(A,B)==0) -#define DISPATCH_VNODE_ALL 0x7f - -#define PATH_STAT_OK 0 -#define PATH_STAT_FAILED 1 -#define PATH_STAT_ACCESS 2 - -#define VPATH_NODE_TYPE_REG 0 -#define VPATH_NODE_TYPE_LINK 1 -#define VPATH_NODE_TYPE_DELETED 2 - -#define DISPATCH_VNODE_UNAVAIL (DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE) - -/* Libinfo global */ -extern uint32_t gL1CacheEnabled; - -/* - * vnode_t represents a vnode. - * - * The dispatch source is of type DISPATCH_SOURCE_TYPE_VNODE for file descriptor fd. - * The handler for the source triggers an update routine for all the path_node_t - * objects in the path_node list. - */ -typedef struct -{ - char *path; - uint32_t type; - int fd; - struct timespec mtime; - struct timespec ctime; - dispatch_source_t src; - uint32_t path_node_count; - path_node_t **path_node; -} vnode_t; - -static struct -{ - dispatch_once_t pathwatch_init; - uint32_t vnode_count; - vnode_t **vnode; - char *tzdir; - size_t tzdir_len; -} _global = {0}; - -/* forward */ -static void _path_node_update(path_node_t *pnode, uint32_t flags, vnode_t *vnode); - -/* - * stat() or lstat() a path as a particular user/group. - */ -static int -_path_stat(const char *path, int link, uid_t uid, gid_t gid) -{ - struct stat sb; - gid_t orig_gidset[NGROUPS_MAX]; - int ngroups, status, stat_status; - struct passwd *p; - uint32_t orig_cache_enabled; - - /* disable L1 cache to avoid notification deadlock */ - orig_cache_enabled = gL1CacheEnabled; - gL1CacheEnabled = 0; - - /* get my group list */ - memset(orig_gidset, 0, sizeof(orig_gidset)); - ngroups = getgroups(NGROUPS_MAX, orig_gidset); - if (ngroups < 0) - { - return PATH_STAT_FAILED; - } - - /* look up user name */ - p = getpwuid(uid); - if (p == NULL) - { - gL1CacheEnabled = orig_cache_enabled; - return PATH_STAT_FAILED; - } - - /* switch to user's grouplist */ - status = initgroups(p->pw_name, gid); - if (status < 0) - { - gL1CacheEnabled = orig_cache_enabled; - return PATH_STAT_FAILED; - } - - /* reset gL1CacheEnabled */ - gL1CacheEnabled = orig_cache_enabled; - - /* set thread credentials */ - pthread_setugid_np(uid, gid); - - /* stat the file */ - stat_status = -1; - if (link != 0) - { - stat_status = lstat(path, &sb); - } - else - { - stat_status = stat(path, &sb); - } - - /* unset thread credentials */ - pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE); - - /* restore original grouplist for UID 0 */ - status = syscall(SYS_initgroups, ngroups, orig_gidset, 0); - if (status < 0) - { - return PATH_STAT_FAILED; - } - - /* return status */ - if (stat_status == 0) - { - return PATH_STAT_OK; - } - - if (errno == EACCES) - { - return PATH_STAT_ACCESS; - } - - return PATH_STAT_FAILED; -} - -/* - * Check access to a path by a particular user/group. - * Sets ftype output parameter if it is non-NULL. - */ -static int -_path_stat_check_access(const char *path, audit_token_t audit, bool client_is_notifyd, uint32_t *ftype) -{ - struct stat sb; - char buf[MAXPATHLEN + 1]; - int status, t; - - if (path == NULL) return PATH_STAT_FAILED; - - if (ftype != NULL) *ftype = PATH_NODE_TYPE_GHOST; - - /* Paths must be absolute */ - if (path[0] != '/') return PATH_STAT_FAILED; - - /* Root dir is readable */ - if (path[1] == '\0') - { - if (ftype != NULL) *ftype = PATH_NODE_TYPE_DIR; - return PATH_STAT_OK; - } - - /* Don't perform stat if sandbox won't allow it. (15907527) */ - if (!client_is_notifyd && (sandbox_check_by_audit_token(audit, "file-read-metadata", SANDBOX_FILTER_PATH | SANDBOX_CHECK_NO_REPORT, path) != 0)) { - return PATH_STAT_ACCESS; - } - - memset(&sb, 0, sizeof(struct stat)); - status = lstat(path, &sb); - - if (status != 0) return PATH_STAT_FAILED; - else if ((sb.st_mode & S_IFMT) == S_IFDIR) t = PATH_NODE_TYPE_DIR; - else if ((sb.st_mode & S_IFMT) == S_IFREG) t = PATH_NODE_TYPE_FILE; - else if ((sb.st_mode & S_IFMT) == S_IFLNK) t = PATH_NODE_TYPE_LINK; - else t = PATH_NODE_TYPE_OTHER; - - if (ftype != NULL) *ftype = t; - - if (t == PATH_NODE_TYPE_OTHER) return PATH_STAT_FAILED; - - /* skip access control check if uid is zero or if the client is notifyd */ - if (client_is_notifyd || audit_token_to_euid(audit) == 0) return 0; - - /* special case: anything in the timezone directory is OK */ - memset(buf, 0, sizeof(buf)); - if (realpath(path, buf) == NULL) return PATH_STAT_FAILED; - if ((_global.tzdir != NULL) && (!strncasecmp(buf, _global.tzdir, _global.tzdir_len))) - { - return PATH_STAT_OK; - } - - /* call _path_stat to check access as the user/group provided */ - if (t == PATH_NODE_TYPE_FILE) - { - status = _path_stat(path, 0, audit_token_to_euid(audit), audit_token_to_egid(audit)); - if ((status == PATH_STAT_ACCESS) && (ftype != NULL)) *ftype = PATH_NODE_TYPE_GHOST; - return status; - } - else if (t == PATH_NODE_TYPE_LINK) - { - status = _path_stat(path, 1, audit_token_to_euid(audit), audit_token_to_egid(audit)); - if ((status == PATH_STAT_ACCESS) && (ftype != NULL)) *ftype = PATH_NODE_TYPE_GHOST; - return status; - } - else if (t == PATH_NODE_TYPE_DIR) - { - snprintf(buf, MAXPATHLEN, "%s/.", path); - status = _path_stat(buf, 0, audit_token_to_euid(audit), audit_token_to_egid(audit)); - if ((status == PATH_STAT_ACCESS) && (ftype != NULL)) *ftype = PATH_NODE_TYPE_GHOST; - return status; - } - - /* we don't ever get here, but... */ - return PATH_STAT_FAILED; -} - -/* - * Uniquely add a pnode to a vnode's list of path nodes. - */ -static void -_vnode_add_pnode(vnode_t *vnode, path_node_t *pnode) -{ - uint32_t i; - - for (i = 0; i < vnode->path_node_count; i++) - { - if (vnode->path_node[i] == pnode) return; - } - - for (i = 0; i < vnode->path_node_count; i++) - { - if (vnode->path_node[i] == NULL) - { - vnode->path_node[i] = pnode; - return; - } - } - - if (vnode->path_node_count == 0) - { - vnode->path_node = (path_node_t **)calloc(1, sizeof(path_node_t *)); - } - else - { - vnode->path_node = (path_node_t **)reallocf(vnode->path_node, (vnode->path_node_count + 1) * sizeof(path_node_t *)); - } - - assert(vnode->path_node != NULL); - - vnode->path_node[vnode->path_node_count++] = pnode; -} - -/* - * Free a vnode_t and cancel/release its dispatch source. - */ -static void -_vnode_free(vnode_t *vnode) -{ - dispatch_source_cancel(vnode->src); - - dispatch_async(get_notifyd_workloop(), ^{ - dispatch_release(vnode->src); - free(vnode->path); - free(vnode->path_node); - free(vnode); - }); -} - -/* - * Handler routine for vnode_t objects. - * Invokes the _path_node_update routine for all of the vnode's pnodes. - */ -static void -_vnode_event(vnode_t *vnode) -{ - uint32_t i, flags; - unsigned long ulf; - struct stat sb; - - if (vnode == NULL) return; - if ((vnode->src != NULL) && (dispatch_source_testcancel(vnode->src))) return; - - ulf = dispatch_source_get_data(vnode->src); - flags = (uint32_t)ulf; - - memset(&sb, 0, sizeof(struct stat)); - if (fstat(vnode->fd, &sb) == 0) - { - if ((vnode->mtime.tv_sec != sb.st_mtimespec.tv_sec) || (vnode->mtime.tv_nsec != sb.st_mtimespec.tv_nsec)) - { - flags |= PATH_NODE_MTIME; - vnode->mtime = sb.st_mtimespec; - } - - if ((vnode->ctime.tv_sec != sb.st_ctimespec.tv_sec) || (vnode->ctime.tv_nsec != sb.st_ctimespec.tv_nsec)) - { - flags |= PATH_NODE_CTIME; - vnode->ctime = sb.st_ctimespec; - } - } - - /* - * Flag deleted sources. - * We can't delete them here, since _path_node_update may need them. - * However, _path_node_update will release them and they will get cleaned - * up in a _vnode_sweep later on. - */ - if (flags & DISPATCH_VNODE_DELETE) vnode->type = VPATH_NODE_TYPE_DELETED; - - for (i = 0; i < vnode->path_node_count; i++) - { - _path_node_update(vnode->path_node[i], flags, vnode); - } -} - -/* - * Creates a vnode_t object. - */ -static vnode_t * -_vnode_create(const char *path, uint32_t type, path_node_t *pnode) -{ - int fd, flags; - uint32_t i; - vnode_t *vnode; - dispatch_source_t src; - struct stat sb; - - if (path == NULL) path = "/"; - if (path[0] == '\0') path = "/"; - - for (i = 0; i < _global.vnode_count; i++) - { - vnode = _global.vnode[i]; - if (vnode == NULL) continue; - - if ((vnode->type == type) && (streq(path, vnode->path))) - { - _vnode_add_pnode(vnode, pnode); - return vnode; - } - } - - vnode = NULL; - - flags = O_EVTONLY; - if (type == VPATH_NODE_TYPE_LINK) flags |= O_SYMLINK; - - fd = open(path, flags, 0); - if (fd < 0) return NULL; - - src = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, (uintptr_t)fd, DISPATCH_VNODE_ALL, get_notifyd_workloop()); - if (src == NULL) - { - close(fd); - return NULL; - } - - vnode = (vnode_t *)calloc(1, sizeof(vnode_t)); - assert(vnode != NULL); - - vnode->type = type; - vnode->path = strdup(path); - assert(vnode->path != NULL); - - vnode->fd = fd; - vnode->src = src; - - memset(&sb, 0, sizeof(struct stat)); - if (fstat(fd, &sb) == 0) - { - vnode->mtime = sb.st_mtimespec; - vnode->ctime = sb.st_ctimespec; - } - - _vnode_add_pnode(vnode, pnode); - - dispatch_source_set_event_handler(src, ^{ _vnode_event(vnode); }); - dispatch_source_set_cancel_handler(src, ^{ close(fd); }); - - if (_global.vnode_count == 0) - { - _global.vnode = (vnode_t **)calloc(1, sizeof(vnode_t *)); - } - else - { - _global.vnode = (vnode_t **)reallocf(_global.vnode, (_global.vnode_count + 1) * sizeof(vnode_t *)); - } - - assert(_global.vnode != NULL); - - _global.vnode[_global.vnode_count++] = vnode; - - dispatch_resume(src); - - return vnode; -} - -static vnode_t * -_vnode_create_real_path(const char *path, uint32_t type, path_node_t *pnode) -{ - char real[MAXPATHLEN + 1]; - - if (path == NULL) return _vnode_create(path, type, pnode); - - if (NULL != realpath(path, real)) return _vnode_create(real, type, pnode); - - return NULL; -} - -/* - * Examines all the vnode_t objects (held in the _global data), - * frees any that have no path nodes. - */ -static void -_vnode_sweep() -{ - uint32_t i, j, new_vnode_count, new_path_node_count; - vnode_t **new_source, *vnode; - path_node_t **new_path_node; - - new_source = NULL; - - for (i = 0; i < _global.vnode_count; i++) - { - vnode = _global.vnode[i]; - if (vnode == NULL) continue; - - new_path_node_count = 0; - new_path_node = NULL; - - for (j = 0; j < vnode->path_node_count; j++) - { - if (vnode->path_node[j] != NULL) new_path_node_count++; - } - - if (new_path_node_count == vnode->path_node_count) - { - /* no change */ - continue; - } - else if (new_path_node_count > 0) - { - new_path_node = (path_node_t **)calloc(new_path_node_count, sizeof(path_node_t *)); - assert(new_path_node != NULL); - - new_path_node_count = 0; - for (j = 0; j < vnode->path_node_count; j++) - { - if (vnode->path_node[j] != NULL) - { - new_path_node[new_path_node_count++] = vnode->path_node[j]; - } - } - } - - free(vnode->path_node); - vnode->path_node = new_path_node; - vnode->path_node_count = new_path_node_count; - } - - new_vnode_count = 0; - for (i = 0; i < _global.vnode_count; i++) - { - vnode = _global.vnode[i]; - if (vnode == NULL) continue; - if (vnode->path_node_count > 0) new_vnode_count++; - } - - if (new_vnode_count == _global.vnode_count) - { - /* no change */ - return; - } - else if (new_vnode_count > 0) - { - new_source = (vnode_t **)calloc(new_vnode_count, sizeof(vnode_t *)); - assert(new_source != NULL); - - new_vnode_count = 0; - for (i = 0; i < _global.vnode_count; i++) - { - vnode = _global.vnode[i]; - if (vnode == NULL) continue; - - if (vnode->path_node_count > 0) - { - new_source[new_vnode_count++] = vnode; - } - else - { - _vnode_free(vnode); - } - } - } - - free(_global.vnode); - _global.vnode = new_source; - _global.vnode_count = new_vnode_count; -} - -/* - * Releases sources that have a particular node on their list. - * This is a deferred release mechanism for vnode_t objects. - * The calling routine must call _vnode_sweep subsequent to - * calling this routine. - * _vnode_sweep will actually free any vnode_t objects - * that have a no path nodes. - */ -static void -_vnode_release_for_node(path_node_t *pnode) -{ - uint32_t i, j; - vnode_t *vnode; - - for (i = 0; i < _global.vnode_count; i++) - { - vnode = _global.vnode[i]; - if (vnode == NULL) continue; - - for (j = 0; j < vnode->path_node_count; j++) - { - if (vnode->path_node[j] == pnode) - { - vnode->path_node[j] = NULL; - break; - } - } - } -} - -/* - * Retain a path_node_t object. - */ -static void -_path_node_retain(path_node_t *pnode) -{ - if (pnode == NULL) return; - pnode->refcount++; -} - -/* - * Free a path_node_t object. - */ -static void -_path_node_free(path_node_t *pnode) -{ - uint32_t i, n; - - if (pnode == NULL) return; - - /* - * Remove this path node from all vnodes. - */ - _vnode_release_for_node(pnode); - _vnode_sweep(); - - free(pnode->path); - - if (pnode->pname != NULL) - { - n = pnode->pname_count; - pnode->pname_count = 0; - - for (i = 0; i < n; i++) - { - free(pnode->pname[i]); - pnode->pname[i] = NULL; - } - - free(pnode->pname); - } - - free(pnode->contextp); - - dispatch_release(pnode->src); - - memset(pnode, 0, sizeof(path_node_t)); - free(pnode); -} - -/* - * Release a path_node_t object. - */ -static void -_path_node_release(path_node_t *pnode) -{ - if (pnode == NULL) return; - - - if (pnode->refcount > 0) pnode->refcount--; - if (pnode->refcount == 0) _path_node_free(pnode); -} - -/* - * Frees a path_node_t object. - */ -void -path_node_close(path_node_t *pnode) -{ - dispatch_assert_queue(get_notifyd_workloop()); - - if (pnode == NULL) return; - - if (pnode->src != NULL) dispatch_source_cancel(pnode->src); - _path_node_release(pnode); -} - -static void -_pathwatch_init() -{ - char buf[MAXPATHLEN]; - - _global.tzdir = NULL; - _global.tzdir_len = 0; - - /* Get the real path to TZDIR */ - if (realpath(TZDIR, buf) != NULL) - { - _global.tzdir_len = strlen(buf); - _global.tzdir = strdup(buf); - if (_global.tzdir == NULL) _global.tzdir_len = 0; - } -} - -/* - * _path_node_init is responsible for allocating a path_node_t structure, - * and for creating the pname array and setting the path component. - * The path is a sanatized version of the caller's path with redundant "/" - * characters stripped out. The pname array contains each "/" separated - * component of the path. - * - * For example, _path_node_init("///foo////bar//baz/") creates: - * pnode->path = "/foo/bar/baz" - * pnode->pname_count = 3 - * pnode->pname[0] = "foo" - * pnode->pname[1] = "bar" - * pnode->pname[2] = "baz" - */ -static path_node_t * -_path_node_init(const char *path) -{ - size_t len; - uint32_t i; - path_node_t *pnode; - const char *start, *end; - char *name; - - if (path == NULL) path = "/"; - if (path[0] != '/') return NULL; - - pnode = (path_node_t *)calloc(1, sizeof(path_node_t)); - assert(pnode != NULL); - - pnode->plen = 1; - start = path; - while (*start == '/') start++; - - forever - { - end = strchr(start, '/'); - if (end == NULL) end = strchr(start, '\0'); - - len = end - start; - if (len == 0) break; - - pnode->plen += (len + 1); - - name = NULL; - if (end == NULL) - { - name = strdup(start); - } - else - { - name = malloc(len + 1); - assert(name != NULL); - strncpy(name, start, len); - name[len] = '\0'; - } - - if (pnode->pname_count == 0) - { - pnode->pname = (char **)calloc(1, sizeof(char *)); - } - else - { - pnode->pname = (char **)reallocf(pnode->pname, (pnode->pname_count + 1) * sizeof(char *)); - } - - assert(pnode->pname != NULL); - pnode->pname[pnode->pname_count] = name; - pnode->pname_count++; - - start = end; - if (start != NULL) - { - /* skip '/' chars */ - while (*start == '/') start++; - } - } - - pnode->path = calloc(1, pnode->plen); - assert(pnode->path != NULL); - /* - * Reconstruct the path here to strip out excess "/" chars. - * This ensures that path comparisons in _path_node_update are correct. - */ - for (i = 0; i < pnode->pname_count; i++) - { - strlcat(pnode->path, "/", pnode->plen); - strlcat(pnode->path, pnode->pname[i], pnode->plen); - } - - return pnode; -} - -static void -_path_node_update(path_node_t *pnode, uint32_t flags, vnode_t *vnode) -{ - char *buf, fixed[MAXPATHLEN + 1]; - uint32_t i, old_type; - int status; - unsigned long data; - struct stat sb; - - if (pnode == NULL) return; - if ((pnode->src != NULL) && (dispatch_source_testcancel(pnode->src))) return; - - old_type = pnode->type; - - status = _path_stat_check_access(pnode->path, pnode->audit, pnode->flags & PATH_NODE_CLIENT_NOTIFYD, &(pnode->type)); - if (status == PATH_STAT_ACCESS) flags |= DISPATCH_VNODE_REVOKE; - - data = 0; - - if (vnode != NULL) - { - /* update status */ - - if (flags & DISPATCH_VNODE_UNAVAIL) - { - pnode->type = PATH_NODE_TYPE_GHOST; - data |= (flags & DISPATCH_VNODE_UNAVAIL); - data |= DISPATCH_VNODE_DELETE; - } - - if ((vnode->path != NULL) && (pnode->path != NULL) && streq(vnode->path, pnode->path)) - { - /* this is the target VNODE - transfer flags to src data */ - data |= flags; - } - - if (old_type == PATH_NODE_TYPE_GHOST) - { - /* transition from ghost to non-ghost */ - if (pnode->type != PATH_NODE_TYPE_GHOST) - { - data |= PATH_NODE_CREATE; - } - else - { - data = 0; - } - } - else if (pnode->type == PATH_NODE_TYPE_GHOST) - { - /* transition from non-ghost to ghost */ - data |= PATH_NODE_DELETE; - } - - data &= (pnode->flags & PATH_NODE_ALL); - if (data != 0) - { - if ((pnode->flags & PATH_SRC_SUSPENDED) == 0) - { - /* suspend pnode->src, and fire it after PNODE_COALESCE_TIME */ - pnode->flags |= PATH_SRC_SUSPENDED; - dispatch_suspend(pnode->src); - - dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, PNODE_COALESCE_TIME); - _path_node_retain(pnode); - - dispatch_after(delay, get_notifyd_workloop(), ^{ - pnode->flags &= ~PATH_SRC_SUSPENDED; - dispatch_resume(pnode->src); - _path_node_release(pnode); - }); - } - - dispatch_source_merge_data(pnode->src, data); - } - } - - buf = NULL; - if (pnode->plen > MAXPATHLEN) buf = fixed; - else buf = malloc(pnode->plen); - assert(buf != NULL); - - /* "autorelease" current sources (_vnode_sweep() will delete those with zero refcount) */ - _vnode_release_for_node(pnode); - - /* create new sources (may re-use existing sources) */ - _vnode_create(NULL, 0, pnode); - - memset(buf, 0, pnode->plen); - for (i = 0; i < pnode->pname_count; i++) - { - assert((strlen(buf) + 1) <= pnode->plen); - strlcat(buf, "/", pnode->plen); - - assert(pnode->pname[i] != NULL); - assert((strlen(buf) + strlen(pnode->pname[i])) <= pnode->plen); - strlcat(buf, pnode->pname[i], pnode->plen); - - memset(&sb, 0, sizeof(struct stat)); - if (lstat(buf, &sb) < 0) - { - /* the path stops existing here */ - break; - } - - if ((sb.st_mode & S_IFMT) == S_IFLNK) - { - /* open the symlink itself */ - _vnode_create(buf, VPATH_NODE_TYPE_LINK, pnode); - - /* open the symlink target */ - _vnode_create_real_path(buf, 0, pnode); - } - else - { - _vnode_create(buf, 0, pnode); - } - } - - /* sweep source list (deletes those with zero refcount) */ - _vnode_sweep(); - - if (buf != fixed) free(buf); -} - -/* - * Creates a dispatch source that activates when a path changes. - * Internally, creates a data structure (path_node_t) that represents the entire path. - * Also creates dispatch sources (vnode_t) for each path component. These vnodes may - * be shared with other path_node_t structures. - */ -path_node_t * -path_node_create(const char *path, audit_token_t audit, bool is_notifyd, uint32_t mask) -{ - path_node_t *pnode; - dispatch_queue_t queue = get_notifyd_workloop(); - - dispatch_assert_queue(queue); - - dispatch_once(&(_global.pathwatch_init), ^{ _pathwatch_init(); }); - - pnode = _path_node_init(path); - if (pnode == NULL) return NULL; - - pnode->refcount = 1; - pnode->audit = audit; - - _path_node_update(pnode, 0, NULL); - - dispatch_retain(queue); - - pnode->src = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_OR, 0, 0, queue); - pnode->flags = mask & PATH_NODE_ALL; - if (is_notifyd) - { - pnode->flags |= PATH_NODE_CLIENT_NOTIFYD; - } - return pnode; -} diff --git a/src/libnotify/notifyd/pathwatch.h b/src/libnotify/notifyd/pathwatch.h deleted file mode 100644 index 637225e85..000000000 --- a/src/libnotify/notifyd/pathwatch.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2009-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _PATHWATCH_H_ -#define _PATHWATCH_H_ - -#include -/* - * types for virtual path nodes (path_node_t) - */ -#define PATH_NODE_TYPE_GHOST 0 -#define PATH_NODE_TYPE_FILE 1 -#define PATH_NODE_TYPE_LINK 2 -#define PATH_NODE_TYPE_DIR 3 -#define PATH_NODE_TYPE_OTHER 4 - - -enum -{ - PATH_NODE_DELETE = 0x0001, /* node or path deleted */ - PATH_NODE_WRITE = 0x0002, /* node written */ - PATH_NODE_EXTEND = 0x0004, /* node extended */ - PATH_NODE_ATTRIB = 0x0008, /* node attributes changed (mtime or ctime) */ - PATH_NODE_LINK = 0x0010, /* node link count changed */ - PATH_NODE_RENAME = 0x0020, /* node renamed, always accompanied by PATH_NODE_DELETE */ - PATH_NODE_REVOKE = 0x0040, /* access revoked, always accompanied by PATH_NODE_DELETE */ - PATH_NODE_CREATE = 0x0080, /* path created or access re-acquired */ - PATH_NODE_MTIME = 0x0100, /* path mtime changed, always accompanied by PATH_NODE_ATTRIB */ - PATH_NODE_CTIME = 0x0200 /* path ctime changed, always accompanied by PATH_NODE_ATTRIB */ -}; - -/* all bits mask */ -#define PATH_NODE_ALL 0x000003ff -/* src is suspended */ -#define PATH_SRC_SUSPENDED 0x10000000 -/* the client is notifyd */ -#define PATH_NODE_CLIENT_NOTIFYD 0x20000000 - -/* Path changes coalesce for 100 milliseconds */ -#define PNODE_COALESCE_TIME 100000000 - -/* - * path_node_t represents a virtual path - */ -typedef struct -{ - char *path; - size_t plen; - audit_token_t audit; - uint32_t pname_count; - char **pname; - uint32_t type; - uint32_t flags; - dispatch_source_t src; - void *contextp; - uint32_t context32; - uint64_t context64; - uint32_t refcount; -} path_node_t; - -path_node_t *path_node_create(const char *path, audit_token_t audit, bool is_notifyd, uint32_t mask); -void path_node_close(path_node_t *pnode); - -#endif /* _PATHWATCH_H_ */ diff --git a/src/libnotify/notifyd/service.c b/src/libnotify/notifyd/service.c deleted file mode 100644 index 2e2b6c0ed..000000000 --- a/src/libnotify/notifyd/service.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Copyright (c) 2003-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include "notify.h" -#include "notifyd.h" -#include "service.h" -#include "pathwatch.h" -#include "timer.h" -#include "notify_internal.h" - -#define NOTIFY_PATH_SERVICE "path:" -#define NOTIFY_PATH_SERVICE_LEN 5 -#define NOTIFY_TIMER_SERVICE "timer:" -#define NOTIFY_TIMER_SERVICE_LEN 6 - -/* Libinfo global */ -extern uint32_t gL1CacheEnabled; - -static uint32_t -service_type(const char *name) -{ - uint32_t len; - - len = SERVICE_PREFIX_LEN; - if (strncmp(name, SERVICE_PREFIX, len)) return SERVICE_TYPE_NONE; - else if (!strncmp(name + len, NOTIFY_PATH_SERVICE, NOTIFY_PATH_SERVICE_LEN)) return SERVICE_TYPE_PATH_PRIVATE; - else if (!strncmp(name + len, NOTIFY_TIMER_SERVICE, NOTIFY_TIMER_SERVICE_LEN)) return SERVICE_TYPE_TIMER_PRIVATE; - - return SERVICE_TYPE_NONE; -} - -/* - * Request notifications for changes on a filesystem path. - * This creates a new pathwatch node and sets it to post notifications for - * the specified name. - * - * If the notify name already has a pathwatch node for this path, this routine - * does nothing and allows the client to piggypack on the existing path watcher. - * - * Note that this routine is only called for path monitoring as directed by - * a "monitor" command in /etc/notify.conf, so only an admin can set up a path - * that gets public notifications. A client being serviced by the server-side - * routines in notify_proc.c will only be able to register for a private - * (per-client) notification for a path. This prevents a client from - * piggybacking on another client's notifications, and thus prevents the client - * from getting notifications for a path to which they don't have access. - */ -int -service_open_path(const char *name, const char *path, uid_t uid, gid_t gid) -{ - name_info_t *n; - svc_info_t *info; - path_node_t *node; - - call_statistics.service_path++; - - if (path == NULL) return NOTIFY_STATUS_INVALID_REQUEST; - - n = _nc_table_find(&global.notify_state.name_table, name); - if (n == NULL) return NOTIFY_STATUS_INVALID_NAME; - - if (n->private != NULL) - { - /* a notify key may only have one service associated with it */ - info = (svc_info_t *)n->private; - if (info->type != SERVICE_TYPE_PATH_PUBLIC) return NOTIFY_STATUS_INVALID_REQUEST; - - /* the client must be asking for the same path that is being monitored */ - node = (path_node_t *)info->private; - if (strcmp(path, node->path)) return NOTIFY_STATUS_INVALID_REQUEST; - - /* the name is already getting notifications for this path */ - return NOTIFY_STATUS_OK; - } - - { - audit_token_t audit; - memset(&audit, 0, sizeof(audit_token_t)); - node = path_node_create(path, audit, true, PATH_NODE_ALL); - } - - if (node == NULL) return NOTIFY_STATUS_PATH_NODE_CREATE_FAILED; - - node->contextp = strdup(name); - - info = (svc_info_t *)calloc(1, sizeof(svc_info_t)); - assert(info != NULL); - - info->type = SERVICE_TYPE_PATH_PUBLIC; - info->private = node; - n->private = info; - - dispatch_source_set_event_handler(node->src, ^{ - daemon_post((const char *)node->contextp, uid, gid); - }); - - dispatch_activate(node->src); - - return NOTIFY_STATUS_OK; -} - -static uint16_t service_info_add(void *info) -{ - assert(global.service_info_count != UINT16_MAX); - - for(int i = 0; i < global.service_info_count; i++) - { - if(global.service_info_list[i] == NULL){ - global.service_info_list[i] = info; - return i + 1; - } - } - - if(global.service_info_count == 0){ - global.service_info_count = 1; - global.service_info_list = malloc(sizeof(void *)); - } else { - global.service_info_count++; - global.service_info_list = realloc(global.service_info_list, global.service_info_count * sizeof(void *)); - } - - global.service_info_list[global.service_info_count - 1] = info; - - return global.service_info_count; -} - -void *service_info_get(uint16_t index) -{ - if(index == 0) - { - return NULL; - } - - return global.service_info_list[index - 1]; -} - - -static void *service_info_remove(uint16_t index) -{ - if(index == 0) - { - return NULL; - } - - void *ret = global.service_info_list[index - 1]; - - global.service_info_list[index - 1] = NULL; - - return ret; - -} - - -/* - * The private (per-client) path watch service. - * Must be callled on global.workloop if it is initialized - */ -int -service_open_path_private(const char *name, client_t *c, const char *path, audit_token_t audit, uint32_t flags) -{ - name_info_t *n; - svc_info_t *info; - path_node_t *node; - - call_statistics.service_path++; - - if (path == NULL) return NOTIFY_STATUS_INVALID_REQUEST; - - n = _nc_table_find(&global.notify_state.name_table, name); - if (n == NULL) return NOTIFY_STATUS_INVALID_NAME; - if (c == NULL) return NOTIFY_STATUS_NULL_INPUT; - - if (c->service_index != 0) - { - /* a client may only have one service */ - info = (svc_info_t *)service_info_get(c->service_index); - if (info->type != SERVICE_TYPE_PATH_PRIVATE) return NOTIFY_STATUS_INVALID_REQUEST; - - /* the client must be asking for the same path that is being monitored */ - node = (path_node_t *)info->private; - if (strcmp(path, node->path)) return NOTIFY_STATUS_INVALID_REQUEST; - - /* the client is already getting notifications for this path */ - return NOTIFY_STATUS_OK; - } - - if (flags == 0) flags = PATH_NODE_ALL; - - node = path_node_create(path, audit, false, flags); - if (node == NULL) return NOTIFY_STATUS_PATH_NODE_CREATE_FAILED; - - node->context64 = c->cid.hash_key; - - info = (svc_info_t *)calloc(1, sizeof(svc_info_t)); - assert(info != NULL); - - info->type = SERVICE_TYPE_PATH_PRIVATE; - info->private = node; - c->service_index = service_info_add(info); - - dispatch_source_set_event_handler(node->src, ^{ - daemon_post_client(node->context64); - }); - - dispatch_activate(node->src); - - return NOTIFY_STATUS_OK; -} - -/* format: [+]nnnn[s|m|h|d] */ -static int -parse_single_arg(const char *arg, int relative_ok, time_t *t) -{ - const char *p, *q; - time_t now, val; - - if (arg == NULL) return -1; - p = arg; - - now = 0; - - if ((relative_ok != 0) && ((*p == '+') || (*p == '-'))) - { - p++; - now = time(NULL); - } - - if ((*p < '0') || (*p > '9')) return -1; - - q = strchr(p, '.'); - if (q != NULL) q--; - else q = arg + strlen(arg) - 1; - -#ifdef __LP64__ - val = (time_t)atoll(p); -#else - val = (time_t)atoi(p); -#endif - - if ((*q >= '0') && (*q <= '9')) - {} - else if (*q == 's') - {} - else if (*q == 'm') - { - val *= 60; - } - else if (*q == 'h') - { - val *= 3600; - } - else if (*q == 'd') - { - val *= 86400; - } - else - { - return -1; - } - - if (*arg == '-') *t = now - val; - else *t = now + val; - - return 0; -} - -static uint32_t -parse_timer_args(const char *args, time_t *s, time_t *f, time_t *e, int32_t *d) -{ - char *p; - uint32_t t; - - if (args == NULL) return TIME_EVENT_NONE; - - /* first arg is start time */ - if (parse_single_arg(args, 1, s) != 0) return TIME_EVENT_NONE; - t = TIME_EVENT_ONESHOT; - - p = strchr(args, '.'); - if (p != NULL) - { - /* second arg is frequency */ - p++; - if (parse_single_arg(p, 0, f) != 0) return TIME_EVENT_NONE; - t = TIME_EVENT_CLOCK; - - p = strchr(p, '.'); - if (p != NULL) - { - /* third arg is end time */ - p++; - if (parse_single_arg(args, 1, e) != 0) return TIME_EVENT_NONE; - - p = strchr(p, '.'); - if (p != NULL) - { - /* fourth arg is day number */ - p++; - *d = atoi(p); - t = TIME_EVENT_CAL; - } - } - } - - if (f == 0) t = TIME_EVENT_ONESHOT; - - return t; -} - -int -service_open_timer(const char *name, const char *args) -{ - uint32_t t; - time_t s, f, e; - int32_t d; - name_info_t *n; - svc_info_t *info; - timer_t *timer; - - call_statistics.service_timer++; - - n = _nc_table_find(&global.notify_state.name_table, name); - if (n == NULL) return NOTIFY_STATUS_INVALID_NAME; - - s = f = e = 0; - d = 0; - - t = parse_timer_args(args, &s, &f, &e, &d); - if (t == TIME_EVENT_NONE) return NOTIFY_STATUS_INVALID_REQUEST; - - if (n->private != NULL) - { - /* a notify key may only have one service associated with it */ - info = (svc_info_t *)n->private; - if (info->type != SERVICE_TYPE_TIMER_PUBLIC) return NOTIFY_STATUS_INVALID_REQUEST; - - /* the client must be asking for the same timer that is active */ - timer = (timer_t *)info->private; - if ((timer->type != t) || (timer->start != s) || (timer->freq != f) || (timer->end != e) || (timer->day != d)) return NOTIFY_STATUS_INVALID_REQUEST; - - /* the name is already getting notifications for this timer */ - return NOTIFY_STATUS_OK; - } - - switch (t) - { - case TIME_EVENT_ONESHOT: - { - timer = timer_oneshot(s, global.workloop); - break; - } - case TIME_EVENT_CLOCK: - { - timer = timer_clock(s, f, e, global.workloop); - break; - } - case TIME_EVENT_CAL: - { - timer = timer_calendar(s, f, e, d, global.workloop); - break; - } - default: - { - return NOTIFY_STATUS_INVALID_TIME_EVENT; - } - } - - if (timer == NULL) return NOTIFY_STATUS_TIMER_FAILED; - timer->contextp = strdup(name); - - info = (svc_info_t *)calloc(1, sizeof(svc_info_t)); - assert(info != NULL); - - info->type = SERVICE_TYPE_TIMER_PUBLIC; - info->private = timer; - n->private = info; - - dispatch_source_set_event_handler(timer->src, ^{ - daemon_post((const char *)timer->contextp, 0, 0); - }); - - dispatch_activate(timer->src); - - return NOTIFY_STATUS_OK; -} - -int -service_open_timer_private(const char *name, client_t *c, const char *args) -{ - uint32_t t; - time_t s, f, e; - int32_t d; - name_info_t *n; - svc_info_t *info; - timer_t *timer; - - call_statistics.service_timer++; - - n = _nc_table_find(&global.notify_state.name_table, name); - if (n == NULL) return NOTIFY_STATUS_INVALID_NAME; - if (c == NULL) return NOTIFY_STATUS_NULL_INPUT; - - s = f = e = 0; - d = 0; - - t = parse_timer_args(args, &s, &f, &e, &d); - if (t == TIME_EVENT_NONE) return NOTIFY_STATUS_INVALID_REQUEST; - - if (c->service_index != 0) - { - /* a client may only have one service */ - info = (svc_info_t *)service_info_get(c->service_index); - if (info->type != SERVICE_TYPE_TIMER_PRIVATE) return NOTIFY_STATUS_INVALID_REQUEST; - - /* the client must be asking for the same timer that is active */ - timer = (timer_t *)info->private; - if ((timer->type != t) || (timer->start != s) || (timer->freq != f) || (timer->end != e) || (timer->day != d)) return NOTIFY_STATUS_INVALID_REQUEST; - - /* the client is already getting notifications for this timer */ - return NOTIFY_STATUS_OK; - } - - switch (t) - { - case TIME_EVENT_ONESHOT: - { - timer = timer_oneshot(s, global.workloop); - break; - } - case TIME_EVENT_CLOCK: - { - timer = timer_clock(s, f, e, global.workloop); - break; - } - case TIME_EVENT_CAL: - { - timer = timer_calendar(s, f, e, d, global.workloop); - break; - } - default: - { - return NOTIFY_STATUS_INVALID_TIME_EVENT; - } - } - - if (timer == NULL) return NOTIFY_STATUS_TIMER_FAILED; - timer->context64 = c->cid.hash_key; - - info = (svc_info_t *)calloc(1, sizeof(svc_info_t)); - assert(info != NULL); - - info->type = SERVICE_TYPE_TIMER_PRIVATE; - info->private = timer; - c->service_index = service_info_add(info); - - dispatch_source_set_event_handler(timer->src, ^{ - daemon_post_client(timer->context64); - }); - - dispatch_activate(timer->src); - - return NOTIFY_STATUS_OK; -} - -/* called from server-side routines in notify_proc - services are private to the client */ -int -service_open(const char *name, client_t *client, audit_token_t audit) -{ - uint32_t t, flags; - char *p, *q; - - t = service_type(name); - - switch (t) - { - case SERVICE_TYPE_NONE: - { - return NOTIFY_STATUS_OK; - } - case SERVICE_TYPE_PATH_PRIVATE: - { - p = strchr(name, ':'); - if (p != NULL) p++; - - flags = 0; - - q = strchr(p, ':'); - if (q != NULL) - { - flags = (uint32_t)strtol(p, NULL, 0); - p = q + 1; - } - - return service_open_path_private(name, client, p, audit, flags); - } - case SERVICE_TYPE_TIMER_PRIVATE: - { - p = strchr(name, ':'); - if (p != NULL) p++; - return service_open_timer_private(name, client, p); - } - default: - { - return NOTIFY_STATUS_INVALID_REQUEST; - } - } - - return NOTIFY_STATUS_INVALID_REQUEST; -} - -void -service_close(uint16_t service_index) -{ - if (service_index == 0) return; - - svc_info_t *info = service_info_remove(service_index); - - switch (info->type) - { - case SERVICE_TYPE_PATH_PUBLIC: - case SERVICE_TYPE_PATH_PRIVATE: - { - path_node_close((path_node_t *)info->private); - break; - } - case SERVICE_TYPE_TIMER_PUBLIC: - case SERVICE_TYPE_TIMER_PRIVATE: - { - timer_close((timer_t *)info->private); - break; - } - default: - { - } - } - - free(info); -} diff --git a/src/libnotify/notifyd/service.h b/src/libnotify/notifyd/service.h deleted file mode 100644 index 21a5e0731..000000000 --- a/src/libnotify/notifyd/service.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2003-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _NOTIFY_SERVICE_H_ -#define _NOTIFY_SERVICE_H_ - -#define SERVICE_TYPE_NONE 0 -#define SERVICE_TYPE_PATH_PUBLIC 1 -#define SERVICE_TYPE_PATH_PRIVATE 2 -#define SERVICE_TYPE_TIMER_PUBLIC 3 -#define SERVICE_TYPE_TIMER_PRIVATE 4 - -#define SERVICE_PREFIX "com.apple.system.notify.service." -#define SERVICE_PREFIX_LEN 32 - -typedef struct -{ - uint32_t type; - void *private; -} svc_info_t; - -int service_open(const char *name, client_t *client, audit_token_t audit); -int service_open_path(const char *name, const char *path, uid_t uid, gid_t gid); -int service_open_path_private(const char *name, client_t *client, const char *path, audit_token_t audit, uint32_t flags); -int service_open_timer(const char *name, const char *args); -int service_open_timer_private(const char *name, client_t *client, const char *args); -void service_close(uint16_t service_index); -void *service_info_get(uint16_t index); - -#endif /* _NOTIFY_SERVICE_H_ */ diff --git a/src/libnotify/notifyd/timer.c b/src/libnotify/notifyd/timer.c deleted file mode 100644 index c1ab31788..000000000 --- a/src/libnotify/notifyd/timer.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (c) 2009-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include "timer.h" - -#define MINUTE 60 -#define HOUR 3600 -#define DAY 86400 - -static const uint8_t mlen[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -/* - * Timed events - * - * Supported event types: - * - * Oneshot - * Every n seconds/minutes/hours/days/weeks - * Specific day of the month, every n months - * Specific weekday following specific day of the month, every n months - * - */ -static time_t -timer_next(timer_t *t, time_t now) -{ - uint32_t y, m; - int32_t d, x, a, b, dd, wd; - struct tm tmp; - time_t next, tt, tod; - - if (t == NULL) return 0; - - switch (t->type) - { - case TIME_EVENT_ONESHOT: - { - /* - * oneshot time event - */ - if (t->start < now) return 0; - return t->start; - } - case TIME_EVENT_CLOCK: - { - /* - * event recurs every t->freq seconds - */ - - /* t->end is the cut-off. If it's in the past, return 0 */ - if ((t->end != 0) && (t->end < now)) return 0; - - /* If the start time is in the future, that's the next occurrence */ - if (t->start >= now) return t->start; - - /* shouldn't happen, as TIME_EVENT_CLOCK should always recur */ - if (t->freq == 0) return 0; - - x = (int32_t)(((t->freq - 1) + now - t->start) / t->freq); - next = t->start + (x * t->freq); - return next; - } - case TIME_EVENT_CAL: - { - /* - * event recurs every t->freq months - * t->base gives us the starting month and year, and the time of day - * t->day specifies the day of the month (negative means relative to last day of the month) - * t->day is > 100 or < 100, then it means a weekday - * 101 = first monday, 102 = first tuesday, ..., 108 = second monday, and so on - * -101 = last monday, -102 = last tuesday, ..., -108 = second last monday, and so on - */ - - /* t->end is the cut-off. If it's in the past, return 0 */ - if ((t->end != 0) && (t->end < now)) return 0; - - /* If the start time is in the future, that's the next occurrence */ - if (t->start >= now) return t->start; - - next = t->start; - - /* If t->next is set from the last time we ran, and it is in the past, we can start there. */ - if ((t->next > 0) && (t->next < now)) next = t->next; - - while (next < now) - { - /* determine year, month, and time-of-day (clock time) of the next occurance */ - memset(&tmp, 0, sizeof(struct tm)); - localtime_r((const time_t *)&(next), &tmp); - y = tmp.tm_year; - m = tmp.tm_mon; - tod = tmp.tm_sec + (MINUTE * tmp.tm_min) + (HOUR * tmp.tm_hour); - - m += t->freq; - if (m > 11) - { - y += (m / 12); - m %= 12; - } - - /* we now have a year (y), a month (m), and a time of day (tod) */ - - if (t->day > 0) - { - if (t->day < 100) - { - /* easy case: day is the date of the month */ - - memset(&tmp, 0, sizeof(struct tm)); - tmp.tm_year = y; - tmp.tm_mon = m; - tmp.tm_mday = t->day; - tmp.tm_isdst = -1; - next = mktime(&tmp) + tod; - continue; - } - else - { - /* t->day is a weekday */ - - wd = t->day - 100; - - /* start by finding out the weekday of the first of the month */ - memset(&tmp, 0, sizeof(struct tm)); - tmp.tm_year = y; - tmp.tm_mon = m; - tmp.tm_mday = 1; - tmp.tm_isdst = -1; - tt = mktime(&tmp); - localtime_r((const time_t *)&tt, &tmp); - - if (tmp.tm_wday == 0) tmp.tm_wday = 7; - - x = 0; - if (tmp.tm_wday > (wd % 7)) x = (wd + 7) - tmp.tm_wday; - else x = wd - tmp.tm_wday; - - tmp.tm_mday += x; - tmp.tm_isdst = -1; - next = mktime(&tmp) + tod; - continue; - } - } - - if (t->day > -100) - { - /* nth day from the end of the month */ - if (m == 1) - { - /* determine weekday of last day of February (== March 0) */ - memset(&tmp, 0, sizeof(struct tm)); - tmp.tm_year = y; - tmp.tm_mon = 2; - tmp.tm_mday = 0; - tmp.tm_isdst = -1; - tt = mktime(&tmp); - memset(&tmp, 0, sizeof(struct tm)); - localtime_r((const time_t *)&(tt), &tmp); - d = tmp.tm_mday + t->day; - } - else - { - d = mlen[m] + t->day; - } - - memset(&tmp, 0, sizeof(struct tm)); - tmp.tm_year = y; - tmp.tm_mon = m; - tmp.tm_mday = d; - tmp.tm_isdst = -1; - next = mktime(&tmp) + tod; - continue; - } - - /* t->day is a weekday relative to the end of the month */ - if (m == 1) - { - /* determine weekday of last day of February (== March 0) */ - memset(&tmp, 0, sizeof(struct tm)); - tmp.tm_year = y; - tmp.tm_mon = 2; - tmp.tm_mday = 0; - tmp.tm_isdst = -1; - tt = mktime(&tmp); - memset(&tmp, 0, sizeof(struct tm)); - localtime_r((const time_t *)&(tt), &tmp); - d = tmp.tm_mday; - } - else - { - d = mlen[m]; - } - - memset(&tmp, 0, sizeof(struct tm)); - tmp.tm_year = y; - tmp.tm_mon = m; - tmp.tm_mday = d; - tmp.tm_isdst = -1; - - dd = -1 * (t->day + 100); - a = dd % 7; - b = (dd + 6) / 7; - if (a <= tmp.tm_wday) b--; - tmp.tm_mday = ((a - tmp.tm_wday) + d) - (b * 7); - next = mktime(&tmp) + tod; - } - - t->next = next; - return next; - } - default: - { - return 0; - } - } - -} - -/* - * This does the actual free. - * It is dispatched on the timer's dispatch source queue to make it safe. - */ -static void -timer_free(timer_t *t) -{ - if (t == NULL) return; - if (t->contextp != NULL) free(t->contextp); - - dispatch_release(t->t_src); - dispatch_release(t->t_queue); - - memset(t, 0, sizeof(timer_t)); - free(t); -} - -void -timer_close(timer_t *t) -{ - if (t == NULL) return; - - if (t->t_src != NULL) dispatch_source_cancel(t->t_src); - - /* - * We need to make sure that the source's event handler isn't currently running - * before we free the timer. We let the source's queue do the actual free. - */ - dispatch_async(t->t_queue, ^{ timer_free(t); }); -} - -timer_t * -timer_oneshot(time_t when, dispatch_queue_t queue) -{ - timer_t *t; - time_t now; - dispatch_time_t trigger; - - /* refuse a trigger time in the past */ - now = time(0); - if (when <= now) return NULL; - - t = calloc(1, sizeof(timer_t)); - if (t == NULL) return NULL; - - dispatch_retain(queue); - - t->type = TIME_EVENT_ONESHOT; - t->start = when; - t->t_queue = queue; - - t->t_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); - t->src = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, queue); - - trigger = dispatch_walltime(NULL, (t->start - now) * NSEC_PER_SEC); - dispatch_source_set_timer(t->t_src, trigger, NSEC_PER_SEC, 0); - - dispatch_source_set_event_handler(t->t_src, ^{ - dispatch_source_merge_data(t->src, 1); - dispatch_source_cancel(t->t_src); - }); - - dispatch_activate(t->t_src); - return t; -} - -timer_t * -timer_clock(time_t first, time_t freq_sec, time_t end, dispatch_queue_t queue) -{ - timer_t *t; - time_t now; - dispatch_time_t trigger; - int64_t x; - - if (freq_sec == 0) return timer_oneshot(first, queue); - - now = time(0); - - t = calloc(1, sizeof(timer_t)); - if (t == NULL) return NULL; - - t->type = TIME_EVENT_CLOCK; - - if (first < now) - { - x = ((freq_sec - 1) + now - first) / freq_sec; - t->start = first + (x * freq_sec); - } - else - { - t->start = first; - } - - t->end = end; - t->freq = (uint32_t)freq_sec; - t->t_queue = queue; - - t->t_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); - t->src = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, queue); - - trigger = dispatch_walltime(NULL, (t->start - now) * NSEC_PER_SEC); - dispatch_source_set_timer(t->t_src, trigger, freq_sec * NSEC_PER_SEC, 0); - - dispatch_source_set_event_handler(t->t_src, ^{ - unsigned long n = dispatch_source_get_data(t->t_src); - dispatch_source_merge_data(t->src, n); - - /* deactivate if this is the last time we want to trigger the client source */ - if ((t->end > 0) && (t->end < (time(0) + freq_sec))) - { - dispatch_source_cancel(t->t_src); - } - }); - - dispatch_activate(t->t_src); - - return t; -} - -timer_t * -timer_calendar(time_t first, time_t freq_mth, time_t end, int day, dispatch_queue_t queue) -{ - timer_t *t; - time_t next, now; - dispatch_time_t trigger; - - if (freq_mth == 0) return timer_oneshot(first, queue); - - now = time(0); - - t = calloc(1, sizeof(timer_t)); - if (t == NULL) return NULL; - - t->type = TIME_EVENT_CAL; - t->start = first; - t->day = day; - t->end = end; - t->freq = (uint32_t)freq_mth; - t->t_queue = queue; - - t->t_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); - t->src = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, queue); - - next = timer_next(t, now); - trigger = dispatch_walltime(NULL, (next - now) * NSEC_PER_SEC); - dispatch_source_set_timer(t->t_src, trigger, NSEC_PER_SEC, 0); - - dispatch_source_set_event_handler(t->t_src, ^{ - unsigned long n = dispatch_source_get_data(t->t_src); - dispatch_source_merge_data(t->src, n); - - time_t now = time(0); - time_t x = timer_next(t, now); - - /* deactivate when there is no next time */ - if (x == 0) - { - dispatch_source_cancel(t->t_src); - } - else - { - dispatch_source_set_timer(t->t_src, dispatch_walltime(NULL, (x - now) * NSEC_PER_SEC), NSEC_PER_SEC, 0); - } - }); - - dispatch_activate(t->t_src); - - return t; -} diff --git a/src/libnotify/notifyd/timer.h b/src/libnotify/notifyd/timer.h deleted file mode 100644 index 84315ef18..000000000 --- a/src/libnotify/notifyd/timer.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2009-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -#define TIME_EVENT_NONE 0 -#define TIME_EVENT_ONESHOT 1 -#define TIME_EVENT_CLOCK 2 -#define TIME_EVENT_CAL 3 - -/* - * Timer Event - */ -typedef struct -{ - dispatch_source_t src; - dispatch_source_t t_src; - dispatch_queue_t t_queue; - void *contextp; - int64_t start; - int64_t end; - int64_t next; - uint64_t context64; - uint32_t freq; - uint32_t type; - int32_t day; - uint32_t context32; -} timer_t; - -timer_t *timer_oneshot(time_t when, dispatch_queue_t queue); -timer_t *timer_clock(time_t first, time_t freq_sec, time_t end, dispatch_queue_t queue); -timer_t *timer_calendar(time_t first, time_t freq_mth, time_t end, int day, dispatch_queue_t queue); - -void timer_close(timer_t *t); diff --git a/src/libnotify/notifyd/xcodescripts/mk_notify_conf.sh b/src/libnotify/notifyd/xcodescripts/mk_notify_conf.sh deleted file mode 100644 index 5220033d0..000000000 --- a/src/libnotify/notifyd/xcodescripts/mk_notify_conf.sh +++ /dev/null @@ -1,6 +0,0 @@ -set -e -x -ETCDIR="$DSTROOT"/private/etc -install -d -o root -g wheel -m 0755 "$ETCDIR" -install -c -o root -g wheel -m 0644 \ - "$SRCROOT"/notifyd/"$NOTIFY_CONFIG" \ - "$ETCDIR"/notify.conf diff --git a/src/libnotify/notifyutil/notifyutil.1 b/src/libnotify/notifyutil/notifyutil.1 deleted file mode 100644 index 01c30d375..000000000 --- a/src/libnotify/notifyutil/notifyutil.1 +++ /dev/null @@ -1,220 +0,0 @@ -.\" Copyright (c) 2006-2011 Apple Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" This file contains Original Code and/or Modifications of Original Code -.\" as defined in and that are subject to the Apple Public Source License -.\" Version 2.0 (the 'License'). You may not use this file except in -.\" compliance with the License. Please obtain a copy of the License at -.\" http://www.opensource.apple.com/apsl/ and read it before using this -.\" file. -.\" -.\" The Original Code and all software distributed under the License are -.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. -.\" Please see the License for the specific language governing rights and -.\" limitations under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.\" -.Dd November 4, 2011 -.Dt notifyutil 1 -.Os "Mac OS X" -.Sh NAME -.Nm notifyutil -.Nd notification command line utility -.Sh SYNOPSIS -.Nm -.Op Fl q -.Op Fl v -.Op Fl z Ar msec -.Op Fl M -.Op Fl R -.Op command Li ... -.Pp -.Sh DESCRIPTION -.Nm -is a command-line utility for interacting with the -.Xr notify 3 -notification system and the -.Xr notifyd 8 -server. -It may be used to post notifications, detect and report notifications, -and to examine and set the state values associated with notification keys. -.Pp -If -.Nm -is used to monitor one or more notification keys, -it prints the notification key when the corresponding notification is received. -The -.Fl v -(verbose) -and -.Fl q -(quiet) flags, if specified, modify the output behavior. -.Pp -The -.Fl v -flag causes -.Nm -to print a time stamp, the notification key, the current state value for that key, -and the type of the notification (port, file, etc). -The -.Fl q -flag supresses any output except for state values fetched following a -.Fl g -command. -.Pp -Commands listed in the table below are processed in left to right order from the command line. -.Pp -.Bl -tag -width "-signal [#]" -compact -offset indent -.It Fl p Ar key -Post a notification for -.Ar key . -.It Fl w Ar key -Register for -.Ar key -and wait forever for notifications. -.It Fl Ar # Ar key -Register for -.Ar key -and wait for -.Ar # -(an integer) notifications. -.It "" -.Li E.g. -.Fl 1 Ar key -waits for a single notification. -.It Fl g Ar key -Get state value for -.Ar key . -.It Fl s Ar key Ar val -Set state value for -.Ar key . -.It Fl port -Use mach port notifications for subsequent -.Fl w -or -.Fl Ar # -registrations. -.It "" -This is the default registration type. -.It Fl file -Use file descriptor notifications for subsequent registrations. -.It Fl check -Use shared memory notifications for subsequent registrations. -.It Fl signal Op Ar # -Use signal notifications for subsequent registrations. -.It "" -Signal 1 (HUP) is the default, but an alternate signal may be specified. -.It Fl dispatch -Use dispatch for subsequent registrations. -.El -.Pp -When invoked with any combination of -.Fl w -and -.Fl Ar # -actions, -.Nm -registers for notification for the specified key(s). -If any key is given with a -.Fl w -action, -.Nm -runs until interrupted with Control-C. -If all registrations are invoked with -.Fl Ar # , -the program continues to run until the corresponding number of notifications for each key have been received. -.Pp -By default, -.Nm -uses mach port registration (using -.Fn notify_register_mach_port ) -for keys given with a -.Fl w -or -.Fl Ar # -flag. -The -.Fl file -command causes -.Nm -to use -.Fn notify_register_file_descriptor -for any subsequent -.Fl w -or -.Fl Ar # -registrations. -Similarly, -.Fl check -causes -.Nm -to use -.Fn notify_register_check -for subsequent registrations, -.Fl signal -switches to -.Fn notify_register_signal , -and -.Fl dispatch -causes it to use -.Fn notify_register_dispatch -for subsequent registrations. -.Pp -If any registrations are made following the use of the -.Fl check -command, -.Nm -will start a timer and check for shared memory notifications every 100 milliseconds. -An alternate timer value may be set following the -.Fl z -flag. -.Pp -The -.Fl M -flag causes -.Nm -to use multiplex all notifications over a single mach connection with -.Nm notifyd . -Notifications (except shared memory notifications) -are received and redistributed by a dispatch handler. -.Pp -The -.Fl R -flag causes -.Nm notifyutil -to regenerate all its registrations in the unlikely event that -.Nm notifyd -restarts. -.Pp -Note that a notification key and its associated state variable only exist -when there are one or more current registrations for that key. -Setting the state for a key that has no registrations has no effect. -Thus the command -.Pp -.Dl notifyutil -s foo.bar 123 -g foo.bar -.Pp -will print -.Pp -.Dl foo.bar 0 -.Pp -unless foo.bar is registered by some other process. -However, the command -.Pp -.Dl notifyutil -w foo.bar -s foo.bar 123 -g foo.bar -.Pp -prints -.Pp -.Dl foo.bar 123 -.Pp -since the -.Dq -w foo.bar -registration ensures the key and its state variable exist before the value is set, -and continue to exist when the value is fetched. -.Sh SEE ALSO -notify(3), notifyd(8) diff --git a/src/libnotify/notifyutil/notifyutil.c b/src/libnotify/notifyutil/notifyutil.c deleted file mode 100644 index b2d493f44..000000000 --- a/src/libnotify/notifyutil/notifyutil.c +++ /dev/null @@ -1,755 +0,0 @@ -/* - * Copyright (c) 2006-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define forever for(;;) -#define IndexNull ((uint32_t)-1) - -#define PRINT_QUIET 0x00000000 -#define PRINT_KEY 0x00000001 -#define PRINT_STATE 0x00000002 -#define PRINT_TIME 0x00000004 -#define PRINT_TYPE 0x00000008 -#define PRINT_TOKEN 0x00000010 -#define PRINT_VERBOSE 0xffffffff - -#ifndef USEC_PER_SEC -#define USEC_PER_SEC 1000000 -#endif - -#define TYPE_NULL 0 -#define TYPE_PORT 1 -#define TYPE_FILE 2 -#define TYPE_DISPATCH 3 -#define TYPE_SIGNAL 4 -#define TYPE_CHECK 5 -#define TYPE_PLAIN 6 - -static const char *typename[] = -{ - "unknown", - "port", - "file", - "dispatch", - "signal", - "check", - "plain" -}; - -typedef struct -{ - uint32_t token; - uint32_t type; - uint32_t signum; - uint32_t count; - char *name; -} reg_entry_t; - -static reg_entry_t *reg; -static uint32_t reg_count = 0; - -static int printopt; -static int port_flag; -static int file_flag; -static int watch_file; -static mach_port_t watch_port; -static dispatch_source_t timer_src; -static dispatch_source_t port_src; -static dispatch_source_t file_src; -static dispatch_source_t sig_src[__DARWIN_NSIG]; -static dispatch_queue_t watch_queue; - -static void -usage(const char *name) -{ - fprintf(stderr, "usage: %s [-q] [-v] [-z msec] [-M] [-R] [command ...]\n", name); - fprintf(stderr, " -q quiet mode\n"); - fprintf(stderr, " -v verbose - prints time, key, state value, and type\n"); - fprintf(stderr, " -z msec pause msec milliseconds after posting [default 100]\n"); - fprintf(stderr, " -M multiplex notifications from notifyd over a single mach port\n"); - fprintf(stderr, " -R regenerate registrations if notifyd restarts\n"); - fprintf(stderr, "commands:\n"); - fprintf(stderr, " -port switch to mach port for subsequent registrations [default]\n"); - fprintf(stderr, " -file switch to file descriptor for subsequent registrations\n"); - fprintf(stderr, " -check switch to shared memory for subsequent registrations\n"); - fprintf(stderr, " -signal [#] switch to signal [#] for subsequent registrations\n"); - fprintf(stderr, " initial default for signal is 1 (SIGHUP)\n"); - fprintf(stderr, " -dispatch switch to dispatch for subsequent registrations\n"); - fprintf(stderr, " -p key post a notification for key\n"); - fprintf(stderr, " -w key register for key and report notifications\n"); - fprintf(stderr, " -# key (# is an integer value, eg \"-1\") register for key and report # notifications\n"); - fprintf(stderr, " -g key get state value for key\n"); - fprintf(stderr, " -s key val set state value for key\n"); - - if(os_variant_has_internal_diagnostics(NULL)) - { - fprintf(stderr, " --dump dumps metadata to a file in /var/run/\n"); - } -} - -// Triggers a notifyd dump -static void -notifyutil_dump() -{ - int ret; - - ret = notify_dump_status("/var/run/notifyd.status"); - - if(ret == NOTIFY_STATUS_OK) - { - fprintf(stdout, "Notifyd dump success! New file created at /var/run/notifyd.status\n"); - } else { - fprintf(stdout, "Notifyd dump failed with %x\n", ret); - } - -} - -static void -reg_add(uint32_t tid, uint32_t type, uint32_t signum, uint32_t count, const char *name) -{ - if (name == NULL) return; - - reg = (reg_entry_t *)reallocf(reg, (reg_count + 1) * sizeof(reg_entry_t)); - if (reg == NULL) - { - fprintf(stderr, "Can't allocate memory!\n"); - reg_count = 0; - return; - } - - reg[reg_count].token = tid; - reg[reg_count].type = type; - reg[reg_count].signum = signum; - reg[reg_count].count = count; - reg[reg_count].name = strdup(name); - if (reg[reg_count].name == NULL) - { - fprintf(stderr, "Can't allocate memory!\n"); - reg = NULL; - reg_count = 0; - return; - } - - reg_count++; -} - -static void -reg_delete(uint32_t index) -{ - uint32_t i; - - if (index == IndexNull) return; - if (index >= reg_count) return; - - free(reg[index].name); - - for (i = index + 1; i < reg_count; i++) reg[i - 1] = reg[i]; - reg_count--; - - if (reg_count == 0) - { - free(reg); - reg = NULL; - } - else - { - reg = (reg_entry_t *)reallocf(reg, reg_count * sizeof(reg_entry_t)); - if (reg == NULL) - { - fprintf(stderr, "Can't allocate memory!\n"); - reg_count = 0; - } - } -} - -static uint32_t -reg_find_token(uint32_t tid) -{ - uint32_t i; - - for (i = 0; i < reg_count; i++) if (tid == reg[i].token) return i; - return IndexNull; -} - -static void -process_event(int tid) -{ - struct timeval now; - char tstr[32]; - int status, index, needspace; - uint64_t state; - - gettimeofday(&now, NULL); - - index = reg_find_token(tid); - if (index == IndexNull) return; - - needspace = 0; - - if (printopt & PRINT_TOKEN) - { - printf("[%d]", tid); - needspace = 1; - } - - if (printopt & PRINT_TIME) - { - if (needspace) printf(" "); - snprintf(tstr, sizeof(tstr), "%llu", now.tv_usec + USEC_PER_SEC + 500); - tstr[4] = '\0'; - printf("%d.%s", (int)now.tv_sec, tstr+1); - needspace = 1; - } - - if (printopt & PRINT_KEY) - { - if (needspace) printf(" "); - printf("%s", reg[index].name); - needspace = 1; - } - - if (printopt & PRINT_STATE) - { - if (needspace) printf(" "); - state = 0; - status = notify_get_state(tid, &state); - if (status == NOTIFY_STATUS_OK) printf("%llu",(unsigned long long)state); - else printf(": Failed with code %d", status); - needspace = 1; - } - - if (printopt & PRINT_TYPE) - { - if (needspace) printf(" "); - printf("%s", typename[reg[index].type]); - needspace = 1; - } - - if (printopt != PRINT_QUIET) printf("\n"); - - if ((reg[index].count != IndexNull) && (reg[index].count != 0)) reg[index].count--; - if (reg[index].count == 0) - { - status = notify_cancel(tid); - reg_delete(index); - } - fflush(stdout); - - if (reg_count == 0) exit(0); -} - -static void -file_handler(int fd) -{ - ssize_t i; - int tid; - - if (fd < 0) return; - - i = read(fd, &tid, sizeof(tid)); - if (i < 0) return; - - tid = ntohl(tid); - process_event(tid); - - if (reg_count == 0) exit(0); -} - -static void -port_handler(mach_port_t port) -{ - int tid; - mach_msg_empty_rcv_t msg; - kern_return_t status; - - if (port == MACH_PORT_NULL) return; - - memset(&msg, 0, sizeof(msg)); - status = mach_msg(&msg.header, MACH_RCV_MSG, 0, sizeof(msg), port, 0, MACH_PORT_NULL); - if (status != KERN_SUCCESS) return; - - tid = msg.header.msgh_id; - process_event(tid); - - if (reg_count == 0) exit(0); -} - -static void -signal_handler(uint32_t sig) -{ - uint32_t i, status; - int check; - - if (printopt != PRINT_QUIET) printf("SIGNAL %u\n", sig); - for (i = 0; i < reg_count; i++) - { - if ((reg[i].type == TYPE_SIGNAL) && (reg[i].signum == sig)) - { - check = 0; - status = notify_check(reg[i].token, &check); - if ((status == NOTIFY_STATUS_OK) && (check != 0)) process_event(reg[i].token); - } - } - - if (reg_count == 0) exit(0); -} - -static void -dispatch_handler(int x) -{ - uint32_t index = reg_find_token(x); - if (index == IndexNull) return; - - process_event(reg[index].token); -} - -static void -timer_handler(void) -{ - uint32_t i, status; - int check; - - for (i = 0; i < reg_count; i++) - { - if ((reg[i].type == TYPE_CHECK) || (reg[i].type == TYPE_PLAIN)) - { - check = 0; - status = notify_check(reg[i].token, &check); - if ((status == NOTIFY_STATUS_OK) && (check != 0)) process_event(reg[i].token); - } - } - - if (reg_count == 0) exit(0); -} - -static uint32_t -do_register(const char *name, uint32_t type, uint32_t signum, uint32_t count) -{ - int tid, check; - uint32_t status; - - switch (type) - { - case TYPE_PORT: - { - status = notify_register_mach_port(name, &watch_port, port_flag, &tid); - if (status != NOTIFY_STATUS_OK) return status; - - port_flag = NOTIFY_REUSE; - if (port_src == NULL) - { - port_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, watch_port, 0, watch_queue); - dispatch_source_set_event_handler(port_src, ^{ - port_handler(watch_port); - }); - dispatch_resume(port_src); - } - - break; - } - - case TYPE_FILE: - { - status = notify_register_file_descriptor(name, &watch_file, file_flag, &tid); - if (status != NOTIFY_STATUS_OK) return status; - - file_flag = NOTIFY_REUSE; - if (file_src == NULL) - { - file_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t)watch_file, 0, watch_queue); - dispatch_source_set_event_handler(file_src, ^{ - file_handler(watch_file); - }); - dispatch_resume(file_src); - } - - break; - } - - case TYPE_SIGNAL: - { - signal(signum, SIG_IGN); - - status = notify_register_signal(name, signum, &tid); - if (status != NOTIFY_STATUS_OK) return status; - - status = notify_check(tid, &check); - - if (sig_src[signum] == NULL) - { - sig_src[signum] = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, (uintptr_t)signum, 0, watch_queue); - dispatch_source_set_event_handler(sig_src[signum], ^{ - signal_handler(signum); - }); - dispatch_resume(sig_src[signum]); - } - - break; - } - - case TYPE_DISPATCH: - { - status = notify_register_dispatch(name, &tid, watch_queue, ^(int x){ dispatch_handler(x); }); - if (status != NOTIFY_STATUS_OK) return status; - break; - } - - case TYPE_CHECK: - { - status = notify_register_check(name, &tid); - if (status != NOTIFY_STATUS_OK) return status; - - status = notify_check(tid, &check); - - if (timer_src == NULL) - { - timer_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, watch_queue); - dispatch_source_set_event_handler(timer_src, ^{ - timer_handler(); - }); - dispatch_source_set_timer(timer_src, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 10), NSEC_PER_SEC / 10, 0); - dispatch_resume(timer_src); - } - - break; - } - - case TYPE_PLAIN: - { - status = notify_register_plain(name, &tid); - if (status != NOTIFY_STATUS_OK) return status; - - status = notify_check(tid, &check); - - if (timer_src == NULL) - { - timer_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, watch_queue); - dispatch_source_set_event_handler(timer_src, ^{ - timer_handler(); - }); - dispatch_source_set_timer(timer_src, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 10), NSEC_PER_SEC / 10, 0); - dispatch_resume(timer_src); - } - - break; - } - - default: return NOTIFY_STATUS_FAILED; - } - - reg_add(tid, type, signum, count, name); - return NOTIFY_STATUS_OK; -} - -int -main(int argc, const char *argv[]) -{ - const char *name; - uint32_t i, n, signum, ntype, status, opts, nap; - int tid; - uint64_t state; - - for (i = 0; i < __DARWIN_NSIG; i++) sig_src[i] = NULL; - - ntype = TYPE_PORT; - signum = 1; - watch_file = -1; - watch_port = MACH_PORT_NULL; - printopt = PRINT_KEY; - opts = 0; - nap = 100000; - - watch_queue = dispatch_queue_create("Watch Q", NULL); - - name = strrchr(argv[0], '/'); - if (name == NULL) name = argv[0]; - else name++; - - for (i = 1; i < argc; i++) - { - if ((!strcmp(argv[i], "-help")) || (!strcmp(argv[i], "-h"))) - { - usage(name); - exit(0); - } - else if (!strcmp(argv[i], "-q")) - { - printopt = PRINT_QUIET; - } - else if (!strcmp(argv[i], "-v")) - { - printopt |= PRINT_VERBOSE; - } - else if (!strcmp(argv[i], "-M")) - { - opts |= NOTIFY_OPT_DISPATCH; - } - else if (!strcmp(argv[i], "-R")) - { - opts |= NOTIFY_OPT_REGEN; - } - else if (!strcmp(argv[i], "-z")) - { - if ((i + 1) >= argc) - { - fprintf(stderr, "timer value must be supplied following -z\n"); - usage(name); - exit(1); - } - - i++; - - if ((argv[i][0] < '0') || (argv[i][1] > '9')) - { - fprintf(stderr, "-z %s is invalid\n", argv[i]); - fprintf(stderr, "timer value must be an integer\n"); - usage(name); - exit(1); - } - nap = 1000 * atoi(argv[i]); - } - else if (!strcmp(argv[i], "-port")) - {} - else if (!strcmp(argv[i], "-file")) - {} - else if ((!strcmp(argv[i], "-sig")) || (!strcmp(argv[i], "-signal"))) - { - if ((i + 1) >= argc) continue; - if (argv[i + 1][0] == '-') continue; - - i++; - - if ((argv[i][0] < '0') || (argv[i][1] > '9')) - { - fprintf(stderr, "-signal %s is invalid\n", argv[i]); - fprintf(stderr, "signals must be specified as integer values\n"); - usage(name); - exit(1); - } - - } - else if (!strcmp(argv[i], "-dispatch")) - {} - else if (!strcmp(argv[i], "-check")) - {} - else if (!strcmp(argv[i], "-plain")) - {} - else if (!strcmp(argv[i], "-p")) - { - if ((i + 1) >= argc) - { - fprintf(stderr, "name required following -p\n"); - usage(name); - exit(1); - } - - i++; - } - else if ((argv[i][0] == '-') && ((argv[i][1] == 'w') || ((argv[i][1] >= '0') && (argv[i][1] <= '9')))) - { - if ((i + 1) >= argc) - { - fprintf(stderr, "name required following %s\n", argv[i]); - usage(name); - exit(1); - } - - i++; - } - else if (!strcmp(argv[i], "-g")) - { - if ((i + 1) >= argc) - { - fprintf(stderr, "name required following -g\n"); - usage(name); - exit(1); - } - - i++; - } - else if (!strcmp(argv[i], "-s")) - { - if ((i + 1) >= argc) - { - fprintf(stderr, "name required following -s\n"); - usage(name); - exit(1); - } - - i++; - - if ((i + 1) >= argc) - { - fprintf(stderr, "value required following -s name\n"); - usage(name); - exit(1); - } - - i++; - state = atoll(argv[i]); - if ((state == 0) && (strcmp(argv[i], "0"))) - { - fprintf(stderr, "value following -s name must be a 64-bit integer\n"); - } - } - else if (!strcmp(argv[i], "--dump") && os_variant_has_internal_diagnostics(NULL)) - { - notifyutil_dump(); - exit(0); - - } - else - { - fprintf(stderr, "unrecognized option: %s\n", argv[i]); - usage(name); - exit(1); - } - } - - if (opts != 0) notify_set_options(opts); - - for (i = 1; i < argc; i++) - { - if (!strcmp(argv[i], "-port")) - { - ntype = TYPE_PORT; - } - else if (!strcmp(argv[i], "-file")) - { - ntype = TYPE_FILE; - } - else if ((!strcmp(argv[i], "-sig")) || (!strcmp(argv[i], "-signal"))) - { - - ntype = TYPE_SIGNAL; - if (((i + 1) < argc) && (argv[i + 1][0] != '-')) - { - i++; - signum = atoi(argv[i]); - } - } - else if (!strcmp(argv[i], "-dispatch")) - { - ntype = TYPE_DISPATCH; - } - else if (!strcmp(argv[i], "-check")) - { - ntype = TYPE_CHECK; - } - else if (!strcmp(argv[i], "-plain")) - { - ntype = TYPE_PLAIN; - } - else if (!strcmp(argv[i], "-p")) - { - if ((i + 1) >= argc) - { - usage(name); - exit(1); - } - - i++; - - status = notify_post(argv[i]); - if (status != NOTIFY_STATUS_OK) printf("%s: Failed with code %d\n", argv[i], status); - else if (nap > 0) usleep(nap); - } - else if ((argv[i][0] == '-') && ((argv[i][1] == 'w') || ((argv[i][1] >= '0') && (argv[i][1] <= '9')))) - { - if ((i + 1) >= argc) - { - usage(name); - exit(1); - } - - n = IndexNull; - if (argv[i][1] != 'w') n = atoi(argv[i] + 1); - - i++; - tid = IndexNull; - - status = do_register(argv[i], ntype, signum, n); - if (status != NOTIFY_STATUS_OK) printf("%s: Failed with code %d\n", argv[i], status); - } - else if (!strcmp(argv[i], "-g")) - { - if ((i + 1) >= argc) - { - usage(name); - exit(1); - } - - i++; - state = 0; - tid = IndexNull; - - status = notify_register_plain(argv[i], &tid); - if (status == NOTIFY_STATUS_OK) - { - status = notify_get_state(tid, &state); - notify_cancel(tid); - } - - if (status == NOTIFY_STATUS_OK) printf("%s %llu\n", argv[i], (unsigned long long)state); - else printf("%s: Failed with code %d\n", argv[i], status); - } - else if (!strcmp(argv[i], "-s")) - { - if ((i + 2) >= argc) - { - usage(name); - exit(1); - } - - i++; - tid = IndexNull; - status = notify_register_plain(argv[i], &tid); - if (status == NOTIFY_STATUS_OK) - { - state = atoll(argv[i + 1]); - status = notify_set_state(tid, state); - notify_cancel(tid); - } - - if (status != NOTIFY_STATUS_OK) printf("%s: Failed with code %d\n", argv[i], status); - i++; - } - } - - if (reg_count == 0) exit(0); - - dispatch_main(); -} diff --git a/src/libnotify/notifyutil/notifyutil_entitlements.plist b/src/libnotify/notifyutil/notifyutil_entitlements.plist deleted file mode 100644 index 5a7576c8d..000000000 --- a/src/libnotify/notifyutil/notifyutil_entitlements.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.private.libnotify.statecapture - - - diff --git a/src/libnotify/table.c b/src/libnotify/table.c deleted file mode 100644 index 6a5144f0c..000000000 --- a/src/libnotify/table.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2003-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "table.h" -#include "notify_internal.h" - -#define TABLE_TOMBSTONE ((void *)~0) -#define TABLE_MINSHIFT 5 -#define TABLE_MINSIZE (1 << TABLE_MINSHIFT) - -OS_ALWAYS_INLINE -static inline uint32_t -table_next(uint32_t i, uint32_t size) -{ - i++; - return i >= size ? 0 : i; -} - -OS_ALWAYS_INLINE -static inline uint32_t -table_prev(uint32_t i, uint32_t size) -{ - return (i ? i : size) - 1; -} - -static inline bool -string_equals(const char *a, const char *b) -{ - return a == b || strcmp(a, b) == 0; -} - -static uint32_t -string_hash(const char *key) -{ - uint32_t hash = 0; - - for (; *key; key++) { - hash += (unsigned char)(*key); - hash += (hash << 10); - hash ^= (hash >> 6); - } - - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash; -} - -static inline bool -uint32_equals(uint32_t a, uint32_t b) -{ - return a == b; -} - -static inline uint32_t -uint32_hash(uint32_t x) -{ - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = (x >> 16) ^ x; - return x; -} - -static inline bool -uint64_equals(uint64_t a, uint64_t b) -{ - return a == b; -} - -static inline uint32_t -uint64_hash(uint64_t key) -{ - return uint32_hash((uint32_t)key ^ (uint32_t)(key >> 32)); -} - -#define ns(n) _nc_table##n -#define key_t char * -#define ckey_t const char * -#define key_hash string_hash -#define key_equals string_equals -#include "table.in.c" - -#define ns(n) _nc_table##n##_n -#define key_t uint32_t -#define ckey_t uint32_t -#define key_hash uint32_hash -#define key_equals uint32_equals -#include "table.in.c" - -#define ns(n) _nc_table##n##_64 -#define key_t uint64_t -#define ckey_t uint64_t -#define key_hash uint64_hash -#define key_equals uint64_equals -#include "table.in.c" diff --git a/src/libnotify/table.h b/src/libnotify/table.h deleted file mode 100644 index 53762ff14..000000000 --- a/src/libnotify/table.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2003-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _NOTIFY_TABLE_H_ -#define _NOTIFY_TABLE_H_ - -#include -#include - -#define _nc_table(key_t, _ns) \ - struct _nc_table##_ns { \ - uint32_t count; \ - uint32_t tombstones; \ - uint32_t size; \ - uint16_t grow_shift; \ - uint16_t key_offset; \ - key_t **keys; \ - } - -typedef _nc_table(char *, ) table_t; -typedef _nc_table(uint32_t, _n) table_n_t; -typedef _nc_table(uint64_t, _64) table_64_t; - -__BEGIN_DECLS - -extern void _nc_table_init(table_t *t, size_t key_offset); -extern void _nc_table_init_n(table_n_t *t, size_t key_offset); -extern void _nc_table_init_64(table_64_t *t, size_t key_offset); - -extern void _nc_table_insert(table_t *t, char **key); -extern void _nc_table_insert_n(table_n_t *t, uint32_t *key); -extern void _nc_table_insert_64(table_64_t *t, uint64_t *key); - -extern void *_nc_table_find(table_t *t, const char *key); -extern void *_nc_table_find_n(table_n_t *t, uint32_t key); -extern void *_nc_table_find_64(table_64_t *t, uint64_t key); - -extern void _nc_table_delete(table_t *t, const char *key); -extern void _nc_table_delete_n(table_n_t *t, uint32_t key); -extern void _nc_table_delete_64(table_64_t *t, uint64_t key); - -extern void _nc_table_foreach(table_t *t, OS_NOESCAPE bool (^)(void *)); -extern void _nc_table_foreach_n(table_n_t *t, OS_NOESCAPE bool (^)(void *)); -extern void _nc_table_foreach_64(table_64_t *t, OS_NOESCAPE bool (^)(void *)); - -__END_DECLS - -#endif /* _NOTIFY_TABLE_H_ */ diff --git a/src/libnotify/table.in.c b/src/libnotify/table.in.c deleted file mode 100644 index e798de9da..000000000 --- a/src/libnotify/table.in.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2018 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -static inline void * -ns(_value)(struct ns() *t, uint32_t i) -{ - return (void *)((uintptr_t)t->keys[i] - t->key_offset); -} - -static inline void -ns(_clear)(struct ns() *t) -{ - free(t->keys); - ns(_init)(t, t->key_offset); -} - -void -ns(_init)(struct ns() *t, size_t offset) -{ - *t = (struct ns()){ - .grow_shift = TABLE_MINSHIFT, - .key_offset = (uint16_t)offset, - }; -} - -OS_NOINLINE -static void -ns(_rehash)(struct ns() *t, int direction) -{ - struct ns() old = *t; - - if (direction > 0) { - t->size += (1 << t->grow_shift); - if (t->size == (8 << t->grow_shift)) { - t->grow_shift++; - } - } else if (direction < 0) { - if (t->grow_shift > TABLE_MINSHIFT) { - t->grow_shift--; - } - t->size = roundup(t->size / 2, (1 << t->grow_shift)); - } - - t->count = 0; - t->tombstones = 0; - t->keys = calloc(t->size, sizeof(key_t *)); - if (t->keys == NULL) { - NOTIFY_INTERNAL_CRASH(0, "Unable to grow table: registration leak?"); - } - - for (uint32_t i = 0; i < old.size; i++) { - if (old.keys[i] == NULL || old.keys[i] == TABLE_TOMBSTONE) { - continue; - } - - ns(_insert)(t, old.keys[i]); - } - free(old.keys); -} - -void * -ns(_find)(struct ns() *t, ckey_t key) -{ - if (t->count == 0) { - return NULL; - } - - uint32_t size = t->size, loop_limit = t->size; - uint32_t i = key_hash(key) % size; - - for (;;) { - if (os_unlikely(loop_limit-- == 0)) { - NOTIFY_INTERNAL_CRASH(0, "Corrupt hash table"); - } - if (t->keys[i] != TABLE_TOMBSTONE) { - if (t->keys[i] == NULL) { - return NULL; - } - if (key_equals(key, *t->keys[i])) { - return ns(_value)(t, i); - } - } - i = table_next(i, size); - } -} - -void -ns(_insert)(struct ns() *t, key_t *key) -{ - /* - * Our algorithm relies on having enough NULLS to end loops. - * Make sure their density is never below 25%. - * - * When it drops too low, if the ratio of tombstones is low, - * assume we're on a growth codepath. - * - * Else, we just rehash in place to prune tombstones. - */ - if (os_unlikely(t->count + t->tombstones >= 3 * t->size / 4)) { - if (t->count >= 4 * t->tombstones) { - ns(_rehash)(t, 1); - } else { - ns(_rehash)(t, 0); - } - } - - uint32_t size = t->size, loop_limit = t->size; - uint32_t i = key_hash(*key) % size; - - for (;;) { - if (os_unlikely(loop_limit-- == 0)) { - NOTIFY_INTERNAL_CRASH(0, "Corrupt hash table"); - } - if (t->keys[i] == NULL) { - break; - } - if (t->keys[i] == TABLE_TOMBSTONE) { - t->tombstones--; - break; - } - i = table_next(i, size); - } - - t->keys[i] = key; - t->count++; -} - -void -ns(_delete)(struct ns() *t, ckey_t key) -{ - if (t->count == 0) { - return; - } - - uint32_t size = t->size, loop_limit = t->size; - uint32_t i = key_hash(key) % size; - - for (;;) { - if (os_unlikely(loop_limit-- == 0)) { - NOTIFY_INTERNAL_CRASH(0, "Corrupt hash table"); - } - if (t->keys[i] != TABLE_TOMBSTONE) { - if (t->keys[i] == NULL) { - return; - } - if (key_equals(key, *t->keys[i])) { - break; - } - } - i = table_next(i, size); - } - - t->keys[i] = TABLE_TOMBSTONE; - t->tombstones++; - t->count--; - - if (t->keys[table_next(i, size)] == NULL) { - do { - t->tombstones--; - t->keys[i] = NULL; - i = table_prev(i, size); - } while (t->keys[i] == TABLE_TOMBSTONE); - } - - if (t->count == 0) { - /* if the table is empty, free all its resources */ - ns(_clear)(t); - } else if (t->size >= TABLE_MINSIZE * 2 && t->count < t->size / 8) { - /* if the table density drops below 12%, shrink it */ - ns(_rehash)(t, -1); - } -} - -void -ns(_foreach)(struct ns() *t, bool (^handler)(void *)) -{ - for (uint32_t i = 0; i < t->size; i++) { - if (t->keys[i] != NULL && t->keys[i] != TABLE_TOMBSTONE) { - if (!handler(ns(_value)(t, i))) break; - } - } -} - -#undef ns -#undef key_t -#undef ckey_t -#undef key_hash -#undef key_equals -#undef make_map diff --git a/src/libnotify/xcodeconfig/base.xcconfig b/src/libnotify/xcodeconfig/base.xcconfig deleted file mode 100644 index ea7c95b69..000000000 --- a/src/libnotify/xcodeconfig/base.xcconfig +++ /dev/null @@ -1,33 +0,0 @@ -#include "/Makefiles/CoreOS/Xcode/BSD.xcconfig" - -// Architectures -SDKROOT = macosx.internal - -ALWAYS_SEARCH_USER_PATHS = YES -HEADER_SEARCH_PATHS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders $(PROJECT_DIR) -ARCHS = $(ARCHS_STANDARD_32_64_BIT) -CODE_SIGN_IDENTITY = - -DEBUG_INFORMATION_FORMAT = dwarf-with-dsym -GCC_ENABLE_CPP_EXCEPTIONS = NO -GCC_ENABLE_CPP_RTTI = NO -GCC_ENABLE_OBJC_EXCEPTIONS = NO -GCC_PREPROCESSOR_DEFINITIONS = __DARWIN_NON_CANCELABLE=1 -GCC_C_LANGUAGE_STANDARD = gnu11 -GCC_WARN_ABOUT_RETURN_TYPE = YES -GCC_WARN_UNUSED_VARIABLE = YES -//GCC_WARN_64_TO_32_BIT_CONVERSION = YES -//GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES -//GCC_WARN_ABOUT_RETURN_TYPE = YES -OTHER_CFLAGS = -fno-exceptions -Weverything -Wno-reserved-id-macro -Wno-padded -Wno-sign-compare -Wno-used-but-marked-unused -Wno-undef -Wno-cast-qual -Wno-documentation -Wno-unused-macros -Wno-gnu -OTHER_CFLAGS_debug = -O0 -CURRENT_PROJECT_VERSION = -CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion) -VERSION_INFO_PREFIX = __ -VERSIONING_SYSTEM = apple-generic -PREBINDING = NO -LLVM_LTO = YES - -NOTIFY_CONFIG = notify.conf.MacOSX -NOTIFY_CONFIG[sdk=iphoneos*] = notify.conf.iPhone -NOTIFY_CONFIG[sdk=tvos*] = notify.conf.iPhone -NOTIFY_CONFIG[sdk=*simulator*] = notify.conf.iOSSimulator diff --git a/src/libnotify/xcodeconfig/libnotify.xcconfig b/src/libnotify/xcodeconfig/libnotify.xcconfig deleted file mode 100644 index 8d3bc6e12..000000000 --- a/src/libnotify/xcodeconfig/libnotify.xcconfig +++ /dev/null @@ -1,35 +0,0 @@ -#include "base.xcconfig" - -PRODUCT_NAME = libsystem_notify -INSTALL_PATH = /usr/lib/system -PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include -PUBLIC_HEADERS_FOLDER_PATH = /usr/include -DYLIB_CURRENT_VERSION = $(CURRENT_PROJECT_VERSION) -EXECUTABLE_PREFIX = -BUILD_VARIANTS = normal -CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion) -VERSION_INFO_PREFIX = __ -VERSIONING_SYSTEM = apple-generic -GCC_SYMBOLS_PRIVATE_EXTERN = YES -STRIP_STYLE = non-global -SUPPORTS_TEXT_BASED_API = YES -TAPI_VERIFY_MODE = Pedantic - -LINK_WITH_STANDARD_LIBRARIES = NO -OTHER_LDFLAGS = -umbrella System -L/usr/lib/system $(LDFLAGS_DYLD) $(LDFLAGS_COMPILER_RT) $(LDFLAGS_SYSCALL) $(LDFLAGS_PLATFORM) $(LDFLAGS_PTHREAD) $(LDFLAGS_MALLOC) $(LDFLAGS_C) $(LDFLAGS_BLOCKS) $(LDFLAGS_DISPATCH) $(LDFLAGS_XPC) $(LDFLAGS_DARWIN) -LDFLAGS_DYLD = -ldyld -LDFLAGS_COMPILER_RT = -lcompiler_rt -LDFLAGS_SYSCALL = -lsystem_kernel -LDFLAGS_SYSCALL[sdk=iphonesimulator*] = -lsystem_sim_kernel -LDFLAGS_PLATFORM = -lsystem_platform -LDFLAGS_PLATFORM[sdk=iphonesimulator*] = -lsystem_sim_platform -LDFLAGS_PTHREAD = -lsystem_pthread -LDFLAGS_PTHREAD[sdk=iphonesimulator*] = -lsystem_sim_pthread -LDFLAGS_MALLOC = -lsystem_malloc -LDFLAGS_C = -lsystem_c -LDFLAGS_BLOCKS = -lsystem_blocks -LDFLAGS_DISPATCH = -ldispatch -LDFLAGS_XPC = -lxpc -LDFLAGS_DARWIN = -lsystem_darwin - -IS_ZIPPERED=YES diff --git a/src/libnotify/xcodeconfig/notifyd.xcconfig b/src/libnotify/xcodeconfig/notifyd.xcconfig deleted file mode 100644 index 16793c706..000000000 --- a/src/libnotify/xcodeconfig/notifyd.xcconfig +++ /dev/null @@ -1,11 +0,0 @@ -#include "base.xcconfig" - -INSTALL_PATH = /usr/sbin - -// Sandbox settings -SANDBOX_PATH = /System/Library/Sandbox/Profiles -SANDBOX_PATH[sdk=iphone*] = -SANDBOX_NAME = com.apple.notifyd -SANDBOX_PROFILE = com.apple.notifyd.sb -OTHER_MIGFLAGS = -DMACH_NOTIFY_SEND_POSSIBLE_EXPECTED=1 - diff --git a/src/libnotify/xcodeconfig/notifyutil.xcconfig b/src/libnotify/xcodeconfig/notifyutil.xcconfig deleted file mode 100644 index 0c00b7e7b..000000000 --- a/src/libnotify/xcodeconfig/notifyutil.xcconfig +++ /dev/null @@ -1,4 +0,0 @@ -#include "base.xcconfig" - -INSTALL_PATH = /usr/bin - diff --git a/src/libnotify/xcodescripts/no-sim-man.sh b/src/libnotify/xcodescripts/no-sim-man.sh deleted file mode 100644 index 773350da4..000000000 --- a/src/libnotify/xcodescripts/no-sim-man.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -ex - -if [[ "${PLATFORM_NAME}" =~ "simulator" ]]; then - rm -rf ${DSTROOT}/usr/share/man -fi diff --git a/src/libnotify/xcodescripts/sim-compat-symlink.sh b/src/libnotify/xcodescripts/sim-compat-symlink.sh deleted file mode 100644 index a837bff4b..000000000 --- a/src/libnotify/xcodescripts/sim-compat-symlink.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -ex - -if [[ "${PLATFORM_NAME}" =~ "simulator" ]]; then - ln -s libsystem_notify.dylib ${DSTROOT}${INSTALL_PATH}/libnotify_sim.dylib -fi diff --git a/src/libnotify/xctests/Info.plist b/src/libnotify/xctests/Info.plist deleted file mode 100644 index 6c40a6cd0..000000000 --- a/src/libnotify/xctests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/src/libnotify/xctests/RegisterTests.m b/src/libnotify/xctests/RegisterTests.m deleted file mode 100644 index 2b3fb76d5..000000000 --- a/src/libnotify/xctests/RegisterTests.m +++ /dev/null @@ -1,162 +0,0 @@ -// -// xctests.m -// xctests -// - -#include -#include -#include -#include - -#include "notify_internal.h" - -#import - -@interface RegisterTests : XCTestCase - -@end - -@implementation RegisterTests - -static dispatch_queue_t noteQueue; - -+ (void)setUp -{ - noteQueue = dispatch_queue_create("noteQ", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); -} - -+ (void)tearDown -{ - noteQueue = nil; -} - -- (void)tearDown -{ - [super tearDown]; -} - -- (void)test00RegisterSimple -{ - static int token; - XCTAssert(notify_register_dispatch("com.example.test.simple", &token, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(token) == NOTIFY_STATUS_OK, @"notify_cancel failed"); -} - -- (void)test01RegisterNested -{ - for (int i = 0; i < 100000; i++) { - static int token1, token2; - XCTAssert(notify_register_dispatch("com.example.test.multiple", &token1, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_register_dispatch("com.example.test.multiple", &token2, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(token1) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - XCTAssert(notify_cancel(token2) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - } -} - -- (void)test02RegisterInterleaved -{ - for (int i = 0; i < 100000; i++) { - static int token1, token2; - XCTAssert(notify_register_dispatch("com.example.test.interleaved", &token1, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(token1) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - XCTAssert(notify_register_dispatch("com.example.test.interleaved", &token2, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(token2) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - } -} - -- (void)test03RegisterRaceWithDealloc -{ - static int tokens[1000000]; - dispatch_apply(1000000, DISPATCH_APPLY_AUTO, ^(size_t i) { - XCTAssert(notify_register_check("com.example.test.race", &tokens[i]) == NOTIFY_STATUS_OK, @"notify_register_check failed"); - XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - XCTAssert(notify_register_dispatch("com.example.test.race", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - XCTAssert(notify_post("com.example.test.race") == NOTIFY_STATUS_OK, @"notify_post failed"); - }); -} - -- (void)test04RegisterManyTokens -{ - static int tokens[100000]; - dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) { - XCTAssert(notify_register_dispatch("com.example.test.many", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - }); -} - -- (void)test05RegisterBulkCancel -{ - static int tokens[100000]; - dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) { - XCTAssert(notify_register_dispatch("com.example.test.bulk", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - }); - - dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) { - XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - }); -} - -- (void)test06RegisterSimpleSelf -{ - static int token; - XCTAssert(notify_register_dispatch("self.example.test.simple", &token, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(token) == NOTIFY_STATUS_OK, @"notify_cancel failed"); -} - -- (void)test07RegisterNestedSelf -{ - for (int i = 0; i < 100000; i++) { - static int token1, token2; - XCTAssert(notify_register_dispatch("self.example.test.multiple", &token1, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_register_dispatch("self.example.test.multiple", &token2, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(token1) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - XCTAssert(notify_cancel(token2) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - } -} - -- (void)test08RegisterInterleavedSelf -{ - for (int i = 0; i < 100000; i++) { - static int token1, token2; - XCTAssert(notify_register_dispatch("self.example.test.interleaved", &token1, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(token1) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - XCTAssert(notify_register_dispatch("self.example.test.interleaved", &token2, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(token2) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - } -} - -- (void)test09RegisterRaceWithDeallocSelf -{ - static int tokens[1000000]; - dispatch_apply(1000000, DISPATCH_APPLY_AUTO, ^(size_t i) { - XCTAssert(notify_register_check("self.example.test.race", &tokens[i]) == NOTIFY_STATUS_OK, @"notify_register_check failed"); - XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - XCTAssert(notify_register_dispatch("self.example.test.race", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - XCTAssert(notify_post("com.example.test.race") == NOTIFY_STATUS_OK, @"notify_post failed"); - }); -} - -- (void)test10RegisterManyTokensSelf -{ - static int tokens[100000]; - dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) { - XCTAssert(notify_register_dispatch("self.example.test.many", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - }); -} - -- (void)test11RegisterBulkCancelSelf -{ - static int tokens[100000]; - dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) { - XCTAssert(notify_register_dispatch("self.example.test.bulk", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed"); - }); - - dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) { - XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed"); - }); -} - -@end From 5ebab950e5416a71e14e38b0cdf4f00cc7be92b5 Mon Sep 17 00:00:00 2001 From: Thomas A Date: Sat, 23 Apr 2022 14:15:38 -0700 Subject: [PATCH 2/3] Add `libnotify` Submodule --- .gitmodules | 3 +++ src/external/libnotify | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/external/libnotify diff --git a/.gitmodules b/.gitmodules index 6f86690e2..51a76dc1a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -387,3 +387,6 @@ [submodule "src/external/AvailabilityVersions"] path = src/external/AvailabilityVersions url = ../darling-AvailabilityVersions +[submodule "src/external/libnotify"] + path = src/external/libnotify + url = ../darling-Libnotify.git diff --git a/src/external/libnotify b/src/external/libnotify new file mode 160000 index 000000000..2526674fb --- /dev/null +++ b/src/external/libnotify @@ -0,0 +1 @@ +Subproject commit 2526674fb546303a1190126226370e35c174893a From 3bf299239de55d61da7fa97d4dcc86f64ffe2ffa Mon Sep 17 00:00:00 2001 From: Thomas A Date: Sat, 23 Apr 2022 15:31:40 -0700 Subject: [PATCH 3/3] Fix Building libnotify --- .../Developer/SDKs/MacOSX.sdk/usr/include/notify.h | 2 +- .../Developer/SDKs/MacOSX.sdk/usr/include/notify_keys.h | 2 +- Developer/symlinks.sh | 2 +- cmake/use_ld64.cmake | 2 +- src/CMakeLists.txt | 2 +- src/external/libnotify | 2 +- src/external/libsystem | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/notify.h b/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/notify.h index 9b8390416..335043c19 120000 --- a/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/notify.h +++ b/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/notify.h @@ -1 +1 @@ -../../../../../../../../src/libnotify/notify.h \ No newline at end of file +../../../../../../../../src/external/libnotify/notify.h \ No newline at end of file diff --git a/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/notify_keys.h b/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/notify_keys.h index c033c9f8e..f0c6121ee 120000 --- a/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/notify_keys.h +++ b/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/notify_keys.h @@ -1 +1 @@ -../../../../../../../../src/libnotify/notify_keys.h \ No newline at end of file +../../../../../../../../src/external/libnotify/notify_keys.h \ No newline at end of file diff --git a/Developer/symlinks.sh b/Developer/symlinks.sh index ac82b2651..5974aaab1 100755 --- a/Developer/symlinks.sh +++ b/Developer/symlinks.sh @@ -24,7 +24,7 @@ ln -sf "$BUILD/src/kernel/libsystem_kernel.dylib" "$LIBS/system" ln -sf "$BUILD/src/keymgr/libkeymgr.dylib" "$LIBS/system" ln -sf "$BUILD/src/libm/libsystem_m.dylib" "$LIBS/system" ln -sf "$BUILD/src/libinfo/libsystem_info.dylib" "$LIBS/system" -ln -sf "$BUILD/src/libnotify/libsystem_notify.dylib" "$LIBS/system" +ln -sf "$BUILD/src/external/libnotify/libsystem_notify.dylib" "$LIBS/system" ln -sf "$BUILD/src/external/libdispatch/libdispatch.dylib" "$LIBS/system" ln -sf "$BUILD/src/external/compiler-rt/lib/builtins/libcompiler_rt.dylib" "$LIBS/system" ln -sf "$BUILD/src/libunwind/libunwind.dylib" "$LIBS/system" diff --git a/cmake/use_ld64.cmake b/cmake/use_ld64.cmake index 9b2c3570e..2357bb7ac 100644 --- a/cmake/use_ld64.cmake +++ b/cmake/use_ld64.cmake @@ -23,7 +23,7 @@ FUNCTION(use_ld64 target) -Wl,-dylib_file,/usr/lib/system/libremovefile.dylib:${CMAKE_BINARY_DIR}/src/libremovefile/libremovefile.dylib \ -Wl,-dylib_file,/usr/lib/system/libcopyfile.dylib:${CMAKE_BINARY_DIR}/src/copyfile/libcopyfile.dylib \ -Wl,-dylib_file,/usr/lib/system/libsystem_coreservices.dylib:${CMAKE_BINARY_DIR}/src/libsystem_coreservices/libsystem_coreservices.dylib \ --Wl,-dylib_file,/usr/lib/system/libsystem_notify.dylib:${CMAKE_BINARY_DIR}/src/libnotify/libsystem_notify_firstpass.dylib \ +-Wl,-dylib_file,/usr/lib/system/libsystem_notify.dylib:${CMAKE_BINARY_DIR}/src/external/libnotify/libsystem_notify_firstpass.dylib \ -Wl,-dylib_file,/usr/lib/system/libdispatch.dylib:${CMAKE_BINARY_DIR}/src/external/libdispatch/liblibdispatch_shared_firstpass.dylib \ -Wl,-dylib_file,/usr/lib/system/libmacho.dylib:${CMAKE_BINARY_DIR}/src/external/cctools/libmacho/libmacho_firstpass.dylib \ -Wl,-dylib_file,/usr/lib/system/libsystem_sandbox.dylib:${CMAKE_BINARY_DIR}/src/sandbox/libsystem_sandbox.dylib \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 106ccb299..f3ec1fc5d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -138,7 +138,7 @@ add_subdirectory(networkextension) add_subdirectory(external/libsystem) add_subdirectory(libsystem_coreservices) add_subdirectory(libutil) -add_subdirectory(libnotify) +add_subdirectory(external/libnotify) add_subdirectory(libremovefile) add_subdirectory(launchd) add_subdirectory(keymgr) diff --git a/src/external/libnotify b/src/external/libnotify index 2526674fb..fac2a3b8c 160000 --- a/src/external/libnotify +++ b/src/external/libnotify @@ -1 +1 @@ -Subproject commit 2526674fb546303a1190126226370e35c174893a +Subproject commit fac2a3b8c585ada88b4a6a9a1e2b88b6a3782879 diff --git a/src/external/libsystem b/src/external/libsystem index 96ea4fd33..d9b57d9cb 160000 --- a/src/external/libsystem +++ b/src/external/libsystem @@ -1 +1 @@ -Subproject commit 96ea4fd335cdf6f82c439a105d4879e6f01a7622 +Subproject commit d9b57d9cbf1c3e61884ef16b6389f5eac7ff71ae