- APPLE PUBLIC SOURCE LICENSE
- Version 1.0 - March 16, 1999
+APPLE PUBLIC SOURCE LICENSE
+Version 2.0 - August 6, 2003
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.0 (or subsequent version thereof),
- as it may be revised from time to time by Apple ("License"). As
- used in this License:
-
-1.1 "Applicable Patents" mean: (a) in the case where Apple is the
- grantor of rights, (i) patents or patent applications that are now
- or hereafter acquired, owned by or assigned to Apple and (ii) whose
- claims 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) patents and patent applications that
- are now or hereafter acquired, owned by or assigned to You and (ii)
- whose claims cover subject matter in Your Modifications, taken alone
- or in combination with Original Code.
-
-1.2 "Covered Code" means the Original Code, Modifications, the
- combination of Original Code and any Modifications, and/or any
- respective portions thereof.
-
-1.3 "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.4 "Larger Work" means a work which combines Covered Code or portions
- thereof with code not governed by the terms of this License.
-
-1.5 "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.6 "Original Code" means 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.
-
-1.7 "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.8 "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 Patents 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) must notify Apple and other third parties of how to obtain Your
-Deployed Modifications by filling out and submitting the required
-information found at
-http://www.apple.com/publicsource/modifications.html; 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 Patents 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 Patents 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 of the Original Code becomes the subject of
- a claim of infringement ("Affected Original Code"), Apple may, at
- its sole discretion and option: (a) attempt to procure the rights
- necessary for You to continue using the Affected Original Code; (b)
- modify the Affected Original Code so that it is no longer
- infringing; or (c) terminate Your rights to use the Affected
- Original Code, 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.
-
-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.
+By downloading or 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") makes publicly available 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 2.0 ("License"). As used in
+this License:
+
+1.1 "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.2 "Contributor" means any person or entity that creates or
+contributes to the creation of Modifications.
+
+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 "Externally Deploy" means: (a) to sublicense, distribute or
+otherwise make Covered Code available, directly or indirectly, to
+anyone other than You; and/or (b) to use Covered Code, alone or as
+part of a Larger Work, in any way to provide a service, including but
+not limited to delivery of content, through electronic communication
+with a client other than You.
+
+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 the Original Code, any previous
+Modifications, the combination of Original Code and any previous
+Modifications, and/or any respective portions thereof. 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 Unmodified Code. You may use, reproduce, display, perform,
+internally distribute within Your organization, and Externally Deploy
+verbatim, unmodified copies of the Original Code, for commercial or
+non-commercial purposes, provided that in each instance:
+
+(a) You must 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; and
+
+(b) You must include a copy of this License with every copy of Source
+Code of Covered Code and documentation You distribute or Externally
+Deploy, 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.
+
+2.2 Modified Code. You may modify Covered Code and use, reproduce,
+display, perform, internally distribute within Your organization, and
+Externally Deploy Your Modifications and Covered Code, for commercial
+or non-commercial purposes, provided that in each instance You also
+meet all of these conditions:
+
+(a) You must satisfy all the conditions of Section 2.1 with respect to
+the Source Code of the Covered Code;
+
+(b) You must duplicate, to the extent it does not already exist, the
+notice in Exhibit A in each file of the Source Code of all Your
+Modifications, and cause the modified files to carry prominent notices
+stating that You changed the files and the date of any change; and
+
+(c) If You Externally Deploy Your Modifications, You must make
+Source Code of all Your Externally Deployed Modifications either
+available to those to whom You have Externally Deployed Your
+Modifications, or publicly available. Source Code of Your Externally
+Deployed Modifications must be released under the terms set forth in
+this License, including the license grants set forth in Section 3
+below, for as long as you Externally Deploy the Covered Code or twelve
+(12) months from the date of initial External Deployment, whichever is
+longer. You should preferably distribute the Source Code of Your
+Externally Deployed Modifications electronically (e.g. download from a
+web site).
+
+2.3 Distribution of Executable Versions. In addition, if You
+Externally Deploy Covered Code (Original Code and/or Modifications) in
+object code, executable form only, You must 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.
+
+2.4 Third Party Rights. You expressly acknowledge and agree that
+although Apple and each Contributor grants the licenses to their
+respective portions of the Covered Code set forth herein, no
+assurances are provided by Apple or any Contributor that the Covered
+Code does not infringe the patent or other intellectual property
+rights of any other entity. Apple and each Contributor disclaim any
+liability to You for claims brought by any other entity based on
+infringement of intellectual property rights or otherwise. As a
+condition to exercising the rights and licenses granted hereunder, You
+hereby assume sole responsibility to secure any other intellectual
+property rights needed, if any. For example, if a third party patent
+license is required to allow You to distribute the Covered Code, it is
+Your responsibility to acquire that license before distributing the
+Covered Code.
+
+3. Your Grants. In consideration of, and as a condition to, the
+licenses granted to You under this License, You hereby grant to any
+person or entity receiving or distributing Covered Code under this
+License a non-exclusive, royalty-free, perpetual, irrevocable license,
+under Your Applicable Patent Rights and other intellectual property
+rights (other than patent) owned or controlled by You, to use,
+reproduce, display, perform, modify, sublicense, distribute and
+Externally Deploy Your Modifications of the same scope and extent as
+Apple's licenses under Sections 2.1 and 2.2 above.
+
+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 or any Contributor. 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 and every Contributor harmless for any liability
+incurred by or claims asserted against Apple or such Contributor 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 Covered Code may contain in whole or in
+part pre-release, untested, or not fully tested works. The Covered
+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 Covered Code, or any portion thereof, is at
+Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
+WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
+APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
+PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
+ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
+MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
+PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
+PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
+INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
+FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
+THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
+ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
+ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
+AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
+You acknowledge that the Covered 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 Covered Code could lead to death, personal injury, or severe
+physical or environmental damage.
+
+9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
+EVENT SHALL APPLE OR ANY CONTRIBUTOR 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 COVERED CODE, OR
+ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
+TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
+APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
+REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
+TO YOU. In no event shall Apple's total liability to You for all
+damages (other than as may be required by applicable law) 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", "Mac OS",
+"QuickTime", "QuickTime Streaming Server" or any other trademarks,
+service marks, logos or trade names belonging to Apple (collectively
+"Apple Marks") or to any trademark, service mark, logo or trade name
+belonging to any Contributor. You agree not to use any Apple Marks in
+or as part of the name of products derived from the Original Code or
+to endorse or promote products derived from the Original Code other
+than as expressly 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. Subject to the licenses granted under this License,
+each Contributor retains all rights, title and interest in and to any
+Modifications made by such Contributor. 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.
12. Termination.
-12.1 Termination. This License and the rights granted hereunder will
- terminate:
+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 Sections 9.1 and/or 13.6(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 and
- distribution of the Covered Code, or Affected Original Code in the
- case of termination under Section 9.1, and to destroy all copies of
- the Covered Code or Affected Original Code (in the case of
- termination under Section 9.1) 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 Export Law Assurances. You may not use or otherwise export or
- re-export the Original Code except as authorized by United States
- law and the laws of the jurisdiction in which the Original Code was
- obtained. In particular, but without limitation, the Original Code
- may not be exported or re-exported (a) into (or to a national or
- resident of) any U.S. embargoed country or (b) to anyone on the
- U.S. Treasury Department's list of Specially Designated Nationals
- or the U.S. Department of Commerce's Table of Denial Orders. By
- using the Original Code, You represent and warrant that You are not
- located in, under control of, or a national or resident of any such
- country or on any such list.
-
-13.2 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.3 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.4 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.5 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.6 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.7 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.8 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.
+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; provided that Apple did not first commence
+an action for patent infringement against You in that instance.
+
+12.2 Effect of Termination. Upon termination, You agree to immediately
+stop any further use, reproduction, modification, sublicensing and
+distribution of the Covered Code. 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. No party will be liable to any 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
+any 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 or among You, Apple or any Contributor, 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 or any Contributor 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
parties ont exige que le present contrat et tous les documents
connexes soient rediges en anglais.
-EXHIBIT A.
+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.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.apple.com/publicsource and read it before using
-this file.
+"Portions Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
-License for the specific language governing rights and limitations
-under the License."
+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."
PROJECTVERSION = 2.8
PROJECT_TYPE = Aggregate
-TOOLS = ac.tproj accton.tproj arch.tproj at.tproj atrun.tproj\
- auditd.tproj audit.tproj chkpasswd.tproj chpass.tproj dmesg.tproj\
- dynamic_pager.tproj getty.tproj hostinfo.tproj init.tproj\
- iostat.tproj kgmon.tproj ktrace.tproj login.tproj mach_init.tproj\
- makekey.tproj mkfile.tproj nvram.tproj passwd.tproj pwd_mkdb.tproj\
+TOOLS = dynamic_pager.tproj ac.tproj accton.tproj arch.tproj at.tproj\
+ atrun.tproj chkpasswd.tproj chpass.tproj dmesg.tproj\
+ getconf.tproj getty.tproj hostinfo.tproj iostat.tproj kgmon.tproj\
+ ktrace.tproj login.tproj makekey.tproj\
+ mkfile.tproj nvram.tproj passwd.tproj pwd_mkdb.tproj\
reboot.tproj shutdown.tproj sync.tproj sysctl.tproj\
update.tproj vipw.tproj zic.tproj zdump.tproj vm_stat.tproj\
zprint.tproj latency.tproj sc_usage.tproj fs_usage.tproj\
- kdump.tproj sadc.tproj sar.tproj
+ kdump.tproj sadc.tproj sar.tproj
LIBRARIES = dp_notify_lib
"PROJECT_HEADERS" = ();
"PUBLIC_HEADERS" = ();
SUBPROJECTS = (
+ "dynamic_pager.tproj",
+ "dp_notify_lib",
"ac.tproj",
"accton.tproj",
"arch.tproj",
"at.tproj",
- "atrun.tproj",
- "audit.tproj",
- "auditd.tproj",
+ "atrun.tproj",
"chkpasswd.tproj",
"chpass.tproj",
"dmesg.tproj",
- "dp_notify_lib",
- "dynamic_pager.tproj",
+ "getconf.tproj",
"getty.tproj",
"hostinfo.tproj",
- "init.tproj",
"iostat.tproj",
"kgmon.tproj",
"ktrace.tproj",
"login.tproj",
- "mach_init.tproj",
"makekey.tproj",
"mkfile.tproj",
"nologin.tproj",
"fs_usage.tproj",
"kdump.tproj",
"sadc.tproj",
- "sar.tproj" );
+ "sar.tproj"
+ );
};
LANGUAGE = English;
"LOCALIZABLE_FILES" = {};
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
PROJECT_HEADERS = privs.h pathnames.h
-NEXTSTEP_PB_CFLAGS += -D__FBSDID=__RCSID -DDAEMON_UID=1 -DDAEMON_GID=1 \
- -DDEFAULT_AT_QUEUE=\'a\' -DDEFAULT_BATCH_QUEUE=\'b\' \
- -DPERM_PATH=\"/var/at/\" -I/System/Library/Frameworks/System.framework/PrivateHeaders
-NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(NAME)/Build
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD
NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $Id: at.1,v 1.3.50.2 2005/01/18 22:17:28 asigel Exp $
+.\" $Id: at.1,v 1.3 2003/06/05 17:13:32 eseidel Exp $
.\"
.Dd December 5, 1993
.Dt "AT" 1
.Xr crond 8 ,
.Xr nice 1 ,
.Xr sh 1 ,
-.Xr compat 5 ,
.Xr atrun 8
.Sh AUTHOR
.Bl -tag
-/*
- * at.c : Put file into atrun queue
- * Copyright (C) 1993, 1994 Thomas Koenig
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
- * Atrun & Atq modifications
- * Copyright (C) 1993 David Parsons
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
+/*
+ * at.c : Put file into atrun queue
+ * Copyright (C) 1993 Thomas Koenig
+ *
+ * Atrun & Atq modifications
+ * Copyright (C) 1993 David Parsons
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/usr.bin/at/at.c,v 1.29 2002/07/22 11:32:16 robert Exp $");
-
#define _USE_BSD 1
/* System Headers */
-
-#include <sys/param.h>
+#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/time.h>
#include <sys/wait.h>
#include <ctype.h>
#include <dirent.h>
-#include <err.h>
#include <errno.h>
#include <fcntl.h>
-#ifndef __FreeBSD__
-#include <getopt.h>
-#endif
-#include <glob.h>
-#ifdef __FreeBSD__
-#include <locale.h>
-#endif
#include <pwd.h>
#include <signal.h>
#include <stddef.h>
#include <time.h>
#include <unistd.h>
-#define COMPAT_MODE(a,b) (0)
-
/* Local headers */
-
#include "at.h"
#include "panic.h"
#include "parsetime.h"
#include "pathnames.h"
-#include "perm.h"
-
#define MAIN
#include "privs.h"
+#include "perm.h"
/* Macros */
-
-#ifndef ATJOB_DIR
-#define ATJOB_DIR _PATH_ATJOBS
-#endif
-
-#ifndef LFILE
-#define LFILE ATJOB_DIR ".lockfile"
-#endif
-
-#ifndef ATJOB_MX
-#define ATJOB_MX 255
-#endif
-
-#define ALARMC 10 /* Number of seconds to wait for timeout */
+#define ALARMC 10 /* Number of seconds to wait for timeout */
#define SIZE 255
#define TIMESIZE 50
-enum { ATQ, ATRM, AT, BATCH, CAT }; /* what program we want to run */
-
/* File scope variables */
-
-const char *no_export[] =
+static char rcsid[] = "$Id: at.c,v 1.2 2003/10/15 22:48:12 lindak Exp $";
+char *no_export[] =
{
- "TERM", "TERMCAP", "DISPLAY", "_"
-} ;
-static int send_mail = 0;
+ "TERM", "TERMCAP", "DISPLAY", "_"
+};
+static send_mail = 0;
/* External variables */
-
extern char **environ;
int fcreated;
-char atfile[] = ATJOB_DIR "12345678901234";
+char *namep;
+char atfile[FILENAME_MAX];
-char *atinput = (char*)0; /* where to get input from */
+char *atinput = (char *) 0; /* where to get input from */
char atqueue = 0; /* which queue to examine for jobs (atq) */
char atverify = 0; /* verify time instead of queuing job */
-char *namep;
-int posixly_correct; /* Behave as per POSIX */
-/* http://www.opengroup.org/onlinepubs/009695399/utilities/at.html */
/* Function declarations */
-
-static void sigc(int signo);
-static void alarmc(int signo);
-static char *cwdname(void);
-static void writefile(time_t runtimer, char queue);
-static void list_jobs(long *, int);
-static long nextjob(void);
-static time_t ttime(const char *arg);
-static int in_job_list(long, long *, int);
-static long *get_job_list(int, char *[], int *);
+static void sigc __P((int signo));
+static void alarmc __P((int signo));
+static char *cwdname __P((void));
+static void writefile __P((time_t runtimer, char queue));
+static void list_jobs __P((void));
/* Signal catching functions */
-static void sigc(int signo __unused)
+static void
+sigc(signo)
+ int signo;
{
-/* If the user presses ^C, remove the spool file and exit
+/* If the user presses ^C, remove the spool file and exit
*/
- if (fcreated)
- {
- PRIV_START
- unlink(atfile);
- PRIV_END
- }
+ if (fcreated) {
+ PRIV_START
+ unlink(atfile);
+ PRIV_END
+ }
- _exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
-static void alarmc(int signo __unused)
+static void
+alarmc(signo)
+ int signo;
{
- char buf[1024];
-
- /* Time out after some seconds. */
- strlcpy(buf, namep, sizeof(buf));
- strlcat(buf, ": file locking timed out\n", sizeof(buf));
- write(STDERR_FILENO, buf, strlen(buf));
- sigc(0);
+/* Time out after some seconds
+ */
+ panic("File locking timed out");
}
/* Local functions */
-static char *cwdname(void)
+static char *
+cwdname()
{
/* Read in the current directory; the name will be overwritten on
* subsequent calls.
*/
- static char *ptr = NULL;
- static size_t size = SIZE;
-
- if (ptr == NULL)
- if ((ptr = malloc(size)) == NULL)
- errx(EXIT_FAILURE, "virtual memory exhausted");
+ static char *ptr = NULL;
+ static size_t size = SIZE;
- while (1)
- {
if (ptr == NULL)
- panic("out of memory");
-
- if (getcwd(ptr, size-1) != NULL)
- return ptr;
-
- if (errno != ERANGE)
- perr("cannot get directory");
-
- free (ptr);
- size += SIZE;
- if ((ptr = malloc(size)) == NULL)
- errx(EXIT_FAILURE, "virtual memory exhausted");
- }
-}
+ ptr = (char *) malloc(size);
-static long
-nextjob()
-{
- long jobno;
- FILE *fid;
-
- if ((fid = fopen(ATJOB_DIR ".SEQ", "r+")) != (FILE*)0) {
- if (fscanf(fid, "%5lx", &jobno) == 1) {
- rewind(fid);
- jobno = (1+jobno) % 0xfffff; /* 2^20 jobs enough? */
- fprintf(fid, "%05lx\n", jobno);
+ while (1) {
+ if (ptr == NULL)
+ panic("Out of memory");
+
+ if (getcwd(ptr, size - 1) != NULL)
+ return ptr;
+
+ if (errno != ERANGE)
+ perr("Cannot get directory");
+
+ free(ptr);
+ size += SIZE;
+ ptr = (char *) malloc(size);
}
- else
- jobno = EOF;
- fclose(fid);
- return jobno;
- }
- else if ((fid = fopen(ATJOB_DIR ".SEQ", "w")) != (FILE*)0) {
- fprintf(fid, "%05lx\n", jobno = 1);
- fclose(fid);
- return 1;
- }
- return EOF;
}
static void
-writefile(time_t runtimer, char queue)
+writefile(runtimer, queue)
+ time_t runtimer;
+ char queue;
{
-/* This does most of the work if at or batch are invoked for writing a job.
- */
- long jobno;
- char *ap, *ppos, *mailname;
- struct passwd *pass_entry;
- struct stat statbuf;
- int fdes, lockdes, fd2;
- FILE *fp, *fpin;
- struct sigaction act;
- char **atenv;
- int ch;
- mode_t cmask;
- struct flock lock;
-
-#ifdef __FreeBSD__
- (void) setlocale(LC_TIME, "");
-#endif
-
-/* Install the signal handler for SIGINT; terminate after removing the
- * spool file if necessary
- */
- act.sa_handler = sigc;
- sigemptyset(&(act.sa_mask));
- act.sa_flags = 0;
-
- sigaction(SIGINT, &act, NULL);
-
- ppos = atfile + strlen(ATJOB_DIR);
-
- /* Loop over all possible file names for running something at this
- * particular time, see if a file is there; the first empty slot at any
- * particular time is used. Lock the file LFILE first to make sure
- * we're alone when doing this.
- */
-
- PRIV_START
-
- if ((lockdes = open(LFILE, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR)) < 0)
- perr("cannot open lockfile " LFILE);
-
- lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0;
- lock.l_len = 0;
-
- act.sa_handler = alarmc;
- sigemptyset(&(act.sa_mask));
- act.sa_flags = 0;
-
- /* Set an alarm so a timeout occurs after ALARMC seconds, in case
- * something is seriously broken.
- */
- sigaction(SIGALRM, &act, NULL);
- alarm(ALARMC);
- fcntl(lockdes, F_SETLKW, &lock);
- alarm(0);
-
- if ((jobno = nextjob()) == EOF)
- perr("cannot generate job number");
-
- sprintf(ppos, "%c%5lx%8lx", queue,
- jobno, (unsigned long) (runtimer/60));
-
- for(ap=ppos; *ap != '\0'; ap ++)
- if (*ap == ' ')
- *ap = '0';
-
- if (stat(atfile, &statbuf) != 0)
- if (errno != ENOENT)
- perr("cannot access " ATJOB_DIR);
-
- /* Create the file. The x bit is only going to be set after it has
- * been completely written out, to make sure it is not executed in the
- * meantime. To make sure they do not get deleted, turn off their r
- * bit. Yes, this is a kluge.
- */
- cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR);
- if ((fdes = creat(atfile, O_WRONLY)) == -1)
- perr("cannot create atjob file");
-
- if ((fd2 = dup(fdes)) <0)
- perr("error in dup() of job file");
-
- if(fchown(fd2, real_uid, real_gid) != 0)
- perr("cannot give away file");
-
- PRIV_END
-
- /* We no longer need suid root; now we just need to be able to write
- * to the directory, if necessary.
- */
-
- REDUCE_PRIV(DAEMON_UID, DAEMON_GID)
-
- /* We've successfully created the file; let's set the flag so it
- * gets removed in case of an interrupt or error.
- */
- fcreated = 1;
-
- /* Now we can release the lock, so other people can access it
- */
- lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = 0;
- lock.l_len = 0;
- fcntl(lockdes, F_SETLKW, &lock);
- close(lockdes);
-
- if((fp = fdopen(fdes, "w")) == NULL)
- panic("cannot reopen atjob file");
-
- /* Get the userid to mail to, first by trying getlogin(),
- * then from LOGNAME, finally from getpwuid().
- */
- mailname = getlogin();
- if (mailname == NULL)
- mailname = getenv("LOGNAME");
-
- if ((mailname == NULL) || (mailname[0] == '\0')
- || (strlen(mailname) >= MAXLOGNAME) || (getpwnam(mailname)==NULL))
- {
- pass_entry = getpwuid(real_uid);
- if (pass_entry != NULL)
- mailname = pass_entry->pw_name;
- }
-
- if (atinput != (char *) NULL)
- {
- fpin = freopen(atinput, "r", stdin);
- if (fpin == NULL)
- perr("cannot open input file");
- }
- fprintf(fp, "#!/bin/sh\n# atrun uid=%ld gid=%ld\n# mail %.*s %d\n",
- (long) real_uid, (long) real_gid, MAXLOGNAME - 1, mailname,
- send_mail);
-
- /* Write out the umask at the time of invocation
- */
- fprintf(fp, "umask %lo\n", (unsigned long) cmask);
-
- /* Write out the environment. Anything that may look like a
- * special character to the shell is quoted, except for \n, which is
- * done with a pair of "'s. Don't export the no_export list (such
- * as TERM or DISPLAY) because we don't want these.
- */
- for (atenv= environ; *atenv != NULL; atenv++)
- {
- int export = 1;
- char *eqp;
-
- eqp = strchr(*atenv, '=');
- if (ap == NULL)
- eqp = *atenv;
- else
- {
- size_t i;
- for (i=0; i<sizeof(no_export)/sizeof(no_export[0]); i++)
- {
- export = export
- && (strncmp(*atenv, no_export[i],
- (size_t) (eqp-*atenv)) != 0);
- }
- eqp++;
- }
+ /*
+ * This does most of the work if at or batch are invoked for
+ * writing a job.
+ */
+ int i;
+ char *ap, *ppos, *mailname;
+ struct passwd *pass_entry;
+ struct stat statbuf;
+ int fdes, lockdes, fd2;
+ FILE *fp, *fpin;
+ struct sigaction act;
+ char **atenv;
+ int ch;
+ mode_t cmask;
+ struct flock lock;
- if (export)
- {
- fwrite(*atenv, sizeof(char), eqp-*atenv, fp);
- for(ap = eqp;*ap != '\0'; ap++)
- {
- if (*ap == '\n')
- fprintf(fp, "\"\n\"");
- else
- {
- if (!isalnum(*ap)) {
- switch (*ap) {
- case '%': case '/': case '{': case '[':
- case ']': case '=': case '}': case '@':
- case '+': case '#': case ',': case '.':
- case ':': case '-': case '_':
- break;
- default:
- fputc('\\', fp);
- break;
- }
- }
- fputc(*ap, fp);
- }
- }
- fputs("; export ", fp);
- fwrite(*atenv, sizeof(char), eqp-*atenv -1, fp);
- fputc('\n', fp);
-
- }
- }
- /* Cd to the directory at the time and write out all the
- * commands the user supplies from stdin.
- */
- fprintf(fp, "cd ");
- for (ap = cwdname(); *ap != '\0'; ap++)
- {
- if (*ap == '\n')
- fprintf(fp, "\"\n\"");
- else
- {
- if (*ap != '/' && !isalnum(*ap))
- fputc('\\', fp);
-
- fputc(*ap, fp);
- }
- }
- /* Test cd's exit status: die if the original directory has been
- * removed, become unreadable or whatever
- */
- fprintf(fp, " || {\n\t echo 'Execution directory "
- "inaccessible' >&2\n\t exit 1\n}\n");
+ /*
+ * Install the signal handler for SIGINT; terminate after removing the
+ * spool file if necessary
+ */
+ act.sa_handler = sigc;
+ sigemptyset(&(act.sa_mask));
+ act.sa_flags = 0;
- while((ch = getchar()) != EOF)
- fputc(ch, fp);
+ sigaction(SIGINT, &act, NULL);
- fprintf(fp, "\n");
- if (ferror(fp))
- panic("output error");
-
- if (ferror(stdin))
- panic("input error");
+ (void)strlcpy(atfile, _PATH_ATJOBS, sizeof atfile);
+ ppos = atfile + strlen(_PATH_ATJOBS);
- fclose(fp);
+ /*
+ * Loop over all possible file names for running something at this
+ * particular time, see if a file is there; the first empty slot at
+ * any particular time is used. Lock the file _PATH_LOCKFILE first
+ * to make sure we're alone when doing this.
+ */
- /* Set the x bit so that we're ready to start executing
- */
+ PRIV_START
- if (fchmod(fd2, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
- perr("cannot give away file");
+ if ((lockdes = open(_PATH_LOCKFILE, O_WRONLY | O_CREAT, 0600)) < 0)
+ perr2("Cannot open lockfile ", _PATH_LOCKFILE);
- close(fd2);
- if (posixly_correct) {
- struct tm runtime;
- char timestr[TIMESIZE];
- runtime = *localtime(&runtimer);
- strftime(timestr, TIMESIZE, "%a %b %e %T %Y", &runtime);
- fprintf(stderr, "job %ld at %s\n", jobno, timestr);
- } else
- fprintf(stderr, "Job %ld will be executed using /bin/sh\n", jobno);
-}
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
-static int
-in_job_list(long job, long *joblist, int len)
-{
- int i;
+ act.sa_handler = alarmc;
+ sigemptyset(&(act.sa_mask));
+ act.sa_flags = 0;
- for (i = 0; i < len; i++)
- if (job == joblist[i])
- return 1;
+ /*
+ * Set an alarm so a timeout occurs after ALARMC seconds, in case
+ * something is seriously broken.
+ */
+ sigaction(SIGALRM, &act, NULL);
+ alarm(ALARMC);
+ fcntl(lockdes, F_SETLKW, &lock);
+ alarm(0);
+
+ for (i = 0; i < AT_MAXJOBS; i++) {
+ sprintf(ppos, "%c%8lx.%3x", queue,
+ (unsigned long) (runtimer / 60), i);
+ for (ap = ppos; *ap != '\0'; ap++)
+ if (*ap == ' ')
+ *ap = '0';
+
+ if (stat(atfile, &statbuf) != 0) {
+ if (errno == ENOENT)
+ break;
+ else
+ perr2("Cannot access ", _PATH_ATJOBS);
+ }
+ } /* for */
- return 0;
-}
+ if (i >= AT_MAXJOBS)
+ panic("Too many jobs already");
-static void
-list_one_job(char *name, long *joblist, int len, int *first)
-{
- struct stat buf;
- struct tm runtime;
- unsigned long ctm;
- char queue;
- long jobno;
- time_t runtimer;
- char timestr[TIMESIZE];
-
- if (stat(name, &buf) != 0)
- perr("cannot stat in " ATJOB_DIR);
-
- /* See it's a regular file and has its x bit turned on and
- * is the user's
- */
- if (!S_ISREG(buf.st_mode)
- || ((buf.st_uid != real_uid) && ! (real_uid == 0))
- || !(S_IXUSR & buf.st_mode || atverify))
- return;
-
- if(sscanf(name, "%c%5lx%8lx", &queue, &jobno, &ctm)!=3)
- return;
-
- /* If jobs are given, only list those jobs */
- if (joblist && !in_job_list(jobno, joblist, len))
- return;
-
- if (atqueue && (queue != atqueue))
- return;
-
- runtimer = 60*(time_t) ctm;
- runtime = *localtime(&runtimer);
- strftime(timestr, TIMESIZE, "%a %b %e %T %Y", &runtime);
- if (*first) {
- if (!posixly_correct)
- printf("Date\t\t\t\tOwner\t\tQueue\tJob#\n");
- *first=0;
- }
- if (posixly_correct)
- printf("%ld\t%s\n", jobno, timestr);
- else {
- struct passwd *pw = getpwuid(buf.st_uid);
-
- printf("%s\t%s\t%c%s\t%s\n",
- timestr,
- pw ? pw->pw_name : "???",
- queue,
- (S_IXUSR & buf.st_mode) ? "":"(done)",
- name);
- }
-}
+ /*
+ * Create the file. The x bit is only going to be set after it has
+ * been completely written out, to make sure it is not executed in
+ * the meantime. To make sure they do not get deleted, turn off
+ * their r bit. Yes, this is a kluge.
+ */
+ cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR);
+ if ((fdes = creat(atfile, O_WRONLY)) == -1)
+ perr("Cannot create atjob file");
-static void
-list_jobs(long *joblist, int len)
-{
- /* List all a user's jobs in the queue, by looping through ATJOB_DIR,
- * or everybody's if we are root
- */
- DIR *spool;
- struct dirent *dirent;
- int first=1;
-
-#ifdef __FreeBSD__
- (void) setlocale(LC_TIME, "");
-#endif
-
- PRIV_START
-
- if (chdir(ATJOB_DIR) != 0)
- perr("cannot change to " ATJOB_DIR);
-
- if (joblist) { /* Force order to match POSIX */
- char jobglob[32];
- glob_t g;
- int i;
+ if ((fd2 = dup(fdes)) < 0)
+ perr("Error in dup() of job file");
- sprintf(jobglob, "?%05lx*", joblist[0]);
- g.gl_offs = 0;
- glob(jobglob, GLOB_DOOFFS, NULL, &g);
- for (i = 1; i < len; i++) {
- sprintf(jobglob, "?%05lx*", joblist[i]);
- glob(jobglob, GLOB_DOOFFS | GLOB_APPEND, NULL, &g);
- }
- for (i = 0; i < g.gl_pathc; i++) {
- list_one_job(g.gl_pathv[i], joblist, len, &first);
- }
- globfree(&g);
- } else {
- if ((spool = opendir(".")) == NULL)
- perr("cannot open " ATJOB_DIR);
+ if (fchown(fd2, real_uid, -1) != 0)
+ perr("Cannot give away file");
+
+ PRIV_END
- /* Loop over every file in the directory
+ /*
+ * We no longer need suid root; now we just need to be able to
+ * write to the directory, if necessary.
*/
- while((dirent = readdir(spool)) != NULL) {
- list_one_job(dirent->d_name, joblist, len, &first);
- }
- closedir(spool);
- }
- PRIV_END
-}
-static void
-process_jobs(int argc, char **argv, int what)
-{
- /* Delete every argument (job - ID) given
- */
- int i;
- struct stat buf;
- DIR *spool;
- struct dirent *dirent;
- unsigned long ctm;
- char queue;
- long jobno;
+ REDUCE_PRIV(0);
- PRIV_START
+ /*
+ * We've successfully created the file; let's set the flag so it
+ * gets removed in case of an interrupt or error.
+ */
+ fcreated = 1;
- if (chdir(ATJOB_DIR) != 0)
- perr("cannot change to " ATJOB_DIR);
+ /* Now we can release the lock, so other people can access it */
+ lock.l_type = F_UNLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
+ fcntl(lockdes, F_SETLKW, &lock);
+ close(lockdes);
- if ((spool = opendir(".")) == NULL)
- perr("cannot open " ATJOB_DIR);
+ if ((fp = fdopen(fdes, "w")) == NULL)
+ panic("Cannot reopen atjob file");
- PRIV_END
+ /*
+ * Get the userid to mail to, first by trying getlogin(), which
+ * reads /etc/utmp, then from LOGNAME, finally from getpwuid().
+ */
+ mailname = getlogin();
+ if (mailname == NULL)
+ mailname = getenv("LOGNAME");
+
+ if ((mailname == NULL) || (mailname[0] == '\0')
+ || (strlen(mailname) > 8)) {
+ pass_entry = getpwuid(getuid());
+ if (pass_entry != NULL)
+ mailname = pass_entry->pw_name;
+ }
- /* Loop over every file in the directory
- */
- while((dirent = readdir(spool)) != NULL) {
+ if (atinput != (char *) NULL) {
+ fpin = freopen(atinput, "r", stdin);
+ if (fpin == NULL)
+ perr("Cannot open input file");
+ }
+ fprintf(fp, "#! /bin/sh\n# mail %8s %d\n", mailname, send_mail);
- PRIV_START
- if (stat(dirent->d_name, &buf) != 0)
- perr("cannot stat in " ATJOB_DIR);
- PRIV_END
+ /* Write out the umask at the time of invocation */
+ fprintf(fp, "umask %lo\n", (unsigned long) cmask);
- if(sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm)!=3)
- continue;
+ /*
+ * Write out the environment. Anything that may look like a special
+ * character to the shell is quoted, except for \n, which is done
+ * with a pair of "'s. Dont't export the no_export list (such as
+ * TERM or DISPLAY) because we don't want these.
+ */
+ for (atenv = environ; *atenv != NULL; atenv++) {
+ int export = 1;
+ char *eqp;
+
+ eqp = strchr(*atenv, '=');
+ if (ap == NULL)
+ eqp = *atenv;
+ else {
+ int i;
+
+ for (i = 0;i < sizeof(no_export) /
+ sizeof(no_export[0]); i++) {
+ export = export
+ && (strncmp(*atenv, no_export[i],
+ (size_t) (eqp - *atenv)) != 0);
+ }
+ eqp++;
+ }
- for (i=optind; i < argc; i++) {
- if (atoi(argv[i]) == jobno || strcmp(argv[i], dirent->d_name)==0) {
- if ((buf.st_uid != real_uid) && !(real_uid == 0))
- errx(EXIT_FAILURE, "%s: not owner", argv[i]);
- switch (what) {
- case ATRM:
+ if (export) {
+ fwrite(*atenv, sizeof(char), eqp - *atenv, fp);
+ for (ap = eqp; *ap != '\0'; ap++) {
+ if (*ap == '\n')
+ fprintf(fp, "\"\n\"");
+ else {
+ if (!isalnum(*ap))
+ fputc('\\', fp);
+
+ fputc(*ap, fp);
+ }
+ }
+ fputs("; export ", fp);
+ fwrite(*atenv, sizeof(char), eqp - *atenv - 1, fp);
+ fputc('\n', fp);
- PRIV_START
+ }
+ }
+ /*
+ * Cd to the directory at the time and write out all the commands
+ * the user supplies from stdin.
+ */
+ fprintf(fp, "cd %s\n", cwdname());
- if (unlink(dirent->d_name) != 0)
- perr(dirent->d_name);
+ while ((ch = getchar()) != EOF)
+ fputc(ch, fp);
- PRIV_END
+ fprintf(fp, "\n");
+ if (ferror(fp))
+ panic("Output error");
- break;
+ if (ferror(stdin))
+ panic("Input error");
- case CAT:
- {
- FILE *fp;
- int ch;
+ fclose(fp);
- PRIV_START
+ /*
+ * Set the x bit so that we're ready to start executing
+ */
+ if (fchmod(fd2, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
+ perr("Cannot give away file");
- fp = fopen(dirent->d_name,"r");
+ close(fd2);
+ fprintf(stderr, "Job %s will be executed using /bin/sh\n", ppos);
+}
- PRIV_END
+static void
+list_jobs()
+{
+ /*
+ * List all a user's jobs in the queue, by looping through
+ * _PATH_ATJOBS, or everybody's if we are root
+ */
+ struct passwd *pw;
+ DIR *spool;
+ struct dirent *dirent;
+ struct stat buf;
+ struct tm runtime;
+ unsigned long ctm;
+ char queue;
+ time_t runtimer;
+ char timestr[TIMESIZE];
+ int first = 1;
- if (!fp) {
- perr("cannot open file");
- }
- while((ch = getc(fp)) != EOF) {
- putchar(ch);
- }
- }
- break;
-
- default:
- errx(EXIT_FAILURE, "internal error, process_jobs = %d",
- what);
- }
- }
- }
- }
-} /* process_jobs */
+ PRIV_START
-#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
+ if (chdir(_PATH_ATJOBS) != 0)
+ perr2("Cannot change to ", _PATH_ATJOBS);
-static time_t
-ttime(const char *arg)
-{
- /*
- * This is pretty much a copy of stime_arg1() from touch.c. I changed
- * the return value and the argument list because it's more convenient
- * (IMO) to do everything in one place. - Joe Halpin
- */
- struct timeval tv[2];
- time_t now;
- struct tm *t;
- int yearset;
- char *p;
-
- if (gettimeofday(&tv[0], NULL))
- panic("Cannot get current time");
-
- /* Start with the current time. */
- now = tv[0].tv_sec;
- if ((t = localtime(&now)) == NULL)
- panic("localtime");
- /* [[CC]YY]MMDDhhmm[.SS] */
- if ((p = strchr(arg, '.')) == NULL)
- t->tm_sec = 0; /* Seconds defaults to 0. */
- else {
- if (strlen(p + 1) != 2)
- goto terr;
- *p++ = '\0';
- t->tm_sec = ATOI2(p);
- }
-
- yearset = 0;
- switch(strlen(arg)) {
- case 12: /* CCYYMMDDhhmm */
- t->tm_year = ATOI2(arg);
- t->tm_year *= 100;
- yearset = 1;
- /* FALLTHROUGH */
- case 10: /* YYMMDDhhmm */
- if (yearset) {
- yearset = ATOI2(arg);
- t->tm_year += yearset;
- } else {
- yearset = ATOI2(arg);
- t->tm_year = yearset + 2000;
+ if ((spool = opendir(".")) == NULL)
+ perr2("Cannot open ", _PATH_ATJOBS);
+
+ /* Loop over every file in the directory */
+ while ((dirent = readdir(spool)) != NULL) {
+ if (stat(dirent->d_name, &buf) != 0)
+ perr2("Cannot stat in ", _PATH_ATJOBS);
+
+ /*
+ * See it's a regular file and has its x bit turned on and
+ * is the user's
+ */
+ if (!S_ISREG(buf.st_mode)
+ || ((buf.st_uid != real_uid) && !(real_uid == 0))
+ || !(S_IXUSR & buf.st_mode || atverify))
+ continue;
+
+ if (sscanf(dirent->d_name, "%c%8lx", &queue, &ctm) != 2)
+ continue;
+
+ if (atqueue && (queue != atqueue))
+ continue;
+
+ runtimer = 60 * (time_t) ctm;
+ runtime = *localtime(&runtimer);
+ strftime(timestr, TIMESIZE, "%X %x", &runtime);
+ if (first) {
+ printf("Date\t\t\tOwner\tQueue\tJob#\n");
+ first = 0;
+ }
+ pw = getpwuid(buf.st_uid);
+
+ printf("%s\t%s\t%c%s\t%s\n",
+ timestr,
+ pw ? pw->pw_name : "???",
+ queue,
+ (S_IXUSR & buf.st_mode) ? "" : "(done)",
+ dirent->d_name);
}
- t->tm_year -= 1900; /* Convert to UNIX time. */
- /* FALLTHROUGH */
- case 8: /* MMDDhhmm */
- t->tm_mon = ATOI2(arg);
- --t->tm_mon; /* Convert from 01-12 to 00-11 */
- t->tm_mday = ATOI2(arg);
- t->tm_hour = ATOI2(arg);
- t->tm_min = ATOI2(arg);
- break;
- default:
- goto terr;
- }
-
- t->tm_isdst = -1; /* Figure out DST. */
- tv[0].tv_sec = tv[1].tv_sec = mktime(t);
- if (tv[0].tv_sec != -1)
- return tv[0].tv_sec;
- else
-terr:
- panic(
- "out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]");
+ PRIV_END
}
-static long *
-get_job_list(int argc, char *argv[], int *joblen)
+static void
+delete_jobs(argc, argv)
+ int argc;
+ char **argv;
{
- int i, len;
- long *joblist;
- char *ep;
-
- joblist = NULL;
- len = argc;
- if (len > 0) {
- if ((joblist = malloc(len * sizeof(*joblist))) == NULL)
- panic("out of memory");
-
- for (i = 0; i < argc; i++) {
- errno = 0;
- if ((joblist[i] = strtol(argv[i], &ep, 10)) < 0 ||
- ep == argv[i] || *ep != '\0' || errno)
- panic("invalid job number");
+ /* Delete every argument (job - ID) given */
+ int i;
+ struct stat buf;
+
+ PRIV_START
+
+ if (chdir(_PATH_ATJOBS) != 0)
+ perr2("Cannot change to ", _PATH_ATJOBS);
+
+ for (i = optind; i < argc; i++) {
+ if (stat(argv[i], &buf) != 0)
+ perr(argv[i]);
+ if ((buf.st_uid != real_uid) && !(real_uid == 0)) {
+ fprintf(stderr, "%s: Not owner\n", argv[i]);
+ exit(EXIT_FAILURE);
+ }
+ if (unlink(argv[i]) != 0)
+ perr(argv[i]);
}
- }
+ PRIV_END
+} /* delete_jobs */
- *joblen = len;
- return joblist;
-}
+/* Global functions */
int
-main(int argc, char **argv)
+main(argc, argv)
+ int argc;
+ char **argv;
{
- int c;
- char queue = DEFAULT_AT_QUEUE;
- char queue_set = 0;
- char *pgm;
-
- int program = AT; /* our default program */
- const char *options = "q:f:t:rmvldbc"; /* default options for at */
- time_t timer;
- long *joblist;
- int joblen;
-
- posixly_correct = COMPAT_MODE("bin/at", "Unix2003");
- joblist = NULL;
- joblen = 0;
- timer = -1;
- RELINQUISH_PRIVS
-
- /* Eat any leading paths
- */
- if ((pgm = strrchr(argv[0], '/')) == NULL)
- pgm = argv[0];
- else
- pgm++;
-
- namep = pgm;
-
- /* find out what this program is supposed to do
- */
- if (strcmp(pgm, "atq") == 0) {
- program = ATQ;
- options = "q:v";
- }
- else if (strcmp(pgm, "atrm") == 0) {
- program = ATRM;
- options = "";
- }
- else if (strcmp(pgm, "batch") == 0) {
- program = BATCH;
- options = "f:q:mv";
- }
-
- /* process whatever options we can process
- */
- opterr=1;
- while ((c=getopt(argc, argv, options)) != -1)
- switch (c) {
- case 'v': /* verify time settings */
- atverify = 1;
- break;
-
- case 'm': /* send mail when job is complete */
- send_mail = 1;
- break;
-
- case 'f':
- atinput = optarg;
- break;
-
- case 'q': /* specify queue */
- if (strlen(optarg) > 1)
- usage();
-
- atqueue = queue = *optarg;
- if (!(islower(queue)||isupper(queue)))
- usage();
-
- queue_set = 1;
- break;
-
- case 'd':
- warnx("-d is deprecated; use -r instead");
- /* fall through to 'r' */
-
- case 'r':
- if (program != AT)
- usage();
-
- program = ATRM;
- options = "";
- break;
-
- case 't':
- if (program != AT)
- usage();
- timer = ttime(optarg);
- break;
-
- case 'l':
- if (program != AT)
- usage();
-
- program = ATQ;
- options = "q:";
- break;
-
- case 'b':
- if (program != AT)
- usage();
-
- program = BATCH;
- options = "f:q:mv";
- break;
-
- case 'c':
- program = CAT;
- options = "";
- break;
-
- default:
- usage();
- break;
+ int c;
+ char queue = 'a';
+ char *pgm;
+
+ enum {
+ ATQ, ATRM, AT, BATCH
+ }; /* what program we want to run */
+ int program = AT; /* our default program */
+ char *options = "q:f:mv"; /* default options for at */
+ time_t timer;
+
+ RELINQUISH_PRIVS
+
+ /* Eat any leading paths */
+ if ((pgm = strrchr(argv[0], '/')) == NULL)
+ pgm = argv[0];
+ else
+ pgm++;
+
+ namep = pgm;
+
+ /* find out what this program is supposed to do */
+ if (strcmp(pgm, "atq") == 0) {
+ program = ATQ;
+ options = "q:v";
+ } else if (strcmp(pgm, "atrm") == 0) {
+ program = ATRM;
+ options = "";
+ } else if (strcmp(pgm, "batch") == 0) {
+ program = BATCH;
+ options = "f:mv";
}
- /* end of options eating
- */
- /* select our program
- */
- if(!check_permission())
- errx(EXIT_FAILURE, "you do not have permission to use this program");
- switch (program) {
- case ATQ:
-
- REDUCE_PRIV(DAEMON_UID, DAEMON_GID)
+ /* process whatever options we can process */
+ opterr = 1;
+ while ((c = getopt(argc, argv, options)) != EOF)
+ switch (c) {
+ case 'v': /* verify time settings */
+ atverify = 1;
+ break;
+
+ case 'm': /* send mail when job is complete */
+ send_mail = 1;
+ break;
+
+ case 'f':
+ atinput = optarg;
+ break;
+
+ case 'q': /* specify queue */
+ if (strlen(optarg) > 1)
+ usage();
+
+ atqueue = queue = *optarg;
+ if ((!islower(queue)) || (queue > 'l'))
+ usage();
+ break;
+
+ default:
+ usage();
+ break;
+ }
+ /* end of options eating */
- if (queue_set == 0)
- joblist = get_job_list(argc - optind, argv + optind, &joblen);
- list_jobs(joblist, joblen);
- break;
+ /* select our program */
+ if (!check_permission())
+ {
+ fprintf(stderr, "You do not have permission to use %s.\n",namep);
+ exit(EXIT_FAILURE);
+ }
+ switch (program) {
+ case ATQ:
- case ATRM:
+ REDUCE_PRIV(0);
- REDUCE_PRIV(DAEMON_UID, DAEMON_GID)
+ list_jobs();
+ break;
- process_jobs(argc, argv, ATRM);
- break;
+ case ATRM:
- case CAT:
+ REDUCE_PRIV(0);
- process_jobs(argc, argv, CAT);
- break;
+ delete_jobs(argc, argv);
+ break;
- case AT:
- /*
- * If timer is > -1, then the user gave the time with -t. In that
- * case, it's already been set. If not, set it now.
- */
- if (timer == -1)
- timer = parsetime(argc, argv);
+ case AT:
+ timer = parsetime(argc, argv);
+ if (atverify) {
+ struct tm *tm = localtime(&timer);
- if (atverify)
- {
- struct tm *tm = localtime(&timer);
- fprintf(stderr, "%s\n", asctime(tm));
- }
- writefile(timer, queue);
- break;
+ fprintf(stderr, "%s\n", asctime(tm));
+ }
+ writefile(timer, queue);
+ break;
- case BATCH:
- if (queue_set)
- queue = toupper(queue);
- else
- queue = DEFAULT_BATCH_QUEUE;
+ case BATCH:
+ writefile(time(NULL), 'b');
+ break;
- if (argc > optind)
- timer = parsetime(argc, argv);
- else
- timer = time(NULL);
-
- if (atverify)
- {
- struct tm *tm = localtime(&timer);
- fprintf(stderr, "%s\n", asctime(tm));
+ default:
+ panic("Internal error");
+ break;
}
-
- writefile(timer, queue);
- break;
-
- default:
- panic("internal error");
- break;
- }
- exit(EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
}
-/*
- * at.h - header for at(1)
- * Copyright (C) 1993 Thomas Koenig
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
+/*
+ * at.h - header for at(1)
+ * Copyright (c) 1993 by Thomas Koenig
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/usr.bin/at/at.h,v 1.5 2001/07/24 14:15:51 obrien Exp $
+ * $Id: at.h,v 1.1.1.2 2000/01/11 02:10:05 wsanchez Exp $
*/
extern int fcreated;
extern char *namep;
extern char atfile[];
extern char atverify;
+
+#define AT_MAXJOBS 255 /* max jobs outstanding per user */
-/*
- * panic.c - terminate fast in case of error
- * Copyright (C) 1993 Thomas Koenig
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
+/*
+ * panic.c - terminate fast in case of error
+ * Copyright (c) 1993 by Thomas Koenig
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/usr.bin/at/panic.c,v 1.17 2002/05/16 00:47:14 tjr Exp $");
-
/* System Headers */
-#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
/* Local headers */
#include "panic.h"
-#include "privs.h"
#include "at.h"
+/* File scope variables */
+
+static char rcsid[] = "$Id: panic.c,v 1.1.1.2 2000/01/11 02:10:05 wsanchez Exp $";
+
/* External variables */
/* Global functions */
+#ifdef __APPLE__
+__private_extern__
+#endif
void
-panic(const char *a)
+panic(a)
+ char *a;
{
/* Something fatal has happened, print error message and exit.
*/
- if (fcreated) {
- PRIV_START
+ fprintf(stderr, "%s: %s\n", namep, a);
+ if (fcreated)
unlink(atfile);
- PRIV_END
- }
- errx(EXIT_FAILURE, "%s", a);
+ exit(EXIT_FAILURE);
}
void
-perr(const char *a)
+perr(a)
+ char *a;
{
/* Some operating system error; print error message and exit.
*/
- int serrno = errno;
-
- if (fcreated) {
- PRIV_START
+ perror(a);
+ if (fcreated)
unlink(atfile);
- PRIV_END
- }
- errno = serrno;
- err(EXIT_FAILURE, "%s", a);
+ exit(EXIT_FAILURE);
+}
+
+void
+perr2(a, b)
+ char *a, *b;
+{
+ fprintf(stderr, "%s", a);
+ perr(b);
}
void
usage(void)
{
- /* Print usage and exit. */
- fprintf(stderr, "usage: at [-q x] [-f file] [-m] time\n"
- " at -c job [job ...]\n"
- " at [-f file] -t [[CC]YY]MMDDhhmm[.SS]\n"
- " at -r job [job ...]\n"
- " at -l -q queuename\n"
- " at -l [job ...]\n"
- " atq [-q x] [-v]\n"
- " atrm job [job ...]\n"
- " batch [-f file] [-m]\n");
- exit(EXIT_FAILURE);
+/* Print usage and exit.
+*/
+ fprintf(stderr, "Usage: at [-q x] [-f file] [-m] time\n"
+ " atq [-q x] [-v]\n"
+ " atrm [-q x] job ...\n"
+ " batch [-f file] [-m]\n");
+ exit(EXIT_FAILURE);
}
-/*
- * panic.h - header for at(1)
- * Copyright (C) 1993 Thomas Koenig
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
+/*
+ * panic.h - header for at(1)
+ * Copyright (c) 1993 Thomas Koenig
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/usr.bin/at/panic.h,v 1.6 2002/01/13 20:21:08 mike Exp $
+ * $Id: panic.h,v 1.1.1.2 2000/01/11 02:10:05 wsanchez Exp $
*/
-#include <sys/cdefs.h>
-
-void panic(const char *a) __dead2;
-void perr(const char *a) __dead2;
-void usage(void) __dead2;
+void panic __P((char *a));
+void perr __P((char *a));
+void perr2 __P((char *a, char *b));
+void usage __P((void));
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
/*
- * parsetime.c - parse time for at(1)
- * Copyright (C) 1993, 1994 Thomas Koenig
+ * parsetime.c - parse time for at(1)
+ * Copyright (C) 1993 Thomas Koenig
*
- * modifications for English-language times
- * Copyright (C) 1993 David Parsons
+ * modifications for english-language times
+ * Copyright (C) 1993 David Parsons
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* at [NOW] PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS
- * DOT ::= ':'|'.'
* /NUMBER [DOT NUMBER] [AM|PM]\ /[MONTH NUMBER [NUMBER]] \
* |NOON | |[TOMORROW] |
- * |MIDNIGHT | |[DAY OF WEEK] |
- * \TEATIME / |NUMBER [SLASH NUMBER [SLASH NUMBER]]|
- * \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/
+ * |MIDNIGHT | |NUMBER [SLASH NUMBER [SLASH NUMBER]]|
+ * \TEATIME / \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/
*/
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/usr.bin/at/parsetime.c,v 1.25 2001/12/10 21:13:01 dwmalone Exp $");
+/* $OpenBSD: parsetime.c,v 1.8 1999/03/21 04:04:42 alex Exp $ */
/* System Headers */
#include <sys/types.h>
-#include <ctype.h>
-#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <tzfile.h>
#include <unistd.h>
-#ifndef __FreeBSD__
-#include <getopt.h>
-#endif
+#include <ctype.h>
/* Local headers */
#include "at.h"
#include "panic.h"
-#include "parsetime.h"
/* Structures and unions */
enum { /* symbols */
MIDNIGHT, NOON, TEATIME,
PM, AM, TOMORROW, TODAY, NOW,
- MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEARS,
- NUMBER, PLUS, DOT, COMMA, SLASH, ID, JUNK,
+ MINUTES, HOURS, DAYS, WEEKS,
+ NUMBER, PLUS, DOT, SLASH, ID, JUNK,
JAN, FEB, MAR, APR, MAY, JUN,
- JUL, AUG, SEP, OCT, NOV, DEC,
- SUN, MON, TUE, WED, THU, FRI, SAT,
- UTC
- };
+ JUL, AUG, SEP, OCT, NOV, DEC
+};
-/* parse translation table - table driven parsers can be your FRIEND!
+/*
+ * parse translation table - table driven parsers can be your FRIEND!
*/
struct {
- const char *name; /* token name */
+ char *name; /* token name */
int value; /* token id */
- int plural; /* is this plural? */
} Specials[] = {
- { "midnight", MIDNIGHT,0 }, /* 00:00:00 of today or tomorrow */
- { "noon", NOON,0 }, /* 12:00:00 of today or tomorrow */
- { "teatime", TEATIME,0 }, /* 16:00:00 of today or tomorrow */
- { "am", AM,0 }, /* morning times for 0-12 clock */
- { "pm", PM,0 }, /* evening times for 0-12 clock */
- { "tomorrow", TOMORROW,0 }, /* execute 24 hours from time */
- { "today", TODAY, 0 }, /* execute today - don't advance time */
- { "now", NOW,0 }, /* opt prefix for PLUS */
-
- { "minute", MINUTES,0 }, /* minutes multiplier */
- { "minutes", MINUTES,1 }, /* (pluralized) */
- { "hour", HOURS,0 }, /* hours ... */
- { "hours", HOURS,1 }, /* (pluralized) */
- { "day", DAYS,0 }, /* days ... */
- { "days", DAYS,1 }, /* (pluralized) */
- { "week", WEEKS,0 }, /* week ... */
- { "weeks", WEEKS,1 }, /* (pluralized) */
- { "month", MONTHS,0 }, /* month ... */
- { "months", MONTHS,1 }, /* (pluralized) */
- { "year", YEARS,0 }, /* year ... */
- { "years", YEARS,1 }, /* (pluralized) */
- { "jan", JAN,0 },
- { "feb", FEB,0 },
- { "mar", MAR,0 },
- { "apr", APR,0 },
- { "may", MAY,0 },
- { "jun", JUN,0 },
- { "jul", JUL,0 },
- { "aug", AUG,0 },
- { "sep", SEP,0 },
- { "oct", OCT,0 },
- { "nov", NOV,0 },
- { "dec", DEC,0 },
- { "january", JAN,0 },
- { "february", FEB,0 },
- { "march", MAR,0 },
- { "april", APR,0 },
- { "may", MAY,0 },
- { "june", JUN,0 },
- { "july", JUL,0 },
- { "august", AUG,0 },
- { "september", SEP,0 },
- { "october", OCT,0 },
- { "november", NOV,0 },
- { "december", DEC,0 },
- { "sunday", SUN, 0 },
- { "sun", SUN, 0 },
- { "monday", MON, 0 },
- { "mon", MON, 0 },
- { "tuesday", TUE, 0 },
- { "tue", TUE, 0 },
- { "wednesday", WED, 0 },
- { "wed", WED, 0 },
- { "thursday", THU, 0 },
- { "thu", THU, 0 },
- { "friday", FRI, 0 },
- { "fri", FRI, 0 },
- { "saturday", SAT, 0 },
- { "sat", SAT, 0 },
- { "utc", UTC, 0 },
+ { "midnight", MIDNIGHT }, /* 00:00:00 of today or tomorrow */
+ { "noon", NOON }, /* 12:00:00 of today or tomorrow */
+ { "teatime", TEATIME }, /* 16:00:00 of today or tomorrow */
+ { "am", AM }, /* morning times for 0-12 clock */
+ { "pm", PM }, /* evening times for 0-12 clock */
+ { "tomorrow", TOMORROW }, /* execute 24 hours from time */
+ { "today", TODAY }, /* execute today - don't advance time */
+ { "now", NOW }, /* opt prefix for PLUS */
+
+ { "minute", MINUTES }, /* minutes multiplier */
+ { "min", MINUTES },
+ { "m", MINUTES },
+ { "minutes", MINUTES }, /* (pluralized) */
+ { "hour", HOURS }, /* hours ... */
+ { "hr", HOURS }, /* abbreviated */
+ { "h", HOURS },
+ { "hours", HOURS }, /* (pluralized) */
+ { "day", DAYS }, /* days ... */
+ { "d", DAYS },
+ { "days", DAYS }, /* (pluralized) */
+ { "week", WEEKS }, /* week ... */
+ { "w", WEEKS },
+ { "weeks", WEEKS }, /* (pluralized) */
+ { "jan", JAN },
+ { "feb", FEB },
+ { "mar", MAR },
+ { "apr", APR },
+ { "may", MAY },
+ { "jun", JUN },
+ { "jul", JUL },
+ { "aug", AUG },
+ { "sep", SEP },
+ { "oct", OCT },
+ { "nov", NOV },
+ { "dec", DEC }
} ;
/* File scope variables */
static int need; /* scanner - need to advance to next argument */
static char *sc_token; /* scanner - token buffer */
-static size_t sc_len; /* scanner - length of token buffer */
+static size_t sc_len; /* scanner - lenght of token buffer */
static int sc_tokid; /* scanner - token id */
-static int sc_tokplur; /* scanner - is token plural? */
+
+static char rcsid[] = "$Id: parsetime.c,v 1.2 2003/10/15 22:48:12 lindak Exp $";
/* Local functions */
* parse a token, checking if it's something special to us
*/
static int
-parse_token(char *arg)
+parse_token(arg)
+ char *arg;
{
- size_t i;
+ int i;
for (i=0; i<(sizeof Specials/sizeof Specials[0]); i++)
if (strcasecmp(Specials[i].name, arg) == 0) {
- sc_tokplur = Specials[i].plural;
return sc_tokid = Specials[i].value;
}
* init_scanner() sets up the scanner to eat arguments
*/
static void
-init_scanner(int argc, char **argv)
+init_scanner(argc, argv)
+ int argc;
+ char **argv;
{
scp = argv;
scc = argc;
need = 1;
sc_len = 1;
- while (argc-- > 0)
- sc_len += strlen(*argv++);
+ while (--argc > 0)
+ sc_len += strlen(*++argv);
- if ((sc_token = malloc(sc_len)) == NULL)
- errx(EXIT_FAILURE, "virtual memory exhausted");
+ sc_token = (char *) malloc(sc_len);
+ if (sc_token == NULL)
+ panic("Insufficient virtual memory");
} /* init_scanner */
/*
* token() fetches a token from the input stream
*/
static int
-token(void)
+token()
{
int idx;
while (1) {
memset(sc_token, 0, sc_len);
sc_tokid = EOF;
- sc_tokplur = 0;
idx = 0;
- /* if we need to read another argument, walk along the argument list;
+ /*
+ * if we need to read another argument, walk along the argument list;
* when we fall off the arglist, we'll just return EOF forever
*/
if (need) {
scc--;
need = 0;
}
- /* eat whitespace now - if we walk off the end of the argument,
+ /*
+ * eat whitespace now - if we walk off the end of the argument,
* we'll continue, which puts us up at the top of the while loop
* to fetch the next argument in
*/
continue;
}
- /* preserve the first character of the new token
+ /*
+ * preserve the first character of the new token
*/
sc_token[0] = *sct++;
- /* then see what it is
+ /*
+ * then see what it is
*/
if (isdigit(sc_token[0])) {
while (isdigit(*sct))
sc_token[++idx] = *sct++;
sc_token[++idx] = 0;
return sc_tokid = NUMBER;
- }
- else if (isalpha(sc_token[0])) {
+ } else if (isalpha(sc_token[0])) {
while (isalpha(*sct))
sc_token[++idx] = *sct++;
sc_token[++idx] = 0;
return sc_tokid = PLUS;
else if (sc_token[0] == '/')
return sc_tokid = SLASH;
- else if (sc_token[0] == ',')
- return sc_tokid = COMMA;
else
return sc_tokid = JUNK;
} /* while (1) */
* plonk() gives an appropriate error message if a token is incorrect
*/
static void
-plonk(int tok)
+plonk(tok)
+ int tok;
{
panic((tok == EOF) ? "incomplete time"
: "garbled time");
* expect() gets a token and dies most horribly if it's not the token we want
*/
static void
-expect(int desired)
+expect(desired)
+ int desired;
{
if (token() != desired)
plonk(sc_tokid); /* and we die here... */
} /* expect */
+/*
+ * dateadd() adds a number of minutes to a date. It is extraordinarily
+ * stupid regarding day-of-month overflow, and will most likely not
+ * work properly
+ */
+static void
+dateadd(minutes, tm)
+ int minutes;
+ struct tm *tm;
+{
+ /* increment days */
+
+ while (minutes > 24*60) {
+ minutes -= 24*60;
+ tm->tm_mday++;
+ }
+
+ /* increment hours */
+ while (minutes > 60) {
+ minutes -= 60;
+ tm->tm_hour++;
+ if (tm->tm_hour > 23) {
+ tm->tm_mday++;
+ tm->tm_hour = 0;
+ }
+ }
+
+ /* increment minutes */
+ tm->tm_min += minutes;
+
+ if (tm->tm_min > 59) {
+ tm->tm_hour++;
+ tm->tm_min -= 60;
+
+ if (tm->tm_hour > 23) {
+ tm->tm_mday++;
+ tm->tm_hour = 0;
+ }
+ }
+} /* dateadd */
+
+
/*
* plus() parses a now + time
*
- * at [NOW] PLUS NUMBER [MINUTES|HOURS|DAYS|WEEKS|MONTHS|YEARS]
+ * at [NOW] PLUS NUMBER [MINUTES|HOURS|DAYS|WEEKS]
*
*/
-
static void
-plus(struct tm *tm)
+plus(tm)
+ struct tm *tm;
{
int delay;
- int expectplur;
expect(NUMBER);
delay = atoi(sc_token);
- expectplur = (delay != 1) ? 1 : 0;
switch (token()) {
- case YEARS:
- tm->tm_year += delay;
- break;
- case MONTHS:
- tm->tm_mon += delay;
- break;
case WEEKS:
delay *= 7;
case DAYS:
- tm->tm_mday += delay;
- break;
+ delay *= 24;
case HOURS:
- tm->tm_hour += delay;
- break;
+ delay *= 60;
case MINUTES:
- tm->tm_min += delay;
- break;
- default:
- plonk(sc_tokid);
- break;
+ dateadd(delay, tm);
+ return;
}
-
- if (expectplur != sc_tokplur)
- warnx("pluralization is wrong");
-
- tm->tm_isdst = -1;
- if (mktime(tm) < 0)
- plonk(sc_tokid);
-
+ plonk(sc_tokid);
} /* plus */
/*
* tod() computes the time of day
- * [NUMBER [DOT NUMBER] [AM|PM]] [UTC]
+ * [NUMBER [DOT NUMBER] [AM|PM]]
*/
static void
-tod(struct tm *tm)
+tod(tm)
+ struct tm *tm;
{
int hour, minute = 0;
size_t tlen;
hour = atoi(sc_token);
tlen = strlen(sc_token);
- /* first pick out the time of day - if it's 4 digits, we assume
+ /*
+ * first pick out the time of day - if it's 4 digits, we assume
* a HHMM time, otherwise it's HH DOT MM time
*/
if (token() == DOT) {
if (minute > 59)
panic("garbled time");
token();
- }
- else if (tlen == 4) {
+ } else if (tlen == 4) {
minute = hour%100;
if (minute > 59)
- panic("garbled time");
+ panic("garbeld time");
hour = hour/100;
}
- /* check if an AM or PM specifier was given
+ /*
+ * check if an AM or PM specifier was given
*/
- switch (sc_tokid) {
- case AM:
- case PM:
+ if (sc_tokid == AM || sc_tokid == PM) {
if (hour > 12)
panic("garbled time");
- if (sc_tokid == PM) {
- if (hour != 12) /* 12:xx PM is 12:xx, not 24:xx */
- hour += 12;
- } else {
- if (hour == 12) /* 12:xx AM is 00:xx, not 12:xx */
- hour = 0;
- }
- if (UTC != token())
- break; /* else fallthrough */
-
- case UTC:
- hour += tm->tm_gmtoff/(60*60);
- while (hour < 0)
- hour += 24;
- minute += (tm->tm_gmtoff/60);
- while (minute < 0)
- minute += 60;
- tm->tm_gmtoff = 0;
- token();
- break;
- default:
- if (hour > 23)
- panic("garbled time");
- break;
- }
+ if (sc_tokid == PM)
+ hour += 12;
+ token();
+ } else if (hour > 23)
+ panic("garbled time");
- /* if we specify an absolute time, we don't want to bump the day even
+ /*
+ * if we specify an absolute time, we don't want to bump the day even
* if we've gone past that time - but if we're specifying a time plus
* a relative offset, it's okay to bump things
- * If minutes are the same assume tomorrow was meant
*/
- if ((sc_tokid == EOF || sc_tokid == PLUS) &&
- ((tm->tm_hour > hour) || ((tm->tm_hour == hour) && (tm->tm_min >= minute)))) {
+ if ((sc_tokid == EOF || sc_tokid == PLUS) && tm->tm_hour > hour)
tm->tm_mday++;
- tm->tm_wday++;
- }
tm->tm_hour = hour;
tm->tm_min = minute;
* assign_date() assigns a date, wrapping to next year if needed
*/
static void
-assign_date(struct tm *tm, long mday, long mon, long year)
+assign_date(tm, mday, mon, year)
+ struct tm *tm;
+ long mday, mon, year;
{
- /*
- * Convert year into tm_year format (year - 1900).
- * We may be given the year in 2 digit, 4 digit, or tm_year format.
- */
- if (year != -1) {
+ if (year > 99) {
if (year >= TM_YEAR_BASE)
- year -= TM_YEAR_BASE; /* convert from 4 digit year */
- else if (year < 100) {
- /* convert from 2 digit year */
- struct tm *lt;
- time_t now;
-
- time(&now);
- lt = localtime(&now);
-
- /* Convert to tm_year assuming current century */
- year += (lt->tm_year / 100) * 100;
-
- if (year == lt->tm_year - 1) year++;
- else if (year < lt->tm_year)
- year += 100; /* must be in next century */
- }
+ year -= TM_YEAR_BASE;
+ else
+ panic("garbled time");
+ } else if (year != -1) {
+ /*
+ * check if the specified year is in the current century.
+ * allow for one year of user error as many people will
+ * enter n - 1 at the start of year n.
+ */
+ if (year < tm->tm_year % 100 -1)
+ year += 100;
+ /* adjust fo the year 2000 and beyond */
+ year += tm->tm_year - (tm->tm_year % 100);
}
if (year < 0 &&
*
* /[<month> NUMBER [NUMBER]] \
* |[TOMORROW] |
- * |[DAY OF WEEK] |
* |NUMBER [SLASH NUMBER [SLASH NUMBER]]|
* \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/
*/
static void
-month(struct tm *tm)
+month(tm)
+ struct tm *tm;
{
- long year= (-1);
- long mday = 0, wday, mon;
- int tlen;
+ int year= (-1);
+ int mday, mon;
+ size_t tlen;
switch (sc_tokid) {
case PLUS:
case TOMORROW:
/* do something tomorrow */
tm->tm_mday ++;
- tm->tm_wday ++;
case TODAY: /* force ourselves to stay in today - no further processing */
token();
break;
case JAN: case FEB: case MAR: case APR: case MAY: case JUN:
case JUL: case AUG: case SEP: case OCT: case NOV: case DEC:
- /* do month mday [,year]
+ /*
+ * do month mday [year]
*/
mon = (sc_tokid-JAN);
expect(NUMBER);
mday = atol(sc_token);
- if (token() == COMMA) {
- if (token() == NUMBER) {
- year = atol(sc_token);
- token();
- }
+ if (token() == NUMBER) {
+ year = atol(sc_token);
+ token();
}
assign_date(tm, mday, mon, year);
- if (sc_tokid == PLUS)
- plus(tm);
- break;
-
- case SUN: case MON: case TUE:
- case WED: case THU: case FRI:
- case SAT:
- /* do a particular day of the week
- */
- wday = (sc_tokid-SUN);
-
- mday = tm->tm_mday;
-
- /* if this day is < today, then roll to next week
- */
- if (wday < tm->tm_wday)
- mday += 7 - (tm->tm_wday - wday);
- else
- mday += (wday - tm->tm_wday);
-
- tm->tm_wday = wday;
-
- assign_date(tm, mday, tm->tm_mon, tm->tm_year);
break;
case NUMBER:
- /* get numeric MMDDYY, mm/dd/yy, or dd.mm.yy
+ /*
+ * get numeric MMDDYY, mm/dd/yy, or dd.mm.yy
*/
tlen = strlen(sc_token);
mon = atol(sc_token);
token();
}
- /* flip months and days for European timing
+ /*
+ * flip months and days for european timing
*/
if (sep == DOT) {
int x = mday;
mday = mon;
mon = x;
}
- }
- else if (tlen == 6 || tlen == 8) {
+ } else if (tlen == 6 || tlen == 8) {
if (tlen == 8) {
year = (mon % 10000) - TM_YEAR_BASE;
mon /= 10000;
- }
- else {
+ } else {
year = mon % 100;
mon /= 100;
}
mday = mon % 100;
mon /= 100;
- }
- else
+ } else
panic("garbled time");
mon--;
/* Global functions */
time_t
-parsetime(int argc, char **argv)
+parsetime(argc, argv)
+ int argc;
+ char **argv;
{
-/* Do the argument parsing, die if necessary, and return the time the job
+/*
+ * Do the argument parsing, die if necessary, and return the time the job
* should be run.
*/
time_t nowtimer, runtimer;
init_scanner(argc-optind, argv+optind);
switch (token()) {
- case NOW:
- if (scc < 1) {
- return nowtimer;
- }
- /* now is optional prefix for PLUS tree */
+ case NOW: /* now is optional prefix for PLUS tree */
expect(PLUS);
case PLUS:
plus(&runtime);
month(&runtime);
break;
- /* evil coding for TEATIME|NOON|MIDNIGHT - we've initialised
+ /*
+ * evil coding for TEATIME|NOON|MIDNIGHT - we've initialised
* hr to zero up above, then fall into this case in such a
* way so we add +12 +4 hours to it for teatime, +12 hours
* to it for noon, and nothing at all for midnight, then
case NOON:
hr += 12;
case MIDNIGHT:
- if (runtime.tm_hour >= hr) {
+ if (runtime.tm_hour >= hr)
runtime.tm_mday++;
- runtime.tm_wday++;
- }
runtime.tm_hour = hr;
runtime.tm_min = 0;
token();
- /* FALLTHROUGH to month setting */
+ /* fall through to month setting */
default:
month(&runtime);
break;
} /* ugly case statement */
expect(EOF);
- /* adjust for daylight savings time
+ /*
+ * adjust for daylight savings time
*/
runtime.tm_isdst = -1;
runtimer = mktime(&runtime);
panic("garbled time");
if (nowtimer > runtimer)
- panic("trying to travel back in time");
+ panic("Trying to travel back in time");
return runtimer;
} /* parsetime */
-/*
- * at.h - header for at(1)
- * Copyright (C) 1993 Thomas Koenig
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
+/*
+ * at.h - header for at(1)
+ * Copyright (c) 1993 by Thomas Koenig
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: parsetime.h,v 1.1.1.2 2000/01/11 02:10:05 wsanchez Exp $
*/
-time_t parsetime(int argc, char **argv);
+time_t parsetime __P((int argc, char **argv));
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
/*
* perm.c - check user permission for at(1)
* Copyright (C) 1994 Thomas Koenig
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/usr.bin/at/perm.c,v 1.13 2001/12/10 21:13:01 dwmalone Exp $");
-
/* System Headers */
#include <sys/types.h>
-#include <err.h>
#include <errno.h>
#include <pwd.h>
#include <stddef.h>
/* Local headers */
-#include "at.h"
-#include "perm.h"
#include "privs.h"
+#include "at.h"
+#include "pathnames.h"
/* Macros */
/* Structures and unions */
+/* File scope variables */
+
+static char rcsid[] = "$Id: perm.c,v 1.1.1.2 2000/01/11 02:10:05 wsanchez Exp $";
+
/* Function declarations */
static int check_for_user(FILE *fp,const char *name);
int found = 0;
len = strlen(name);
- if ((buffer = malloc(len+2)) == NULL)
- errx(EXIT_FAILURE, "virtual memory exhausted");
+ if ((buffer = malloc(sizeof (char) * (len+2))) == NULL) {
+ fprintf(stderr, "malloc error!");
+ exit(EXIT_FAILURE);
+ }
while(fgets(buffer, len+2, fp) != NULL)
{
return found;
}
/* Global functions */
-int check_permission(void)
+int check_permission()
{
FILE *fp;
uid_t uid = geteuid();
return 1;
if ((pentry = getpwuid(uid)) == NULL)
- err(EXIT_FAILURE, "cannot access user database");
+ {
+ perror("Cannot access user database");
+ exit(EXIT_FAILURE);
+ }
PRIV_START
- fp=fopen(PERM_PATH "at.allow","r");
+ fp=fopen(_PATH_AT "at.allow","r");
PRIV_END
{
return check_for_user(fp, pentry->pw_name);
}
- else if (errno == ENOENT)
+ else
{
PRIV_START
- fp=fopen(PERM_PATH "at.deny", "r");
+ fp=fopen(_PATH_AT "at.deny", "r");
PRIV_END
{
return !check_for_user(fp, pentry->pw_name);
}
- else if (errno != ENOENT)
- warn("at.deny");
+ perror("at.deny");
}
- else
- warn("at.allow");
return 0;
}
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
/*
* perm.h - header for at(1)
* Copyright (C) 1994 Thomas Koenig
* THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/usr.bin/at/perm.h,v 1.4 2001/12/02 12:26:18 markm Exp $
*/
-int check_permission(void);
+int check_permission();
-/*
- * privs.h - header for privileged operations
- * Copyright (C) 1993 Thomas Koenig
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
+/*
+ * privs.h - header for privileged operations
+ * Copyright (c) 1993 by Thomas Koenig
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/usr.bin/at/privs.h,v 1.8 2001/09/04 16:15:51 ru Exp $
+ * $Id: privs.h,v 1.1.1.2 2000/01/11 02:10:05 wsanchez Exp $
*/
#ifndef _PRIVS_H
#include <unistd.h>
-/* Relinquish privileges temporarily for a setuid or setgid program
- * with the option of getting them back later. This is done by
- * utilizing POSIX saved user and group IDs. Call RELINQUISH_PRIVS once
- * at the beginning of the main program. This will cause all operations
+/* Relinquish privileges temporarily for a setuid program
+ * with the option of getting them back later. This is done by swapping
+ * the real and effective userid BSD style. Call RELINQUISH_PRIVS once
+ * at the beginning of the main program. This will cause all operatons
* to be executed with the real userid. When you need the privileges
- * of the setuid/setgid invocation, call PRIV_START; when you no longer
+ * of the setuid invocation, call PRIV_START; when you no longer
* need it, call PRIV_END. Note that it is an error to call PRIV_START
* and not PRIV_END within the same function.
*
- * Use RELINQUISH_PRIVS_ROOT(a,b) if your program started out running
+ * Use RELINQUISH_PRIVS_ROOT(a) if your program started out running
* as root, and you want to drop back the effective userid to a
* and the effective group id to b, with the option to get them back
* later.
*
* If you no longer need root privileges, but those of some other
- * userid/groupid, you can call REDUCE_PRIV(a,b) when your effective
+ * userid, you can call REDUCE_PRIV(a) when your effective
* is the user's.
*
* Problems: Do not use return between PRIV_START and PRIV_END; this
* It is NOT safe to call exec(), system() or popen() with a user-
* supplied program (i.e. without carefully checking PATH and any
* library load paths) with relinquished privileges; the called program
- * can acquire them just as easily. Set both effective and real userid
+ * can aquire them just as easily. Set both effective and real userid
* to the real userid before calling any of them.
*/
#endif
uid_t real_uid, effective_uid;
-#ifndef MAIN
-extern
-#endif
-gid_t real_gid, effective_gid;
-
#define RELINQUISH_PRIVS { \
real_uid = getuid(); \
effective_uid = geteuid(); \
- real_gid = getgid(); \
- effective_gid = getegid(); \
- setegid(real_gid); \
seteuid(real_uid); \
}
-#define RELINQUISH_PRIVS_ROOT(a, b) { \
+#define RELINQUISH_PRIVS_ROOT(a) { \
real_uid = (a); \
effective_uid = geteuid(); \
- real_gid = (b); \
- effective_gid = getegid(); \
- setegid(real_gid); \
seteuid(real_uid); \
}
#define PRIV_START { \
- if (seteuid(0)<0) perr("cannot regain privs"); \
- if (setegid(effective_gid)<0) perr("cannot reset gid"); \
- if (seteuid(effective_uid)<0) perr("cannot reset uid"); \
-}
+ seteuid(effective_uid);
-#define PRIV_END { \
- if (seteuid(0)<0) perr("cannot regain privs"); \
- if (setegid(real_gid)<0) perr("cannot reset gid"); \
- if (seteuid(real_uid)<0) perr("cannot reset uid"); \
+#define PRIV_END \
+ seteuid(real_uid); \
}
-#define REDUCE_PRIV(a, b) { \
- PRIV_START \
- effective_uid = (a); \
- effective_gid = (b); \
- setregid((gid_t)-1, effective_gid); \
- setreuid((uid_t)-1, effective_uid); \
- PRIV_END \
+#define REDUCE_PRIV(a) { \
+ seteuid(effective_uid); \
+ real_uid = effective_uid = (a); \
+ setuid(real_uid); \
}
#endif
CFILES = atrun.c
-OTHERSRCS = Makefile.preamble Makefile Makefile.dist atrun.8 Makefile.postamble
-
-NEXTSTEP_PB_CFLAGS += -DDAEMON_UID=1 -DDAEMON_GID=1
+OTHERSRCS = Makefile.preamble Makefile Makefile.dist atrun.8
MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
PROF_LIBS = $(LIBS)
-HEADER_PATHS = -I../at.tproj
+HEADER_PATHS = -I../at
NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+++ /dev/null
-after_install:
- mkdir -p $(DSTROOT)/usr/share/man/man8
- install -c -m 444 atrun.8 $(DSTROOT)/usr/share/man/man8
-/*
- * atrun.c - run jobs queued by at; run with root privileges.
- * Copyright (C) 1993, 1994 Thomas Koenig
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 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 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@
+ */
+/*
+ * atrun.c - run jobs queued by at; run with root privileges.
+ * Copyright (c) 1993 by Thomas Koenig
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD: src/libexec/atrun/atrun.c,v 1.18 2004/07/11 17:37:32 stefanf Exp $";
-#endif /* not lint */
-
/* System Headers */
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
-#include <sys/param.h>
-#include <ctype.h>
#include <dirent.h>
-#include <err.h>
-#include <grp.h>
+#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
#include <time.h>
#include <unistd.h>
-#include <utmp.h>
-#if 1
-#include <paths.h>
-#else
-#include <getopt.h>
-#endif
+#include <syslog.h>
-#if (MAXLOGNAME-1) > UT_NAMESIZE
-#define LOGNAMESIZE UT_NAMESIZE
-#else
-#define LOGNAMESIZE (MAXLOGNAME-1)
-#endif
+#include <paths.h>
/* Local headers */
#define MAIN
#include "privs.h"
#include "pathnames.h"
-/* Macros */
-
-#ifndef ATJOB_DIR
-#define ATJOB_DIR _PATH_ATJOBS
-#endif
-
-#ifndef ATSPOOL_DIR
-#define ATSPOOL_DIR _PATH_ATSPOOL
-#endif
-
-#ifndef LOADAVG_MX
-#define LOADAVG_MX 1.5
-#endif
+#include "atrun.h"
/* File scope variables */
-static int debug = 0;
-
-void perr(const char *a);
-static void usage(void);
+static char *namep;
+static char rcsid[] = "$Id: atrun.c,v 1.1.1.2 2000/01/11 02:10:06 wsanchez Exp $";
/* Local functions */
-static int
-write_string(int fd, const char* a)
+static void
+perr(a)
+ const char *a;
{
- return write(fd, a, strlen(a));
+ syslog(LOG_ERR, "%s: %m", a);
+ exit(EXIT_FAILURE);
}
-#undef DEBUG_FORK
-#ifdef DEBUG_FORK
-static pid_t
-myfork(void)
+static int
+write_string(fd, a)
+ int fd;
+ const char *a;
{
- pid_t res;
- res = fork();
- if (res == 0)
- kill(getpid(),SIGSTOP);
- return res;
+ return write(fd, a, strlen(a));
}
-#define fork myfork
-#endif
-
static void
-run_file(const char *filename, uid_t uid, gid_t gid)
+run_file(filename, uid, gid)
+ const char *filename;
+ uid_t uid;
+ gid_t gid;
{
-/* Run a file by spawning off a process which redirects I/O,
- * spawns a subshell, then waits for it to complete and sends
- * mail to the user.
- */
- pid_t pid;
- int fd_out, fd_in;
- int queue;
- char mailbuf[LOGNAMESIZE + 1], fmt[49];
- char *mailname = NULL;
- FILE *stream;
- int send_mail = 0;
- struct stat buf, lbuf;
- off_t size;
- struct passwd *pentry;
- int fflags;
- long nuid;
- long ngid;
-
-
- PRIV_START
-
- if (chmod(filename, S_IRUSR) != 0)
- {
- perr("cannot change file permissions");
- }
-
- PRIV_END
-
- pid = fork();
- if (pid == -1)
- perr("cannot fork");
-
- else if (pid != 0)
- return;
-
- /* Let's see who we mail to. Hopefully, we can read it from
- * the command file; if not, send it to the owner, or, failing that,
- * to root.
- */
-
- pentry = getpwuid(uid);
- if (pentry == NULL)
- {
- syslog(LOG_ERR,"Userid %lu not found - aborting job %s",
- (unsigned long) uid, filename);
- exit(EXIT_FAILURE);
- }
- PRIV_START
-
- stream=fopen(filename, "r");
-
- PRIV_END
-
-#ifdef __FreeBSD__
- if (pentry->pw_expire && time(NULL) >= pentry->pw_expire)
- {
- syslog(LOG_ERR, "Userid %lu is expired - aborting job %s",
- (unsigned long) uid, filename);
- exit(EXIT_FAILURE);
- }
-#endif
-
- if (stream == NULL)
- perr("cannot open input file");
-
- if ((fd_in = dup(fileno(stream))) <0)
- perr("error duplicating input file descriptor");
+ /*
+ * Run a file by by spawning off a process which redirects I/O,
+ * spawns a subshell, then waits for it to complete and spawns another
+ * process to send mail to the user.
+ */
+ pid_t pid;
+ int fd_out, fd_in;
+ int queue;
+ char mailbuf[9];
+ char *mailname = NULL;
+ FILE *stream;
+ int send_mail = 0;
+ struct stat buf;
+ off_t size;
+ struct passwd *pentry;
+ int fflags;
+
+ pid = fork();
+ if (pid == -1)
+ perr("Cannot fork");
+ else if (pid > 0)
+ return;
+
+ /*
+ * Let's see who we mail to. Hopefully, we can read it from the
+ * command file; if not, send it to the owner, or, failing that, to
+ * root.
+ */
- if (fstat(fd_in, &buf) == -1)
- perr("error in fstat of input file descriptor");
+ PRIV_START
- if (lstat(filename, &lbuf) == -1)
- perr("error in fstat of input file");
+ stream = fopen(filename, "r");
- if (S_ISLNK(lbuf.st_mode)) {
- syslog(LOG_ERR,"Symbolic link encountered in job %s - aborting",
- filename);
- exit(EXIT_FAILURE);
- }
- if ((lbuf.st_dev != buf.st_dev) || (lbuf.st_ino != buf.st_ino) ||
- (lbuf.st_uid != buf.st_uid) || (lbuf.st_gid != buf.st_gid) ||
- (lbuf.st_size!=buf.st_size)) {
- syslog(LOG_ERR,"Somebody changed files from under us for job %s - "
- "aborting",filename);
- exit(EXIT_FAILURE);
- }
- if (buf.st_nlink > 1) {
- syslog(LOG_ERR,"Someboy is trying to run a linked script for job %s",
- filename);
- exit(EXIT_FAILURE);
- }
- if ((fflags = fcntl(fd_in, F_GETFD)) <0)
- perr("error in fcntl");
+ PRIV_END
- fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);
+ if (stream == NULL)
+ perr("Cannot open input file");
- snprintf(fmt, sizeof(fmt),
- "#!/bin/sh\n# atrun uid=%%ld gid=%%ld\n# mail %%%ds %%d",
- LOGNAMESIZE);
- if (fscanf(stream, fmt, &nuid, &ngid, mailbuf, &send_mail) != 4) {
- syslog(LOG_ERR,"File %s is in wrong format - aborting", filename);
- exit(EXIT_FAILURE);
- }
- if (mailbuf[0] == '-') {
- syslog(LOG_ERR,"illegal mail name %s in %s",mailbuf,filename);
- exit(EXIT_FAILURE);
- }
- mailname = mailbuf;
- if (nuid != uid) {
- syslog(LOG_ERR,"Job %s - userid %ld does not match file uid %lu",
- filename, nuid, (unsigned long)uid);
- exit(EXIT_FAILURE);
- }
- if (ngid != gid) {
- syslog(LOG_ERR,"Job %s - groupid %ld does not match file gid %lu",
- filename, ngid, (unsigned long)gid);
- exit(EXIT_FAILURE);
- }
- fclose(stream);
- if (chdir(ATSPOOL_DIR) < 0)
- perr("cannot chdir to " ATSPOOL_DIR);
-
- /* Create a file to hold the output of the job we are about to run.
- * Write the mail header.
- */
- if((fd_out=open(filename,
- O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR)) < 0)
- perr("cannot create output file");
-
- write_string(fd_out, "Subject: Output from your job ");
- write_string(fd_out, filename);
- write_string(fd_out, "\n\n");
- fstat(fd_out, &buf);
- size = buf.st_size;
-
- close(STDIN_FILENO);
- close(STDOUT_FILENO);
- close(STDERR_FILENO);
-
- pid = fork();
- if (pid < 0)
- perr("error in fork");
-
- else if (pid == 0)
- {
- char *nul = NULL;
- char **nenvp = &nul;
-
- /* Set up things for the child; we want standard input from the input file,
- * and standard output and error sent to our output file.
- */
+ if ((fd_in = dup(fileno(stream))) < 0)
+ perr("Error duplicating input file descriptor");
- if (lseek(fd_in, (off_t) 0, SEEK_SET) < 0)
- perr("error in lseek");
+ if ((fflags = fcntl(fd_in, F_GETFD)) < 0)
+ perr("Error in fcntl");
- if (dup(fd_in) != STDIN_FILENO)
- perr("error in I/O redirection");
+ fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);
- if (dup(fd_out) != STDOUT_FILENO)
- perr("error in I/O redirection");
+ if (fscanf(stream, "#! /bin/sh\n# mail %8s %d", mailbuf, &send_mail) == 2) {
+ mailname = mailbuf;
+ } else {
+ pentry = getpwuid(uid);
+ if (pentry == NULL)
+ mailname = "root";
+ else
+ mailname = pentry->pw_name;
+ }
+ fclose(stream);
+ if (chdir(_PATH_ATSPOOL) < 0)
+ perr("Cannot chdir to " _PATH_ATSPOOL);
- if (dup(fd_out) != STDERR_FILENO)
- perr("error in I/O redirection");
+ /*
+ * Create a file to hold the output of the job we are about to
+ * run. Write the mail header.
+ */
+ if ((fd_out = open(filename,
+ O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR)) < 0)
+ perr("Cannot create output file");
- close(fd_in);
- close(fd_out);
- if (chdir(ATJOB_DIR) < 0)
- perr("cannot chdir to " ATJOB_DIR);
+ write_string(fd_out, "Subject: Output from your job ");
+ write_string(fd_out, filename);
+ write_string(fd_out, "\n\n");
+ fstat(fd_out, &buf);
+ size = buf.st_size;
- queue = *filename;
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
- PRIV_START
+ pid = fork();
+ if (pid < 0)
+ perr("Error in fork");
+ else if (pid == 0) {
+ char *nul = NULL;
+ char **nenvp = &nul;
- nice(tolower(queue) - 'a');
-
- if (initgroups(pentry->pw_name,pentry->pw_gid))
- perr("cannot delete saved userids");
+ /*
+ * Set up things for the child; we want standard input from
+ * the input file, and standard output and error sent to
+ * our output file.
+ */
- if (setgid(gid) < 0 || setegid(pentry->pw_gid) < 0)
- perr("cannot change group");
+ if (lseek(fd_in, (off_t) 0, SEEK_SET) < 0)
+ perr("Error in lseek");
- if (setlogin(pentry->pw_name))
- perr("cannot set login name");
+ if (dup(fd_in) != STDIN_FILENO)
+ perr("Error in I/O redirection");
- if (setuid(uid) < 0 || seteuid(uid) < 0)
- perr("cannot set user id");
+ if (dup(fd_out) != STDOUT_FILENO)
+ perr("Error in I/O redirection");
- if (chdir(pentry->pw_dir))
- chdir("/");
+ if (dup(fd_out) != STDERR_FILENO)
+ perr("Error in I/O redirection");
- if(execle("/bin/sh","sh",(char *) NULL, nenvp) != 0)
- perr("exec failed for /bin/sh");
+ close(fd_in);
+ close(fd_out);
+ if (chdir(_PATH_ATJOBS) < 0)
+ perr("Cannot chdir to " _PATH_ATJOBS);
- PRIV_END
- }
- /* We're the parent. Let's wait.
- */
- close(fd_in);
- close(fd_out);
- waitpid(pid, (int *) NULL, 0);
-
- /* Send mail. Unlink the output file first, so it is deleted after
- * the run.
- */
- stat(filename, &buf);
- if (open(filename, O_RDONLY) != STDIN_FILENO)
- perr("open of jobfile failed");
-
- unlink(filename);
- if ((buf.st_size != size) || send_mail)
- {
- PRIV_START
+ queue = *filename;
- if (initgroups(pentry->pw_name,pentry->pw_gid))
- perr("cannot delete saved userids");
+ PRIV_START
- if (setgid(gid) < 0 || setegid(pentry->pw_gid) < 0)
- perr("cannot change group");
+ if (queue > 'b')
+ nice(queue - 'b');
- if (setlogin(pentry->pw_name))
- perr("cannot set login name");
+ if (setgid(gid) < 0)
+ perr("Cannot change group");
- if (setuid(uid) < 0 || seteuid(uid) < 0)
- perr("cannot set user id");
+ if (setuid(uid) < 0)
+ perr("Cannot set user id");
- if (chdir(pentry->pw_dir))
chdir("/");
-#if 1
- execl(_PATH_SENDMAIL, "sendmail", "-F", "Atrun Service",
- "-odi", "-oem",
- mailname, (char *) NULL);
-#else
- execl(MAIL_CMD, MAIL_CMD, mailname, (char *) NULL);
-#endif
- perr("exec failed for mail command");
+ if (execle("/bin/sh", "sh", (char *) NULL, nenvp) != 0)
+ perr("Exec failed");
- PRIV_END
- }
- exit(EXIT_SUCCESS);
+ PRIV_END
+ }
+ /* We're the parent. Let's wait. */
+ close(fd_in);
+ close(fd_out);
+ waitpid(pid, (int *) NULL, 0);
+
+ stat(filename, &buf);
+ if ((buf.st_size != size) || send_mail) {
+ /* Fork off a child for sending mail */
+ pid = fork();
+ if (pid < 0)
+ perr("Fork failed");
+ else if (pid == 0) {
+ if (open(filename, O_RDONLY) != STDIN_FILENO)
+ perr("Cannot reopen output file");
+
+ execl(_PATH_SENDMAIL, _PATH_SENDMAIL, mailname,
+ (char *) NULL);
+ perr("Exec failed");
+ }
+ waitpid(pid, (int *) NULL, 0);
+ }
+ unlink(filename);
+ exit(EXIT_SUCCESS);
}
/* Global functions */
-/* Needed in gloadavg.c */
-void
-perr(const char *a)
-{
- if (debug)
- {
- warn("%s", a);
- }
- else
- syslog(LOG_ERR, "%s: %m", a);
-
- exit(EXIT_FAILURE);
-}
-
int
-main(int argc, char *argv[])
+main(argc, argv)
+ int argc;
+ char *argv[];
{
-/* Browse through ATJOB_DIR, checking all the jobfiles wether they should
- * be executed and or deleted. The queue is coded into the first byte of
- * the job filename, the date (in minutes since Eon) as a hex number in the
- * following eight bytes, followed by a dot and a serial number. A file
- * which has not been executed yet is denoted by its execute - bit set.
- * For those files which are to be executed, run_file() is called, which forks
- * off a child which takes care of I/O redirection, forks off another child
- * for execution and yet another one, optionally, for sending mail.
- * Files which already have run are removed during the next invocation.
- */
- DIR *spool;
- struct dirent *dirent;
- struct stat buf;
- unsigned long ctm;
- unsigned long jobno;
- char queue;
- time_t now, run_time;
- char batch_name[] = "Z2345678901234";
- uid_t batch_uid;
- gid_t batch_gid;
- int c;
- int run_batch;
- double load_avg = LOADAVG_MX, la;
-
-/* We don't need root privileges all the time; running under uid and gid daemon
- * is fine.
- */
-
- RELINQUISH_PRIVS_ROOT(DAEMON_UID, DAEMON_GID)
-
- openlog("atrun", LOG_PID, LOG_CRON);
-
- opterr = 0;
- while((c=getopt(argc, argv, "dl:"))!= -1)
- {
- switch (c)
- {
- case 'l':
- if (sscanf(optarg, "%lf", &load_avg) != 1)
- perr("garbled option -l");
- if (load_avg <= 0.)
- load_avg = LOADAVG_MX;
- break;
-
- case 'd':
- debug ++;
- break;
-
- case '?':
- default:
- usage();
- }
- }
-
- if (chdir(ATJOB_DIR) != 0)
- perr("cannot change to " ATJOB_DIR);
-
- /* Main loop. Open spool directory for reading and look over all the
- * files in there. If the filename indicates that the job should be run
- * and the x bit is set, fork off a child which sets its user and group
- * id to that of the files and exec a /bin/sh which executes the shell
- * script. Unlink older files if they should no longer be run. For
- * deletion, their r bit has to be turned on.
- *
- * Also, pick the oldest batch job to run, at most one per invocation of
- * atrun.
- */
- if ((spool = opendir(".")) == NULL)
- perr("cannot read " ATJOB_DIR);
-
- now = time(NULL);
- run_batch = 0;
- batch_uid = (uid_t) -1;
- batch_gid = (gid_t) -1;
-
- while ((dirent = readdir(spool)) != NULL) {
- if (stat(dirent->d_name,&buf) != 0)
- perr("cannot stat in " ATJOB_DIR);
-
- /* We don't want directories
+ /*
+ * Browse through _PATH_ATJOBS, checking all the jobfiles wether
+ * they should be executed and or deleted. The queue is coded into
+ * the first byte of the job filename, the date (in minutes since
+ * Eon) as a hex number in the following eight bytes, followed by
+ * a dot and a serial number. A file which has not been executed
+ * yet is denoted by its execute - bit set. For those files which
+ * are to be executed, run_file() is called, which forks off a
+ * child which takes care of I/O redirection, forks off another
+ * child for execution and yet another one, optionally, for sending
+ * mail. Files which already have run are removed during the
+ * next invocation.
*/
- if (!S_ISREG(buf.st_mode))
- continue;
-
- if (sscanf(dirent->d_name,"%c%5lx%8lx",&queue,&jobno,&ctm) != 3)
- continue;
-
- run_time = (time_t) ctm*60;
-
- if ((S_IXUSR & buf.st_mode) && (run_time <=now)) {
- if (isupper(queue) && (strcmp(batch_name,dirent->d_name) > 0)) {
- run_batch = 1;
- strncpy(batch_name, dirent->d_name, sizeof(batch_name));
- batch_uid = buf.st_uid;
- batch_gid = buf.st_gid;
- }
-
- /* The file is executable and old enough
+ DIR *spool;
+ struct dirent *dirent;
+ struct stat buf;
+ int older;
+ unsigned long ctm;
+ char queue;
+
+ /*
+ * We don't need root privileges all the time; running under uid
+ * and gid daemon is fine.
*/
- if (islower(queue))
- run_file(dirent->d_name, buf.st_uid, buf.st_gid);
- }
- /* Delete older files
+
+ RELINQUISH_PRIVS_ROOT(0) /* it's setuid root */
+ openlog("atrun", LOG_PID, LOG_CRON);
+
+ namep = argv[0];
+ if (chdir(_PATH_ATJOBS) != 0)
+ perr("Cannot change to " _PATH_ATJOBS);
+
+ /*
+ * Main loop. Open spool directory for reading and look over all
+ * the files in there. If the filename indicates that the job
+ * should be run and the x bit is set, fork off a child which sets
+ * its user and group id to that of the files and exec a /bin/sh
+ * which executes the shell script. Unlink older files if they
+ * should no longer be run. For deletion, their r bit has to be
+ * turned on.
*/
- if ((run_time < now) && !(S_IXUSR & buf.st_mode) && (S_IRUSR & buf.st_mode))
- unlink(dirent->d_name);
- }
- /* run the single batch file, if any
- */
- if (run_batch && (getloadavg(&la, 1) == 1) && la < load_avg)
- run_file(batch_name, batch_uid, batch_gid);
-
- closelog();
- exit(EXIT_SUCCESS);
-}
+ if ((spool = opendir(".")) == NULL)
+ perr("Cannot read " _PATH_ATJOBS);
-static void
-usage(void)
-{
- if (debug)
- fprintf(stderr, "usage: atrun [-l load_avg] [-d]\n");
- else
- syslog(LOG_ERR, "usage: atrun [-l load_avg] [-d]");
+ while ((dirent = readdir(spool)) != NULL) {
+ double la;
+
+ if (stat(dirent->d_name, &buf) != 0)
+ perr("Cannot stat in " _PATH_ATJOBS);
+
+ /* We don't want directories */
+ if (!S_ISREG(buf.st_mode))
+ continue;
- exit(EXIT_FAILURE);
+ if (sscanf(dirent->d_name, "%c%8lx", &queue, &ctm) != 2)
+ continue;
+
+ if ((queue == 'b') && ((getloadavg(&la, 1) != 1) ||
+ (la > ATRUN_MAXLOAD)))
+ continue;
+
+ older = (time_t) ctm *60 <= time(NULL);
+
+ /* The file is executable and old enough */
+ if (older && (S_IXUSR & buf.st_mode)) {
+ /*
+ * Now we know we want to run the file, we can turn
+ * off the execute bit
+ */
+
+ PRIV_START
+
+ if (chmod(dirent->d_name, S_IRUSR) != 0)
+ perr("Cannot change file permissions");
+
+ PRIV_END
+
+ run_file(dirent->d_name, buf.st_uid, buf.st_gid);
+ }
+ /* Delete older files */
+ if (older && !(S_IXUSR & buf.st_mode) &&
+ (S_IRUSR & buf.st_mode))
+ unlink(dirent->d_name);
+ }
+ closelog();
+ exit(EXIT_SUCCESS);
}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
+++ /dev/null
-#
-# Generated by the Apple Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = audit
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-CFILES = audit.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
- auditd_control.defs audit.1
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /usr/sbin
-WINDOWS_INSTALLDIR = /Library/Executables
-PDO_UNIX_INSTALLDIR = /bin
-LIBS =
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-
-HEADER_PATHS = -I../auditd.tproj
-
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
+++ /dev/null
-###############################################################################
-# Makefile.postamble
-# Copyright 2004, Apple Computer, Inc.
-#
-# Use this makefile, which is imported after all other makefiles, to
-# override attributes for a project's Makefile environment. This allows you
-# to take advantage of the environment set up by the other Makefiles.
-# You can also define custom rules at the end of this file.
-#
-###############################################################################
-#
-# These variables are exported by the standard makefiles and can be
-# used in any customizations you make. They are *outputs* of
-# the Makefiles and should be used, not set.
-#
-# PRODUCTS: products to install. All of these products will be placed in
-# the directory $(DSTROOT)$(INSTALLDIR)
-# GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
-# LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
-# OFILE_DIR: Directory into which .o object files are generated.
-# DERIVED_SRC_DIR: Directory used for all other derived files
-#
-# ALL_CFLAGS: flags to pass when compiling .c files
-# ALL_MFLAGS: flags to pass when compiling .m files
-# ALL_CCFLAGS: flags to pass when compiling .cc, .cxx, and .C files
-# ALL_MMFLAGS: flags to pass when compiling .mm, .mxx, and .M files
-# ALL_PRECOMPFLAGS: flags to pass when precompiling .h files
-# ALL_LDFLAGS: flags to pass when linking object files
-# ALL_LIBTOOL_FLAGS: flags to pass when libtooling object files
-# ALL_PSWFLAGS: flags to pass when processing .psw and .pswm (pswrap) files
-# ALL_RPCFLAGS: flags to pass when processing .rpc (rpcgen) files
-# ALL_YFLAGS: flags to pass when processing .y (yacc) files
-# ALL_LFLAGS: flags to pass when processing .l (lex) files
-#
-# NAME: name of application, bundle, subproject, palette, etc.
-# LANGUAGES: langages in which the project is written (default "English")
-# English_RESOURCES: localized resources (e.g. nib's, images) of project
-# GLOBAL_RESOURCES: non-localized resources of project
-#
-# SRCROOT: base directory in which to place the new source files
-# SRCPATH: relative path from SRCROOT to present subdirectory
-#
-# INSTALLDIR: Directory the product will be installed into by 'install' target
-# PUBLIC_HDR_INSTALLDIR: where to install public headers. Don't forget
-# to prefix this with DSTROOT when you use it.
-# PRIVATE_HDR_INSTALLDIR: where to install private headers. Don't forget
-# to prefix this with DSTROOT when you use it.
-#
-# EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
-#
-###############################################################################
-
-# Some compiler flags can be overridden here for certain build situations.
-#
-# WARNING_CFLAGS: flag used to set warning level (defaults to -Wmost)
-# DEBUG_SYMBOLS_CFLAGS: debug-symbol flag passed to all builds (defaults
-# to -g)
-# DEBUG_BUILD_CFLAGS: flags passed during debug builds (defaults to -DDEBUG)
-# OPTIMIZE_BUILD_CFLAGS: flags passed during optimized builds (defaults
-# to -O)
-# PROFILE_BUILD_CFLAGS: flags passed during profile builds (defaults
-# to -pg -DPROFILE)
-# LOCAL_DIR_INCLUDE_DIRECTIVE: flag used to add current directory to
-# the include path (defaults to -I.)
-# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
-# passed to ld/libtool (defaults to nothing)
-
-
-# Library and Framework projects only:
-# INSTALL_NAME_DIRECTIVE: This directive ensures that executables linked
-# against the framework will run against the correct version even if
-# the current version of the framework changes. You may override this
-# to "" as an alternative to using the DYLD_LIBRARY_PATH during your
-# development cycle, but be sure to restore it before installing.
-MIGFLAGS =
-MIG = $(NEXT_ROOT)/usr/bin/mig
-
-auditd_control_user.c auditd_control.h: auditd_control.defs
- cp $(SRCROOT)/auditd.tproj/auditd_control.defs $(SYM_DIR);
- cd $(SYM_DIR) && \
- $(MIG) $(MIGFLAGS) -user auditd_control_user.c -header auditd_control.h \
- -server /dev/null -sheader /dev/null auditd_control.defs
-
- install-man-page:
- install -d $(DSTROOT)/usr/share/man/man1
- install -c -m 444 audit.1 $(DSTROOT)/usr/share/man/man1/audit.1
+++ /dev/null
-###############################################################################
-# Makefile.preamble
-# Copyright 2004, Apple Computer, Inc.
-#
-# Use this makefile for configuring the standard application makefiles
-# associated with ProjectBuilder. It is included before the main makefile.
-# In Makefile.preamble you set attributes for a project, so they are available
-# to the project's makefiles. In contrast, you typically write additional rules or
-# override built-in behavior in the Makefile.postamble.
-#
-# Each directory in a project tree (main project plus subprojects) should
-# have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-#
-OTHER_GENERATED_OFILES = $(VERS_OFILE)
-BEFORE_BUILD = auditd_control.h auditd_control_user.c
-OTHER_OFILES = auditd_control_user.o
-AFTER_INSTALL += install-man-page
-
+++ /dev/null
-{
- "DYNAMIC_CODE_GEN" = YES;
- FILESTABLE = {
- FRAMEWORKS = ();
- HEADERSEARCH = ("../auditd.tproj");
- "OTHER_LINKED" = ("audit.c");
- "OTHER_SOURCES" = (
- "Makefile.preamble",
- Makefile,
- "Makefile.postamble",
- "auditd_control.defs",
- "audit.1"
- );
- };
- LANGUAGE = English;
- MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
- "NEXTSTEP_BUILDTOOL" = "/usr/bin/gnumake";
- "NEXTSTEP_INSTALLDIR" = "/usr/sbin";
- "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
- "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
- "PDO_UNIX_BUILDTOOL" = "$NEXT_ROOT/Developer/bin/make";
- "PDO_UNIX_INSTALLDIR" = "/bin";
- "PDO_UNIX_JAVA_COMPILER" = "$(JDKBINDIR)/javac";
- "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
- PROJECTNAME = audit;
- PROJECTTYPE = Tool;
- PROJECTVERSION = "2.8";
- "WINDOWS_BUILDTOOL" = "$NEXT_ROOT/Developer/Executables/make";
- "WINDOWS_INSTALLDIR" = "/Library/Executables";
- "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
- "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
-}
+++ /dev/null
-.\" Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
-.\"
-.Dd Jan 24, 2004
-.Dt AUDIT 1
-.Os "Mac OS X"
-.Sh NAME
-.Nm audit
-.Nd audit management utility
-.Sh SYNOPSIS
-.Nm audit
-.Op Fl nst
-.Op Ar file
-.Sh DESCRIPTION
-The
-.Nm
-utility controls the state of auditing system. The optional
-.Ar file
-operand specifies the location of the audit control input file (default
-/etc/security/audit_control).
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl n
-Forces the audit system to close the existing audit log file and rotate to
-a new log file in a location specified in the audit control file.
-.It Fl s
-Specifies that the audit system should [re]synchronize its
-configuration from the audit control file. A new log file will be
-created.
-.It Fl t
-Specifies that the audit system should terminate. Log files are closed
-and renamed to indicate the time of the shutdown.
-.El
-.Sh NOTES
-The auditd(8) daemon must already be running.
-.Sh FILES
-.Bl -tag -width "/etc/security/audit_control" -compact
-.It Pa /etc/security/audit_control
-Default audit policy file used to configure the auditing system.
-.El
-.Sh SEE ALSO
-.Xr auditd 8
-.Xr audit_control 5
+++ /dev/null
-/*
- * Program to trigger the audit daemon with a message that is either:
- * - Open a new audit log file
- * - Read the audit control file and take action on it
- * - Close the audit log file and exit
- *
- */
-
-#include <mach/mach.h>
-#include <servers/netname.h>
-#include <mach/message.h>
-#include <mach/port.h>
-#include <mach/mach_error.h>
-#include <mach/host_special_ports.h>
-#include <servers/bootstrap.h>
-
-#include <auditd_control.h>
-#include <auditd.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-
-mach_port_t serverPort;
-mach_port_t bootstrapPort;
-
-void init();
-void process(int flags);
-
-/*
- * Main routine to process command line options.
- */
-int main(int argc, char **argv)
-{
- char ch;
- int flags = 0;
- while ((ch = getopt(argc, argv, "nst")) != -1) {
- switch(ch) {
-
- case 'n':
- flags = OPEN_NEW;
- break;
-
- case 's':
- flags = READ_FILE;
- break;
-
- case 't':
- flags = CLOSE_AND_DIE;
- break;
-
- case '?':
- default:
- (void)fprintf(stderr,
- "usage: audit -n | -s | -t \n");
- exit(1);
- }
- }
- init();
- process(flags);
- return 0;
-}
-
-/*
- * Program initialization:
- * Look up the server port and store it away.
- */
-void init()
-{
- if(host_get_audit_control_port(mach_host_self(), &serverPort) != KERN_SUCCESS) {
- fprintf(stderr, "Cannot get auditd_control\n");
- exit(1);
- }
-
- printf("Server port is %d\n", serverPort);
-}
-
-/*
- * Do all the real work.
- * Send a message to the audit daemon and check the return code.
- */
-void process(int flags)
-{
- kern_return_t retcode;
- retcode = auditd_control(serverPort, flags);
- if(retcode != KERN_SUCCESS) {
- mach_error("error doing IPC: ", retcode);
- exit(1);
- }
- printf("Client call successful\n");
-}
+++ /dev/null
-/*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "Portions Copyright (c) 2004 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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "../auditd.tproj/auditd_control.defs"
+++ /dev/null
-#
-# Generated by the Apple Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = auditd
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-HFILES = auditd.h
-
-CFILES = audit_warn.c auditd.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
- audit_triggers.defs auditd_control.defs auditd.8 rc.audit
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /usr/sbin
-WINDOWS_INSTALLDIR = /Library/Executables
-PDO_UNIX_INSTALLDIR = /usr/sbin
-LIBS =
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-
-NEXTSTEP_PB_LDFLAGS = -lbsm
-
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
+++ /dev/null
-###############################################################################
-# Makefile.postamble
-# Copyright 1997, Apple Computer, Inc.
-#
-# Use this makefile, which is imported after all other makefiles, to
-# override attributes for a project's Makefile environment. This allows you
-# to take advantage of the environment set up by the other Makefiles.
-# You can also define custom rules at the end of this file.
-#
-###############################################################################
-#
-# These variables are exported by the standard makefiles and can be
-# used in any customizations you make. They are *outputs* of
-# the Makefiles and should be used, not set.
-#
-# PRODUCTS: products to install. All of these products will be placed in
-# the directory $(DSTROOT)$(INSTALLDIR)
-# GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
-# LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
-# OFILE_DIR: Directory into which .o object files are generated.
-# DERIVED_SRC_DIR: Directory used for all other derived files
-#
-# ALL_CFLAGS: flags to pass when compiling .c files
-# ALL_MFLAGS: flags to pass when compiling .m files
-# ALL_CCFLAGS: flags to pass when compiling .cc, .cxx, and .C files
-# ALL_MMFLAGS: flags to pass when compiling .mm, .mxx, and .M files
-# ALL_PRECOMPFLAGS: flags to pass when precompiling .h files
-# ALL_LDFLAGS: flags to pass when linking object files
-# ALL_LIBTOOL_FLAGS: flags to pass when libtooling object files
-# ALL_PSWFLAGS: flags to pass when processing .psw and .pswm (pswrap) files
-# ALL_RPCFLAGS: flags to pass when processing .rpc (rpcgen) files
-# ALL_YFLAGS: flags to pass when processing .y (yacc) files
-# ALL_LFLAGS: flags to pass when processing .l (lex) files
-#
-# NAME: name of application, bundle, subproject, palette, etc.
-# LANGUAGES: langages in which the project is written (default "English")
-# English_RESOURCES: localized resources (e.g. nib's, images) of project
-# GLOBAL_RESOURCES: non-localized resources of project
-#
-# SRCROOT: base directory in which to place the new source files
-# SRCPATH: relative path from SRCROOT to present subdirectory
-#
-# INSTALLDIR: Directory the product will be installed into by 'install' target
-# PUBLIC_HDR_INSTALLDIR: where to install public headers. Don't forget
-# to prefix this with DSTROOT when you use it.
-# PRIVATE_HDR_INSTALLDIR: where to install private headers. Don't forget
-# to prefix this with DSTROOT when you use it.
-#
-# EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
-#
-###############################################################################
-
-# Some compiler flags can be overridden here for certain build situations.
-#
-# WARNING_CFLAGS: flag used to set warning level (defaults to -Wmost)
-# DEBUG_SYMBOLS_CFLAGS: debug-symbol flag passed to all builds (defaults
-# to -g)
-# DEBUG_BUILD_CFLAGS: flags passed during debug builds (defaults to -DDEBUG)
-# OPTIMIZE_BUILD_CFLAGS: flags passed during optimized builds (defaults
-# to -O)
-# PROFILE_BUILD_CFLAGS: flags passed during profile builds (defaults
-# to -pg -DPROFILE)
-# LOCAL_DIR_INCLUDE_DIRECTIVE: flag used to add current directory to
-# the include path (defaults to -I.)
-# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
-# passed to ld/libtool (defaults to nothing)
-
-
-# Library and Framework projects only:
-# INSTALL_NAME_DIRECTIVE: This directive ensures that executables linked
-# against the framework will run against the correct version even if
-# the current version of the framework changes. You may override this
-# to "" as an alternative to using the DYLD_LIBRARY_PATH during your
-# development cycle, but be sure to restore it before installing.
-
-
-# Ownership and permissions of files installed by 'install' target
-
-#INSTALL_AS_USER = root
- # User/group ownership
-#INSTALL_AS_GROUP = wheel
- # (probably want to set both of these)
-#INSTALL_PERMISSIONS =
- # If set, 'install' chmod's executable to this
-
-
-# Options to strip. Note: -S strips debugging symbols (executables can be stripped
-# down further with -x or, if they load no bundles, with no options at all).
-
-#STRIPFLAGS = -S
-
-
-#########################################################################
-# Put rules to extend the behavior of the standard Makefiles here. Include them in
-# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
-#
-# You should avoid redefining things like "install" or "app", as they are
-# owned by the top-level Makefile API and no context has been set up for where
-# derived files should go.
-#
-ETCDIR = $(DSTROOT)/private/etc
-MIGFLAGS = -no-cpp-precomp -R -untyped -DNO_DIRECT_RPC
-MIG = $(NEXT_ROOT)/usr/bin/mig
-
-auditd_control_server.c : auditd_control.defs
- cp $(SRCROOT)/auditd.tproj/auditd_control.defs $(SYM_DIR);
- cd $(SYM_DIR) && \
- $(MIG) $(MIGFLAGS) -user /dev/null -server auditd_control_server.c -sheader auditd_control_server.h auditd_control.defs
-
-audit_triggers_server.c: audit_triggers.defs
- cp $(SRCROOT)/auditd.tproj/audit_triggers.defs $(SYM_DIR);
- cd $(SYM_DIR) && \
- $(MIG) $(MIGFLAGS) -user /dev/null -server audit_triggers_server.c -sheader audit_triggers_server.h audit_triggers.defs
-
-install-startup:
- install -d $(ETCDIR)/security
- install -c -m 400 rc.audit $(ETCDIR)/security/rc.audit
-
-install-man-page:
- install -d $(DSTROOT)/usr/share/man/man8
- install -c -m 444 auditd.8 $(DSTROOT)/usr/share/man/man8/auditd.8
+++ /dev/null
-###############################################################################
-# Makefile.preamble
-# Copyright 2004, Apple Computer, Inc.
-#
-# Use this makefile for configuring the standard application makefiles
-# associated with ProjectBuilder. It is included before the main makefile.
-# In Makefile.preamble you set attributes for a project, so they are available
-# to the project's makefiles. In contrast, you typically write additional rules or
-# override built-in behavior in the Makefile.postamble.
-#
-# Each directory in a project tree (main project plus subprojects) should
-# have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-OTHER_GENERATED_OFILES = $(VERS_OFILE)
-BEFORE_BUILD = auditd_control_server.c auditd_control_server.h \
- audit_triggers_server.c audit_triggers_server.h
-OTHER_OFILES = auditd_control_server.o audit_triggers_server.o
-AFTER_INSTALL += install-startup install-man-page
+++ /dev/null
-{
- "DYNAMIC_CODE_GEN" = YES;
- FILESTABLE = {
- FRAMEWORKS = ();
- "H_FILES" = ("auditd.h");
- "OTHER_LINKED" = ("audit_warn.c", "auditd.c");
- "OTHER_SOURCES" = (
- "Makefile.preamble",
- Makefile,
- "Makefile.postamble",
- "audit_triggers.defs",
- "auditd_control.defs",
- "auditd.8",
- "rc.audit"
- );
- "PRECOMPILED_HEADERS" = ();
- "PROJECT_HEADERS" = ();
- "PUBLIC_HEADERS" = ();
- };
- LANGUAGE = English;
- MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
- "NEXTSTEP_BUILDTOOL" = "/usr/bin/gnumake";
- "NEXTSTEP_INSTALLDIR" = "/usr/sbin";
- "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
- "NEXTSTEP_LINKEROPTIONS" = "-lbsm";
- "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
- "PDO_UNIX_BUILDTOOL" = "$NEXT_ROOT/Developer/bin/make";
- "PDO_UNIX_INSTALLDIR" = "/bin";
- "PDO_UNIX_JAVA_COMPILER" = "$(JDKBINDIR)/javac";
- "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
- PROJECTNAME = auditd;
- PROJECTTYPE = Tool;
- PROJECTVERSION = "2.8";
- "WINDOWS_BUILDTOOL" = "$NEXT_ROOT/Developer/Executables/make";
- "WINDOWS_INSTALLDIR" = "/Library/Executables";
- "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
- "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
-}
+++ /dev/null
-#include <mach/audit_triggers.defs>
+++ /dev/null
-/*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "Portions Copyright (c) 2004 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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include <auditd.h>
-
-/* Write to the audit log. */
-static int auditwarnlog(char *args[])
-{
- char *loc_args[9];
- int i;
- pid_t pid;
- loc_args[0] = AUDITWARN_SCRIPT;
- for (i = 0; args[i] != NULL && i < 8; i++) {
- loc_args[i+1] = args[i];
- }
- loc_args[i+1] = NULL;
-
- pid = fork();
- if (pid == 0) {
- return execv(AUDITWARN_SCRIPT, loc_args);
- /* not reached */
- exit(1);
- } else if (pid == -1) {
- return -1;
- } else {
- return 0;
- }
-}
-
-/*
- * Indicates that the hard limit for all filesystems
- * has been exceeded count times
- */
-int audit_warn_allhard(int count)
-{
- char intstr[12];
- char *args[3];
-
- snprintf(intstr, 12, "%d", count);
-
- args[0] = HARDLIM_ALL_WARN;
- args[1] = intstr;
- args[2] = NULL;
-
- return auditwarnlog(args);
-}
-
-/*
- * Indicates that the soft limit for all filesystems
- * has been exceeded
- */
-int audit_warn_allsoft()
-{
- char *args[2];
-
- args[0] = SOFTLIM_ALL_WARN;
- args[1] = NULL;
-
- return auditwarnlog(args);
-}
-
-/*
- * Indicates that someone other than the audit daemon
- * turned off auditing
- * XXX Its not clear at this point how this function will
- * XXX be invoked
- */
-int audit_warn_auditoff()
-{
- char *args[2];
-
- args[0] = AUDITOFF_WARN;
- args[1] = NULL;
-
- return auditwarnlog(args);
-}
-
-/*
- * Indicates that the audit deammn is already running
- */
-int audit_warn_ebusy()
-{
- char *args[2];
-
- args[0] = EBUSY_WARN;
- args[1] = NULL;
-
- return auditwarnlog(args);
-
-}
-
-/*
- * Indicates that there is a problem getting the directory
- * from audit_control
- *
- * XXX Note that we take the filename instead of a count
- * XXX as the argument here (different from BSM)
- */
-int audit_warn_getacdir(char *filename)
-{
- char *args[3];
-
- args[0] = GETACDIR_WARN;
- args[1] = filename;
- args[2] = NULL;
-
- return auditwarnlog(args);
-}
-
-
-/*
- * Indicates that the hard limit for this file has been
- * exceeded
- */
-int audit_warn_hard(char *filename)
-{
- char *args[3];
-
- args[0] = HARDLIM_WARN;
- args[1] = filename;
- args[2] = NULL;
-
- return auditwarnlog(args);
-
-}
-
-/*
- * Indicates that auditing could not be started
- */
-int audit_warn_nostart()
-{
- char *args[2];
-
- args[0] = NOSTART_WARN;
- args[1] = NULL;
-
- return auditwarnlog(args);
-}
-
-/*
- * Indicaes that an error occrred during the orderly shutdown
- * of the audit daemon
- */
-int audit_warn_postsigterm()
-{
- char *args[2];
-
- args[0] = POSTSIGTERM_WARN;
- args[1] = NULL;
-
- return auditwarnlog(args);
-}
-
-/*
- * Indicates that the soft limit for this file has been
- * exceeded
- */
-int audit_warn_soft(char *filename)
-{
- char *args[3];
-
- args[0] = SOFTLIM_WARN;
- args[1] = filename;
- args[2] = NULL;
-
- return auditwarnlog(args);
-
-}
-
-/*
- * Indicates that the temporary audit file already exists
- * indicating a fatal error
- */
-int audit_warn_tmpfile()
-{
- char *args[2];
-
- args[0] = TMPFILE_WARN;
- args[1] = NULL;
-
- return auditwarnlog(args);
-}
+++ /dev/null
-.\" Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
-.\"
-.Dd Jan 24, 2004
-.Dt AUDITD 8
-.Os "Mac OS X"
-.Sh NAME
-.Nm auditd
-.Nd audit log management daemon
-.Sh SYNOPSIS
-.Nm auditd
-.Op Fl dhs
-.Sh DESCRIPTION
-The
-.Nm
-daemon responds to requests from the audit(1) utility and notifications
-from the kernel. It manages the resulting audit log files and specified
-log file locations.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl d
-Starts the daemon in debug mode - it will not daemonize.
-.It Fl h
-Specifies that if auditing cannot be performed as specified, the system should
-halt (panic). Normally, the system will attempt to proceed - although individual
-processes may be stopped (see the -s option).
-.It Fl s
-Specifies that individual processes should stop rather than perform operations
-that may cause audit records to be lost due to log file full conditions
-.El
-.Sh NOTE
-.Pp
-To assure uninterrupted audit support, the
-.Nm auditd
-daemon should not be started and stopped manually. Instead, the audit(1) command
-should be used to inform the daemon to change state/configuration after altering
-the audit_control file.
-.Pp
-Sending a SIGHUP to a running
-.Nm auditd
-daemon will force it to exit.
-.Sh FILES
-.Bl -tag -width "/var/audit" -compact
-.It Pa /var/audit
-Default directory for storing audit log files.
-.El
-.Sh SEE ALSO
-.Xr audit 1
+++ /dev/null
-/*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "Portions Copyright (c) 2004 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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <mach/port.h>
-#include <mach/mach_error.h>
-#include <mach/mach_traps.h>
-#include <mach/mach.h>
-#include <mach/host_special_ports.h>
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include <fcntl.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <syslog.h>
-#include <signal.h>
-#include <string.h>
-#include <notify.h>
-
-#include <bsm/audit.h>
-#include <bsm/audit_uevents.h>
-#include <bsm/libbsm.h>
-
-#include <auditd.h>
-#include "auditd_control_server.h"
-#include "audit_triggers_server.h"
-#define NA_EVENT_STR_SIZE 25
-
-static int ret, minval;
-static char *lastfile = NULL;
-
-static int allhardcount = 0;
-
-mach_port_t bp = MACH_PORT_NULL;
-mach_port_t control_port = MACH_PORT_NULL;
-mach_port_t signal_port = MACH_PORT_NULL;
-mach_port_t port_set = MACH_PORT_NULL;
-
-#ifndef __BSM_INTERNAL_NOTIFY_KEY
-#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
-#endif /* __BSM_INTERNAL_NOTIFY_KEY */
-
-TAILQ_HEAD(, dir_ent) dir_q;
-
-
-/* Error starting auditd */
-void fail_exit()
-{
- audit_warn_nostart();
- exit(1);
-}
-
-/*
- * Free our local list of directory names
- */
-void free_dir_q()
-{
- struct dir_ent *dirent;
-
- while ((dirent = TAILQ_FIRST(&dir_q))) {
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- free(dirent->dirname);
- free(dirent);
- }
-}
-
-/*
- * generate the timestamp string
- */
-int getTSstr(char *buf, int len)
-{
- struct timeval ts;
- struct timezone tzp;
- time_t tt;
-
- if(gettimeofday(&ts, &tzp) != 0) {
- return -1;
- }
- tt = (time_t)ts.tv_sec;
- if(!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt))) {
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Concat the directory name to the given file name
- * XXX We should affix the hostname also
- */
-char *affixdir(char *name, struct dir_ent *dirent)
-{
- char *fn;
- char *curdir;
- const char *sep = "/";
-
- curdir = dirent->dirname;
- syslog(LOG_INFO, "dir = %s\n", dirent->dirname);
-
- fn = (char *) malloc (strlen(curdir) + strlen(sep)
- + (2 * POSTFIX_LEN) + 1);
- if(fn == NULL) {
- return NULL;
- }
- strcpy(fn, curdir);
- strcat(fn, sep);
- strcat(fn, name);
-
- return fn;
-}
-
-/* Close the previous audit trail file */
-int close_lastfile(char *TS)
-{
- char *ptr;
- char *oldname;
-
- if(lastfile != NULL) {
- oldname = (char *)malloc(strlen(lastfile) + 1);
- if(oldname == NULL) {
- return -1;
- }
- strcpy(oldname, lastfile);
-
- /* rename the last file -- append timestamp */
-
- if((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
- *ptr = '.';
- strcpy(ptr+1, TS);
- if(rename(oldname, lastfile) != 0) {
- syslog(LOG_ERR, "Could not rename %s to %s \n",
- oldname, lastfile);
- }
- else {
- syslog(LOG_INFO, "renamed %s to %s \n",
- oldname, lastfile);
- }
- }
-
- free(lastfile);
- free(oldname);
-
- lastfile = NULL;
- }
-
- return 0;
-}
-
-/*
- * Create the new file name, swap with existing audit file
- */
-int swap_audit_file()
-{
- char timestr[2 * POSTFIX_LEN];
- char *fn;
- char TS[POSTFIX_LEN];
- struct dir_ent *dirent;
-
- if(getTSstr(TS, POSTFIX_LEN) != 0) {
- return -1;
- }
-
- strcpy(timestr, TS);
- strcat(timestr, NOT_TERMINATED);
-
- /* try until we succeed */
- while((dirent = TAILQ_FIRST(&dir_q))) {
- if((fn = affixdir(timestr, dirent)) == NULL) {
- return -1;
- }
-
- syslog(LOG_INFO, "New audit file is %s\n", fn);
- if (open(fn, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP) < 0) {
- perror("File open");
- }
- else if (auditctl(fn) != 0) {
- syslog(LOG_ERR, "auditctl failed! : %s\n",
- strerror(errno));
- }
- else {
- /* Success */
- close_lastfile(TS);
- lastfile = fn;
- return 0;
- }
-
- /* Tell the administrator about lack of permissions for dirent */
- audit_warn_getacdir(dirent->dirname);
-
- /* Try again with a different directory */
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- free(dirent->dirname);
- free(dirent);
- }
- return -1;
-}
-
-/*
- * Read the audit_control file contents
- */
-int read_control_file()
-{
- char cur_dir[MAX_DIR_SIZE];
- struct dir_ent *dirent;
- au_qctrl_t qctrl;
-
- /* Clear old values */
- free_dir_q();
- endac(); // force a re-read of the file the next time
-
- /* Post that the audit config changed */
- notify_post(__BSM_INTERNAL_NOTIFY_KEY);
-
- /* Read the list of directories into a local linked list */
- /* XXX We should use the reentrant interfaces once they are available */
- while(getacdir(cur_dir, MAX_DIR_SIZE) >= 0) {
- dirent = (struct dir_ent *) malloc (sizeof(struct dir_ent));
- if(dirent == NULL) {
- return -1;
- }
-
- dirent->softlim = 0;
- dirent->dirname = (char *) malloc (MAX_DIR_SIZE);
- if(dirent->dirname == NULL) {
- free(dirent);
- return -1;
- }
-
- strcpy(dirent->dirname, cur_dir);
- TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
- }
-
- allhardcount = 0;
-
- if(swap_audit_file() == -1) {
- syslog(LOG_ERR, "Could not swap audit file\n");
- /*
- * XXX Faulty directory listing? - user should be given
- * XXX an opportunity to change the audit_control file
- * XXX switch to a reduced mode of auditing?
- */
- return -1;
- }
-
- /*
- * XXX There are synchronization problems here
- * XXX what should we do if a trigger for the earlier limit
- * XXX is generated here?
- */
- if(0 == (ret = getacmin(&minval))) {
-
- syslog(LOG_INFO, "min free = %d\n", minval);
-
- if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
- syslog(LOG_ERR,
- "could not get audit queue settings\n");
- return -1;
- }
- qctrl.aq_minfree = minval;
- if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
- syslog(LOG_ERR,
- "could not set audit queue settings\n");
- return -1;
- }
- }
-
- return 0;
-}
-
-/*
- * Close all log files, control files, and tell the audit system.
- */
-int close_all()
-{
- int err_ret = 0;
- char TS[POSTFIX_LEN];
- int aufd;
- token_t *tok;
-
- /* Generate an audit record */
- if((aufd = au_open()) == -1) {
- syslog(LOG_ERR, "Could not create audit shutdown event.\n");
- } else {
-
- if((tok = au_to_text("auditd::Audit shutdown")) != NULL) {
- au_write(aufd, tok);
- }
-
- if(au_close(aufd, 1, AUE_audit_shutdown) == -1) {
- syslog(LOG_ERR, "Could not close audit shutdown event.\n");
- }
- }
-
- /* flush contents */
- err_ret = auditctl(NULL);
- if (err_ret != 0) {
- syslog(LOG_ERR, "auditctl failed! : %s\n",
- strerror(errno));
- err_ret = 1;
- }
- if(getTSstr(TS, POSTFIX_LEN) == 0) {
- close_lastfile(TS);
- }
- if(lastfile != NULL)
- free(lastfile);
-
- free_dir_q();
- if((remove(AUDITD_PIDFILE) == -1) || err_ret) {
- syslog(LOG_ERR, "Could not unregister\n");
- audit_warn_postsigterm();
- return (1);
- }
- endac();
- syslog(LOG_INFO, "Finished.\n");
- return (0);
-}
-
-/*
- * When we get a signal, we are often not at a clean point.
- * So, little can be done in the signal handler itself. Instead,
- * we send a message to the main servicing loop to do proper
- * handling from a non-signal-handler context.
- */
-static void
-relay_signal(int signal)
-{
- mach_msg_empty_send_t msg;
-
- msg.header.msgh_id = signal;
- msg.header.msgh_remote_port = signal_port;
- msg.header.msgh_local_port = MACH_PORT_NULL;
- msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
- mach_msg(&(msg.header), MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof(msg),
- 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-}
-
-/* registering the daemon */
-int register_daemon()
-{
- FILE * pidfile;
- int fd;
- pid_t pid;
-
- /* Set up the signal hander */
- if (signal(SIGTERM, relay_signal) == SIG_ERR) {
- fail_exit();
- }
- if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
- fail_exit();
- }
-
- if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
- audit_warn_tmpfile();
- return -1;
- }
-
- /* attempt to lock the pid file; if a lock is present, exit */
- fd = fileno(pidfile);
- if(flock(fd, LOCK_EX | LOCK_NB) < 0) {
- syslog(LOG_ERR, "PID file is locked (is another auditd running?).\n");
- audit_warn_ebusy();
- return -1;
- }
-
- pid = getpid();
- ftruncate(fd, 0);
- if(fprintf(pidfile, "%u\n", pid) < 0) {
- /* should not start the daemon */
- fail_exit();
- }
-
- fflush(pidfile);
- return 0;
-}
-
-/*
- * React to input from the audit tool
- */
-kern_return_t auditd_control(auditd_port, flags)
- mach_port_t auditd_port;
- int flags;
-{
- int err_ret = 0;
-
- switch(flags) {
-
- case OPEN_NEW :
- /* create a new file and swap with the one being used in kernel */
- if(swap_audit_file() == -1) {
- syslog(LOG_ERR, "Error swapping audit file\n");
- }
- break;
-
- case READ_FILE :
- if(read_control_file() == -1) {
- syslog(LOG_ERR, "Error in audit control file\n");
- }
- break;
-
- case CLOSE_AND_DIE :
- err_ret = close_all();
- exit (err_ret);
- break;
-
- default :
- break;
- }
-
- return KERN_SUCCESS;
-}
-
-/*
- * Suppress duplicate messages within a 30 second interval.
- * This should be enough to time to rotate log files without
- * thrashing from soft warnings generated before the log is
- * actually rotated.
- */
-#define DUPLICATE_INTERVAL 30
-/*
- * Implementation of the audit_triggers() MIG routine.
- */
-kern_return_t audit_triggers(audit_port, flags)
- mach_port_t audit_port;
- int flags;
-{
- static int last_flags;
- static time_t last_time;
- struct dir_ent *dirent;
-
- /*
- * Suppres duplicate messages from the kernel within the specified interval
- */
- struct timeval ts;
- struct timezone tzp;
- time_t tt;
-
- if(gettimeofday(&ts, &tzp) == 0) {
- tt = (time_t)ts.tv_sec;
- if ((flags == last_flags) && (tt < (last_time + DUPLICATE_INTERVAL))) {
- return KERN_SUCCESS;
- }
- last_flags = flags;
- last_time = tt;
- }
-
- syslog(LOG_INFO,
- "audit_triggers() called within auditd with flags = %d\n",
- flags);
- /*
- * XXX Message processing is done here
- */
- dirent = TAILQ_FIRST(&dir_q);
- if(flags == AUDIT_TRIGGER_LOW_SPACE) {
- if(dirent && (dirent->softlim != 1)) {
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- /* add this node to the end of the list */
- TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
- audit_warn_soft(dirent->dirname);
- dirent->softlim = 1;
-
- if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL && swap_audit_file() == -1) {
- syslog(LOG_ERR, "Error swapping audit file\n");
- }
-
- /*
- * check if the next dir has already reached its
- * soft limit
- */
- dirent = TAILQ_FIRST(&dir_q);
- if(dirent->softlim == 1) {
- /* all dirs have reached their soft limit */
- audit_warn_allsoft();
- }
- }
- else {
- /*
- * Continue auditing to the current file
- * Also generate an allsoft warning
- * XXX do we want to do this ?
- */
- audit_warn_allsoft();
- }
- }
- else if (flags == AUDIT_TRIGGER_FILE_FULL) {
-
- /* delete current dir, go on to next */
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- audit_warn_hard(dirent->dirname);
- free(dirent->dirname);
- free(dirent);
-
- if(swap_audit_file() == -1) {
- syslog(LOG_ERR, "Error swapping audit file in response to AUDIT_TRIGGER_FILE_FULL message\n");
-
- /* Nowhere to write to */
- audit_warn_allhard(++allhardcount);
- }
- }
- return KERN_SUCCESS;
-}
-
-/*
- * Reap our children.
- */
-static void
-reap_children(void)
-{
- pid_t child;
- int wstatus;
-
- while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
- if (wstatus) {
- syslog(LOG_INFO, "warn process [pid=%d] %s %d.\n", child,
- ((WIFEXITED(wstatus)) ?
- "exited with non-zero status" :
- "exited as a result of signal"),
- ((WIFEXITED(wstatus)) ?
- WEXITSTATUS(wstatus) :
- WTERMSIG(wstatus)));
- }
- }
-}
-
-/*
- * Handle an RPC call
- */
-boolean_t auditd_combined_server(
- mach_msg_header_t *InHeadP,
- mach_msg_header_t *OutHeadP)
-{
- mach_port_t local_port = InHeadP->msgh_local_port;
-
- if (local_port == signal_port) {
- int signo = InHeadP->msgh_id;
- int ret;
-
- if (SIGTERM == signo) {
- ret = close_all();
- exit (ret);
- } else if (SIGCHLD == signo) {
- reap_children();
- return TRUE;
- } else {
- syslog(LOG_INFO, "Recevied signal %d.\n", signo);
- return TRUE;
- }
- } else if (local_port == control_port) {
- boolean_t result;
-
- result = audit_triggers_server(InHeadP, OutHeadP);
- if (!result)
- result = auditd_control_server(InHeadP, OutHeadP);
- return result;
- }
- syslog(LOG_INFO, "Recevied msg on bad port 0x%x.\n", local_port);
- return FALSE;
-}
-
-void wait_on_audit_trigger(port_set)
- mach_port_t port_set;
-{
- kern_return_t result;
- result = mach_msg_server(auditd_combined_server, 4096, port_set, MACH_MSG_OPTION_NONE);
- syslog(LOG_ERR, "abnormal exit\n");
-}
-
-/*
- * Configure the audit controls in the kernel: the event to class mapping,
- * kernel preselection mask, etc.
- */
-int config_audit_controls(long flags)
-{
- au_event_ent_t *ev;
- au_evclass_map_t evc_map;
- au_mask_t aumask;
- int ctr = 0;
- char naeventstr[NA_EVENT_STR_SIZE];
-
- /* Process the audit event file, obtaining a class mapping for each
- * event, and send that mapping into the kernel.
- * XXX There's a risk here that the BSM library will return NULL
- * for an event when it can't properly map it to a class. In that
- * case, we will not process any events beyond the one that failed,
- * but should. We need a way to get a count of the events.
- */
-
- setauevent();
- while((ev = getauevent()) != NULL) {
- evc_map.ec_number = ev->ae_number;
- evc_map.ec_class = ev->ae_class;
- if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t)) != 0) {
- syslog(LOG_ERR,
- "Failed to register class mapping for event %s",
- ev->ae_name);
- } else {
- ctr++;
- }
- free(ev->ae_name);
- free(ev->ae_desc);
- free(ev);
- }
- endauevent();
- if (ctr == 0)
- syslog(LOG_ERR, "No events to class mappings registered.");
- else
- syslog(LOG_INFO, "Registered %d event to class mappings.", ctr);
-
- /* Get the non-attributable event string and set the kernel mask
- * from that.
- */
- if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0)
- && ( getauditflagsbin(naeventstr, &aumask) == 0)) {
-
- if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t))){
- syslog(LOG_ERR,
- "Failed to register non-attributable event mask.");
- } else {
- syslog(LOG_INFO, "Registered non-attributable event mask.");
- }
-
- } else {
- syslog(LOG_ERR,"Failed to obtain non-attributable event mask.");
- }
-
- /*
- * Set the audit policy flags based on passed in parameter values.
- */
- if (auditon(A_SETPOLICY, &flags, sizeof(flags))) {
- syslog(LOG_ERR,
- "Failed to set audit policy.");
- }
-
- return 0;
-}
-
-void setup(long flags)
-{
- mach_msg_type_name_t poly;
- int aufd;
- token_t *tok;
-
- /* Allocate a port set */
- if (mach_port_allocate(mach_task_self(),
- MACH_PORT_RIGHT_PORT_SET,
- &port_set) != KERN_SUCCESS) {
- syslog(LOG_ERR, "allocation of port set failed\n");
- fail_exit();
- }
-
- /* Allocate a signal reflection port */
- if (mach_port_allocate(mach_task_self(),
- MACH_PORT_RIGHT_RECEIVE,
- &signal_port) != KERN_SUCCESS ||
- mach_port_move_member(mach_task_self(),
- signal_port,
- port_set) != KERN_SUCCESS) {
- syslog(LOG_ERR, "allocation of signal port failed\n");
- fail_exit();
- }
-
- /* Allocate a trigger port */
- if (mach_port_allocate(mach_task_self(),
- MACH_PORT_RIGHT_RECEIVE,
- &control_port) != KERN_SUCCESS ||
- mach_port_move_member(mach_task_self(),
- control_port,
- port_set) != KERN_SUCCESS) {
- syslog(LOG_ERR, "allocation of trigger port failed\n");
- fail_exit();
- }
-
- /* create a send right on our trigger port */
- mach_port_extract_right(mach_task_self(), control_port,
- MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
-
- TAILQ_INIT(&dir_q);
-
- /* register the trigger port with the kernel */
- if(host_set_audit_control_port(mach_host_self(), control_port) != KERN_SUCCESS) {
- syslog(LOG_ERR, "Cannot set Mach control port\n");
- fail_exit();
- }
- else {
- syslog(LOG_ERR, "Mach control port registered\n");
- }
-
- if(read_control_file() == -1) {
- syslog(LOG_ERR, "Error reading control file\n");
- fail_exit();
- }
-
- /* Generate an audit record */
- if((aufd = au_open()) == -1) {
- syslog(LOG_ERR, "Could not create audit startup event.\n");
- } else {
-
- if((tok = au_to_text("auditd::Audit startup")) != NULL) {
- au_write(aufd, tok);
- }
-
- if(au_close(aufd, 1, AUE_audit_startup) == -1) {
- syslog(LOG_ERR, "Could not close audit startup event.\n");
- }
- }
-
- if (config_audit_controls(flags) == 0)
- syslog(LOG_INFO, "Initialization successful\n");
- else
- syslog(LOG_INFO, "Initialization failed\n");
-}
-
-
-int main(int argc, char **argv)
-{
- char ch;
- long flags = AUDIT_CNT;
- int debug = 0;
-
- while ((ch = getopt(argc, argv, "dhs")) != -1) {
- switch(ch) {
-
- /* debug option */
- case 'd':
- debug = 1;
- break;
-
- /* fail-stop option */
- case 's':
- flags &= ~(AUDIT_CNT);
- break;
-
- /* halt-stop option */
- case 'h':
- flags |= AUDIT_AHLT;
- break;
-
- case '?':
- default:
- (void)fprintf(stderr,
- "usage: auditd [-h | -s]\n");
- exit(1);
- }
- }
-
- openlog("auditd", LOG_CONS | LOG_PID, LOG_DAEMON);
- syslog(LOG_INFO, "starting...\n");
-
- if (debug == 0 && daemon(0, 0) == -1) {
- syslog(LOG_ERR, "Failed to daemonize\n");
- exit(1);
- }
-
- if(register_daemon() == -1) {
- syslog(LOG_ERR, "Could not register as daemon\n");
- exit(1);
- }
-
- setup(flags);
- wait_on_audit_trigger(port_set);
- syslog(LOG_INFO, "exiting.\n");
-
- exit(1);
-}
+++ /dev/null
-#ifndef _AUDITD_H_
-#define _AUDITD_H_
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <syslog.h>
-
-#define MAX_DIR_SIZE 255
-#define AUDITD_NAME "auditd"
-
-#define POSTFIX_LEN 16
-#define NOT_TERMINATED ".not_terminated"
-
-struct dir_ent {
- char *dirname;
- char softlim;
- TAILQ_ENTRY(dir_ent) dirs;
-};
-
-/* audit utility flags */
-#define OPEN_NEW 0x1
-#define READ_FILE 0x2
-#define CLOSE_AND_DIE 0x4
-
-#define HARDLIM_ALL_WARN "allhard"
-#define SOFTLIM_ALL_WARN "allsoft"
-#define AUDITOFF_WARN "aditoff"
-#define EBUSY_WARN "ebusy"
-#define GETACDIR_WARN "getacdir"
-#define HARDLIM_WARN "hard"
-#define NOSTART_WARN "nostart"
-#define POSTSIGTERM_WARN "postsigterm"
-#define SOFTLIM_WARN "soft"
-#define TMPFILE_WARN "tmpfile"
-
-#define AUDITWARN_SCRIPT "/etc/security/audit_warn"
-#define AUDITD_PIDFILE "/var/run/auditd.pid"
-
-int audit_warn_allhard(int count);
-int audit_warn_allsoft();
-int audit_warn_auditoff();
-int audit_warn_ebusy();
-int audit_warn_getacdir(char *filename);
-int audit_warn_hard(char *filename);
-int audit_warn_nostart();
-int audit_warn_postsigterm();
-int audit_warn_soft(char *filename);
-int audit_warn_tmpfile();
-
-#endif /* !_AUDITD_H_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "Portions Copyright (c) 2004 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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Exported client calls to the auditd facility.
- */
-
-subsystem
- KernelUser
- auditd_control 456;
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-
-simpleroutine auditd_control(
- auditd_port : mach_port_t;
- in flags : int);
-
+++ /dev/null
-##
-# Startup script for Common Criteria Auditing function.
-##
-# Copyright 2004 Apple Computer, Inc.
-##
-
-. /etc/rc.common
-
-##
-# Start the audit daemon (if present)
-##
-if [ "${AUDIT:=-NO-}" == "-YES-" ]; then
- if [ -f /usr/sbin/auditd ]; then
- /usr/sbin/auditd
- fi
-elif [ "${AUDIT:=-NO-}" == "-FAILSTOP-" ]; then
- if [ -f /usr/sbin/auditd ]; then
- /usr/sbin/auditd -s
- fi
-elif [ "${AUDIT:=-NO-}" == "-FAILHALT-" ]; then
- if [ -f /usr/sbin/auditd ]; then
- /usr/sbin/auditd -h
- fi
-
-fi
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
}
return l;
}
-
-char *itoa(int n)
-{
- char s[32];
-
- sprintf(s, "%d", n);
- return copyString(s);
-}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
char *suffix(char *, char);
char *lowerCase(char *);
char **explode(char *, char);
-char *itoa(int);
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
.Ar filesize .
.It Fl P
This option is currently unimplemented.
+.El
.Sh FILES
-.Bl -tag -width /private/var/vp/swapfile* --compact
+.Bl -tag -width /private/var/vp/swapfile* -compact
.It Pa /private/var/vm/swapfile*
Default external paging files.
-.Sh SEE ALSO
-.Xr macx_swapon 2 ,
-.Xr macx_swapoff 2 .
+.El
return kr;
mlock(bufReply, max_size + MAX_TRAILER_SIZE);
while(TRUE) {
- mr = mach_msg_overwrite_trap(&bufRequest->Head, MACH_RCV_MSG|options,
- 0, max_size, rcv_name,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL,
- (mach_msg_header_t *) 0, 0);
+ mr = mach_msg(&bufRequest->Head, MACH_RCV_MSG|options,
+ 0, max_size, rcv_name,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
if (mr == MACH_MSG_SUCCESS) {
/* we have a request message */
sprintf(subfile, "%s%d", fileroot, file_count);
file_ptr = fopen(subfile, "w+");
- fchmod(fileno(file_ptr), (mode_t)01600);
- error = fcntl(fileno(file_ptr), F_SETSIZE, &filesize);
- if(error) {
- error = ftruncate(fileno(file_ptr), filesize);
+ if (file_ptr == NULL) {
+ /* force error recovery below */
+ error = -1;
+ } else {
+ fchmod(fileno(file_ptr), (mode_t)01600);
+ error = fcntl(fileno(file_ptr), F_SETSIZE, &filesize);
+ if(error) {
+ error = ftruncate(fileno(file_ptr), filesize);
+ }
+ if(error)
+ unlink(subfile);
+ fclose(file_ptr);
}
- fclose(file_ptr);
if(error == -1) {
- unlink(subfile);
file_count--;
if (file_count > max_valid)
result = server_alert_loop(4096, trigger_port, MACH_MSG_OPTION_NONE);
if (result != KERN_SUCCESS) {
fprintf(stderr, "dynamic_pager: default pager alert failed\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
- exit(0);
+ exit(EXIT_SUCCESS);
}
void
file_count = 0;
sprintf(subfile, "%s%d", fileroot, file_count);
file_ptr = fopen(subfile, "w+");
+ if (file_ptr == NULL) {
+ fprintf(stderr, "dynamic_pager: cannot create paging file %s!\n",
+ subfile);
+ exit(EXIT_FAILURE);
+ }
fchmod(fileno(file_ptr), (mode_t)01600);
+
error = fcntl(fileno(file_ptr), F_SETSIZE, &filesize);
if(error) {
- error = ftruncate(fileno(file_ptr), filesize);
+ error = ftruncate(fileno(file_ptr), filesize);
}
fclose(file_ptr);
+
+ if (error == -1) {
+ fprintf(stderr, "dynamic_pager: cannot extend paging file size %s to %llu!\n",
+ subfile, filesize);
+ exit(EXIT_FAILURE);
+ }
macx_swapon(subfile, flags, size, priority);
if (mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
&trigger_port) != KERN_SUCCESS) {
- fprintf(stderr,"allocation of trigger port failed\n");
- exit(1);
+ fprintf(stderr,"dynamic_pager: allocation of trigger port failed\n");
+ exit(EXIT_FAILURE);
}
/* create a send right on our local port */
mach_port_extract_right(mach_task_self(), trigger_port,
set_dp_control_port(mach_host_self(), trigger_port);
wait_on_paging_trigger(trigger_port);
}
- exit(0);
+ exit(EXIT_SUCCESS);
}
int
main(int argc, char **argv)
default:
(void)fprintf(stderr,
"usage: dynamic_pager [-F filename] [-L low water alert trigger] [-H high water alert trigger] [-S file size] [-P priority]\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
}
* space is left on the volume being used for swap and the amount of physical ram
* installed on the system...
* basically, we'll pick a maximum size that doesn't exceed the following limits...
- * 1/4 the remaining free space of the swap volume
+ * 1/8 the remaining free space of the swap volume
* the size of phsyical ram
* MAXIMUM_SIZE - currently set to 1 Gbyte...
* once we have the maximum, we'll create a list of sizes and low_water limits
if (statfs(tmp, &sfs) != -1) {
/*
- * limit the maximum size of a swap file to 1/4 the free
+ * Limit the maximum size of a swap file to 1/8 the free
* space available on the filesystem where the swap files
- * are to reside
+ * are to reside. This will allow us to allocate and
+ * deallocate in finer increments on systems without much
+ * free space.
*/
- fs_limit = ((u_int64_t)sfs.f_bfree * (u_int64_t)sfs.f_bsize) / 4;
+ fs_limit = ((u_int64_t)sfs.f_bfree * (u_int64_t)sfs.f_bsize) / 8;
} else {
- (void)fprintf(stderr, "usage: swap directory must exist\n");
- exit(1);
+ (void)fprintf(stderr, "dynamic_pager: swap directory must exist\n");
+ exit(EXIT_FAILURE);
}
mib[0] = CTL_HW;
mib[1] = HW_MEMSIZE;
else
limits[i].low_water = size + limits[i - 1].size;
}
- if (size >= memsize)
- break;
if (i) {
/*
* make the first 2 files the same size
*/
size = size * 2;
+ if (size > memsize)
+ break;
}
max_valid++;
}
local_hi_water = hi_water;
if((limits[0].low_water != 0) && (limits[0].low_water <= (limits[0].size + hi_water))) {
- (void)fprintf(stderr, "usage: low water trigger must be larger than size + hi_water\n");
- exit(1);
+ (void)fprintf(stderr, "dynamic_pager: low water trigger must be larger than size + hi_water\n");
+ exit(EXIT_FAILURE);
}
argc -= optind;
argv += optind;
.Nd report system calls and page faults related to filesystem activity in
real-time
.Sh SYNOPSIS
-.Nm fs_usage [-e] [-w] [-f mode] [ pid|cmd [pid|cmd] ...]
+.Nm fs_usage [-e] [-w] [-f mode [-f mode] ...] [ pid|cmd [pid|cmd] ...]
.Sh DESCRIPTION
The
.Nm fs_usage
option turns on output filtering based on the
.Pa mode
provided.
-By default no filtering occurs.
+Multiple filtering options can be specified.
+By default no output filtering occurs.
The supported modes are:
.Pp
.Pa network
.Pp
.Pa filesys
Only file system related output is displayed.
+.Pp
+.Pa cachehit
+Exclude CACHE_HIT output from the displayed data.
.It pid | cmd
The sampled data can be limited to a list of process ids or commands.
When a command name is given, all processes with that name will be sampled.
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
* Network only or filesystem only output filter
* Default of zero means report all activity - no filtering
*/
-#define FILESYS_FILTER 0x01
-#define NETWORK_FILTER 0x02
-#define DEFAULT_DO_NOT_FILTER 0x0
+#define FILESYS_FILTER 1
+#define NETWORK_FILTER 2
+#define CACHEHIT_FILTER 4
+#define DEFAULT_DO_NOT_FILTER 0
int filter_mode = DEFAULT_DO_NOT_FILTER;
#define NFS_DEV -1
void cache_disk_names();
int ReadSegAddrTable();
void mark_thread_waited(int);
-int check_filter_mode(struct th_info *, int, int, int);
+int check_filter_mode(struct th_info *, int, int, int, char *);
void fs_usage_fd_set(unsigned int, unsigned int);
int fs_usage_fd_isset(unsigned int, unsigned int);
void fs_usage_fd_clear(unsigned int, unsigned int);
int get_real_command_name(int, char *, int);
void create_map_entry(int, int, char *);
-#define DBG_ZERO_FILL_FAULT 1
-#define DBG_PAGEIN_FAULT 2
-#define DBG_COW_FAULT 3
-#define DBG_CACHE_HIT_FAULT 4
-
#define TRACE_DATA_NEWTHREAD 0x07000004
#define TRACE_DATA_EXEC 0x07000008
#define TRACE_STRING_NEWTHREAD 0x07010004
int quit();
if ( geteuid() != 0 ) {
- printf("'fs_usage' must be run as root...\n");
+ fprintf(stderr, "'fs_usage' must be run as root...\n");
exit(1);
}
get_screenwidth();
filter_mode |= NETWORK_FILTER;
else if (!strcmp(optarg, "filesys"))
filter_mode |= FILESYS_FILTER;
+ else if (!strcmp(optarg, "cachehit"))
+ filter_mode |= CACHEHIT_FILTER; /* turns off CACHE_HIT */
break;
default:
for (i = 0; i < num_of_pids; i++)
{
if (exclude_pids)
- printf("exclude pid %d\n", pids[i]);
+ fprintf(stderr, "exclude pid %d\n", pids[i]);
else
- printf("pid %d\n", pids[i]);
+ fprintf(stderr, "pid %d\n", pids[i]);
}
#endif
if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
if (on_off == 1)
- printf("pid %d does not exist\n", pid);
+ fprintf(stderr, "pid %d does not exist\n", pid);
}
else {
one_good_pid++;
if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
if (on_off == 1)
- printf("pid %d does not exist\n", pid);
+ fprintf(stderr, "pid %d does not exist\n", pid);
}
}
count = needed;
if (bufinfo.flags & KDBG_WRAPPED) {
- printf("buffer wrapped count = %d\n", count);
+ fprintf(stderr, "buffer wrapped count = %d\n", count);
for (i = 0; i < cur_max; i++) {
th_state[i].thread = 0;
}
kd = (kd_buf *)my_buffer;
#if 0
- printf("READTR returned %d items\n", count);
+ fprintf(stderr, "READTR returned %d items\n", count);
#endif
for (i = 0; i < count; i++) {
int debugid, thread;
void extend_syscall();
void kill_thread_map();
- thread = kd[i].arg5 & KDBG_THREAD_MASK;
+ thread = kd[i].arg5;
debugid = kd[i].debugid;
type = kd[i].debugid & DBG_FUNC_MASK;
- now = kd[i].timestamp;
+ now = kd[i].timestamp & KDBG_TIMESTAMP_MASK;
if (i == 0)
{
if ((ti = find_thread(thread, type)) == (struct th_info *)0)
return;
- if (check_filter_mode(ti, type, error, retval))
+ if (check_filter_mode(ti, type, error, retval, sc_name))
format_print(ti, sc_name, thread, type, error, retval, has_fd, has_ret, now, ti->stime, ti->waited, ti->pathname, NULL);
if (ti == &th_state[cur_max - 1])
if (set_remove_flag)
set_remove();
- printf("fs_usage: ");
+ fprintf(stderr, "fs_usage: ");
if (s)
- printf("%s", s);
+ fprintf(stderr, "%s", s);
exit(1);
}
p = " ";
break;
}
- if (check_filter_mode(NULL, dio->type,0, 0))
+ if (check_filter_mode(NULL, dio->type,0, 0, p))
format_print(NULL, p, dio->issuing_thread, dio->type, 0, 0, 0, 7, dio->completed_time, dio->issued_time, 1, "", dio);
}
/* If the map is not big enough, then reallocate it */
while (fdmap->fd_setsize < fd)
{
- printf("reallocating bitmap for threadid %d, fd = %d, setsize = %d\n",
+ fprintf(stderr, "reallocating bitmap for threadid %d, fd = %d, setsize = %d\n",
thread, fd, fdmap->fd_setsize);
n = fdmap->fd_setsize * 2;
fdmap->fd_setptr = (unsigned long *)realloc(fdmap->fd_setptr, (FS_USAGE_NFDBYTES(n)));
* ret = 0 means don't print the entry
*/
int
-check_filter_mode(struct th_info * ti, int type, int error, int retval)
+check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc_name)
{
int ret = 0;
int network_fd_isset = 0;
if (filter_mode == DEFAULT_DO_NOT_FILTER)
return(1);
+ if (filter_mode & CACHEHIT_FILTER)
+ {
+ /* Do not print if cachehit filter is set */
+ if (!strcmp (sc_name, "CACHE_HIT"))
+ return(0);
+ }
+
if (ti == (struct th_info *)0)
{
if(filter_mode & FILESYS_FILTER)
ret = 0;
return(ret);
}
-
switch (type) {
case BSC_close:
--- /dev/null
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = getconf
+
+PROJECTVERSION = 1.0
+PROJECT_TYPE = Tool
+
+CFILES = getconf.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
+ _fbsd_compat.h confstr.gperf fake-gperf.awk getconf.1\
+ getconf.h limits.gperf pathconf.gperf progenv.gperf sysconf.gperf
+OTHER_GENERATED_SRCFILES = $(OBJROOT)/confstr.c $(OBJROOT)/limits.c\
+ $(OBJROOT)/pathconf.c $(OBJROOT)/progenv.c $(OBJROOT)/sysconf.c
+OTHER_GENERATED_OFILES = confstr.o limits.o pathconf.o progenv.o sysconf.o
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
+LIBS =
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
--- /dev/null
+INSTALL_AS_USER = root
+
+after_install::
+ install -o $(INSTALL_AS_USER) -m 755 -d $(DSTROOT)/usr/share/man/man1
+ install -o $(INSTALL_AS_USER) -m 644 -c getconf.1 \
+ $(DSTROOT)/usr/share/man/man1
--- /dev/null
+-include ../Makefile.include
+
+$(OBJROOT)/%.c: %.gperf
+ LC_ALL=C awk -f fake-gperf.awk $< > $@
+
+OTHER_CFLAGS += -include _fbsd_compat.h -DAPPLE_GETCONF_UNDERSCORE \
+ -DAPPLE_GETCONF_SPEC
+vpath %.c $(OBJROOT)
--- /dev/null
+{
+ DOCICONFILES = ();
+ FILESTABLE = {
+ CLASSES = ();
+ OTHER_LIBS = ();
+ OTHER_LINKED = (dummy.c);
+ OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble);
+ SUBPROJECTS = ();
+ };
+ LANGUAGE = English;
+ LOCALIZABLE_FILES = {};
+ NEXTSTEP_INSTALLDIR = /usr/bin;
+ NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
+ NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
+ PDO_UNIX_INSTALLDIR = /usr/bin;
+ PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac";
+ PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
+ PROJECTNAME = usr-share-locale;
+ PROJECTTYPE = Tool;
+ PROJECTVERSION = 2.8;
+ WINDOWS_INSTALLDIR = /usr/bin;
+ WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
+ WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
+}
--- /dev/null
+#define __FBSDID(x)
+#ifdef __ppc__
+#define __powerpc__
+#endif /* __ppc__ */
--- /dev/null
+%{
+/*
+ * Copyright is disclaimed as to the contents of this file.
+ *
+ * $FreeBSD: src/usr.bin/getconf/confstr.gperf,v 1.5 2003/08/22 17:32:07 markm Exp $
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#include "getconf.h"
+
+/*
+ * Override gperf's built-in external scope.
+ */
+static const struct map *in_word_set(const char *str);
+
+/*
+ * The Standard seems a bit ambiguous over whether the POSIX_V6_*
+ * are specified with or without a leading underscore, so we just
+ * use both.
+ */
+%}
+struct map { const char *name; int key; int valid; };
+%%
+PATH, _CS_PATH
+POSIX_V6_ILP32_OFF32_CFLAGS, _CS_POSIX_V6_ILP32_OFF32_CFLAGS
+POSIX_V6_ILP32_OFF32_LDFLAGS, _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
+POSIX_V6_ILP32_OFF32_LIBS, _CS_POSIX_V6_ILP32_OFF32_LIBS
+POSIX_V6_ILP32_OFFBIG_CFLAGS, _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
+POSIX_V6_ILP32_OFFBIG_LDFLAGS, _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
+POSIX_V6_ILP32_OFFBIG_LIBS, _CS_POSIX_V6_ILP32_OFFBIG_LIBS
+POSIX_V6_LP64_OFF64_CFLAGS, _CS_POSIX_V6_LP64_OFF64_CFLAGS
+POSIX_V6_LP64_OFF64_LDFLAGS, _CS_POSIX_V6_LP64_OFF64_LDFLAGS
+POSIX_V6_LP64_OFF64_LIBS, _CS_POSIX_V6_LP64_OFF64_LIBS
+POSIX_V6_LPBIG_OFFBIG_CFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
+POSIX_V6_LPBIG_OFFBIG_LDFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
+POSIX_V6_LPBIG_OFFBIG_LIBS, _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
+POSIX_V6_WIDTH_RESTRICTED_ENVS, _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS
+_POSIX_V6_ILP32_OFF32_CFLAGS, _CS_POSIX_V6_ILP32_OFF32_CFLAGS
+_POSIX_V6_ILP32_OFF32_LDFLAGS, _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
+_POSIX_V6_ILP32_OFF32_LIBS, _CS_POSIX_V6_ILP32_OFF32_LIBS
+_POSIX_V6_ILP32_OFFBIG_CFLAGS, _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
+_POSIX_V6_ILP32_OFFBIG_LDFLAGS, _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
+_POSIX_V6_ILP32_OFFBIG_LIBS, _CS_POSIX_V6_ILP32_OFFBIG_LIBS
+_POSIX_V6_LP64_OFF64_CFLAGS, _CS_POSIX_V6_LP64_OFF64_CFLAGS
+_POSIX_V6_LP64_OFF64_LDFLAGS, _CS_POSIX_V6_LP64_OFF64_LDFLAGS
+_POSIX_V6_LP64_OFF64_LIBS, _CS_POSIX_V6_LP64_OFF64_LIBS
+_POSIX_V6_LPBIG_OFFBIG_CFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
+_POSIX_V6_LPBIG_OFFBIG_LDFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
+_POSIX_V6_LPBIG_OFFBIG_LIBS, _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
+_POSIX_V6_WIDTH_RESTRICTED_ENVS, _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS
+%%
+int
+find_confstr(const char *name, int *key)
+{
+ const struct map *rv;
+
+ rv = in_word_set(name);
+ if (rv != NULL) {
+ if (rv->valid) {
+ *key = rv->key;
+ return 1;
+ }
+ return -1;
+ }
+ return 0;
+}
--- /dev/null
+#!/usr/bin/awk -f
+# $FreeBSD: src/usr.bin/getconf/fake-gperf.awk,v 1.3 2003/08/22 17:32:07 markm Exp $
+BEGIN {
+ state = 0;
+ struct_seen = "";
+}
+/^%{$/ && state == 0 {
+ state = 1;
+ next;
+}
+/^%}$/ && state == 1 {
+ state = 0;
+ next;
+}
+state == 1 { print; next; }
+/^struct/ && state == 0 {
+ print;
+ struct_seen = $2;
+ next;
+}
+/^%%$/ && state == 0 {
+ state = 2;
+ if (struct_seen !~ /^$/) {
+ print "static const struct", struct_seen, "wordlist[] = {";
+ } else {
+ print "static const struct map {";
+ print "\tconst char *name;";
+ print "\tint key;";
+ print "\tint valid;";
+ print "} wordlist[] = {";
+ struct_seen = "map";
+ }
+ next;
+}
+/^%%$/ && state == 2 {
+ state = 3;
+ print "\t{ NULL, 0, 0 }";
+ print "};";
+ print "#define\tNWORDS\t(sizeof(wordlist)/sizeof(wordlist[0]) - 1)";
+ print "static const struct map *";
+ print "in_word_set(const char *word)";
+ print "{";
+ print "\tconst struct", struct_seen, "*mp;";
+ print "";
+ print "\tfor (mp = wordlist; mp < &wordlist[NWORDS]; mp++) {";
+ print "\t\tif (strcmp(word, mp->name) == 0)";
+ print "\t\t\treturn (mp);";
+ print "\t}";
+ print "\treturn (NULL);";
+ print "}";
+ print "";
+ next;
+}
+state == 2 && NF == 2 {
+ name = substr($1, 1, length($1) - 1);
+ printf "#ifdef %s\n", $2;
+ printf "\t{ \"%s\", %s, 1 },\n", name, $2;
+ print "#else";
+ printf "\t{ \"%s\", 0, 0 },\n", name, $2;
+ print "#endif"
+ next;
+}
+state == 3 { print; next; }
+{
+ # eat anything not matched.
+}
--- /dev/null
+.\"
+.\" Copyright 2000 Massachusetts Institute of Technology
+.\"
+.\" Permission to use, copy, modify, and distribute this software and
+.\" its documentation for any purpose and without fee is hereby
+.\" granted, provided that both the above copyright notice and this
+.\" permission notice appear in all copies, that both the above
+.\" copyright notice and this permission notice appear in all
+.\" supporting documentation, and that the name of M.I.T. not be used
+.\" in advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission. M.I.T. makes
+.\" no representations about the suitability of this software for any
+.\" purpose. It is provided "as is" without express or implied
+.\" warranty.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+.\" SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/usr.bin/getconf/getconf.1,v 1.12 2003/09/08 19:57:21 ru Exp $
+.\"
+.Dd September 18, 2002
+.Dt GETCONF 1
+.Os
+.Sh NAME
+.Nm getconf
+.Nd retrieve standard configuration variables
+.Sh SYNOPSIS
+.Nm
+.Op Fl v Ar environment
+.Ar path_var
+.Ar file
+.Nm
+.Op Fl v Ar environment
+.Ar system_var
+.Sh DESCRIPTION
+The
+.Nm
+utility prints the value of a
+.Tn POSIX
+or
+.Tn X/Open
+path or system configuration variable to the standard output.
+If the specified variable is undefined, the string
+.Dq Li undefined
+is output.
+.Pp
+The first form of the command, with two mandatory
+arguments, retrieves file- and file system-specific
+configuration variables using
+.Xr pathconf 2 .
+The second form, with a single argument, retrieves system
+configuration variables using
+.Xr confstr 3
+and
+.Xr sysconf 3 ,
+depending on the type of variable.
+As an extension, the second form can also be used to query static limits from
+.In limits.h .
+.Pp
+All
+.Xr sysconf 3
+and
+.Xr pathconf 2
+variables use the same name as the manifest constants defined in
+the relevant standard C-language bindings, including any leading
+underscore or prefix.
+That is to say,
+.Ar system_var
+might be
+.Dv ARG_MAX
+or
+.Dv _POSIX_VERSION ,
+as opposed to the
+.Xr sysconf 3
+names
+.Dv _SC_ARG_MAX
+or
+.Dv _SC_POSIX_VERSION .
+Variables retrieved from
+.Xr confstr 3
+have the leading
+.Ql _CS_
+stripped off; thus,
+.Dv _CS_PATH
+is queried by a
+.Ar system_var
+of
+.Dq Li PATH .
+.Ss Programming Environments
+The
+.Fl v Ar environment
+option specifies a
+.St -p1003.1-2001
+programming environment under which the values are to be queried.
+This option currently does nothing, but may in the future be used
+to select between 32-bit and 64-bit execution environments on platforms
+which support both.
+Specifying an environment which is not supported on the current execution
+platform gives undefined results.
+.Pp
+The standard programming environments are as follows:
+.Bl -tag -width ".Li POSIX_V6_LPBIG_OFFBIG" -offset indent
+.It Li POSIX_V6_ILP32_OFF32
+Exactly 32-bit integer, long, pointer, and file offset.
+.Sy Supported platforms :
+None.
+.It Li POSIX_V6_ILP32_OFFBIG
+Exactly 32-bit integer, long, and pointer; at least 64-bit file offset.
+.Sy Supported platforms :
+.Tn IA32 ,
+.Tn PowerPC .
+.It Li POSIX_V6_LP64_OFF64
+Exactly 32-bit integer; exactly 64-bit long, pointer, and file offset.
+.Sy Supported platforms :
+.Tn Alpha ,
+.Tn SPARC64 .
+.It Li POSIX_V6_LPBIG_OFFBIG
+At least 32-bit integer; at least 64-bit long, pointer, and file offset.
+.Sy Supported platforms :
+None.
+.El
+.Pp
+The command:
+.Pp
+.Dl "getconf POSIX_V6_WIDTH_RESTRICTED_ENVS"
+.Pp
+returns a newline-separated list of environments in which the width
+of certain fundamental types is no greater than the width of the native
+C type
+.Vt long .
+At present, all programming environments supported by
+.Fx
+have this property.
+Several of the
+.Xr confstr 3
+variables provide information on the necessary compiler and linker flags
+to use the standard programming environments described above.
+.Sh DIAGNOSTICS
+.Ex -std
+Use of a
+.Ar system_var
+or
+.Ar path_var
+which is completely unrecognized is considered an error,
+causing a diagnostic message to be written to standard error.
+One
+which is known but merely undefined does not result in an error
+indication.
+The
+.Nm
+utility recognizes all of the variables defined for
+.St -p1003.1-2001 ,
+including those which are not currently implemented.
+.Sh EXAMPLES
+The command:
+.Pp
+.Dl "getconf PATH"
+.Pp
+will display the system default setting for the
+.Ev PATH
+environment variable.
+.Pp
+The command:
+.Pp
+.Dl "getconf NAME_MAX /tmp"
+.Pp
+will display the maximum length of a filename in the
+.Pa /tmp
+directory.
+.Pp
+The command:
+.Pp
+.Dl "getconf -v POSIX_V6_LPBIG_OFFBIG LONG_MAX"
+.Pp
+will display the maximum value of the C type
+.Vt long
+in the
+.Li POSIX_V6_LPBIG_OFFBIG
+programming environment,
+if the system supports that environment.
+.Sh SEE ALSO
+.Xr pathconf 2 ,
+.Xr confstr 3 ,
+.Xr sysconf 3
+.Sh STANDARDS
+The
+.Nm
+utility is expected to be compliant with
+.St -p1003.1-2001 .
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 5.0 .
+.Sh AUTHORS
+.An Garrett A. Wollman Aq wollman@lcs.mit.edu
--- /dev/null
+/*
+ * Copyright 2000 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/usr.bin/getconf/getconf.c,v 1.9 2003/08/22 17:32:07 markm Exp $");
+
+#include <sys/types.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "getconf.h"
+
+static void do_confstr(const char *name, int key);
+static void do_sysconf(const char *name, int key);
+static void do_pathconf(const char *name, int key, const char *path);
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+"usage: getconf [-v prog_env] system_var\n"
+" getconf [-v prog_env] path_var pathname\n");
+ exit(EX_USAGE);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c, key, valid;
+ const char *name, *vflag, *alt_path;
+ intmax_t limitval;
+
+ vflag = NULL;
+ while ((c = getopt(argc, argv, "v:")) != -1) {
+ switch (c) {
+ case 'v':
+ vflag = optarg;
+ break;
+
+ default:
+ usage();
+ }
+ }
+
+ if ((name = argv[optind]) == NULL)
+ usage();
+
+ if (vflag != NULL) {
+ if ((valid = find_progenv(vflag, &alt_path)) == 0)
+ errx(EX_USAGE, "invalid programming environment %s",
+ vflag);
+ if (valid > 0 && alt_path != NULL) {
+ if (argv[optind + 1] == NULL)
+ execl(alt_path, "getconf", argv[optind],
+ (char *)NULL);
+ else
+ execl(alt_path, "getconf", argv[optind],
+ argv[optind + 1], (char *)NULL);
+
+ err(EX_OSERR, "execl: %s", alt_path);
+ }
+ if (valid < 0)
+ errx(EX_UNAVAILABLE, "environment %s is not available",
+ vflag);
+ }
+
+ if (argv[optind + 1] == NULL) { /* confstr or sysconf */
+#ifdef APPLE_GETCONF_SPEC
+ if ((valid = find_progenv(name, &alt_path)) != 0) {
+ printf(valid > 0 ? "defined\n" : "undefined\n");
+ return 0;
+ }
+#endif /* APPLE_GETCONF_SPEC */
+ if ((valid = find_limit(name, &limitval)) != 0) {
+ if (valid > 0)
+ printf("%" PRIdMAX "\n", limitval);
+ else
+ printf("undefined\n");
+
+ return 0;
+ }
+ if ((valid = find_confstr(name, &key)) != 0) {
+ if (valid > 0)
+ do_confstr(name, key);
+ else
+ printf("undefined\n");
+ } else {
+ valid = find_sysconf(name, &key);
+ if (valid > 0) {
+ do_sysconf(name, key);
+ } else if (valid < 0) {
+ printf("undefined\n");
+ } else
+ errx(EX_USAGE,
+ "no such configuration parameter `%s'",
+ name);
+ }
+ } else {
+ valid = find_pathconf(name, &key);
+ if (valid != 0) {
+ if (valid > 0)
+ do_pathconf(name, key, argv[optind + 1]);
+ else
+ printf("undefined\n");
+ } else
+ errx(EX_USAGE,
+ "no such path configuration parameter `%s'",
+ name);
+ }
+ return 0;
+}
+
+static void
+do_confstr(const char *name, int key)
+{
+ size_t len;
+
+ len = confstr(key, 0, 0);
+ if (len == (size_t)-1)
+ err(EX_OSERR, "confstr: %s", name);
+
+ if (len == 0)
+ printf("undefined\n");
+ else {
+ char buf[len + 1];
+
+ confstr(key, buf, len);
+ printf("%s\n", buf);
+ }
+}
+
+static void
+do_sysconf(const char *name, int key)
+{
+ long value;
+
+ errno = 0;
+ value = sysconf(key);
+ if (value == -1 && errno != 0)
+ err(EX_OSERR, "sysconf: %s", name);
+ else if (value == -1)
+ printf("undefined\n");
+ else
+ printf("%ld\n", value);
+}
+
+static void
+do_pathconf(const char *name, int key, const char *path)
+{
+ long value;
+
+ errno = 0;
+ value = pathconf(path, key);
+ if (value == -1 && errno != 0)
+ err(EX_OSERR, "pathconf: %s", name);
+ else if (value == -1)
+ printf("undefined\n");
+ else
+ printf("%ld\n", value);
+}
+
--- /dev/null
+/*
+ * Copyright 2000 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/usr.bin/getconf/getconf.h,v 1.4 2002/10/27 04:14:08 wollman Exp $
+ */
+
+#ifdef STABLE
+typedef long long intmax_t;
+#define PRIdMAX "lld"
+#else
+#include <inttypes.h>
+#endif
+
+int find_confstr(const char *name, int *key);
+int find_limit(const char *name, intmax_t *value);
+int find_pathconf(const char *name, int *key);
+int find_progenv(const char *name, const char **alt_path);
+int find_sysconf(const char *name, int *key);
--- /dev/null
+%{
+/*
+ * Copyright is disclaimed as to the contents of this file.
+ *
+ * $FreeBSD: src/usr.bin/getconf/limits.gperf,v 1.2 2003/08/22 17:32:07 markm Exp $
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+#include <limits.h>
+#ifdef APPLE_GETCONF_UNDERSCORE
+#include <alloca.h>
+#endif /* APPLE_GETCONF_UNDERSCORE */
+
+#include "getconf.h"
+
+/*
+ * Override gperf's built-in external scope.
+ */
+static const struct map *in_word_set(const char *str);
+
+%}
+struct map { const char *name; intmax_t value; int valid; };
+%%
+_POSIX_CLOCKRES_MIN, _POSIX_CLOCKRES_MIN
+_POSIX_AIO_LISTIO_MAX, _POSIX_AIO_LISTIO_MAX
+_POSIX_AIO_MAX, _POSIX_AIO_MAX
+_POSIX_ARG_MAX, _POSIX_ARG_MAX
+_POSIX_CHILD_MAX, _POSIX_CHILD_MAX
+_POSIX_DELAYTIMER_MAX, _POSIX_DELAYTIMER_MAX
+_POSIX2_EXPR_NEST_MAX, _POSIX2_EXPR_NEST_MAX
+_POSIX_HOST_NAME_MAX, _POSIX_HOST_NAME_MAX
+_POSIX_LINK_MAX, _POSIX_LINK_MAX
+_POSIX_LOGIN_NAME_MAX, _POSIX_LOGIN_NAME_MAX
+_POSIX_MAX_CANON, _POSIX_MAX_CANON
+_POSIX_MAX_INPUT, _POSIX_MAX_INPUT
+_POSIX_MQ_OPEN_MAX, _POSIX_MQ_OPEN_MAX
+_POSIX_MQ_PRIO_MAX, _POSIX_MQ_PRIO_MAX
+_POSIX_NAME_MAX, _POSIX_NAME_MAX
+_POSIX_NGROUPS_MAX, _POSIX_NGROUPS_MAX
+_POSIX_OPEN_MAX, _POSIX_OPEN_MAX
+_POSIX_PATH_MAX, _POSIX_PATH_MAX
+_POSIX_PIPE_BUF, __POSIX_PIPE_BUF
+_POSIX_RE_DUP_MAX, _POSIX_RE_DUP_MAX
+_POSIX_RTSIG_MAX, _POSIX_RTSIG_MAX
+_POSIX_SEM_NSEMS_MAX, _POSIX_SEM_NSEMS_MAX
+_POSIX_SEM_VALUE_MAX, _POSIX_SEM_VALUE_MAX
+_POSIX_SIGQUEUE_MAX, _POSIX_SIGQUEUE_MAX
+_POSIX_SSIZE_MAX, _POSIX_SSIZE_MAX
+_POSIX_STREAM_MAX, _POSIX_STREAM_MAX
+_POSIX_SS_REPL_MAX, _POSIX_SS_REPL_MAX
+_POSIX_SYMLINK_MAX, _POSIX_SYMLINK_MAX
+_POSIX_SYMLOOP_MAX, _POSIX_SYMLOOP_MAX
+_POSIX_THREAD_DESTRUCTOR_ITERATIONS, _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+_POSIX_THREAD_KEYS_MAX, _POSIX_THREAD_KEYS_MAX
+_POSIX_THREAD_THREADS_MAX, _POSIX_THREAD_THREADS_MAX
+_POSIX_TIMER_MAX, _POSIX_TIMER_MAX
+_POSIX_TRACE_EVENT_NAME_MAX, _POSIX_TRACE_EVENT_NAME_MAX
+_POSIX_TRACE_NAME_MAX, _POSIX_TRACE_NAME_MAX
+_POSIX_TRACE_SYS_MAX, _POSIX_TRACE_SYS_MAX
+_POSIX_TRACE_USER_EVENT_MAX, _POSIX_TRACE_USER_EVENT_MAX
+_POSIX_TTY_NAME_MAX, _POSIX_TTY_NAME_MAX
+_POSIX_TZNAME_MAX, _POSIX_TZNAME_MAX
+_POSIX2_BC_BASE_MAX, _POSIX2_BC_BASE_MAX
+_POSIX2_BC_DIM_MAX, _POSIX2_BC_DIM_MAX
+_POSIX2_BC_SCALE_MAX, _POSIX2_BC_SCALE_MAX
+_POSIX2_BC_STRING_MAX, _POSIX2_BC_STRING_MAX
+_POSIX2_CHARCLASS_NAME_MAX, _POSIX2_CHARCLASS_NAME_MAX
+_POSIX2_COLL_WEIGHTS_MAX, _POSIX2_COLL_WEIGHTS_MAX
+_POSIX2_EXPR_NEXT_MAX, _POSIX2_EXPR_NEST_MAX
+_POSIX2_LINE_MAX, _POSIX2_LINE_MAX
+_POSIX2_RE_DUP_MAX, _POSIX2_RE_DUP_MAX
+_XOPEN_IOV_MAX, _XOPEN_IOV_MAX
+_XOPEN_NAME_MAX, _XOPEN_NAME_MAX
+_XOPEN_PATH_MAX, _XOPEN_PATH_MAX
+CHAR_BIT, CHAR_BIT
+CHAR_MAX, CHAR_MAX
+CHAR_MIN, CHAR_MIN
+INT_MAX, INT_MAX
+INT_MIN, INT_MIN
+LLONG_MIN, LLONG_MIN
+LLONG_MAX, LLONG_MAX
+LONG_BIT, LONG_BIT
+LONG_MAX, LONG_MAX
+LONG_MIN, LONG_MIN
+MB_LEN_MAX, MB_LEN_MAX
+SCHAR_MAX, SCHAR_MAX
+SCHAR_MIN, SCHAR_MIN
+SHRT_MAX, SHRT_MAX
+SHRT_MIN, SHRT_MIN
+SSIZE_MAX, SSIZE_MAX
+UCHAR_MAX, UCHAR_MAX
+UINT_MAX, UINT_MAX
+ULLONG_MAX, ULLONG_MAX
+ULONG_MAX, ULONG_MAX
+USHRT_MAX, USHRT_MAX
+WORD_BIT, WORD_BIT
+CHARCLASS_NAME_MAX, CHARCLASS_NAME_MAX
+NL_ARGMAX, NL_ARGMAX
+ML_LANGMAX, NL_LANGMAX
+NL_MSGMAX, NL_MSGMAX
+NL_NMAX, NL_NMAX
+NL_SETMAX, NL_SETMAX
+NL_TEXTMAX, NL_TEXTMAX
+NZERO, NZERO
+%%
+int
+find_limit(const char *name, intmax_t *value)
+{
+ const struct map *rv;
+#ifdef APPLE_GETCONF_UNDERSCORE
+ char *alt;
+#endif /* APPLE_GETCONF_UNDERSCORE */
+
+ rv = in_word_set(name);
+ if (rv != NULL) {
+ if (rv->valid) {
+ *value = rv->value;
+ return 1;
+ }
+ return -1;
+ }
+#ifdef APPLE_GETCONF_UNDERSCORE
+ if(*name == '_')
+ alt = name + 1;
+ else {
+ if((alt = (char *)alloca(strlen(name) + 2)) == NULL)
+ return 0;
+ *alt = '_';
+ strcpy(alt + 1, name);
+ }
+ rv = in_word_set(alt);
+ if (rv != NULL) {
+ if (rv->valid) {
+ *value = rv->value;
+ return 1;
+ }
+ return -1;
+ }
+#endif /* APPLE_GETCONF_UNDERSCORE */
+ return 0;
+}
--- /dev/null
+%{
+/*
+ * Copyright is disclaimed as to the contents of this file.
+ *
+ * $FreeBSD: src/usr.bin/getconf/pathconf.gperf,v 1.4 2003/08/22 17:32:07 markm Exp $
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+#include <unistd.h>
+#ifdef APPLE_GETCONF_UNDERSCORE
+#include <alloca.h>
+#endif /* APPLE_GETCONF_UNDERSCORE */
+
+#include "getconf.h"
+
+/*
+ * Override gperf's built-in external scope.
+ */
+static const struct map *in_word_set(const char *str);
+
+%}
+struct map { const char *name; int key; int valid; };
+%%
+FILESIZEBITS, _PC_FILESIZEBITS
+LINK_MAX, _PC_LINK_MAX
+MAX_CANON, _PC_MAX_CANON
+MAX_INPUT, _PC_MAX_INPUT
+NAME_MAX, _PC_NAME_MAX
+PATH_MAX, _PC_PATH_MAX
+PIPE_BUF, _PC_PIPE_BUF
+POSIX_ALLOC_SIZE_MIN, _PC_ALLOC_SIZE_MIN
+POSIX_REC_INCR_XFER_SIZE, _PC_REC_INCR_XFER_SIZE
+POSIX_REC_MAX_XFER_SIZE, _PC_REC_MAX_XFER_SIZE
+POSIX_REC_MIN_XFER_SIZE, _PC_REC_MIN_XFER_SIZE
+POSIX_REC_XFER_ALIGN, _PC_REC_XFER_ALIGN
+SYMLINK_MAX, _PC_SYMLINK_MAX
+TRUSTEDBSD_ACL_EXTENDED, _PC_ACL_EXTENDED
+TRUSTEDBSD_ACL_PATH_MAX, _PC_ACL_PATH_MAX
+TRUSTEDBSD_CAP_PRESENT, _PC_CAP_PRESENT
+TRUSTEDBSD_INF_PRESENT, _PC_INF_PRESENT
+TRUSTEDBSD_MAC_PRESENT, _PC_MAC_PRESENT
+_POSIX_CHOWN_RESTRICTED, _PC_CHOWN_RESTRICTED
+_POSIX_NO_TRUNC, _PC_NO_TRUNC
+_POSIX_VDISABLE, _PC_VDISABLE
+_POSIX_ASYNC_IO, _PC_ASYNC_IO
+_POSIX_PRIO_IO, _PC_PRIO_IO
+_POSIX_SYNC_IO, _PC_SYNC_IO
+%%
+int
+find_pathconf(const char *name, int *key)
+{
+ const struct map *rv;
+#ifdef APPLE_GETCONF_UNDERSCORE
+ char *alt;
+#endif /* APPLE_GETCONF_UNDERSCORE */
+
+ rv = in_word_set(name);
+ if (rv != NULL) {
+ if (rv->valid) {
+ *key = rv->key;
+ return 1;
+ }
+ return -1;
+ }
+#ifdef APPLE_GETCONF_UNDERSCORE
+ if(*name == '_')
+ alt = name + 1;
+ else {
+ if((alt = (char *)alloca(strlen(name) + 2)) == NULL)
+ return 0;
+ *alt = '_';
+ strcpy(alt + 1, name);
+ }
+ rv = in_word_set(alt);
+ if (rv != NULL) {
+ if (rv->valid) {
+ *key = rv->key;
+ return 1;
+ }
+ return -1;
+ }
+#endif /* APPLE_GETCONF_UNDERSCORE */
+ return 0;
+}
--- /dev/null
+%{
+/*
+ * Copyright is disclaimed as to the contents of this file.
+ *
+ * $FreeBSD: src/usr.bin/getconf/progenv.gperf,v 1.2 2003/08/22 17:32:07 markm Exp $
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#include "getconf.h"
+
+/*
+ * Override gperf's built-in external scope.
+ */
+static const struct map *in_word_set(const char *str);
+
+/*
+ * The Standard seems a bit ambiguous over whether the POSIX_V6_*
+ * are specified with or without a leading underscore, so we just
+ * use both.
+ */
+/*
+ * The alt_path member gives the path containing another `getconf'
+ * executable which was compiled using the specified programming
+ * environment. If it is NULL, the current executable is good enough.
+ * If we ever support multiple environments, this table will need to
+ * be updated. (We cheat here and define the supported environments
+ * statically.)
+ */
+#if defined(__alpha__) || defined(__sparc64__)
+#define have_LP64_OFF64 NULL
+#endif
+
+#if defined(__i386__) || defined(__powerpc__)
+#define have_ILP32_OFFBIG NULL
+#endif
+
+%}
+struct map { const char *name; const char *alt_path; int valid; };
+%%
+POSIX_V6_ILP32_OFF32, notdef
+POSIX_V6_ILP32_OFFBIG, have_ILP32_OFFBIG
+POSIX_V6_LP64_OFF64, have_LP64_OFF64
+POSIX_V6_LPBIG_OFFBIG, notdef
+_POSIX_V6_ILP32_OFF32, notdef
+_POSIX_V6_ILP32_OFFBIG, have_ILP32_OFFBIG
+_POSIX_V6_LP64_OFF64, have_LP64_OFF64
+_POSIX_V6_LPBIG_OFFBIG, notdef
+%%
+int
+find_progenv(const char *name, const char **alt_path)
+{
+ const struct map *rv;
+
+ rv = in_word_set(name);
+ if (rv != NULL) {
+ if (rv->valid) {
+ *alt_path = rv->alt_path;
+ return 1;
+ }
+ return -1;
+ }
+ return 0;
+}
--- /dev/null
+%{
+/*
+ * Copyright is disclaimed as to the contents of this file.
+ *
+ * $FreeBSD: src/usr.bin/getconf/sysconf.gperf,v 1.5 2003/08/22 17:32:07 markm Exp $
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+#include <unistd.h>
+#ifdef APPLE_GETCONF_UNDERSCORE
+#include <alloca.h>
+#endif /* APPLE_GETCONF_UNDERSCORE */
+
+#include "getconf.h"
+
+/*
+ * Override gperf's built-in external scope.
+ */
+static const struct map *in_word_set(const char *str);
+
+%}
+struct map { const char *name; int key; int valid; };
+%%
+AIO_LISTIO_MAX, _SC_AIO_LISTIO_MAX
+AIO_MAX, _SC_AIO_MAX
+AIO_PRIO_DELTA_MAX, _SC_AIO_PRIO_DELTA_MAX
+ARG_MAX, _SC_ARG_MAX
+ATEXIT_MAX, _SC_ATEXIT_MAX
+BC_BASE_MAX, _SC_BC_BASE_MAX
+BC_DIM_MAX, _SC_BC_DIM_MAX
+BC_SCALE_MAX, _SC_BC_SCALE_MAX
+BC_STRING_MAX, _SC_BC_STRING_MAX
+CHILD_MAX, _SC_CHILD_MAX
+CLK_TCK, _SC_CLK_TCK
+COLL_WEIGHTS_MAX, _SC_COLL_WEIGHTS_MAX
+DELAYTIMER_MAX, _SC_DELAYTIMER_MAX
+EXPR_NEST_MAX, _SC_EXPR_NEST_MAX
+GETGR_R_SIZE_MAX, _SC_GETGR_R_SIZE_MAX
+GETPW_R_SIZE_MAX, _SC_GETPW_R_SIZE_MAX
+HOST_NAME_MAX, _SC_HOST_NAME_MAX
+IOV_MAX, _SC_IOV_MAX
+LINE_MAX, _SC_LINE_MAX
+LOGIN_NAME_MAX, _SC_LOGIN_NAME_MAX
+MQ_OPEN_MAX, _SC_MQ_OPEN_MAX
+MQ_PRIO_MAX, _SC_MQ_PRIO_MAX
+NGROUPS_MAX, _SC_NGROUPS_MAX
+NPROCESSORS_CONF, _SC_NPROCESSORS_CONF
+NPROCESSORS_ONLN, _SC_NPROCESSORS_ONLN
+OPEN_MAX, _SC_OPEN_MAX
+PAGESIZE, _SC_PAGESIZE
+PAGE_SIZE, _SC_PAGESIZE
+PASS_MAX, _SC_PASS_MAX
+PTHREAD_DESTRUCTOR_ITERATIONS, _SC_THREAD_DESTRUCTOR_ITERATIONS
+PTHREAD_KEYS_MAX, _SC_THREAD_KEYS_MAX
+PTHREAD_STACK_MIN, _SC_THREAD_STACK_MIN
+PTHREAD_THREADS_MAX, _SC_THREAD_THREADS_MAX
+RE_DUP_MAX, _SC_RE_DUP_MAX
+RTSIG_MAX, _SC_RTSIG_MAX
+SEM_NSEMS_MAX, _SC_SEM_NSEMS_MAX
+SEM_VALUE_MAX, _SC_SEM_VALUE_MAX
+SIGQUEUE_MAX, _SC_SIGQUEUE_MAX
+STREAM_MAX, _SC_STREAM_MAX
+SYMLOOP_MAX, _SC_SYMLOOP_MAX
+TIMER_MAX, _SC_TIMER_MAX
+TTY_NAME_MAX, _SC_TTY_NAME_MAX
+TZNAME_MAX, _SC_TZNAME_MAX
+_POSIX2_CHAR_TERM, _SC_2_CHAR_TERM
+_POSIX2_C_BIND, _SC_2_C_BIND
+_POSIX2_C_DEV, _SC_2_C_DEV
+_POSIX2_C_VERSION, _SC_2_C_VERSION
+_POSIX2_FORT_DEV, _SC_2_FORT_DEV
+_POSIX2_FORT_RUN, _SC_2_FORT_RUN
+_POSIX2_LOCALEDEF, _SC_2_LOCALEDEF
+_POSIX2_SW_DEV, _SC_2_SW_DEV
+_POSIX2_UPE, _SC_2_UPE
+_POSIX2_VERSION, _SC_2_VERSION
+_POSIX_ASYNCHRONOUS_IO, _SC_ASYNCHRONOUS_IO
+_POSIX_BARRIERS, _SC_BARRIERS
+_POSIX_CLOCK_SELECTION, _SC_CLOCK_SELECTION
+_POSIX_CPUTIME, _SC_CPUTIME
+_POSIX_FILE_LOCKING, _SC_FILE_LOCKING
+_POSIX_FSYNC, _SC_FSYNC
+_POSIX_IPV6, _SC_IPV6
+_POSIX_JOB_CONTROL, _SC_JOB_CONTROL
+_POSIX_MAPPED_FILES, _SC_MAPPED_FILES
+_POSIX_MEMLOCK, _SC_MEMLOCK
+_POSIX_MEMLOCK_RANGE, _SC_MEMLOCK_RANGE
+_POSIX_MEMORY_PROTECTION, _SC_MEMORY_PROTECTION
+_POSIX_MESSAGE_PASSING, _SC_MESSAGE_PASSING
+_POSIX_MONOTONIC_CLOCK, _SC_MONOTONIC_CLOCK
+_POSIX_PRIORITIZED_IO, _SC_PRIORITIZED_IO
+_POSIX_PRIORITY_SCHEDULING, _SC_PRIORITY_SCHEDULING
+_POSIX_READER_WRITER_LOCKS, _SC_READER_WRITER_LOCKS
+_POSIX_REALTIME_SIGNALS, _SC_REALTIME_SIGNALS
+_POSIX_REGEXP, _SC_REGEXP
+_POSIX_SAVED_IDS, _SC_SAVED_IDS
+_POSIX_SEMAPHORES, _SC_SEMAPHORES
+_POSIX_SHARED_MEMORY_OBJECTS, _SC_SHARED_MEMORY_OBJECTS
+_POSIX_SHELL, _SC_SHELL
+_POSIX_SPAWN, _SC_SPAWN
+_POSIX_SPIN_LOCKS, _SC_SPIN_LOCKS
+_POSIX_SPORADIC_SERVER, _SC_SPORADIC_SERVER
+_POSIX_SYNCHRONIZED_IO, _SC_SYNCHRONIZED_IO
+_POSIX_THREADS, _SC_THREADS
+_POSIX_THREAD_ATTR_STACKADDR, _SC_THREAD_ATTR_STACKADDR
+_POSIX_THREAD_ATTR_STACKSIZE, _SC_THREAD_ATTR_STACKSIZE
+_POSIX_THREAD_CPUTIME, _SC_THREAD_CPUTIME
+_POSIX_THREAD_PRIORITY_SCHEDULING, _SC_THREAD_PRIORITY_SCHEDULING
+_POSIX_THREAD_PRIO_INHERIT, _SC_THREAD_PRIO_INHERIT
+_POSIX_THREAD_PRIO_PROTECT, _SC_THREAD_PRIO_PROTECT
+_POSIX_THREAD_PROCESS_SHARED, _SC_THREAD_PROCESS_SHARED
+_POSIX_THREAD_SAFE_FUNCTIONS, _SC_THREAD_SAFE_FUNCTIONS
+_POSIX_THREAD_SPORADIC_SERVER, _SC_THREAD_SPORADIC_SERVER
+_POSIX_TIMEOUTS, _SC_TIMEOUTS
+_POSIX_TRACE, _SC_TRACE
+_POSIX_TRACE_EVENT_FILTER, _SC_TRACE_EVENT_FILTER
+_POSIX_TRACE_INHERIT, _SC_TRACE_INHERIT
+_POSIX_TRACE_LOG, _SC_TRACE_LOG
+_POSIX_TIMERS, _SC_TIMERS
+_POSIX_TYPED_MEMORY_OBJECTS, _SC_TYPED_MEMORY_OBJECTS
+_POSIX_VERSION, _SC_VERSION
+_POSIX_V6_ILP32_OFF32, _SC_V6_ILP32_OFF32
+_POSIX_V6_ILP32_OFFBIG, _SC_V6_ILP32_OFFBIG
+_POSIX_V6_LP64_OFF64, _SC_V6_LP64_OFF64
+_POSIX_V6_LP64_OFFBIG, _SC_V6_LP64_OFFBIG
+_XOPEN_CRYPT, _SC_XOPEN_CRYPT
+_XOPEN_ENH_I18N, _SC_XOPEN_ENH_I18N
+_XOPEN_LEGACY, _SC_XOPEN_LEGACY
+_XOPEN_REALTIME, _SC_XOPEN_REALTIME
+_XOPEN_REALTIME_THREADS, _SC_XOPEN_REALTIME_THREADS
+_XOPEN_SHM, _SC_XOPEN_SHM
+_XOPEN_UNIX, _SC_XOPEN_UNIX
+_XOPEN_VERSION, _SC_XOPEN_VERSION
+_XOPEN_XCU_VERSION, _SC_XCU_VERSION
+%%
+int
+find_sysconf(const char *name, int *key)
+{
+ const struct map *rv;
+#ifdef APPLE_GETCONF_UNDERSCORE
+ char *alt;
+#endif /* APPLE_GETCONF_UNDERSCORE */
+
+ rv = in_word_set(name);
+ if (rv != NULL) {
+ if (rv->valid) {
+ *key = rv->key;
+ return 1;
+ }
+ return -1;
+ }
+#ifdef APPLE_GETCONF_UNDERSCORE
+ if(*name == '_')
+ alt = name + 1;
+ else {
+ if((alt = (char *)alloca(strlen(name) + 2)) == NULL)
+ return 0;
+ *alt = '_';
+ strcpy(alt + 1, name);
+ }
+ rv = in_word_set(alt);
+ if (rv != NULL) {
+ if (rv->valid) {
+ *key = rv->key;
+ return 1;
+ }
+ return -1;
+ }
+#endif /* APPLE_GETCONF_UNDERSCORE */
+ return 0;
+}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
CFILES = hostinfo.c
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble hostinfo.8
MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
#
# Note: on MS Windows, executables, have an extension, so rules and dependencies
# for generated tools should use $(EXECUTABLE_EXT) on the end.
+
+SHAREDIR = /usr/share
+MANDIR = $(SHAREDIR)/man/man8
+
+install-man-pages:
+ $(MKDIRS) $(DSTROOT)$(MANDIR)
+ install -c -m 444 hostinfo.8 $(DSTROOT)$(MANDIR)/hostinfo.8
# uncomment the following line. This can be a big time saver.
#SKIP_EXPORTING_HEADERS = YES
+# These variables provide hooks enabling you to add behavior at almost every
+# stage of the make:
+#
+# BEFORE_PREBUILD: targets to build before installing headers for a subproject
+# AFTER_PREBUILD: targets to build after installing headers for a subproject
+# BEFORE_BUILD_RECURSION: targets to make before building subprojects
+# BEFORE_BUILD: targets to make before a build, but after subprojects
+# AFTER_BUILD: targets to make after a build
+#
+# BEFORE_INSTALL: targets to build before installing the product
+# AFTER_INSTALL: targets to build after installing the product
+
+AFTER_INSTALL += install-man-pages
+
# Stuff related to exporting headers from this project that isn't already
# handled by PB.
OTHER_PUBLIC_HEADERS =
--- /dev/null
+.\" Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+.\"
+.\" The contents of this file constitute Original Code as defined in and
+.\" 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.
+.\"
+.\" This 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.
+.\"
+.\" @(#)hostinfo.1
+.Dd October 30, 2003 \" DATE
+.Dt hostinfo 8 \" Program name and manual section number
+.Os "Mac OS X"
+.Sh NAME \" Section Header - required - don't modify
+.Nm hostinfo
+.\" The following lines are read in generating the apropos(man -k) database. Use only key
+.\" words here as the database is built based on the words here and in the .ND line.
+.\" Use .Nm macro to designate other names for the documented program.
+.Nd host information
+.Sh SYNOPSIS \" Section Header - required - don't modify
+.Nm
+.Sh DESCRIPTION \" Section Header - required - don't modify
+The
+.Nm
+command displays information about the host system on which the command is executing.
+The output includes
+a kernel version description,
+processor configuration data,
+available physical memory,
+and various scheduling statistics.
+.Pp
+.Sh OPTIONS
+There are no options.
+.Sh DISPLAY
+.Pp
+.Bl -ohang -width Primary_memory_available_ -offset indent
+.It Mach kernel version:
+The version string compiled into the kernel executing on the host system.
+.Pp
+.It Processor Configuration:
+The maximum possible processors for which the kernel is configured,
+followed by the number of processors physically available.
+.Pp
+.It Processor type:
+The host's processor type and subtype.
+.Pp
+.It Processor active:
+A list of active processors on the host system.
+Active processors are members of a processor set and are ready to
+dispatch threads.
+On a single processor system, the active processor, is processor 0.
+.Pp
+.It Primary memory available:
+The amount of physical memory that is configured for use on the host system.
+.Pp
+.It Default processor set:
+Displays the number of tasks currently assigned to the host processor set,
+the number of threads currently assigned to the host processor set,
+and the number of processors included in the host processor set.
+.Pp
+.It Load average:
+Measures the average number of threads in the run queue.
+.Pp
+.It Mach factor:
+A variant of the load average which measures
+the processing resources available to a new thread.
+Mach factor is based on the number of CPUs divided by (1 + the number of runnablethreads)
+or
+the number of CPUs minus the number of runnable threads when the number of runnable threads
+is less than the number of CPUs.
+The closer the Mach factor value is to zero, the higher the load.
+On an idle system with a fixed number of active processors, the mach factor will be equal to the number of CPUs.
+.El
+.Sh SEE ALSO
+.\" List links in ascending order by section, alphabetically within a section.
+.Xr sysctl 8
+.\" .Sh BUGS \" Document known, unremedied bugs
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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 <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/bootstrap.h>
+#include <sys/sysctl.h>
+#include <sys/errno.h>
#include <stdio.h>
#include <stdlib.h>
int size;
char *cpu_name, *cpu_subname;
int i, count;
+ int mib[2];
+ size_t len;
+ uint64_t memsize;
processor_set_name_port_t default_pset;
host_name_port_t host;
struct processor_set_basic_info basic_info;
mach_error(argv[0], ret);
exit(EXIT_FAILURE);
}
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_MEMSIZE;
+ len = sizeof(memsize);
+ memsize = 0L;
+ if(sysctl(mib, 2, &memsize, &len, NULL, 0 ) == -1)
+ {
+ perror("sysctl");
+ exit(EXIT_FAILURE);
+ }
+
+
if (hi.max_cpus > 1)
printf("Kernel configured for up to %d processors.\n",
hi.max_cpus);
printf(" %d", i);
printf("\n");
- printf("Primary memory available: %.2f megabytes.\n",
- (float)hi.memory_size/(1024.0*1024.0));
+ if (((float)memsize / (1024.0 * 1024.0)) >= 1024.0)
+ printf("Primary memory available: %.2f gigabytes\n",
+ (float)memsize/(1024.0*1024.0*1024.0));
+ else
+ printf("Primary memory available: %.2f megabytes\n",
+ (float)memsize/(1024.0*1024.0));
+
printf("Default processor set: %d tasks, %d threads, %d processors\n",
load_info.task_count, load_info.thread_count, basic_info.processor_count);
printf("Load average: %d.%02d, Mach factor: %d.%02d\n",
(load_info.load_average%LOAD_SCALE)/10,
load_info.mach_factor/LOAD_SCALE,
(load_info.mach_factor%LOAD_SCALE)/10);
+
+ exit(0);
}
+++ /dev/null
-#
-# Generated by the NeXT Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = init
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-HFILES = pathnames.h
-
-CFILES = init.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\
- NOTES init.8
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /sbin
-WINDOWS_INSTALLDIR = /sbin
-PDO_UNIX_INSTALLDIR = /sbin
-LIBS =
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(USER)/BUILD
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
+++ /dev/null
-# @(#)Makefile 8.1 (Berkeley) 7/19/93
-
-PROG= init
-MAN8= init.0
-DPADD= ${LIBUTIL}
-LDADD= -lutil
-BINMODE=500
-INSTALLFLAGS=-fschg
-CFLAGS+=-DDEBUGSHELL -DSECURE
-
-.include <bsd.prog.mk>
+++ /dev/null
-INSTALL_PERMISSIONS = 500 # If set, 'install' chmod's executable to this
-#CHFLAGS = /usr/bin/chflags
-#after_install::
-# $(CHFLAGS) schg $(DSTROOT)$(INSTALLDIR)/$(NAME)
-after_install:
- mkdir -p "$(DSTROOT)/usr/share/man/man8"
- install -c -m 644 init.8 "$(DSTROOT)/usr/share/man/man8/init.8"
- ln -f "$(DSTROOT)/usr/share/man/man8/init.8" "$(DSTROOT)/usr/share/man/man8/securelevel.8"
+++ /dev/null
-# can be added to Compiler Flags to provide Secure login
-# -DSECURE LIBS = -lutil
-OTHER_CFLAGS = -DSECURE
-OTHER_GENERATED_OFILES = $(VERS_OFILE)
-AFTER_INSTALL = after_install
+++ /dev/null
-POSIX and init:
---------------
-
-POSIX.1 does not define 'init' but it mentions it in a few places.
-
-B.2.2.2, p205 line 873:
-
- This is part of the extensive 'job control' glossary entry.
- This specific reference says that 'init' must by default provide
- protection from job control signals to jobs it starts --
- it sets SIGTSTP, SIGTTIN and SIGTTOU to SIG_IGN.
-
-B.2.2.2, p206 line 889:
-
- Here is a reference to 'vhangup'. It says, 'POSIX.1 does
- not specify how controlling terminal access is affected by
- a user logging out (that is, by a controlling process
- terminating).' vhangup() is recognized as one way to handle
- the problem. I'm not clear what happens in Reno; I have
- the impression that when the controlling process terminates,
- references to the controlling terminal are converted to
- references to a 'dead' vnode. I don't know whether vhangup()
- is required.
-
-B.2.2.2, p206 line 921:
-
- Orphaned process groups bear indirectly on this issue. A
- session leader's process group is considered to be orphaned;
- that is, it's immune to job control signals from the terminal.
-
-B.2.2.2, p233 line 2055:
-
- 'Historically, the implementation-dependent process that
- inherits children whose parents have terminated without
- waiting on them is called "init" and has a process ID of 1.'
-
- It goes on to note that it used to be the case that 'init'
- was responsible for sending SIGHUP to the foreground process
- group of a tty whose controlling process has exited, using
- vhangup(). It is now the responsibility of the kernel to
- do this when the controlling process calls _exit(). The
- kernel is also responsible for sending SIGCONT to stopped
- process groups that become orphaned. This is like old BSD
- but entire process groups are signaled instead of individual
- processes.
-
- In general it appears that the kernel now automatically
- takes care of orphans, relieving 'init' of any responsibility.
- Specifics are listed on the _exit() page (p50).
-
-On setsid():
------------
-
-It appears that neither getty nor login call setsid(), so init must
-do this -- seems reasonable. B.4.3.2 p 248 implies that this is the
-way that 'init' should work; it says that setsid() should be called
-after forking.
-
-Process group leaders cannot call setsid() -- another reason to
-fork! Of course setsid() causes the current process to become a
-process group leader, so we can only call setsid() once. Note that
-the controlling terminal acquires the session leader's process
-group when opened.
-
-Controlling terminals:
----------------------
-
-B.7.1.1.3 p276: 'POSIX.1 does not specify a mechanism by which to
-allocate a controlling terminal. This is normally done by a system
-utility (such as 'getty') and is considered ... outside the scope
-of POSIX.1.' It goes on to say that historically the first open()
-of a tty in a session sets the controlling terminal. P130 has the
-full details; nothing particularly surprising.
-
-The glossary p12 describes a 'controlling process' as the first
-process in a session that acquires a controlling terminal. Access
-to the terminal from the session is revoked if the controlling
-process exits (see p50, in the discussion of process termination).
-
-Design notes:
-------------
-
-your generic finite state machine
-we are fascist about which signals we elect to receive,
- even signals purportedly generated by hardware
-handle fatal errors gracefully if possible (we reboot if we goof!!)
- if we get a segmentation fault etc., print a message on the console
- and spin for a while before rebooting
- (this at least decreases the amount of paper consumed :-)
-apply hysteresis to rapidly exiting gettys
-check wait status of children we reap
- don't wait for stopped children
-don't use SIGCHILD, it's too expensive
- but it may close windows and avoid races, sigh
-look for EINTR in case we need to change state
-init is responsible for utmp and wtmp maintenance (ick)
- maybe now we can consider replacements? maintain them in parallel
- init only removes utmp and closes out wtmp entries...
-
-necessary states and state transitions (gleaned from the man page):
- 1: single user shell (with password checking?); on exit, go to 2
- 2: rc script: on exit 0, go to 3; on exit N (error), go to 1
- 3: read ttys file: on completion, go to 4
- 4: multi-user operation: on SIGTERM, go to 7; on SIGHUP, go to 5;
- on SIGTSTP, go to 6
- 5: clean up mode (re-read ttys file, killing off controlling processes
- on lines that are now 'off', starting them on lines newly 'on')
- on completion, go to 4
- 6: boring mode (no new sessions); signals as in 4
- 7: death: send SIGHUP to all controlling processes, reap for 30 seconds,
- then go to 1 (warn if not all processes died, i.e. wait blocks)
-Given the -s flag, we start at state 1; otherwise state 2
+++ /dev/null
-{
- APPCLASS = NSApplication;
- FILESTABLE = {
- FRAMEWORKS = ();
- H_FILES = (pathnames.h);
- M_FILES = ();
- OTHER_LIBS = ();
- OTHER_LINKED = (init.c);
- OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, Makefile.dist, NOTES, init.8);
- PRECOMPILED_HEADERS = ();
- PROJECT_HEADERS = ();
- PUBLIC_HEADERS = ();
- SUBPROJECTS = ();
- };
- LANGUAGE = English;
- LOCALIZABLE_FILES = {};
- NEXTSTEP_BUILDDIR = "/tmp/$(USER)/BUILD";
- NEXTSTEP_BUILDTOOL = /bin/gnumake;
- NEXTSTEP_COMPILEROPTIONS = "-traditional-cpp";
- NEXTSTEP_INSTALLDIR = /sbin;
- NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
- NEXTSTEP_MAINNIB = init;
- NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
- PDO_UNIX_BUILDDIR = "";
- PDO_UNIX_BUILDTOOL = /bin/make;
- PDO_UNIX_COMPILEROPTIONS = "";
- PDO_UNIX_INSTALLDIR = /sbin;
- PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac";
- PDO_UNIX_LINKEROPTIONS = "";
- PDO_UNIX_MAINNIB = init;
- PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
- PROJECTNAME = init;
- PROJECTTYPE = Tool;
- PROJECTVERSION = 2.8;
- WINDOWS_BUILDDIR = "";
- WINDOWS_BUILDTOOL = /bin/make;
- WINDOWS_COMPILEROPTIONS = "";
- WINDOWS_INSTALLDIR = /sbin;
- WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
- WINDOWS_LINKEROPTIONS = "";
- WINDOWS_MAINNIB = init;
- WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
-}
+++ /dev/null
-.\" Copyright (c) 1980, 1991, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" This code is derived from software contributed to Berkeley by
-.\" Donn Seeley at Berkeley Software Design, Inc.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)init.8 8.6 (Berkeley) 5/26/95
-.\"
-.Dd May 26, 1995
-.Dt INIT 8
-.Os BSD 4
-.Sh NAME
-.Nm init
-.Nd process control initialization
-.Sh SYNOPSIS
-.Nm init
-.Sh DESCRIPTION
-The
-.Nm init
-program
-is the last stage of the boot process.
-It normally runs the automatic reboot sequence as described in
-.Xr reboot 8 ,
-and if this succeeds, begins multi-user operation.
-If the reboot scripts fail,
-.Nm init
-commences single user operation by giving
-the super-user a shell on the console.
-The
-.Nm init
-program may be passed parameters
-from the boot program to
-prevent the system from going multi-user and to instead execute
-a single user shell without starting the normal daemons.
-The system is then quiescent for maintenance work and may
-later be made to go to multi-user by exiting the
-single-user shell (with ^D).
-This
-causes
-.Nm init
-to run the
-.Pa /etc/rc
-start up command file in fastboot mode (skipping disk checks).
-.Pp
-If the
-.Nm console
-entry in the
-.Xr ttys 5
-file is marked ``insecure'',
-then
-.Nm init
-will require that the superuser password be
-entered before the system will start a single-user shell.
-The password check is skipped if the
-.Nm console
-is marked as ``secure''.
-.Pp
-The kernel runs with four different levels of security.
-Any superuser process can raise the security level, but only
-.Nm init
-can lower it.
-Security levels are defined as follows:
-.Bl -tag -width flag
-.It Ic -1
-Permanently insecure mode \- always run system in level 0 mode.
-.It Ic 0
-Insecure mode \- immutable and append-only flags may be turned off.
-All devices may be read or written subject to their permissions.
-.It Ic 1
-Secure mode \- immutable and append-only flags may not be changed;
-disks for mounted filesystems,
-.Pa /dev/mem ,
-and
-.Pa /dev/kmem
-are read-only.
-The
-.Xr settimeofday 2
-system call can only advance the time.
-.It Ic 2
-Highly secure mode \- same as secure mode, plus disks are always
-read-only whether mounted or not.
-This level precludes tampering with filesystems by unmounting them,
-but also inhibits running
-.Xr newfs 8
-while the system is multi-user.
-.El
-.Pp
-Normally, the system runs in level 0 mode while single user
-and in level 1 mode while multiuser.
-If the level 2 mode is desired while running multiuser,
-it can be set in the startup script
-.Pa /etc/rc
-using
-.Xr sysctl 8 .
-If it is desired to run the system in level 0 mode while multiuser,
-the administrator must build a kernel with the variable
-.Nm securelevel
-defined in the file
-.Pa /sys/compile/MACHINE/param.c
-and initialize it to -1.
-.Pp
-In multi-user operation,
-.Nm init
-maintains
-processes for the terminal ports found in the file
-.Xr ttys 5 .
-.Nm Init
-reads this file, and executes the command found in the second field.
-This command is usually
-.Xr getty 8 ;
-.Xr getty
-opens and initializes the tty line
-and
-executes the
-.Xr login
-program.
-The
-.Xr login
-program, when a valid user logs in,
-executes a shell for that user. When this shell
-dies, either because the user logged out
-or an abnormal termination occurred (a signal),
-the
-.Nm init
-program wakes up, deletes the user
-from the
-.Xr utmp 5
-file of current users and records the logout in the
-.Xr wtmp
-file.
-The cycle is
-then restarted by
-.Nm init
-executing a new
-.Xr getty
-for the line.
-.pl +1
-.Pp
-Line status (on, off, secure, getty, or window information)
-may be changed in the
-.Xr ttys
-file without a reboot by sending the signal
-.Dv SIGHUP
-to
-.Nm init
-with the command
-.Dq Li "kill \-s HUP 1" .
-On receipt of this signal,
-.Nm init
-re-reads the
-.Xr ttys
-file.
-When a line is turned off in
-.Xr ttys ,
-.Nm init
-will send a SIGHUP signal to the controlling process
-for the session associated with the line.
-For any lines that were previously turned off in the
-.Xr ttys
-file and are now on,
-.Nm init
-executes a new
-.Xr getty
-to enable a new login.
-If the getty or window field for a line is changed,
-the change takes effect at the end of the current
-login session (e.g., the next time
-.Nm init
-starts a process on the line).
-If a line is commented out or deleted from
-.Xr ttys ,
-.Nm init
-will not do anything at all to that line.
-However, it will complain that the relationship between lines
-in the
-.Xr ttys
-file and records in the
-.Xr utmp
-file is out of sync,
-so this practice is not recommended.
-.Pp
-.Nm Init
-will terminate multi-user operations and resume single-user mode
-if sent a terminate
-.Pq Dv TERM
-signal, for example,
-.Dq Li "kill \-s TERM 1" .
-If there are processes outstanding that are deadlocked (because of
-hardware or software failure),
-.Xr init
-will not wait for them all to die (which might take forever), but
-will time out after 30 seconds and print a warning message.
-.Pp
-.Nm Init
-will cease creating new
-.Xr getty Ns 's
-and allow the system to slowly die away, if it is sent a terminal stop
-.Pq Dv TSTP
-signal, i.e.
-.Dq Li "kill \-s TSTP 1" .
-A later hangup will resume full
-multi-user operations, or a terminate will start a single user shell.
-This hook is used by
-.Xr reboot 8
-and
-.Xr halt 8 .
-.Pp
-The role of
-.Nm init
-is so critical that if it dies, the system will reboot itself
-automatically.
-If, at bootstrap time, the
-.Xr init
-process cannot be located, the system will panic with the message
-``panic: "init died (signal %d, exit %d)''.
-.Sh DIAGNOSTICS
-.Bl -diag
-.It "getty repeating too quickly on port %s, sleeping"
-A process being started to service a line is exiting quickly
-each time it is started.
-This is often caused by a ringing or noisy terminal line.
-.Em "Init will sleep for 10 seconds" ,
-.Em "then continue trying to start the process" .
-.Pp
-.It "some processes would not die; ps axl advised."
-A process
-is hung and could not be killed when the system was shutting down.
-This condition is usually caused by a process
-that is stuck in a device driver because of
-a persistent device error condition.
-.El
-.Sh FILES
-.Bl -tag -width /var/log/wtmp -compact
-.It Pa /dev/console
-System console device.
-.It Pa /dev/tty*
-Terminal ports found in
-.Xr ttys .
-.It Pa /var/run/utmp
-Record of Current users on the system.
-.It Pa /var/log/wtmp
-Record of all logins and logouts.
-.It Pa /etc/ttys
-The terminal initialization information file.
-.It Pa /etc/rc
-System startup commands.
-.El
-.Sh SEE ALSO
-.Xr login 1 ,
-.Xr kill 1 ,
-.Xr sh 1 ,
-.Xr ttys 5 ,
-.Xr crash 8 ,
-.Xr getty 8 ,
-.Xr rc 8 ,
-.Xr reboot 8 ,
-.Xr halt 8 ,
-.Xr shutdown 8
-.Sh HISTORY
-A
-.Nm
-command appeared in
-.At v6 .
-.Sh BUGS
-Systems without
-.Xr sysctl
-behave as though they have security level \-1.
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Donn Seeley at Berkeley Software Design, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/wait.h>
-
-#include <db.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <time.h>
-#include <ttyent.h>
-#include <unistd.h>
-#include <paths.h>
-
-#include <stdarg.h>
-
-#ifdef SECURE
-#include <pwd.h>
-#endif
-
-#include "pathnames.h"
-
-/*
- * Until the mythical util.h arrives...
- */
-extern int login_tty __P((int));
-extern int logout __P((const char *));
-extern void logwtmp __P((const char *, const char *, const char *));
-
-/*
- * Sleep times; used to prevent thrashing.
- */
-#define GETTY_SPACING 5 /* N secs minimum getty spacing */
-#define GETTY_SLEEP 30 /* sleep N secs after spacing problem */
-#define WINDOW_WAIT 3 /* wait N secs after starting window */
-#define STALL_TIMEOUT 30 /* wait N secs after warning */
-#define DEATH_WATCH 10 /* wait N secs for procs to die */
-#define FAILED_HW_PASS 5 /* wait N secs before croaking user */
-
-void handle __P((sig_t, ...));
-void delset __P((sigset_t *, ...));
-
-void stall __P((char *, ...));
-void warning __P((char *, ...));
-void emergency __P((char *, ...));
-void disaster __P((int));
-void badsys __P((int));
-
-/*
- * We really need a recursive typedef...
- * The following at least guarantees that the return type of (*state_t)()
- * is sufficiently wide to hold a function pointer.
- */
-typedef long (*state_func_t) __P((void));
-typedef state_func_t (*state_t) __P((void));
-
-state_func_t single_user __P((void));
-state_func_t runcom __P((void));
-state_func_t read_ttys __P((void));
-state_func_t multi_user __P((void));
-state_func_t clean_ttys __P((void));
-state_func_t catatonia __P((void));
-state_func_t death __P((void));
-
-enum { AUTOBOOT, FASTBOOT, BOOT_SCRIPT } runcom_mode = AUTOBOOT;
-int runcom_boot = 1; /* Run the rc.boot script */
-int runcom_verbose = 0;
-int runcom_safe = 0;
-
-void transition __P((state_t));
-state_t requested_transition = runcom;
-
-void setctty __P((char *, int));
-
-
-// gvdl@next.com 14 Aug 1995
-// - from ~apps/loginwindow_proj/loginwindow/common.h
-#define REALLY_EXIT_TO_CONSOLE 229
-
-// From old init.c
-// These flags are used in the se_flags field of the init_session structure
-#define SE_SHUTDOWN 0x1 /* session won't be restarted */
-
-// The flags below control what sort of getty is launched.
-#define SE_GETTY_LAUNCH 0x30 /* What type of getty to launch */
-#define SE_COMMON 0x00 /* Usual command that is run - getty */
-#define SE_ONERROR 0x10 /* Command to run if error condition occurs.
- * This will almost always be the windowserver
- * and loginwindow. This is so if the w.s.
- * ever dies, that the naive user (stan)
- * doesn't ever see the console window. */
-#define SE_ONOPTION 0x20 /* Command to run when loginwindow exits with
- * special error code (229). This signifies
- * that the user typed "console" at l.w. and
- * l.w. wants to exit and have init run getty
- * which will then put up a console window. */
-
-typedef struct _se_command {
- char *path; /* what to run on that port */
- char **argv; /* pre-parsed argument array */
-} se_cmd_t;
-
-typedef struct init_session {
- int se_index; /* index of entry in ttys file */
- pid_t se_process; /* controlling process */
- time_t se_started; /* used to avoid thrashing */
- int se_flags; /* status of session */
- char *se_device; /* filename of port */
- se_cmd_t se_getty; /* what to run on that port */
- se_cmd_t se_window; /* window system (started only once) */
- se_cmd_t se_onerror; /* See SE_ONERROR above */
- se_cmd_t se_onoption; /* See SE_ONOPTION above */
- struct init_session *se_prev;
- struct init_session *se_next;
-} session_t;
-
-void free_session __P((session_t *));
-session_t *new_session __P((session_t *, int, struct ttyent *));
-session_t *sessions;
-
-char **construct_argv __P((char *));
-void collect_child __P((pid_t));
-pid_t start_getty __P((session_t *));
-void transition_handler __P((int));
-void alrm_handler __P((int));
-void setsecuritylevel __P((int));
-int getsecuritylevel __P((void));
-int setupargv __P((session_t *, struct ttyent *));
-int clang;
-
-void clear_session_logs __P((session_t *));
-
-int start_session_db __P((void));
-void add_session __P((session_t *));
-void del_session __P((session_t *));
-session_t *find_session __P((pid_t));
-DB *session_db;
-
-/*
- * The mother of all processes.
- */
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- int c;
- struct sigaction sa;
- sigset_t mask;
-
-
- /* Dispose of random users. */
- if (getuid() != 0) {
- (void)fprintf(stderr, "init: %s\n", strerror(EPERM));
- exit (1);
- }
-
- /* System V users like to reexec init. */
- if (getpid() != 1) {
- (void)fprintf(stderr, "init: already running\n");
- exit (1);
- }
-
- /*
- * Note that this does NOT open a file...
- * Does 'init' deserve its own facility number?
- */
- openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
-
- /*
- * Create an initial session.
- */
- if (setsid() < 0)
- warning("initial setsid() failed: %m");
-
- /*
- * Establish an initial user so that programs running
- * single user do not freak out and die (like passwd).
- */
- if (setlogin("root") < 0)
- warning("setlogin() failed: %m");
-
- /*
- * This code assumes that we always get arguments through flags,
- * never through bits set in some random machine register.
- */
-
-#ifdef DEBUG
- {
- int i;
- for (i = 0; i <= argc; i++) {
- if (argv[i])
- warning("init argument %d: '%s'", i, argv[i]);
- else
- warning("init argument %d: ***NULL***", i);
- }
- }
-#endif
-
- while ((c = getopt(argc, argv, "sfbvx")) != -1) {
-#ifdef DEBUG
- warning("handling init argument '-%c'", c);
-#endif
- switch (c) {
- case 's':
- requested_transition = single_user;
- break;
- case 'f':
- runcom_mode = FASTBOOT;
- break;
- case 'b':
- runcom_boot = 0; // Don't runcom rc.boot
- break;
- case 'v':
- runcom_verbose = 1;
- break;
- case 'x':
- runcom_safe = 1;
- break;
- default:
- warning("unrecognized flag '-%c'", c);
- break;
- }
- }
-
- if (optind != argc)
- warning("ignoring excess arguments");
-
- /*
- * We catch or block signals rather than ignore them,
- * so that they get reset on exec.
- */
- handle(badsys, SIGSYS, 0);
- handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV,
- SIGBUS, SIGXCPU, SIGXFSZ, 0);
- handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, 0);
- handle(alrm_handler, SIGALRM, 0);
- sigfillset(&mask);
- delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
- SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGTSTP, SIGALRM, 0);
- sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGTTIN, &sa, (struct sigaction *)0);
- (void) sigaction(SIGTTOU, &sa, (struct sigaction *)0);
-
- /*
- * Paranoia.
- */
- close(0);
- close(1);
- close(2);
-
- if (runcom_boot)
- {
- int old_rc_mode = runcom_mode;
-
- runcom_mode = BOOT_SCRIPT;
- if (runcom() == (state_func_t) single_user)
- requested_transition = single_user; // Error in script
- runcom_mode = old_rc_mode;
- }
-
- /*
- * Start the state machine.
- */
- transition(requested_transition);
-
- /*
- * Should never reach here.
- */
- return 1;
-}
-
-/*
- * Associate a function with a signal handler.
- */
-void
-handle(sig_t handler, ...)
-{
- int sig;
- struct sigaction sa;
- int mask_everything;
- va_list ap;
- va_start(ap, handler);
-
- sa.sa_handler = handler;
- sigfillset(&mask_everything);
-
- while (sig = va_arg(ap, int)) {
- sa.sa_mask = mask_everything;
- /* XXX SA_RESTART? */
- sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0;
- sigaction(sig, &sa, (struct sigaction *) 0);
- }
- va_end(ap);
-}
-
-/*
- * Delete a set of signals from a mask.
- */
-void
-delset(sigset_t *maskp, ...)
-{
- int sig;
- va_list ap;
- va_start(ap, maskp);
-
- while (sig = va_arg(ap, int))
- sigdelset(maskp, sig);
- va_end(ap);
-}
-
-/*
- * Log a message and sleep for a while (to give someone an opportunity
- * to read it and to save log or hardcopy output if the problem is chronic).
- * NB: should send a message to the session logger to avoid blocking.
- */
-void
-stall(char *message, ...)
-{
- va_list ap;
- va_start(ap, message);
-
- vsyslog(LOG_ALERT, message, ap);
- va_end(ap);
- sleep(STALL_TIMEOUT);
-}
-
-/*
- * Like stall(), but doesn't sleep.
- * If cpp had variadic macros, the two functions could be #defines for another.
- * NB: should send a message to the session logger to avoid blocking.
- */
-void
-warning(char *message, ...)
-{
- va_list ap;
- va_start(ap, message);
-
- vsyslog(LOG_ALERT, message, ap);
- va_end(ap);
-}
-
-/*
- * Log an emergency message.
- * NB: should send a message to the session logger to avoid blocking.
- */
-void
-emergency(char *message, ...)
-{
- va_list ap;
- va_start(ap, message);
-
- vsyslog(LOG_EMERG, message, ap);
- va_end(ap);
-}
-
-/*
- * Catch a SIGSYS signal.
- *
- * These may arise if a system does not support sysctl.
- * We tolerate up to 25 of these, then throw in the towel.
- */
-void
-badsys(sig)
- int sig;
-{
- static int badcount = 0;
-
- if (badcount++ < 25)
- return;
- disaster(sig);
-}
-
-/*
- * Catch an unexpected signal.
- */
-void
-disaster(sig)
- int sig;
-{
- emergency("fatal signal: %s",
- sig < (unsigned) NSIG ? sys_siglist[sig] : "unknown signal");
-
- sleep(STALL_TIMEOUT);
- _exit(sig); /* reboot */
-}
-
-/*
- * Get the security level of the kernel.
- */
-int
-getsecuritylevel()
-{
-#ifdef KERN_SECURELVL
- int name[2], curlevel;
- size_t len;
- extern int errno;
-
- name[0] = CTL_KERN;
- name[1] = KERN_SECURELVL;
- len = sizeof curlevel;
- if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
- emergency("cannot get kernel security level: %s",
- strerror(errno));
- return (-1);
- }
- return (curlevel);
-#else
- return (-1);
-#endif
-}
-
-/*
- * Set the security level of the kernel.
- */
-void
-setsecuritylevel(newlevel)
- int newlevel;
-{
-#ifdef KERN_SECURELVL
- int name[2], curlevel;
- extern int errno;
-
- curlevel = getsecuritylevel();
- if (newlevel == curlevel)
- return;
- name[0] = CTL_KERN;
- name[1] = KERN_SECURELVL;
- if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) {
- emergency(
- "cannot change kernel security level from %d to %d: %s",
- curlevel, newlevel, strerror(errno));
- return;
- }
-#ifdef SECURE
- warning("kernel security level changed from %d to %d",
- curlevel, newlevel);
-#endif
-#endif
-}
-
-/*
- * Change states in the finite state machine.
- * The initial state is passed as an argument.
- */
-void
-transition(s)
- state_t s;
-{
- for (;;)
- s = (state_t) (*s)();
-}
-
-/*
- * Close out the accounting files for a login session.
- * NB: should send a message to the session logger to avoid blocking.
- */
-void
-clear_session_logs(sp)
- session_t *sp;
-{
- char *line = sp->se_device + sizeof(_PATH_DEV) - 1;
-
- if (logout(line))
- logwtmp(line, "", "");
-}
-
-/*
- * Start a session and allocate a controlling terminal.
- * Only called by children of init after forking.
- */
-void
-setctty(name, flags)
- char *name;
- int flags;
-{
- int fd;
-
- (void) revoke(name);
- if ((fd = open(name, flags | O_RDWR)) == -1) {
- stall("can't open %s: %m", name);
- _exit(1);
- }
- if (login_tty(fd) == -1) {
- stall("can't get %s for controlling terminal: %m", name);
- _exit(1);
- }
-}
-
-#if m68k
-/*
- * Taken from etc/halt/halt.c
- */
-
-#include <stdio.h>
-#include <signal.h>
-#include <sgtty.h>
-
-static void shutend(void)
-{
- register i;
-
- acct(0);
- for (i = 0; i < 10; i++)
- close(i);
-
- logwtmp("~", "shutdown", "");
-}
-
-static void do_halt(void)
-{
- char sbuf [40];
- int halthowto = RB_HALT;
-
- (void) kill(-1, SIGTERM); /* one chance to catch it */
-
- sprintf (sbuf, "Invalid hardware password, halting machine...\n");
- write (1, sbuf, strlen (sbuf));
-
- signal(SIGALRM, SIG_DFL);
- shutend();
- sync();
-
- signal(SIGALRM, alrm_handler);
- alarm(FAILED_HW_PASS);
- pause();
-
- syscall(SYS_reboot, halthowto);
-}
-
-/*
- * Taken from lib/gen/getpass.c
- */
-
-static char *gethwpasswd(char *prompt)
-{
- struct termios term;
- register char *p;
- register c;
- static char pbuf[9];
- int echo;
-
- (void) tcgetattr(1, &term);
- if (echo = (term.c_lflag & ECHO))
- {
- term.c_lflag &= ~ECHO;
- (void) tcsetattr(1, TCSAFLUSH|TCSASOFT, &term);
- }
-
- write(2, prompt, strlen(prompt));
-
- for (p = pbuf; (c = getchar()) != '\n' && c != EOF; )
- if (p < &pbuf[8])
- *p++ = c;
- *p = '\0';
-
- p = "\n";
- write(2, p, strlen(p));
-
- if (echo)
- {
- term.c_lflag |= ECHO;
- (void) tcsetattr(1, TCSAFLUSH|TCSASOFT, &term);
- }
-
- return(pbuf);
-}
-
-
-static char *hw_passwd (void)
-{
- char sbuf[40];
- static char buffer [12];
- struct nvram_info nvi;
- int vidfd, count;
-
- if ((vidfd = open ("/dev/vid0", O_RDONLY, 0)) == -1)
- return NULL;
-
- if (ioctl (vidfd, DKIOCGNVRAM, &nvi) == -1)
- return NULL;
-
- if (nvi.ni_hw_pwd != HW_PWD)
- return NULL;
- else
- {
-
- for (count = 0; count < NVRAM_HW_PASSWD; count++)
- nvi.ni_ep[count] ^= 'N';
- strncpy(buffer, nvi.ni_ep, NVRAM_HW_PASSWD);
- /* ni_ep is not necessarily null terminated */
-
- // gvdl I sure hope it is 'cause bad things will happen otherwise
-
- return buffer;
- }
-}
-
-
-#endif m68k
-
-
-static void
-do_security_check(void)
-{
-#if m68k
- char sbuf[128];
- char *try, *passwd;
- int retries = 0;
-
- /*
- * If there is a hardware passwd, we want to
- * prompt the user for it. The write will be
- * to the console window because of the O_POPUP flag.
- */
- passwd = hw_passwd();
- write (1, "\n\n", 2);
-
- if (passwd != NULL)
- {
- do
- {
- try = gethwpasswd ("Enter hardware password:");
- if (strncmp (try, passwd, NVRAM_HW_PASSWD) == 0)
- {
- execl(shell, minus, (char *)0);
- exit (0);
- }
- else
- {
- sprintf (sbuf, "Password incorrect.\n\n");
- write (1, sbuf, strlen (sbuf));
- }
- }
- while (++retries < 3);
- do_halt();
- }
-#elif defined(SECURE)
- struct ttyent *typ;
- struct passwd *pp;
- static const char banner[] =
- "Enter root password, or ^D to go multi-user\n";
- char *clear, *password;
-
- /*
- * Check the root password.
- * We don't care if the console is 'on' by default;
- * it's the only tty that can be 'off' and 'secure'.
- */
- typ = getttynam("console");
- pp = getpwnam("root");
- if (typ && (typ->ty_status & TTY_SECURE) == 0 && pp)
- {
- write(2, banner, sizeof banner - 1);
- for (;;)
- {
- clear = getpass("Password:");
- if (clear == 0 || *clear == '\0')
- _exit(0);
- password = crypt(clear, pp->pw_passwd);
- memset(clear, 0, _PASSWORD_LEN);
- if (strcmp(password, pp->pw_passwd) == 0)
- break;
- warning("single-user login failed\n");
- }
- }
- endttyent();
- endpwent();
-#endif /* SECURE */
-}
-
-/*
- * Bring the system up single user.
- */
-state_func_t
-single_user()
-{
- pid_t pid, wpid;
- int status;
- sigset_t mask;
- char *shell = _PATH_BSHELL;
- char *argv[2];
- /*
- * If the kernel is in secure mode, downgrade it to insecure mode.
- */
- if (getsecuritylevel() > 0)
- setsecuritylevel(0);
-
- if ((pid = fork()) == 0) {
- /*
- * Start the single user session.
- */
- setctty(_PATH_CONSOLE, O_POPUP);
-
- do_security_check();
-
-#ifdef DEBUGSHELL
- {
- char altshell[128], *cp = altshell;
- int num;
-
-#define SHREQUEST \
- "Enter pathname of shell or RETURN for sh: "
- (void)write(STDERR_FILENO,
- SHREQUEST, sizeof(SHREQUEST) - 1);
- while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
- num != 0 && *cp != '\n' && cp < &altshell[127])
- cp++;
- *cp = '\0';
- if (altshell[0] != '\0')
- shell = altshell;
- }
-#endif /* DEBUGSHELL */
-
- /*
- * Unblock signals.
- * We catch all the interesting ones,
- * and those are reset to SIG_DFL on exec.
- */
- sigemptyset(&mask);
- sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
-
- /*
- * Set up the PATH to be approriate for the root user.
- */
- setenv("PATH", _PATH_STDPATH, 1);
-
- /*
- * We're dropping into the console; set TERM appropriately.
- */
- setenv("TERM", "vt100", 1);
-
- /*
- * Fire off a shell.
- * If the default one doesn't work, try the Bourne shell.
- */
- argv[0] = "-sh";
- argv[1] = 0;
- execv(shell, argv);
- emergency("can't exec %s for single user: %m", shell);
- execv(_PATH_BSHELL, argv);
- emergency("can't exec %s for single user: %m", _PATH_BSHELL);
- sleep(STALL_TIMEOUT);
- _exit(1);
- }
-
- if (pid == -1) {
- /*
- * We are seriously hosed. Do our best.
- */
- emergency("can't fork single-user shell, trying again");
- while (waitpid(-1, (int *) 0, WNOHANG) > 0)
- continue;
- return (state_func_t) single_user;
- }
-
- requested_transition = 0;
- do {
- if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
- collect_child(wpid);
- if (wpid == -1) {
- if (errno == EINTR)
- continue;
- warning("wait for single-user shell failed: %m; restarting");
- return (state_func_t) single_user;
- }
- if (wpid == pid && WIFSTOPPED(status)) {
- warning("init: shell stopped, restarting\n");
- kill(pid, SIGCONT);
- wpid = -1;
- }
- } while (wpid != pid && !requested_transition);
-
- if (requested_transition)
- return (state_func_t) requested_transition;
-
- if (!WIFEXITED(status)) {
- if (WTERMSIG(status) == SIGKILL) {
- /*
- * reboot(8) killed shell?
- */
- warning("single user shell terminated.");
- sleep(STALL_TIMEOUT);
- _exit(0);
- } else {
- warning("single user shell terminated, restarting");
- return (state_func_t) single_user;
- }
- }
-
- runcom_mode = FASTBOOT;
- return (state_func_t) runcom;
-}
-
-/*
- * Run the system startup script.
- */
-state_func_t
-runcom()
-{
- pid_t pid, wpid;
- int status;
- char *argv[4];
- char options[4];
- struct sigaction sa;
-
- if ((pid = fork()) == 0) {
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGTSTP, &sa, (struct sigaction *)0);
- (void) sigaction(SIGHUP, &sa, (struct sigaction *)0);
-#ifdef __APPLE__
- (void) sigaction(SIGINT, &sa, (struct sigaction *)0);
-#endif
-
- setctty(_PATH_CONSOLE, 0);
-
- argv[0] = "sh";
-
- if (runcom_mode == BOOT_SCRIPT)
- {
- argv[1] = _PATH_RUNCOM_BOOT;
- argv[2] = requested_transition == single_user
- ? "singleuser" : "multiuser";
- }
- else /* runcom_mode != BOOT_SCRIPT */
- {
- argv[1] = _PATH_RUNCOM;
-
- switch(runcom_mode) {
- case AUTOBOOT:
- argv[2] = "autoboot";
- break;
- default:
- argv[2] = "multiuser";
- break;
- }
- }
-
- if (runcom_verbose || runcom_safe)
- {
- int i = 0;
-
- options[i++] = '-';
- if (runcom_verbose) options[i++] = 'v';
- if (runcom_safe ) options[i++] = 'x';
- options[i] = '\0';
-
- argv[3] = options;
- }
- else
- {
- argv[3] = 0;
- }
-
- argv[4] = 0;
-
-#ifdef DEBUG
- {
- int i;
- for (i = 0; i <= 4; i++) {
- if (argv[i])
- warning("%s argument: %s", _PATH_RUNCOM, argv[i]);
- }
- }
-#endif
-
- sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0);
-
- execv(_PATH_BSHELL, argv);
- stall("can't exec %s for %s: %m", _PATH_BSHELL, _PATH_RUNCOM);
- _exit(1); /* force single user mode */
- }
-
- if (pid == -1) {
- emergency("can't fork for %s on %s: %m",
- _PATH_BSHELL, _PATH_RUNCOM);
- while (waitpid(-1, (int *) 0, WNOHANG) > 0)
- continue;
- sleep(STALL_TIMEOUT);
- return (state_func_t) single_user;
- }
-
- /*
- * Copied from single_user(). This is a bit paranoid.
- */
- do {
- if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
- collect_child(wpid);
- if (wpid == -1) {
- if (errno == EINTR)
- continue;
- warning("wait for %s on %s failed: %m; going to single user mode",
- _PATH_BSHELL, _PATH_RUNCOM);
- return (state_func_t) single_user;
- }
- if (wpid == pid && WIFSTOPPED(status)) {
- warning("init: %s on %s stopped, restarting\n",
- _PATH_BSHELL, _PATH_RUNCOM);
- kill(pid, SIGCONT);
- wpid = -1;
- }
- } while (wpid != pid);
-
- if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
- requested_transition == catatonia) {
- /* /etc/rc executed /sbin/reboot; wait for the end quietly */
- sigset_t s;
-
- sigfillset(&s);
- for (;;)
- sigsuspend(&s);
- }
-
- if (!WIFEXITED(status)) {
- warning("%s on %s terminated abnormally, going to single user mode",
- _PATH_BSHELL, _PATH_RUNCOM);
- return (state_func_t) single_user;
- }
-
- if (WEXITSTATUS(status))
- return (state_func_t) single_user;
-
- runcom_mode = AUTOBOOT; /* the default */
- /* NB: should send a message to the session logger to avoid blocking. */
- logwtmp("~", "reboot", "");
- return (state_func_t) read_ttys;
-}
-
-/*
- * Open the session database.
- *
- * NB: We could pass in the size here; is it necessary?
- */
-int
-start_session_db()
-{
- if (session_db && (*session_db->close)(session_db))
- emergency("session database close: %s", strerror(errno));
- if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == 0) {
- emergency("session database open: %s", strerror(errno));
- return (1);
- }
- return (0);
-
-}
-
-/*
- * Add a new login session.
- */
-void
-add_session(sp)
- session_t *sp;
-{
- DBT key;
- DBT data;
-
- key.data = &sp->se_process;
- key.size = sizeof sp->se_process;
- data.data = &sp;
- data.size = sizeof sp;
-
- if ((*session_db->put)(session_db, &key, &data, 0))
- emergency("insert %d: %s", sp->se_process, strerror(errno));
-}
-
-/*
- * Delete an old login session.
- */
-void
-del_session(sp)
- session_t *sp;
-{
- DBT key;
-
- key.data = &sp->se_process;
- key.size = sizeof sp->se_process;
-
- if ((*session_db->del)(session_db, &key, 0))
- emergency("delete %d: %s", sp->se_process, strerror(errno));
-}
-
-/*
- * Look up a login session by pid.
- */
-session_t *
-find_session(pid_t pid)
-{
- DBT key;
- DBT data;
- session_t *ret;
-
- key.data = &pid;
- key.size = sizeof pid;
- if ((*session_db->get)(session_db, &key, &data, 0) != 0)
- return 0;
- memmove(&ret, data.data, sizeof(ret));
- return ret;
-}
-
-/*
- * Construct an argument vector from a command line.
- */
-char **
-construct_argv(command)
- char *command;
-{
- register int argc = 0;
- register char **argv = (char **) malloc(((strlen(command) + 1) / 2 + 1)
- * sizeof (char *));
- static const char separators[] = " \t";
-
- if ((argv[argc++] = strtok(command, separators)) == 0)
- return 0;
- while (argv[argc++] = strtok((char *) 0, separators))
- continue;
- return argv;
-}
-
-/*
- * Deallocate a session descriptor.
- */
-
-static __inline__ void free_command(se_cmd_t *se_cmd)
-{
- if (se_cmd->path)
- {
- free(se_cmd->path);
- free(se_cmd->argv);
- }
-}
-
-void
-free_session(sp)
- register session_t *sp;
-{
- free(sp->se_device);
- free_command(&sp->se_getty);
- free_command(&sp->se_window);
- free_command(&sp->se_onerror);
- free_command(&sp->se_onoption);
- memset(sp, '\0', sizeof(*sp)); // a bit of defensive programming
-
- free(sp);
-}
-
-static int setup_command(se_cmd_t *se_cmd, char *command, char *arg )
-{
-
- char *commandWithArg;
-
- commandWithArg = malloc( strlen( command) + strlen( arg) + 2);
- (void) sprintf(commandWithArg, "%s %s", command, arg);
-
- free_command(se_cmd);
-
- se_cmd->path = commandWithArg;
- se_cmd->argv = construct_argv(commandWithArg);
- if (se_cmd->argv == NULL)
- {
- free(se_cmd->path);
- se_cmd->path = NULL;
- return 0;
- }
- return 1;
-}
-
-/*
- * Calculate getty and if useful window argv vectors.
- */
-int
-setupargv(sp, typ)
- session_t *sp;
- struct ttyent *typ;
-{
- char *type;
-
- if ( !setup_command(&sp->se_getty, typ->ty_getty, typ->ty_name) )
- {
- type = "getty";
- goto bad_args;
- }
-
- if (typ->ty_window
- && !setup_command(&sp->se_window, typ->ty_window, typ->ty_name) )
- {
- type = "window";
- goto bad_args;
- }
-
- if (typ->ty_onerror
- && !setup_command(&sp->se_onerror, typ->ty_onerror, typ->ty_name) )
- {
- type = "onerror";
- goto bad_args;
- }
-
- if (typ->ty_onoption
- && !setup_command(&sp->se_onoption, typ->ty_onoption, typ->ty_name) )
- {
- type = "onoption";
- goto bad_args;
- }
-
- return 1;
-
-bad_args:
- warning("can't parse %s for port %s", type, sp->se_device);
- return 0;
-}
-
-
-/*
- * Allocate a new session descriptor.
- */
-session_t *
-new_session(sprev, session_index, typ)
- session_t *sprev;
- int session_index;
- register struct ttyent *typ;
-{
- register session_t *sp;
-
- if ((typ->ty_status & TTY_ON) == 0 ||
- typ->ty_name == 0 ||
- typ->ty_getty == 0)
- return 0;
-
- sp = (session_t *) malloc(sizeof (session_t));
- memset(sp, 0, sizeof *sp);
-
- sp->se_index = session_index;
-
- sp->se_device = malloc(sizeof(_PATH_DEV) + strlen(typ->ty_name));
- (void) sprintf(sp->se_device, "%s%s", _PATH_DEV, typ->ty_name);
-
- if (setupargv(sp, typ) == 0) {
- free_session(sp);
- return (0);
- }
-
- sp->se_next = 0;
- if (sprev == 0) {
- sessions = sp;
- sp->se_prev = 0;
- } else {
- sprev->se_next = sp;
- sp->se_prev = sprev;
- }
-
- return sp;
-}
-
-/*
- * Walk the list of ttys and create sessions for each active line.
- */
-state_func_t
-read_ttys()
-{
- int session_index = 0;
- register session_t *sp, *snext;
- register struct ttyent *typ;
-
- /*
- * Destroy any previous session state.
- * There shouldn't be any, but just in case...
- */
- for (sp = sessions; sp; sp = snext) {
- if (sp->se_process)
- clear_session_logs(sp);
- snext = sp->se_next;
- free_session(sp);
- }
- sessions = 0;
- if (start_session_db())
- return (state_func_t) single_user;
-
- /*
- * Allocate a session entry for each active port.
- * Note that sp starts at 0.
- */
- while (typ = getttyent())
- if (snext = new_session(sp, ++session_index, typ))
- sp = snext;
-
- endttyent();
-
- return (state_func_t) multi_user;
-}
-
-/*
- * Start a window system running.
- */
-static pid_t
-start_window_system(session_t *sp)
-{
- pid_t pid;
- sigset_t mask;
-
- if ((pid = fork()) == -1) {
- emergency("can't fork for window system on port %s: %m",
- sp->se_device);
- /* hope that getty fails and we can try again */
- return -1;
- }
-
- if (pid)
- return pid;
-
- sigemptyset(&mask);
- sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
-
- if (setsid() < 0)
- emergency("setsid failed (window) %m");
-
- execv(sp->se_window.argv[0], sp->se_window.argv);
- stall("can't exec window system '%s' for port %s: %m",
- sp->se_window.argv[0], sp->se_device);
- _exit(1);
-}
-
-/*
- * Start a login session running.
- */
-pid_t
-start_getty(sp)
- session_t *sp;
-{
- pid_t pid;
- sigset_t mask;
- se_cmd_t *se_cmd;
- const char *session_type = NULL;
- time_t current_time = time((time_t *) 0);
-
- // Setup the default values;
- switch (sp->se_flags & SE_GETTY_LAUNCH)
- {
- case SE_ONOPTION:
- if (sp->se_onoption.path)
- {
- se_cmd = &sp->se_onoption;
- session_type = "onoption";
- break;
- }
- /* No break */
-
- case SE_ONERROR:
- if (sp->se_onerror.path)
- {
- se_cmd = &sp->se_onerror;
- session_type = "onerror";
- break;
- }
- /* No break */
-
- case SE_COMMON:
- default:
- se_cmd = &sp->se_getty;
- session_type = "getty";
- break;
- }
-
- if (sp->se_window.path
- && ((sp->se_flags & SE_GETTY_LAUNCH) != SE_ONOPTION))
- {
- if (start_window_system(sp) == -1)
- return -1;
- }
-
- /*
- * fork(), not vfork() -- we can't afford to block.
- */
- if ((pid = fork()) == -1) {
- emergency("can't fork for %s on port %s: %m",
- session_type, sp->se_device);
- return -1;
- }
-
- if (pid)
- return pid;
-
- if (current_time > sp->se_started &&
- current_time - sp->se_started < GETTY_SPACING) {
- warning("%s repeating too quickly on port %s, sleeping",
- session_type, sp->se_device);
- sleep((unsigned) GETTY_SLEEP);
- }
-
- sigemptyset(&mask);
- sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
-
- execv(se_cmd->argv[0], se_cmd->argv);
- stall("can't exec %s '%s' for port %s: %m", session_type,
- se_cmd->argv[0], sp->se_device);
- _exit(1);
-}
-
-/*
- * Collect exit status for a child.
- * If an exiting login, start a new login running.
- */
-void
-collect_child(pid_t pid)
-{
- register session_t *sp, *sprev, *snext;
-
- if ( !sessions)
- return;
-
- if ( !(sp = find_session(pid)) )
- return;
-
- clear_session_logs(sp);
- del_session(sp);
- sp->se_process = 0;
-
- if (sp->se_flags & SE_SHUTDOWN) {
- if (sprev = sp->se_prev)
- sprev->se_next = sp->se_next;
- else
- sessions = sp->se_next;
- if (snext = sp->se_next)
- snext->se_prev = sp->se_prev;
- free_session(sp);
- return;
- }
-
- if ((pid = start_getty(sp)) == -1) {
- /* serious trouble */
- requested_transition = clean_ttys;
- return;
- }
-
- sp->se_process = pid;
- sp->se_started = time((time_t *) 0);
- sp->se_flags &= ~SE_GETTY_LAUNCH; // clear down getty launch type
- add_session(sp);
-}
-
-/*
- * Catch a signal and request a state transition.
- */
-void
-transition_handler(sig)
- int sig;
-{
-
- switch (sig) {
- case SIGHUP:
- requested_transition = clean_ttys;
- break;
- case SIGTERM:
- requested_transition = death;
- break;
- case SIGTSTP:
- requested_transition = catatonia;
- break;
- default:
- requested_transition = 0;
- break;
- }
-}
-
-/*
- * Take the system multiuser.
- */
-state_func_t
-multi_user()
-{
- pid_t pid;
- register session_t *sp;
-
- requested_transition = 0;
-
- /*
- * If the administrator has not set the security level to -1
- * to indicate that the kernel should not run multiuser in secure
- * mode, and the run script has not set a higher level of security
- * than level 1, then put the kernel into secure mode.
- */
- if (getsecuritylevel() == 0)
- setsecuritylevel(1);
-
- for (sp = sessions; sp; sp = sp->se_next) {
- if (sp->se_process)
- continue;
- if ((pid = start_getty(sp)) == -1) {
- /* serious trouble */
- requested_transition = clean_ttys;
- break;
- }
- sp->se_process = pid;
- sp->se_started = time((time_t *) 0);
- add_session(sp);
- }
-
- while (!requested_transition)
- {
- int status;
- session_t *sp;
-
- pid = waitpid(-1, &status, 0);
- if (!sessions || !(sp = find_session(pid)))
- continue;
-
- if (WIFSIGNALED(status))
- sp->se_flags |= SE_ONERROR;
- else if (WEXITSTATUS(status) == REALLY_EXIT_TO_CONSOLE)
- { /* WIFEXITED(status) assumed */
- sp->se_flags |= SE_ONOPTION;
- }
- else
- sp->se_flags |= SE_ONERROR;
-
- if (pid != -1)
- collect_child(pid);
- }
-
- return (state_func_t) requested_transition;
-}
-
-/*
- * This is an n-squared algorithm. We hope it isn't run often...
- */
-state_func_t
-clean_ttys()
-{
- register session_t *sp, *sprev;
- register struct ttyent *typ;
- register int session_index = 0;
- register int devlen;
-
- if (! sessions)
- return (state_func_t) multi_user;
-
- devlen = sizeof(_PATH_DEV) - 1;
- while (typ = getttyent()) {
- ++session_index;
-
- for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next)
- if (strcmp(typ->ty_name, sp->se_device + devlen) == 0)
- break;
-
- if (sp) {
- if (sp->se_index != session_index) {
- warning("port %s changed utmp index from %d to %d",
- sp->se_device, sp->se_index,
- session_index);
- sp->se_index = session_index;
- }
- if ((typ->ty_status & TTY_ON) == 0 ||
- typ->ty_getty == 0) {
- sp->se_flags |= SE_SHUTDOWN;
- kill(sp->se_process, SIGHUP);
- continue;
- }
- sp->se_flags &= ~SE_SHUTDOWN;
- if (setupargv(sp, typ) == 0) {
- warning("can't parse getty for port %s",
- sp->se_device);
- sp->se_flags |= SE_SHUTDOWN;
- kill(sp->se_process, SIGHUP);
- }
- continue;
- }
-
- new_session(sprev, session_index, typ);
- }
-
- endttyent();
-
- return (state_func_t) multi_user;
-}
-
-/*
- * Block further logins.
- */
-state_func_t
-catatonia()
-{
- register session_t *sp;
-
- for (sp = sessions; sp; sp = sp->se_next)
- sp->se_flags |= SE_SHUTDOWN;
-
- return (state_func_t) multi_user;
-}
-
-/*
- * Note SIGALRM.
- */
-void
-alrm_handler(sig)
- int sig;
-{
- clang = 1;
-}
-
-/*
- * Bring the system down to single user.
- */
-state_func_t
-death()
-{
- register session_t *sp;
- register int i;
- pid_t pid;
- static const int death_sigs[3] = { SIGHUP, SIGTERM, SIGKILL };
-
- for (sp = sessions; sp; sp = sp->se_next)
- sp->se_flags |= SE_SHUTDOWN;
-
- /* NB: should send a message to the session logger to avoid blocking. */
- logwtmp("~", "shutdown", "");
-
- for (i = 0; i < 3; ++i) {
- if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH)
- return (state_func_t) single_user;
-
- clang = 0;
- alarm(DEATH_WATCH);
- do
- if ((pid = waitpid(-1, (int *)0, 0)) != -1)
- collect_child(pid);
- while (clang == 0 && errno != ECHILD);
-
- if (errno == ECHILD)
- return (state_func_t) single_user;
- }
-
- warning("some processes would not die; ps axl advised");
-
- return (state_func_t) single_user;
-}
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <paths.h>
-
-#define _PATH_SLOGGER "/sbin/session_logger"
-#define _PATH_RUNCOM "/etc/rc"
-#define _PATH_RUNCOM_BOOT _PATH_RUNCOM ".boot"
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * 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.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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 DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
#define DBG_FUNC_MASK 0xfffffffc
+#define CPU_NUMBER(ts) ((ts & KDBG_CPU_MASK) >> KDBG_CPU_SHIFT)
+
#define DBG_ZERO_FILL_FAULT 1
#define DBG_PAGEIN_FAULT 2
#define DBG_COW_FAULT 3
sysctl(mib, 3, &kr, &needed, NULL, 0);
}
-set_rtcdec(decval)
+void set_rtcdec(decval)
int decval;
{kd_regtype kr;
int ret;
mib[5] = 0; /* no flags */
errno = 0;
-
if ((ret=sysctl(mib, 3, &kr, &needed, NULL, 0)) < 0)
{
- decrementer_val = 0;
- quit("trace facility failure, KERN_KDSETRTCDEC\n");
+ decrementer_val = 0;
+ /* ignore this sysctl error if it's not supported */
+ if (errno == ENOENT)
+ return;
+ else
+ quit("trace facility failure, KERN_KDSETRTCDEC\n");
}
}
elapsed_secs -= elapsed_mins * 60;
sprintf(tbuf, "%-19.19s %2ld:%02ld:%02ld\n", &(ctime(&curr_time)[0]),
- elapsed_hours, elapsed_mins, elapsed_secs);
+ (long)elapsed_hours, (long)elapsed_mins, (long)elapsed_secs);
if (fp)
fprintf(fp, "%s", tbuf);
else
{
fprintf(stderr, "Usage: latency [-rt] [-c codefile] [-l logfile] [-st threshold]\n");
- fprintf(stderr, " [-it threshold] [-s sleep_in_usecs]\n");
+
+#if defined (__i386__)
+ fprintf(stderr, " [-it threshold] [-s sleep_in_usecs] [-n kernel]\n\n");
+#else
+ fprintf(stderr, " [-it threshold] [-s sleep_in_usecs]\n");
fprintf(stderr, " [-d decrementer_in_usecs] [-n kernel]\n\n");
+#endif
+
fprintf(stderr, " -rt Set realtime scheduling policy. Default is timeshare.\n");
fprintf(stderr, " -c specify name of codes file\n");
fprintf(stderr, " -st set scheduler latency threshold in microseconds... if latency exceeds this, then log trace\n");
fprintf(stderr, " -it set interrupt latency threshold in microseconds... if latency exceeds this, then log trace\n");
fprintf(stderr, " -s set sleep time in microseconds\n");
+#if !defined (__i386__)
fprintf(stderr, " -d set decrementer in microseconds.\n");
+#endif
fprintf(stderr, " -n specify kernel, default is /mach_kernel\n");
fprintf(stderr, "\nlatency must be run as root\n\n");
}
-
+int
main(argc, argv)
int argc;
char *argv[];
{
- mach_timespec_t remain;
uint64_t start, stop;
uint64_t timestamp1;
uint64_t timestamp2;
int decrementer_usec = 0;
kern_return_t ret;
int size;
- int i, count;
host_name_port_t host;
void getdivisor();
void sample_sc();
void init_code_file();
void do_kernel_nm();
void open_logfile();
+ void mk_wait_until();
my_policy = THREAD_STANDARD_POLICY;
policy_name = "TIMESHARE";
num_of_usecs_to_sleep = atoi(argv[1]);
else
exit_usage();
- } else if (strcmp(argv[1], "-d") == 0) {
+ }
+ else if (strcmp(argv[1], "-d") == 0) {
argc--;
argv++;
decrementer_usec = atoi(argv[1]);
else
exit_usage();
- } else if (strcmp(argv[1], "-n") == 0) {
+#if defined(__i386__)
+ /* ignore this option - setting the decrementer has no effect */
+ decrementer_usec = 0;
+#endif
+ }
+ else if (strcmp(argv[1], "-n") == 0) {
argc--;
argv++;
getdivisor();
decrementer_val = decrementer_usec * divisor;
- /* get the cpu count for the DECR_TRAP array */
+ /* get the cpu countfor the DECR_TRAP array */
host = mach_host_self();
size = sizeof(hi)/sizeof(int);
ret = host_info(host, HOST_BASIC_INFO, (host_info_t)&hi, &size);
size = bufinfo.nkdthreads * sizeof(kd_threadmap);
if (size)
{
- if (mapptr = (kd_threadmap *) malloc(size))
+ if ((mapptr = (kd_threadmap *) malloc(size)))
bzero (mapptr, size);
else
{
{
kd_threadmap *map;
- if (map = find_thread_map(thread)) {
+ if ((map = find_thread_map(thread))) {
#if 0
if (log_fp)
uint64_t now;
int count, i;
int first_entry = 1;
+ double timestamp = 0.0;
+ double last_timestamp = 0.0;
+ double delta = 0.0;
+ double start_bias = 0.0;
char command[32];
- double timestamp, last_timestamp, delta, start_bias;
void read_command_map();
if (log_fp && (my_policy == THREAD_TIME_CONSTRAINT_POLICY))
char *p;
long *sargptr;
kd_buf *cur_kd;
- double i_latency;
+ double i_latency = 0.0;
struct th_info *ti;
char command1[32];
char sched_info[64];
void exit_syscall();
void print_entry();
- thread = kd->arg5 & KDBG_THREAD_MASK;
- cpunum = (kd->arg5 & KDBG_CPU_MASK) ? 1: 0;
+ thread = kd->arg5;
+ cpunum = CPU_NUMBER(kd->timestamp);
debugid = kd->debugid;
type = kd->debugid & DBG_FUNC_MASK;
if (type == DECR_TRAP)
i_latency = handle_decrementer(kd);
- now = kd->timestamp;
+ now = kd->timestamp & KDBG_TIMESTAMP_MASK;
timestamp = ((double)now) / divisor;
}
if ((kd->debugid & DBG_FUNC_MASK) == DECR_TRAP)
{
- cpunum = (kd->arg5 & KDBG_CPU_MASK) ? 1: 0;
+ cpunum = CPU_NUMBER(kd->timestamp);
last_decrementer_kd[cpunum] = kd;
}
else
}
delta = timestamp - last_timestamp;
- if (map = find_thread_map(thread))
+ if ((map = find_thread_map(thread)))
strcpy(command, map->command);
else
command[0] = 0;
mode = 1;
- if (ti = find_thread((kd->arg5 & KDBG_THREAD_MASK), 0, 0)) {
+ if ((ti = find_thread(kd->arg5, 0, 0))) {
if (ti->type == -1 && strcmp(command, "kernel_task"))
mode = 0;
}
case MACH_stkhandoff:
last_mach_sched = kd;
- if (map = find_thread_map(kd->arg2))
+ if ((map = find_thread_map(kd->arg2)))
strcpy(command1, map->command);
else
sprintf(command1, "%-8x", kd->arg2);
- if (ti = find_thread(kd->arg2, 0, 0)) {
+ if ((ti = find_thread(kd->arg2, 0, 0))) {
if (ti->type == -1 && strcmp(command1, "kernel_task"))
p = "U";
else
int cpunum;
char *p;
- cpunum = (kd->arg5 & KDBG_CPU_MASK) ? 1: 0;
+ cpunum = CPU_NUMBER(kd->timestamp);
if (print_info && fp) {
- if (p = find_code(type)) {
+ if ((p = find_code(type))) {
if (type == INTERRUPT) {
int mode = 1;
- if (ti = find_thread((kd->arg5 & KDBG_THREAD_MASK), 0, 0)) {
+ if ((ti = find_thread(kd->arg5, 0, 0))) {
if (ti->type == -1 && strcmp(command, "kernel_task"))
mode = 0;
}
int cpunum;
char *p;
- cpunum = (kd->arg5 & KDBG_CPU_MASK) ? 1: 0;
+ cpunum = CPU_NUMBER(kd->timestamp);
+
ti = find_thread(thread, type, type);
#if 0
if (print_info && fp)
else
fprintf(fp, "%9.1f %8.1f() \t", timestamp - bias, delta);
- if (p = find_code(type)) {
+ if ((p = find_code(type))) {
if (type == INTERRUPT) {
fprintf(fp, "INTERRUPT %-8x %d %s\n", thread, cpunum, command);
} else if (type == MACH_vmfault && kd->arg2 <= DBG_CACHE_HIT_FAULT) {
if (!fp)
return;
- cpunum = (kd->arg5 & KDBG_CPU_MASK) ? 1: 0;
-
+ cpunum = CPU_NUMBER(kd->timestamp);
#if 0
fprintf(fp, "cur_max = %d, type = %x, thread = %x, cpunum = %d\n", cur_max, type, thread, cpunum);
#endif
- if (p = find_code(type)) {
+ if ((p = find_code(type))) {
fprintf(fp, "%9.1f %8.1f\t\t%-28.28s %-8x %-8x %-8x %-8x %-8x %d %s\n",
timestamp - bias, delta, p, kd->arg1, kd->arg2, kd->arg3, kd->arg4,
thread, cpunum, command);
{
kd_buf *kd, *kd_start, *kd_stop;
int kd_count; /* Limit the boundary of kd_start */
- double timestamp, last_timestamp, delta, start_bias;
+ double timestamp = 0.0;
+ double last_timestamp = 0.0;
+ double delta = 0.0;
+ double start_bias = 0.0;
int thread, cpunum;
int debugid, type, clen;
int len;
fprintf(log_fp, "RelTime(Us) Delta debugid arg1 arg2 arg3 arg4 thread cpu command\n\n");
- thread = kd_beg->arg5 & KDBG_THREAD_MASK;
- cpunum = (kd_end->arg5 & KDBG_CPU_MASK) ? 1: 0;
+ thread = kd_beg->arg5;
+ cpunum = CPU_NUMBER(kd_end->timestamp);
for (kd_count = 0, kd_start = kd_beg - 1; (kd_start >= (kd_buf *)my_buffer); kd_start--, kd_count++) {
if (kd_count == MAX_LOG_COUNT)
break;
- if((kd_start->arg5 & KDBG_CPU_MASK) != cpunum)
+ if (CPU_NUMBER(kd_start->timestamp) != cpunum)
continue;
if ((kd_start->debugid & DBG_FUNC_MASK) == DECR_TRAP)
break;
- if((kd_start->arg5 & KDBG_THREAD_MASK) != thread)
+ if (kd_start->arg5 != thread)
break;
}
if (kd_start < (kd_buf *)my_buffer)
kd_start = (kd_buf *)my_buffer;
- thread = kd_end->arg5 & KDBG_THREAD_MASK;
+ thread = kd_end->arg5;
for (kd_stop = kd_end + 1; kd_stop < end_of_sample; kd_stop++) {
if ((kd_stop->debugid & DBG_FUNC_MASK) == DECR_TRAP)
break;
- if((kd_stop->arg5 & KDBG_CPU_MASK) != cpunum)
+ if (CPU_NUMBER(kd_stop->timestamp) != cpunum)
continue;
- if((kd_stop->arg5 & KDBG_THREAD_MASK) != thread)
+ if (kd_stop->arg5 != thread)
break;
}
if (kd_stop >= end_of_sample)
kd_stop = end_of_sample - 1;
- now = kd_start->timestamp;
+ now = kd_start->timestamp & KDBG_TIMESTAMP_MASK;
timestamp = ((double)now) / divisor;
for (kd = kd_start; kd <= kd_stop; kd++) {
type = kd->debugid & DBG_FUNC_MASK;
- if (ti = find_thread((kd->arg5 & KDBG_THREAD_MASK), type, type)) {
+ if ((ti = find_thread(kd->arg5, type, type))) {
if (ti->stime >= timestamp)
ti->type = -1;
}
for (kd = kd_start; kd <= kd_stop; kd++) {
int mode;
- thread = kd->arg5 & KDBG_THREAD_MASK;
- cpunum = (kd->arg5 & KDBG_CPU_MASK) ? 1: 0;
+ thread = kd->arg5;
+ cpunum = CPU_NUMBER(kd->timestamp);
debugid = kd->debugid;
type = kd->debugid & DBG_FUNC_MASK;
- now = kd->timestamp;
+ now = kd->timestamp & KDBG_TIMESTAMP_MASK;
timestamp = ((double)now) / divisor;
}
delta = timestamp - last_timestamp;
- if (map = find_thread_map(thread))
+ if ((map = find_thread_map(thread)))
strcpy(command, map->command);
else
command[0] = 0;
mode = 1;
- if (ti = find_thread((kd->arg5 & KDBG_THREAD_MASK), 0, 0)) {
+ if ((ti = find_thread(kd->arg5, 0, 0))) {
if (ti->type == -1 && strcmp(command, "kernel_task"))
mode = 0;
}
case MACH_sched:
case MACH_stkhandoff:
- if (map = find_thread_map(kd->arg2))
+ if ((map = find_thread_map(kd->arg2)))
strcpy(command1, map->command);
else
sprintf(command1, "%-8x", kd->arg2);
- if (ti = find_thread(kd->arg2, 0, 0)) {
+ if ((ti = find_thread(kd->arg2, 0, 0))) {
if (ti->type == -1 && strcmp(command1, "kernel_task"))
p = "U";
else
FILE *fp = (FILE *)0;
char tmp_nm_file[128];
char tmpstr[1024];
- int inchr;
+ char inchr;
bzero(tmp_nm_file, 128);
bzero(tmpstr, 1024);
for (i=0; i<kern_sym_count; i++)
{
bzero(tmpstr, 1024);
- if (fscanf(fp, "%x %c %s", &kern_sym_tbl[i].k_sym_addr, &inchr, tmpstr) != 3)
+ if (fscanf(fp, "%lx %c %s", &kern_sym_tbl[i].k_sym_addr, &inchr, tmpstr) != 3)
break;
else
{
len = max_len - 8;
memcpy(pcstring, kern_sym_tbl[ret].k_sym_name, len);
- sprintf(&pcstring[len], "+0x%-5x", pc - kern_sym_tbl[ret].k_sym_addr);
+ sprintf(&pcstring[len], "+0x%-5lx", pc - kern_sym_tbl[ret].k_sym_addr);
return (pcstring);
}
#
-# Generated by the Apple Project Builder.
+# Generated by the NeXT Project Builder.
#
# NOTE: Do NOT change this file -- Project Builder maintains it.
#
NEXTSTEP_INSTALLDIR = /usr/bin
WINDOWS_INSTALLDIR = /usr/bin
PDO_UNIX_INSTALLDIR = /usr/bin
-LIBS = -lbsm -lpam -lpam_misc
+LIBS = -lpam -lpam_misc
DEBUG_LIBS = $(LIBS)
PROF_LIBS = $(LIBS)
{
DOCICONFILES = ();
FILESTABLE = {
- "C_FILES" = ();
- "H_FILES" = ("pathnames.h");
- "OTHER_LIBS" = (bsm, pam, "pam_misc");
- "OTHER_LINKED" = ("klogin.c", "login.c");
- "OTHER_SOURCES" = ("Makefile.preamble", Makefile, "Makefile.postamble", "login.1");
+ C_FILES = ();
+ H_FILES = (pathnames.h);
+ OTHER_LIBS = ();
+ OTHER_LINKED = (klogin.c, login.c);
+ OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, login.1);
SUBPROJECTS = ();
};
LANGUAGE = English;
- "LOCALIZABLE_FILES" = {};
- "NEXTSTEP_INSTALLDIR" = "/usr/bin";
- "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
- "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
- "PDO_UNIX_INSTALLDIR" = "/usr/bin";
- "PDO_UNIX_JAVA_COMPILER" = "$(NEXTDEV_BIN)/javac";
- "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
+ LOCALIZABLE_FILES = {};
+ NEXTSTEP_INSTALLDIR = /usr/bin;
+ NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
+ NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
+ PDO_UNIX_INSTALLDIR = /usr/bin;
+ PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac";
+ PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
PROJECTNAME = login;
PROJECTTYPE = Tool;
- PROJECTVERSION = "2.8";
- "WINDOWS_INSTALLDIR" = "/usr/bin";
- "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
- "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
+ PROJECTVERSION = 2.8;
+ WINDOWS_INSTALLDIR = /usr/bin;
+ WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
+ WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
/*
- * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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 <unistd.h>
#include <utmp.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include <bsm/libbsm.h>
-#include <bsm/audit_uevents.h>
-
#ifdef USE_PAM
#include <pam/pam_appl.h>
#include <pam/pam_misc.h>
#ifdef KERBEROS
int klogin __P((struct passwd *, char *, char *, char *));
#endif
-void au_success();
-void au_fail(char *, int);
-
extern void login __P((struct utmp *));
int failures;
char term[64], *hostname, *username = NULL, *tty;
-#define NA_EVENT_STR_SIZE 25
-au_tid_t tid;
-
int
main(argc, argv)
int argc;
pid_t pid;
#endif
- char auditsuccess = 1;
-
(void)signal(SIGALRM, timedout);
(void)alarm(timeout);
(void)signal(SIGQUIT, SIG_IGN);
openlog("login", LOG_ODELAY, LOG_AUTH);
-
/*
* -p is used by getty to tell login not to destroy the environment
* -f is used to skip a second login authentication
else
tty = ttyn;
- /* Set the terminal id */
- audit_set_terminal_id(&tid);
- if (fstat(STDIN_FILENO, &st) < 0) {
- fprintf(stderr, "login: Unable to stat terminal\n");
- au_fail("Unable to stat terminal", 1);
- exit(-1);
- }
- if (S_ISCHR(st.st_mode)) {
- tid.port = st.st_rdev;
- } else {
- tid.port = 0;
- }
-
#ifdef USE_PAM
rval = pam_start("login", username, &conv, &pamh);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
- au_fail("PAM Error", 1);
exit(1);
}
rval = pam_set_item(pamh, PAM_TTY, tty);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
- au_fail("PAM Error", 1);
exit(1);
}
rval = pam_set_item(pamh, PAM_RHOST, hostname);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
- au_fail("PAM Error", 1);
exit(1);
}
rval = pam_set_item(pamh, PAM_USER_PROMPT, "login: ");
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
- au_fail("PAM Error", 1);
exit(1);
}
if( (pwd != NULL) && fflag && ((uid == 0) || (uid == pwd->pw_uid)) ){
rval = 0;
- auditsuccess = 0; /* we've simply opened a terminal window */
} else {
rval = pam_authenticate(pamh, 0);
(rval == PAM_USER_UNKNOWN) ||
(rval == PAM_CRED_INSUFFICIENT) ||
(rval == PAM_AUTHINFO_UNAVAIL))) {
- /*
- * we are not exiting here, but this corresponds to
- * a failed login event, so set exitstatus to 1
- */
- au_fail("Login incorrect", 1);
badlogin(username);
printf("Login incorrect\n");
rootlogin = 0;
pam_get_item(pamh, PAM_USER, (void *)&username);
badlogin(username);
printf("Login incorrect\n");
- au_fail("Login incorrect", 1);
exit(1);
}
}
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
- au_fail("PAM error", 1);
exit(1);
}
-
}
rval = pam_get_item(pamh, PAM_USER, (void *)&username);
rval = pam_open_session(pamh, 0);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
- au_fail("PAM error", 1);
exit(1);
}
rval = pam_setcred(pamh, PAM_ESTABLISH_CRED);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
- au_fail("PAM error", 1);
exit(1);
}
* for nonexistent name (mistyped username).
*/
if (failures && strcmp(tbuf, username)) {
- if (failures > (pwd ? 0 : 1)) {
+ if (failures > (pwd ? 0 : 1))
badlogin(tbuf);
- }
failures = 0;
}
(void)strcpy(tbuf, username);
syslog(LOG_NOTICE,
"LOGIN %s REFUSED ON TTY %s",
pwd->pw_name, tty);
- au_fail("Login refused on terminal", 0);
continue;
}
if (++cnt > 3) {
if (cnt >= 10) {
badlogin(username);
- au_fail("Login incorrect", 1);
sleepexit(1);
}
- au_fail("Login incorrect", 1);
sleep((u_int)((cnt - 3) * 5));
}
}
if (!rootlogin)
checknologin();
- /* Audit successful login */
- if (auditsuccess)
- au_success();
-
setegid(pwd->pw_gid);
seteuid(rootlogin ? 0 : pwd->pw_uid);
- /* First do a stat in case the homedir is automounted */
- stat(pwd->pw_dir,&st);
+ /* First do a stat in case the homedir is automounted */
+\r stat(pwd->pw_dir,&st);
if (chdir(pwd->pw_dir) < 0) {
(void)printf("No home directory %s!\n", pwd->pw_dir);
- if (chdir("/")) {
+ if (chdir("/"))
exit(0);
- }
pwd->pw_dir = "/";
(void)printf("Logging in with home = \"/\".\n");
}
-
seteuid(euid);
setegid(egid);
quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
/* Nothing else left to fail -- really log in. */
-
memset((void *)&utmp, 0, sizeof(utmp));
(void)time(&utmp.ut_time);
(void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
pam_setcred(pamh, PAM_DELETE_CRED);
rval = pam_close_session(pamh, 0);
pam_end(pamh,rval);
+ chown(ttyn, 0, 0);
+ chmod(ttyn, 0666);
exit(0);
}
else
(void) setuid(pwd->pw_uid);
-
execlp(pwd->pw_shell, tbuf, 0);
err(1, "%s", pwd->pw_shell);
}
#define NBUFSIZ (MAXLOGNAME + 1)
#endif
-/*
- * The following tokens are included in the audit record for successful login attempts
- * header
- * subject
- * return
- */
-void au_success()
-{
- token_t *tok;
- int aufd;
- au_mask_t aumask;
- auditinfo_t auinfo;
- uid_t uid = pwd->pw_uid;
- gid_t gid = pwd->pw_gid;
- pid_t pid = getpid();
- long au_cond;
-
- /* If we are not auditing, don't cut an audit record; just return */
- if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
- fprintf(stderr, "login: Could not determine audit condition\n");
- exit(1);
- }
- if (au_cond == AUC_NOAUDIT)
- return;
-
- /* Compute and Set the user's preselection mask */
- if(au_user_mask(pwd->pw_name, &aumask) == -1) {
- fprintf(stderr, "login: Could not set audit mask\n");
- exit(1);
- }
-
- /* Set the audit info for the user */
- auinfo.ai_auid = uid;
- auinfo.ai_asid = pid;
- bcopy(&tid, &auinfo.ai_termid, sizeof(auinfo.ai_termid));
- bcopy(&aumask, &auinfo.ai_mask, sizeof(auinfo.ai_mask));
- if(setaudit(&auinfo) != 0) {
- fprintf(stderr, "login: setaudit failed: %s\n", strerror(errno));
- exit(1);
- }
-
- if((aufd = au_open()) == -1) {
- fprintf(stderr, "login: Audit Error: au_open() failed\n");
- exit(1);
- }
-
- /* The subject that is created (euid, egid of the current process) */
- if((tok = au_to_subject32(uid, geteuid(), getegid(),
- uid, gid, pid, pid, &tid)) == NULL) {
- fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if((tok = au_to_return32(0, 0)) == NULL) {
- fprintf(stderr, "login: Audit Error: au_to_return32() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if(au_close(aufd, 1, AUE_login) == -1) {
- fprintf(stderr, "login: Audit Record was not committed.\n");
- exit(1);
- }
-}
-
-/*
- * The following tokens are included in the audit record for successful login attempts
- * header
- * subject
- * text
- * return
- */
-void au_fail(char *errmsg, int na)
-{
- token_t *tok;
- int aufd;
- long au_cond;
- uid_t uid;
- gid_t gid;
- pid_t pid = getpid();
-
- /* If we are not auditing, don't cut an audit record; just return */
- if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
- fprintf(stderr, "login: Could not determine audit condition\n");
- exit(1);
- }
- if (au_cond == AUC_NOAUDIT)
- return;
-
- if((aufd = au_open()) == -1) {
- fprintf(stderr, "login: Audit Error: au_open() failed\n");
- exit(1);
- }
-
- if(na) {
- /* Non attributable event */
- /* Assuming that login is not called within a users' session => auid,asid == -1 */
- if((tok = au_to_subject32(-1, geteuid(), getegid(), -1, -1,
- pid, -1, &tid)) == NULL) {
-
- fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
- exit(1);
- }
- }
- else {
- /* we know the subject -- so use its value instead */
- uid = pwd->pw_uid;
- gid = pwd->pw_gid;
- if((tok = au_to_subject32(uid, geteuid(), getegid(),
- uid, gid, pid, pid, &tid)) == NULL) {
- fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
- exit(1);
- }
- }
- au_write(aufd, tok);
-
- /* Include the error message */
- if((tok = au_to_text(errmsg)) == NULL) {
- fprintf(stderr, "login: Audit Error: au_to_text() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if((tok = au_to_return32(1, errno)) == NULL) {
- fprintf(stderr, "login: Audit Error: au_to_return32() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if(au_close(aufd, 1, AUE_login) == -1) {
- fprintf(stderr, "login: Audit Error: au_close() was not committed\n");
- exit(1);
- }
-}
-
void
getloginname()
{
if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
(void)write(fileno(stdout), tbuf, nchars);
-
- au_fail("No login", 0);
sleepexit(0);
}
}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
+++ /dev/null
-#
-# Generated by the Apple Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = mach_init
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-HFILES = bootstrap_internal.h error_log.h lists.h
-
-CFILES = bootstrap.c error_log.c lists.c rpc_services.c
-
-OTHERSRCS = Makefile.preamble Makefile bootstrap.defs mach_init.8\
- Makefile.postamble
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /sbin
-WINDOWS_INSTALLDIR = /sbin
-PDO_UNIX_INSTALLDIR = /sbin
-LIBS = -lbsm
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-
-NEXTSTEP_PB_CFLAGS = -DMACH_USER_API
-WINDOWS_PB_CFLAGS = -DMACH_USER_API
-PDO_UNIX_PB_CFLAGS = -DMACH_USER_API
-
-
-NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(USER)/BUILD
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
+++ /dev/null
-###############################################################################
-# Makefile.postamble
-# Copyright 1997, Apple Computer, Inc.
-#
-# Use this makefile, which is imported after all other makefiles, to
-# override attributes for a project's Makefile environment. This allows you
-# to take advantage of the environment set up by the other Makefiles.
-# You can also define custom rules at the end of this file.
-#
-###############################################################################
-#
-# These variables are exported by the standard makefiles and can be
-# used in any customizations you make. They are *outputs* of
-# the Makefiles and should be used, not set.
-#
-# PRODUCTS: products to install. All of these products will be placed in
-# the directory $(DSTROOT)$(INSTALLDIR)
-# GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
-# LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
-# OFILE_DIR: Directory into which .o object files are generated.
-# DERIVED_SRC_DIR: Directory used for all other derived files
-#
-# ALL_CFLAGS: flags to pass when compiling .c files
-# ALL_MFLAGS: flags to pass when compiling .m files
-# ALL_CCFLAGS: flags to pass when compiling .cc, .cxx, and .C files
-# ALL_MMFLAGS: flags to pass when compiling .mm, .mxx, and .M files
-# ALL_PRECOMPFLAGS: flags to pass when precompiling .h files
-# ALL_LDFLAGS: flags to pass when linking object files
-# ALL_LIBTOOL_FLAGS: flags to pass when libtooling object files
-# ALL_PSWFLAGS: flags to pass when processing .psw and .pswm (pswrap) files
-# ALL_RPCFLAGS: flags to pass when processing .rpc (rpcgen) files
-# ALL_YFLAGS: flags to pass when processing .y (yacc) files
-# ALL_LFLAGS: flags to pass when processing .l (lex) files
-#
-# NAME: name of application, bundle, subproject, palette, etc.
-# LANGUAGES: langages in which the project is written (default "English")
-# English_RESOURCES: localized resources (e.g. nib's, images) of project
-# GLOBAL_RESOURCES: non-localized resources of project
-#
-# SRCROOT: base directory in which to place the new source files
-# SRCPATH: relative path from SRCROOT to present subdirectory
-#
-# INSTALLDIR: Directory the product will be installed into by 'install' target
-# PUBLIC_HDR_INSTALLDIR: where to install public headers. Don't forget
-# to prefix this with DSTROOT when you use it.
-# PRIVATE_HDR_INSTALLDIR: where to install private headers. Don't forget
-# to prefix this with DSTROOT when you use it.
-#
-# EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
-#
-###############################################################################
-
-# Some compiler flags can be overridden here for certain build situations.
-#
-# WARNING_CFLAGS: flag used to set warning level (defaults to -Wmost)
-# DEBUG_SYMBOLS_CFLAGS: debug-symbol flag passed to all builds (defaults
-# to -g)
-# DEBUG_BUILD_CFLAGS: flags passed during debug builds (defaults to -DDEBUG)
-# OPTIMIZE_BUILD_CFLAGS: flags passed during optimized builds (defaults
-# to -O)
-# PROFILE_BUILD_CFLAGS: flags passed during profile builds (defaults
-# to -pg -DPROFILE)
-# LOCAL_DIR_INCLUDE_DIRECTIVE: flag used to add current directory to
-# the include path (defaults to -I.)
-# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
-# passed to ld/libtool (defaults to nothing)
-
-
-# Library and Framework projects only:
-# INSTALL_NAME_DIRECTIVE: This directive ensures that executables linked
-# against the framework will run against the correct version even if
-# the current version of the framework changes. You may override this
-# to "" as an alternative to using the DYLD_LIBRARY_PATH during your
-# development cycle, but be sure to restore it before installing.
-
-
-# Ownership and permissions of files installed by 'install' target
-
-#INSTALL_AS_USER = root
- # User/group ownership
-#INSTALL_AS_GROUP = wheel
- # (probably want to set both of these)
-#INSTALL_PERMISSIONS = 4555
- # If set, 'install' chmod's executable to this
-
-
-# Options to strip. Note: -S strips debugging symbols (executables can be stripped
-# down further with -x or, if they load no bundles, with no options at all).
-
-#STRIPFLAGS = -S
-
-
-#########################################################################
-# Put rules to extend the behavior of the standard Makefiles here. Include them in
-# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
-#
-# You should avoid redefining things like "install" or "app", as they are
-# owned by the top-level Makefile API and no context has been set up for where
-# derived files should go.
-#
-
-install-man-page:
- install -d $(DSTROOT)/usr/share/man/man8
- install -c -m 444 mach_init.8 $(DSTROOT)/usr/share/man/man8/mach_init.8
+++ /dev/null
-OTHER_GENERATED_OFILES = $(VERS_OFILE)
-BEFORE_BUILD += bootstrap.h
-OTHER_OFILES = bootstrapServer.o
-AFTER_INSTALL += install-man-page
+++ /dev/null
-{
- APPCLASS = NSApplication;
- FILESTABLE = {
- BUNDLES = ();
- CLASSES = ();
- "C_FILES" = ();
- FRAMEWORKS = ();
- FRAMEWORKSEARCH = ();
- HEADERSEARCH = ();
- "H_FILES" = ("bootstrap_internal.h", "error_log.h", "lists.h");
- "M_FILES" = ();
- "OTHER_LIBS" = (bsm);
- "OTHER_LINKED" = ("bootstrap.c", "error_log.c", "lists.c", "rpc_services.c");
- "OTHER_SOURCES" = (
- "Makefile.preamble",
- Makefile,
- "bootstrap.defs",
- "mach_init.8",
- "Makefile.postamble"
- );
- SUBPROJECTS = ();
- TOOLS = ();
- };
- LANGUAGE = English;
- "LOCALIZABLE_FILES" = {};
- "NEXTSTEP_BUILDDIR" = "/tmp/$(USER)/BUILD";
- "NEXTSTEP_BUILDTOOL" = "/bin/gnumake";
- "NEXTSTEP_COMPILEROPTIONS" = "-DMACH_USER_API";
- "NEXTSTEP_INSTALLDIR" = "/sbin";
- "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
- "NEXTSTEP_MAINNIB" = "mach_init";
- "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
- "PDO_UNIX_COMPILEROPTIONS" = "-DMACH_USER_API";
- "PDO_UNIX_INSTALLDIR" = "/sbin";
- "PDO_UNIX_JAVA_COMPILER" = "$(NEXTDEV_BIN)/javac";
- "PDO_UNIX_MAINNIB" = "mach_init";
- "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
- PROJECTNAME = "mach_init";
- PROJECTTYPE = Tool;
- PROJECTVERSION = "2.8";
- "WINDOWS_COMPILEROPTIONS" = "-DMACH_USER_API";
- "WINDOWS_INSTALLDIR" = "/sbin";
- "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
- "WINDOWS_MAINNIB" = "mach_init";
- "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
-}
+++ /dev/null
-/*
- * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990. All rights reserved.
- *
- * bootstrap.c -- implementation of bootstrap main service loop
- */
-
-/*
- * Imports
- */
-#import <mach/mach.h>
-#import <mach/boolean.h>
-#import <mach/message.h>
-#import <mach/notify.h>
-#import <mach/mig_errors.h>
-#include <mach/mach_traps.h>
-#include <mach/mach_interface.h>
-#include <mach/bootstrap.h>
-#include <mach/host_info.h>
-#include <mach/mach_host.h>
-#include <mach/exception.h>
-
-#import <sys/ioctl.h>
-#import <sys/types.h>
-#import <sys/time.h>
-#import <sys/resource.h>
-#import <sys/wait.h>
-#import <pthread.h>
-#import <string.h>
-#import <ctype.h>
-#import <stdio.h>
-#import <libc.h>
-#import <paths.h>
-#import <pwd.h>
-
-#include <bsm/audit.h>
-#include <bsm/libbsm.h>
-
-#import "bootstrap.h"
-
-#import "bootstrap_internal.h"
-#import "lists.h"
-#import "error_log.h"
-
-/* Mig should produce a declaration for this, but doesn't */
-extern boolean_t bootstrap_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
-
-/*
- * Exports
- */
-const char *program_name; /* our name for error messages */
-
-#ifndef INIT_PATH
-#define INIT_PATH "/sbin/init" /* default init path */
-#endif INIT_PATH
-
-uid_t inherited_uid = 0;
-auditinfo_t inherited_audit;
-mach_port_t inherited_bootstrap_port = MACH_PORT_NULL;
-boolean_t forward_ok = FALSE;
-boolean_t shutdown_in_progress = FALSE;
-boolean_t debugging = FALSE;
-boolean_t register_self = FALSE;
-boolean_t force_fork = FALSE;
-const char *register_name;
-task_t bootstrap_self;
-
-#ifndef ASSERT
-#define ASSERT(p)
-#endif
-
-/*
- * Private macros
- */
-#define NELEM(x) (sizeof(x)/sizeof(x[0]))
-#define END_OF(x) (&(x)[NELEM(x)])
-#define streq(a,b) (strcmp(a,b) == 0)
-
-/*
- * Private declarations
- */
-static void wait_for_go(mach_port_t init_notify_port);
-static void init_ports(void);
-static void start_server(server_t *serverp);
-static void unblock_init(mach_port_t init_notify_port, mach_port_t newBootstrap);
-static void exec_server(server_t *serverp);
-static char **argvize(const char *string);
-static void *demand_loop(void *arg);
-static void server_loop(void);
-extern kern_return_t bootstrap_register
-(
- mach_port_t bootstrap_port,
- name_t service_name,
- mach_port_t service_port
-);
-
-/*
- * Private ports we hold receive rights for. We also hold receive rights
- * for all the privileged ports. Those are maintained in the server
- * structs.
- */
-mach_port_t bootstrap_port_set;
-mach_port_t demand_port_set;
-pthread_t demand_thread;
-
-mach_port_t notify_port;
-mach_port_t backup_port;
-
-
-static void
-enablecoredumps(boolean_t enabled)
-{
- struct rlimit rlimit;
-
- getrlimit(RLIMIT_CORE, &rlimit);
- rlimit.rlim_cur = (enabled) ? rlimit.rlim_max : 0;
- setrlimit(RLIMIT_CORE, &rlimit);
-}
-
-static void
-toggle_debug(int signal)
-{
-
- debugging = (debugging) ? FALSE : TRUE;
- enablecoredumps(debugging);
-}
-
-static mach_msg_return_t
-inform_server_loop(
- mach_port_name_t about,
- mach_msg_option_t options)
-{
- mach_port_destroyed_notification_t not;
- mach_msg_size_t size = sizeof(not) - sizeof(not.trailer);
-
- not.not_header.msgh_id = DEMAND_REQUEST;
- not.not_header.msgh_remote_port = backup_port;
- not.not_header.msgh_local_port = MACH_PORT_NULL;
- not.not_header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
- not.not_header.msgh_size = size;
- not.not_body.msgh_descriptor_count = 1;
- not.not_port.type = MACH_MSG_PORT_DESCRIPTOR;
- not.not_port.disposition = MACH_MSG_TYPE_PORT_NAME;
- not.not_port.name = about;
- return mach_msg(¬.not_header, MACH_SEND_MSG|options, size,
- 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-}
-
-static void
-notify_server_loop(mach_port_name_t about)
-{
- mach_msg_return_t result;
-
- result = inform_server_loop(about, MACH_MSG_OPTION_NONE);
- if (result != MACH_MSG_SUCCESS)
- kern_error(result, "notify_server_loop: mach_msg()");
-}
-
-void start_shutdown(int signal)
-{
- shutdown_in_progress = TRUE;
- (void) inform_server_loop(MACH_PORT_NULL, MACH_SEND_TIMEOUT);
-}
-
-int
-main(int argc, char * argv[])
-{
- const char *argp;
- char c;
- kern_return_t result;
- mach_port_t init_notify_port;
- pthread_attr_t attr;
- sigset_t mask;
- int pid;
-
- /*
- * If we are pid one, we have to exec init. Before doing so, we'll
- * fork a child, and that will become the true mach_init. But we have
- * to be very careful about ports. They aren't inherited across fork,
- * so we have to avoid storing port names in memory before the fork that
- * might not be valid after.
- */
- pid = getpid();
- if (pid == 1)
- {
- result = mach_port_allocate(
- mach_task_self(),
- MACH_PORT_RIGHT_RECEIVE,
- &init_notify_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_allocate");
-
- result = mach_port_insert_right(
- mach_task_self(),
- init_notify_port,
- init_notify_port,
- MACH_MSG_TYPE_MAKE_SEND);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_insert_right");
-
- result = task_set_bootstrap_port(
- mach_task_self(),
- init_notify_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "task_set_bootstrap_port");
-
- pid = fork();
-
- if (pid < 0)
- unix_fatal("fork");
-
- else if (pid != 0) { /* PARENT - will become init when ready */
- int fd;
-
- /*
- * Wait for mach_init ot give us a real bootstrap port
- */
- wait_for_go(init_notify_port);
-
- close(0);
- close(1);
- close(2);
- fd = open("/dev/tty", O_RDONLY);
- if (fd >= 0) {
- ioctl(fd, TIOCNOTTY, 0);
- close(fd);
- }
-
- /* pass our arguments on to init */
- argv[0] = INIT_PATH;
- execv(argv[0], argv);
- exit(1); /* will likely trigger a panic */
-
- }
-
- /*
- * Child - will continue along as mach_init. Save off
- * the init_notify_port and put back a NULL bootstrap
- * port for ourselves.
- */
- init_notify_port = bootstrap_port;
- bootstrap_port = MACH_PORT_NULL;
- (void)task_set_bootstrap_port(
- mach_task_self(),
- bootstrap_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "task_get_bootstrap_port");
-
- close(0);
- open("/dev/null", O_RDONLY, 0);
- close(1);
- open("/dev/null", O_WRONLY, 0);
- close(2);
- open("/dev/null", O_WRONLY, 0);
-
- } else
- init_notify_port = MACH_PORT_NULL;
-
- /* Initialize error handling */
- program_name = rindex(*argv, '/');
- if (program_name)
- program_name++;
- else
- program_name = *argv;
- argv++; argc--;
-
- /* Parse command line args */
- while (argc > 0 && **argv == '-') {
- argp = *argv++ + 1; argc--;
- while (*argp) {
- switch (c = *argp++) {
- case 'd':
- debugging = TRUE;
- break;
- case 'D':
- debugging = FALSE;
- break;
- case 'F':
- if (init_notify_port != MACH_PORT_NULL)
- force_fork = TRUE;
- break;
- case 'r':
- register_self = forward_ok = TRUE;
- if (argc > 0) {
- register_name = *argv++; argc--;
- } else
- fatal("-r requires name");
- break;
- case '-':
- default:
- break;
- }
- }
- }
-
- /*
- * If we must fork, do it now before we get Mach ports in use
- */
- if (force_fork) {
- pid = fork();
- if (pid < 0)
- unix_fatal("fork");
- else if (pid != 0) /* PARENT: just exit */
- exit(0);
- }
-
- /*
- * This task will become the bootstrap task, initialize the ports.
- */
- bootstrap_self = mach_task_self();
- inherited_uid = getuid();
- getaudit(&inherited_audit);
- init_lists();
- init_ports();
-
- if (init_notify_port != MACH_PORT_NULL) {
- /* send init a real bootstrap port to use */
- unblock_init(init_notify_port, bootstraps.bootstrap_port);
-
- result = mach_port_deallocate(
- bootstrap_self,
- init_notify_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_deallocate");
-
- forward_ok = FALSE;
- inherited_bootstrap_port = MACH_PORT_NULL;
-
- } else {
- /* get inherited bootstrap port */
- result = task_get_bootstrap_port(
- bootstrap_self,
- &inherited_bootstrap_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "task_get_bootstrap_port");
-
- /* We set this explicitly as we start each child */
- task_set_bootstrap_port(bootstrap_self, MACH_PORT_NULL);
- if (inherited_bootstrap_port == MACH_PORT_NULL)
- forward_ok = FALSE;
-
- /* register "self" port with anscestor */
- if (register_self && forward_ok) {
- result = bootstrap_register(
- inherited_bootstrap_port,
- (char *)register_name,
- bootstraps.bootstrap_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "register self");
- }
- }
-
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate ( &attr, PTHREAD_CREATE_DETACHED );
- result = pthread_create(
- &demand_thread,
- &attr,
- demand_loop,
- NULL);
- if (result) {
- unix_error("pthread_create()");
- exit(1);
- }
-
- /* block all but SIGHUP and SIGTERM */
- sigfillset(&mask);
- sigdelset(&mask, SIGHUP);
- signal(SIGHUP, toggle_debug);
- sigdelset(&mask, SIGTERM);
- signal(SIGTERM, start_shutdown);
- (void) sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
-
- /*
- * Construct a very basic environment - as much as if we
- * were actually forked from init (instead of the other
- * way around):
- *
- * Set up the PATH to be approriate for the root user.
- * Create an initial session.
- * Establish an initial user.
- * Disbale core dumps.
- */
- setsid();
- setlogin("root");
- enablecoredumps(debugging);
- setenv("PATH", _PATH_STDPATH, 1);
-
- init_errlog(pid == 0); /* are we a daemon? */
- notice("Started with uid=%d audit-uid=%d%s%s%s",
- inherited_uid,
- inherited_audit.ai_auid,
- (register_self) ? " registered-as=" : "",
- (register_self) ? register_name : "",
- (debugging) ? " in debug-mode" : "");
-
- /* Process bootstrap service requests */
- server_loop(); /* Should never return */
- exit(1);
-}
-
-static void
-wait_for_go(mach_port_t init_notify_port)
-{
- struct {
- mach_msg_header_t hdr;
- mach_msg_trailer_t trailer;
- } init_go_msg;
- kern_return_t result;
-
- /*
- * For now, we just blindly wait until we receive a message or
- * timeout. We don't expect any notifications, and if we get one,
- * it probably means something dire has happened; so we might as
- * well give a shot at letting init run.
- */
- result = mach_msg(
- &init_go_msg.hdr, MACH_RCV_MSG,
- 0, sizeof(init_go_msg), init_notify_port,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (result != KERN_SUCCESS) {
- kern_error(result, "mach_msg(receive) failed in wait_for_go");
- }
- bootstrap_port = init_go_msg.hdr.msgh_remote_port;
- result = task_set_bootstrap_port(
- mach_task_self(),
- bootstrap_port);
- if (result != KERN_SUCCESS) {
- kern_error(result, "task_get_bootstrap_port()");
- }
-}
-
-
-static void
-unblock_init(mach_port_t init_notify_port,
- mach_port_t newBootstrap)
-{
- mach_msg_header_t init_go_msg;
- kern_return_t result;
-
- /*
- * Proc 1 is blocked in a msg_receive on its notify port, this lets
- * it continue, and we hand off its new bootstrap port
- */
- init_go_msg.msgh_remote_port = init_notify_port;
- init_go_msg.msgh_local_port = newBootstrap;
- init_go_msg.msgh_bits = MACH_MSGH_BITS(
- MACH_MSG_TYPE_COPY_SEND,
- MACH_MSG_TYPE_MAKE_SEND);
- init_go_msg.msgh_size = sizeof(init_go_msg);
- result = mach_msg_send(&init_go_msg);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "unblock_init mach_msg_send() failed");
- debug("sent go message");
-}
-
-
-static void
-init_ports(void)
-{
- kern_return_t result;
-
- /*
- * This task will become the bootstrap task.
- */
- /* Create port set that server loop listens to */
- result = mach_port_allocate(
- bootstrap_self,
- MACH_PORT_RIGHT_PORT_SET,
- &bootstrap_port_set);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "port_set_allocate");
-
- /* Create demand port set that second thread listens to */
- result = mach_port_allocate(
- bootstrap_self,
- MACH_PORT_RIGHT_PORT_SET,
- &demand_port_set);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "port_set_allocate");
-
- /* Create notify port and add to server port set */
- result = mach_port_allocate(
- bootstrap_self,
- MACH_PORT_RIGHT_RECEIVE,
- ¬ify_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_allocate");
-
- result = mach_port_move_member(
- bootstrap_self,
- notify_port,
- bootstrap_port_set);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_move_member");
-
- /* Create backup port and add to server port set */
- result = mach_port_allocate(
- bootstrap_self,
- MACH_PORT_RIGHT_RECEIVE,
- &backup_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_allocate");
-
- result = mach_port_move_member(
- bootstrap_self,
- backup_port,
- bootstrap_port_set);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_move_member");
-
- /* Create "self" port and add to server port set */
- result = mach_port_allocate(
- bootstrap_self,
- MACH_PORT_RIGHT_RECEIVE,
- &bootstraps.bootstrap_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_allocate");
- result = mach_port_insert_right(
- bootstrap_self,
- bootstraps.bootstrap_port,
- bootstraps.bootstrap_port,
- MACH_MSG_TYPE_MAKE_SEND);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_insert_right");
-
- /* keep the root bootstrap port "active" */
- bootstraps.requestor_port = bootstraps.bootstrap_port;
-
- result = mach_port_move_member(
- bootstrap_self,
- bootstraps.bootstrap_port,
- bootstrap_port_set);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_move_member");
-}
-
-boolean_t
-active_bootstrap(bootstrap_info_t *bootstrap)
-{
- return (bootstrap->requestor_port != MACH_PORT_NULL);
-}
-
-boolean_t
-useless_server(server_t *serverp)
-{
- return ( !active_bootstrap(serverp->bootstrap) ||
- !lookup_service_by_server(serverp) ||
- !serverp->activity);
-}
-
-boolean_t
-active_server(server_t *serverp)
-{
- return ( serverp->port ||
- serverp->task_port || serverp->active_services);
-}
-
-static void
-reap_server(server_t *serverp)
-{
- kern_return_t result;
- pid_t presult;
- int wstatus;
-
- /*
- * Reap our children.
- */
- presult = waitpid(serverp->pid, &wstatus, WNOHANG);
- if (presult != serverp->pid) {
- unix_error("waitpid: cmd = %s", serverp->cmd);
- } else if (wstatus) {
- notice("Server %x in bootstrap %x uid %d: \"%s\": %s %d [pid %d]",
- serverp->port, serverp->bootstrap->bootstrap_port,
- serverp->uid, serverp->cmd,
- ((WIFEXITED(wstatus)) ?
- "exited with non-zero status" :
- "exited as a result of signal"),
- ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) : WTERMSIG(wstatus)),
- serverp->pid);
- }
- serverp->pid = 0;
-
- /*
- * Release the server task port reference, if we ever
- * got it in the first place.
- */
- if (serverp->task_port != MACH_PORT_NULL) {
- result = mach_port_deallocate(
- mach_task_self(),
- serverp->task_port);
- if (result != KERN_SUCCESS)
- kern_error(result, "mach_port_deallocate");
- serverp->task_port = MACH_PORT_NULL;
- }
-}
-
-static void
-demand_server(server_t *serverp)
-{
- service_t *servicep;
- kern_return_t result;
-
- /*
- * For on-demand servers, make sure that the service ports are
- * back in on-demand portset. Active service ports should come
- * back through a PORT_DESTROYED notification. We only have to
- * worry about the inactive ports that may have been previously
- * pulled from the set but never checked-in by the server.
- */
-
- for ( servicep = FIRST(services)
- ; !IS_END(servicep, services)
- ; servicep = NEXT(servicep))
- {
- if (serverp == servicep->server && !servicep->isActive) {
- result = mach_port_move_member(
- mach_task_self(),
- servicep->port,
- demand_port_set);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_move_member");
- }
- }
-}
-
-static
-void dispatch_server(server_t *serverp)
-{
- if (!active_server(serverp)) {
- if (useless_server(serverp))
- delete_server(serverp);
- else if (serverp->servertype == RESTARTABLE)
- start_server(serverp);
- else if (serverp->servertype == DEMAND)
- demand_server(serverp);
- }
-}
-
-void
-setup_server(server_t *serverp)
-{
- kern_return_t result;
- mach_port_t old_port;
-
- /* Allocate privileged port for requests from service */
- result = mach_port_allocate(mach_task_self(),
- MACH_PORT_RIGHT_RECEIVE ,
- &serverp->port);
- info("Allocating port %x for server %s", serverp->port, serverp->cmd);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "port_allocate");
-
- /* Request no-senders notification so we can tell when server dies */
- result = mach_port_request_notification(mach_task_self(),
- serverp->port,
- MACH_NOTIFY_NO_SENDERS,
- 1,
- serverp->port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &old_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_request_notification");
-
- /* Add privileged server port to bootstrap port set */
- result = mach_port_move_member(mach_task_self(),
- serverp->port,
- bootstrap_port_set);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_move_member");
-}
-
-static void
-start_server(server_t *serverp)
-{
- kern_return_t result;
- mach_port_t old_port;
- int pid;
-
- /*
- * Do what's appropriate to get bootstrap port setup in server task
- */
- switch (serverp->servertype) {
-
- case MACHINIT:
- break;
-
- case SERVER:
- case DEMAND:
- case RESTARTABLE:
- if (!serverp->port)
- setup_server(serverp);
-
- serverp->activity = 0;
-
- /* Insert a send right */
- result = mach_port_insert_right(mach_task_self(),
- serverp->port,
- serverp->port,
- MACH_MSG_TYPE_MAKE_SEND);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_insert_right");
-
- /* Give trusted service a unique bootstrap port */
- result = task_set_bootstrap_port(mach_task_self(),
- serverp->port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "task_set_bootstrap_port");
-
- result = mach_port_deallocate(mach_task_self(),
- serverp->port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_deallocate");
-
- pid = fork();
- if (pid < 0) {
- unix_error("fork");
- } else if (pid == 0) { /* CHILD */
- exec_server(serverp);
- exit(1);
- } else { /* PARENT */
-
- result = task_set_bootstrap_port(
- mach_task_self(),
- MACH_PORT_NULL);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "task_set_bootstrap_port");
-
- info("Launched server %x in bootstrap %x uid %d: \"%s\": [pid %d]",
- serverp->port, serverp->bootstrap->bootstrap_port,
- serverp->uid, serverp->cmd, pid);
- serverp->pid = pid;
- result = task_for_pid(
- mach_task_self(),
- pid,
- &serverp->task_port);
- if (result != KERN_SUCCESS) {
- kern_error(result, "getting server task port");
- reap_server(serverp);
- dispatch_server(serverp);
- break;
- }
-
- /* Request dead name notification to tell when task dies */
- result = mach_port_request_notification(
- mach_task_self(),
- serverp->task_port,
- MACH_NOTIFY_DEAD_NAME,
- 0,
- notify_port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &old_port);
- if (result != KERN_SUCCESS) {
- kern_error(result, "mach_port_request_notification");
- reap_server(serverp);
- dispatch_server(serverp);
- }
- }
- break;
- }
-}
-
-static void
-exec_server(server_t *serverp)
-{
- char **argv;
- sigset_t mask;
-
- /*
- * Setup environment for server, someday this should be Mach stuff
- * rather than Unix crud
- */
- argv = argvize(serverp->cmd);
- close_errlog();
-
- /*
- * Set up the audit state for the user (if necessesary).
- */
- if (inherited_uid == 0 &&
- (serverp->auinfo.ai_auid != inherited_uid ||
- serverp->auinfo.ai_asid != inherited_audit.ai_asid)) {
- struct passwd *pwd = NULL;
-
- pwd = getpwuid(serverp->auinfo.ai_auid);
- if (pwd == NULL) {
- unix_fatal("Disabled server %x bootstrap %x: \"%s\": getpwuid(%d) failed",
- serverp->port, serverp->bootstrap->bootstrap_port,
- serverp->cmd, serverp->auinfo.ai_auid);
-
- } else if (au_user_mask(pwd->pw_name, &serverp->auinfo.ai_mask) != 0) {
- unix_fatal("Disabled server %x bootstrap %x: \"%s\": au_user_mask(%s) failed",
- serverp->port, serverp->bootstrap->bootstrap_port,
- serverp->cmd, pwd->pw_name);
- } else if (setaudit(&serverp->auinfo) != 0)
- unix_fatal("Disabled server %x bootstrap %x: \"%s\": setaudit()",
- serverp->port, serverp->bootstrap->bootstrap_port,
- serverp->cmd);
- }
-
- if (serverp->uid != inherited_uid)
- if (setuid(serverp->uid) < 0)
- unix_fatal("Disabled server %x bootstrap %x: \"%s\": setuid(%d)",
- serverp->port, serverp->bootstrap->bootstrap_port,
- serverp->cmd, serverp->uid);
-
- if (setsid() < 0) {
- /*
- * We can't keep this from happening, but we shouldn't start
- * the server not as a process group leader. So, just fake like
- * there was real activity, and exit the child. If needed,
- * we'll re-launch it under another pid.
- */
- serverp->activity = 1;
- unix_fatal("Temporary failure server %x bootstrap %x: \"%s\": setsid()",
- serverp->port, serverp->bootstrap->bootstrap_port,
- serverp->cmd);
- }
-
- sigemptyset(&mask);
- (void) sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
-
- execv(argv[0], argv);
- unix_fatal("Disabled server %x bootstrap %x: \"%s\": exec()",
- serverp->port,
- serverp->bootstrap->bootstrap_port,
- serverp->cmd);
-}
-
-static char **
-argvize(const char *string)
-{
- static char *argv[100], args[1000];
- const char *cp;
- char *argp, term;
- int nargs;
-
- /*
- * Convert a command line into an argv for execv
- */
- nargs = 0;
- argp = args;
-
- for (cp = string; *cp;) {
- while (isspace(*cp))
- cp++;
- term = (*cp == '"') ? *cp++ : '\0';
- if (nargs < NELEM(argv))
- argv[nargs++] = argp;
- while (*cp && (term ? *cp != term : !isspace(*cp))
- && argp < END_OF(args)) {
- if (*cp == '\\')
- cp++;
- *argp++ = *cp;
- if (*cp)
- cp++;
- }
- *argp++ = '\0';
- }
- argv[nargs] = NULL;
- return argv;
-}
-
-static void *
-demand_loop(void *arg)
-{
- mach_msg_empty_rcv_t dummy;
- kern_return_t dresult;
-
-
- for(;;) {
- mach_port_name_array_t members;
- mach_msg_type_number_t membersCnt;
- mach_port_status_t status;
- mach_msg_type_number_t statusCnt;
- int i;
-
- /*
- * Receive indication of message on demand service
- * ports without actually receiving the message (we'll
- * let the actual server do that.
- */
- dresult = mach_msg(
- &dummy.header,
- MACH_RCV_MSG|MACH_RCV_LARGE,
- 0,
- 0,
- demand_port_set,
- 0,
- MACH_PORT_NULL);
- if (dresult != MACH_RCV_TOO_LARGE) {
- kern_error(dresult, "demand_loop: mach_msg()");
- continue;
- }
-
- /*
- * If we are shutting down, there is no use processing
- * any more of these messages.
- */
- if (shutdown_in_progress == TRUE)
- return arg;
-
- /*
- * Some port(s) now have messages on them, find out
- * which ones (there is no indication of which port
- * triggered in the MACH_RCV_TOO_LARGE indication).
- */
- dresult = mach_port_get_set_status(
- mach_task_self(),
- demand_port_set,
- &members,
- &membersCnt);
- if (dresult != KERN_SUCCESS) {
- kern_error(dresult, "demand_loop: mach_port_get_set_status()");
- continue;
- }
-
- for (i = 0; i < membersCnt; i++) {
- statusCnt = MACH_PORT_RECEIVE_STATUS_COUNT;
- dresult = mach_port_get_attributes(
- mach_task_self(),
- members[i],
- MACH_PORT_RECEIVE_STATUS,
- (mach_port_info_t)&status,
- &statusCnt);
- if (dresult != KERN_SUCCESS) {
- kern_error(dresult, "demand_loop: mach_port_get_attributes()");
- continue;
- }
-
- /*
- * For each port with messages, take it out of the
- * demand service portset, and inform the main thread
- * that it might have to start the server responsible
- * for it.
- */
- if (status.mps_msgcount) {
- dresult = mach_port_move_member(
- mach_task_self(),
- members[i],
- MACH_PORT_NULL);
- if (dresult != KERN_SUCCESS) {
- kern_error(dresult, "demand_loop: mach_port_move_member()");
- continue;
- }
- notify_server_loop(members[i]);
- }
- }
-
- dresult = vm_deallocate(
- mach_task_self(),
- (vm_address_t) members,
- (vm_size_t) membersCnt * sizeof(mach_port_name_t));
- if (dresult != KERN_SUCCESS) {
- kern_error(dresult, "demand_loop: vm_deallocate()");
- continue;
- }
- }
- return NULL;
-}
-
-/*
- * server_demux -- processes requests off our service port
- * Also handles notifications
- */
-
-static boolean_t
-server_demux(
- mach_msg_header_t *Request,
- mach_msg_header_t *Reply)
-{
- bootstrap_info_t *bootstrap;
- service_t *servicep;
- server_t *serverp;
- kern_return_t result;
- mig_reply_error_t *reply;
-
- debug("received message on port %x\n", Request->msgh_local_port);
-
- /*
- * Do minimal cleanup and then exit.
- */
- if (shutdown_in_progress == TRUE) {
- notice("Shutting down. Deactivating root bootstrap (%x) ...",
- bootstraps.bootstrap_port);
- deactivate_bootstrap(&bootstraps);
- notice("Done.");
- exit(0);
- }
-
- reply = (mig_reply_error_t *)Reply;
-
- /*
- * Pick off notification messages
- */
- if (Request->msgh_local_port == notify_port) {
- mach_port_name_t np;
-
- memset(reply, 0, sizeof(*reply));
- switch (Request->msgh_id) {
- case MACH_NOTIFY_DEAD_NAME:
- np = ((mach_dead_name_notification_t *)Request)->not_port;
- debug("Notified dead name %x", np);
-
- if (np == inherited_bootstrap_port) {
- inherited_bootstrap_port = MACH_PORT_NULL;
- forward_ok = FALSE;
- }
-
- /*
- * Check to see if a subset requestor port was deleted.
- */
- while (bootstrap = lookup_bootstrap_by_req_port(np)) {
- debug("Received dead name notification for bootstrap subset %x requestor port %x",
- bootstrap->bootstrap_port, bootstrap->requestor_port);
- mach_port_deallocate(
- mach_task_self(),
- bootstrap->requestor_port);
- bootstrap->requestor_port = MACH_PORT_NULL;
- deactivate_bootstrap(bootstrap);
- }
-
- /*
- * Check to see if a defined service has gone
- * away.
- */
- while (servicep = lookup_service_by_port(np)) {
- /*
- * Port gone, registered service died.
- */
- debug("Received dead name notification for service %s "
- "on bootstrap port %x\n",
- servicep->name, servicep->bootstrap);
- debug("Service %s failed - deallocate", servicep->name);
- delete_service(servicep);
- }
-
- /*
- * Check to see if a launched server task has gone
- * away.
- */
- if (serverp = lookup_server_by_task_port(np)) {
- /*
- * Port gone, server died.
- */
- debug("Received task death notification for server %s ",
- serverp->cmd);
- reap_server(serverp);
- dispatch_server(serverp);
- }
-
- mach_port_deallocate(mach_task_self(), np);
- reply->RetCode = KERN_SUCCESS;
- break;
-
- case MACH_NOTIFY_PORT_DELETED:
- np = ((mach_port_deleted_notification_t *)Request)->not_port;
- debug("port deleted notification on 0x%x\n", np);
- reply->RetCode = KERN_SUCCESS;
- break;
-
- case MACH_NOTIFY_SEND_ONCE:
- debug("notification send-once right went unused\n");
- reply->RetCode = KERN_SUCCESS;
- break;
-
- default:
- error("Unexpected notification: %d", Request->msgh_id);
- reply->RetCode = KERN_FAILURE;
- break;
- }
- }
-
- else if (Request->msgh_local_port == backup_port) {
- mach_port_name_t np;
-
- memset(reply, 0, sizeof(*reply));
-
- np = ((mach_port_destroyed_notification_t *)Request)->not_port.name;
- servicep = lookup_service_by_port(np);
- if (servicep != NULL) {
- server_t *serverp = servicep->server;
-
- switch (Request->msgh_id) {
-
- case MACH_NOTIFY_PORT_DESTROYED:
- /*
- * Port sent back to us, server died.
- */
- debug("Received destroyed notification for service %s",
- servicep->name);
- debug("Service %x bootstrap %x backed up: %s",
- servicep->port, servicep->bootstrap->bootstrap_port,
- servicep->name);
- ASSERT(canReceive(servicep->port));
- servicep->isActive = FALSE;
- serverp->active_services--;
- dispatch_server(serverp);
- reply->RetCode = KERN_SUCCESS;
- break;
-
- case DEMAND_REQUEST:
- /* message reflected over from demand start thread */
- if (!active_server(serverp))
- start_server(serverp);
- reply->RetCode = KERN_SUCCESS;
- break;
-
- default:
- debug("Mysterious backup_port notification %d", Request->msgh_id);
- reply->RetCode = KERN_FAILURE;
- break;
- }
- } else {
- debug("Backup_port notification - previously deleted service");
- reply->RetCode = KERN_FAILURE;
- }
- }
-
- else if (Request->msgh_id == MACH_NOTIFY_NO_SENDERS) {
- mach_port_t ns = Request->msgh_local_port;
-
- if ((serverp = lookup_server_by_port(ns)) != NULL_SERVER) {
- /*
- * A server we launched has released his bootstrap
- * port send right. We won't re-launch him unless
- * his services came back to roost. But we need to
- * destroy the bootstrap port for fear of leaking.
- */
- debug("server %s dropped server port", serverp->cmd);
- serverp->port = MACH_PORT_NULL;
- dispatch_server(serverp);
- } else if (bootstrap = lookup_bootstrap_by_port(ns)) {
- /*
- * The last direct user of a deactivated bootstrap went away.
- * We can finally free it.
- */
- debug("Deallocating bootstrap %x: no more clients", ns);
- bootstrap->bootstrap_port = MACH_PORT_NULL;
- deallocate_bootstrap(bootstrap);
- }
-
- result = mach_port_mod_refs(
- mach_task_self(),
- ns,
- MACH_PORT_RIGHT_RECEIVE,
- -1);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_mod_refs");
-
- memset(reply, 0, sizeof(*reply));
- reply->RetCode = KERN_SUCCESS;
- }
-
- else { /* must be a service request */
- debug("Handled request.");
- return bootstrap_server(Request, Reply);
- }
- return TRUE;
-}
-
-/*
- * server_loop -- pick requests off our service port and process them
- * Also handles notifications
- */
-#define bootstrapMaxRequestSize 1024
-#define bootstrapMaxReplySize 1024
-
-static void
-server_loop(void)
-{
- mach_msg_return_t mresult;
-
- for (;;) {
- mresult = mach_msg_server(
- server_demux,
- bootstrapMaxRequestSize,
- bootstrap_port_set,
- MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER)|
- MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0));
- if (mresult != MACH_MSG_SUCCESS)
- kern_error(mresult, "mach_msg_server");
- }
-}
-
-boolean_t
-canReceive(mach_port_t port)
-{
- mach_port_type_t p_type;
- kern_return_t result;
-
- result = mach_port_type(mach_task_self(), port, &p_type);
- if (result != KERN_SUCCESS) {
- kern_error(result, "port_type");
- return FALSE;
- }
- return ((p_type & MACH_PORT_TYPE_RECEIVE) != 0);
-}
-
-
-boolean_t
-canSend(mach_port_t port)
-{
- mach_port_type_t p_type;
- kern_return_t result;
-
- result = mach_port_type(mach_task_self(), port, &p_type);
- if (result != KERN_SUCCESS) {
- kern_error(result, "port_type");
- return FALSE;
- }
- return ((p_type & MACH_PORT_TYPE_PORT_RIGHTS) != 0);
-}
+++ /dev/null
-/*
- * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990. All rights reserved.
- *
- * bootstrap.defs -- Mig interface definition
- */
-
-subsystem bootstrap 400;
-
-/*
- * Interface: Bootstrap server
- *
- * The bootstrap server is the first user-mode task initiated by the Mach
- * kernel at system boot time. The bootstrap server provides two services,
- * it initiates other system tasks, and manages a table of name-port bindings
- * for fundamental system services (e.g. lookupd, Window Manager, etc...).
- *
- * Name-port bindings can be established with the bootstrap server by either
- * of two mechanisms:
- *
- * 1. The binding can be indicated, in advance of the service that backs it
- * being available, via a "service create" request. In this case, bootstrap
- * will immediately create a port and bind the indicated name with that port.
- * At a later time, a service may "checkin" for the name-port
- * binding and will be returned receive rights for the bound port. Lookup's
- * on bindings created by this mechanism will return send rights to the port,
- * even if no service has "checked-in". In this case, requests sent to the
- * bound port will be queued until a server has checked-in and can satisfy the
- * request.
- *
- * 2. Bindings can be established dynamically via a "register" request. In
- * this case, the register request provides bootstrap with a name and send
- * rights for a port. Bootstrap will provide send rights for the bound port
- * to any requestor via the lookup request.
- *
- * Bootstrap provides its service port to descendant tasks via the Mach
- * "bootstrap" special task port. All direct descendants of bootstrap receive
- * a "privileged" bootstrap service port. System services that initiate
- * untrusted tasks should replace the Mach bootstrap task special port with
- * a subset bootstrap port to prevent them from infecting the namespace.
- *
- * The bootstrap server creates a "backup" port for each service that it
- * creates. This is used to detect when a checked out service is no longer
- * being served. The bootstrap server regains all rights to the port and
- * it is marked available for check-out again. This allows crashed servers to
- * resume service to previous clients. Lookup's on this named port will
- * continue to be serviced by bootstrap while holding receive rights for the
- * bound port. A client may detect that the service is inactive via the
- * bootstrap status request. If an inactive service re-registers rather
- * than "checking-in" the original bound port is destroyed.
- *
- * The status of a named service may be obtained via the "status" request.
- * A service is "active" if a name-port binding exists and receive rights
- * to the bound port are held by a task other than bootstrap.
- *
- * The bootstrap server may also (re)start server processes associated with
- * with a set of services. The definition of the server process is done
- * through the "create server" request. The server will be launched in the
- * same bootstrap context in which it was registered.
- */
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-import <servers/bootstrap_defs.h>;
-
-type cmd_t = c_string[512];
-type name_t = c_string[128];
-type cmd_array_t = ^array [] of cmd_t;
-type name_array_t = ^array [] of name_t;
-type bootstrap_status_t = integer_t;
-type bootstrap_status_array_t = ^array [] of bootstrap_status_t;
-
-serverprefix x_;
-
-/*
- * kern_return_t
- * bootstrap_create_server(mach_port_t bootstrap_port,
- * cmd_t server_command,
- * integer_t server_uid,
- * boolean_t on_demand,
- * mach_port_t *server_port)
- *
- * Declares a server that mach_init will re-spawn within the specified
- * bootstrap context. The server is considered already "active"
- * (i.e. will not be re-spawned) until the returned server_port is
- * deallocated.
- *
- * In the meantime, services can be declared against the server,
- * by using the server_port as the privileged bootstrap target of
- * subsequent bootstrap_create_service() calls.
- *
- * When mach_init re-spawns the server, its task bootstrap port
- * is set to the privileged sever_port. Through this special
- * bootstrap port, it can access all of parent bootstrap's context
- * (and all services are created in the parent's namespace). But
- * all additional service declarations (and declaration removals)
- * will be associated with this particular server.
- *
- * Only a holder of the server_port privilege bootstrap port can
- * check in or register over those services.
- *
- * When all services associated with a server are deleted, and the server
- * exits, it will automatically be deleted itself.
- *
- * If the server is declared "on_demand," then a non-running server
- * will be re-launched on first use of one of the service ports
- * registered against it. Otherwise, it will be re-launched
- * immediately upon exiting (whether any client is actively using
- * any of the service ports or not).
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_NOT_PRIVILEGED, bootstrap or uid invalid.
- */
-routine bootstrap_create_server(
- bootstrap_port : mach_port_t;
- server_cmd : cmd_t;
- server_uid : integer_t;
- on_demand : boolean_t;
- ServerAuditToken token : audit_token_t;
- out server_port : mach_port_make_send_t);
-
-/*
- * kern_return_t
- * bootstrap_unprivileged(mach_port_t bootstrap_port,
- * mach_port_t *unpriv_port)
- *
- * Given a bootstrap port, return its unprivileged equivalent. If
- * the port is already unprivileged, another reference to the same
- * port is returned.
- *
- * This is most often used by servers, which are launched with their
- * bootstrap port set to the privileged port for the server, to get
- * an unprivileged version of the same port for use by its unprivileged
- * children (or any offspring that it does not want to count as part
- * of the "server" for mach_init registration and re-launch purposes).
- */
-routine bootstrap_unprivileged(
- bootstrap_port : mach_port_t;
- out unpriv_port : mach_port_t);
-
-/*
- * kern_return_t
- * bootstrap_check_in(mach_port_t bootstrap_port,
- * name_t service_name,
- * mach_port_t *service_port)
- *
- * Returns the receive right for the service named by service_name. The
- * service must have previously been declared in this bootstrap context via
- * a call to bootstrap_create_service(). Attempts to check_in a service
- * which is already active are not allowed.
- *
- * If the service was declared as being associated with a server, the
- * check_in must come from the server's privileged port (server_port).
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to
- * bootstrap port without privilege.
- * Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been
- * registered or checked-in.
- */
-routine bootstrap_check_in(
- bootstrap_port : mach_port_t;
- service_name : name_t;
- out service_port : mach_port_move_receive_t);
-
-/*
- * kern_return_t
- * bootstrap_register(mach_port_t bootstrap_port,
- * name_t service_name,
- * mach_port_t service_port)
- *
- * Registers a send right for service_port with the service identified by
- * service_name. Attempts to register a service where an active binding
- * already exists are rejected.
- *
- * If the service was previously declared with bootstrap_create_service(),
- * but is not currently active, this call can be used to undeclare the
- * service. The bootstrap port used must have sufficient privilege to
- * do so. (Registering MACH_PORT_NULL is especially useful for shutting
- * down declared services).
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to
- * bootstrap port without privilege.
- * Returns BOOTSTRAP_NAME_IN_USE, if service has already been
- * register or checked-in.
- */
-routine bootstrap_register(
- bootstrap_port : mach_port_t;
- service_name : name_t;
- service_port : mach_port_t);
-
-/*
- * kern_return_t
- * bootstrap_look_up(mach_port_t bootstrap_port,
- * name_t service_name,
- * mach_port_t *service_port)
- *
- * Returns a send right for the service port declared/registered under the
- * name service_name. The service is not guaranteed to be active. Use the
- * bootstrap_status call to determine the status of the service.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- */
-routine bootstrap_look_up(
- bootstrap_port : mach_port_t;
- service_name : name_t;
- out service_port : mach_port_t);
-
-/*
- * kern_return_t
- * bootstrap_look_up_array(mach_port_t bootstrap_port,
- * name_array_t service_names,
- * int service_names_cnt,
- * port_array_t *service_port,
- * int *service_ports_cnt,
- * boolean_t *all_services_known)
- *
- * Returns port send rights in corresponding entries of the array service_ports
- * for all services named in the array service_names. Service_ports_cnt is
- * returned and will always equal service_names_cnt (assuming service_names_cnt
- * is greater than or equal to zero).
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_NO_MEMORY, if server couldn't obtain memory
- * for response.
- * Unknown service names have the corresponding service port set
- * to PORT_NULL.
- * If all services are known, all_services_known is true on
- * return, if any service is unknown, it's false.
- */
-routine bootstrap_look_up_array(
- bootstrap_port : mach_port_t;
- service_names : name_array_t;
- out service_ports : mach_port_array_t;
- out all_services_known: boolean_t);
-
-/*
- * kern_return_t
- * bootstrap_parent(mach_port_t bootstrap_port,
- * mach_port_t *parent_port);
- *
- * Given a bootstrap subset port, return the parent bootstrap port.
- * If the specified bootstrap port is already the root subset,
- * MACH_PORT_NULL will be returned.
- *
- * Errors:
- * Returns BOOTSTRAP_NOT_PRIVILEGED if the caller is not running
- * with an effective user id of root (as determined by the security
- * token in the message trailer).
- */
-routine bootstrap_parent(
- bootstrap_port : mach_port_t;
- ServerSecToken token : security_token_t;
- out parent_port : mach_port_make_send_t);
-
-/*
- * kern_return_t
- * bootstrap_status(mach_port_t bootstrap_port,
- * name_t service_name,
- * bootstrap_status_t *service_active);
- *
- * Returns: service_active indicates if service is active, inactive, or
- * associated with a launch-on-demand server.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- */
-routine bootstrap_status(
- bootstrap_port : mach_port_t;
- service_name : name_t;
- out service_active : bootstrap_status_t);
-
-/*
- * kern_return_t
- * bootstrap_info(port_t bootstrap_port,
- * name_array_t *service_names,
- * int *service_names_cnt,
- * name_array_t *server_names,
- * int *server_names_cnt,
- * bool_array_t *service_active,
- * int *service_active_cnt);
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- */
-routine bootstrap_info(
- bootstrap_port : mach_port_t;
- out service_names : name_array_t, dealloc;
- out server_names : name_array_t, dealloc;
- out service_active : bootstrap_status_array_t, dealloc);
-
-/*
- * kern_return_t
- * bootstrap_subset(mach_port_t bootstrap_port,
- * mach_port_t requestor_port,
- * mach_port_t *subset_port);
- *
- * Returns a new port to use as a bootstrap port. This port behaves
- * exactly like the previous bootstrap_port, except that ports dynamically
- * registered via bootstrap_register() are available only to users of this
- * specific subset_port. Lookups on the subset_port will return ports
- * registered with this port specifically, and ports registered with
- * ancestors of this subset_port. Duplications of services already
- * registered with an ancestor port may be registered with the subset port
- * are allowed. Services already advertised may then be effectively removed
- * by registering PORT_NULL for the service.
- * When it is detected that the requestor_port is destroyed the subset
- * port and all services advertized by it are destroied as well.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- */
-routine bootstrap_subset(
- bootstrap_port : mach_port_t;
- requestor_port : mach_port_t;
- out subset_port : mach_port_t);
-
-/*
- * kern_return_t
- * bootstrap_create_service(mach_port_t bootstrap_port,
- * name_t service_name,
- * mach_port_t *service_port)
- *
- * Creates a service named "service_name" and returns send rights to that
- * port in "service_port." The port may later be checked in as if this
- * port were configured in the bootstrap configuration file.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_SERVICE_ACTIVE, if service already exists.
- */
-routine bootstrap_create_service(
- bootstrap_port : mach_port_t;
- service_name : name_t;
- out service_port : mach_port_t);
-
+++ /dev/null
-/*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990. All rights reserved.
- *
- * bootstrap_internal.h -- global internal data definitions
- */
-
-#import <mach/mach.h>
-#import <mach/boolean.h>
-#import <mach/notify.h>
-
-#define BASEPRI_USER 31 /* AOF 20/02/2002 */
-
-#define BITS_PER_BYTE 8 /* this SHOULD be a well defined constant */
-#define ANYWHERE TRUE /* For use with vm_allocate() */
-
-#define DEMAND_REQUEST MACH_NOTIFY_LAST /* demand service messaged */
-
-extern const char *program_name;
-extern mach_port_t lookup_only_port;
-extern mach_port_t inherited_bootstrap_port;
-extern mach_port_t self_port; /* Compatability hack */
-extern boolean_t forward_ok;
-extern boolean_t debugging;
-extern mach_port_t bootstrap_port_set;
-extern mach_port_t demand_port_set;
-extern mach_port_t notify_port;
-extern mach_port_t backup_port;
-extern boolean_t canReceive(mach_port_t port);
-extern boolean_t canSend(mach_port_t port);
+++ /dev/null
-/*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990. All rights reserved.
- *
- * error_log.c -- implementation of logging routines
- *
- * Routines may be safely invoked from multiple threads
- */
-
-#import <pthread.h>
-#import <mach/mach_error.h>
-#import <stdio.h>
-#import <syslog.h>
-#import <sys/syslimits.h>
-#import <libc.h>
-#import <errno.h>
-
-#import "bootstrap_internal.h"
-#import "error_log.h"
-
-static pthread_mutex_t errlog_lock = PTHREAD_MUTEX_INITIALIZER;
-static boolean_t stderr_open = FALSE;
-static boolean_t log_stopped = FALSE;
-
-void
-init_errlog(boolean_t daemon)
-{
- int nfds, fd;
-
- if (!daemon) {
- stderr_open = TRUE;
- nfds = getdtablesize();
- for (fd = 3; fd < nfds; fd++)
- close(fd);
- } else {
- openlog((char *)program_name, LOG_PID|LOG_CONS, LOG_DAEMON);
- setlogmask(LOG_UPTO(LOG_DEBUG)); /* we'll do our own filtering */
- }
-}
-
-void
-stop_errlog(void)
-{
- log_stopped = TRUE;
-}
-
-void
-close_errlog(void)
-{
- stop_errlog();
- closelog();
-}
-
-static void do_log(const int level, const char *format, va_list ap)
-{
- if (!log_stopped && (debugging || level <= LOG_NOTICE)) {
- pthread_mutex_lock(&errlog_lock);
- if (stderr_open) {
- fprintf(stderr, "%s[%d]%s: ",
- level == LOG_ALERT ? " FATAL" : "",
- getpid(), program_name);
- vfprintf(stderr, format, ap);
- fprintf(stderr, "\n");
- } else {
- vsyslog(level, format, ap);
- }
- pthread_mutex_unlock(&errlog_lock);
- }
-}
-
-void debug(const char *format, ...)
-{
- if (debugging) {
- va_list ap;
-
- va_start(ap, format);
- do_log(LOG_DEBUG, format, ap);
- va_end(ap);
- }
-}
-
-void info(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- do_log(LOG_INFO, format, ap);
- va_end(ap);
-}
-
-void notice(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- do_log(LOG_NOTICE, format, ap);
- va_end(ap);
-}
-
-void error(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- do_log(LOG_CRIT, format, ap);
- va_end(ap);
-}
-
-void kern_error(kern_return_t result, const char *format, ...)
-{
- va_list ap;
- char buf[1000];
-
- sprintf(buf, "%s: %s(%d)", format, mach_error_string(result), result);
-
- va_start(ap, format);
- do_log(LOG_CRIT, buf, ap);
- va_end(ap);
-}
-
-void unix_error(const char *format, ...)
-{
- va_list ap;
- char buf[1000];
-
- sprintf(buf, "%s: %s(%d)", format, strerror(errno), errno);
-
- va_start(ap, format);
- do_log(LOG_CRIT, buf, ap);
- va_end(ap);
-}
-
-void parse_error(const char *token_string, const char *format, ...)
-{
- va_list ap;
- char buf[1000];
-
- sprintf(buf, "%s unexpected: %s", token_string, format);
-
- va_start(ap, format);
- do_log(LOG_CRIT, buf, ap);
- va_end(ap);
-}
-
-void fatal(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- do_log(LOG_ALERT, format, ap);
- va_end(ap);
- exit(1);
-}
-
-void kern_fatal(kern_return_t result, const char *format, ...)
-{
- va_list ap;
- char buf[1000];
-
- sprintf(buf, "%s: %s(%d)", format, mach_error_string(result), result);
-
- va_start(ap, format);
- do_log(LOG_ALERT, buf, ap);
- va_end(ap);
- exit(1);
-}
-
-void unix_fatal(const char *format, ...)
-{
- va_list ap;
- char buf[1000];
-
- sprintf(buf, "%s: %s(%d)", format, strerror(errno), errno);
-
- va_start(ap, format);
- do_log(LOG_ALERT, buf, ap);
- va_end(ap);
- exit(1);
-}
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990. All rights reserved.
- *
- * error_log.h -- interface to logging routines
- */
-
-#import <mach/mach.h>
-
-extern void init_errlog(boolean_t);
-extern void stop_errlog(void);
-extern void close_errlog(void);
-extern void debug(const char *format, ...);
-extern void info(const char *format, ...);
-extern void notice(const char *format, ...);
-extern void error(const char *format, ...);
-extern void kern_error(kern_return_t result, const char *format, ...);
-extern void parse_error(const char *token_string, const char *format, ...);
-extern void unix_error(const char *msg, ...);
-extern void fatal(const char *msg, ...);
-extern void kern_fatal(kern_return_t result, const char *msg, ...);
-extern void unix_fatal(const char *msg, ...);
-
+++ /dev/null
-/*
- * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990. All rights reserved.
- *
- * lists.c -- implementation of list handling routines
- */
-
-#import <mach/boolean.h>
-#import <mach/mach_error.h>
-
-#import <stdlib.h>
-#import <string.h>
-
-#import <bsm/audit.h>
-
-#import "bootstrap_internal.h"
-#import "lists.h"
-#import "error_log.h"
-
-/*
- * Exports
- */
-bootstrap_info_t bootstraps; /* head of list of all bootstrap ports */
-server_t servers; /* head of list of all servers */
-service_t services; /* head of list of all services */
-unsigned nservices; /* number of services in list */
-
-#ifndef ASSERT
-#define ASSERT(p)
-#endif
-
-/*
- * Private macros
- */
-#define NEW(type, num) ((type *)ckmalloc(sizeof(type) * num))
-#define STREQ(a, b) (strcmp(a, b) == 0)
-#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
-#define LAST_ELEMENT(x) ((x)[NELEM(x)-1])
-
-void
-init_lists(void)
-{
- bootstraps.ref_count = 2; /* make sure we never deallocate this one */
- bootstraps.next = bootstraps.prev = &bootstraps;
- bootstraps.parent = &bootstraps;
- servers.next = servers.prev = &servers;
- services.next = services.prev = &services;
- nservices = 0;
-}
-
-server_t *
-new_server(
- bootstrap_info_t *bootstrap,
- const char *cmd,
- int uid,
- servertype_t servertype,
- auditinfo_t auinfo)
-{
- server_t *serverp;
-
- debug("adding new server \"%s\" with uid %d\n", cmd, uid);
- serverp = NEW(server_t, 1);
- if (serverp != NULL) {
- /* Doubly linked list */
- servers.prev->next = serverp;
- serverp->prev = servers.prev;
- serverp->next = &servers;
- servers.prev = serverp;
-
- bootstrap->ref_count++;
- serverp->bootstrap = bootstrap;
-
- serverp->pid = NO_PID;
- serverp->task_port = MACH_PORT_NULL;
-
- serverp->uid = uid;
- serverp->auinfo = auinfo;
-
- serverp->port = MACH_PORT_NULL;
- serverp->servertype = servertype;
- serverp->activity = 0;
- serverp->active_services = 0;
- strncpy(serverp->cmd, cmd, sizeof serverp->cmd);
- LAST_ELEMENT(serverp->cmd) = '\0';
- }
- return serverp;
-}
-
-service_t *
-new_service(
- bootstrap_info_t *bootstrap,
- const char *name,
- mach_port_t service_port,
- boolean_t isActive,
- servicetype_t servicetype,
- server_t *serverp)
-{
- service_t *servicep;
-
- servicep = NEW(service_t, 1);
- if (servicep != NULL) {
- /* Doubly linked list */
- services.prev->next = servicep;
- servicep->prev = services.prev;
- servicep->next = &services;
- services.prev = servicep;
-
- nservices += 1;
-
- strncpy(servicep->name, name, sizeof servicep->name);
- LAST_ELEMENT(servicep->name) = '\0';
- servicep->servicetype = servicetype;
- servicep->bootstrap = bootstrap;
- servicep->port = service_port;
- servicep->server = serverp;
- servicep->isActive = isActive;
- }
- return servicep;
-}
-
-bootstrap_info_t *
-new_bootstrap(
- bootstrap_info_t *parent,
- mach_port_t bootstrap_port,
- mach_port_t requestor_port)
-{
- bootstrap_info_t *bootstrap;
-
- bootstrap = NEW(bootstrap_info_t, 1);
- if (bootstrap != NULL) {
- /* Doubly linked list */
- bootstraps.prev->next = bootstrap;
- bootstrap->prev = bootstraps.prev;
- bootstrap->next = &bootstraps;
- bootstraps.prev = bootstrap;
-
- bootstrap->bootstrap_port = bootstrap_port;
- bootstrap->requestor_port = requestor_port;
-
- bootstrap->ref_count = 1;
- bootstrap->parent = parent;
- parent->ref_count++;
- }
- return bootstrap;
-}
-
-bootstrap_info_t *
-lookup_bootstrap_by_port(mach_port_t port)
-{
- bootstrap_info_t *bootstrap;
- bootstrap_info_t *first;
- server_t *serverp;
-
- bootstrap = first = FIRST(bootstraps);
- do {
- if (bootstrap->bootstrap_port == port)
- return bootstrap;
- bootstrap = NEXT(bootstrap);
- } while (bootstrap != first);
-
- for ( serverp = FIRST(servers)
- ; !IS_END(serverp, servers)
- ; serverp = NEXT(serverp))
- {
- if (port == serverp->port)
- return serverp->bootstrap;
- }
- return NULL;
-}
-
-bootstrap_info_t *
-lookup_bootstrap_by_req_port(mach_port_t port)
-{
- bootstrap_info_t *bootstrap;
-
- for ( bootstrap = FIRST(bootstraps)
- ; !IS_END(bootstrap, bootstraps)
- ; bootstrap = NEXT(bootstrap))
- {
- if (bootstrap->requestor_port == port)
- return bootstrap;
- }
-
- return NULL;
-}
-
-service_t *
-lookup_service_by_name(bootstrap_info_t *bootstrap, name_t name)
-{
- service_t *servicep;
-
- if (bootstrap)
- do {
- for ( servicep = FIRST(services)
- ; !IS_END(servicep, services)
- ; servicep = NEXT(servicep))
- {
- if (!STREQ(name, servicep->name))
- continue;
- if (bootstrap && servicep->bootstrap != bootstrap)
- continue;
- return servicep;
- }
- } while (bootstrap != &bootstraps &&
- (bootstrap = bootstrap->parent));
- return NULL;
-}
-
-void
-unlink_service(service_t *servicep)
-{
- ASSERT(servicep->prev->next == servicep);
- ASSERT(servicep->next->prev == servicep);
- servicep->prev->next = servicep->next;
- servicep->next->prev = servicep->prev;
- servicep->prev = servicep->next = servicep; // idempotent
-}
-
-void
-delete_service(service_t *servicep)
-{
- unlink_service(servicep);
- switch (servicep->servicetype) {
- case REGISTERED:
- info("Registered service %s deleted", servicep->name);
- mach_port_deallocate(mach_task_self(), servicep->port);
- break;
- case DECLARED:
- info("Declared service %s now unavailable", servicep->name);
- mach_port_deallocate(mach_task_self(), servicep->port);
- mach_port_mod_refs(mach_task_self(), servicep->port,
- MACH_PORT_RIGHT_RECEIVE, -1);
- break;
- default:
- error("unknown service type %d\n", servicep->servicetype);
- break;
- }
- free(servicep);
- nservices -= 1;
-}
-
-void
-delete_bootstrap_services(bootstrap_info_t *bootstrap)
-{
- server_t *serverp;
- service_t *servicep;
- service_t *next;
-
- for ( servicep = FIRST(services)
- ; !IS_END(servicep, services)
- ; servicep = next)
- {
- next = NEXT(servicep);
- if (bootstrap != servicep->bootstrap)
- continue;
-
- if (!servicep->isActive || !servicep->server) {
- delete_service(servicep);
- continue;
- }
-
- serverp = servicep->server;
- delete_service(servicep);
- serverp->active_services--;
- if (!active_server(serverp))
- delete_server(serverp);
- }
-}
-
-service_t *
-lookup_service_by_port(mach_port_t port)
-{
- service_t *servicep;
-
- for ( servicep = FIRST(services)
- ; !IS_END(servicep, services)
- ; servicep = NEXT(servicep))
- {
- if (port == servicep->port)
- return servicep;
- }
- return NULL;
-}
-
-service_t *
-lookup_service_by_server(server_t *serverp)
-{
- service_t *servicep;
-
- for ( servicep = FIRST(services)
- ; !IS_END(servicep, services)
- ; servicep = NEXT(servicep))
- {
- if (serverp == servicep->server)
- return servicep;
- }
- return NULL;
-}
-
-server_t *
-lookup_server_by_task_port(mach_port_t port)
-{
- server_t *serverp;
-
- for ( serverp = FIRST(servers)
- ; !IS_END(serverp, servers)
- ; serverp = NEXT(serverp))
- {
- if (port == serverp->task_port)
- return serverp;
- }
- return NULL;
-}
-
-server_t *
-lookup_server_by_port(mach_port_t port)
-{
- server_t *serverp;
-
- for ( serverp = FIRST(servers)
- ; !IS_END(serverp, servers)
- ; serverp = NEXT(serverp))
- {
- if (port == serverp->port)
- return serverp;
- }
- return NULL;
-}
-
-void
-delete_server(server_t *serverp)
-{
- service_t *servicep;
- service_t *next;
-
- info("Deleting server %s", serverp->cmd);
- ASSERT(serverp->prev->next == serverp);
- ASSERT(serverp->next->prev == serverp);
- serverp->prev->next = serverp->next;
- serverp->next->prev = serverp->prev;
-
- for ( servicep = FIRST(services)
- ; !IS_END(servicep, services)
- ; servicep = next)
- {
- next = NEXT(servicep);
- if (serverp == servicep->server)
- delete_service(servicep);
- }
-
- deallocate_bootstrap(serverp->bootstrap);
-
- if (serverp->port)
- mach_port_mod_refs(mach_task_self(), serverp->port,
- MACH_PORT_RIGHT_RECEIVE, -1);
-
- free(serverp);
-}
-
-void
-deactivate_bootstrap(bootstrap_info_t *bootstrap)
-{
- bootstrap_info_t *deactivating_bootstraps;
- bootstrap_info_t *query_bootstrap;
- bootstrap_info_t *next_limit;
- bootstrap_info_t *limit;
-
- /*
- * we need to recursively deactivate the whole subset tree below
- * this point. But we don't want to do real recursion because
- * we don't have a limit on the depth. So, build up a chain of
- * active bootstraps anywhere underneath this one.
- */
- deactivating_bootstraps = bootstrap;
- bootstrap->deactivate = NULL;
- for (next_limit = deactivating_bootstraps, limit = NULL
- ; deactivating_bootstraps != limit
- ; limit = next_limit, next_limit = deactivating_bootstraps)
- {
- for (bootstrap = deactivating_bootstraps
- ; bootstrap != limit
- ; bootstrap = bootstrap->deactivate)
- {
- for ( query_bootstrap = FIRST(bootstraps)
- ; !IS_END(query_bootstrap, bootstraps)
- ; query_bootstrap = NEXT(query_bootstrap))
- {
- if (query_bootstrap->parent == bootstrap &&
- query_bootstrap->requestor_port != MACH_PORT_NULL) {
- mach_port_deallocate(
- mach_task_self(),
- query_bootstrap->requestor_port);
- query_bootstrap->requestor_port = MACH_PORT_NULL;
- query_bootstrap->deactivate = deactivating_bootstraps;
- deactivating_bootstraps = query_bootstrap;
- }
- }
- }
- }
-
- /*
- * The list is ordered with the furthest away progeny being
- * at the front, and concluding with the one we started with.
- * This allows us to safely deactivate and remove the reference
- * each holds on their parent without fear of the chain getting
- * corrupted (because each active parent holds a reference on
- * itself and that doesn't get removed until we reach its spot
- * in the list).
- */
- do {
- bootstrap = deactivating_bootstraps;
- deactivating_bootstraps = bootstrap->deactivate;
-
- info("deactivating bootstrap %x", bootstrap->bootstrap_port);
-
- delete_bootstrap_services(bootstrap);
-
- mach_port_deallocate(mach_task_self(), bootstrap->bootstrap_port);
-
- {
- mach_port_t previous;
- mach_port_request_notification(
- mach_task_self(),
- bootstrap->bootstrap_port,
- MACH_NOTIFY_NO_SENDERS,
- 1,
- bootstrap->bootstrap_port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &previous);
- }
- } while (deactivating_bootstraps != NULL);
-}
-
-void
-deallocate_bootstrap(bootstrap_info_t *bootstrap)
-{
- ASSERT(bootstrap->prev->next == bootstrap);
- ASSERT(bootstrap->next->prev == bootstrap);
- if (--bootstrap->ref_count > 0)
- return;
-
- bootstrap->prev->next = bootstrap->next;
- bootstrap->next->prev = bootstrap->prev;
- deallocate_bootstrap(bootstrap->parent);
- free(bootstrap);
-}
-
-void *
-ckmalloc(unsigned nbytes)
-{
- void *cp;
-
- if ((cp = malloc(nbytes)) == NULL)
- fatal("Out of memory");
- return cp;
-}
-
-
+++ /dev/null
-/*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990. All rights reserved.
- *
- * lists.h -- interface to list routines
- */
-
-#import <sys/types.h>
-#import <mach/mach.h>
-#import <mach/boolean.h>
-#import <servers/bootstrap_defs.h>
-
-#import <bsm/audit.h>
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif NULL
-
-typedef struct bootstrap bootstrap_info_t;
-typedef struct service service_t;
-typedef struct server server_t;
-
-/* Bootstrap info */
-struct bootstrap {
- bootstrap_info_t *next; /* list of all bootstraps */
- bootstrap_info_t *prev;
- bootstrap_info_t *parent;
- bootstrap_info_t *deactivate; /* list being deactivated */
- mach_port_name_t bootstrap_port;
- mach_port_name_t requestor_port;
- unsigned int ref_count;
-};
-
-/* Service types */
-typedef enum {
- DECLARED, /* Declared in config file */
- REGISTERED /* Registered dynamically */
-} servicetype_t;
-
-struct service {
- service_t *next; /* list of all services */
- service_t *prev;
- name_t name; /* service name */
- mach_port_name_t port; /* service port,
- may have all rights if inactive */
- bootstrap_info_t *bootstrap; /* bootstrap port(s) used at this
- * level. */
- boolean_t isActive; /* server is running */
- servicetype_t servicetype; /* Declared, Registered, or Machport */
- server_t *server; /* server, declared services only */
-};
-
-/* Server types */
-typedef enum {
- SERVER, /* Launchable server */
- RESTARTABLE, /* Restartable server */
- DEMAND, /* Restartable server - on demand */
- MACHINIT, /* mach_init doesn't get launched. */
-} servertype_t;
-
-#define NULL_SERVER NULL
-#define ACTIVE TRUE
-
-struct server {
- server_t *next; /* list of all servers */
- server_t *prev;
- servertype_t servertype;
- int uid; /* uid to exec server with */
- auditinfo_t auinfo; /* server's audit information */
- mach_port_t port; /* server's priv bootstrap port */
- mach_port_t task_port; /* server's task port */
- pid_t pid; /* server's pid */
- int activity; /* count of checkins/registers this instance */
- int active_services;/* count of active services */
- bootstrap_info_t *bootstrap; /* bootstrap context */
- cmd_t cmd; /* server command to exec */
-};
-
-#define NO_PID (-1)
-
-extern void init_lists(void);
-
-extern server_t *new_server(
- bootstrap_info_t *bootstrap,
- const char *cmd,
- int uid,
- servertype_t servertype,
- auditinfo_t auinfo);
-
-extern service_t *new_service(
- bootstrap_info_t *bootstrap,
- const char *name,
- mach_port_t service_port,
- boolean_t isActive,
- servicetype_t servicetype,
- server_t *serverp);
-
-extern bootstrap_info_t *new_bootstrap(
- bootstrap_info_t *parent,
- mach_port_name_t bootstrap_port,
- mach_port_name_t requestor_port);
-
-extern server_t *lookup_server_by_port(mach_port_t port);
-extern server_t *lookup_server_by_task_port(mach_port_t port);
-extern void setup_server(server_t *serverp);
-extern void delete_server(server_t *serverp);
-extern boolean_t active_server(server_t *serverp);
-extern boolean_t useless_server(server_t *serverp);
-
-extern void delete_service(service_t *servicep);
-extern service_t *lookup_service_by_name(bootstrap_info_t *bootstrap, name_t name);
-extern service_t *lookup_service_by_port(mach_port_t port);
-extern service_t *lookup_service_by_server(server_t *serverp);
-
-extern bootstrap_info_t *lookup_bootstrap_by_port(mach_port_t port);
-extern bootstrap_info_t *lookup_bootstrap_by_req_port(mach_port_t port);
-extern void deactivate_bootstrap(bootstrap_info_t *bootstrap);
-extern void deallocate_bootstrap(bootstrap_info_t *bootstrap);
-extern boolean_t active_bootstrap(bootstrap_info_t *bootstrap);
-
-extern void *ckmalloc(unsigned nbytes);
-
-extern bootstrap_info_t bootstraps; /* head of list of bootstrap ports */
-extern server_t servers; /* head of list of all servers */
-extern service_t services; /* head of list of all services */
-extern unsigned nservices; /* number of services in list */
-
-#define FIRST(q) ((q).next)
-#define NEXT(qe) ((qe)->next)
-#define PREV(qe) ((qe)->prev)
-#define IS_END(qe, q) ((qe) == &(q))
+++ /dev/null
-.\" Copyright (c) 2002, Apple Computer, Inc. All rights reserved.
-.\"
-.Dd March 20, 2002
-.Dt MACH_INIT 8
-.Os "Mac OS X"
-.Sh NAME
-.Nm mach_init
-.Nd Mach service naming (bootstrap) daemon
-.Sh SYNOPSIS
-.Nm mach_init
-.Op Fl D
-.Op Fl d
-.Op Fl F
-.Op Fl r Ar name-in-existing-server
-.Sh DESCRIPTION
-.Nm mach_init
-is a daemon that maintains various mappings between service names and
-the Mach ports that provide access to those services. Clients of mach_init
-can register and lookup services, create new mapping subsets, and
-associate services with declared servers. The mach_init daemon will
-also be responsible for launching (and/or re-launching) those service
-providing servers when attempts to use one or more of the associated services
-is detected.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl D
-When the
-.Fl D
-option is specified,
-.Nm mach_init
-starts in normal (non-debug) mode. Logging is minimal (only security-related
-and process launch failures are logged). Core dumps are disabled for launched
-servers. This is the default.
-.It Fl d
-When the
-.Fl d
-option is specified,
-.Nm mach_init
-starts in debug mode. Logging is extensive. Core dumps will be taken for any
-launched servers that crash.
-.It Fl F
-When the
-.Fl F
-option is specified,
-.Nm mach_init
-forks during initialization so that it doesn't have to be put in
-the background manually by the caller.
-.It Fl r
-Using the
-.Fl r
-option tells
-.Nm mach_init
-to register itself in a previously running copy of
-.Nm mach_init
-under the service name
-.Ar name-in-existing-server.
-This is most useful when debugging new instances of
-.Nm mach_init
-itself, but can also be used for robustness or to allow the subsequent
-.Nm mach_init
-processes to run as a non-root user. As mach_init is often used to
-launch servers, this could be more secure. However,
-.Nm mach_init
-will not allow a server declaration to specify a user id different
-than that of the requesting client (unless the client is running as root).
-So it shouldn't be required for a secure configuration.
-.El
-.Pp
-Access to
-.Nm mach_init
-is provided through the bootstrap series of RPC APIs
-over service ports published by mach_init itself. Each Mach task has
-an assigned bootstrap port retrieved via task_get_bootstrap_port().
-These bootstrap port registrations are inherited across fork().
-.Pp
-The service registrations are grouped into subsets, providing a level
-of security. Only processes with access to the subset's bootstrap port
-will be able to register/lookup Mach ports within that subset. Lookups
-from within a subset will search the subset first, then move on to its
-parent, and then its grand-parent, etc... until a string name match is
-found or the top of the bootstrap tree is reached. Subsets are sometimes
-associated with login sessions to protect session-specific ports from being
-exposed outside the session.
-.Pp
-The first instance of
-.Nm mach_init
-is responsible for launching the traditional BSD process control initialization
-daemon (/sbin/init).
-.Sh SAMPLE USAGE
-.Pp
-mach_init -d -r com.company.bootstrap
-.Pp
-.Nm mach_init
-will start in debug mode, and register itself in an already running
-instance of
-.Nm mach_init
-under the service name com.company.bootstrap.
-.Sh NOTE
-.Pp
-Sending a SIGHUP to a running mach_init will toggle debug mode.
-.Sh SEE ALSO
-.Xr init 8
+++ /dev/null
-/*
- * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.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."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990. All rights reserved.
- *
- * rpc_services.c -- implementation of bootstrap rpc services
- */
-
-#import <mach/mach.h>
-#import <string.h>
-
-#import <bsm/audit.h>
-#import <bsm/libbsm.h>
-
-#import "bootstrap_internal.h"
-#import "error_log.h"
-#import "lists.h"
-#import "bootstrap.h"
-
-#ifndef ASSERT
-#define ASSERT(p)
-#endif
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif NULL
-
-#define bsstatus(servicep) \
- (((servicep)->isActive) ? BOOTSTRAP_STATUS_ACTIVE : \
- (((servicep)->server && (servicep)->server->servertype == DEMAND) ? \
- BOOTSTRAP_STATUS_ON_DEMAND : BOOTSTRAP_STATUS_INACTIVE))
-
-/* extern port_all_t backup_port; */
-
-/*
- * kern_return_t
- * bootstrap_create_server(mach_port_t bootstrap_port,
- * cmd_t server_cmd,
- * integer_t server_uid,
- * boolean_t on_demand,
- * mach_port_t *server_portp)
- *
- * Returns send rights to server_port of service. At this point, the
- * server appears active, so nothing will try to launch it. The server_port
- * can be used to delare services associated with this server by calling
- * bootstrap_create_service() and passing server_port as the bootstrap port.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_NOT_PRIVILEGED, if bootstrap port invalid.
- */
-kern_return_t
-x_bootstrap_create_server(
- mach_port_t bootstrap_port,
- cmd_t server_cmd,
- int server_uid,
- boolean_t on_demand,
- audit_token_t client_audit_token,
- mach_port_t *server_portp)
-{
- server_t *serverp;
- struct auditinfo audit_info;
- bootstrap_info_t *bootstrap;
-
- uid_t client_euid;
-
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- debug("Server create attempt: \"%s\" bootstrap %x",
- server_cmd, bootstrap_port);
-
- /* No forwarding allowed for this call - security risk (we run as root) */
- if (!bootstrap || !active_bootstrap(bootstrap)) {
- debug("Server create: \"%s\": invalid bootstrap %x",
- server_cmd, bootstrap_port);
- return BOOTSTRAP_NOT_PRIVILEGED;
- }
-
- /* get the identity of the requestor and set up audit_info of server */
- audit_token_to_au32(client_audit_token,
- &audit_info.ai_auid,
- &client_euid,
- NULL /* egid */,
- NULL /* ruid */,
- NULL /* rgid */,
- NULL /* pid */,
- &audit_info.ai_asid,
- &audit_info.ai_termid);
-
- if (client_euid != 0 && client_euid != server_uid) {
- notice("Server create: \"%s\": insufficient privilege for specified uid (euid-%d != requested-%d)",
- server_cmd, client_euid, server_uid);
- return BOOTSTRAP_NOT_PRIVILEGED;
- }
-
- serverp = new_server(
- bootstrap,
- server_cmd,
- server_uid,
- (on_demand) ? DEMAND : RESTARTABLE,
- audit_info);
- setup_server(serverp);
-
- info("New server %x in bootstrap %x: \"%s\"",
- serverp->port, bootstrap_port, server_cmd);
- *server_portp = serverp->port;
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_unprivileged(mach_port_t bootstrap_port,
- * mach_port_t *unpriv_port)
- *
- * Given a bootstrap port, return its unprivileged equivalent. If
- * the port is already unprivileged, another reference to the same
- * port is returned.
- *
- * This is most often used by servers, which are launched with their
- * bootstrap port set to the privileged port for the server, to get
- * an unprivileged version of the same port for use by its unprivileged
- * children (or any offspring that it does not want to count as part
- * of the "server" for mach_init registration and re-launch purposes).
- */
-kern_return_t
-x_bootstrap_unprivileged(
- mach_port_t bootstrap_port,
- mach_port_t *unpriv_portp)
-{
- bootstrap_info_t *bootstrap;
-
- debug("Get unprivileged attempt for bootstrap %x", bootstrap_port);
-
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- if (!bootstrap) {
- debug("Get unprivileged: invalid bootstrap %x", bootstrap_port);
- return BOOTSTRAP_NOT_PRIVILEGED;
- }
-
- *unpriv_portp = bootstrap->bootstrap_port;
-
- debug ("Get unpriv bootstrap %x returned for bootstrap %x",
- bootstrap->bootstrap_port, bootstrap_port);
- return BOOTSTRAP_SUCCESS;
-}
-
-
-/*
- * kern_return_t
- * bootstrap_check_in(mach_port_t bootstrap_port,
- * name_t service_name,
- * mach_port_t *service_portp)
- *
- * Returns receive rights to service_port of service named by service_name.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- * Returns BOOTSTRAP_SERVICE_NOT_DECLARED, if service not declared
- * in /etc/bootstrap.conf.
- * Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been
- * registered or checked-in.
- */
-kern_return_t
-x_bootstrap_check_in(
- mach_port_t bootstrap_port,
- name_t service_name,
- mach_port_t *service_portp)
-{
- kern_return_t result;
- mach_port_t previous;
- service_t *servicep;
- server_t *serverp;
- bootstrap_info_t *bootstrap;
-
- serverp = lookup_server_by_port(bootstrap_port);
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- debug("Service checkin attempt for service %s bootstrap %x",
- service_name, bootstrap_port);
-
- servicep = lookup_service_by_name(bootstrap, service_name);
- if (servicep == NULL || servicep->port == MACH_PORT_NULL) {
- debug("bootstrap_check_in service %s unknown%s", service_name,
- forward_ok ? " forwarding" : "");
- return forward_ok ?
- bootstrap_check_in(
- inherited_bootstrap_port,
- service_name,
- service_portp) :
- BOOTSTRAP_UNKNOWN_SERVICE;
- }
- if (servicep->server != NULL && servicep->server != serverp) {
- debug("bootstrap_check_in service %s not privileged",
- service_name);
- return BOOTSTRAP_NOT_PRIVILEGED;
- }
- if (!canReceive(servicep->port)) {
- ASSERT(servicep->isActive);
- debug("bootstrap_check_in service %s already active",
- service_name);
- return BOOTSTRAP_SERVICE_ACTIVE;
- }
- debug("Checkin service %s for bootstrap %x", service_name,
- bootstrap->bootstrap_port);
- ASSERT(servicep->isActive == FALSE);
- servicep->isActive = TRUE;
-
- if (servicep->server != NULL_SERVER) {
- /* registered server - service needs backup */
- serverp->activity++;
- serverp->active_services++;
- result = mach_port_request_notification(
- mach_task_self(),
- servicep->port,
- MACH_NOTIFY_PORT_DESTROYED,
- 0,
- backup_port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &previous);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_request_notification");
- } else {
- /* one time use/created service */
- servicep->servicetype = REGISTERED;
- result = mach_port_request_notification(
- mach_task_self(),
- servicep->port,
- MACH_NOTIFY_DEAD_NAME,
- 0,
- notify_port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &previous);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_request_notification");
- else if (previous != MACH_PORT_NULL) {
- debug("deallocating old notification port (%x) for checked in service %x",
- previous, servicep->port);
- result = mach_port_deallocate(
- mach_task_self(),
- previous);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_deallocate");
- }
- }
-
- info("Check-in service %x in bootstrap %x: %s",
- servicep->port, servicep->bootstrap->bootstrap_port, servicep->name);
-
- *service_portp = servicep->port;
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_register(mach_port_t bootstrap_port,
- * name_t service_name,
- * mach_port_t service_port)
- *
- * Registers send rights for the port service_port for the service named by
- * service_name. Registering a declared service or registering a service for
- * which bootstrap has receive rights via a port backup notification is
- * allowed.
- * The previous service port will be deallocated. Restarting services wishing
- * to resume service for previous clients must first attempt to checkin to the
- * service.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to
- * unprivileged bootstrap port.
- * Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been
- * register or checked-in.
- */
-kern_return_t
-x_bootstrap_register(
- mach_port_t bootstrap_port,
- name_t service_name,
- mach_port_t service_port)
-{
- kern_return_t result;
- service_t *servicep;
- server_t *serverp;
- bootstrap_info_t *bootstrap;
- mach_port_t old_port;
-
- debug("Register attempt for service %s port %x",
- service_name, service_port);
-
- /*
- * Validate the bootstrap.
- */
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- if (!bootstrap || !active_bootstrap(bootstrap))
- return BOOTSTRAP_NOT_PRIVILEGED;
-
- /*
- * If this bootstrap port is for a server, or it's an unprivileged
- * bootstrap can't register the port.
- */
- serverp = lookup_server_by_port(bootstrap_port);
- servicep = lookup_service_by_name(bootstrap, service_name);
- if (servicep && servicep->server && servicep->server != serverp)
- return BOOTSTRAP_NOT_PRIVILEGED;
-
- if (servicep == NULL || servicep->bootstrap != bootstrap) {
- servicep = new_service(bootstrap,
- service_name,
- service_port,
- ACTIVE,
- REGISTERED,
- NULL_SERVER);
- debug("Registered new service %s", service_name);
- } else {
- if (servicep->isActive) {
- debug("Register: service %s already active, port %x",
- servicep->name, servicep->port);
- ASSERT(!canReceive(servicep->port));
- return BOOTSTRAP_SERVICE_ACTIVE;
- }
- old_port = servicep->port;
- if (servicep->servicetype == DECLARED) {
- servicep->servicetype = REGISTERED;
-
- if (servicep->server) {
- ASSERT(servicep->server == serverp);
- ASSERT(active_server(serverp));
- servicep->server = NULL_SERVER;
- serverp->activity++;
- }
-
- result = mach_port_mod_refs(
- mach_task_self(),
- old_port,
- MACH_PORT_RIGHT_RECEIVE,
- -1);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_mod_refs");
- }
- result = mach_port_deallocate(
- mach_task_self(),
- old_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_mod_refs");
-
- servicep->port = service_port;
- servicep->isActive = TRUE;
- debug("Re-registered inactive service %x bootstrap %x: %s",
- servicep->port, servicep->bootstrap->bootstrap_port, service_name);
- }
-
- /* detect the new service port going dead */
- result = mach_port_request_notification(
- mach_task_self(),
- service_port,
- MACH_NOTIFY_DEAD_NAME,
- 0,
- notify_port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &old_port);
- if (result != KERN_SUCCESS) {
- debug("Can't request notification on service %x bootstrap %x: %s",
- service_port, servicep->bootstrap->bootstrap_port, "must be dead");
- delete_service(servicep);
- return BOOTSTRAP_SUCCESS;
- } else if (old_port != MACH_PORT_NULL) {
- debug("deallocating old notification port (%x) for service %x",
- old_port, service_port);
- result = mach_port_deallocate(
- mach_task_self(),
- old_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_deallocate");
- }
- info("Registered service %x bootstrap %x: %s",
- servicep->port, servicep->bootstrap->bootstrap_port, servicep->name);
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_look_up(mach_port_t bootstrap_port,
- * name_t service_name,
- * mach_port_t *service_portp)
- *
- * Returns send rights for the service port of the service named by
- * service_name in *service_portp. Service is not guaranteed to be active.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- */
-kern_return_t
-x_bootstrap_look_up(
- mach_port_t bootstrap_port,
- name_t service_name,
- mach_port_t *service_portp)
-{
- service_t *servicep;
- bootstrap_info_t *bootstrap;
-
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- servicep = lookup_service_by_name(bootstrap, service_name);
- if (servicep == NULL || servicep->port == MACH_PORT_NULL) {
- if (forward_ok) {
- debug("bootstrap_look_up service %s forwarding",
- service_name);
- return bootstrap_look_up(inherited_bootstrap_port,
- service_name,
- service_portp);
- } else {
- debug("bootstrap_look_up service %s unknown",
- service_name);
- return BOOTSTRAP_UNKNOWN_SERVICE;
- }
- }
- *service_portp = servicep->port;
- debug("Lookup returns port %x for service %s",
- servicep->port,
- servicep->name);
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_look_up_array(mach_port_t bootstrap_port,
- * name_array_t service_names,
- * int service_names_cnt,
- * mach_port_array_t *service_ports,
- * int *service_ports_cnt,
- * boolean_t *all_services_known)
- *
- * Returns port send rights in corresponding entries of the array service_ports
- * for all services named in the array service_names. Service_ports_cnt is
- * returned and will always equal service_names_cnt (assuming service_names_cnt
- * is greater than or equal to zero).
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_NO_MEMORY, if server couldn't obtain memory
- * for response.
- * Unknown service names have the corresponding service
- * port set to MACH_PORT_NULL.
- * If all services are known, all_services_known is true on
- * return,
- * if any service is unknown, it's false.
- */
-kern_return_t
-x_bootstrap_look_up_array(
- mach_port_t bootstrap_port,
- name_array_t service_names,
- unsigned int service_names_cnt,
- mach_port_array_t *service_portsp,
- unsigned int *service_ports_cnt,
- boolean_t *all_services_known)
-{
- unsigned int i;
- static mach_port_t service_ports[BOOTSTRAP_MAX_LOOKUP_COUNT];
-
- if (service_names_cnt > BOOTSTRAP_MAX_LOOKUP_COUNT)
- return BOOTSTRAP_BAD_COUNT;
- *service_ports_cnt = service_names_cnt;
- *all_services_known = TRUE;
- for (i = 0; i < service_names_cnt; i++) {
- if ( x_bootstrap_look_up(bootstrap_port,
- service_names[i],
- &service_ports[i])
- != BOOTSTRAP_SUCCESS)
- {
- *all_services_known = FALSE;
- service_ports[i] = MACH_PORT_NULL;
- }
- }
- debug("bootstrap_look_up_array returns %d ports", service_names_cnt);
- *service_portsp = service_ports;
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_parent(mach_port_t bootstrap_port,
- * mach_port_t *parent_port);
- *
- * Given a bootstrap subset port, return the parent bootstrap port.
- * If the specified bootstrap port is already the root subset,
- * MACH_PORT_NULL will be returned.
- *
- * Errors:
- * Returns BOOTSTRAP_NOT_PRIVILEGED if the caller is not running
- * with an effective user id of root (as determined by the security
- * token in the message trailer).
- */
-kern_return_t
-x_bootstrap_parent(
- mach_port_t bootstrap_port,
- security_token_t sectoken,
- mach_port_t *parent_port)
-{
- bootstrap_info_t *bootstrap;
-
- debug("Parent attempt for bootstrap %x", bootstrap_port);
-
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- if (!bootstrap) {
- debug("Parent attempt for bootstrap %x: invalid bootstrap",
- bootstrap_port);
- return BOOTSTRAP_NOT_PRIVILEGED;
- }
- if (sectoken.val[0]) {
- notice("Bootstrap parent for bootstrap %x: invalid security token (%d)",
- bootstrap_port, sectoken.val[0]);
- return BOOTSTRAP_NOT_PRIVILEGED;
- }
- debug("Returning bootstrap parent %x for bootstrap %x",
- bootstrap->parent->bootstrap_port, bootstrap_port);
- *parent_port = bootstrap->parent->bootstrap_port;
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_status(mach_port_t bootstrap_port,
- * name_t service_name,
- * bootstrap_status_t *service_active);
- *
- * Returns: service_active indicates if service is available.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- */
-kern_return_t
-x_bootstrap_status(
- mach_port_t bootstrap_port,
- name_t service_name,
- bootstrap_status_t *service_active)
-{
- service_t *servicep;
- bootstrap_info_t *bootstrap;
-
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- servicep = lookup_service_by_name(bootstrap, service_name);
- if (servicep == NULL) {
- if (forward_ok) {
- debug("bootstrap_status forwarding status, server %s",
- service_name);
- return bootstrap_status(inherited_bootstrap_port,
- service_name,
- service_active);
- } else {
- debug("bootstrap_status service %s unknown",
- service_name);
- return BOOTSTRAP_UNKNOWN_SERVICE;
- }
- }
- *service_active = bsstatus(servicep);
-
- debug("bootstrap_status server %s %sactive", service_name,
- servicep->isActive ? "" : "in");
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_info(mach_port_t bootstrap_port,
- * name_array_t *service_names,
- * int *service_names_cnt,
- * name_array_t *server_names,
- * int *server_names_cnt,
- * bootstrap_status_array_t *service_actives,
- * int *service_active_cnt);
- *
- * Returns bootstrap status for all known services.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- */
-kern_return_t
-x_bootstrap_info(
- mach_port_t bootstrap_port,
- name_array_t *service_namesp,
- unsigned int *service_names_cnt,
- name_array_t *server_namesp,
- unsigned int *server_names_cnt,
- bootstrap_status_array_t *service_activesp,
- unsigned int *service_actives_cnt)
-{
- kern_return_t result;
- unsigned int i, cnt;
- service_t *servicep;
- server_t *serverp;
- bootstrap_info_t *bootstrap;
- name_array_t service_names;
- name_array_t server_names;
- bootstrap_status_array_t service_actives;
-
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
-
- for ( cnt = i = 0, servicep = services.next
- ; i < nservices
- ; servicep = servicep->next, i++)
- {
- if (lookup_service_by_name(bootstrap, servicep->name) == servicep)
- {
- cnt++;
- }
- }
- result = vm_allocate(mach_task_self(),
- (vm_address_t *)&service_names,
- cnt * sizeof(service_names[0]),
- ANYWHERE);
- if (result != KERN_SUCCESS)
- return BOOTSTRAP_NO_MEMORY;
-
- result = vm_allocate(mach_task_self(),
- (vm_address_t *)&server_names,
- cnt * sizeof(server_names[0]),
- ANYWHERE);
- if (result != KERN_SUCCESS) {
- (void)vm_deallocate(mach_task_self(),
- (vm_address_t)service_names,
- cnt * sizeof(service_names[0]));
- return BOOTSTRAP_NO_MEMORY;
- }
- result = vm_allocate(mach_task_self(),
- (vm_address_t *)&service_actives,
- cnt * sizeof(service_actives[0]),
- ANYWHERE);
- if (result != KERN_SUCCESS) {
- (void)vm_deallocate(mach_task_self(),
- (vm_address_t)service_names,
- cnt * sizeof(service_names[0]));
- (void)vm_deallocate(mach_task_self(),
- (vm_address_t)server_names,
- cnt * sizeof(server_names[0]));
- return BOOTSTRAP_NO_MEMORY;
- }
-
- for ( i = 0, servicep = services.next
- ; i < cnt
- ; servicep = servicep->next)
- {
- if ( lookup_service_by_name(bootstrap, servicep->name)
- != servicep)
- continue;
- strncpy(service_names[i],
- servicep->name,
- sizeof(service_names[0]));
- service_names[i][sizeof(service_names[0]) - 1] = '\0';
- if (servicep->server) {
- serverp = servicep->server;
- strncpy(server_names[i],
- serverp->cmd,
- sizeof(server_names[0]));
- server_names[i][sizeof(server_names[0]) - 1] = '\0';
- debug("bootstrap info service %s server %s %sactive",
- servicep->name,
- serverp->cmd, servicep->isActive ? "" : "in");
- } else {
- server_names[i][0] = '\0';
- debug("bootstrap info service %s %sactive",
- servicep->name, servicep->isActive ? "" : "in");
- }
- service_actives[i] = bsstatus(servicep);
- i++;
- }
- *service_namesp = service_names;
- *server_namesp = server_names;
- *service_activesp = service_actives;
- *service_names_cnt = *server_names_cnt =
- *service_actives_cnt = cnt;
-
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_subset(mach_port_t bootstrap_port,
- * mach_port_t requestor_port,
- * mach_port_t *subset_port);
- *
- * Returns a new port to use as a bootstrap port. This port behaves
- * exactly like the previous bootstrap_port, except that ports dynamically
- * registered via bootstrap_register() are available only to users of this
- * specific subset_port. Lookups on the subset_port will return ports
- * registered with this port specifically, and ports registered with
- * ancestors of this subset_port. Duplications of services already
- * registered with an ancestor port may be registered with the subset port
- * are allowed. Services already advertised may then be effectively removed
- * by registering MACH_PORT_NULL for the service.
- * When it is detected that the requestor_port is destroied the subset
- * port and all services advertized by it are destroied as well.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- */
-kern_return_t
-x_bootstrap_subset(
- mach_port_t bootstrap_port,
- mach_port_t requestor_port,
- mach_port_t *subset_port)
-{
- kern_return_t result;
- bootstrap_info_t *bootstrap;
- bootstrap_info_t *subset;
- mach_port_t new_bootstrap_port;
- mach_port_t previous;
-
- debug("Subset create attempt: bootstrap %x, requestor: %x",
- bootstrap_port, requestor_port);
-
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- if (!bootstrap || !active_bootstrap(bootstrap))
- return BOOTSTRAP_NOT_PRIVILEGED;
-
- result = mach_port_allocate(
- mach_task_self(),
- MACH_PORT_RIGHT_RECEIVE,
- &new_bootstrap_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_allocate");
-
- result = mach_port_insert_right(
- mach_task_self(),
- new_bootstrap_port,
- new_bootstrap_port,
- MACH_MSG_TYPE_MAKE_SEND);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "failed to insert send right");
-
- result = mach_port_insert_member(
- mach_task_self(),
- new_bootstrap_port,
- bootstrap_port_set);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "port_set_add");
-
- subset = new_bootstrap(bootstrap, new_bootstrap_port, requestor_port);
-
- result = mach_port_request_notification(
- mach_task_self(),
- requestor_port,
- MACH_NOTIFY_DEAD_NAME,
- 0,
- notify_port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &previous);
- if (result != KERN_SUCCESS) {
- kern_error(result, "mach_port_request_notification");
- mach_port_deallocate(mach_task_self(), requestor_port);
- subset->requestor_port = MACH_PORT_NULL;
- deactivate_bootstrap(subset);
- } else if (previous != MACH_PORT_NULL) {
- debug("deallocating old notification port (%x) for requestor %x",
- previous, requestor_port);
- result = mach_port_deallocate(
- mach_task_self(),
- previous);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "mach_port_deallocate");
- }
-
- info("Created bootstrap subset %x parent %x requestor %x",
- new_bootstrap_port, bootstrap_port, requestor_port);
- *subset_port = new_bootstrap_port;
- return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_create_service(mach_port_t bootstrap_port,
- * name_t service_name,
- * mach_port_t *service_port)
- *
- * Creates a service named "service_name" and returns send rights to that
- * port in "service_port." The port may later be checked in as if this
- * port were configured in the bootstrap configuration file.
- *
- * Errors: Returns appropriate kernel errors on rpc failure.
- * Returns BOOTSTRAP_NAME_IN_USE, if service already exists.
- */
-kern_return_t
-x_bootstrap_create_service(
- mach_port_t bootstrap_port,
- name_t service_name,
- mach_port_t *service_port)
-{
- server_t *serverp;
- service_t *servicep;
- bootstrap_info_t *bootstrap;
- kern_return_t result;
-
- bootstrap = lookup_bootstrap_by_port(bootstrap_port);
- if (!bootstrap || !active_bootstrap(bootstrap))
- return BOOTSTRAP_NOT_PRIVILEGED;
-
- debug("Service creation attempt for service %s bootstrap %x",
- service_name, bootstrap_port);
-
- servicep = lookup_service_by_name(bootstrap, service_name);
- if (servicep) {
- debug("Service creation attempt for service %s failed, "
- "service already exists", service_name);
- return BOOTSTRAP_NAME_IN_USE;
- }
-
- serverp = lookup_server_by_port(bootstrap_port);
-
- result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, service_port);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "port_allocate");
- result = mach_port_insert_right(mach_task_self(), *service_port, *service_port, MACH_MSG_TYPE_MAKE_SEND);
- if (result != KERN_SUCCESS)
- kern_fatal(result, "failed to insert send right");
-
- if (serverp)
- serverp->activity++;
-
- servicep = new_service(bootstrap,
- service_name,
- *service_port,
- !ACTIVE,
- DECLARED,
- serverp);
-
- info("Created new service %x in bootstrap %x: %s",
- servicep->port, bootstrap->bootstrap_port, service_name);
-
- return BOOTSTRAP_SUCCESS;
-}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
$(MKDIRS) $(DSTROOT)$(MANDIR)
$(CP) -f $(MANPAGE) $(DSTROOT)$(MANDIR)/$(MANPAGE)
$(CHMOD) og-w $(DSTROOT)$(MANDIR)/$(MANPAGE)
+ $(MV) $(DSTROOT)/usr/sbin/nvram $(DSTROOT)/usr/sbin/nvram.tmp
+ lipo -thin ppc -output $(DSTROOT)/usr/sbin/nvram $(DSTROOT)/usr/sbin/nvram.tmp
+ $(RM) -f $(DSTROOT)/usr/sbin/nvram.tmp
.\"
-.\" Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+.\" Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
.\"
-.TH nvram 8 "December 12, 2000"
+.TH nvram 8 "October 28, 2003"
.SH NAME
nvram \- manipulate Open Firmware NVRAM variables
.SH SYNOPSIS
.B -f
.IR filename
] [
+.B -d
.IR name
-] [=
+] [
+.IR name
+[=
.IR value
-] ...
+]] ...
.SH DESCRIPTION
The
.I nvram
Set Open Firmware variables from a text file. The file must be a
list name=value statements. If the last character of a line is
\\, the value will be continued to the next line.
+.TP
+.BI \-d " name"
+Deletes the named Open Firmware variable.
.SH EXAMPLES
.LP
.RS
.LP
Create a new variable, my-variable, containing a list of two
C-strings that is terminated by a NUL.
+.LP
+.RS
+example% nvram -d my-variable
+.RE
+.LP
+Deletes the variable named my-variable.
.PD
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * 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.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ *
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * 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@
*/
/*
-cc -o nvram nvram.c -framework IOKit -Wall
+cc -o nvram nvram.c -framework CoreFoundation -framework IOKit -Wall
*/
#include <stdio.h>
#include <IOKit/IOKitLib.h>
+#include <IOKit/IOKitKeys.h>
#include <CoreFoundation/CoreFoundation.h>
// Prototypes
static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef,
CFTypeRef *valueRef);
static kern_return_t SetOFVariable(char *name, char *value);
+static void DeleteOFVariable(char *name);
static void PrintOFVariables(void);
static void PrintOFVariable(const void *key,const void *value,void *context);
static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value);
}
break;
+ case 'd':
+ cnt++;
+ if (cnt < argc && *argv[cnt] != '-') {
+ DeleteOFVariable(argv[cnt]);
+ } else {
+ UsageMessage("missing name");
+ }
+ break;
+
default:
strcpy(errorMessage, "no such option as --");
errorMessage[strlen(errorMessage)-1] = *str;
{
Error("(usage: %s)", (long)message);
- printf("%s [-p] [-f filename] name[=value] ...\n", gToolName);
+ printf("%s [-p] [-f filename] [-d name] name[=value] ...\n", gToolName);
printf("\t-p print all Open Firmware variables\n");
printf("\t-f set Open Firmware variables from a text file\n");
+ printf("\t-d delete the named variable\n");
printf("\tname=value set named variable\n");
printf("\tname print variable\n");
printf("Note that arguments and options are executed in order.\n");
}
+// DeleteOFVariable(name)
+//
+// Delete the named Open Firmware variable.
+//
+//
+static void DeleteOFVariable(char *name)
+{
+ SetOFVariable(kIONVRAMDeletePropertyKey, name);
+}
+
+
// PrintOFVariables()
//
// Print all of the Open Firmware variables.
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
location may be a NIS domainname
.It for opendirectory,
location may be a directory node name
-.Bl
+.El
.El
.Pp
The super-user privilages are not required change a user's current password
.Xr login 1 ,
.Xr passwd 5 ,
.Xr pwd_mkdb 8 ,
-.Xr vipw 8,
+.Xr vipw 8 ,
.Xr nicl 1
.Rs
.%A Robert Morris
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
}
return l;
}
-
-char *itoa(int n)
-{
- char s[32];
-
- sprintf(s, "%d", n);
- return copyString(s);
-}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
char *suffix(char *, char);
char *lowerCase(char *);
char **explode(char *, char);
-char *itoa(int);
if (flags != (int *)NULL)
*flags = 0;
+#ifdef __APPLE__
+ if (bp[0] == '#') {
+ pw->pw_name = NULL;
+ return(1);
+ }
+#endif
+
if (!(p = strsep(&bp, ":")) || *p == '\0') /* login */
goto fmt;
pw->pw_name = p;
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
key.data = (u_char *)tbuf;
for (cnt = 1; scan(fp, pw, &flags); ++cnt) {
+#ifdef __APPLE__
+ if (pw->pw_name == NULL)
+ continue;
+#endif
+
if (firsttime) {
/* Look like YP? */
if ((pw->pw_name[0] == '+') || (pw->pw_name[0] == '-'))
.Xr wtmp 5
file.
.Pp
+When the system is halted with the halt command, the system is powered off.
+.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl l
-.\" Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+.\"Portions Copyright (c) 1999-2003 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 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.
.\"
-.\" The contents of this file constitute Original Code as defined in and
-.\" 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.
-.\"
-.\" This 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.
-.\"
-.\" @(#)sadc.8
+.\" @(#)sa1.8
.Dd Jul 25 2003 \" DATE
.Dt sa1 8 \" Program name and manual section number
.Os "Mac OS X"
#!/bin/sh
# /usr/lib/sa/sa1.sh
-# Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+# Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+# Reserved.
#
-# @APPLE_LICENSE_HEADER_START@
-#
-# "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.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.apple.com/publicsource and read it before using
-# this file.
+# 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 OR NON-INFRINGEMENT. Please see the
-# License for the specific language governing rights and limitations
-# under the License."
-#
-# @APPLE_LICENSE_HEADER_END@
+# 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.
#
umask 0022
DATE=`/bin/date +%d`
-.\" Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+.\"Portions Copyright (c) 1999-2003 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 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.
.\"
-.\" The contents of this file constitute Original Code as defined in and
-.\" 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.
-.\"
-.\" This 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.
-.\"
-.\" @(#)sadc.8
+.\" @(#)sa2.8
.Dd Jul 25 2003 \" DATE
.Dt sa2 8 \" Program name and manual section number
.Os "Mac OS X"
#!/bin/sh
# /usr/lib/sa/sa2.sh
-# Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+# Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+# Reserved.
#
-# @APPLE_LICENSE_HEADER_START@
-#
-# "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.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.apple.com/publicsource and read it before using
-# this file.
+# 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 OR NON-INFRINGEMENT. Please see the
-# License for the specific language governing rights and limitations
-# under the License."
-#
-# @APPLE_LICENSE_HEADER_END@
+# 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.
#
umask 0022
DATE=`/bin/date +%d`
-.\" Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
-.\"
-.\" The contents of this file constitute Original Code as defined in and
-.\" 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.
-.\"
-.\" This 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.
+.\"Portions Copyright (c) 1999-2003 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 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.
.\"
.\" @(#)sadc.8
.Dd Jul 25 2003 \" DATE
.Xr sc_usage 1 ,
.Xr fs_usage 1
.\" .Sh BUGS \" Document known, unremedied bugs
-\r
/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+ * Reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
+ * 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.
+*/
#define IOKIT 1 /* to get io_name_t in device_types.h */
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+ * Reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
+ * 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.
+*/
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
-.\" Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
-.\"
-.\" The contents of this file constitute Original Code as defined in and
-.\" 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.
-.\"
-.\" This 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.
+.\"Portions Copyright (c) 1999-2003 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 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.
.\"
.\" @(#)sadc.8
+
.Dd Jul 25, 2003 \" DATE
.Dt sar 1 \" Program name and manual section number
.Os "Mac OS X"
/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+ * Reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
+ * 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.
+*/
/*
cc -Wall -Wno-long-double -I. -I ../sadc.tproj -O -o sar sar.c
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+ * Reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
+ * 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.
+*/
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
struct sc_entry *se;
struct entry *te;
- thread = kd[i].arg5 & KDBG_THREAD_MASK;
+ thread = kd[i].arg5;
debugid = kd[i].debugid;
type = kd[i].debugid & DBG_FUNC_MASK;
switched_out = (struct th_info *)0;
switched_in = (struct th_info *)0;
- now = kd[i].timestamp;
+ now = kd[i].timestamp & KDBG_TIMESTAMP_MASK;
baseid = debugid & 0xffff0000;
else if (baseid == msc_base)
code = 512 + ((debugid >> 2) & 0x1ff);
else if (type == mach_sched || type == mach_stkhandoff) {
- switched_out = find_thread((kd[i].arg5 & KDBG_THREAD_MASK));
+ switched_out = find_thread(kd[i].arg5);
switched_in = find_thread(kd[i].arg2);
if (in_idle) {
-918
+917
0x1f000000 DYLD_initialize
0x1f010000 DYLD_CALL_image_init_routine
0x1f010004 DYLD_CALL_dependent_init_routine
0x1f040010 DYLD_map_bundle_image
0x1f040014 DYLD_load_dependent_libraries
0x1f040018 DYLD_notify_prebinding_agent
+0x21070000 LAUNCH_LSOpen
+0x21070004 LAUNCH_LSRegisterItem
+0x21070008 LAUNCH_LSGetApplicationAndFlagsForInfo
0x1fff0000 LAUNCH_START_FINDER
0x1fff0100 LAUNCH_START_DOCK
-0x1fff0200 LAUNCH_LSOpen
-0x1fff0204 LAUNCH_LSRegisterItem
-0x1fff0208 LAUNCH_LSGetApplicationAndFlagsForInfo
0x1fff0300 LAUNCH_CPSLaunch
0x1fff0304 LAUNCH_CPSRegisterwithServer
0x1fff0308 LAUNCH_CGSCheckInNewProcess
0xff001f40 MSG_memory_object_get_attributes
0xff001f44 MSG_memory_object_change_attributes
0xff001f48 MSG_memory_object_synchronize_completed
-0xff001f4c MSG_memory_object_data_unavailable
-0xff001f50 MSG_memory_object_lock_request
-0xff001f54 MSG_memory_object_data_error
-0xff001f58 MSG_memory_object_destroy
-0xff001f5c MSG_memory_object_data_supply
-0xff001f60 MSG_memory_object_discard_reply
-0xff001f64 MSG_vm_object_upl_request
-0xff001f68 MSG_vm_pager_upl_request
-0xff001f6c MSG_vm_upl_map
-0xff001f70 MSG_vm_upl_unmap
-0xff001f74 MSG_vm_upl_abort
-0xff001f78 MSG_vm_upl_commit
-0xff001f7c MSG_vm_upl_commit_range
+0xff001f4c MSG_memory_object_lock_request
+0xff001f50 MSG_memory_object_destroy
+0xff001f54 MSG_memory_object_upl_request
+0xff001f58 MSG_memory_object_super_upl_request
+0xff001f5c MSG_memory_object_page_op
+0xff001f60 MSG_memory_object_recover_named
+0xff001f64 MSG_memory_object_release_name
+0xff001f68 MSG_memory_object_range_op
0xff002008 MSG_upl_abort
0xff00200c MSG_upl_abort_range
0xff002010 MSG_upl_commit
0xff003bcc MSG_vm_map_get_upl
0xff003bd0 MSG_vm_upl_map
0xff003bd4 MSG_vm_upl_unmap
+0xff003bd8 MSG_vm_purgable_control
0xff003e80 MSG_processor_set_statistics
0xff003e84 MSG_processor_set_destroy
0xff003e88 MSG_processor_set_max_priority
0xff25abd4 MSG_semaphore_wait_signal
0xff25abd8 MSG_semaphore_timedwait_signal
0xffbebdcc MSG_clock_alarm_reply
-
0x1300000 MACH_vmfault
0x1300004 MACH_Pageout
0x1400000 MACH_SCHED
0x40c02d4 BSC_setgid
0x40c02d8 BSC_setegid
0x40c02dc BSC_seteuid
-0x40c02e0 BSC_#184
+0x40c02e0 BSC_sigreturn
0x40c02e4 BSC_#185
0x40c02e8 BSC_#186
0x40c02ec BSC_#187
0x40c056c BSC_#347
0x40c0570 BSC_#348
0x40c0574 BSC_#349
-0x40c0578 BSC_#350
-0x40c057c BSC_#351
-0x40c0580 BSC_#352
-0x40c0584 BSC_#353
-0x40c0588 BSC_#354
-0x40c058c BSC_#355
-0x40c0590 BSC_#356
-0x40c0594 BSC_#357
-0x40c0598 BSC_#358
-0x40c059c BSC_#359
+0x40c0578 BSC_audit
+0x40c057c BSC_auditon
+0x40c0580 BSC_auditsvc
+0x40c0584 BSC_getauid
+0x40c0588 BSC_setauid
+0x40c058c BSC_getaudit
+0x40c0590 BSC_setaudit
+0x40c0594 BSC_getaudit_addr
+0x40c0598 BSC_setaudit_addr
+0x40c059c BSC_auditctl
0x40c05a0 BSC_#360
0x40c05a4 BSC_#361
0x40c05a8 BSC_kqueue
#
-# Generated by the Apple Project Builder.
+# Generated by the NeXT Project Builder.
#
# NOTE: Do NOT change this file -- Project Builder maintains it.
#
NEXTSTEP_INSTALLDIR = /sbin
WINDOWS_INSTALLDIR = /sbin
PDO_UNIX_INSTALLDIR = /sbin
-LIBS = -lbsm
+LIBS =
DEBUG_LIBS = $(LIBS)
PROF_LIBS = $(LIBS)
APPCLASS = NSApplication;
FILESTABLE = {
FRAMEWORKS = ();
- "H_FILES" = ("pathnames.h");
- "M_FILES" = ();
- "OTHER_LIBS" = (bsm);
- "OTHER_LINKED" = ("shutdown.c");
- "OTHER_SOURCES" = (
- "Makefile.preamble",
- Makefile,
- "Makefile.postamble",
- "Makefile.dist",
- "shutdown.8"
- );
- "PRECOMPILED_HEADERS" = ();
- "PROJECT_HEADERS" = ();
- "PUBLIC_HEADERS" = ();
+ H_FILES = (pathnames.h);
+ M_FILES = ();
+ OTHER_LIBS = ();
+ OTHER_LINKED = (shutdown.c);
+ OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, Makefile.dist, shutdown.8);
+ PRECOMPILED_HEADERS = ();
+ PROJECT_HEADERS = ();
+ PUBLIC_HEADERS = ();
SUBPROJECTS = ();
};
LANGUAGE = English;
- "LOCALIZABLE_FILES" = {};
- "NEXTSTEP_INSTALLDIR" = "/sbin";
- "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
- "NEXTSTEP_MAINNIB" = shutdown;
- "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
- "PDO_UNIX_INSTALLDIR" = "/sbin";
- "PDO_UNIX_JAVA_COMPILER" = "$(NEXTDEV_BIN)/javac";
- "PDO_UNIX_MAINNIB" = shutdown;
- "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
+ LOCALIZABLE_FILES = {};
+ NEXTSTEP_INSTALLDIR = /sbin;
+ NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
+ NEXTSTEP_MAINNIB = shutdown;
+ NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
+ PDO_UNIX_INSTALLDIR = /sbin;
+ PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac";
+ PDO_UNIX_MAINNIB = shutdown;
+ PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
PROJECTNAME = shutdown;
PROJECTTYPE = Tool;
- PROJECTVERSION = "2.8";
- "WINDOWS_INSTALLDIR" = "/sbin";
- "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
- "WINDOWS_MAINNIB" = shutdown;
- "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
+ PROJECTVERSION = 2.8;
+ WINDOWS_INSTALLDIR = /sbin;
+ WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
+ WINDOWS_MAINNIB = shutdown;
+ WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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 <string.h>
#include <unistd.h>
-#include <errno.h>
-#include <bsm/libbsm.h>
-#include <bsm/audit_uevents.h>
-
-
#include "pathnames.h"
#ifdef __APPLE__
static const char *nosync, *whom;
void badtime(void);
+#ifdef __APPLE__
+void log_and_exec_reboot_or_halt(void);
+#else
void die_you_gravy_sucking_pig_dog(void);
+#endif
void finish(int);
void getoffset(char *);
void loop(void);
void timeout(int);
void timewarn(int);
void usage(const char *);
-int audit_shutdown(int);
int
main(argc, argv)
if (!(whom = getlogin()))
whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
-
#ifdef DEBUG
- audit_shutdown(0);
(void)putc('\n', stdout);
#else
(void)setpriority(PRIO_PROCESS, 0, PRIO_MIN);
int forkpid;
forkpid = fork();
- if (forkpid == -1) {
- audit_shutdown(1);
+ if (forkpid == -1)
err(1, "fork");
- }
- if (forkpid) {
+ if (forkpid)
errx(0, "[pid %d]", forkpid);
- }
}
- audit_shutdown(0);
setsid();
#endif
openlog("shutdown", LOG_CONS, LOG_AUTH);
if (!tp->timeleft)
break;
}
+#ifdef __APPLE__
+ log_and_exec_reboot_or_halt();
+#else
die_you_gravy_sucking_pig_dog();
+#endif
}
static jmp_buf alarmbuf;
}
void
+#ifdef __APPLE__
+log_and_exec_reboot_or_halt()
+#else
die_you_gravy_sucking_pig_dog()
+#endif
{
char *empty_environ[] = { NULL };
doreboot ? "reboot" : dohalt ? "halt" :
#endif
"shutdown", whom, mbuf);
+#ifndef __APPLE__
(void)sleep(2);
+#endif
(void)printf("\r\nSystem shutdown time has arrived\007\007\r\n");
if (killflg) {
" time [warning-message ...]\n");
exit(1);
}
-
-/*
- * The following tokens are included in the audit record for shutdown
- * header
- * subject
- * return
- */
-int audit_shutdown(int exitstatus)
-{
- int aufd;
- token_t *tok;
- long au_cond;
-
- /* If we are not auditing, don't cut an audit record; just return */
- if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
- fprintf(stderr, "shutdown: Could not determine audit condition\n");
- return 0;
- }
- if (au_cond == AUC_NOAUDIT)
- return 0;
-
- if((aufd = au_open()) == -1) {
- fprintf(stderr, "shutdown: Audit Error: au_open() failed\n");
- exit(1);
- }
-
- /* The subject that performed the operation */
- if((tok = au_to_me()) == NULL) {
- fprintf(stderr, "shutdown: Audit Error: au_to_me() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- /* success and failure status */
- if((tok = au_to_return32(exitstatus, errno)) == NULL) {
- fprintf(stderr, "shutdown: Audit Error: au_to_return32() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if(au_close(aufd, 1, AUE_shutdown) == -1) {
- fprintf(stderr, "shutdown: Audit Error: au_close() failed\n");
- exit(1);
- }
- return 1;
-}
-
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
{ 0, 0 }, /* CTL_VFS */
{ 0, 0 }, /* CTL_NET */
{ 0, CTL_DEBUG_MAXID }, /* CTL_DEBUG */
- { 0, 0 }, /* CTL_HW */
+ { hwname, HW_MAXID }, /* CTL_HW */
#ifdef CTL_MACHDEP_NAMES
{ machdepname, CPU_MAXID }, /* CTL_MACHDEP */
#else
}
if (argc == 0)
usage();
- for (; *argv != NULL; ++argv)
+ for (; *argv != NULL; ++argv)
parse(*argv, 1);
exit(0);
}
char *name;
int i;
+ /* Make 'sysctl kern.' style behave the same as 'sysctl kern' 3360872*/
+ if (bufp[0][strlen(*bufp)-1] == '.')
+ bufp[0][strlen(*bufp)-1]='\0';
if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
fprintf(stderr, "%s: incomplete specification\n", string);
return (-1);
PROJECTVERSION = 2.8
PROJECT_TYPE = Tool
-CFILES = update.c
+CFILES = update.c disk_power.c power_mgmt.c
+HFILES = disk_power.h power_mgmt.h
OTHERSRCS = Makefile.preamble Makefile Makefile.postamble update.8
+FRAMEWORKS = -framework CoreFoundation -framework IOKit
MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
CODE_GEN_STYLE = DYNAMIC
{
DOCICONFILES = ();
FILESTABLE = {
- C_FILES = ();
- H_FILES = ();
+ C_FILES = (update.c disk_power.c power_mgmt.c);
+ H_FILES = (disk_power.h power_mgmt.h);
OTHER_LIBS = ();
- OTHER_LINKED = (update.c);
+ OTHER_LINKED = ();
OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, update.8);
PRECOMPILED_HEADERS = ();
PROJECT_HEADERS = ();
PUBLIC_HEADERS = ();
- SUBPROJECTS = ();
+ SUBPROJECTS = ();
+ FRAMEWORKS = (CoreFoundation.framework, IOKit.framework);
};
GENERATEMAIN = YES;
LANGUAGE = English;
--- /dev/null
+#include <IOKit/IOKitLib.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
+#include <IOKit/pwr_mgt/IOPM.h>
+
+#include <time.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "disk_power.h"
+
+int PowerStateSummary( IOATAPowerState powerState );
+
+/*
+-- PowerStateString()
+*/
+
+char * PowerStateString( IOATAPowerState x, int opt_summary )
+{
+ char * result;
+
+ if ( opt_summary )
+ {
+ switch ( PowerStateSummary( x ) )
+ {
+ case -1:
+ result = "ON";
+ break;
+ case 0: // This is the only value where the two scales collide.
+ result = "OFF";
+ break;
+ default:
+ fprintf(stderr, "ERROR: %s: unknown IOATAPowerState %d\n", __FUNCTION__, (int)x);
+ result = "UNKNOWN";
+ break;
+ }
+ }
+ else
+ {
+ switch ( x )
+ {
+ case kIOATAPowerStateSystemSleep: // This is the only value where the two scales collide.
+ result = "SystemSleep";
+ break;
+ case kIOATAPowerStateSleep:
+ result = "Sleep";
+ break;
+ case kIOATAPowerStateStandby:
+ result = "Standby";
+ break;
+ case kIOATAPowerStateIdle:
+ result = "Idle";
+ break;
+ case kIOATAPowerStateActive:
+ result = "Active";
+ break;
+ default:
+ fprintf(stderr, "ERROR: %s: unknown IOATAPowerState %d\n", __FUNCTION__, (int)x);
+ result = "UNKNOWN";
+ break;
+ }
+ }
+
+ return result;
+
+} // PowerStateString()
+
+/*
+-- PowerStatesMax()
+*/
+
+IOATAPowerState PowerStatesMax( IOATAPowerStates * powerStates )
+{
+ IOATAPowerState driverDesire = powerStates->driverDesire;
+ IOATAPowerState deviceDesire = powerStates->deviceDesire;
+ IOATAPowerState userDesire = powerStates->userDesire;
+
+ IOATAPowerState maxState = 0;
+
+ if ( driverDesire > maxState ) maxState = driverDesire;
+
+ if ( deviceDesire > maxState ) maxState = deviceDesire;
+
+ if ( userDesire > maxState ) maxState = userDesire;
+
+ return maxState;
+
+} // PowerStatesMax()
+
+/*
+-- PowerStateSummary()
+*/
+
+/* Returns
+-- -1 == ON
+-- 0 == OFF
+-- Can be used together with the positive values denoting IOATAPowerState's.
+-- But you have to be careful not to confuse with OFF == 0 == kIOATAPowerStateSystemSleep.
+*/
+
+int PowerStateSummary( IOATAPowerState powerState )
+{
+ int result;
+
+ // Summarizing twice does nothing. Idempotent.
+ if ( powerState <= 0 )
+ result = powerState;
+ else
+#if 1
+ if ( 0 <= powerState && powerState <= kIOATAPowerStateSleep )
+ result = 0;
+ else
+ result = -1;
+#else
+ if ( 0 <= powerState && powerState <= kIOATAPowerStateStandby ) // Spun down.
+ result = 0; // OFF
+ else
+ if ( kIOATAPowerStateIdle <= powerState && powerState <= kIOATAPowerStateActive ) // Spun up.
+ result = -1; // ON
+ else
+ {
+ fprintf(stderr, "ERROR: %s(%d): unexpected value.\n", __FUNCTION__, powerState);
+ exit(-1);
+ }
+#endif
+
+ return result;
+
+} // PowerStateSummary()
+
+/*
+-- GetATADeviceInfo()
+*/
+
+// Fairly often this returns -11, meaning that it was unable to locate a matching device.
+// If this happens, just wait awhile and try again.
+//
+// See GetATADeviceInfoWithRetry()
+//
+
+int GetATADeviceInfo( DiskDevice * device )
+{
+ int result;
+
+ IOATAPowerStates * powerStates = & device->powerStates;
+
+ kern_return_t kr;
+ mach_port_t masterPort;
+ io_registry_entry_t service;
+ io_iterator_t iterator;
+
+ kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
+ assert(KERN_SUCCESS==kr);
+
+ /* look for drives */
+ IOServiceGetMatchingServices(masterPort, IOServiceMatching ( "ATADeviceNub" ), & iterator );
+ if ( ! iterator )
+ {
+ result = -10;
+ goto Return;
+ }
+
+ while (( service = IOIteratorNext( iterator ) ))
+ {
+ CFStringRef str = nil;
+ CFMutableDictionaryRef properties = nil;
+ CFDictionaryRef physCharacteristics = nil;
+ io_iterator_t child_iterator;
+ io_registry_entry_t child;
+
+ // Device Model
+
+ char deviceModel[ 256 ];
+ bzero( deviceModel, sizeof deviceModel );
+
+ str = IORegistryEntryCreateCFProperty( service, CFSTR("device model"), kCFAllocatorDefault, kNilOptions );
+ if ( str )
+ {
+ CFStringGetCString( str, deviceModel, sizeof deviceModel, kCFStringEncodingMacRoman );
+ CFRelease( str );
+ }
+
+ // Device Interconnect & Device Location
+
+ char deviceInterconnect[ 256 ];
+ bzero(deviceInterconnect, sizeof deviceInterconnect );
+ char deviceLocation[ 256 ];
+ bzero(deviceLocation, sizeof deviceLocation );
+
+ IORegistryEntryCreateCFProperties( service, & properties, kCFAllocatorDefault, kNilOptions );
+ if ( properties )
+ {
+ physCharacteristics = CFDictionaryGetValue( properties, CFSTR("Protocol Characteristics") );
+ if ( physCharacteristics )
+ {
+ // device interconnect
+ str = CFDictionaryGetValue( physCharacteristics, CFSTR("Physical Interconnect") );
+ if ( str )
+ {
+ CFStringGetCString( str, deviceInterconnect, sizeof deviceInterconnect, kCFStringEncodingMacRoman );
+ }
+
+ // device location
+ str = CFDictionaryGetValue( physCharacteristics, CFSTR("Physical Interconnect Location") );
+ if ( str )
+ {
+ CFStringGetCString( str, deviceLocation, sizeof deviceLocation, kCFStringEncodingMacRoman );
+ }
+ }
+
+ CFRelease( properties );
+ }
+
+ IORegistryEntryGetChildIterator( service, kIOServicePlane, & child_iterator );
+ while (( child = IOIteratorNext( child_iterator ) ))
+ {
+ int driverDesire, deviceDesire, userDesire;
+
+ // fill in interconnect info if we don't already have it
+ if ( 0 == strlen(deviceInterconnect) )
+ {
+ str = IORegistryEntryCreateCFProperty( child, CFSTR("Physical Interconnect"), kCFAllocatorDefault, kNilOptions );
+ if ( str )
+ {
+ CFStringGetCString( str, deviceInterconnect, sizeof deviceInterconnect, kCFStringEncodingMacRoman );
+ CFRelease( str );
+ }
+ }
+
+ if ( 0 == strlen( deviceLocation ) )
+ {
+ str = IORegistryEntryCreateCFProperty( child, CFSTR("Physical Interconnect Location"), kCFAllocatorDefault, kNilOptions );
+ if ( str )
+ {
+ CFStringGetCString( str, deviceLocation, sizeof deviceLocation , kCFStringEncodingMacRoman );
+ CFRelease( str );
+ }
+ }
+
+ // Device Type
+
+ char deviceType[ 256 ];
+ bzero( deviceType, sizeof deviceType );
+
+ // Power State
+
+ char powerState[ 256 ];
+ bzero( powerState, sizeof powerState );
+
+ // find out what type of device this is - ATAPI will be added as SCSI devices
+ str = IORegistryEntryCreateCFProperty( service, CFSTR("ata device type"), kCFAllocatorDefault, kNilOptions );
+ if ( str )
+ {
+ CFStringGetCString( str, deviceType, sizeof deviceType, kCFStringEncodingMacRoman );
+ CFRelease( str );
+
+ if ( 0 == strcmp( deviceType, "ata" ) ) // regular ATA disks (not ATAPI)
+ {
+ IORegistryEntryCreateCFProperties( child, & properties, kCFAllocatorDefault, kNilOptions );
+ if ( properties )
+ {
+ str = CFDictionaryGetValue( properties, CFSTR("Power Management private data") );
+ if ( str )
+ {
+ CFStringGetCString( str, powerState, sizeof powerState, kCFStringEncodingMacRoman );
+ }
+ CFRelease( properties );
+ }
+ }
+ }
+
+ if ( 3 == sscanf ( powerState,
+ "{ this object = %*x, interested driver = %*x, driverDesire = %d, deviceDesire = %d, ourDesiredPowerState = %d, previousRequest = %*d }",
+ & driverDesire, & deviceDesire, & userDesire
+ )
+ )
+ {
+ device->timestamp = time( NULL );
+
+ device->name = strdup( deviceModel ); // copy of the original
+ device->location = strdup( deviceLocation ); // copy of the original
+ device->interconnect = strdup( deviceInterconnect ); // copy of the original
+
+ powerStates->driverDesire = driverDesire;
+ powerStates->deviceDesire = deviceDesire;
+ powerStates->userDesire = userDesire;
+
+ IOObjectRelease( child_iterator );
+ IOObjectRelease( iterator );
+
+ result = 0;
+ goto Return;
+ }
+
+ } // while (child...)
+
+ IOObjectRelease( child_iterator );
+
+ } // while (service...)
+
+ IOObjectRelease( iterator );
+
+ result = -11;
+ goto Return;
+
+Return:
+ return result;
+
+} // GetATADeviceInfo()
+
+
+/*
+-- GetATADeviceInfoWithRetry()
+*/
+
+// Devices are often momentarily busy, e.g., when spinning up. Retry up to 10 times, 1 second apart.
+
+int GetATADeviceInfoWithRetry( DiskDevice * diskDevice )
+{
+ int err;
+
+ int retryNumber;
+
+ for ( retryNumber = 0; retryNumber < 10; retryNumber++ )
+ {
+ err = GetATADeviceInfo( diskDevice );
+ if ( noErr == err )
+ {
+ goto Return;
+ }
+#if 0
+ char errorStringBuffer[ 256 ];
+ char * errorString = errorStringBuffer;
+ errorString += sprintf_timestamp_now( errorString );
+ errorString += sprintf(errorString, ": WARNING: %s: sleeping and retrying...\n", __FUNCTION__);
+ fputs( errorStringBuffer, stderr );
+ fflush(stdout);
+#endif
+ sleep(1);
+ }
+
+ // Failure.
+ goto Return;
+
+Return:
+ return err;
+
+} // GetATADeviceInfoWithRetry()
+
--- /dev/null
+#ifndef __SPINDOWN_H__
+
+#define __SPINDOWN_H__
+
+#include <stdio.h>
+#include <time.h>
+
+/*
+--
+*/
+
+/* Public types */
+
+/* ATA power states, from lowest to highest power usage */
+// This is taken from the IOATABlockStorage project, IOATAStorageDefines.h
+enum IOATAPowerState
+{
+ kIOATAPowerStateSystemSleep = 0,
+ kIOATAPowerStateSleep = 1,
+ kIOATAPowerStateStandby = 2,
+ kIOATAPowerStateIdle = 3,
+ kIOATAPowerStateActive = 4,
+
+ kNumIOATAPowerStates
+};
+
+typedef enum IOATAPowerState IOATAPowerState;
+
+/* IOATAPowerStates */
+
+struct IOATAPowerStates
+{
+ IOATAPowerState driverDesire;
+ IOATAPowerState deviceDesire;
+ IOATAPowerState userDesire;
+};
+
+typedef struct IOATAPowerStates IOATAPowerStates;
+
+/* DiskDevice: see GetATADeviceInfo(), GetATADeviceInfoWithRetry() */
+
+struct DiskDevice
+{
+ time_t timestamp;
+ char * name;
+ char * location;
+ char * interconnect;
+ IOATAPowerStates powerStates;
+};
+
+typedef struct DiskDevice DiskDevice;
+
+/* Devices */
+
+
+/* PowerStatesMax()
+-- Returns the max-of-three power state "desires" from the given IOATAPowerStates.
+*/
+IOATAPowerState PowerStatesMax( IOATAPowerStates * powerStates );
+
+/* PowerStateString()
+-- Returns human-readable string name for the given IOATAPowerState.
+-- Returns pointer to a static, const string.
+*/
+char * PowerStateString( IOATAPowerState x, int opt_summary );
+
+/* Routines for printing fs_usage-compatible timestamps: HH:MM:SS.000
+*/
+int sprintf_timestamp( char * str, time_t t );
+int sprintf_timestamp_now( char * str );
+char * timestampStr_static( time_t t ); /* Returns pointer to a static, const string. */
+
+#if 0
+/* Routines for printing time intervals: HH:MM:SS
+*/
+int sprintf_interval( char * str, time_t interval );
+char * intervalStr_static( time_t interval ); /* Returns pointer to a static, const string. */
+#endif
+
+/* GetATADeviceInfoWithRetry()
+-- This invokes GetATADeviceInfo() repeatedly at one second intervals until it returns without error.
+-- Gives up after 10 tries, so it is possible that this could return an error.
+*/
+int GetATADeviceInfoWithRetry( DiskDevice * diskDevice );
+
+/*
+--
+*/
+
+#endif /* __SPINDOWN_H__ */
--- /dev/null
+
+#include "disk_power.h"
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
+#include <IOKit/pwr_mgt/IOPM.h>
+
+#include <CoreFoundation/CFNumber.h>
+
+/*
+--
+*/
+
+int on_battery_power( void )
+{
+ int result = 0; // Assume we're not running on battery power.
+ kern_return_t kr;
+ mach_port_t master_device_port;
+
+ CFArrayRef cfarray = NULL;
+
+ kr = IOMasterPort( bootstrap_port, & master_device_port);
+ if ( KERN_SUCCESS != kr)
+ {
+ fprintf(stderr,"ERROR: IOMasterPort() failed\n");
+ goto Return;
+ }
+
+ kr = IOPMCopyBatteryInfo( master_device_port, & cfarray );
+ if ( kIOReturnSuccess != kr )
+ {
+ // This case handles desktop machines in addition to error cases.
+ result = 0;
+ goto Return;
+ }
+
+ {
+ CFDictionaryRef dict;
+ CFNumberRef cfnum;
+ int flags;
+
+ dict = CFArrayGetValueAtIndex( cfarray, 0 );
+ cfnum = CFDictionaryGetValue( dict, CFSTR(kIOBatteryFlagsKey) );
+
+ if ( CFNumberGetTypeID() != CFGetTypeID( cfnum ) )
+ {
+ fprintf(stderr, "ERROR: on_battery_power(): battery flags not a CFNumber!!!\n");
+ result = 0;
+ goto Return;
+ }
+
+ CFNumberGetValue( cfnum, kCFNumberLongType, & flags );
+
+#if 0
+ printf( "BatteryFlags = %#08x\n", flags );
+
+ printf( "BatteryChargerConnect : %s\n", ( 0 != ( flags & kIOBatteryChargerConnect ) ) ? "TRUE" : "FALSE" );
+ printf( "BatteryCharge : %s\n", ( 0 != ( flags & kIOBatteryCharge ) ) ? "TRUE" : "FALSE" );
+ printf( "BatteryInstalled : %s\n", ( 0 != ( flags & kIOBatteryInstalled ) ) ? "TRUE" : "FALSE" );
+#endif
+
+ result = ( 0 == ( flags & kIOPMACInstalled ) );
+ }
+
+Return:
+ if (cfarray)
+ CFRelease(cfarray);
+ return result;
+
+} // on_battery_power()
+
+/*
+--
+*/
+
+int is_disk_awake( void )
+{
+ int result = 1; // Go ahead and sync by default.
+ int err;
+ DiskDevice diskDevice;
+ IOATAPowerState powerState;
+
+ bzero(&diskDevice, sizeof(diskDevice));
+
+ err = GetATADeviceInfoWithRetry( & diskDevice );
+ if ( err )
+ {
+ result = 1; // Go ahead and sync.
+ goto Return;
+ }
+
+ powerState = PowerStatesMax( & diskDevice.powerStates );
+
+// printf( "%s: power state = %s\n", __FUNCTION__, PowerStateString( powerState, /* opt_summary = */ 0 ) );
+
+ result = ( powerState >= kIOATAPowerStateStandby );
+
+Return:
+ if (diskDevice.name)
+ free(diskDevice.name);
+ if (diskDevice.location)
+ free(diskDevice.location);
+ if (diskDevice.interconnect)
+ free(diskDevice.interconnect);
+
+// printf( "%s => %s\n", __FUNCTION__, result ? "TRUE" : "FALSE" );
+ return result;
+
+} // is_disk_awake()
+
+/*
+--
+*/
+
--- /dev/null
+int on_battery_power( void );
+int is_disk_awake( void );
\ No newline at end of file
.Nd flush internal filesystem caches to disk frequently
.Sh SYNOPSIS
.Nm update
+.Op Ar normal_interval Op Ar save_energy_interval
.Sh DESCRIPTION
The
.Nm update
uses the
.Xr sync 2
function call to do the task.
+The normal_interval and save_energy_interval can be used to set the
+.Xr sync 2 interval in seconds of the normal case and the case where the computer is trying to save energy.
.Pp
.Nm Update
is commonly invoked at startup time by
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
/*-
* Copyright (c) 1987, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1987, 1990, 1993\n\
- The Regents of the University of California. All rights reserved.\n";
+ The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)update.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)update.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
-#include <sys/time.h>
-#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <getopt.h>
+
+#include "power_mgmt.h"
+#include "disk_power.h"
+
+extern char *optarg;
-main()
+static void usage(const char *argv0) __attribute__((noreturn));
+static int parsetime(const char *arg);
+
+int main(int argc, char *const argv[])
{
- struct itimerval value;
- void mysync();
+ int normal_intr = 30;
+ int save_pwr_intr = 30;
+ int on_bat, disk_up, last_sync = 0, current_sync_interval = 0;
+
+ if (argc > 3)
+ usage(argv[0]);
+ if (argc > 2)
+ save_pwr_intr = parsetime(argv[2]);
+ if (argc > 1)
+ normal_intr = parsetime(argv[1]);
+
+ if (normal_intr == -1 || save_pwr_intr == -1)
+ usage(argv[0]);
+
+ if (normal_intr > save_pwr_intr)
+ normal_intr = save_pwr_intr;
daemon(0, 0);
- (void)signal(SIGALRM, mysync);
+ for (;;) {
+ if (last_sync >= current_sync_interval) {
+ sync();
+ last_sync = 0;
+ }
+ sleep(30);
+ last_sync += 30;
- value.it_interval.tv_sec = 30;
- value.it_interval.tv_usec = 0;
- value.it_value = value.it_interval;
- if (setitimer(ITIMER_REAL, &value, NULL)) {
- perror("update: setitimer");
- exit(1);
+ on_bat = on_battery_power();
+ disk_up = is_disk_awake();
+
+ current_sync_interval = normal_intr;
+ if (on_bat && !disk_up)
+ current_sync_interval = save_pwr_intr;
+
}
- for (;;)
- sigpause(sigblock(0L));
- /* NOTREACHED */
+
+}
+
+static int parsetime(const char *arg)
+{
+ char *q = NULL;
+ int r;
+
+ r = strtol(arg, &q, 10);
+
+ if (r < 1)
+ return -1;
+ if (arg == q)
+ return -1;
+
+ switch (*q) {
+ case 'h':
+ r *= 60;
+ case 'm':
+ r *= 60;
+ case 's':
+ case '\0':
+ break;
+ default:
+ return -1;
+ }
+
+ return r;
}
-void
-mysync()
+static void usage(const char *argv0)
{
- (void)sync();
+ fprintf(stderr, "usage: %s [normal_interval [power_saving_interval]]\n", argv0);
+ exit(EXIT_FAILURE);
}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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 <stddef.h>
+#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <mach/mach.h>
vm_statistics_data_t vm_stat, last;
-int percent;
+natural_t percent;
int delay;
char *pgmname;
mach_port_t myHost;
int pageSize = 4096; /* set to 4k default */
-void usage();
-void banner();
-void snapshot();
-void pstat(char *str, int n);
-void print_stats();
+void usage(void);
+void banner(void);
+void snapshot(void);
+void pstat(char *str, natural_t n);
+void print_stats(void);
void get_stats(struct vm_statistics *stat);
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char *argv[])
{
pgmname = argv[0];
sleep(delay);
}
}
- exit(0);
+ exit(EXIT_SUCCESS);
}
void
-usage()
+usage(void)
{
fprintf(stderr, "usage: %s [ repeat-interval ]\n", pgmname);
- exit(1);
+ exit(EXIT_FAILURE);
}
void
-banner()
+banner(void)
{
get_stats(&vm_stat);
printf("Mach Virtual Memory Statistics: ");
- printf("(page size of %d bytes, cache hits %d%%)\n",
+ printf("(page size of %d bytes, cache hits %u%%)\n",
pageSize, percent);
printf("%6s %6s %4s %4s %8s %8s %8s %8s %8s %8s\n",
"free",
}
void
-snapshot()
+snapshot(void)
{
get_stats(&vm_stat);
pstat("Pages reactivated:", vm_stat.reactivations);
pstat("Pageins:", vm_stat.pageins);
pstat("Pageouts:", vm_stat.pageouts);
- printf("Object cache: %d hits of %d lookups (%d%% hit rate)\n",
+ printf("Object cache: %u hits of %u lookups (%u%% hit rate)\n",
vm_stat.hits, vm_stat.lookups, percent);
}
void
-pstat(str, n)
- char *str;
- int n;
+pstat(char *str, natural_t n)
{
- printf("%-25s %10d.\n", str, n);
+ printf("%-25s %10u.\n", str, n);
}
void
-print_stats()
+print_stats(void)
{
- static count = 0;
+ static int count = 0;
if (count++ == 0)
banner();
count = 0;
get_stats(&vm_stat);
- printf("%6d %6d %4d %4d %8d %8d %8d %8d %8d %8d\n",
+ printf("%6u %6u %4u %4u %8u %8u %8u %8u %8u %8u\n",
vm_stat.free_count,
vm_stat.active_count,
vm_stat.inactive_count,
}
void
-get_stats(stat)
- struct vm_statistics *stat;
+get_stats(struct vm_statistics *stat)
{
int count = HOST_VM_INFO_COUNT;
- if (host_statistics(myHost, HOST_VM_INFO, stat,&count) != KERN_SUCCESS) {
+ if (host_statistics(myHost, HOST_VM_INFO, (host_info_t)stat, &count) != KERN_SUCCESS) {
fprintf(stderr, "%s: failed to get statistics.\n", pgmname);
- exit(2);
+ exit(EXIT_FAILURE);
}
if (stat->lookups == 0)
percent = 0;
- else
- percent = (stat->hits*100)/stat->lookups;
+ else {
+ /*
+ * We have limited precision with the 32-bit natural_t fields
+ * in the vm_statistics structure. There's nothing we can do
+ * about counter overflows, but we can avoid percentage
+ * calculation overflows by doing the computation in floating
+ * point arithmetic ...
+ */
+ percent = (natural_t)(((double)stat->hits*100)/stat->lookups);
+ }
}
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
- * "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.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.apple.com/publicsource and read it before using
- * this file.
+ * Copyright (c) 1999-2003 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 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 OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * 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@
*/