mirror of
https://github.com/darlinghq/darling-libutil.git
synced 2024-11-26 22:20:23 +00:00
Move Source From Main Repo
Based on libutil-57 source
This commit is contained in:
commit
79b03e8a11
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
build/
|
||||
xcuserdata/
|
||||
project.xcworkspace/
|
||||
*~
|
50
CMakeLists.txt
Normal file
50
CMakeLists.txt
Normal file
@ -0,0 +1,50 @@
|
||||
project(libutil)
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
if(COMMAND cmake_policy)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
endif(COMMAND cmake_policy)
|
||||
|
||||
include(InstallSymlink)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc -D__DARWIN_UNIX03 -fPIC -w")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc -nostdinc++ -D__DARWIN_UNIX03 -fPIC -w")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib")
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(util_SRCS
|
||||
ExtentManager.cpp
|
||||
getmntopts.c
|
||||
humanize_number.c
|
||||
pidfile.c
|
||||
realhostname.c
|
||||
reexec_to_match_kernel.c
|
||||
trimdomain.c
|
||||
tzlink.c
|
||||
wipefs.cpp
|
||||
)
|
||||
|
||||
set(DYLIB_INSTALL_NAME "/usr/lib/libutil1.0.dylib")
|
||||
set(DYLIB_COMPAT_VERSION "1.0.0")
|
||||
set(DYLIB_CURRENT_VERSION "1.0.0")
|
||||
|
||||
add_darling_library(util SHARED ${util_SRCS})
|
||||
make_fat(util)
|
||||
target_link_libraries(util PRIVATE system cxx)
|
||||
set_target_properties(util PROPERTIES OUTPUT_NAME "util1.0")
|
||||
|
||||
install(TARGETS util DESTINATION libexec/darling/usr/lib)
|
||||
install(FILES
|
||||
reexec_to_match_kernel.3
|
||||
realhostname.3
|
||||
humanize_number.3
|
||||
getmntopts.3
|
||||
realhostname_sa.3
|
||||
pidfile.3
|
||||
wipefs.3
|
||||
trimdomain.3
|
||||
DESTINATION
|
||||
libexec/darling/usr/share/man/man3
|
||||
)
|
||||
InstallSymlink("libutil1.0.dylib" "${CMAKE_INSTALL_PREFIX}/libexec/darling/usr/lib/libutil.dylib")
|
305
ExtentManager.cpp
Normal file
305
ExtentManager.cpp
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009,2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
//
|
||||
// ExtentManager.cpp
|
||||
//
|
||||
|
||||
#include "ExtentManager.h"
|
||||
|
||||
void
|
||||
ExtentManager::Init(uint32_t theBlockSize, uint32_t theNativeBlockSize, off_t theTotalBytes)
|
||||
{
|
||||
blockSize = theBlockSize;
|
||||
nativeBlockSize = theNativeBlockSize;
|
||||
totalBytes = theTotalBytes;
|
||||
totalBlocks = howmany(totalBytes, blockSize);
|
||||
|
||||
// add sentry empty extents at both sides so empty partition doesn't need to be handled specially
|
||||
AddBlockRangeExtent(0, 0);
|
||||
AddBlockRangeExtent(totalBlocks, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ExtentManager::MergeExtent(const ExtentInfo &a, const ExtentInfo &b, ExtentInfo *c)
|
||||
{
|
||||
// merge ext into *curIt
|
||||
c->blockAddr = min(a.blockAddr, b.blockAddr);
|
||||
c->numBlocks = max(a.blockAddr + a.numBlocks, b.blockAddr + b.numBlocks) - c->blockAddr;
|
||||
}
|
||||
|
||||
void
|
||||
ExtentManager::AddBlockRangeExtent(off_t blockAddr, off_t numBlocks)
|
||||
{
|
||||
struct ExtentInfo ext, newExt;
|
||||
ListExtIt curIt, newIt;
|
||||
bool merged = false;
|
||||
|
||||
// make the range a valid range
|
||||
if ((blockAddr > totalBlocks) || (blockAddr + numBlocks < 0)) { // totally out of range, do nothing
|
||||
return;
|
||||
}
|
||||
if (blockAddr < 0) {
|
||||
numBlocks = blockAddr + numBlocks;
|
||||
blockAddr = 0;
|
||||
}
|
||||
if (blockAddr + numBlocks > totalBlocks) {
|
||||
numBlocks = totalBlocks - blockAddr;
|
||||
}
|
||||
|
||||
ext.blockAddr = blockAddr;
|
||||
ext.numBlocks = numBlocks;
|
||||
|
||||
for (curIt = extentList.begin(); curIt != extentList.end(); curIt++) {
|
||||
if (BeforeExtent(ext, *curIt))
|
||||
break;
|
||||
if (!BeforeExtent(*curIt, ext)) { // overlapped extents
|
||||
MergeExtent(ext, *curIt, &newExt);
|
||||
*curIt = newExt;
|
||||
merged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// insert ext before curIt
|
||||
if (!merged) {
|
||||
curIt = extentList.insert(curIt, ext); // throws bad_alloc when out of memory
|
||||
}
|
||||
|
||||
// merge the extents
|
||||
newIt = curIt;
|
||||
curIt = extentList.begin();
|
||||
while (curIt != extentList.end()) {
|
||||
if (curIt == newIt || BeforeExtent(*curIt, *newIt)) { // curIt is before newIt
|
||||
curIt++;
|
||||
continue;
|
||||
}
|
||||
if (BeforeExtent(*newIt, *curIt)) { // curIt is after newIt now, we are done
|
||||
break;
|
||||
}
|
||||
// merge the two extents
|
||||
MergeExtent(*curIt, *newIt, &newExt);
|
||||
*newIt = newExt;
|
||||
curIt = extentList.erase(curIt);
|
||||
}
|
||||
// printf("After %s(%lld, %lld)\n", __func__, blockAddr, numBlocks); DebugPrint();
|
||||
} // ExtentManager::AddBlockRangeExtent
|
||||
|
||||
void
|
||||
ExtentManager::RemoveBlockRangeExtent(off_t blockAddr, off_t numBlocks)
|
||||
{
|
||||
struct ExtentInfo ext, newExt;
|
||||
ListExtIt curIt;
|
||||
|
||||
ext.blockAddr = blockAddr;
|
||||
ext.numBlocks = numBlocks;
|
||||
|
||||
curIt = extentList.begin();
|
||||
while (curIt != extentList.end()) {
|
||||
if (BeforeExtent(*curIt, ext)) {
|
||||
curIt++;
|
||||
continue;
|
||||
}
|
||||
if (BeforeExtent(ext, *curIt)) // we are done
|
||||
break;
|
||||
|
||||
//
|
||||
// If we get here, the input extent and *curIt have at least one block in common.
|
||||
// That is, they overlap in some way. Thus *curIt needs to change, be removed,
|
||||
// or be split into two non-contiguous extents.
|
||||
//
|
||||
|
||||
if (curIt->blockAddr >= ext.blockAddr &&
|
||||
curIt->blockAddr + curIt->numBlocks <= ext.blockAddr + ext.numBlocks) {
|
||||
//
|
||||
// The input extent totally contains *curIt, so remove *curIt.
|
||||
//
|
||||
curIt = extentList.erase(curIt);
|
||||
} else if (curIt->blockAddr < ext.blockAddr &&
|
||||
curIt->blockAddr + curIt->numBlocks > ext.blockAddr + ext.numBlocks) {
|
||||
//
|
||||
// The input extent does not include the start of *curIt, nor the end of *curIt,
|
||||
// so split *curIt into two extents.
|
||||
//
|
||||
newExt.blockAddr = ext.blockAddr + ext.numBlocks;
|
||||
newExt.numBlocks = curIt->blockAddr + curIt->numBlocks - newExt.blockAddr;
|
||||
curIt->numBlocks = ext.blockAddr - curIt->blockAddr;
|
||||
curIt++;
|
||||
extentList.insert(curIt, newExt); // throws bad_alloc when out of memory
|
||||
curIt++;
|
||||
} else {
|
||||
//
|
||||
// The input extent contains either the start or the end of *curIt, but not both.
|
||||
// The remove will leave either the end or the start of *curIt (respectively) and
|
||||
// not change the number of extents in the list.
|
||||
//
|
||||
if (curIt->blockAddr >= ext.blockAddr) {
|
||||
//
|
||||
// Remove the start of *curIt by updating both its starting block and size.
|
||||
//
|
||||
assert(curIt->blockAddr + curIt->numBlocks > ext.blockAddr + ext.numBlocks);
|
||||
newExt.blockAddr = ext.blockAddr + ext.numBlocks;
|
||||
newExt.numBlocks = curIt->blockAddr + curIt->numBlocks - newExt.blockAddr;
|
||||
*curIt = newExt;
|
||||
} else {
|
||||
//
|
||||
// Remove the end of *curIt by updating its size.
|
||||
//
|
||||
curIt->numBlocks = ext.blockAddr - curIt->blockAddr;
|
||||
}
|
||||
curIt++;
|
||||
}
|
||||
}
|
||||
//printf("After %s(%lld, %lld)\n", __func__, blockAddr, numBlocks); DebugPrint();
|
||||
}
|
||||
|
||||
void
|
||||
ExtentManager::AddByteRangeExtent(off_t byteAddr, off_t numBytes)
|
||||
{
|
||||
off_t blockAddr = byteAddr / blockSize;
|
||||
off_t blockAddrOfLastByte = (byteAddr + numBytes - 1) / blockSize;
|
||||
off_t numBlocks = blockAddrOfLastByte - blockAddr + 1;
|
||||
AddBlockRangeExtent(blockAddr, numBlocks);
|
||||
}
|
||||
|
||||
void
|
||||
ExtentManager::DebugPrint()
|
||||
{
|
||||
ListExtIt it;
|
||||
|
||||
for (it = extentList.begin(); it != extentList.end(); it++) {
|
||||
printf("[%lld, %lld] ", it->blockAddr, it->numBlocks);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
#if UNIT_TEST
|
||||
|
||||
/*
|
||||
clang++ -arch i386 -arch x86_64 -DUNIT_TEST ExtentManager.cpp -o ExtentManager && ./ExtentManager
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
const char *DebugDescription(class ExtentManager *extMan)
|
||||
{
|
||||
char *result = strdup("");
|
||||
char *temp;
|
||||
|
||||
ListExtIt it;
|
||||
|
||||
for (it = extMan->extentList.begin(); it != extMan->extentList.end(); it++) {
|
||||
temp = result;
|
||||
asprintf(&result, "%s[%lld, %lld] ", temp, it->blockAddr, it->numBlocks);
|
||||
free(temp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int SimpleTestCase(off_t addAddr, off_t addBlocks, off_t removeAddr, off_t removeBlocks, const char *expectedResult)
|
||||
{
|
||||
class ExtentManager extMan;
|
||||
const char *actualResult;
|
||||
int result = 0;
|
||||
|
||||
extMan.Init(512, 512, 512*999);
|
||||
extMan.AddBlockRangeExtent(addAddr, addBlocks);
|
||||
extMan.RemoveBlockRangeExtent(removeAddr, removeBlocks);
|
||||
actualResult = DebugDescription(&extMan);
|
||||
if (strcmp(actualResult, expectedResult))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"SimpleTestCase(%lld, %lld, %lld, %lld) failed.\n"
|
||||
" Expected result: %s\n"
|
||||
" Actual result: %s\n",
|
||||
addAddr, addBlocks, removeAddr, removeBlocks,
|
||||
expectedResult, actualResult);
|
||||
result = 1;
|
||||
}
|
||||
free((void *)actualResult);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int failed = 0;
|
||||
class ExtentManager *extMan;
|
||||
|
||||
// Create an extent, and remove one contained inside,
|
||||
// leaving the start and end of the original extent.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [......]
|
||||
failed |= SimpleTestCase(10, 10, 12, 6, "[0, 0] [10, 2] [18, 2] [999, 0] ");
|
||||
|
||||
// Create an extent, and remove the whole extent.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [..........]
|
||||
failed |= SimpleTestCase(10, 10, 10, 10, "[0, 0] [999, 0] ");
|
||||
|
||||
// Create an extent, and remove the first part of the extent.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [......]
|
||||
failed |= SimpleTestCase(10, 10, 10, 6, "[0, 0] [16, 4] [999, 0] ");
|
||||
|
||||
// Create an extent, and remove the last part of the extent.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [......]
|
||||
failed |= SimpleTestCase(10, 10, 14, 6, "[0, 0] [10, 4] [999, 0] ");
|
||||
|
||||
// Create an extent and remove before the start, through the middle.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [..........]
|
||||
failed |= SimpleTestCase(10, 10, 6, 10, "[0, 0] [16, 4] [999, 0] ");
|
||||
|
||||
// Create an extent and remove from middle to past the end.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [..........]
|
||||
failed |= SimpleTestCase(10, 10, 14, 10, "[0, 0] [10, 4] [999, 0] ");
|
||||
|
||||
// Create an extent and remove from before through past end.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [..............]
|
||||
failed |= SimpleTestCase(10, 10, 6, 18, "[0, 0] [999, 0] ");
|
||||
|
||||
// Create an extent and remove purely before the extent.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [...]
|
||||
failed |= SimpleTestCase(10, 10, 2, 5, "[0, 0] [10, 10] [999, 0] ");
|
||||
|
||||
// Create an extent and remove purely after the extent.
|
||||
// Create: [xxxxxxxxxx]
|
||||
// Remove: [...]
|
||||
failed |= SimpleTestCase(10, 10, 22, 5, "[0, 0] [10, 10] [999, 0] ");
|
||||
|
||||
if (failed)
|
||||
printf("FAIL!\n");
|
||||
else
|
||||
printf("Success.\n");
|
||||
|
||||
return failed;
|
||||
}
|
||||
|
||||
#endif /* UNIT_TEST */
|
74
ExtentManager.h
Normal file
74
ExtentManager.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
//
|
||||
// ExtentManager.h
|
||||
//
|
||||
#ifndef EXTENTMANAGER_H
|
||||
#define EXTENTMANAGER_H
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
using namespace std;
|
||||
|
||||
struct ExtentInfo {
|
||||
off_t blockAddr;
|
||||
off_t numBlocks;
|
||||
};
|
||||
|
||||
inline bool BeforeExtent(const ExtentInfo &a, const ExtentInfo &b)
|
||||
{
|
||||
return (a.blockAddr + a.numBlocks) < b.blockAddr;
|
||||
}
|
||||
|
||||
typedef list<ExtentInfo>::iterator ListExtIt;
|
||||
|
||||
class ExtentManager {
|
||||
public:
|
||||
ExtentManager() : blockSize(0), totalBytes(0), totalBlocks(0) {};
|
||||
~ExtentManager() {};
|
||||
|
||||
void Init(uint32_t theBlockSize, uint32_t theNativeBlockSize, off_t theTotalBytes);
|
||||
|
||||
void AddBlockRangeExtent(off_t blockAddr, off_t numBlocks);
|
||||
void AddByteRangeExtent(off_t byteAddr, off_t numBytes);
|
||||
void RemoveBlockRangeExtent(off_t blockAddr, off_t numBlocks);
|
||||
|
||||
void DebugPrint();
|
||||
|
||||
protected:
|
||||
void MergeExtent(const ExtentInfo &a, const ExtentInfo &b, ExtentInfo *c);
|
||||
|
||||
public:
|
||||
size_t blockSize;
|
||||
size_t nativeBlockSize;
|
||||
off_t totalBytes;
|
||||
off_t totalBlocks;
|
||||
list<ExtentInfo> extentList;
|
||||
};
|
||||
|
||||
#endif // #ifndef EXTENTMANAGER_H
|
296
getmntopts.3
Normal file
296
getmntopts.3
Normal file
@ -0,0 +1,296 @@
|
||||
.\" $NetBSD: getmntopts.3,v 1.12 2010/08/24 12:05:01 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1994
|
||||
.\" 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
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)getmntopts.3 8.3 (Berkeley) 3/30/95
|
||||
.\"
|
||||
.Dd May 4, 2010
|
||||
.Dt GETMNTOPTS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm getmntopts
|
||||
.Nd scan mount options
|
||||
.Sh LIBRARY
|
||||
.Lb libutil
|
||||
.Sh SYNOPSIS
|
||||
.In mntopts.h
|
||||
.Ft mntoptparse_t
|
||||
.Fn getmntopts "const char *options" "const struct mntopt *mopts" "int *flagp" "int *altflagp"
|
||||
.Ft const char *
|
||||
.Fn getmntoptstr "mntoptparse_t mp" "const char *opt"
|
||||
.Ft long
|
||||
.Fn getmntoptnum "mntoptparse_t mp" "const char *opt"
|
||||
.Ft void
|
||||
.Fn freemntopts "mntoptparse_t mp"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn getmntopts
|
||||
function takes a comma separated option list and a list
|
||||
of valid option names, and computes the bitmasks
|
||||
corresponding to the requested set of options.
|
||||
.Pp
|
||||
The string
|
||||
.Ar options
|
||||
is broken down into a sequence of comma separated tokens.
|
||||
Each token is looked up in the table described by
|
||||
.Ar mopts
|
||||
and the bits in
|
||||
the word referenced by either
|
||||
.Ar flagp
|
||||
or
|
||||
.Ar altflagp
|
||||
(depending on the
|
||||
.Dv m_altloc
|
||||
field of the option's table entry)
|
||||
are updated.
|
||||
The flag words are not initialized by
|
||||
.Fn getmntopts .
|
||||
The table,
|
||||
.Ar mopts ,
|
||||
has the following format:
|
||||
.Bd -literal
|
||||
struct mntopt {
|
||||
const char *m_option; /* option name */
|
||||
int m_inverse; /* negative option, e.g., "dev" */
|
||||
int m_flag; /* bit to set, e.g., MNT_RDONLY */
|
||||
int m_altloc; /* use altflagp rather than flagp */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width m_inverse
|
||||
.It Fa m_option
|
||||
the option name,
|
||||
for example
|
||||
.Dq suid .
|
||||
.It Fa m_inverse
|
||||
tells
|
||||
.Fn getmntopts
|
||||
that the name has the inverse meaning of the bit.
|
||||
For example,
|
||||
.Dq suid
|
||||
is the string, whereas the mount flag is
|
||||
.Dv MNT_NOSUID .
|
||||
In this case, the sense of the string and the flag
|
||||
are inverted, so the
|
||||
.Fa m_inverse
|
||||
flag should be set.
|
||||
.It Fa m_flag
|
||||
the value of the bit to be set or cleared in
|
||||
the flag word when the option is recognized.
|
||||
The bit is set when the option is discovered,
|
||||
but cleared if the option name was preceded
|
||||
by the letters
|
||||
.Dq no .
|
||||
The
|
||||
.Fa m_inverse
|
||||
flag causes these two operations to be reversed.
|
||||
.It Fa m_altloc
|
||||
the bit should be set or cleared in
|
||||
.Ar altflagp
|
||||
rather than
|
||||
.Ar flagp .
|
||||
.El
|
||||
.Pp
|
||||
Each of the user visible
|
||||
.Dv MNT_
|
||||
flags has a corresponding
|
||||
.Dv MOPT_
|
||||
macro which defines an appropriate
|
||||
.Li "struct mntopt"
|
||||
entry.
|
||||
To simplify the program interface and ensure consistency across all
|
||||
programs, a general purpose macro,
|
||||
.Dv MOPT_STDOPTS ,
|
||||
is defined which contains an entry for all the generic VFS options:
|
||||
.Bd -literal -offset indent
|
||||
MOPT_USERQUOTA,
|
||||
MOPT_GROUPQUOTA,
|
||||
MOPT_FSTAB_COMPAT,
|
||||
MOPT_NODEV,
|
||||
MOPT_NOEXEC,
|
||||
MOPT_NOSUID,
|
||||
MOPT_RDONLY,
|
||||
MOPT_UNION,
|
||||
MOPT_BROWSE,
|
||||
MOPT_AUTOMOUNTED,
|
||||
MOPT_DEFWRITE,
|
||||
MOPT_NOATIME,
|
||||
MOPT_PERMISSIONS,
|
||||
MOPT_IGNORE_OWNERSHIP,
|
||||
MOPT_QUARANTINE,
|
||||
MOPT_CPROTECT
|
||||
.Ed
|
||||
.Pp
|
||||
In addition, the macros
|
||||
.Dv MOPT_FORCE
|
||||
and
|
||||
.Dv MOPT_UPDATE
|
||||
exist to enable the
|
||||
.Dv MNT_FORCE
|
||||
and
|
||||
.Dv MNT_UPDATE
|
||||
flags to be set.
|
||||
Finally, the table must be terminated by an entry with a
|
||||
.Dv NULL
|
||||
first element.
|
||||
.Pp
|
||||
.Fn getmntopts
|
||||
returns a
|
||||
.Li "mntoptparse_t"
|
||||
handle that can be used in subsequent
|
||||
.Fn getmntoptstr
|
||||
and
|
||||
.Fn getmntoptnum
|
||||
calls to fetch a value for an option and that must be freed with a call
|
||||
to
|
||||
.Fn freemntopts .
|
||||
If an error occurred, then if the external integer value
|
||||
.Va getmnt_silent
|
||||
is zero then
|
||||
.Fn getmntopts
|
||||
prints an error message and exits;
|
||||
if
|
||||
.Va getmnt_silent
|
||||
is non-zero then
|
||||
.Fn getmntopts
|
||||
returns
|
||||
.Dv NULL .
|
||||
.Pp
|
||||
The
|
||||
.Fn getmntoptstr
|
||||
function returns the string value of the named option, if such a value
|
||||
was set in the option string.
|
||||
If the value was not set, then if the external integer value
|
||||
.Va getmnt_silent
|
||||
is zero then
|
||||
.Fn getmntoptstr
|
||||
prints an error message and exits;
|
||||
if
|
||||
.Va getmnt_silent
|
||||
is non-zero then
|
||||
.Fn getmntoptstr
|
||||
returns
|
||||
.Dv NULL .
|
||||
.Pp
|
||||
The
|
||||
.Fn getmntoptnum
|
||||
returns the long value of the named option, if such a value was set in the
|
||||
option string.
|
||||
If the value was not set, or could not be converted from a string to a
|
||||
long, then if the external integer value
|
||||
.Va getmnt_silent
|
||||
is zero then
|
||||
.Fn getmntoptnum
|
||||
prints an error message and exits;
|
||||
if
|
||||
.Va getmnt_silent
|
||||
is non-zero then
|
||||
.Fn getmntoptnum
|
||||
returns \-1.
|
||||
.Pp
|
||||
The
|
||||
.Fn freemntopts
|
||||
frees the storage used by
|
||||
.Fn getmntopts .
|
||||
.Sh RETURN VALUES
|
||||
.Fn getmntopts
|
||||
returns
|
||||
.Dv NULL
|
||||
if an error occurred.
|
||||
Note that some bits may already have been set in
|
||||
.Va flagp
|
||||
and
|
||||
.Va altflagp
|
||||
even if
|
||||
.Dv NULL
|
||||
is returned.
|
||||
.Fn getmntoptstr
|
||||
returns
|
||||
.Dv NULL
|
||||
if an error occurred.
|
||||
.Fn getmntoptnum
|
||||
returns \-1 if an error occurred.
|
||||
.Sh EXAMPLES
|
||||
Most commands will use the standard option set.
|
||||
Local filesystems which support the
|
||||
.Dv MNT_UPDATE
|
||||
flag, would also have an
|
||||
.Dv MOPT_UPDATE
|
||||
entry.
|
||||
This can be declared and used as follows:
|
||||
.Bd -literal -offset indent
|
||||
#include \*[Lt]mntopts.h\*[Gt]
|
||||
|
||||
static const struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_UPDATE,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
\&...
|
||||
|
||||
long val;
|
||||
mntoptparse_t mp;
|
||||
mntflags = mntaltflags = 0;
|
||||
|
||||
\&...
|
||||
|
||||
mp = getmntopts(options, mopts, \*[Am]mntflags, \*[Am]mntaltflags);
|
||||
|
||||
if (mp == NULL)
|
||||
err(EXIT_FAILURE, "getmntopts");
|
||||
|
||||
\&...
|
||||
|
||||
val = getmntoptnum(mp, "rsize");
|
||||
freemntopts(mp);
|
||||
.Ed
|
||||
.Sh DIAGNOSTICS
|
||||
If the external integer variable
|
||||
.Va getmnt_silent
|
||||
is zero then the
|
||||
.Fn getmntopts ,
|
||||
.Fn getmntoptstr ,
|
||||
and
|
||||
.Fn getmntoptnum
|
||||
functions display an error message and exit if an error occurred.
|
||||
By default
|
||||
.Va getmnt_silent
|
||||
is zero.
|
||||
.Sh SEE ALSO
|
||||
.Xr err 3 ,
|
||||
.Xr mount 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn getmntopts
|
||||
function appeared in
|
||||
.Bx 4.4 .
|
||||
It was moved to the utilities library and enhanced to retrieve option
|
||||
values in
|
||||
.Nx 2.0 .
|
188
getmntopts.c
Normal file
188
getmntopts.c
Normal file
@ -0,0 +1,188 @@
|
||||
/* $NetBSD: getmntopts.c,v 1.3 2003/08/07 16:44:58 agc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* 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
|
||||
* 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. 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: getmntopts.c,v 1.3 2003/08/07 16:44:58 agc Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fstab.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mntopts.h>
|
||||
|
||||
int getmnt_silent = 0;
|
||||
|
||||
static const char errmsg[] = "-o %s: option not supported";
|
||||
|
||||
struct mntoptparse {
|
||||
const char *options;
|
||||
const struct mntopt *mopts;
|
||||
char *optbuf;
|
||||
char **optarg;
|
||||
};
|
||||
|
||||
const char *
|
||||
getmntoptstr(mntoptparse_t mp, const char *opt)
|
||||
{
|
||||
const struct mntopt *m;
|
||||
|
||||
for (m = mp->mopts; m->m_option != NULL; m++)
|
||||
if (strcasecmp(opt, m->m_option) == 0)
|
||||
break;
|
||||
|
||||
if (m->m_option == NULL) {
|
||||
if (getmnt_silent == 0)
|
||||
errx(1, errmsg, opt);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mp->optarg[m - mp->mopts];
|
||||
}
|
||||
|
||||
long
|
||||
getmntoptnum(mntoptparse_t mp, const char *opt)
|
||||
{
|
||||
char *ep;
|
||||
long rv;
|
||||
void (*fun)(int, const char *, ...) = NULL;
|
||||
const char *val = getmntoptstr(mp, opt);
|
||||
|
||||
if (val == NULL) {
|
||||
if (getmnt_silent == 0)
|
||||
errx(1, "Missing %s argument", opt);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
rv = strtol(val, &ep, 0);
|
||||
|
||||
if (*ep)
|
||||
fun = errx;
|
||||
|
||||
if (errno == ERANGE && (rv == LONG_MAX || rv == LONG_MIN))
|
||||
fun = err;
|
||||
|
||||
if (fun) {
|
||||
if (getmnt_silent != 0)
|
||||
return -1;
|
||||
(*fun)(1, "Invalid %s argument `%s'", opt, val);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
freemntopts(mntoptparse_t mp)
|
||||
{
|
||||
free(mp->optbuf);
|
||||
free(mp->optarg);
|
||||
free(mp);
|
||||
}
|
||||
|
||||
mntoptparse_t
|
||||
getmntopts(const char *options, const struct mntopt *m0, int *flagp,
|
||||
int *altflagp)
|
||||
{
|
||||
const struct mntopt *m;
|
||||
int negative;
|
||||
char *opt, *p, *ctx = NULL;
|
||||
int *thisflagp;
|
||||
size_t nopts;
|
||||
mntoptparse_t mp;
|
||||
|
||||
for (nopts = 0, m = m0; m->m_option != NULL; ++m, nopts++)
|
||||
continue;
|
||||
|
||||
if ((mp = malloc(sizeof(struct mntoptparse))) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Copy option string, since it is about to be torn asunder... */
|
||||
if ((mp->optbuf = strdup(options)) == NULL) {
|
||||
free(mp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((mp->optarg = calloc(nopts, sizeof(char *))) == NULL) {
|
||||
free(mp->optbuf);
|
||||
free(mp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp->mopts = m0;
|
||||
mp->options = options;
|
||||
|
||||
for (opt = mp->optbuf; (opt = strtok_r(opt, ",", &ctx)) != NULL; opt = NULL) {
|
||||
/* Check for "no" prefix. */
|
||||
if (opt[0] == 'n' && opt[1] == 'o') {
|
||||
negative = 1;
|
||||
opt += 2;
|
||||
} else
|
||||
negative = 0;
|
||||
|
||||
/*
|
||||
* for options with assignments in them (ie. quotas)
|
||||
* ignore the assignment as it's handled elsewhere
|
||||
*/
|
||||
p = strchr(opt, '=');
|
||||
if (p) {
|
||||
*p++ = '\0';
|
||||
}
|
||||
|
||||
/* Scan option table. */
|
||||
for (m = m0; m->m_option != NULL; ++m)
|
||||
if (strcasecmp(opt, m->m_option) == 0)
|
||||
break;
|
||||
|
||||
/* Save flag, or fail if option is not recognised. */
|
||||
if (m->m_option) {
|
||||
mp->optarg[m - m0] = p;
|
||||
thisflagp = m->m_altloc ? altflagp : flagp;
|
||||
if (negative == m->m_inverse)
|
||||
*thisflagp |= m->m_flag;
|
||||
else
|
||||
*thisflagp &= ~m->m_flag;
|
||||
} else if (!getmnt_silent) {
|
||||
errx(1, errmsg, opt);
|
||||
}
|
||||
}
|
||||
return mp;
|
||||
}
|
202
humanize_number.3
Normal file
202
humanize_number.3
Normal file
@ -0,0 +1,202 @@
|
||||
.\" $NetBSD: humanize_number.3,v 1.4 2003/04/16 13:34:37 wiz Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.\" Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Luke Mewburn and by Tomas Svensson.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
.\"
|
||||
.Dd October 7, 2013
|
||||
.Dt HUMANIZE_NUMBER 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm humanize_number
|
||||
.Nd format a number into a human readable form
|
||||
.Sh LIBRARY
|
||||
.Lb libutil
|
||||
.Sh SYNOPSIS
|
||||
.In libutil.h
|
||||
.Ft int
|
||||
.Fo humanize_number
|
||||
.Fa "char *buf" "size_t len" "int64_t number" "const char *suffix"
|
||||
.Fa "int scale" "int flags"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn humanize_number
|
||||
function formats the signed 64-bit quantity given in
|
||||
.Fa number
|
||||
into
|
||||
.Fa buf .
|
||||
A space and then
|
||||
.Fa suffix
|
||||
is appended to the end.
|
||||
The buffer pointed to by
|
||||
.Fa buf
|
||||
must be at least
|
||||
.Fa len
|
||||
bytes long.
|
||||
.Pp
|
||||
If the formatted number (including
|
||||
.Fa suffix )
|
||||
would be too long to fit into
|
||||
.Fa buf ,
|
||||
then divide
|
||||
.Fa number
|
||||
by 1024 until it will.
|
||||
In this case, prefix
|
||||
.Fa suffix
|
||||
with the appropriate designator.
|
||||
The
|
||||
.Fn humanize_number
|
||||
function follows the traditional computer science conventions by
|
||||
default, rather than the IEE/IEC (and now also SI) power of two
|
||||
convention or the power of ten notion.
|
||||
This behaviour however can be altered by specifying the
|
||||
.Dv HN_DIVISOR_1000
|
||||
and
|
||||
.Dv HN_IEC_PREFIXES
|
||||
flags.
|
||||
.Pp
|
||||
The traditional
|
||||
.Pq default
|
||||
prefixes are:
|
||||
.Bl -column "Prefix" "Description" "1000000000000000000" -offset indent
|
||||
.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier" Ta Sy "Multiplier 1000x"
|
||||
.It Li (note) Ta No kilo Ta 1024 Ta 1000
|
||||
.It Li M Ta No mega Ta 1048576 Ta 1000000
|
||||
.It Li G Ta No giga Ta 1073741824 Ta 1000000000
|
||||
.It Li T Ta No tera Ta 1099511627776 Ta 1000000000000
|
||||
.It Li P Ta No peta Ta 1125899906842624 Ta 1000000000000000
|
||||
.It Li E Ta No exa Ta 1152921504606846976 Ta 1000000000000000000
|
||||
.El
|
||||
.Pp
|
||||
Note:
|
||||
An uppercase K indicates a power of two, a lowercase k a power of ten.
|
||||
.Pp
|
||||
The IEE/IEC (and now also SI) power of two prefixes are:
|
||||
.Bl -column "Prefix" "Description" "1000000000000000000" -offset indent
|
||||
.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier"
|
||||
.It Li Ki Ta No kibi Ta 1024
|
||||
.It Li Mi Ta No mebi Ta 1048576
|
||||
.It Li Gi Ta No gibi Ta 1073741824
|
||||
.It Li Ti Ta No tebi Ta 1099511627776
|
||||
.It Li Pi Ta No pebi Ta 1125899906842624
|
||||
.It Li Ei Ta No exbi Ta 1152921504606846976
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fa len
|
||||
argument must be at least 4 plus the length of
|
||||
.Fa suffix ,
|
||||
in order to ensure a useful result is generated into
|
||||
.Fa buf .
|
||||
To use a specific prefix, specify this as
|
||||
.Fa scale
|
||||
.Po multiplier = 1024 ^ scale;
|
||||
when
|
||||
.Dv HN_DIVISOR_1000
|
||||
is specified,
|
||||
multiplier = 1000 ^ scale
|
||||
.Pc .
|
||||
This cannot be combined with any of the
|
||||
.Fa scale
|
||||
flags below.
|
||||
.Pp
|
||||
The following flags may be passed in
|
||||
.Fa scale :
|
||||
.Bl -tag -width ".Dv HN_DIVISOR_1000" -offset indent
|
||||
.It Dv HN_AUTOSCALE
|
||||
Format the buffer using the lowest multiplier possible.
|
||||
.It Dv HN_GETSCALE
|
||||
Return the prefix index number (the number of times
|
||||
.Fa number
|
||||
must be divided to fit) instead of formatting it to the buffer.
|
||||
.El
|
||||
.Pp
|
||||
The following flags may be passed in
|
||||
.Fa flags :
|
||||
.Bl -tag -width ".Dv HN_DIVISOR_1000" -offset indent
|
||||
.It Dv HN_DECIMAL
|
||||
If the final result is less than 10, display it using one decimal place.
|
||||
.It Dv HN_NOSPACE
|
||||
Do not put a space between
|
||||
.Fa number
|
||||
and the prefix.
|
||||
.It Dv HN_B
|
||||
Use
|
||||
.Ql B
|
||||
(bytes) as prefix if the original result does not have a prefix.
|
||||
.It Dv HN_DIVISOR_1000
|
||||
Divide
|
||||
.Fa number
|
||||
with 1000 instead of 1024.
|
||||
.It Dv HN_IEC_PREFIXES
|
||||
Use the IEE/IEC notion of prefixes (Ki, Mi, Gi...).
|
||||
This flag has no effect when
|
||||
.Dv HN_DIVISOR_1000
|
||||
is also specified.
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
Upon success, the
|
||||
.Nm
|
||||
function returns the number of characters that would have been stored in
|
||||
.Fa buf
|
||||
(excluding the terminating
|
||||
.Dv NUL )
|
||||
if
|
||||
.Fa buf
|
||||
was large enough, or \-1 upon failure.
|
||||
Even upon failure, the contents of
|
||||
.Fa buf
|
||||
may be modified.
|
||||
If
|
||||
.Dv HN_GETSCALE
|
||||
is specified, the prefix index number will be returned instead.
|
||||
.\" .Sh SEE ALSO
|
||||
.\" .Xr expand_number 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Dv HN_DIVISOR_1000
|
||||
and
|
||||
.Dv HN_IEC_PREFIXES
|
||||
flags
|
||||
conform to
|
||||
.Tn ISO/IEC
|
||||
Std\~80000-13:2008
|
||||
and
|
||||
.Tn IEEE
|
||||
Std\~1541-2002.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn humanize_number
|
||||
function first appeared in
|
||||
.Nx 2.0
|
||||
and then in
|
||||
.Fx 5.3 .
|
||||
The
|
||||
.Dv HN_IEC_PREFIXES
|
||||
flag was introduced in
|
||||
.Fx 9.0 .
|
179
humanize_number.c
Normal file
179
humanize_number.c
Normal file
@ -0,0 +1,179 @@
|
||||
/* $NetBSD: humanize_number.c,v 1.14 2008/04/28 20:22:59 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
|
||||
* Copyright 2013 John-Mark Gurney <jmg@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <libutil.h>
|
||||
|
||||
static const int maxscale = 7;
|
||||
|
||||
int
|
||||
humanize_number(char *buf, size_t len, int64_t quotient,
|
||||
const char *suffix, int scale, int flags)
|
||||
{
|
||||
const char *prefixes, *sep;
|
||||
int i, r, remainder, s1, s2, sign;
|
||||
int divisordeccut;
|
||||
int64_t divisor, max;
|
||||
size_t baselen;
|
||||
|
||||
/* Since so many callers don't check -1, NUL terminate the buffer */
|
||||
if (len > 0)
|
||||
buf[0] = '\0';
|
||||
|
||||
/* validate args */
|
||||
if (buf == NULL || suffix == NULL)
|
||||
return (-1);
|
||||
if (scale < 0)
|
||||
return (-1);
|
||||
else if (scale >= maxscale &&
|
||||
((scale & ~(HN_AUTOSCALE|HN_GETSCALE)) != 0))
|
||||
return (-1);
|
||||
if ((flags & HN_DIVISOR_1000) && (flags & HN_IEC_PREFIXES))
|
||||
return (-1);
|
||||
|
||||
/* setup parameters */
|
||||
remainder = 0;
|
||||
|
||||
if (flags & HN_IEC_PREFIXES) {
|
||||
baselen = 2;
|
||||
/*
|
||||
* Use the prefixes for power of two recommended by
|
||||
* the International Electrotechnical Commission
|
||||
* (IEC) in IEC 80000-3 (i.e. Ki, Mi, Gi...).
|
||||
*
|
||||
* HN_IEC_PREFIXES implies a divisor of 1024 here
|
||||
* (use of HN_DIVISOR_1000 would have triggered
|
||||
* an assertion earlier).
|
||||
*/
|
||||
divisor = 1024;
|
||||
divisordeccut = 973; /* ceil(.95 * 1024) */
|
||||
if (flags & HN_B)
|
||||
prefixes = "B\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei";
|
||||
else
|
||||
prefixes = "\0\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei";
|
||||
} else {
|
||||
baselen = 1;
|
||||
if (flags & HN_DIVISOR_1000) {
|
||||
divisor = 1000;
|
||||
divisordeccut = 950;
|
||||
if (flags & HN_B)
|
||||
prefixes = "B\0\0k\0\0M\0\0G\0\0T\0\0P\0\0E";
|
||||
else
|
||||
prefixes = "\0\0\0k\0\0M\0\0G\0\0T\0\0P\0\0E";
|
||||
} else {
|
||||
divisor = 1024;
|
||||
divisordeccut = 973; /* ceil(.95 * 1024) */
|
||||
if (flags & HN_B)
|
||||
prefixes = "B\0\0K\0\0M\0\0G\0\0T\0\0P\0\0E";
|
||||
else
|
||||
prefixes = "\0\0\0K\0\0M\0\0G\0\0T\0\0P\0\0E";
|
||||
}
|
||||
}
|
||||
|
||||
#define SCALE2PREFIX(scale) (&prefixes[(scale) * 3])
|
||||
|
||||
if (quotient < 0) {
|
||||
sign = -1;
|
||||
quotient = -quotient;
|
||||
baselen += 2; /* sign, digit */
|
||||
} else {
|
||||
sign = 1;
|
||||
baselen += 1; /* digit */
|
||||
}
|
||||
if (flags & HN_NOSPACE)
|
||||
sep = "";
|
||||
else {
|
||||
sep = " ";
|
||||
baselen++;
|
||||
}
|
||||
baselen += strlen(suffix);
|
||||
|
||||
/* Check if enough room for `x y' + suffix + `\0' */
|
||||
if (len < baselen + 1)
|
||||
return (-1);
|
||||
|
||||
if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
|
||||
/* See if there is additional columns can be used. */
|
||||
for (max = 1, i = len - baselen; i-- > 0 && max <= (INT64_MAX / 10);)
|
||||
max *= 10;
|
||||
|
||||
/*
|
||||
* Divide the number until it fits the given column.
|
||||
* If there will be an overflow by the rounding below,
|
||||
* divide once more.
|
||||
*/
|
||||
for (i = 0;
|
||||
(quotient >= max || (quotient == max - 1 &&
|
||||
remainder >= divisordeccut)) && i < maxscale; i++) {
|
||||
remainder = quotient % divisor;
|
||||
quotient /= divisor;
|
||||
}
|
||||
|
||||
if (scale & HN_GETSCALE)
|
||||
return (i);
|
||||
} else {
|
||||
for (i = 0; i < scale && i < maxscale; i++) {
|
||||
remainder = quotient % divisor;
|
||||
quotient /= divisor;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a value <= 9.9 after rounding and ... */
|
||||
/*
|
||||
* XXX - should we make sure there is enough space for the decimal
|
||||
* place and if not, don't do HN_DECIMAL?
|
||||
*/
|
||||
if (((quotient == 9 && remainder < divisordeccut) || quotient < 9) &&
|
||||
i > 0 && flags & HN_DECIMAL) {
|
||||
s1 = (int)quotient + ((remainder * 10 + divisor / 2) /
|
||||
divisor / 10);
|
||||
s2 = ((remainder * 10 + divisor / 2) / divisor) % 10;
|
||||
r = snprintf(buf, len, "%d%s%d%s%s%s",
|
||||
sign * s1, localeconv()->decimal_point, s2,
|
||||
sep, SCALE2PREFIX(i), suffix);
|
||||
} else
|
||||
r = snprintf(buf, len, "%" PRId64 "%s%s%s",
|
||||
sign * (quotient + (remainder + divisor / 2) / divisor),
|
||||
sep, SCALE2PREFIX(i), suffix);
|
||||
|
||||
return (r);
|
||||
}
|
20
libutil.exports
Normal file
20
libutil.exports
Normal file
@ -0,0 +1,20 @@
|
||||
_freemntopts
|
||||
_getmnt_silent
|
||||
_getmntoptnum
|
||||
_getmntopts
|
||||
_getmntoptstr
|
||||
_humanize_number
|
||||
_pidfile_close
|
||||
_pidfile_open
|
||||
_pidfile_remove
|
||||
_pidfile_write
|
||||
_realhostname
|
||||
_realhostname_sa
|
||||
_reexec_to_match_kernel
|
||||
_reexec_to_match_lp64ness
|
||||
_tzlink
|
||||
_wipefs_alloc
|
||||
_wipefs_except_blocks
|
||||
_wipefs_free
|
||||
_wipefs_include_blocks
|
||||
_wipefs_wipe
|
95
libutil.h
Normal file
95
libutil.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 1996 Peter Wemm <peter@FreeBSD.org>.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed for the FreeBSD Project by
|
||||
* ThinkSec AS and NAI Labs, the Security Research Division of Network
|
||||
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
|
||||
* ("CBOSS"), as part of the DARPA CHATS research program.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD: src/lib/libutil/libutil.h,v 1.42 2006/02/18 11:25:28 des Exp $
|
||||
*/
|
||||
|
||||
#ifndef _LIBUTIL_H_
|
||||
#define _LIBUTIL_H_
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef _SYS_PARAM_H_
|
||||
/* for pidfile.c */
|
||||
struct pidfh {
|
||||
int pf_fd;
|
||||
char pf_path[MAXPATHLEN + 1];
|
||||
dev_t pf_dev;
|
||||
ino_t pf_ino;
|
||||
};
|
||||
#else
|
||||
struct pidfh;
|
||||
#endif
|
||||
|
||||
struct in_addr;
|
||||
struct sockaddr;
|
||||
|
||||
__BEGIN_DECLS
|
||||
int humanize_number(char *_buf, size_t _len, int64_t _number,
|
||||
const char *_suffix, int _scale, int _flags);
|
||||
|
||||
int realhostname(char *host, size_t hsize, const struct in_addr *ip);
|
||||
int realhostname_sa(char *host, size_t hsize, struct sockaddr *addr,
|
||||
int addrlen);
|
||||
|
||||
struct pidfh *pidfile_open(const char *path, mode_t mode, pid_t *pidptr);
|
||||
int pidfile_write(struct pidfh *pfh);
|
||||
int pidfile_close(struct pidfh *pfh);
|
||||
int pidfile_remove(struct pidfh *pfh);
|
||||
|
||||
int reexec_to_match_kernel(void);
|
||||
int reexec_to_match_lp64ness(bool isLP64);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
/* return values from realhostname() */
|
||||
#define HOSTNAME_FOUND (0)
|
||||
#define HOSTNAME_INCORRECTNAME (1)
|
||||
#define HOSTNAME_INVALIDADDR (2)
|
||||
#define HOSTNAME_INVALIDNAME (3)
|
||||
|
||||
/* Values for humanize_number(3)'s flags parameter. */
|
||||
#define HN_DECIMAL 0x01
|
||||
#define HN_NOSPACE 0x02
|
||||
#define HN_B 0x04
|
||||
#define HN_DIVISOR_1000 0x08
|
||||
#define HN_IEC_PREFIXES 0x10
|
||||
|
||||
/* Values for humanize_number(3)'s scale parameter. */
|
||||
#define HN_GETSCALE 0x10
|
||||
#define HN_AUTOSCALE 0x20
|
||||
|
||||
#endif /* !_LIBUTIL_H_ */
|
34
libutil.plist
Normal file
34
libutil.plist
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array>
|
||||
<dict>
|
||||
<key>OpenSourceSCM</key>
|
||||
<string>cvs -d freebsdanoncvs@anoncvs.FreeBSD.org:/home/ncvs co libutil</string>
|
||||
<key>OpenSourceImportDate</key>
|
||||
<string>2006-05-20</string>
|
||||
<key>OpenSourceLicense</key>
|
||||
<string>BSD</string>
|
||||
<key>OpenSourceLicenseFile</key>
|
||||
<string>libutil.txt</string>
|
||||
<key>OpenSourceProject</key>
|
||||
<string>libutil</string>
|
||||
<key>OpenSourceVersion</key>
|
||||
<string>2005-02-13</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>OpenSourceImportDate</key>
|
||||
<string>2006-05-20</string>
|
||||
<key>OpenSourceLicense</key>
|
||||
<string>BSD</string>
|
||||
<key>OpenSourceLicenseFile</key>
|
||||
<string>libutil.txt</string>
|
||||
<key>OpenSourceProject</key>
|
||||
<string>libutil</string>
|
||||
<key>OpenSourceVersion</key>
|
||||
<string>1.3</string>
|
||||
<key>OpenSourceURL</key>
|
||||
<string>http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/lib/libutil/getmntopts.c?rev=1.3</string>
|
||||
</dict>
|
||||
</array>
|
||||
</plist>
|
238
libutil.txt
Normal file
238
libutil.txt
Normal file
@ -0,0 +1,238 @@
|
||||
_secure_path.c:
|
||||
/*-
|
||||
* Based on code copyright (c) 1995,1997 by
|
||||
* Berkeley Software Design, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* 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. This work was done expressly for inclusion into FreeBSD. Other use
|
||||
* is permitted provided this notation is included.
|
||||
* 4. Absolutely no warranty of function or purpose is made by the authors.
|
||||
* 5. Modifications may be freely made to this file providing the above
|
||||
* conditions are met.
|
||||
*/
|
||||
|
||||
fparseln.c:
|
||||
/*
|
||||
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
|
||||
*
|
||||
* 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 Christos Zoulas.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
|
||||
*/
|
||||
|
||||
humanize_number.c:
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson.
|
||||
*
|
||||
* 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 NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
pidfile.c:
|
||||
/*-
|
||||
* Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
property.c:
|
||||
/*
|
||||
*
|
||||
* Simple property list handling code.
|
||||
*
|
||||
* Copyright (c) 1998
|
||||
* Jordan "Perky" Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 OR HIS PETS 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, LIFE 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.
|
||||
*/
|
||||
|
||||
realhostname.c:
|
||||
/*-
|
||||
* Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
trimdomain.c:
|
||||
/*-
|
||||
* Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
|
||||
* Based on original work by Atsushi Murai <amurai@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
uucplock.c:
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
827
libutil.xcodeproj/project.pbxproj
Normal file
827
libutil.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,827 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
3EB206C51F5096F100B150D3 /* bridgeos */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = 3EB206CC1F5096F100B150D3 /* Build configuration list for PBXAggregateTarget "bridgeos" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
3EB206C61F5096F100B150D3 /* PBXTargetDependency */,
|
||||
3EB206C81F5096F100B150D3 /* PBXTargetDependency */,
|
||||
);
|
||||
name = bridgeos;
|
||||
productName = ios;
|
||||
};
|
||||
FDA4990F199D69B800A32E83 /* tests */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = FDA49910199D69B800A32E83 /* Build configuration list for PBXAggregateTarget "tests" */;
|
||||
buildPhases = (
|
||||
FDA46DEB1D6D10DE00C63528 /* CopyFiles */,
|
||||
);
|
||||
dependencies = (
|
||||
FDA49918199D69C800A32E83 /* PBXTargetDependency */,
|
||||
);
|
||||
name = tests;
|
||||
productName = tests;
|
||||
};
|
||||
FDBC26E41741B09300CA4B2B /* osx */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = FDBC26E71741B09300CA4B2B /* Build configuration list for PBXAggregateTarget "osx" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
FDBC27001741B1B300CA4B2B /* PBXTargetDependency */,
|
||||
FDA49916199D69C600A32E83 /* PBXTargetDependency */,
|
||||
3EB98B671E37CEFE0059EC72 /* PBXTargetDependency */,
|
||||
);
|
||||
name = osx;
|
||||
productName = OSX;
|
||||
};
|
||||
FDBC26E81741B09D00CA4B2B /* ios */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = FDBC26E91741B09D00CA4B2B /* Build configuration list for PBXAggregateTarget "ios" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
FDBC27021741B1B500CA4B2B /* PBXTargetDependency */,
|
||||
FDA49914199D69C100A32E83 /* PBXTargetDependency */,
|
||||
FDBC27041741B1B700CA4B2B /* PBXTargetDependency */,
|
||||
);
|
||||
name = ios;
|
||||
productName = ios;
|
||||
};
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
BA79F9CB13BB7207006A292D /* ExtentManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9A313BB70FF006A292D /* ExtentManager.cpp */; };
|
||||
BA79F9CC13BB7207006A292D /* getmntopts.c in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9A613BB70FF006A292D /* getmntopts.c */; };
|
||||
BA79F9CD13BB7207006A292D /* humanize_number.c in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9A813BB70FF006A292D /* humanize_number.c */; };
|
||||
BA79F9CE13BB7207006A292D /* pidfile.c in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9B013BB70FF006A292D /* pidfile.c */; };
|
||||
BA79F9D013BB7207006A292D /* realhostname.c in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9B513BB70FF006A292D /* realhostname.c */; };
|
||||
BA79F9D113BB7207006A292D /* reexec_to_match_kernel.c in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9B713BB70FF006A292D /* reexec_to_match_kernel.c */; };
|
||||
BA79F9D213BB7207006A292D /* trimdomain.c in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9B913BB70FF006A292D /* trimdomain.c */; };
|
||||
BA79F9D413BB7207006A292D /* wipefs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9BD13BB70FF006A292D /* wipefs.cpp */; };
|
||||
BA79F9D513BB7235006A292D /* libutil.h in Headers */ = {isa = PBXBuildFile; fileRef = BA79F9AA13BB70FF006A292D /* libutil.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
BA79F9D613BB7235006A292D /* mntopts.h in Headers */ = {isa = PBXBuildFile; fileRef = BA79F9AE13BB70FF006A292D /* mntopts.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
BA79F9D713BB7235006A292D /* wipefs.h in Headers */ = {isa = PBXBuildFile; fileRef = BA79F9BE13BB70FF006A292D /* wipefs.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
BA79F9D813BB7243006A292D /* ExtentManager.h in Headers */ = {isa = PBXBuildFile; fileRef = BA79F9A413BB70FF006A292D /* ExtentManager.h */; };
|
||||
BA79F9DD13BB76B0006A292D /* getmntopts.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9A513BB70FF006A292D /* getmntopts.3 */; };
|
||||
BA79F9DE13BB76B0006A292D /* humanize_number.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9A713BB70FF006A292D /* humanize_number.3 */; };
|
||||
BA79F9DF13BB76B0006A292D /* pidfile.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9AF13BB70FF006A292D /* pidfile.3 */; };
|
||||
BA79F9E113BB76B0006A292D /* realhostname_sa.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9B313BB70FF006A292D /* realhostname_sa.3 */; };
|
||||
BA79F9E213BB76B0006A292D /* realhostname.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9B413BB70FF006A292D /* realhostname.3 */; };
|
||||
BA79F9E313BB76B0006A292D /* reexec_to_match_kernel.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9B613BB70FF006A292D /* reexec_to_match_kernel.3 */; };
|
||||
BA79F9E413BB76B0006A292D /* trimdomain.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9B813BB70FF006A292D /* trimdomain.3 */; };
|
||||
BA79F9E613BB76B0006A292D /* wipefs.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9BC13BB70FF006A292D /* wipefs.3 */; };
|
||||
BA79F9E913BB77FA006A292D /* libutil.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9AB13BB70FF006A292D /* libutil.plist */; };
|
||||
BA79F9EA13BB77FF006A292D /* libutil.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9AC13BB70FF006A292D /* libutil.txt */; };
|
||||
FDA46DED1D6D110000C63528 /* libutil.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = FDA46DEC1D6D110000C63528 /* libutil.plist */; };
|
||||
FDA4991B199D6A0400A32E83 /* humanize_number_test.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA4991A199D6A0400A32E83 /* humanize_number_test.c */; };
|
||||
FDA4991C199D6B9300A32E83 /* libutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BA79F9C513BB718B006A292D /* libutil.dylib */; };
|
||||
FDBC27051741B1C300CA4B2B /* com.apple.tzlinkd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = FDBC26FA1741B19000CA4B2B /* com.apple.tzlinkd.plist */; };
|
||||
FDBC27061741B1CF00CA4B2B /* tzlinkd.c in Sources */ = {isa = PBXBuildFile; fileRef = FDBC26FE1741B19000CA4B2B /* tzlinkd.c */; };
|
||||
FDBC27071741B1D600CA4B2B /* tzlink.c in Sources */ = {isa = PBXBuildFile; fileRef = FDBC26F91741B18500CA4B2B /* tzlink.c */; };
|
||||
FDBC270B1741B55400CA4B2B /* tzlink.h in Headers */ = {isa = PBXBuildFile; fileRef = FDBC27091741B47200CA4B2B /* tzlink.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
3EB206C71F5096F100B150D3 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = BA79F9C413BB718B006A292D;
|
||||
remoteInfo = util;
|
||||
};
|
||||
3EB206C91F5096F100B150D3 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = FDA4990F199D69B800A32E83;
|
||||
remoteInfo = tests;
|
||||
};
|
||||
3EB98B661E37CEFE0059EC72 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = FDBC26EF1741B13400CA4B2B;
|
||||
remoteInfo = tzlinkd;
|
||||
};
|
||||
FDA49913199D69C100A32E83 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = FDA4990F199D69B800A32E83;
|
||||
remoteInfo = tests;
|
||||
};
|
||||
FDA49915199D69C600A32E83 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = FDA4990F199D69B800A32E83;
|
||||
remoteInfo = tests;
|
||||
};
|
||||
FDA49917199D69C800A32E83 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = FDA49902199D69B000A32E83;
|
||||
remoteInfo = humanize_number_test;
|
||||
};
|
||||
FDBC26FF1741B1B300CA4B2B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = BA79F9C413BB718B006A292D;
|
||||
remoteInfo = util;
|
||||
};
|
||||
FDBC27011741B1B500CA4B2B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = BA79F9C413BB718B006A292D;
|
||||
remoteInfo = util;
|
||||
};
|
||||
FDBC27031741B1B700CA4B2B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BA79F99713BB70D7006A292D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = FDBC26EF1741B13400CA4B2B;
|
||||
remoteInfo = tzlinkd;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
BA79F9DB13BB7698006A292D /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/local/share/man/man3;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
BA79F9DD13BB76B0006A292D /* getmntopts.3 in CopyFiles */,
|
||||
BA79F9DE13BB76B0006A292D /* humanize_number.3 in CopyFiles */,
|
||||
BA79F9DF13BB76B0006A292D /* pidfile.3 in CopyFiles */,
|
||||
BA79F9E113BB76B0006A292D /* realhostname_sa.3 in CopyFiles */,
|
||||
BA79F9E213BB76B0006A292D /* realhostname.3 in CopyFiles */,
|
||||
BA79F9E313BB76B0006A292D /* reexec_to_match_kernel.3 in CopyFiles */,
|
||||
BA79F9E413BB76B0006A292D /* trimdomain.3 in CopyFiles */,
|
||||
BA79F9E613BB76B0006A292D /* wipefs.3 in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
BA79F9E713BB77BB006A292D /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/local/OpenSourceVersions;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
BA79F9E913BB77FA006A292D /* libutil.plist in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
BA79F9E813BB77D6006A292D /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/local/OpenSourceLicenses;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
BA79F9EA13BB77FF006A292D /* libutil.txt in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
FDA46DEB1D6D10DE00C63528 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /AppleInternal/CoreOS/BATS/unit_tests;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
FDA46DED1D6D110000C63528 /* libutil.plist in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FDBC26EE1741B13400CA4B2B /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /System/Library/LaunchDaemons;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
FDBC27051741B1C300CA4B2B /* com.apple.tzlinkd.plist in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3F09C378186D1F73007AF93C /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = "<group>"; };
|
||||
3F7A5E8820510D34007087AF /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = "<group>"; };
|
||||
BA79F9A313BB70FF006A292D /* ExtentManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ExtentManager.cpp; sourceTree = "<group>"; };
|
||||
BA79F9A413BB70FF006A292D /* ExtentManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtentManager.h; sourceTree = "<group>"; };
|
||||
BA79F9A513BB70FF006A292D /* getmntopts.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getmntopts.3; sourceTree = "<group>"; };
|
||||
BA79F9A613BB70FF006A292D /* getmntopts.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getmntopts.c; sourceTree = "<group>"; };
|
||||
BA79F9A713BB70FF006A292D /* humanize_number.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = humanize_number.3; sourceTree = "<group>"; };
|
||||
BA79F9A813BB70FF006A292D /* humanize_number.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = humanize_number.c; sourceTree = "<group>"; };
|
||||
BA79F9A913BB70FF006A292D /* libutil.exports */ = {isa = PBXFileReference; lastKnownFileType = text; path = libutil.exports; sourceTree = "<group>"; };
|
||||
BA79F9AA13BB70FF006A292D /* libutil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libutil.h; sourceTree = "<group>"; };
|
||||
BA79F9AB13BB70FF006A292D /* libutil.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = libutil.plist; sourceTree = "<group>"; };
|
||||
BA79F9AC13BB70FF006A292D /* libutil.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = libutil.txt; sourceTree = "<group>"; };
|
||||
BA79F9AE13BB70FF006A292D /* mntopts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mntopts.h; sourceTree = "<group>"; };
|
||||
BA79F9AF13BB70FF006A292D /* pidfile.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pidfile.3; sourceTree = "<group>"; };
|
||||
BA79F9B013BB70FF006A292D /* pidfile.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pidfile.c; sourceTree = "<group>"; };
|
||||
BA79F9B313BB70FF006A292D /* realhostname_sa.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = realhostname_sa.3; sourceTree = "<group>"; };
|
||||
BA79F9B413BB70FF006A292D /* realhostname.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = realhostname.3; sourceTree = "<group>"; };
|
||||
BA79F9B513BB70FF006A292D /* realhostname.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = realhostname.c; sourceTree = "<group>"; };
|
||||
BA79F9B613BB70FF006A292D /* reexec_to_match_kernel.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = reexec_to_match_kernel.3; sourceTree = "<group>"; };
|
||||
BA79F9B713BB70FF006A292D /* reexec_to_match_kernel.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = reexec_to_match_kernel.c; sourceTree = "<group>"; };
|
||||
BA79F9B813BB70FF006A292D /* trimdomain.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = trimdomain.3; sourceTree = "<group>"; };
|
||||
BA79F9B913BB70FF006A292D /* trimdomain.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = trimdomain.c; sourceTree = "<group>"; };
|
||||
BA79F9BC13BB70FF006A292D /* wipefs.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = wipefs.3; sourceTree = "<group>"; };
|
||||
BA79F9BD13BB70FF006A292D /* wipefs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wipefs.cpp; sourceTree = "<group>"; };
|
||||
BA79F9BE13BB70FF006A292D /* wipefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wipefs.h; sourceTree = "<group>"; };
|
||||
BA79F9C513BB718B006A292D /* libutil.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libutil.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FDA46DEC1D6D110000C63528 /* libutil.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = libutil.plist; sourceTree = "<group>"; };
|
||||
FDA49903199D69B000A32E83 /* humanize_number_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = humanize_number_test; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FDA4991A199D6A0400A32E83 /* humanize_number_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = humanize_number_test.c; sourceTree = "<group>"; };
|
||||
FDA4991D199D6CB800A32E83 /* test.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = test.xcconfig; sourceTree = "<group>"; };
|
||||
FDBC26F01741B13400CA4B2B /* tzlinkd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tzlinkd; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FDBC26F91741B18500CA4B2B /* tzlink.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tzlink.c; sourceTree = "<group>"; };
|
||||
FDBC26FA1741B19000CA4B2B /* com.apple.tzlinkd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.tzlinkd.plist; sourceTree = "<group>"; };
|
||||
FDBC26FB1741B19000CA4B2B /* com.apple.tzlinkd.sb */ = {isa = PBXFileReference; lastKnownFileType = text; path = com.apple.tzlinkd.sb; sourceTree = "<group>"; };
|
||||
FDBC26FE1741B19000CA4B2B /* tzlinkd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tzlinkd.c; sourceTree = "<group>"; };
|
||||
FDBC27081741B47200CA4B2B /* tzlink_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tzlink_internal.h; sourceTree = "<group>"; };
|
||||
FDBC27091741B47200CA4B2B /* tzlink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tzlink.h; sourceTree = "<group>"; };
|
||||
FDBC270D1741B66500CA4B2B /* tzlinkd.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = tzlinkd.xcconfig; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
BA79F9C213BB718B006A292D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FDA49900199D69B000A32E83 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FDA4991C199D6B9300A32E83 /* libutil.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FDBC26ED1741B13400CA4B2B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
7259A9711D519321008F83F6 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BA79F99513BB70D7006A292D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BA79F9A313BB70FF006A292D /* ExtentManager.cpp */,
|
||||
BA79F9A413BB70FF006A292D /* ExtentManager.h */,
|
||||
BA79F9A513BB70FF006A292D /* getmntopts.3 */,
|
||||
BA79F9A613BB70FF006A292D /* getmntopts.c */,
|
||||
BA79F9A713BB70FF006A292D /* humanize_number.3 */,
|
||||
BA79F9A813BB70FF006A292D /* humanize_number.c */,
|
||||
BA79F9A913BB70FF006A292D /* libutil.exports */,
|
||||
BA79F9AA13BB70FF006A292D /* libutil.h */,
|
||||
BA79F9AB13BB70FF006A292D /* libutil.plist */,
|
||||
BA79F9AC13BB70FF006A292D /* libutil.txt */,
|
||||
BA79F9AE13BB70FF006A292D /* mntopts.h */,
|
||||
BA79F9AF13BB70FF006A292D /* pidfile.3 */,
|
||||
BA79F9B013BB70FF006A292D /* pidfile.c */,
|
||||
BA79F9B313BB70FF006A292D /* realhostname_sa.3 */,
|
||||
BA79F9B413BB70FF006A292D /* realhostname.3 */,
|
||||
BA79F9B513BB70FF006A292D /* realhostname.c */,
|
||||
BA79F9B613BB70FF006A292D /* reexec_to_match_kernel.3 */,
|
||||
BA79F9B713BB70FF006A292D /* reexec_to_match_kernel.c */,
|
||||
FDA49919199D6A0400A32E83 /* tests */,
|
||||
BA79F9B813BB70FF006A292D /* trimdomain.3 */,
|
||||
BA79F9B913BB70FF006A292D /* trimdomain.c */,
|
||||
FDBC26F91741B18500CA4B2B /* tzlink.c */,
|
||||
FDBC27091741B47200CA4B2B /* tzlink.h */,
|
||||
FDBC27081741B47200CA4B2B /* tzlink_internal.h */,
|
||||
FDBC26F11741B13400CA4B2B /* tzlinkd */,
|
||||
BA79F9BC13BB70FF006A292D /* wipefs.3 */,
|
||||
BA79F9BD13BB70FF006A292D /* wipefs.cpp */,
|
||||
BA79F9BE13BB70FF006A292D /* wipefs.h */,
|
||||
FDBC270C1741B66500CA4B2B /* xcconfigs */,
|
||||
BA79F9C613BB718B006A292D /* Products */,
|
||||
7259A9711D519321008F83F6 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BA79F9C613BB718B006A292D /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BA79F9C513BB718B006A292D /* libutil.dylib */,
|
||||
FDBC26F01741B13400CA4B2B /* tzlinkd */,
|
||||
FDA49903199D69B000A32E83 /* humanize_number_test */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDA49919199D6A0400A32E83 /* tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDA46DEC1D6D110000C63528 /* libutil.plist */,
|
||||
FDA4991A199D6A0400A32E83 /* humanize_number_test.c */,
|
||||
);
|
||||
path = tests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDBC26F11741B13400CA4B2B /* tzlinkd */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDBC26FA1741B19000CA4B2B /* com.apple.tzlinkd.plist */,
|
||||
FDBC26FB1741B19000CA4B2B /* com.apple.tzlinkd.sb */,
|
||||
FDBC26FE1741B19000CA4B2B /* tzlinkd.c */,
|
||||
);
|
||||
path = tzlinkd;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDBC270C1741B66500CA4B2B /* xcconfigs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3F09C378186D1F73007AF93C /* base.xcconfig */,
|
||||
3F7A5E8820510D34007087AF /* lib.xcconfig */,
|
||||
FDA4991D199D6CB800A32E83 /* test.xcconfig */,
|
||||
FDBC270D1741B66500CA4B2B /* tzlinkd.xcconfig */,
|
||||
);
|
||||
path = xcconfigs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
BA79F9C313BB718B006A292D /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
BA79F9D513BB7235006A292D /* libutil.h in Headers */,
|
||||
BA79F9D613BB7235006A292D /* mntopts.h in Headers */,
|
||||
FDBC270B1741B55400CA4B2B /* tzlink.h in Headers */,
|
||||
BA79F9D713BB7235006A292D /* wipefs.h in Headers */,
|
||||
BA79F9D813BB7243006A292D /* ExtentManager.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
BA79F9C413BB718B006A292D /* util */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = BA79F9C713BB718B006A292D /* Build configuration list for PBXNativeTarget "util" */;
|
||||
buildPhases = (
|
||||
BA79F9C113BB718B006A292D /* Sources */,
|
||||
BA79F9C213BB718B006A292D /* Frameworks */,
|
||||
BA79F9C313BB718B006A292D /* Headers */,
|
||||
BA79F9DA13BB750E006A292D /* ShellScript */,
|
||||
BA79F9EB13BB7864006A292D /* ShellScript */,
|
||||
BA79F9DB13BB7698006A292D /* CopyFiles */,
|
||||
BA79F9E713BB77BB006A292D /* CopyFiles */,
|
||||
BA79F9E813BB77D6006A292D /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = util;
|
||||
productName = util;
|
||||
productReference = BA79F9C513BB718B006A292D /* libutil.dylib */;
|
||||
productType = "com.apple.product-type.library.dynamic";
|
||||
};
|
||||
FDA49902199D69B000A32E83 /* humanize_number_test */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = FDA4990E199D69B000A32E83 /* Build configuration list for PBXNativeTarget "humanize_number_test" */;
|
||||
buildPhases = (
|
||||
FDA498FF199D69B000A32E83 /* Sources */,
|
||||
FDA49900199D69B000A32E83 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = humanize_number_test;
|
||||
productName = humanize_number_test;
|
||||
productReference = FDA49903199D69B000A32E83 /* humanize_number_test */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
FDBC26EF1741B13400CA4B2B /* tzlinkd */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = FDBC26F81741B13400CA4B2B /* Build configuration list for PBXNativeTarget "tzlinkd" */;
|
||||
buildPhases = (
|
||||
FDBC26EC1741B13400CA4B2B /* Sources */,
|
||||
FDBC26ED1741B13400CA4B2B /* Frameworks */,
|
||||
FDBC26EE1741B13400CA4B2B /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = tzlinkd;
|
||||
productName = tzlinkd;
|
||||
productReference = FDBC26F01741B13400CA4B2B /* tzlinkd */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
BA79F99713BB70D7006A292D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0420;
|
||||
};
|
||||
buildConfigurationList = BA79F99A13BB70D7006A292D /* Build configuration list for PBXProject "libutil" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = BA79F99513BB70D7006A292D;
|
||||
productRefGroup = BA79F9C613BB718B006A292D /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
FDBC26E81741B09D00CA4B2B /* ios */,
|
||||
3EB206C51F5096F100B150D3 /* bridgeos */,
|
||||
FDBC26E41741B09300CA4B2B /* osx */,
|
||||
BA79F9C413BB718B006A292D /* util */,
|
||||
FDBC26EF1741B13400CA4B2B /* tzlinkd */,
|
||||
FDA4990F199D69B800A32E83 /* tests */,
|
||||
FDA49902199D69B000A32E83 /* humanize_number_test */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
BA79F9DA13BB750E006A292D /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(BUILT_PRODUCTS_DIR)/libutil1.0.dylib",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "set -e\nset -x\n\nln -sf ${EXECUTABLE_NAME} \"${BUILT_PRODUCTS_DIR}/libutil1.0.dylib\"\n";
|
||||
};
|
||||
BA79F9EB13BB7864006A292D /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 8;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DSTROOT)/$(INSTALL_PATH)/libutil1.0.dylib",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "set -e\nset -x\n\nln -sf ${EXECUTABLE_NAME} \"${DSTROOT}/${INSTALL_PATH}/libutil1.0.dylib\"\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
BA79F9C113BB718B006A292D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
BA79F9CB13BB7207006A292D /* ExtentManager.cpp in Sources */,
|
||||
BA79F9CC13BB7207006A292D /* getmntopts.c in Sources */,
|
||||
BA79F9CD13BB7207006A292D /* humanize_number.c in Sources */,
|
||||
BA79F9CE13BB7207006A292D /* pidfile.c in Sources */,
|
||||
BA79F9D013BB7207006A292D /* realhostname.c in Sources */,
|
||||
BA79F9D113BB7207006A292D /* reexec_to_match_kernel.c in Sources */,
|
||||
BA79F9D213BB7207006A292D /* trimdomain.c in Sources */,
|
||||
FDBC27071741B1D600CA4B2B /* tzlink.c in Sources */,
|
||||
BA79F9D413BB7207006A292D /* wipefs.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FDA498FF199D69B000A32E83 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FDA4991B199D6A0400A32E83 /* humanize_number_test.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FDBC26EC1741B13400CA4B2B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FDBC27061741B1CF00CA4B2B /* tzlinkd.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
3EB206C61F5096F100B150D3 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = BA79F9C413BB718B006A292D /* util */;
|
||||
targetProxy = 3EB206C71F5096F100B150D3 /* PBXContainerItemProxy */;
|
||||
};
|
||||
3EB206C81F5096F100B150D3 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = FDA4990F199D69B800A32E83 /* tests */;
|
||||
targetProxy = 3EB206C91F5096F100B150D3 /* PBXContainerItemProxy */;
|
||||
};
|
||||
3EB98B671E37CEFE0059EC72 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = FDBC26EF1741B13400CA4B2B /* tzlinkd */;
|
||||
targetProxy = 3EB98B661E37CEFE0059EC72 /* PBXContainerItemProxy */;
|
||||
};
|
||||
FDA49914199D69C100A32E83 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = FDA4990F199D69B800A32E83 /* tests */;
|
||||
targetProxy = FDA49913199D69C100A32E83 /* PBXContainerItemProxy */;
|
||||
};
|
||||
FDA49916199D69C600A32E83 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = FDA4990F199D69B800A32E83 /* tests */;
|
||||
targetProxy = FDA49915199D69C600A32E83 /* PBXContainerItemProxy */;
|
||||
};
|
||||
FDA49918199D69C800A32E83 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = FDA49902199D69B000A32E83 /* humanize_number_test */;
|
||||
targetProxy = FDA49917199D69C800A32E83 /* PBXContainerItemProxy */;
|
||||
};
|
||||
FDBC27001741B1B300CA4B2B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = BA79F9C413BB718B006A292D /* util */;
|
||||
targetProxy = FDBC26FF1741B1B300CA4B2B /* PBXContainerItemProxy */;
|
||||
};
|
||||
FDBC27021741B1B500CA4B2B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = BA79F9C413BB718B006A292D /* util */;
|
||||
targetProxy = FDBC27011741B1B500CA4B2B /* PBXContainerItemProxy */;
|
||||
};
|
||||
FDBC27041741B1B700CA4B2B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = FDBC26EF1741B13400CA4B2B /* tzlinkd */;
|
||||
targetProxy = FDBC27031741B1B700CA4B2B /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
3EB206CD1F5096F100B150D3 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3EB206CE1F5096F100B150D3 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
BA79F99C13BB70D7006A292D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3F09C378186D1F73007AF93C /* base.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLY_RULES_IN_COPY_FILES = YES;
|
||||
"PLIST_FILE_OUTPUT_FORMAT[sdk=iphoneos*]" = binary;
|
||||
"PLIST_FILE_OUTPUT_FORMAT[sdk=macosx*]" = XML;
|
||||
USE_HEADERMAP = NO;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
BA79F99D13BB70D7006A292D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3F09C378186D1F73007AF93C /* base.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLY_RULES_IN_COPY_FILES = YES;
|
||||
"PLIST_FILE_OUTPUT_FORMAT[sdk=iphoneos*]" = binary;
|
||||
"PLIST_FILE_OUTPUT_FORMAT[sdk=macosx*]" = XML;
|
||||
USE_HEADERMAP = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
BA79F9C813BB718B006A292D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3F7A5E8820510D34007087AF /* lib.xcconfig */;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
DYLIB_COMPATIBILITY_VERSION = 1.0;
|
||||
DYLIB_CURRENT_VERSION = 1.0;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
EXPORTED_SYMBOLS_FILE = libutil.exports;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = "$(SRCROOT)";
|
||||
INSTALL_PATH = /usr/lib;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_TEXT_BASED_API = YES;
|
||||
TAPI_VERIFY_MODE = Pedantic;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
BA79F9C913BB718B006A292D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3F7A5E8820510D34007087AF /* lib.xcconfig */;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
DYLIB_COMPATIBILITY_VERSION = 1.0;
|
||||
DYLIB_CURRENT_VERSION = 1.0;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
EXPORTED_SYMBOLS_FILE = libutil.exports;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = "$(SRCROOT)";
|
||||
INSTALL_PATH = /usr/lib;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_TEXT_BASED_API = YES;
|
||||
TAPI_VERIFY_MODE = Pedantic;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FDA4990C199D69B000A32E83 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FDA4991D199D6CB800A32E83 /* test.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FDA4990D199D69B000A32E83 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FDA4991D199D6CB800A32E83 /* test.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FDA49911199D69B800A32E83 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FDA49912199D69B800A32E83 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FDBC26E51741B09300CA4B2B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FDBC26E61741B09300CA4B2B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FDBC26EA1741B09D00CA4B2B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FDBC26EB1741B09D00CA4B2B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FDBC26F61741B13400CA4B2B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FDBC270D1741B66500CA4B2B /* tzlinkd.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FDBC26F71741B13400CA4B2B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FDBC270D1741B66500CA4B2B /* tzlinkd.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
3EB206CC1F5096F100B150D3 /* Build configuration list for PBXAggregateTarget "bridgeos" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3EB206CD1F5096F100B150D3 /* Debug */,
|
||||
3EB206CE1F5096F100B150D3 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
BA79F99A13BB70D7006A292D /* Build configuration list for PBXProject "libutil" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
BA79F99C13BB70D7006A292D /* Debug */,
|
||||
BA79F99D13BB70D7006A292D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
BA79F9C713BB718B006A292D /* Build configuration list for PBXNativeTarget "util" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
BA79F9C813BB718B006A292D /* Debug */,
|
||||
BA79F9C913BB718B006A292D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FDA4990E199D69B000A32E83 /* Build configuration list for PBXNativeTarget "humanize_number_test" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FDA4990C199D69B000A32E83 /* Debug */,
|
||||
FDA4990D199D69B000A32E83 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FDA49910199D69B800A32E83 /* Build configuration list for PBXAggregateTarget "tests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FDA49911199D69B800A32E83 /* Debug */,
|
||||
FDA49912199D69B800A32E83 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FDBC26E71741B09300CA4B2B /* Build configuration list for PBXAggregateTarget "osx" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FDBC26E51741B09300CA4B2B /* Debug */,
|
||||
FDBC26E61741B09300CA4B2B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FDBC26E91741B09D00CA4B2B /* Build configuration list for PBXAggregateTarget "ios" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FDBC26EA1741B09D00CA4B2B /* Debug */,
|
||||
FDBC26EB1741B09D00CA4B2B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FDBC26F81741B13400CA4B2B /* Build configuration list for PBXNativeTarget "tzlinkd" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FDBC26F61741B13400CA4B2B /* Debug */,
|
||||
FDBC26F71741B13400CA4B2B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = BA79F99713BB70D7006A292D /* Project object */;
|
||||
}
|
138
mntopts.h
Normal file
138
mntopts.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/* $NetBSD: mntopts.h,v 1.7 2006/02/12 01:32:06 chs Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* 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
|
||||
* 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. 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.
|
||||
*
|
||||
* @(#)mntopts.h 8.7 (Berkeley) 3/29/95
|
||||
*/
|
||||
#ifndef _MNTOPTS_H_
|
||||
#define _MNTOPTS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct mntopt {
|
||||
const char *m_option; /* option name */
|
||||
int m_inverse; /* if a negative option, eg "dev" */
|
||||
int m_flag; /* bit to set, eg. MNT_RDONLY */
|
||||
int m_altloc; /* 1 => set bit in altflags */
|
||||
};
|
||||
|
||||
/* User-visible MNT_ flags. */
|
||||
#define MOPT_ASYNC { "async", 0, MNT_ASYNC, 0 }
|
||||
#define MOPT_NODEV { "dev", 1, MNT_NODEV, 0 }
|
||||
#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC, 0 }
|
||||
#define MOPT_NOSUID { "suid", 1, MNT_NOSUID, 0 }
|
||||
#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY, 0 }
|
||||
#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS, 0 }
|
||||
#define MOPT_UNION { "union", 0, MNT_UNION, 0 }
|
||||
#define MOPT_USERQUOTA { "userquota", 0, 0, 0 }
|
||||
#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 }
|
||||
#define MOPT_BROWSE { "browse", 1, MNT_DONTBROWSE, 0 }
|
||||
#define MOPT_AUTOMOUNTED { "automounted",0, MNT_AUTOMOUNTED, 0 }
|
||||
#define MOPT_DEFWRITE { "defwrite", 0, MNT_DEFWRITE, 0}
|
||||
#define MOPT_NOATIME { "atime", 1, MNT_NOATIME, 0}
|
||||
#define MOPT_IGNORE_OWNERSHIP { "owners", 1, MNT_IGNORE_OWNERSHIP, 0}
|
||||
/* alias the deprecated name for compatibility */
|
||||
#define MOPT_PERMISSIONS { "perm", 1, MNT_IGNORE_OWNERSHIP, 0}
|
||||
#define MOPT_QUARANTINE { "quarantine", 0, MNT_QUARANTINE, 0}
|
||||
#define MOPT_CPROTECT { "protect", 0, MNT_CPROTECT, 0 }
|
||||
|
||||
/* Control flags. */
|
||||
#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 }
|
||||
#define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 }
|
||||
#define MOPT_RELOAD { "reload", 0, MNT_RELOAD, 0 }
|
||||
|
||||
/* Support for old-style "ro", "rw" flags. */
|
||||
#define MOPT_RO { "ro", 0, MNT_RDONLY, 0 }
|
||||
#define MOPT_RW { "rw", 1, MNT_RDONLY, 0 }
|
||||
|
||||
/* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
|
||||
#define MOPT_AUTO { "auto", 0, 0, 0 }
|
||||
|
||||
#define MOPT_FSTAB_COMPAT \
|
||||
MOPT_RO, \
|
||||
MOPT_RW, \
|
||||
MOPT_AUTO
|
||||
|
||||
/* Standard options which all mounts can understand. */
|
||||
#define MOPT_STDOPTS \
|
||||
MOPT_USERQUOTA, \
|
||||
MOPT_GROUPQUOTA, \
|
||||
MOPT_FSTAB_COMPAT, \
|
||||
MOPT_NODEV, \
|
||||
MOPT_NOEXEC, \
|
||||
MOPT_NOSUID, \
|
||||
MOPT_RDONLY, \
|
||||
MOPT_UNION, \
|
||||
MOPT_BROWSE, \
|
||||
MOPT_AUTOMOUNTED, \
|
||||
MOPT_DEFWRITE, \
|
||||
MOPT_NOATIME, \
|
||||
MOPT_PERMISSIONS, \
|
||||
MOPT_IGNORE_OWNERSHIP, \
|
||||
MOPT_QUARANTINE, \
|
||||
MOPT_CPROTECT
|
||||
|
||||
typedef struct mntoptparse *mntoptparse_t;
|
||||
mntoptparse_t getmntopts(const char *, const struct mntopt *, int *, int *);
|
||||
const char *getmntoptstr(mntoptparse_t, const char *);
|
||||
long getmntoptnum(mntoptparse_t, const char *);
|
||||
void freemntopts(mntoptparse_t);
|
||||
|
||||
extern int getmnt_silent;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MNTOPTS_H_ */
|
249
pidfile.3
Normal file
249
pidfile.3
Normal file
@ -0,0 +1,249 @@
|
||||
.\" Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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.
|
||||
.\"
|
||||
.\" $FreeBSD: src/lib/libutil/pidfile.3,v 1.5 2006/03/04 15:20:28 keramida Exp $
|
||||
.\"
|
||||
.Dd August 22, 2005
|
||||
.Dt PIDFILE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pidfile_open ,
|
||||
.Nm pidfile_write ,
|
||||
.Nm pidfile_close ,
|
||||
.Nm pidfile_remove
|
||||
.Nd "library for PID files handling"
|
||||
.Sh LIBRARY
|
||||
.Lb libutil
|
||||
.Sh SYNOPSIS
|
||||
.In sys/param.h
|
||||
.In libutil.h
|
||||
.Ft "struct pidfh *"
|
||||
.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr"
|
||||
.Ft int
|
||||
.Fn pidfile_write "struct pidfh *pfh"
|
||||
.Ft int
|
||||
.Fn pidfile_close "struct pidfh *pfh"
|
||||
.Ft int
|
||||
.Fn pidfile_remove "struct pidfh *pfh"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm pidfile
|
||||
family of functions allows daemons to handle PID files.
|
||||
It uses
|
||||
.Xr flock 2
|
||||
to lock a pidfile and detect already running daemons.
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_open
|
||||
function opens (or creates) a file specified by the
|
||||
.Fa path
|
||||
argument and locks it with the
|
||||
.Xr flock 2
|
||||
system call.
|
||||
If a file can not be locked, a PID of an already running daemon is returned in
|
||||
the
|
||||
.Fa pidptr
|
||||
argument (if it is not
|
||||
.Dv NULL ) .
|
||||
The function does not write process' PID into the file here, so it can be
|
||||
used before
|
||||
.Fn fork Ns ing
|
||||
and exit with a proper error message when needed.
|
||||
If the
|
||||
.Fa path
|
||||
argument is
|
||||
.Dv NULL ,
|
||||
.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid
|
||||
file will be used.
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_write
|
||||
function writes process' PID into a previously opened file.
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_close
|
||||
function closes a pidfile.
|
||||
It should be used after daemon
|
||||
.Fn fork Ns s
|
||||
to start a child process.
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_remove
|
||||
function closes and removes a pidfile.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn pidfile_open
|
||||
function returns a valid pointer to a
|
||||
.Vt pidfh
|
||||
structure on success, or
|
||||
.Dv NULL
|
||||
if an error occurs.
|
||||
If an error occurs,
|
||||
.Va errno
|
||||
will be set.
|
||||
.Rv -std pidfile_write pidfile_close pidfile_remove
|
||||
.Sh EXAMPLES
|
||||
The following example shows in which order these functions should be used.
|
||||
Note that it is safe to pass
|
||||
.Dv NULL
|
||||
to
|
||||
.Fn pidfile_write ,
|
||||
.Fn pidfile_remove
|
||||
and
|
||||
.Fn pidfile_close
|
||||
functions.
|
||||
.Bd -literal
|
||||
struct pidfh *pfh;
|
||||
pid_t otherpid, childpid;
|
||||
|
||||
pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid);
|
||||
if (pfh == NULL) {
|
||||
if (errno == EEXIST) {
|
||||
errx(EXIT_FAILURE, "Daemon already running, pid: %jd.",
|
||||
(intmax_t)otherpid);
|
||||
}
|
||||
/* If we cannot create pidfile from other reasons, only warn. */
|
||||
warn("Cannot open or create pidfile");
|
||||
}
|
||||
|
||||
if (daemon(0, 0) == -1) {
|
||||
warn("Cannot daemonize");
|
||||
pidfile_remove(pfh);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pidfile_write(pfh);
|
||||
|
||||
for (;;) {
|
||||
/* Do work. */
|
||||
childpid = fork();
|
||||
switch (childpid) {
|
||||
case -1:
|
||||
syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
|
||||
break;
|
||||
case 0:
|
||||
pidfile_close(pfh);
|
||||
/* Do child work. */
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pidfile_remove(pfh);
|
||||
exit(EXIT_SUCCESS);
|
||||
.Ed
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn pidfile_open
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EEXIST
|
||||
Some process already holds the lock on the given pidfile, meaning that a
|
||||
daemon is already running.
|
||||
.It Bq Er ENAMETOOLONG
|
||||
Specified pidfile's name is too long.
|
||||
.It Bq Er EINVAL
|
||||
Some process already holds the lock on the given pidfile, but PID read
|
||||
from there is invalid.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_open
|
||||
function may also fail and set
|
||||
.Va errno
|
||||
for any errors specified for the
|
||||
.Xr fstat 2 ,
|
||||
.Xr open 2 ,
|
||||
and
|
||||
.Xr read 2
|
||||
calls.
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_write
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EDOOFUS
|
||||
Improper function use.
|
||||
Probably called before
|
||||
.Fn pidfile_open .
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_write
|
||||
function may also fail and set
|
||||
.Va errno
|
||||
for any errors specified for the
|
||||
.Xr fstat 2 ,
|
||||
.Xr ftruncate 2 ,
|
||||
and
|
||||
.Xr write 2
|
||||
calls.
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_close
|
||||
function may fail and set
|
||||
.Va errno
|
||||
for any errors specified for the
|
||||
.Xr close 2
|
||||
and
|
||||
.Xr fstat 2
|
||||
calls.
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_remove
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EDOOFUS
|
||||
Improper function use.
|
||||
Probably called not from the process which made
|
||||
.Fn pidfile_write .
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn pidfile_remove
|
||||
function may also fail and set
|
||||
.Va errno
|
||||
for any errors specified for the
|
||||
.Xr close 2 ,
|
||||
.Xr flock 2 ,
|
||||
.Xr fstat 2 ,
|
||||
.Xr write 2 ,
|
||||
and
|
||||
.Xr unlink 2
|
||||
calls.
|
||||
.Sh SEE ALSO
|
||||
.Xr flock 2 ,
|
||||
.Xr open 2 ,
|
||||
.Xr daemon 3
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm pidfile
|
||||
functionality is based on ideas from
|
||||
.An John-Mark Gurney Aq jmg@FreeBSD.org .
|
||||
.Pp
|
||||
The code and manual page was written by
|
||||
.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org .
|
243
pidfile.c
Normal file
243
pidfile.c
Normal file
@ -0,0 +1,243 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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/cdefs.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <libutil.h>
|
||||
|
||||
static int _pidfile_remove(struct pidfh *pfh, int freeit);
|
||||
|
||||
static int
|
||||
pidfile_verify(struct pidfh *pfh)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (pfh == NULL || pfh->pf_fd == -1)
|
||||
return EINVAL;
|
||||
/*
|
||||
* Check remembered descriptor.
|
||||
*/
|
||||
if (fstat(pfh->pf_fd, &sb) == -1)
|
||||
return (errno);
|
||||
if (sb.st_dev != pfh->pf_dev || sb.st_ino != pfh->pf_ino)
|
||||
return EINVAL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pidfile_read(const char *path, pid_t *pidptr)
|
||||
{
|
||||
char buf[16], *endptr;
|
||||
int error, fd, i;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return (errno);
|
||||
|
||||
i = read(fd, buf, sizeof(buf) - 1);
|
||||
error = errno; /* Remember errno in case close() wants to change it. */
|
||||
close(fd);
|
||||
if (i == -1)
|
||||
return (error);
|
||||
buf[i] = '\0';
|
||||
|
||||
*pidptr = strtol(buf, &endptr, 10);
|
||||
if (endptr != &buf[i])
|
||||
return (EINVAL);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct pidfh *
|
||||
pidfile_open(const char *path, mode_t mode, pid_t *pidptr)
|
||||
{
|
||||
struct pidfh *pfh;
|
||||
struct stat sb;
|
||||
int error, fd;
|
||||
|
||||
pfh = malloc(sizeof(*pfh));
|
||||
if (pfh == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (path == NULL) {
|
||||
snprintf(pfh->pf_path, sizeof(pfh->pf_path), "/var/run/%s.pid",
|
||||
getprogname());
|
||||
} else {
|
||||
strlcpy(pfh->pf_path, path, sizeof(pfh->pf_path));
|
||||
}
|
||||
if (strlen(pfh->pf_path) == sizeof(pfh->pf_path) - 1) {
|
||||
free(pfh);
|
||||
errno = ENAMETOOLONG;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the PID file and obtain exclusive lock.
|
||||
* We truncate PID file here only to remove old PID immediatelly,
|
||||
* PID file will be truncated again in pidfile_write(), so
|
||||
* pidfile_write() can be called multiple times.
|
||||
*/
|
||||
fd = open(pfh->pf_path,
|
||||
O_WRONLY | O_CREAT | O_EXLOCK | O_TRUNC | O_NONBLOCK, mode);
|
||||
if (fd == -1) {
|
||||
if (errno == EWOULDBLOCK && pidptr != NULL) {
|
||||
errno = pidfile_read(pfh->pf_path, pidptr);
|
||||
if (errno == 0)
|
||||
errno = EEXIST;
|
||||
}
|
||||
free(pfh);
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Remember file information, so in pidfile_write() we are sure we write
|
||||
* to the proper descriptor.
|
||||
*/
|
||||
if (fstat(fd, &sb) == -1) {
|
||||
error = errno;
|
||||
unlink(pfh->pf_path);
|
||||
close(fd);
|
||||
free(pfh);
|
||||
errno = error;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
pfh->pf_fd = fd;
|
||||
pfh->pf_dev = sb.st_dev;
|
||||
pfh->pf_ino = sb.st_ino;
|
||||
|
||||
return (pfh);
|
||||
}
|
||||
|
||||
int
|
||||
pidfile_write(struct pidfh *pfh)
|
||||
{
|
||||
char pidstr[16];
|
||||
int error, fd;
|
||||
|
||||
/*
|
||||
* Check remembered descriptor, so we don't overwrite some other
|
||||
* file if pidfile was closed and descriptor reused.
|
||||
*/
|
||||
errno = pidfile_verify(pfh);
|
||||
if (errno != 0) {
|
||||
/*
|
||||
* Don't close descriptor, because we are not sure if it's ours.
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
fd = pfh->pf_fd;
|
||||
|
||||
/*
|
||||
* Truncate PID file, so multiple calls of pidfile_write() are allowed.
|
||||
*/
|
||||
if (ftruncate(fd, 0) == -1) {
|
||||
error = errno;
|
||||
_pidfile_remove(pfh, 0);
|
||||
errno = error;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
snprintf(pidstr, sizeof(pidstr), "%u", getpid());
|
||||
if (pwrite(fd, pidstr, strlen(pidstr), 0) != (ssize_t)strlen(pidstr)) {
|
||||
error = errno;
|
||||
_pidfile_remove(pfh, 0);
|
||||
errno = error;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pidfile_close(struct pidfh *pfh)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = pidfile_verify(pfh);
|
||||
if (error != 0) {
|
||||
errno = error;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (close(pfh->pf_fd) == -1)
|
||||
error = errno;
|
||||
free(pfh);
|
||||
if (error != 0) {
|
||||
errno = error;
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
_pidfile_remove(struct pidfh *pfh, int freeit)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = pidfile_verify(pfh);
|
||||
if (error != 0) {
|
||||
errno = error;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (unlink(pfh->pf_path) == -1)
|
||||
error = errno;
|
||||
if (flock(pfh->pf_fd, LOCK_UN) == -1) {
|
||||
if (error == 0)
|
||||
error = errno;
|
||||
}
|
||||
if (close(pfh->pf_fd) == -1) {
|
||||
if (error == 0)
|
||||
error = errno;
|
||||
}
|
||||
if (freeit)
|
||||
free(pfh);
|
||||
else
|
||||
pfh->pf_fd = -1;
|
||||
if (error != 0) {
|
||||
errno = error;
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pidfile_remove(struct pidfh *pfh)
|
||||
{
|
||||
|
||||
return (_pidfile_remove(pfh, 1));
|
||||
}
|
105
realhostname.3
Normal file
105
realhostname.3
Normal file
@ -0,0 +1,105 @@
|
||||
.\" Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
.\"
|
||||
.\" $FreeBSD: src/lib/libutil/realhostname.3,v 1.10 2005/02/13 22:25:14 ru Exp $
|
||||
.\"
|
||||
.Dd April 6, 1999
|
||||
.Os
|
||||
.Dt REALHOSTNAME 3
|
||||
.Sh NAME
|
||||
.Nm realhostname
|
||||
.Nd "convert an IP number to the real host name"
|
||||
.Sh LIBRARY
|
||||
.Lb libutil
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In netinet/in.h
|
||||
.In libutil.h
|
||||
.Ft int
|
||||
.Fn realhostname "char *host" "size_t hsize" "const struct in_addr *ip"
|
||||
.Sh DESCRIPTION
|
||||
The function
|
||||
.Fn realhostname
|
||||
converts
|
||||
.Ar ip
|
||||
to the corresponding host name.
|
||||
This is done by resolving
|
||||
.Ar ip
|
||||
to a host name and then ensuring that the host name resolves
|
||||
back to
|
||||
.Ar ip .
|
||||
.Pp
|
||||
.Ar host
|
||||
must point to a buffer of at least
|
||||
.Ar hsize
|
||||
bytes, and will always be written to by this function.
|
||||
.Pp
|
||||
If the name resolution does not work both ways or if the host name is longer
|
||||
than
|
||||
.Ar hsize
|
||||
bytes,
|
||||
.Xr inet_ntoa 3
|
||||
is used to convert
|
||||
.Ar ip
|
||||
to an ASCII form.
|
||||
.Pp
|
||||
If the string written to
|
||||
.Ar host
|
||||
is
|
||||
.Ar hsize
|
||||
bytes long,
|
||||
.Ar host
|
||||
will not be NUL terminated.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn realhostname
|
||||
function will return one of the following constants which are defined in
|
||||
.In libutil.h :
|
||||
.Pp
|
||||
.Bl -tag -width XXX -offset XXX
|
||||
.It Li HOSTNAME_FOUND
|
||||
A valid host name was found.
|
||||
.It Li HOSTNAME_INCORRECTNAME
|
||||
A host name was found, but it did not resolve back to the passed
|
||||
.Ar ip .
|
||||
.Ar host
|
||||
now contains the numeric value of
|
||||
.Ar ip .
|
||||
.It Li HOSTNAME_INVALIDADDR
|
||||
.Ar ip
|
||||
could not be resolved.
|
||||
.Ar host
|
||||
now contains the numeric value of
|
||||
.Ar ip .
|
||||
.It Li HOSTNAME_INVALIDNAME
|
||||
A host name was found, but it could not be resolved back to any ip number.
|
||||
.Ar host
|
||||
now contains the numeric value of
|
||||
.Ar ip .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr gethostbyaddr 3 ,
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr inet_ntoa 3 ,
|
||||
.Xr realhostname_sa 3
|
186
realhostname.c
Normal file
186
realhostname.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/cdefs.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libutil.h"
|
||||
|
||||
struct sockinet {
|
||||
u_char si_len;
|
||||
u_char si_family;
|
||||
u_short si_port;
|
||||
};
|
||||
|
||||
void trimdomain(char *_fullhost, size_t _hostsize);
|
||||
|
||||
int
|
||||
realhostname(char *host, size_t hsize, const struct in_addr *ip)
|
||||
{
|
||||
char trimmed[MAXHOSTNAMELEN];
|
||||
int result;
|
||||
struct hostent *hp;
|
||||
|
||||
result = HOSTNAME_INVALIDADDR;
|
||||
hp = gethostbyaddr((const char *)ip, sizeof(*ip), AF_INET);
|
||||
|
||||
if (hp != NULL) {
|
||||
strlcpy(trimmed, hp->h_name, sizeof(trimmed));
|
||||
trimdomain(trimmed, strlen(trimmed));
|
||||
if (strlen(trimmed) <= hsize) {
|
||||
char lookup[MAXHOSTNAMELEN];
|
||||
|
||||
strncpy(lookup, hp->h_name, sizeof(lookup) - 1);
|
||||
lookup[sizeof(lookup) - 1] = '\0';
|
||||
hp = gethostbyname(lookup);
|
||||
if (hp == NULL)
|
||||
result = HOSTNAME_INVALIDNAME;
|
||||
else for (; ; hp->h_addr_list++) {
|
||||
if (*hp->h_addr_list == NULL) {
|
||||
result = HOSTNAME_INCORRECTNAME;
|
||||
break;
|
||||
}
|
||||
if (!memcmp(*hp->h_addr_list, ip, sizeof(*ip))) {
|
||||
strncpy(host, trimmed, hsize);
|
||||
return HOSTNAME_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(host, inet_ntoa(*ip), hsize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
realhostname_sa(char *host, size_t hsize, struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
int result, error;
|
||||
char buf[NI_MAXHOST];
|
||||
|
||||
result = HOSTNAME_INVALIDADDR;
|
||||
|
||||
#ifdef INET6
|
||||
/* IPv4 mapped IPv6 addr consideraton, specified in rfc2373. */
|
||||
if (addr->sa_family == AF_INET6 &&
|
||||
addrlen == sizeof(struct sockaddr_in6) &&
|
||||
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)addr)->sin6_addr)) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)addr;
|
||||
|
||||
memset(&lsin, 0, sizeof(lsin));
|
||||
lsin.sin_len = sizeof(struct sockaddr_in);
|
||||
lsin.sin_family = AF_INET;
|
||||
lsin.sin_port = sin6->sin6_port;
|
||||
memcpy(&lsin.sin_addr, &sin6->sin6_addr.s6_addr[12],
|
||||
sizeof(struct in_addr));
|
||||
addr = (struct sockaddr *)&lsin;
|
||||
addrlen = lsin.sin_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
if (error == 0) {
|
||||
struct addrinfo hints, *res, *ores;
|
||||
struct sockaddr *sa;
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = addr->sa_family;
|
||||
hints.ai_flags = AI_CANONNAME | AI_PASSIVE;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
error = getaddrinfo(buf, NULL, &hints, &res);
|
||||
if (error) {
|
||||
result = HOSTNAME_INVALIDNAME;
|
||||
goto numeric;
|
||||
}
|
||||
for (ores = res; ; res = res->ai_next) {
|
||||
if (res == NULL) {
|
||||
freeaddrinfo(ores);
|
||||
result = HOSTNAME_INCORRECTNAME;
|
||||
goto numeric;
|
||||
}
|
||||
sa = res->ai_addr;
|
||||
if (sa == NULL) {
|
||||
freeaddrinfo(ores);
|
||||
result = HOSTNAME_INCORRECTNAME;
|
||||
goto numeric;
|
||||
}
|
||||
if (sa->sa_len == addrlen &&
|
||||
sa->sa_family == addr->sa_family) {
|
||||
((struct sockinet *)sa)->si_port = ((struct sockinet *)addr)->si_port;
|
||||
#ifdef INET6
|
||||
/*
|
||||
* XXX: sin6_socpe_id may not been
|
||||
* filled by DNS
|
||||
*/
|
||||
if (sa->sa_family == AF_INET6 &&
|
||||
((struct sockaddr_in6 *)sa)->sin6_scope_id == 0)
|
||||
((struct sockaddr_in6 *)sa)->sin6_scope_id = ((struct sockaddr_in6 *)addr)->sin6_scope_id;
|
||||
#endif
|
||||
if (!memcmp(sa, addr, sa->sa_len)) {
|
||||
result = HOSTNAME_FOUND;
|
||||
if (ores->ai_canonname == NULL) {
|
||||
freeaddrinfo(ores);
|
||||
goto numeric;
|
||||
}
|
||||
strlcpy(buf, ores->ai_canonname,
|
||||
sizeof(buf));
|
||||
trimdomain(buf, hsize);
|
||||
if (strlen(buf) > hsize &&
|
||||
addr->sa_family == AF_INET) {
|
||||
freeaddrinfo(ores);
|
||||
goto numeric;
|
||||
}
|
||||
strncpy(host, buf, hsize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
freeaddrinfo(ores);
|
||||
} else {
|
||||
numeric:
|
||||
if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
|
||||
NI_NUMERICHOST) == 0)
|
||||
strncpy(host, buf, hsize);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
133
realhostname_sa.3
Normal file
133
realhostname_sa.3
Normal file
@ -0,0 +1,133 @@
|
||||
.\" Copyright (C) 1995, 1996, 1997, 1998, 1999, and 2000 WIDE Project.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
.\"
|
||||
.\" $FreeBSD: src/lib/libutil/realhostname_sa.3,v 1.11 2005/02/13 22:25:14 ru Exp $
|
||||
.\"
|
||||
.Dd January 11, 2000
|
||||
.Os
|
||||
.Dt REALHOSTNAME_SA 3
|
||||
.Sh NAME
|
||||
.Nm realhostname_sa
|
||||
.Nd "convert a"
|
||||
.Vt "struct sockaddr"
|
||||
to the real host name
|
||||
.Sh LIBRARY
|
||||
.Lb libutil
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In netinet/in.h
|
||||
.In libutil.h
|
||||
.Ft int
|
||||
.Fn realhostname_sa "char *host" "size_t hsize" "struct sockaddr *addr" "int addrlen"
|
||||
.Sh DESCRIPTION
|
||||
The function
|
||||
.Fn realhostname_sa
|
||||
converts
|
||||
.Ar addr
|
||||
to the corresponding host name.
|
||||
This is done by resolving
|
||||
.Ar addr
|
||||
to a host name and then ensuring that the host name resolves
|
||||
back to
|
||||
.Ar addr .
|
||||
.Pp
|
||||
.Ar host
|
||||
must point to a buffer of at least
|
||||
.Ar hsize
|
||||
bytes, and will always be written to by this function.
|
||||
.Pp
|
||||
If the name resolution does not work both ways or if the host name is longer
|
||||
than
|
||||
.Ar hsize
|
||||
bytes,
|
||||
.Xr getnameinfo 3
|
||||
with NI_NUMERICHOST specified, is used to convert
|
||||
.Ar addr
|
||||
to an ASCII form.
|
||||
.Pp
|
||||
If the string written to
|
||||
.Ar host
|
||||
is
|
||||
.Ar hsize
|
||||
bytes long,
|
||||
.Ar host
|
||||
will not be NUL terminated.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn realhostname_sa
|
||||
function will return one of the following constants which are defined in
|
||||
.In libutil.h :
|
||||
.Pp
|
||||
.Bl -tag -width XXX -offset XXX
|
||||
.It Li HOSTNAME_FOUND
|
||||
A valid host name was found.
|
||||
.It Li HOSTNAME_INCORRECTNAME
|
||||
A host name was found, but it did not resolve back to the passed
|
||||
.Ar ip .
|
||||
.Ar host
|
||||
now contains the numeric value of
|
||||
.Ar ip .
|
||||
.It Li HOSTNAME_INVALIDADDR
|
||||
.Ar ip
|
||||
could not be resolved.
|
||||
.Ar host
|
||||
now contains the numeric value of
|
||||
.Ar ip .
|
||||
.It Li HOSTNAME_INVALIDNAME
|
||||
A host name was found, but it could not be resolved back to any ip number.
|
||||
.Ar host
|
||||
now contains the numeric value of
|
||||
.Ar ip .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr getaddrinfo 3 ,
|
||||
.Xr getnameinfo 3 ,
|
||||
.Xr realhostname 3
|
50
reexec_to_match_kernel.3
Normal file
50
reexec_to_match_kernel.3
Normal file
@ -0,0 +1,50 @@
|
||||
.Dd Apr 14, 2008
|
||||
.Dt REEXEC_TO_MATCH_KERNEL 3
|
||||
.Os "Mac OS X"
|
||||
.Sh NAME
|
||||
.Nm reexec_to_match_kernel
|
||||
.Nd Re-exec the current binary to match the ABI of the running kernel
|
||||
.Sh LIBRARY
|
||||
.Lb libutil
|
||||
.Sh SYNOPSIS
|
||||
.In libutil.h
|
||||
.Ft int
|
||||
.Fo reexec_to_match_kernel
|
||||
.Fa "void"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo reexec_to_match_lp64ness
|
||||
.Fa "bool isLP64"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn reexec_to_match_kernel
|
||||
function re-executes the current binary to match the ABI of the running kernel.
|
||||
That is, if the current kernel is a 64-bit Intel kernel, it will attempt to
|
||||
execute the 64-bit x86_64 userspace slice of the universal binary. The API
|
||||
intentionally does not take arguments because its use should be transparent
|
||||
to the program and to the user.
|
||||
.Pp
|
||||
The
|
||||
.Fn reexec_to_match_lp64ness
|
||||
is coarser-grained, and only attempts to match the word width that is requested.
|
||||
For example, if the current system defaults to executing the 64-bit x86_64
|
||||
userspace slice, but the program should instead run in 32-bit i386 mode,
|
||||
this routine can be used.
|
||||
.Pp
|
||||
Both
|
||||
.Fn reexec_to_match_kernel
|
||||
and
|
||||
.Fn reexec_to_match_lp64ness
|
||||
can each be used exactly once in a program's lifetime. In certain circumstances,
|
||||
it may even be desirable to use one, and then the other.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn reexec_to_match_kernel
|
||||
and
|
||||
.Fn reexec_to_match_lp64ness
|
||||
functions return 0 if re-execution was not required. It returns -1 and
|
||||
sets errno if there was an error performing the re-execution, for example
|
||||
if the binary is not universal, or does not contain a slice to match the running
|
||||
kernel's ABI. If the function succeeds, control never returns to the caller
|
||||
and the program starts from main() again.
|
222
reexec_to_match_kernel.c
Normal file
222
reexec_to_match_kernel.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <spawn.h>
|
||||
#include <errno.h>
|
||||
#include <crt_externs.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libutil.h"
|
||||
|
||||
static cpu_type_t current_program_arch(void);
|
||||
static cpu_type_t current_kernel_arch(void);
|
||||
static int reexec(cpu_type_t cputype, const char *guardenv);
|
||||
|
||||
#define kReExecToMatchKernel "REEXEC_TO_MATCH_KERNEL"
|
||||
#define kReExecToMatchLP64 "REEXEC_TO_MATCH_LP64NESS"
|
||||
|
||||
int reexec_to_match_kernel(void)
|
||||
{
|
||||
cpu_type_t kernarch, progarch;
|
||||
char *alreadyenv;
|
||||
|
||||
alreadyenv = getenv(kReExecToMatchKernel);
|
||||
if (alreadyenv) {
|
||||
/* we've done this at least once, assume
|
||||
another try won't help */
|
||||
return 0;
|
||||
}
|
||||
|
||||
kernarch = current_kernel_arch();
|
||||
progarch = current_program_arch();
|
||||
|
||||
if (kernarch == 0) {
|
||||
/* could not determine kernel arch */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (kernarch == progarch) {
|
||||
/* nothing to do here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now we need to re-exec */
|
||||
return reexec(kernarch, kReExecToMatchKernel);
|
||||
}
|
||||
|
||||
int reexec_to_match_lp64ness(bool isLP64)
|
||||
{
|
||||
cpu_type_t kernarch, progarch, targetarch;
|
||||
char *alreadyenv;
|
||||
|
||||
alreadyenv = getenv(kReExecToMatchLP64);
|
||||
if (alreadyenv) {
|
||||
/* we've done this at least once, assume
|
||||
another try won't help */
|
||||
return 0;
|
||||
}
|
||||
|
||||
progarch = current_program_arch();
|
||||
|
||||
/* Check if the program is already the correct lp64ness */
|
||||
if((!isLP64 && 0 == (progarch & CPU_ARCH_ABI64)) ||
|
||||
(isLP64 && 0 != (progarch & CPU_ARCH_ABI64))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
kernarch = current_kernel_arch();
|
||||
|
||||
if (kernarch == 0) {
|
||||
/* could not determine kernel arch */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (isLP64) {
|
||||
targetarch = kernarch | CPU_ARCH_ABI64;
|
||||
} else {
|
||||
targetarch = kernarch & ~CPU_ARCH_ABI64;
|
||||
}
|
||||
|
||||
if (targetarch == progarch) {
|
||||
/* nothing to do here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now we need to re-exec */
|
||||
return reexec(targetarch, kReExecToMatchLP64);
|
||||
}
|
||||
|
||||
static cpu_type_t current_program_arch(void)
|
||||
{
|
||||
cpu_type_t current_arch = (_NSGetMachExecuteHeader())->cputype;
|
||||
|
||||
return current_arch;
|
||||
}
|
||||
|
||||
static cpu_type_t current_kernel_arch(void)
|
||||
{
|
||||
struct host_basic_info hi;
|
||||
unsigned int size;
|
||||
kern_return_t kret;
|
||||
cpu_type_t current_arch;
|
||||
int ret, mib[4];
|
||||
size_t len;
|
||||
struct kinfo_proc kp;
|
||||
|
||||
size = sizeof(hi)/sizeof(int);
|
||||
kret = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hi, &size);
|
||||
if (kret != KERN_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
current_arch = hi.cpu_type;
|
||||
|
||||
/* Now determine if the kernel is running in 64-bit mode */
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PID;
|
||||
mib[3] = 0; /* kernproc, pid 0 */
|
||||
len = sizeof(kp);
|
||||
ret = sysctl(mib, sizeof(mib)/sizeof(mib[0]), &kp, &len, NULL, 0);
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (kp.kp_proc.p_flag & P_LP64) {
|
||||
current_arch |= CPU_ARCH_ABI64;
|
||||
}
|
||||
|
||||
return current_arch;
|
||||
}
|
||||
|
||||
static int reexec(cpu_type_t cputype, const char *guardenv)
|
||||
{
|
||||
posix_spawnattr_t attr;
|
||||
int ret, envcount;
|
||||
size_t copied = 0;
|
||||
char **argv, **oldenvp, **newenvp;
|
||||
char execpath[MAXPATHLEN+1];
|
||||
uint32_t execsize;
|
||||
char guardstr[32];
|
||||
|
||||
argv = *_NSGetArgv();
|
||||
oldenvp = *_NSGetEnviron();
|
||||
for (envcount = 0; oldenvp[envcount]; envcount++);
|
||||
// if there are 4 elements and a NULL, envcount will be 4
|
||||
|
||||
newenvp = calloc(envcount+2, sizeof(newenvp[0]));
|
||||
for (envcount = 0; oldenvp[envcount]; envcount++) {
|
||||
newenvp[envcount] = oldenvp[envcount];
|
||||
}
|
||||
|
||||
snprintf(guardstr, sizeof(guardstr), "%s=1", guardenv);
|
||||
newenvp[envcount++] = guardstr;
|
||||
newenvp[envcount] = NULL;
|
||||
|
||||
execsize = (uint32_t)sizeof(execpath);
|
||||
ret = _NSGetExecutablePath(execpath, &execsize);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = posix_spawnattr_init(&attr);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETEXEC);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
ret = posix_spawnattr_setbinpref_np(&attr, 1, &cputype, &copied);
|
||||
if (ret != 0 || copied != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "reexec: %s (arch=%d)\n", execpath, cputype);
|
||||
for (envcount=0; newenvp[envcount]; envcount++) {
|
||||
fprintf(stderr, "env[%d] = %s\n", envcount, newenvp[envcount]);
|
||||
}
|
||||
for (envcount=0; argv[envcount]; envcount++) {
|
||||
fprintf(stderr, "argv[%d] = %s\n", envcount, argv[envcount]);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = posix_spawn(NULL, execpath, NULL, &attr, argv, newenvp);
|
||||
if (ret != 0) {
|
||||
errno = ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* should not be reached */
|
||||
return 0;
|
||||
}
|
85
trimdomain.3
Normal file
85
trimdomain.3
Normal file
@ -0,0 +1,85 @@
|
||||
.\" Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
.\"
|
||||
.\" $FreeBSD: src/lib/libutil/trimdomain.3,v 1.8 2004/07/02 23:52:20 ru Exp $
|
||||
.\"
|
||||
.Dd April 7, 1999
|
||||
.Os
|
||||
.Dt TRIMDOMAIN 3
|
||||
.Sh NAME
|
||||
.Nm trimdomain
|
||||
.Nd "trim the current domain name from a host name"
|
||||
.Sh LIBRARY
|
||||
.Lb libutil
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In libutil.h
|
||||
.Ft void
|
||||
.Fn trimdomain "char *fullhost" "int hostsize"
|
||||
.Sh DESCRIPTION
|
||||
The function
|
||||
.Fn trimdomain
|
||||
removes the current domain name from the passed
|
||||
.Ar fullhost
|
||||
name by writing a
|
||||
.Dv NUL
|
||||
character over the first period of the passed name.
|
||||
The current domain
|
||||
name is determined by calling
|
||||
.Xr gethostname 3
|
||||
and removing everything up to the first period.
|
||||
The name is determined
|
||||
the first time this function is called and is cached for future use.
|
||||
.Pp
|
||||
The
|
||||
.Fn trimdomain
|
||||
function will only trim the domain name if the passed
|
||||
.Ar fullname
|
||||
ends with the current domain name and if the length of the resulting host
|
||||
name does not exceed
|
||||
.Ar hostsize .
|
||||
.Pp
|
||||
If the passed
|
||||
.Ar fullname
|
||||
is actually a
|
||||
.Dv DISPLAY
|
||||
specification of the form
|
||||
.Sm off
|
||||
.Ar host . domain : nn Oo .
|
||||
.Ar nn
|
||||
.Oc
|
||||
.Sm on
|
||||
and the domain name is the same as the local domain name,
|
||||
.Fn trimdomain
|
||||
will remove the embedded domain name, copying the screen and display
|
||||
numbers to the end of the base host name and resulting in
|
||||
.Sm off
|
||||
.Ar host : nn Op . Ar nn .
|
||||
.Sm on
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn trimdomain
|
||||
function does not return a value.
|
||||
.Sh SEE ALSO
|
||||
.Xr gethostname 3
|
116
trimdomain.c
Normal file
116
trimdomain.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
|
||||
* Based on original work by Atsushi Murai <amurai@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/cdefs.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <libutil.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void trimdomain(char *_fullhost, size_t _hostsize);
|
||||
|
||||
static int isDISP(const char *);
|
||||
|
||||
/*-
|
||||
* Trim the current domain name from fullhost, but only if the result
|
||||
* is less than or equal to hostsize in length.
|
||||
*
|
||||
* This function understands $DISPLAY type fullhosts.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* trimdomain("abcde.my.domain", 5) -> "abcde"
|
||||
* trimdomain("abcde.my.domain", 4) -> "abcde.my.domain"
|
||||
* trimdomain("abcde.my.domain:0.0", 9) -> "abcde:0.0"
|
||||
* trimdomain("abcde.my.domain:0.0", 8) -> "abcde.my.domain:0.0"
|
||||
*/
|
||||
void
|
||||
trimdomain(char *fullhost, size_t hostsize)
|
||||
{
|
||||
static size_t dlen;
|
||||
static int first = 1;
|
||||
static char domain[MAXHOSTNAMELEN];
|
||||
char *end, *s;
|
||||
size_t len;
|
||||
|
||||
if (first) {
|
||||
/* XXX: Should we assume that our domain is this persistent ? */
|
||||
first = 0;
|
||||
if (gethostname(domain, sizeof(domain) - 1) == 0 &&
|
||||
(s = strchr(domain, '.')) != NULL)
|
||||
memmove(domain, s + 1, strlen(s + 1) + 1);
|
||||
else
|
||||
domain[0] = '\0';
|
||||
dlen = strlen(domain);
|
||||
}
|
||||
|
||||
if (domain[0] == '\0')
|
||||
return;
|
||||
|
||||
s = fullhost;
|
||||
end = (char *)((uintptr_t)s + hostsize + 1);
|
||||
if ((s = memchr(s, '.', (size_t)(end - s))) != NULL) {
|
||||
if (strncasecmp(s + 1, domain, dlen) == 0) {
|
||||
if (s[dlen + 1] == '\0') {
|
||||
/* Found -- lose the domain. */
|
||||
*s = '\0';
|
||||
} else if (s[dlen + 1] == ':' &&
|
||||
isDISP(s + dlen + 2) &&
|
||||
(len = strlen(s + dlen + 1)) < (size_t)(end - s)) {
|
||||
/* Found -- shuffle the DISPLAY back. */
|
||||
memmove(s, s + dlen + 1, len + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the given string NN or NN.NN where ``NN'' is an all-numeric string ?
|
||||
*/
|
||||
static int
|
||||
isDISP(const char *disp)
|
||||
{
|
||||
size_t w;
|
||||
int res;
|
||||
|
||||
w = strspn(disp, "0123456789");
|
||||
res = 0;
|
||||
if (w > 0) {
|
||||
if (disp[w] == '\0')
|
||||
res = 1; /* NN */
|
||||
else if (disp[w] == '.') {
|
||||
disp += w + 1;
|
||||
w = strspn(disp, "0123456789");
|
||||
if (w > 0 && disp[w] == '\0')
|
||||
res = 1; /* NN.NN */
|
||||
}
|
||||
}
|
||||
return (res);
|
||||
}
|
67
tzlink.c
Normal file
67
tzlink.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
#include <xpc/xpc.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "tzlink.h"
|
||||
#include "tzlink_internal.h"
|
||||
|
||||
errno_t
|
||||
tzlink(const char *tz)
|
||||
{
|
||||
#if TARGET_OS_IPHONE || TARGET_OS_OSX && !TARGET_OS_SIMULATOR
|
||||
xpc_connection_t connection;
|
||||
xpc_object_t request, reply;
|
||||
errno_t e;
|
||||
|
||||
if (tz == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
connection = xpc_connection_create_mach_service(TZLINK_SERVICE_NAME, NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
|
||||
xpc_connection_set_event_handler(connection, ^(__unused xpc_object_t event) {
|
||||
});
|
||||
xpc_connection_resume(connection);
|
||||
|
||||
request = xpc_dictionary_create(NULL, NULL, 0);
|
||||
xpc_dictionary_set_string(request, TZLINK_KEY_REQUEST_TIMEZONE, tz);
|
||||
|
||||
reply = xpc_connection_send_message_with_reply_sync(connection, request);
|
||||
if (xpc_get_type(reply) == XPC_TYPE_DICTIONARY) {
|
||||
e = (errno_t)xpc_dictionary_get_uint64(reply, TZLINK_KEY_REPLY_ERROR);
|
||||
} else {
|
||||
e = EIO;
|
||||
}
|
||||
|
||||
xpc_release(reply);
|
||||
xpc_release(request);
|
||||
xpc_release(connection);
|
||||
|
||||
return e;
|
||||
#else /* !TARGET_OS_IPHONE */
|
||||
#pragma unused (tz)
|
||||
return ENOTSUP;
|
||||
#endif /* TARGET_OS_IPHONE */
|
||||
}
|
58
tzlink.h
Normal file
58
tzlink.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef _TZLINK_H_
|
||||
#define _TZLINK_H_
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/*!
|
||||
* @function tzlink
|
||||
* Create the timezone link at TZDEFAULT
|
||||
*
|
||||
* @param tz
|
||||
* New timezone, e.g. "America/Los_Angeles". This path is relative to TZDIR,
|
||||
* and must not contain any relative path components or stray slashes.
|
||||
* The file must exist and must be a valid timezone file with correct
|
||||
* ownership (root:wheel) and permissions (0644).
|
||||
*
|
||||
* @result
|
||||
* If the call succeeds, will return zero. Otherwise, returns an error:
|
||||
* EINVAL: Invalid input, e.g. NULL or a path with relative components.
|
||||
* ENAMETOOLONG: Input too long (generates a path > PATH_MAX)
|
||||
* ENOENT: Specified file doesn't exist or fails owner/perm check.
|
||||
* EPERM: Entitlement check failed.
|
||||
* EIO: Failed to communicate with backing daemon.
|
||||
* ENOTSUP: Always returned on OS X.
|
||||
* And possibly others not documented here.
|
||||
*
|
||||
* @discussion
|
||||
* This call can be used by any sufficiently-entitled client to overwrite
|
||||
* the timezone link at TZDEFAULT (see <tzfile.h>). It communicates with a
|
||||
* root daemon that does the necessary validation and file system work.
|
||||
* Upon success, the "SignificantTimeChangeNotification" notification is
|
||||
* posted.
|
||||
*/
|
||||
errno_t tzlink(const char *tz);
|
||||
|
||||
#endif /* !_TZLINK_H_ */
|
29
tzlink_internal.h
Normal file
29
tzlink_internal.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#define TZLINK_SERVICE_NAME "com.apple.tzlink"
|
||||
|
||||
#define TZLINK_ENTITLEMENT "com.apple.tzlink.allow"
|
||||
|
||||
#define TZLINK_KEY_REQUEST_TIMEZONE "tz" // string
|
||||
#define TZLINK_KEY_REPLY_ERROR "error" // uint64
|
26
tzlinkd/com.apple.tzlinkd.plist
Normal file
26
tzlinkd/com.apple.tzlinkd.plist
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>EnableTransactions</key>
|
||||
<true/>
|
||||
<key>JetsamProperties</key>
|
||||
<dict>
|
||||
<key>JetsamMemoryLimit</key>
|
||||
<integer>300</integer>
|
||||
<key>JetsamPriority</key>
|
||||
<integer>-49</integer>
|
||||
</dict>
|
||||
<key>Label</key>
|
||||
<string>com.apple.tzlinkd</string>
|
||||
<key>MachServices</key>
|
||||
<dict>
|
||||
<key>com.apple.tzlink</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>POSIXSpawnType</key>
|
||||
<string>Adaptive</string>
|
||||
<key>Program</key>
|
||||
<string>/usr/libexec/tzlinkd</string>
|
||||
</dict>
|
||||
</plist>
|
11
tzlinkd/com.apple.tzlinkd.sb
Normal file
11
tzlinkd/com.apple.tzlinkd.sb
Normal file
@ -0,0 +1,11 @@
|
||||
(version 1)
|
||||
|
||||
(deny default)
|
||||
|
||||
(import "system.sb")
|
||||
|
||||
(allow file-write-create file-write-unlink
|
||||
(literal "/private/var/db/timezone/localtime"))
|
||||
|
||||
(allow file-read*
|
||||
(literal "/private/var/db/timezone/zoneinfo"))
|
12
tzlinkd/entitlements.plist
Normal file
12
tzlinkd/entitlements.plist
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>seatbelt-profiles</key>
|
||||
<array>
|
||||
<string>com.apple.tzlinkd</string>
|
||||
</array>
|
||||
<key>com.apple.rootless.storage.timezone</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
201
tzlinkd/tzlinkd.c
Normal file
201
tzlinkd/tzlinkd.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include <xpc/xpc.h>
|
||||
#include <xpc/private.h>
|
||||
#include <notify.h>
|
||||
#include <tzfile.h>
|
||||
#include <os/log.h>
|
||||
|
||||
#include "tzlink_internal.h"
|
||||
|
||||
static bool peer_entitled(xpc_connection_t);
|
||||
static int set_timezone(const char *);
|
||||
static int build_source_path(char *, size_t, const char *);
|
||||
static int validate_source_path(const char *);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
dispatch_queue_t queue;
|
||||
xpc_connection_t listener;
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
xpc_track_activity();
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
queue = dispatch_queue_create(TZLINK_SERVICE_NAME, NULL);
|
||||
|
||||
listener = xpc_connection_create_mach_service(TZLINK_SERVICE_NAME, queue, XPC_CONNECTION_MACH_SERVICE_LISTENER);
|
||||
xpc_connection_set_event_handler(listener, ^(xpc_object_t peer) {
|
||||
if (xpc_get_type(peer) != XPC_TYPE_CONNECTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
xpc_connection_set_target_queue(peer, queue);
|
||||
xpc_connection_set_event_handler(peer, ^(xpc_object_t request) {
|
||||
xpc_object_t reply;
|
||||
const char *tz;
|
||||
int error;
|
||||
|
||||
if (xpc_get_type(request) != XPC_TYPE_DICTIONARY) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (peer_entitled(peer)) {
|
||||
tz = xpc_dictionary_get_string(request, TZLINK_KEY_REQUEST_TIMEZONE);
|
||||
error = tz ? set_timezone(tz) : EINVAL;
|
||||
} else {
|
||||
error = EPERM;
|
||||
}
|
||||
|
||||
reply = xpc_dictionary_create_reply(request);
|
||||
xpc_dictionary_set_uint64(reply, TZLINK_KEY_REPLY_ERROR, (uint64_t)error);
|
||||
xpc_connection_send_message(peer, reply);
|
||||
xpc_release(reply);
|
||||
});
|
||||
xpc_connection_resume(peer);
|
||||
});
|
||||
xpc_connection_resume(listener);
|
||||
|
||||
dispatch_main();
|
||||
}
|
||||
|
||||
static bool
|
||||
peer_entitled(xpc_connection_t peer)
|
||||
{
|
||||
xpc_object_t val;
|
||||
bool entitled;
|
||||
|
||||
entitled = false;
|
||||
|
||||
val = xpc_connection_copy_entitlement_value(peer, TZLINK_ENTITLEMENT);
|
||||
if (val != NULL) {
|
||||
entitled = xpc_bool_get_value(val);
|
||||
xpc_release(val);
|
||||
}
|
||||
|
||||
return entitled;
|
||||
}
|
||||
|
||||
static int
|
||||
set_timezone(const char *tz)
|
||||
{
|
||||
char srcpath[PATH_MAX];
|
||||
int error;
|
||||
|
||||
error = build_source_path(srcpath, sizeof(srcpath), tz);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = validate_source_path(srcpath);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
(void)unlink(TZDEFAULT);
|
||||
if (symlink(srcpath, TZDEFAULT) != 0) {
|
||||
return errno ? errno : EFAULT;
|
||||
}
|
||||
|
||||
/*
|
||||
* notifyd posts "com.apple.system.timezone" automatically,
|
||||
* but we also need post this. Sigh.
|
||||
*/
|
||||
(void)notify_post("SignificantTimeChangeNotification");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create path from input. */
|
||||
static int
|
||||
build_source_path(char *path, size_t size, const char *tz)
|
||||
{
|
||||
char *str, *str0;
|
||||
char *pathcomp;
|
||||
int error;
|
||||
|
||||
if (strlcpy(path, TZDIR, size) >= size) {
|
||||
return ENAMETOOLONG;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
/* Attempt to validate the input; construct a clean path as we go. */
|
||||
str0 = str = strdup(tz);
|
||||
while ((pathcomp = strsep(&str, "/")) != NULL) {
|
||||
if (pathcomp[0] == '\0' || pathcomp[0] == '.') {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (strlcat(path, "/", size) >= size) {
|
||||
error = ENAMETOOLONG;
|
||||
break;
|
||||
}
|
||||
if (strlcat(path, pathcomp, size) >= size) {
|
||||
error = ENAMETOOLONG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(str0);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Validate path. */
|
||||
static int
|
||||
validate_source_path(const char *path)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (lstat(path, &sb) != 0) {
|
||||
return errno ? errno : EFAULT;
|
||||
}
|
||||
|
||||
/* Ensure that the time zone file is... */
|
||||
|
||||
/* ... a regular file. */
|
||||
if (!S_ISREG(sb.st_mode)) {
|
||||
os_log_fault(OS_LOG_DEFAULT, "tzlink failed; \"%{public}s\" is not a regular file", path);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
/* ... owned by root:wheel */
|
||||
if (sb.st_uid != 0 || sb.st_gid != 0) {
|
||||
os_log_fault(OS_LOG_DEFAULT, "tzlink failed; \"%{public}s\" is owned by %d:%d", path, sb.st_uid, sb.st_gid);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
/* ... 0644 perms */
|
||||
if ((sb.st_mode & ACCESSPERMS) != 0644) {
|
||||
os_log_fault(OS_LOG_DEFAULT, "tzlink failed; \"%{public}s\" has access permissions %o", path, sb.st_mode);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
/* ... is a real tzfile (starts with TZif) */
|
||||
// TODO: Validate contents of file.
|
||||
|
||||
return 0;
|
||||
}
|
162
wipefs.3
Normal file
162
wipefs.3
Normal file
@ -0,0 +1,162 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2008,2011 Apple Inc. All rights reserved.
|
||||
.\"
|
||||
.\" @APPLE_LICENSE_HEADER_START@
|
||||
.\"
|
||||
.\" This file contains Original Code and/or Modifications of Original Code
|
||||
.\" as defined in and that are subject to the Apple Public Source License
|
||||
.\" Version 2.0 (the 'License'). You may not use this file except in
|
||||
.\" compliance with the License. Please obtain a copy of the License at
|
||||
.\" http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
.\" file.
|
||||
.\"
|
||||
.\" The Original Code and all software distributed under the License are
|
||||
.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
.\" Please see the License for the specific language governing rights and
|
||||
.\" limitations under the License.
|
||||
.\"
|
||||
.\" @APPLE_LICENSE_HEADER_END@
|
||||
.\"
|
||||
.Dd 6/30/11 \" DATE
|
||||
.Dt libutil 3 \" Program name and manual section number
|
||||
.Os Mac OS X
|
||||
.Sh NAME \" Section Header - required - don't modify
|
||||
.\" 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.
|
||||
.Nm wipefs_alloc ,
|
||||
.Nm wipefs_except_blocks ,
|
||||
.Nm wipefs_wipe ,
|
||||
.Nm wipefs_free
|
||||
.\" Use .Nm macro to designate other names for the documented program.
|
||||
.Nd wipes existing file systems on a volume
|
||||
.Sh LIBRARY \" Section Header - required - don't modify
|
||||
.Lb libutil
|
||||
.Sh SYNOPSIS
|
||||
.In wipefs.h
|
||||
.Ft int
|
||||
.Fo wipefs_alloc
|
||||
.Fa "int fd"
|
||||
.Fa "size_t block_size"
|
||||
.Fa "wipefs_ctx *handle"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo wipefs_include_blocks
|
||||
.Fa "wipefs_ctx handle"
|
||||
.Fa "off_t block_offset"
|
||||
.Fa "off_t nblocks"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo wipefs_except_blocks
|
||||
.Fa "wipefs_ctx handle"
|
||||
.Fa "off_t block_offset"
|
||||
.Fa "off_t nblocks"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo wipefs_wipe
|
||||
.Fa "wipefs_ctx handle"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo wipefs_free
|
||||
.Fa "wipefs_ctx *handle"
|
||||
.Fc
|
||||
.Sh DESCRIPTION \" Section Header - required - don't modify
|
||||
The wipefs family of functions wipe existing file systems on a volume. A
|
||||
.Li DKIOCUNMAP
|
||||
ioctl is sent to the device to invalidate all of its content.
|
||||
Then zeroes are written to various locations that are used by various file systems to recognize their content and mount their volumes.
|
||||
This is usually used by the newfs_* utilities before they create new file systems on the volume, so that the existing file system will not be mounted accidentally after the new file system is created.
|
||||
.Pp
|
||||
.Sy NOTE:
|
||||
These routines do not overwrite all volume structures.
|
||||
These routines do not securely erase the previous content.
|
||||
They only overwrite enough to make sure that the normal utilities will no longer recognize any file system content.
|
||||
It is possible that previous file system content could be recovered by other means.
|
||||
.Pp
|
||||
The
|
||||
.Fn wipefs_alloc
|
||||
function initializes a
|
||||
.Fa wipefs_ctx
|
||||
object (which is an opaque data type).
|
||||
.Fa file_desc
|
||||
is the file handle of the volume to be wiped, which can be a block device node, a character device node, or a file.
|
||||
.Fa file_desc
|
||||
must be opened with write access. If
|
||||
.Fa block_size
|
||||
is 0, this function calls
|
||||
.Xr ioctl 2
|
||||
to get the block size. A valid
|
||||
.Fa block_size
|
||||
must be supplied if
|
||||
.Fa file_desc
|
||||
is a regular file. This function does not write any data to the volume.
|
||||
.Pp
|
||||
The
|
||||
.Fn wipefs_include_blocks
|
||||
function tells wipefs to write zeroes in the block range provided, in addition to any other ranges
|
||||
it would normally write. This may be more efficient than if the caller were to write this range
|
||||
separately, especially if the block range overlaps or is contiguous with other ranges that wipefs
|
||||
will write. This function does not write any data to the volume. If this function is called
|
||||
multiple times, the union of all the ranges provided will be written by
|
||||
.Fn wipefs_wipe .
|
||||
.Pp
|
||||
The
|
||||
.Fn wipefs_except_blocks
|
||||
function tells wipefs not to write anything in the block range provided. This function is used for performance
|
||||
optimizations if the caller will write to these blocks. It is the caller's responsibility to write to these blocks.
|
||||
Otherwise, some file systems may still be recognized on the volume. This function does not write any data to the
|
||||
volume. If this function is called multiple times, the union of all the ranges provided will be excluded from being
|
||||
written by
|
||||
.Fn wipefs_wipe .
|
||||
.Pp
|
||||
The
|
||||
.Fn wipefs_wipe
|
||||
function sends a
|
||||
.Li DKIOCUNMAP
|
||||
ioctl and then writes data to the volume to wipe out existing file systems on it.
|
||||
.Sy CAUTION:
|
||||
this function destroys any file system or partition scheme on the volume represented by
|
||||
.Fa file_desc .
|
||||
If
|
||||
.Fa file_desc
|
||||
represents the entire disk (e.g. /dev/diskX), the partition map of the disk will be destroyed. If
|
||||
.Fa file_desc
|
||||
represents a partition (e.g., /dev/diskXsY), only the file system in that partition is destroyed. Although the partition scheme or file system on
|
||||
.Fa file_desc
|
||||
may be beyond repair after
|
||||
.Fn wipefs_wipe ,
|
||||
this function is not designed as a means to safely delete all data. It is possible that some user data (or intact file systems in some partitions) may still be recovered.
|
||||
.Pp
|
||||
The
|
||||
.Fn wipefs_free
|
||||
function frees the allocated
|
||||
.Fa wipefs_ctx
|
||||
handle and set
|
||||
.Fa *handlep
|
||||
to NULL.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn wipefs_alloc ,
|
||||
.Fn wipefs_include_blocks ,
|
||||
.Fn wipefs_except_blocks
|
||||
and
|
||||
.Fn wipefs_wipe
|
||||
functions return 0 on success, or will fail and return an error code.
|
||||
Each function may return
|
||||
.Fa ENOMEM
|
||||
if insufficient memory is available. In addition, if
|
||||
.Fa block_size
|
||||
is not provided,
|
||||
.Fn wipefs_alloc
|
||||
may return any error
|
||||
.Xr ioctl 2
|
||||
returns;
|
||||
.Fn wipefs_wipe
|
||||
may return any error
|
||||
.Xr pwrite 2
|
||||
returns.
|
||||
.\" .Sh BUGS \" Document known, unremedied bugs
|
||||
.\".Sh HISTORY \" Document history if command behaves in a unique manner
|
||||
.\"The wipefs family of functions first appeared in Mac OS X Leopard (10.5.3).
|
456
wipefs.cpp
Normal file
456
wipefs.cpp
Normal file
@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
//
|
||||
// wipefs.cpp
|
||||
//
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <string.h>
|
||||
#include <spawn.h>
|
||||
#include <os/log.h>
|
||||
|
||||
#include "ExtentManager.h"
|
||||
#include "wipefs.h"
|
||||
|
||||
#define wipefs_roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
||||
|
||||
struct __wipefs_ctx {
|
||||
int fd;
|
||||
class ExtentManager extMan;
|
||||
|
||||
// xartutil information
|
||||
char *diskname;
|
||||
};
|
||||
|
||||
static void
|
||||
AddExtentsForFutureFS(class ExtentManager *extMan)
|
||||
{
|
||||
// we don't know what blocks future FS will use to recognize itself. But we'd better be safe than sorry and write
|
||||
// the first and last 2MB of the volume
|
||||
off_t size = 2 * 1024 * 1024;
|
||||
extMan->AddByteRangeExtent(0, size);
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes - size, size);
|
||||
}
|
||||
|
||||
static void
|
||||
AddExtentsForHFS(class ExtentManager *extMan)
|
||||
{
|
||||
// first 1KB is boot block, last 512B is reserved
|
||||
// the Volume Header (512B) is after 1KB and before the last 512B
|
||||
extMan->AddByteRangeExtent(0, 1024 + 512);
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes - 1024, 1024);
|
||||
}
|
||||
|
||||
static void
|
||||
AddExtentsForMSDOS(class ExtentManager *extMan)
|
||||
{
|
||||
// MSDOS needs the first block (in theory, up to 32KB)
|
||||
extMan->AddByteRangeExtent(0, 32 * 1024);
|
||||
}
|
||||
|
||||
static void
|
||||
AddExtentsForNTFS(class ExtentManager *extMan)
|
||||
{
|
||||
// NTFS supports block size from 256B to 32768B. The first, middle and last block are needed
|
||||
extMan->AddByteRangeExtent(0, 32 * 1024);
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes - 32 * 1024, 32 * 1024);
|
||||
// to be safe, add the rage from (mid_point - 32KB) to (mid_point + 32KB)
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes / 2 - 32 * 1024, 64 * 1024);
|
||||
}
|
||||
|
||||
static void
|
||||
AddExtentsForUDF(class ExtentManager *extMan)
|
||||
{
|
||||
off_t lastBlockAddr = extMan->totalBlocks - 1;
|
||||
|
||||
// Volume Recognization Sequence (VRS) starts at 32KB, usually less than 7 Volume Structure Descriptors (2KB each)
|
||||
extMan->AddByteRangeExtent(32 * 1024, 14 * 1024);
|
||||
|
||||
// AVDP is on 256, 512, last block, last block - 256
|
||||
extMan->AddBlockRangeExtent(256, 1);
|
||||
extMan->AddBlockRangeExtent(512, 1);
|
||||
extMan->AddBlockRangeExtent(lastBlockAddr, 1);
|
||||
extMan->AddBlockRangeExtent(lastBlockAddr - 256, 1);
|
||||
|
||||
// to be safe, assume the device has 2KB block size and do it again
|
||||
if (extMan->blockSize != 2048) {
|
||||
off_t blockSize = 2048;
|
||||
// AVDP is on 256, 512, last block, last block - 256
|
||||
extMan->AddByteRangeExtent(256 * blockSize, blockSize);
|
||||
extMan->AddByteRangeExtent(512 * blockSize, blockSize);
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes - blockSize, blockSize);
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes - 256 * blockSize, blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
AddExtentsForUFS(class ExtentManager *extMan)
|
||||
{
|
||||
// UFS super block is 8KB at offset 8KB
|
||||
extMan->AddByteRangeExtent(8192, 8192);
|
||||
}
|
||||
|
||||
static void
|
||||
AddExtentsForZFS(class ExtentManager *extMan)
|
||||
{
|
||||
// ZFS needs the first 512KB and last 512KB for all the 4 disk labels
|
||||
extMan->AddByteRangeExtent(0, 512 * 1024);
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes - 512 * 1024, 512 * 1024);
|
||||
}
|
||||
|
||||
static void
|
||||
AddExtentsForPartitions(class ExtentManager *extMan)
|
||||
{
|
||||
// MBR (Master Boot Record) needs the first sector
|
||||
// APM (Apple Partition Map) needs the second sector
|
||||
// GPT (GUID Partition Table) needs the first 34 and last 33 sectors
|
||||
extMan->AddByteRangeExtent(0, 512 * 34);
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes - 512 * 33, 512 * 33);
|
||||
}
|
||||
|
||||
static void
|
||||
AddExtentsForCoreStorage(class ExtentManager *extMan)
|
||||
{
|
||||
// the CoreStorage VolumeHeader structures reside in the first/last 512 bytes of each PV
|
||||
extMan->AddByteRangeExtent(0, 512);
|
||||
extMan->AddByteRangeExtent(extMan->totalBytes - 512, 512);
|
||||
}
|
||||
|
||||
static char *
|
||||
query_disk_info(int fd) {
|
||||
char disk_path[PATH_MAX];
|
||||
char *disk_name;
|
||||
|
||||
// Fetch the path
|
||||
if (fcntl(fd, F_GETPATH, disk_path) == -1) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Find the last pathname component.
|
||||
disk_name = strrchr(disk_path, '/');
|
||||
if (disk_name == NULL) {
|
||||
// Not that we expect this to happen...
|
||||
disk_name = disk_path;
|
||||
} else {
|
||||
// Skip over the '/'.
|
||||
disk_name++;
|
||||
}
|
||||
|
||||
if (*disk_name == 'r') {
|
||||
// Raw device; skip over leading 'r'.
|
||||
disk_name++;
|
||||
}
|
||||
|
||||
// ...and make sure it's really a disk.
|
||||
if (strncmp(disk_name, "disk", strlen("disk")) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (strdup(disk_name));
|
||||
}
|
||||
|
||||
static
|
||||
int run_xartutil(char *const diskname)
|
||||
{
|
||||
pid_t child_pid, wait_pid;
|
||||
posix_spawn_file_actions_t fileActions;
|
||||
bool haveFileActions = false;
|
||||
int child_status = 0;
|
||||
int result = 0;
|
||||
|
||||
char arg1[] = "xartutil";
|
||||
char arg2[] = "--erase-disk";
|
||||
|
||||
char *const xartutil_argv[] = {arg1, arg2, diskname, NULL};
|
||||
|
||||
result = posix_spawn_file_actions_init(&fileActions);
|
||||
if (result) {
|
||||
os_log_error(OS_LOG_DEFAULT, "Warning, init xartutil file actions error: %d", result);
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
haveFileActions = true;
|
||||
|
||||
// Redirect stdout & stderr (results not critical, so we ignore return values).
|
||||
posix_spawn_file_actions_addopen(&fileActions, STDOUT_FILENO, "/dev/null", O_WRONLY, 0);
|
||||
posix_spawn_file_actions_addopen(&fileActions, STDERR_FILENO, "/dev/null", O_WRONLY, 0);
|
||||
|
||||
result = posix_spawn(&child_pid, "/usr/sbin/xartutil", &fileActions, NULL, xartutil_argv, NULL);
|
||||
|
||||
if (result) {
|
||||
os_log_error(OS_LOG_DEFAULT, "Warning, unable to start xartutil, spawn error: %d", result);
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
do {
|
||||
wait_pid = waitpid(child_pid, &child_status, 0);
|
||||
} while (wait_pid == -1 && errno == EINTR);
|
||||
|
||||
if (wait_pid == -1) {
|
||||
os_log_error(OS_LOG_DEFAULT, "Warning, unable to start xartutil, waitpid error: %d", errno);
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (WIFEXITED(child_status)) {
|
||||
// xartutil terminated normally, get exit status
|
||||
result = WEXITSTATUS(child_status);
|
||||
|
||||
if (result) {
|
||||
os_log_error(OS_LOG_DEFAULT, "Warning, xartutil returned status %d", result);
|
||||
}
|
||||
} else {
|
||||
result = -1;
|
||||
|
||||
if (WIFSIGNALED(child_status)) {
|
||||
os_log_error(OS_LOG_DEFAULT, "Warning, xartutil terminated by signal: %u", WTERMSIG(child_status));
|
||||
} else if (WIFSTOPPED(child_status)) {
|
||||
os_log_error(OS_LOG_DEFAULT, "Warning, xartutil stopped by signal: %u", WSTOPSIG(child_status));
|
||||
} else {
|
||||
os_log_error(OS_LOG_DEFAULT, "Warning, xartutil terminated abnormally, status 0x%x", child_status);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
if (haveFileActions) {
|
||||
posix_spawn_file_actions_destroy(&fileActions);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
wipefs_alloc(int fd, size_t block_size, wipefs_ctx *handle)
|
||||
{
|
||||
int err = 0;
|
||||
uint64_t numBlocks = 0;
|
||||
uint32_t nativeBlockSize = 0;
|
||||
off_t totalSizeInBytes = 0;
|
||||
class ExtentManager *extMan = NULL;
|
||||
struct stat sbuf = { 0 };
|
||||
char *diskname = NULL;
|
||||
|
||||
*handle = NULL;
|
||||
(void)fstat(fd, &sbuf);
|
||||
switch (sbuf.st_mode & S_IFMT) {
|
||||
case S_IFCHR:
|
||||
case S_IFBLK:
|
||||
if (ioctl(fd, DKIOCGETBLOCKSIZE, (char *)&nativeBlockSize) < 0) {
|
||||
err = errno;
|
||||
goto labelExit;
|
||||
}
|
||||
if (ioctl(fd, DKIOCGETBLOCKCOUNT, (char *)&numBlocks) < 0) {
|
||||
err = errno;
|
||||
goto labelExit;
|
||||
}
|
||||
totalSizeInBytes = numBlocks * nativeBlockSize;
|
||||
|
||||
diskname = query_disk_info(fd);
|
||||
break;
|
||||
case S_IFREG:
|
||||
nativeBlockSize = sbuf.st_blksize;
|
||||
numBlocks = sbuf.st_size / sbuf.st_blksize;
|
||||
totalSizeInBytes = sbuf.st_size;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
goto labelExit;
|
||||
}
|
||||
if (block_size == 0) {
|
||||
block_size = nativeBlockSize;
|
||||
}
|
||||
if (block_size == 0 || totalSizeInBytes == 0) {
|
||||
err = EINVAL;
|
||||
goto labelExit;
|
||||
}
|
||||
|
||||
try {
|
||||
*handle = new __wipefs_ctx;
|
||||
if (*handle == NULL) {
|
||||
bad_alloc e;
|
||||
throw e;
|
||||
}
|
||||
|
||||
(*handle)->fd = fd;
|
||||
(*handle)->diskname = NULL;
|
||||
extMan = &(*handle)->extMan;
|
||||
|
||||
extMan->Init(block_size, nativeBlockSize, totalSizeInBytes);
|
||||
AddExtentsForFutureFS(extMan);
|
||||
AddExtentsForHFS(extMan);
|
||||
AddExtentsForMSDOS(extMan);
|
||||
AddExtentsForNTFS(extMan);
|
||||
AddExtentsForUDF(extMan);
|
||||
AddExtentsForUFS(extMan);
|
||||
AddExtentsForZFS(extMan);
|
||||
AddExtentsForPartitions(extMan);
|
||||
AddExtentsForCoreStorage(extMan);
|
||||
|
||||
(*handle)->diskname = diskname;
|
||||
}
|
||||
catch (bad_alloc &e) {
|
||||
err = ENOMEM;
|
||||
}
|
||||
catch (...) { // currently only ENOMEM is possible
|
||||
err = ENOMEM;
|
||||
}
|
||||
|
||||
labelExit:
|
||||
if (err != 0) {
|
||||
if (diskname != NULL)
|
||||
free(diskname);
|
||||
wipefs_free(handle);
|
||||
}
|
||||
return err;
|
||||
} // wipefs_alloc
|
||||
|
||||
extern "C" int
|
||||
wipefs_include_blocks(wipefs_ctx handle, off_t block_offset, off_t nblocks)
|
||||
{
|
||||
int err = 0;
|
||||
try {
|
||||
handle->extMan.AddBlockRangeExtent(block_offset, nblocks);
|
||||
}
|
||||
catch (bad_alloc &e) {
|
||||
err = ENOMEM;
|
||||
}
|
||||
catch (...) { // currently only ENOMEM is possible
|
||||
err = ENOMEM;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
wipefs_except_blocks(wipefs_ctx handle, off_t block_offset, off_t nblocks)
|
||||
{
|
||||
int err = 0;
|
||||
try {
|
||||
handle->extMan.RemoveBlockRangeExtent(block_offset, nblocks);
|
||||
}
|
||||
catch (bad_alloc &e) {
|
||||
err = ENOMEM;
|
||||
}
|
||||
catch (...) { // currently only ENOMEM is possible
|
||||
err = ENOMEM;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
wipefs_wipe(wipefs_ctx handle)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t *bufZero = NULL;
|
||||
ListExtIt curExt;
|
||||
size_t bufSize;
|
||||
dk_extent_t extent;
|
||||
dk_unmap_t unmap;
|
||||
|
||||
if (handle->diskname != NULL) {
|
||||
// Remove this disk's entry from the xART.
|
||||
run_xartutil(handle->diskname);
|
||||
}
|
||||
|
||||
memset(&extent, 0, sizeof(dk_extent_t));
|
||||
extent.length = handle->extMan.totalBytes;
|
||||
|
||||
memset(&unmap, 0, sizeof(dk_unmap_t));
|
||||
unmap.extents = &extent;
|
||||
unmap.extentsCount = 1;
|
||||
|
||||
//
|
||||
// Don't bother to check the return value since this is mostly
|
||||
// informational for the lower-level drivers.
|
||||
//
|
||||
ioctl(handle->fd, DKIOCUNMAP, (caddr_t)&unmap);
|
||||
|
||||
bufSize = 128 * 1024; // issue large I/O to get better performance
|
||||
if (handle->extMan.nativeBlockSize > bufSize) {
|
||||
bufSize = handle->extMan.nativeBlockSize;
|
||||
}
|
||||
bufZero = new uint8_t[bufSize];
|
||||
bzero(bufZero, bufSize);
|
||||
|
||||
off_t byteOffset, totalBytes;
|
||||
size_t numBytes, numBytesToWrite, blockSize;
|
||||
|
||||
blockSize = handle->extMan.blockSize;
|
||||
totalBytes = handle->extMan.totalBytes;
|
||||
// write zero to all extents
|
||||
for (curExt = handle->extMan.extentList.begin(); curExt != handle->extMan.extentList.end(); curExt++) {
|
||||
byteOffset = curExt->blockAddr * blockSize;
|
||||
numBytes = curExt->numBlocks * blockSize;
|
||||
// make both offset and numBytes on native block boundary
|
||||
if (byteOffset % handle->extMan.nativeBlockSize != 0 ||
|
||||
numBytes % handle->extMan.nativeBlockSize != 0) {
|
||||
size_t nativeBlockSize = handle->extMan.nativeBlockSize;
|
||||
off_t newOffset, newEndOffset;
|
||||
newOffset = byteOffset / nativeBlockSize * nativeBlockSize;
|
||||
newEndOffset = wipefs_roundup(byteOffset + numBytes, nativeBlockSize);
|
||||
byteOffset = newOffset;
|
||||
numBytes = newEndOffset - newOffset;
|
||||
}
|
||||
if (byteOffset + (off_t)numBytes > totalBytes) {
|
||||
numBytes = totalBytes - byteOffset;
|
||||
}
|
||||
while (numBytes > 0) {
|
||||
numBytesToWrite = min(numBytes, bufSize);
|
||||
if (pwrite(handle->fd, bufZero, numBytesToWrite, byteOffset) != (ssize_t)numBytesToWrite) {
|
||||
err = errno;
|
||||
goto labelExit;
|
||||
}
|
||||
numBytes -= numBytesToWrite;
|
||||
byteOffset += numBytesToWrite;
|
||||
}
|
||||
}
|
||||
|
||||
labelExit:
|
||||
|
||||
(void)ioctl(handle->fd, DKIOCSYNCHRONIZECACHE);
|
||||
if (bufZero != NULL)
|
||||
delete[] bufZero;
|
||||
|
||||
return err;
|
||||
} // wipefs_wipe
|
||||
|
||||
extern "C" void
|
||||
wipefs_free(wipefs_ctx *handle)
|
||||
{
|
||||
if (*handle != NULL) {
|
||||
char *diskname;
|
||||
|
||||
if ((diskname = (*handle)->diskname) != NULL)
|
||||
free(diskname);
|
||||
delete *handle;
|
||||
*handle = NULL;
|
||||
}
|
||||
}
|
48
wipefs.h
Normal file
48
wipefs.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
//
|
||||
// wipefs.h
|
||||
//
|
||||
#ifndef WIPEFS_H
|
||||
#define WIPEFS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct __wipefs_ctx *wipefs_ctx;
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern int wipefs_alloc(int fd, size_t block_size, wipefs_ctx *handle);
|
||||
extern int wipefs_include_blocks(wipefs_ctx handle, off_t block_offset, off_t nblocks);
|
||||
extern int wipefs_except_blocks(wipefs_ctx handle, off_t block_offset, off_t nblocks);
|
||||
extern int wipefs_wipe(wipefs_ctx handle);
|
||||
extern void wipefs_free(wipefs_ctx *handle);
|
||||
__END_DECLS
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #ifndef WIPEFS_H
|
||||
|
1
xcconfigs/base.xcconfig
Normal file
1
xcconfigs/base.xcconfig
Normal file
@ -0,0 +1 @@
|
||||
#include "<DEVELOPER_DIR>/Makefiles/CoreOS/Xcode/BSD.xcconfig"
|
3
xcconfigs/lib.xcconfig
Normal file
3
xcconfigs/lib.xcconfig
Normal file
@ -0,0 +1,3 @@
|
||||
PUBLIC_HEADERS_FOLDER_PATH = /usr/include
|
||||
PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include
|
||||
IS_ZIPPERED = YES
|
1
xcconfigs/test.xcconfig
Normal file
1
xcconfigs/test.xcconfig
Normal file
@ -0,0 +1 @@
|
||||
INSTALL_PATH = /AppleInternal/Tests/libutil
|
28
xcconfigs/tzlinkd.xcconfig
Normal file
28
xcconfigs/tzlinkd.xcconfig
Normal file
@ -0,0 +1,28 @@
|
||||
INSTALL_PATH = /usr/libexec
|
||||
PRODUCT_NAME = tzlinkd
|
||||
|
||||
CODE_SIGN_IDENTITY = -
|
||||
CODE_SIGN_ENTITLEMENTS = tzlinkd/entitlements.plist
|
||||
|
||||
USER_HEADER_SEARCH_PATHS = $(SRCROOT)
|
||||
|
||||
ALWAYS_SEARCH_USER_PATHS = NO
|
||||
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES
|
||||
CLANG_WARN_BOOL_CONVERSION = YES
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR
|
||||
CLANG_WARN_EMPTY_BODY = YES
|
||||
CLANG_WARN_ENUM_CONVERSION = YES
|
||||
CLANG_WARN_INT_CONVERSION = YES
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES
|
||||
GCC_WARN_UNUSED_FUNCTION = YES
|
||||
GCC_WARN_UNUSED_VARIABLE = YES
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES
|
||||
GCC_WARN_UNUSED_LABEL = YES
|
||||
GCC_WARN_UNUSED_PARAMETER = YES
|
Loading…
Reference in New Issue
Block a user