Added Apple libutil, fix libcxx rpath

This commit is contained in:
Lubos Dolezel 2015-10-28 10:47:07 +01:00
parent ea971de809
commit 72b5a9392d
43 changed files with 4670 additions and 8 deletions

View File

@ -3,4 +3,5 @@
/usr/lib/libc++.1.dylib=libc++.so.1
/usr/lib/libc++abi.dylib=libc++abi.so.1
/usr/lib/libiconv.2.dylib=libiconv.so
/usr/lib/libutil.dylib=libutil.so

View File

@ -59,6 +59,7 @@ add_subdirectory(libinfo)
add_subdirectory(libmalloc)
add_subdirectory(libunwind)
add_subdirectory(libsystem)
add_subdirectory(libutil)
add_subdirectory(keymgr)
add_subdirectory(libiconv)
add_subdirectory(duct/src)

View File

@ -29,11 +29,11 @@ endif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64" OR ${CMAKE_SYSTEM_PROCESSOR} S
add_executable(dyld-bin ${dyld_SRCS})
set_target_properties(dyld-bin PROPERTIES OUTPUT_NAME dyld${SUFFIX})
target_link_libraries(dyld-bin dyld util mach-o)
target_link_libraries(dyld-bin dyld darling-util mach-o)
#if (NOT DEFINED SUFFIX OR SUFFIX STREQUAL "64")
add_executable(dyldd dyldd.cpp)
target_link_libraries(dyldd dyld util mach-o)
target_link_libraries(dyldd dyld darling-util mach-o)
install(TARGETS dyldd DESTINATION bin)
#endif (NOT DEFINED SUFFIX OR SUFFIX STREQUAL "64")

2
src/external/libcxx vendored

@ -1 +1 @@
Subproject commit a943d024709012d9e1ac6f8db0502509ba574ea6
Subproject commit 13005b1738a889b0cc1a871548016d4a5adf9c4a

View File

@ -43,7 +43,7 @@ mbtowc_l(wchar_t * __restrict pwc, const char * __restrict s, size_t n,
NORMALIZE_LOCALE(loc);
if (s == NULL) {
/* No support for state dependent encodings. */
loc->__mbs_mbtowc = initial;
// loc->__mbs_mbtowc = initial;
return (0);
}
rval = loc->__lc_ctype->__mbrtowc(pwc, s, n, &loc->__mbs_mbtowc, loc);

View File

@ -57,7 +57,7 @@ SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
add_library(dyld SHARED ${dyld_SRCS})
target_link_libraries(dyld -ldl -lpthread mach-o util)
target_link_libraries(dyld -ldl -lpthread mach-o darling-util)
install(TARGETS dyld DESTINATION lib${SUFFIX}/darling)

View File

@ -23,7 +23,7 @@ set(mach-o_SRCS
add_library(mach-o SHARED ${mach-o_SRCS})
set_target_properties(mach-o PROPERTIES VERSION 1.0.0 SOVERSION 1.0)
set_target_properties(mach-o PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
target_link_libraries(mach-o -ldl -lpthread util)
target_link_libraries(mach-o -ldl -lpthread darling-util)
install(TARGETS mach-o DESTINATION "lib${SUFFIX}/darling")

View File

@ -0,0 +1,36 @@
project(libutil)
cmake_minimum_required(VERSION 2.4.0)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
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 -Wl,--unresolved-symbols=ignore-all -Wl,--version-script=${DARLING_TOP_DIRECTORY}/darwin.map")
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${DARLING_TOP_DIRECTORY}/src/libc/include)
include_directories(${DARLING_TOP_DIRECTORY}/src/external/libcxx/include)
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(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib${SUFFIX}/darling")
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
add_library(util SHARED ${util_SRCS})
target_link_libraries(util system)
install(TARGETS util DESTINATION lib${SUFFIX}/darling)

View 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 */

View 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
src/libutil/getmntopts.3 Normal file
View 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
src/libutil/getmntopts.c Normal file
View 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;
}

View File

@ -0,0 +1,148 @@
.\" $NetBSD: humanize_number.3,v 1.4 2003/04/16 13:34:37 wiz Exp $
.\" $FreeBSD: src/lib/libutil/humanize_number.3,v 1.8 2005/04/10 12:15:25 delphij Exp $
.\"
.\" 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.
.\" 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.
.\"
.Dd May 25, 2004
.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 buffer .
A space and then
.Fa suffix
is appended to the end.
The buffer pointed to by
.Fa buffer
must be at least
.Fa len
bytes long.
.Pp
If the formatted number (including
.Fa suffix )
would be too long to fit into
.Fa buffer ,
then divide
.Fa number
by 1024 until it will.
In this case, prefix
.Fa suffix
with the appropriate SI designator.
.Pp
The prefixes are:
.Bl -column "Prefix" "Description" "Multiplier" -offset indent
.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier"
.It Li k Ta No kilo Ta 1024
.It Li M Ta No mega Ta 1048576
.It Li G Ta No giga Ta 1073741824
.It Li T Ta No tera Ta 1099511627776
.It Li P Ta No peta Ta 1125899906842624
.It Li E Ta No exa 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 buffer .
To use a specific prefix, specify this as
.Fa scale
(multiplier = 1024 ^ scale).
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 digit.
.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.
.El
.Sh RETURN VALUES
The
.Fn humanize_number
function returns the number of characters stored in
.Fa buffer
(excluding the terminating
.Dv NUL )
upon success, or \-1 upon failure.
If
.Dv HN_GETSCALE
is specified, the prefix index number will be returned instead.
.Sh HISTORY
The
.Fn humanize_number
function first appeared in
.Nx 2.0 .

View File

@ -0,0 +1,159 @@
/* $NetBSD: humanize_number.c,v 1.8 2004/07/27 01:56:24 enami Exp $ */
/*
* 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.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <libutil.h>
#include <stdint.h>
#include <limits.h>
int
humanize_number(char *buf, size_t len, int64_t bytes,
const char *suffix, int scale, int flags)
{
const char *prefixes, *sep;
int b, i, r, maxscale, s1, s2, sign;
int64_t divisor, max;
// We multiply bytes by 100 to deal with rounding, so we need something
// big enough to hold LLONG_MAX * 100. On 64-bit we can use 128-bit wide
// integers with __int128_t, but on 32-bit we have to use long double.
#ifdef __LP64__
__int128_t scalable = (__int128_t)bytes;
#else
long double scalable = (long double)bytes;
#endif
size_t baselen;
assert(buf != NULL);
assert(suffix != NULL);
assert(scale >= 0);
if (flags & HN_DIVISOR_1000) {
/* SI for decimal multiplies */
divisor = 1000;
if (flags & HN_B)
prefixes = "B\0k\0M\0G\0T\0P\0E";
else
prefixes = "\0\0k\0M\0G\0T\0P\0E";
} else {
/*
* binary multiplies
* XXX IEC 60027-2 recommends Ki, Mi, Gi...
*/
divisor = 1024;
if (flags & HN_B)
prefixes = "B\0K\0M\0G\0T\0P\0E";
else
prefixes = "\0\0K\0M\0G\0T\0P\0E";
}
#define SCALE2PREFIX(scale) (&prefixes[(scale) << 1])
maxscale = 7;
if (scale >= maxscale &&
(scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
return (-1);
if (buf == NULL || suffix == NULL)
return (-1);
if (len > 0)
buf[0] = '\0';
if (bytes < 0) {
sign = -1;
scalable *= -100;
baselen = 3; /* sign, digit, prefix */
} else {
sign = 1;
scalable *= 100;
baselen = 2; /* digit, prefix */
}
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 = 100, i = len - baselen; i-- > 0;)
max *= 10;
for (i = 0; scalable >= max && i < maxscale; i++)
scalable /= divisor;
if (scale & HN_GETSCALE)
return (i);
} else
for (i = 0; i < scale && i < maxscale; i++)
scalable /= divisor;
/* If a value <= 9.9 after rounding and ... */
if (scalable < 995 && i > 0 && flags & HN_DECIMAL) {
/* baselen + \0 + .N */
if (len < baselen + 1 + 2)
return (-1);
b = ((int)scalable + 5) / 10;
s1 = b / 10;
s2 = b % 10;
r = snprintf(buf, len, "%s%d%s%d%s%s%s",
((sign == -1) ? "-" : ""),
s1, localeconv()->decimal_point, s2,
sep, SCALE2PREFIX(i), suffix);
} else
r = snprintf(buf, len, "%s%lld%s%s%s",
/* LONGLONG */
((sign == -1) ? "-" : ""),
(long long)((scalable + 50) / 100),
sep, SCALE2PREFIX(i), suffix);
return (r);
}

View 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

93
src/libutil/libutil.h Normal file
View File

@ -0,0 +1,93 @@
/*
* 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;
};
#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);
#ifdef _SYS_PARAM_H_
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);
#endif
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)
/* humanize_number(3) */
#define HN_DECIMAL 0x01
#define HN_NOSPACE 0x02
#define HN_B 0x04
#define HN_DIVISOR_1000 0x08
#define HN_GETSCALE 0x10
#define HN_AUTOSCALE 0x20
#endif /* !_LIBUTIL_H_ */

34
src/libutil/libutil.plist Normal file
View 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
src/libutil/libutil.txt Normal file
View 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.
*/

View File

@ -0,0 +1,575 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXAggregateTarget section */
FDBC26E41741B09300CA4B2B /* osx */ = {
isa = PBXAggregateTarget;
buildConfigurationList = FDBC26E71741B09300CA4B2B /* Build configuration list for PBXAggregateTarget "osx" */;
buildPhases = (
);
dependencies = (
FDBC27001741B1B300CA4B2B /* PBXTargetDependency */,
);
name = osx;
productName = OSX;
};
FDBC26E81741B09D00CA4B2B /* ios */ = {
isa = PBXAggregateTarget;
buildConfigurationList = FDBC26E91741B09D00CA4B2B /* Build configuration list for PBXAggregateTarget "ios" */;
buildPhases = (
);
dependencies = (
FDBC27021741B1B500CA4B2B /* 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 */; };
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 */
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 = "$(INSTALL_PATH_PREFIX)/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 = "$(INSTALL_PATH_PREFIX)/usr/local/OpenSourceVersions";
dstSubfolderSpec = 0;
files = (
BA79F9E913BB77FA006A292D /* libutil.plist in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
BA79F9E813BB77D6006A292D /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = "$(INSTALL_PATH_PREFIX)/usr/local/OpenSourceLicenses";
dstSubfolderSpec = 0;
files = (
BA79F9EA13BB77FF006A292D /* libutil.txt in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
FDBC26EE1741B13400CA4B2B /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "$(INSTALL_PATH_PREFIX)/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; name = base.xcconfig; path = xcconfigs/base.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; };
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;
};
FDBC26ED1741B13400CA4B2B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
BA79F99513BB70D7006A292D = {
isa = PBXGroup;
children = (
3F09C378186D1F73007AF93C /* base.xcconfig */,
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 */,
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 */,
);
sourceTree = "<group>";
};
BA79F9C613BB718B006A292D /* Products */ = {
isa = PBXGroup;
children = (
BA79F9C513BB718B006A292D /* libutil.dylib */,
FDBC26F01741B13400CA4B2B /* tzlinkd */,
);
name = Products;
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 = (
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";
};
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 */,
FDBC26E41741B09300CA4B2B /* osx */,
BA79F9C413BB718B006A292D /* util */,
FDBC26EF1741B13400CA4B2B /* tzlinkd */,
);
};
/* 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;
};
FDBC26EC1741B13400CA4B2B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FDBC27061741B1CF00CA4B2B /* tzlinkd.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
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 */
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;
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;
INSTALL_PATH_ACTUAL = /usr/lib;
PRODUCT_NAME = "$(TARGET_NAME)";
WARNING_CFLAGS = "-Wall";
};
name = Debug;
};
BA79F9C913BB718B006A292D /* Release */ = {
isa = XCBuildConfiguration;
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;
INSTALL_PATH_ACTUAL = /usr/lib;
PRODUCT_NAME = "$(TARGET_NAME)";
WARNING_CFLAGS = "-Wall";
};
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 */
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;
};
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 */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:libutil.xcodeproj">
</FileRef>
</Workspace>

138
src/libutil/mntopts.h Normal file
View 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
src/libutil/pidfile.3 Normal file
View 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
src/libutil/pidfile.c Normal file
View 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
src/libutil/realhostname.3 Normal file
View 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
src/libutil/realhostname.c Normal file
View 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;
}

View 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

View 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.

View File

@ -0,0 +1,215 @@
/*
* 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;
}
kernarch = current_kernel_arch();
progarch = current_program_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
src/libutil/trimdomain.3 Normal file
View 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
src/libutil/trimdomain.c Normal file
View 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);
}

70
src/libutil/tzlink.c Normal file
View File

@ -0,0 +1,70 @@
// Modified by Lubos Dolezel for Darling build
/*
* 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>
#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
# include <xpc/xpc.h>
#endif
#include <errno.h>
#include "tzlink.h"
#include "tzlink_internal.h"
errno_t
tzlink(const char *tz)
{
#if TARGET_OS_IPHONE && !TARGET_IPHONE_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 */
}

56
src/libutil/tzlink.h Normal file
View File

@ -0,0 +1,56 @@
/*
* 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_
/*!
* @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_ */

View 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

View 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>

View 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"))

View File

@ -0,0 +1,10 @@
<?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>
</dict>
</plist>

View File

@ -0,0 +1,194 @@
/*
* 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 "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;
xpc_track_activity();
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)) {
return ENOENT;
}
/* ... owned by root:wheel */
if (sb.st_uid != 0 || sb.st_gid != 0) {
return ENOENT;
}
/* ... 0644 perms */
if ((sb.st_mode & ACCESSPERMS) != 0644) {
return ENOENT;
}
/* ... is a real tzfile (starts with TZif) */
// TODO: Validate contents of file.
return 0;
}

162
src/libutil/wipefs.3 Normal file
View 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).

317
src/libutil/wipefs.cpp Normal file
View File

@ -0,0 +1,317 @@
/*
* 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 <cstring>
#include <strings.h>
#include "ExtentManager.h"
#include "wipefs.h"
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
struct __wipefs_ctx {
int fd;
class ExtentManager extMan;
};
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);
}
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 };
*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;
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;
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);
}
catch (bad_alloc &e) {
err = ENOMEM;
}
catch (...) { // currently only ENOMEM is possible
err = ENOMEM;
}
labelExit:
if (err != 0) {
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;
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 = 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:
if (bufZero != NULL)
delete[] bufZero;
return err;
} // wipefs_wipe
extern "C" void
wipefs_free(wipefs_ctx *handle)
{
if (*handle != NULL) {
delete *handle;
*handle = NULL;
}
}

48
src/libutil/wipefs.h Normal file
View 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

View File

@ -0,0 +1,11 @@
#include "<DEVELOPER_DIR>/Makefiles/CoreOS/Xcode/BSD.xcconfig"
#include "<DEVELOPER_DIR>/AppleInternal/XcodeConfig/SimulatorSupport.xcconfig"
// Set INSTALL_PATH[sdk=macosx*] when SimulatorSupport.xcconfig is unavailable
INSTALL_PATH[sdk=macosx*] = $(INSTALL_PATH_ACTUAL)
// Use $(INSTALL_PATH_PREFIX) instead of $(SDKROOT) as a prefix for other
// variables as appropriate
PUBLIC_HEADERS_FOLDER_PATH = $(INSTALL_PATH_PREFIX)/usr/include
PRIVATE_HEADERS_FOLDER_PATH = $(INSTALL_PATH_PREFIX)/usr/local/include

View File

@ -0,0 +1,33 @@
#include "<DEVELOPER_DIR>/AppleInternal/XcodeConfig/SimulatorSupport.xcconfig"
// Set INSTALL_PATH_ACTUAL to whatever INSTALL_PATH would normally be
INSTALL_PATH_ACTUAL = /usr/sbin
INSTALL_PATH_ACTUAL = /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

View File

@ -16,6 +16,6 @@ set(util-SRCS
leb.cpp
)
add_library(util ${util-SRCS})
set_target_properties(util PROPERTIES COMPILE_FLAGS "-fPIC")
add_library(darling-util ${util-SRCS})
set_target_properties(darling-util PROPERTIES COMPILE_FLAGS "-fPIC")