From owner-svn-soc-all@FreeBSD.ORG Sun May 13 14:23:50 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 0AAB61065670 for ; Sun, 13 May 2012 14:23:48 +0000 (UTC) (envelope-from gpf@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Sun, 13 May 2012 14:23:48 +0000 Date: Sun, 13 May 2012 14:23:48 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120513142348.0AAB61065670@hub.freebsd.org> Cc: Subject: socsvn commit: r235718 - soc2012/gpf X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 May 2012 14:23:50 -0000 Author: gpf Date: Sun May 13 14:23:46 2012 New Revision: 235718 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235718 Log: adding milestones file Added: soc2012/gpf/milestones Added: soc2012/gpf/milestones ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/milestones Sun May 13 14:23:46 2012 (r235718) @@ -0,0 +1,9 @@ +- Extend sbin/pefs so that it creates checksum file with dummy tags/tweaks which is then read during pefs_mount. pf_nodes are properly marked upon creation. + +- Extend sbin/pefs so that it accepts secret key from userland and that proper tags/tweaks are created for checksum file. At this point test with one HMAC algorithm. + +- Integrity checks in Vnode Operations. + +- Implement authentication checks for checksum files during mount. + +- Extension of securelevel and perhaps rtld. From owner-svn-soc-all@FreeBSD.ORG Sun May 13 14:39:43 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id B5913106566B for ; Sun, 13 May 2012 14:39:41 +0000 (UTC) (envelope-from gpf@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Sun, 13 May 2012 14:39:41 +0000 Date: Sun, 13 May 2012 14:39:41 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120513143941.B5913106566B@hub.freebsd.org> Cc: Subject: socsvn commit: r235719 - in soc2012/gpf/pefs_kmod: . lib lib/libpam lib/libpam/modules lib/libpam/modules/pam_pefs sbin sbin/pefs sys sys/crypto sys/crypto/hmac sys/crypto/rijndael sys/crypto/sha2 ... X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 May 2012 14:39:44 -0000 Author: gpf Date: Sun May 13 14:39:41 2012 New Revision: 235719 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235719 Log: merging pefs.kmod to my branch Added: soc2012/gpf/pefs_kmod/ soc2012/gpf/pefs_kmod/Makefile soc2012/gpf/pefs_kmod/README soc2012/gpf/pefs_kmod/lib/ soc2012/gpf/pefs_kmod/lib/libpam/ soc2012/gpf/pefs_kmod/lib/libpam/modules/ soc2012/gpf/pefs_kmod/lib/libpam/modules/Makefile.inc soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/ soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/Makefile soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/pam_pefs.8 soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/pam_pefs.c soc2012/gpf/pefs_kmod/sbin/ soc2012/gpf/pefs_kmod/sbin/pefs/ soc2012/gpf/pefs_kmod/sbin/pefs/Makefile soc2012/gpf/pefs_kmod/sbin/pefs/pefs.8 soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h soc2012/gpf/pefs_kmod/sbin/pefs/pefs_key.c soc2012/gpf/pefs_kmod/sbin/pefs/pefs_keychain.c soc2012/gpf/pefs_kmod/sbin/pefs/pefs_keychain.h soc2012/gpf/pefs_kmod/sbin/pefs/pefs_subr.c soc2012/gpf/pefs_kmod/sys/ soc2012/gpf/pefs_kmod/sys/crypto/ soc2012/gpf/pefs_kmod/sys/crypto/hmac/ soc2012/gpf/pefs_kmod/sys/crypto/hmac/hmac_sha512.c soc2012/gpf/pefs_kmod/sys/crypto/hmac/hmac_sha512.h soc2012/gpf/pefs_kmod/sys/crypto/rijndael/ soc2012/gpf/pefs_kmod/sys/crypto/rijndael/rijndael-alg-fst.c soc2012/gpf/pefs_kmod/sys/crypto/rijndael/rijndael-api-fst.c soc2012/gpf/pefs_kmod/sys/crypto/rijndael/rijndael-api-fst.h soc2012/gpf/pefs_kmod/sys/crypto/rijndael/rijndael-api.c soc2012/gpf/pefs_kmod/sys/crypto/rijndael/rijndael.h soc2012/gpf/pefs_kmod/sys/crypto/rijndael/rijndael_local.h soc2012/gpf/pefs_kmod/sys/crypto/sha2/ soc2012/gpf/pefs_kmod/sys/crypto/sha2/sha2.c soc2012/gpf/pefs_kmod/sys/crypto/sha2/sha2.h soc2012/gpf/pefs_kmod/sys/fs/ soc2012/gpf/pefs_kmod/sys/fs/pefs/ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_aesni.c soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_aesni.h soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_crypto.c soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_crypto.h soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_dircache.c soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_dircache.h soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_subr.c soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vfsops.c soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_xbase64.c soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_xts.c soc2012/gpf/pefs_kmod/sys/fs/pefs/vmac.c soc2012/gpf/pefs_kmod/sys/fs/pefs/vmac.h soc2012/gpf/pefs_kmod/sys/geom/ soc2012/gpf/pefs_kmod/sys/geom/eli/ soc2012/gpf/pefs_kmod/sys/geom/eli/pkcs5v2.c soc2012/gpf/pefs_kmod/sys/geom/eli/pkcs5v2.h soc2012/gpf/pefs_kmod/sys/modules/ soc2012/gpf/pefs_kmod/sys/modules/pefs/ soc2012/gpf/pefs_kmod/sys/modules/pefs/Makefile Added: soc2012/gpf/pefs_kmod/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/pefs_kmod/Makefile Sun May 13 14:39:41 2012 (r235719) @@ -0,0 +1,7 @@ +SUBDIR= sys/modules/pefs \ + sbin/pefs + +# Should be built from sources tree +SUBDIR+= lib/libpam/modules/pam_pefs + +.include Added: soc2012/gpf/pefs_kmod/README ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/pefs_kmod/README Sun May 13 14:39:41 2012 (r235719) @@ -0,0 +1,32 @@ +PEFS is a kernel level stacked cryptographic filesystem for FreeBSD. + +The following is a list of its most important features: + +* Kernel level file system, no user level daemons needed. Transparently runs + on top of existing file systems. + +* Random per file tweak value used for encryption, which guaranties different + cipher texts for the same encrypted files. + +* Saves metadata only in encrypted file name, but not in file itself. + +* Supports arbitrary number of keys per file system, default directory key, + mixing files encrypted with different keys in same directory. + +* Allows defining key chains, can be used to add/delete several keys by + specifying only master key. + +* Uses modern cryptographic algorithms: AES and Camellia in XTS mode, + PKCS#5v2 and HKDF for key generation. + +FreeBSD wiki page: http://wiki.freebsd.org/PEFS +blog: http://glebkurtsou.blogspot.com/search/label/pefs + + +Installation instructions: + +# git clone git://github.com/glk/pefs.git pefs +# cd pefs +# make obj all +# make install +# make clean Added: soc2012/gpf/pefs_kmod/lib/libpam/modules/Makefile.inc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/pefs_kmod/lib/libpam/modules/Makefile.inc Sun May 13 14:39:41 2012 (r235719) @@ -0,0 +1,4 @@ +# Include Makefiles from $SRCDIR + +.include + Added: soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/Makefile Sun May 13 14:39:41 2012 (r235719) @@ -0,0 +1,24 @@ +# PAM module for pefs +# $FreeBSD$ + +SYS= ${.CURDIR}/../../../../sys +PEFSDIR= ${.CURDIR}/../../../../sbin/pefs + +LIB= pam_pefs +MAN= pam_pefs.8 +SRCS= pam_pefs.c +SRCS+= pefs_key.c pefs_keychain.c pefs_subr.c +SRCS+= hmac_sha512.c pkcs5v2.c sha2.c +SRCS+= rijndael-api.c rijndael-api-fst.c rijndael-alg-fst.c + +CFLAGS+= -I${PEFSDIR} +CFLAGS+= -I${SYS} + +DPADD= ${LIBUTIL} +LDADD= -lutil + +.include + +.PATH: ${PEFSDIR} +.PATH: ${SYS}/geom/eli +.PATH: ${SYS}/crypto/hmac ${SYS}/crypto/sha2 ${SYS}/crypto/rijndael Added: soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/pam_pefs.8 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/pam_pefs.8 Sun May 13 14:39:41 2012 (r235719) @@ -0,0 +1,147 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. +.\" Copyright (c) 2009 Gleb Kurtsou +.\" All rights reserved. +.\" +.\" This software was 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, 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. 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$ +.\" +.Dd December 1, 2009 +.Dt PAM_PEFS 8 +.Os +.Sh NAME +.Nm pam_pefs +.Nd pefs PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_pefs +.Op Ar options +.Sh DESCRIPTION +The +pefs +authentication service module for PAM, +.Nm +provides functionality for two PAM categories: +authentication +and session management. +In terms of the +.Ar module-type +parameter, they are the +.Dq Li auth +and +.Dq Li session +features. +.Pp +Module expects pefs file system to be mounted on user home directory +and fails otherwise. +.Ss Pefs Authentication Module +The +pefs +authentication component +provides a function to verify the identity of a user +.Pq Fn pam_sm_authenticate , +by prompting the user for a passphrase and verifying that it exists in +pefs key chain database. +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm use_first_pass" +.It Cm use_first_pass +If the authentication module +is not the first in the stack, +and a previous module +obtained the user's password, +that password is used +to authenticate the user. +If this fails, +the authentication module returns failure +without prompting the user for a password. +This option has no effect +if the authentication module +is the first in the stack, +or if no previous modules +obtained the user's password. +.It Cm try_first_pass +This option is similar to the +.Cm use_first_pass +option, +except that if the previously obtained password fails, +the user is prompted for another password. +.It Cm ignore_missing +Accept any passphrase provided by the user. +This option is used not to authenticate user, but to preserve keys that +should be added to pefs file system by session management module. +Option is incompatible with +.Cm try_first_pass +option and should be used with +.Cm use_first_pass +option. +.It Cm delkeys +Remove keys at the end of last session. +Module tracks the number of concurrent sessions, removing all keys from +file system when session count reaches zero. +.El +.Ss Pefs Session Management Module +The +pefs +session management component +provides functions to initiate +.Pq Fn pam_sm_open_session +and terminate +.Pq Fn pam_sm_close_session +sessions. +The +.Fn pam_sm_open_session +function adds key or key chain decrypted during the authentication phase +to the pefs file system mounted on user home directory. +.Sh FILES +.Bl -tag -width ".Pa $HOME/.pefs.conf" -compact +.It Pa $HOME/.pefs.conf +pefs configuration file +.It Pa $HOME/.pefs.db +pefs key chain database file +.El +.Sh SEE ALSO +.Xr pam.conf 5 , +.Xr pam 8 +.Xr pefs 8 +.Sh AUTHORS +The +.Nm +module was written by +.An -nosplit +.An "Gleb Kurtsou" Aq gk@FreeBSD.org . +.Sh BUGS +.Fn pam_sm_close_session +function +doesn't delete keys added during by +.Fn pam_sm_open_session . Added: soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/pam_pefs.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/pefs_kmod/lib/libpam/modules/pam_pefs/pam_pefs.c Sun May 13 14:39:41 2012 (r235719) @@ -0,0 +1,526 @@ +/*- + * Copyright (c) 2003 Networks Associates Technology, Inc. + * Copyright (c) 2009 Gleb Kurtsou + * All rights reserved. + * + * This software was 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, 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. 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PAM_SM_AUTH +#define PAM_SM_SESSION + +#include +#include +#include +#include + +#include + +#include "pefs_ctl.h" +#include "pefs_keychain.h" + +#define PEFS_OPT_IGNORE_MISSING "ignore_missing" +#define PEFS_OPT_DELKEYS "delkeys" + +#define PAM_PEFS_KEYS "pam_pefs_keys" + +#define PEFS_SESSION_DIR "/var/run/pefs" +#define PEFS_SESSION_DIR_MODE 0700 +#define PEFS_SESSION_FILE_MODE 0600 +#define PEFS_SESSION_FILE_FLAGS \ + (O_RDWR | O_NONBLOCK | O_CREAT | O_EXLOCK) + +static int pam_pefs_debug; + +void +pefs_warn(const char *fmt, ...) +{ + static const char *label = "pam_pefs: "; + char buf[BUFSIZ]; + va_list ap; + + if (pam_pefs_debug == 0) + return; + + va_start(ap, fmt); + if (strlen(fmt) + sizeof(label) >= sizeof(buf)) { + vsyslog(LOG_DEBUG, fmt, ap); + } else { + strlcpy(buf, label, sizeof(buf)); + strlcat(buf, fmt, sizeof(buf)); + vsyslog(LOG_DEBUG, buf, ap); + } + va_end(ap); +} + +static int +flopen_retry(const char *filename) +{ + int fd, try; + + for (try = 1; try <= 1024; try *= 2) { + fd = flopen(filename, PEFS_SESSION_FILE_FLAGS, + PEFS_SESSION_FILE_MODE); + if (fd != -1) + return (fd); + else if (errno != EWOULDBLOCK) + return (-1); + // Exponential back-off up to 1 second + usleep(try * 1000000 / 1024); + } + errno = ETIMEDOUT; + return (-1); +} + +static int +pefs_session_count_incr(const char *user, bool incr) +{ + struct stat sb; + struct timespec tp_uptime, tp_now; + ssize_t offset; + int fd, total = 0; + char filename[MAXPATHLEN], buf[16]; + const char *errstr; + + snprintf(filename, sizeof(filename), "%s/%s", PEFS_SESSION_DIR, user); + + if (lstat(PEFS_SESSION_DIR, &sb) == -1) { + if (errno != ENOENT) { + pefs_warn("unable to access session directory %s: %s", + PEFS_SESSION_DIR, strerror(errno)); + return (-1); + } + if (mkdir(PEFS_SESSION_DIR, PEFS_SESSION_DIR_MODE) == -1) { + pefs_warn("unable to create session directory %s: %s", + PEFS_SESSION_DIR, strerror(errno)); + return (-1); + } + } else if (!S_ISDIR(sb.st_mode)) { + pefs_warn("%s is not a directory", PEFS_SESSION_DIR); + return (-1); + } + + if ((fd = flopen_retry(filename)) == -1) { + pefs_warn("unable to create session counter file %s: %s", + filename, strerror(errno)); + return (-1); + } + + if ((offset = pread(fd, buf, sizeof(buf) - 1, 0)) == -1) { + pefs_warn("unable to read from the session counter file %s: %s", + filename, strerror(errno)); + close(fd); + return (-1); + } + buf[offset] = '\0'; + if (offset != 0) { + total = strtonum(buf, 0, INT_MAX, &errstr); + if (errstr != NULL) + pefs_warn("corrupted session counter file: %s: %s", + filename, errstr); + } + + /* + * Determine if this is the first increment of the session file. + * + * It is considered the first increment if the session file has not + * been modified since the last boot time. + */ + if (incr && total > 0) { + if (fstat(fd, &sb) == -1) { + pefs_warn("unable to access session counter file %s: %s", + filename, strerror(errno)); + close(fd); + return (-1); + } + /* + * Check is messy and will fail if wall clock isn't monotonical + * (e.g. because of ntp, DST, leap seconds) + */ + clock_gettime(CLOCK_REALTIME_FAST, &tp_now); + clock_gettime(CLOCK_UPTIME_FAST, &tp_uptime); + if (sb.st_mtime < tp_now.tv_sec - tp_uptime.tv_sec) { + pefs_warn("stale session counter file: %s", + filename); + total = 0; + } + } + + lseek(fd, 0L, SEEK_SET); + ftruncate(fd, 0L); + + total += incr ? 1 : -1; + if (total < 0) { + pefs_warn("corrupted session counter file: %s", + filename); + total = 0; + } else + pefs_warn("%s: session count %d", user, total); + + buf[0] = '\0'; + snprintf(buf, sizeof(buf), "%d", total); + pwrite(fd, buf, strlen(buf), 0); + close(fd); + + return (total); +} + +static int +pam_pefs_checkfs(const char *homedir) +{ + char fsroot[MAXPATHLEN]; + int error; + + error = pefs_getfsroot(homedir, 0, fsroot, sizeof(fsroot)); + if (error != 0) { + pefs_warn("file system is not mounted: %s", homedir); + return (PAM_USER_UNKNOWN); + } if (strcmp(fsroot, homedir) != 0) { + pefs_warn("file system is not mounted on home dir: %s", fsroot); + return (PAM_USER_UNKNOWN); + } + + return (PAM_SUCCESS); +} + +/* + * Perform key lookup in ~/.pefs; + * returns PAM_AUTH_ERR if and only if key wasn't found in database. + */ +static int +pam_pefs_getkeys(struct pefs_keychain_head *kch, + const char *homedir, const char *passphrase, int chainflags) +{ + struct pefs_xkey k; + struct pefs_keyparam kp; + int error; + + pefs_keyparam_create(&kp); + pefs_keyparam_init(&kp, homedir); + + error = pefs_key_generate(&k, passphrase, &kp); + if (error != 0) + return (PAM_SERVICE_ERR); + + error = pefs_keychain_get(kch, homedir, chainflags, &k); + bzero(&k, sizeof(k)); + if (error != 0) + return (error == PEFS_ERR_NOENT ? PAM_AUTH_ERR : + PAM_SERVICE_ERR); + + return (PAM_SUCCESS); +} + +static int +pam_pefs_addkeys(const char *homedir, struct pefs_keychain_head *kch) +{ + struct pefs_keychain *kc; + int fd; + + fd = open(homedir, O_RDONLY); + if (fd == -1) { + pefs_warn("cannot open homedir %s: %s", + homedir, strerror(errno)); + return (PAM_USER_UNKNOWN); + } + + TAILQ_FOREACH(kc, kch, kc_entry) { + if (ioctl(fd, PEFS_ADDKEY, &kc->kc_key) == -1) { + pefs_warn("cannot add key: %s: %s", + homedir, strerror(errno)); + break; + } + } + close(fd); + + return (PAM_SUCCESS); +} + +static int +pam_pefs_delkeys(const char *homedir) +{ + struct pefs_xkey k; + int fd; + + fd = open(homedir, O_RDONLY); + if (fd == -1) { + pefs_warn("cannot open homedir %s: %s", + homedir, strerror(errno)); + return (PAM_USER_UNKNOWN); + } + + bzero(&k, sizeof(k)); + while (1) { + if (ioctl(fd, PEFS_GETKEY, &k) == -1) + break; + + if (ioctl(fd, PEFS_DELKEY, &k) == -1) { + pefs_warn("cannot del key: %s: %s", + homedir, strerror(errno)); + k.pxk_index++; + } + } + close(fd); + + return (PAM_SUCCESS); +} + +static void +pam_pefs_freekeys(pam_handle_t *pamh __unused, void *data, int pam_err __unused) +{ + struct pefs_keychain_head *kch = data; + + pefs_keychain_free(kch); + free(kch); +} + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, + int argc __unused, const char *argv[] __unused) +{ + struct pefs_keychain_head *kch; + struct passwd *pwd; + const char *passphrase, *user; + const void *item; + int pam_err, canretry, chainflags; + + /* Get user name and home directory */ + pam_err = pam_get_user(pamh, &user, NULL); + if (pam_err != PAM_SUCCESS) + return (pam_err); + pwd = getpwnam(user); + if (pwd == NULL) + return (PAM_USER_UNKNOWN); + if (pwd->pw_dir == NULL) + return (PAM_AUTH_ERR); + + pam_pefs_debug = (openpam_get_option(pamh, PAM_OPT_DEBUG) != NULL); + + chainflags = PEFS_KEYCHAIN_USE; + if (openpam_get_option(pamh, PEFS_OPT_IGNORE_MISSING) != NULL) + chainflags = PEFS_KEYCHAIN_IGNORE_MISSING; + + canretry = (pam_get_item(pamh, PAM_AUTHTOK, &item) == PAM_SUCCESS && + item != NULL && chainflags != PEFS_KEYCHAIN_IGNORE_MISSING); + + pam_err = openpam_borrow_cred(pamh, pwd); + if (pam_err != PAM_SUCCESS) + return (pam_err); + + /* + * Check to see if the passwd db is available, avoids asking for + * password if we cannot even validate it. + */ + pam_err = pam_pefs_checkfs(pwd->pw_dir); + openpam_restore_cred(pamh); + if (pam_err != PAM_SUCCESS) + return (pam_err); + + +retry: + /* Get passphrase */ + pam_err = pam_get_authtok(pamh, PAM_AUTHTOK, + &passphrase, NULL); + if (pam_err != PAM_SUCCESS) + return (pam_err); + + if (*passphrase != '\0') { + kch = calloc(1, sizeof(*kch)); + if (kch == NULL) + return (PAM_SYSTEM_ERR); + + /* Switch to user credentials */ + pam_err = openpam_borrow_cred(pamh, pwd); + if (pam_err != PAM_SUCCESS) + return (pam_err); + + pam_err = pam_pefs_getkeys(kch, pwd->pw_dir, passphrase, + chainflags); + if (pam_err == PAM_SUCCESS) + pam_set_data(pamh, PAM_PEFS_KEYS, kch, + pam_pefs_freekeys); + else + free(kch); + + /* Switch back to arbitrator credentials */ + openpam_restore_cred(pamh); + } else + pam_err = PAM_AUTH_ERR; + + /* + * If we tried an old token and didn't get anything, and + * try_first_pass was specified, try again after prompting the + * user for a new passphrase. + */ + if (pam_err == PAM_AUTH_ERR && canretry != 0 && + openpam_get_option(pamh, "try_first_pass") != NULL) { + pam_set_item(pamh, PAM_AUTHTOK, NULL); + canretry = 0; + goto retry; + } + + return (pam_err); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, + int argc __unused, const char *argv[] __unused) +{ + + return (PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh, int flags __unused, + int argc __unused, const char *argv[] __unused) +{ + struct pefs_keychain_head *kch = NULL; + struct passwd *pwd; + const char *user; + int pam_err, opt_delkeys; + + pam_err = pam_get_user(pamh, &user, NULL); + if (pam_err != PAM_SUCCESS) + return (pam_err); + pwd = getpwnam(user); + if (pwd == NULL) + return (PAM_USER_UNKNOWN); + if (pwd->pw_dir == NULL) + return (PAM_SYSTEM_ERR); + + pam_pefs_debug = (openpam_get_option(pamh, PAM_OPT_DEBUG) != NULL); + opt_delkeys = (openpam_get_option(pamh, PEFS_OPT_DELKEYS) != NULL); + + pam_err = pam_get_data(pamh, PAM_PEFS_KEYS, + (const void **)(void *)&kch); + if (pam_err != PAM_SUCCESS || kch == NULL || TAILQ_EMPTY(kch)) { + pam_err = PAM_SUCCESS; + opt_delkeys = 0; + goto out; + } + + /* Switch to user credentials */ + pam_err = openpam_borrow_cred(pamh, pwd); + if (pam_err != PAM_SUCCESS) + goto out; + + pam_err = pam_pefs_checkfs(pwd->pw_dir); + if (pam_err != PAM_SUCCESS) { + openpam_restore_cred(pamh); + pam_err = PAM_SUCCESS; + opt_delkeys = 0; + goto out; + } + + pam_err = pam_pefs_addkeys(pwd->pw_dir, kch); + + /* Switch back to arbitrator credentials */ + openpam_restore_cred(pamh); + +out: + /* Remove keys from memory */ + if (kch != NULL) + pefs_keychain_free(kch); + + /* Increment login count */ + if (pam_err == PAM_SUCCESS && opt_delkeys) + pefs_session_count_incr(user, true); + + return (pam_err); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh, int flags __unused, + int argc __unused, const char *argv[] __unused) +{ + struct passwd *pwd; + const char *user; + int pam_err, opt_delkeys; + + pam_err = pam_get_user(pamh, &user, NULL); + if (pam_err != PAM_SUCCESS) + return (pam_err); + + pwd = getpwnam(user); + if (pwd == NULL) + return (PAM_USER_UNKNOWN); + if (pwd->pw_dir == NULL) + return (PAM_SYSTEM_ERR); + + pam_pefs_debug = (openpam_get_option(pamh, PAM_OPT_DEBUG) != NULL); + opt_delkeys = (openpam_get_option(pamh, PEFS_OPT_DELKEYS) != NULL); + if (!opt_delkeys) + return PAM_SUCCESS; + + pam_err = openpam_borrow_cred(pamh, pwd); + if (pam_err != PAM_SUCCESS) + return (pam_err); + pam_err = pam_pefs_checkfs(pwd->pw_dir); + openpam_restore_cred(pamh); + if (pam_err != PAM_SUCCESS) + return (PAM_SUCCESS); + + /* Decrease login count and remove keys if at zero */ + pam_err = PAM_SUCCESS; + if (pefs_session_count_incr(user, false) == 0) { + pam_err = openpam_borrow_cred(pamh, pwd); + if (pam_err != PAM_SUCCESS) + return (pam_err); + pam_err = pam_pefs_delkeys(pwd->pw_dir); + openpam_restore_cred(pamh); + } + + return (pam_err); +} + +PAM_MODULE_ENTRY("pam_pefs"); Added: soc2012/gpf/pefs_kmod/sbin/pefs/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/pefs_kmod/sbin/pefs/Makefile Sun May 13 14:39:41 2012 (r235719) @@ -0,0 +1,24 @@ +# $FreeBSD$ + +SYS= ${.CURDIR}/../../sys +.PATH: ${SYS}/geom/eli +.PATH: ${SYS}/crypto/hmac ${SYS}/crypto/rijndael ${SYS}/crypto/sha2 + +PROG= pefs +SRCS= pefs_ctl.c pefs_key.c pefs_keychain.c pefs_subr.c +SRCS+= hmac_sha512.c sha2.c +SRCS+= rijndael-api.c rijndael-api-fst.c rijndael-alg-fst.c +SRCS+= pkcs5v2.c + +MAN= pefs.8 + +CFLAGS+=-I${SYS} +WARNS?= 6 +DEBUG_FLAGS+= -g + +DPADD= ${LIBUTIL} +LDADD= -lutil + +BINDIR?= /sbin + +.include Added: soc2012/gpf/pefs_kmod/sbin/pefs/pefs.8 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs.8 Sun May 13 14:39:41 2012 (r235719) @@ -0,0 +1,441 @@ +.\" Copyright (c) 2005-2008 Pawel Jakub Dawidek +.\" Copyright (c) 2009 Gleb Kurtsou +.\" 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$ +.\" +.Dd December 1, 2009 +.Dt PEFS 8 +.Os +.Sh NAME +.Nm pefs +.Nd configure pefs file systems +.Sh SYNOPSIS +.Nm +.Cm mount +.Op Fl o Ar options +.Op Ar from filesystem +.Nm +.Cm unmount +.Op Fl fv +.Ar filesystem +.Pp +.Nm +.Cm addkey +.Op Fl cCpv +.Op Fl a Ar alg +.Op Fl i Ar iterations +.Op Fl k Ar keyfile +.Ar filesystem +.Nm +.Cm delkey +.Op Fl cCpv +.Op Fl i Ar iterations +.Op Fl k Ar keyfile +.Ar filesystem +.Nm +.Cm flushkeys +.Ar filesystem +.Nm +.Cm getkey +.Op Fl t +.Ar file +.Nm +.Cm setkey +.Op Fl cCpvx +.Op Fl a Ar alg +.Op Fl i Ar iterations +.Op Fl k Ar keyfile +.Ar directory +.Nm +.Cm showkeys +.Op Fl t +.Ar filesystem +.Pp +.Nm +.Cm addchain +.Op Fl fpPvZ +.Op Fl a Ar alg +.Op Fl i Ar iterations +.Op Fl k Ar keyfile +.Op Fl A Ar alg +.Op Fl I Ar iterations +.Op Fl K Ar keyfile +.Ar filesystem +.Nm +.Cm delchain +.Op Fl fFpv +.Op Fl i Ar iterations +.Op Fl k Ar keyfile +.Ar filesystem +.Nm +.Cm randomchain +.Op Fl fv +.Op Fl i Ar iterations +.Op Fl k Ar keyfile +.Ar filesystem +.Nm +.Cm showchains +.Op Fl fp +.Op Fl i Ar iterations +.Op Fl k Ar keyfile +.Ar filesystem +.Pp +.Nm +.Cm showalgs +.Sh DESCRIPTION +The +.Nm +utility is the user interface for configuring stacked cryptographic file system. +.Pp +The following is a list of the most important file system features: +.Bl -bullet -offset indent -compact +.It +Kernel level file system, no user level daemons needed. +Transparently runs on top of existing file systems. +.It +Random per file tweak value used for encryption, which guaranties different +cipher texts for the same encrypted files. +.It +Saves metadata only in encrypted file name, but not in file itself. +.It +Supports arbitrary number of keys per file system, default directory key, +mixing files encrypted with different keys in same directory. +.It +Allows defining key chains, can be used to add/delete several keys by +specifying only master key. +.It +Uses modern cryptographic algorithms: AES and Camellia in XTS mode, +PKCS#5v2 and HKDF for key generation. +.El +.Pp +First argument of +.Nm +utility indicates the command to be performed (see the +.Sx COMMAND OPTIONS +section for information on options): +.Bl -tag -width indent +.It Cm mount +Mount file system. +Encryption keys should be specified separately after mounting the file system. +If no agrumnt specified prints all mounted +.Nm +file systems. +See +.Xr mount 8 +for more information. +.It Cm unmount Ar filesystem +Unmount +.Ar filesystem . +.Fl f +and +.Fl v +options can be specified to force unmount or enable verbose mode respectively. +See +.Xr umount 8 +for more information. +.It Cm addkey Ar filesystem +Add key to the +.Ar filesystem +.It Cm delkey Ar filesystem +Delete key from +.Ar filesystem . +Command doesn't accept +.Fl a Ar alg +argument because the key fingerprint generated from the key doesn't depend on +encryption algorithm. +.It Cm getkey Ar file +Print fingerprint of the key used by +.Ar file . +.It Cm flushkeys Ar filesystem +Delete all keys from +.Ar filesystem . +After the command all opened files would become unavailable. +.It Cm setkey Ar directory +Change default key for the +.Ar directory . +Default key is used as a new key for files and directories created in the +.Ar directory . +Technically just a rename takes place on underlaying file system. +Keys for entries in the +.Ar directory +are not changed and no data is re-encrypted with new key. +.Fl x +option can be used to add a new key to file system if it isn't found. +.It Cm showkeys Ar filesystem +Print fingerprints if all active keys. +.It Cm addchain Ar filesystem +Add a new key chain element. +Element consists of parent and child keys. +Parent key is defined by +.Fl a , Fl i +and +.Fl p +options and child key by equivalent +.Fl A , Fl I +and +.Fl P +options. +Element consisting only of a parent key can be constructed by specifying +.Fl Z +option. +.Fl f +option disables file system type checks making manipulation on key chains +possible without mounting +.Nm +file system. +See +.Sx KEY CHAINS +section for more information. +.It Cm delchain Ar filesystem +Delete key chain element defined by parent key. *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-soc-all@FreeBSD.ORG Mon May 14 14:04:03 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 9FDF01065670 for ; Mon, 14 May 2012 14:04:02 +0000 (UTC) (envelope-from vbotton@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Mon, 14 May 2012 14:04:02 +0000 Date: Mon, 14 May 2012 14:04:02 +0000 From: vbotton@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120514140402.9FDF01065670@hub.freebsd.org> Cc: Subject: socsvn commit: r235762 - soc2012/vbotton/ntfs_apple X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 May 2012 14:04:03 -0000 Author: vbotton Date: Mon May 14 14:04:01 2012 New Revision: 235762 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235762 Log: Some works towards portability, essentially endianness related functions Added: soc2012/vbotton/ntfs_apple/ soc2012/vbotton/ntfs_apple/ntfs.h soc2012/vbotton/ntfs_apple/ntfs_attr.c soc2012/vbotton/ntfs_apple/ntfs_attr.h soc2012/vbotton/ntfs_apple/ntfs_attr_list.c soc2012/vbotton/ntfs_apple/ntfs_attr_list.h soc2012/vbotton/ntfs_apple/ntfs_bitmap.c soc2012/vbotton/ntfs_apple/ntfs_bitmap.h soc2012/vbotton/ntfs_apple/ntfs_collate.c soc2012/vbotton/ntfs_apple/ntfs_collate.h soc2012/vbotton/ntfs_apple/ntfs_compress.c soc2012/vbotton/ntfs_apple/ntfs_compress.h soc2012/vbotton/ntfs_apple/ntfs_debug.c soc2012/vbotton/ntfs_apple/ntfs_debug.h soc2012/vbotton/ntfs_apple/ntfs_dir.c soc2012/vbotton/ntfs_apple/ntfs_dir.h soc2012/vbotton/ntfs_apple/ntfs_endian.h soc2012/vbotton/ntfs_apple/ntfs_hash.c soc2012/vbotton/ntfs_apple/ntfs_hash.h soc2012/vbotton/ntfs_apple/ntfs_index.c soc2012/vbotton/ntfs_apple/ntfs_index.h soc2012/vbotton/ntfs_apple/ntfs_inode.c soc2012/vbotton/ntfs_apple/ntfs_inode.h soc2012/vbotton/ntfs_apple/ntfs_layout.h soc2012/vbotton/ntfs_apple/ntfs_lcnalloc.c soc2012/vbotton/ntfs_apple/ntfs_lcnalloc.h soc2012/vbotton/ntfs_apple/ntfs_logfile.c soc2012/vbotton/ntfs_apple/ntfs_logfile.h soc2012/vbotton/ntfs_apple/ntfs_mft.c soc2012/vbotton/ntfs_apple/ntfs_mft.h soc2012/vbotton/ntfs_apple/ntfs_mst.c soc2012/vbotton/ntfs_apple/ntfs_mst.h soc2012/vbotton/ntfs_apple/ntfs_page.c soc2012/vbotton/ntfs_apple/ntfs_page.h soc2012/vbotton/ntfs_apple/ntfs_quota.c soc2012/vbotton/ntfs_apple/ntfs_quota.h soc2012/vbotton/ntfs_apple/ntfs_runlist.c soc2012/vbotton/ntfs_apple/ntfs_runlist.h soc2012/vbotton/ntfs_apple/ntfs_secure.c soc2012/vbotton/ntfs_apple/ntfs_secure.h soc2012/vbotton/ntfs_apple/ntfs_sfm.c soc2012/vbotton/ntfs_apple/ntfs_sfm.h soc2012/vbotton/ntfs_apple/ntfs_time.h soc2012/vbotton/ntfs_apple/ntfs_types.h soc2012/vbotton/ntfs_apple/ntfs_unistr.c soc2012/vbotton/ntfs_apple/ntfs_unistr.h soc2012/vbotton/ntfs_apple/ntfs_usnjrnl.c soc2012/vbotton/ntfs_apple/ntfs_usnjrnl.h soc2012/vbotton/ntfs_apple/ntfs_vfsops.c soc2012/vbotton/ntfs_apple/ntfs_vnops.c soc2012/vbotton/ntfs_apple/ntfs_vnops.h soc2012/vbotton/ntfs_apple/ntfs_volume.h Added: soc2012/vbotton/ntfs_apple/ntfs.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/vbotton/ntfs_apple/ntfs.h Mon May 14 14:04:01 2012 (r235762) @@ -0,0 +1,167 @@ +/* + * ntfs.h - Some generic defines for the NTFS kernel driver. + * + * Copyright (c) 2006-2008 Anton Altaparmakov. All Rights Reserved. + * Portions Copyright (c) 2006-2008 Apple Inc. 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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. + * + * ALTERNATIVELY, provided that this notice and licensing terms are retained in + * full, this file may be redistributed and/or modified under the terms of the + * GNU General Public License (GPL) Version 2, in which case the provisions of + * that version of the GPL will apply to you instead of the license terms + * above. You can obtain a copy of the GPL Version 2 at + * http://developer.apple.com/opensource/licenses/gpl-2.txt. + */ + +#ifndef _OSX_NTFS_H +#define _OSX_NTFS_H + +#ifdef KERNEL + +#include +#include + +/* The email address of the NTFS developers. */ +__private_extern__ const char ntfs_dev_email[]; +__private_extern__ const char ntfs_please_email[]; + +/* + * Lock group and lock attribute for de-/initialization of locks (defined + * in ntfs_vfsops.c). + */ +__private_extern__ lck_grp_t *ntfs_lock_grp; +__private_extern__ lck_attr_t *ntfs_lock_attr; + +/* + * A tag for allocation and freeing of memory (defined in ntfs_vfsops.c). + */ +__private_extern__ OSMallocTag ntfs_malloc_tag; + +#include "ntfs_volume.h" + +/** + * NTFS_MP - return the NTFS volume given a vfs mount + * @mp: VFS mount + * + * NTFS_MP() returns the NTFS volume associated with the VFS mount @mp. + */ +static inline ntfs_volume *NTFS_MP(mount_t mp) +{ + return (ntfs_volume*)vfs_fsprivate(mp); +} + +__private_extern__ void ntfs_do_postponed_release(ntfs_volume *vol); + +#endif /* KERNEL */ + +#include "ntfs_endian.h" +#include "ntfs_types.h" + +/* Some useful constants to do with NTFS. */ +enum { + NTFS_BLOCK_SIZE = 512, + NTFS_BLOCK_SIZE_SHIFT = 9, + NTFS_MAX_NAME_LEN = 255, + NTFS_MAX_ATTR_NAME_LEN = 255, + NTFS_MAX_SECTOR_SIZE = 4096, /* 4kiB */ + NTFS_MAX_CLUSTER_SIZE = 64 * 1024, /* 64kiB */ + NTFS_ALLOC_BLOCK = 1024, + NTFS_MAX_HARD_LINKS = 65535, /* 2^16 - 1 */ + NTFS_MAX_ATTR_LIST_SIZE = 256 * 1024, /* 256kiB, corresponding to the + VACB_MAPPING_GRANULARITY on + Windows. */ + NTFS_COMPRESSION_UNIT = 4, +}; + +/* + * The maximum attribute size on NTFS is 2^63 - 1 bytes as it is stored in a + * signed 64 bit type (s64). + */ +#define NTFS_MAX_ATTRIBUTE_SIZE 0x7fffffffffffffffULL + +/* + * The maximum number of MFT records allowed on NTFS is 2^32 as described in + * various documentation to be found on the Microsoft web site. This is an + * imposed limit rather than an inherent NTFS format limit. + */ +#define NTFS_MAX_NR_MFT_RECORDS 0x100000000ULL + +// TODO: Constants so ntfs_vfsops.c compiles for now... +enum { + /* One of these must be present, default is ON_ERRORS_CONTINUE. */ + ON_ERRORS_PANIC = 0x01, + ON_ERRORS_REMOUNT_RO = 0x02, + ON_ERRORS_CONTINUE = 0x04, + /* Optional, can be combined with any of the above. */ + ON_ERRORS_RECOVER = 0x10, +}; + +/* + * The NTFS mount options header passed in from user space. + */ +typedef struct { +#ifndef KERNEL + char *fspec; /* Path of device to mount, consumed by mount(2). */ +#endif /* !KERNEL */ + u8 major_ver; /* The major version of the mount options structure. */ + u8 minor_ver; /* The minor version of the mount options structure. */ +} __attribute__((__packed__)) ntfs_mount_options_header; + +/* + * The NTFS mount options passed in from user space. This follows the + * ntfs_mount_options_header aligned to an eight byte boundary. + * + * This is major version 0, minor version 0, which does not have any options, + * i.e. is empty. + */ +typedef struct { + /* Mount options version 0.0 does not have any ntfs options. */ +} __attribute__((__packed__)) ntfs_mount_options_0_0; + +/* + * The currently defined flags for the ntfs mount options structure. + */ +enum { + /* Below flag(s) appeared in mount options version 1.0. */ + NTFS_MNT_OPT_CASE_SENSITIVE = htole32(0x00000001), + /* Below flag(s) appeared in mount options version x.y. */ + // TODO: Add NTFS specific mount options flags here. +}; + +typedef le32 NTFS_MNT_OPTS; + +/* + * The NTFS mount options passed in from user space. This follows the + * ntfs_mount_options_header aligned to an eight byte boundary. + * + * This is major version 1, minor version 0, which has only one option, a + * little endian, 32-bit flags option. + */ +typedef struct { + NTFS_MNT_OPTS flags; + // TODO: Add NTFS specific mount options here. +} __attribute__((__packed__)) ntfs_mount_options_1_0; + +#endif /* !_OSX_NTFS_H */ Added: soc2012/vbotton/ntfs_apple/ntfs_attr.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/vbotton/ntfs_apple/ntfs_attr.c Mon May 14 14:04:01 2012 (r235762) @@ -0,0 +1,9096 @@ +/* + * ntfs_attr.c - NTFS kernel attribute operations. + * + * Copyright (c) 2006-2011 Anton Altaparmakov. All Rights Reserved. + * Portions Copyright (c) 2006-2011 Apple Inc. 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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. + * + * ALTERNATIVELY, provided that this notice and licensing terms are retained in + * full, this file may be redistributed and/or modified under the terms of the + * GNU General Public License (GPL) Version 2, in which case the provisions of + * that version of the GPL will apply to you instead of the license terms + * above. You can obtain a copy of the GPL Version 2 at + * http://developer.apple.com/opensource/licenses/gpl-2.txt. + */ + +#include +#include +#include +/*#include */ + +#include + +/*#include +#include */ + +//#include +//#include + +#include "ntfs.h" +#include "ntfs_attr.h" +#include "ntfs_attr_list.h" +#include "ntfs_debug.h" +#include "ntfs_dir.h" +#include "ntfs_endian.h" +#include "ntfs_index.h" +#include "ntfs_inode.h" +#include "ntfs_layout.h" +#include "ntfs_lcnalloc.h" +#include "ntfs_mft.h" +#include "ntfs_page.h" +#include "ntfs_runlist.h" +#include "ntfs_time.h" +#include "ntfs_types.h" +#include "ntfs_unistr.h" + +ntfschar AT_UNNAMED[1] = { 0 }; + +/** + * ntfs_attr_map_runlist - map the whole runlist of an ntfs inode + * @ni: ntfs inode for which to map the whole runlist + * + * Map the whole runlist of the ntfs inode @ni. + * + * Return 0 on success and errno on error. + * + * Note this function requires the runlist not to be mapped yet at all. This + * limitation is ok because we only use this function at mount time to map the + * runlist of some system files thus we are guaranteed that they will not have + * any runlist fragments mapped yet. + * + * Note the runlist can be NULL after this function returns if the attribute + * has zero allocated size, i.e. there simply is no runlist. + */ +errno_t ntfs_attr_map_runlist(ntfs_inode *ni) +{ + VCN vcn, end_vcn; + ntfs_inode *base_ni; + MFT_RECORD *m; + ntfs_attr_search_ctx *ctx; + ATTR_RECORD *a; + errno_t err = 0; + + ntfs_debug("Entering for mft_no 0x%llx, type 0x%x.", + (unsigned long long)ni->mft_no, + (unsigned)le32_to_cpu(ni->type)); + /* If the attribute is resident there is nothing to do. */ + if (!NInoNonResident(ni)) { + ntfs_debug("Done (resident, nothing to do)."); + return 0; + } + lck_rw_lock_exclusive(&ni->rl.lock); + /* Verify that the runlist is not mapped yet. */ + if (ni->rl.alloc && ni->rl.elements) + panic("%s(): ni->rl.alloc && ni->rl.elements\n", __FUNCTION__); + base_ni = ni; + if (NInoAttr(ni)) + base_ni = ni->base_ni; + err = ntfs_mft_record_map(base_ni, &m); + if (err) + goto err; + ctx = ntfs_attr_search_ctx_get(base_ni, m); + if (!ctx) { + err = ENOMEM; + goto unm_err; + } + vcn = 0; + end_vcn = ni->allocated_size >> ni->vol->cluster_size_shift; + do { + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, vcn, + NULL, 0, ctx); + if (err) { + if (err == ENOENT) + err = EIO; + break; + } + a = ctx->a; + if (!a->non_resident) { +corrupt_err: + ntfs_error(ni->vol->mp, "Inode 0x%llx contains corrupt " + "attribute extent, run chkdsk.", + (unsigned long long)base_ni->mft_no); + NVolSetErrors(ni->vol); + err = EIO; + break; + } + /* + * If we are in the first attribute extent, verify the cached + * allocated size is correct. + */ + if (!a->lowest_vcn) + if (sle64_to_cpu(a->allocated_size) != + ni->allocated_size) + panic("%s(): sle64_to_cpu(a->allocated_size) " + "!= ni->allocated_size\n", + __FUNCTION__); + /* + * Sanity check the lowest_vcn of the attribute is equal to the + * vcn we looked up and that the highest_vcn of the attribute + * is above the current vcn. + */ + if (sle64_to_cpu(a->lowest_vcn) != vcn || (vcn && + sle64_to_cpu(a->highest_vcn) < vcn)) + goto corrupt_err; + /* Determine the next vcn. */ + vcn = sle64_to_cpu(a->highest_vcn) + 1; + /* + * Finally, map the runlist fragment contained in this + * attribute extent. + */ + err = ntfs_mapping_pairs_decompress(ni->vol, a, &ni->rl); + } while (!err && vcn < end_vcn); +unm_err: + ntfs_attr_search_ctx_put(ctx); + ntfs_mft_record_unmap(base_ni); +err: + lck_rw_unlock_exclusive(&ni->rl.lock); + if (!err) + ntfs_debug("Done."); + else + ntfs_error(ni->vol->mp, "Failed (error %d).", (int)err); + return err; +} + +/** + * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode + * @ni: ntfs inode for which to map (part of) a runlist + * @vcn: map runlist part containing this vcn + * @ctx: active attribute search context if present or NULL if not + * + * Map the part of a runlist containing the @vcn of the ntfs inode @ni. + * + * If @ctx is specified, it is an active search context of @ni and its base mft + * record. This is needed when ntfs_map_runlist_nolock() encounters unmapped + * runlist fragments and allows their mapping. If you do not have the mft + * record mapped, you can specify @ctx as NULL and ntfs_map_runlist_nolock() + * will perform the necessary mapping and unmapping. + * + * Note, ntfs_map_runlist_nolock() saves the state of @ctx on entry and + * restores it before returning. Thus, @ctx will be left pointing to the same + * attribute on return as on entry. However, the actual pointers in @ctx may + * point to different memory locations on return, so you must remember to reset + * any cached pointers from the @ctx, i.e. after the call to + * ntfs_map_runlist_nolock(), you will probably want to do: + * m = ctx->m; + * a = ctx->a; + * Assuming you cache ctx->a in a variable @a of type ATTR_RECORD * and that + * you cache ctx->m in a variable @m of type MFT_RECORD *. + * + * Return 0 on success and errno on error. There is one special error code + * which is not an error as such. This is ENOENT. It means that @vcn is out + * of bounds of the runlist. + * + * Note the runlist can be NULL after this function returns if @vcn is zero and + * the attribute has zero allocated size, i.e. there simply is no runlist. + * + * WARNING: If @ctx is supplied, regardless of whether success or failure is + * returned, you need to check @ctx->is_error and if 1 the @ctx is no + * longer valid, i.e. you need to either call + * ntfs_attr_search_ctx_reinit() or ntfs_attr_search_ctx_put() on it. + * In that case @ctx->error will give you the error code for why the + * mapping of the old inode failed. + * Also if @ctx is supplied and the current attribute (or the mft + * record it is in) has been modified then the caller must call + * NInoSetMrecNeedsDirtying(ctx->ni); before calling + * ntfs_map_runlist_nolock() or the changes may be lost. + * + * Locking: - The runlist described by @ni must be locked for writing on entry + * and is locked on return. Note the runlist will be modified. + * - If @ctx is NULL, the base mft record of @ni must not be mapped on + * entry and it will be left unmapped on return. + * - If @ctx is not NULL, the base mft record must be mapped on entry + * and it will be left mapped on return. + */ +errno_t ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, + ntfs_attr_search_ctx *ctx) +{ + VCN end_vcn; + ntfs_inode *base_ni; + MFT_RECORD *m; + ATTR_RECORD *a; + errno_t err = 0; + BOOL ctx_is_temporary, ctx_needs_reset; + ntfs_attr_search_ctx old_ctx = { { NULL, }, }; + + ntfs_debug("Entering for mft_no 0x%llx, vcn 0x%llx.", + (unsigned long long)ni->mft_no, + (unsigned long long)vcn); + base_ni = ni; + if (NInoAttr(ni)) + base_ni = ni->base_ni; + if (!ctx) { + ctx_is_temporary = ctx_needs_reset = TRUE; + err = ntfs_mft_record_map(base_ni, &m); + if (err) + goto done; + ctx = ntfs_attr_search_ctx_get(base_ni, m); + if (!ctx) { + err = ENOMEM; + goto err; + } + } else { + VCN allocated_size_vcn; + + if (ctx->is_error) + panic("%s(): ctx->is_error\n", __FUNCTION__); + a = ctx->a; + if (!a->non_resident) + panic("%s(): !a->non_resident\n", __FUNCTION__); + ctx_is_temporary = FALSE; + end_vcn = sle64_to_cpu(a->highest_vcn); + lck_spin_lock(&ni->size_lock); + allocated_size_vcn = ni->allocated_size >> + ni->vol->cluster_size_shift; + lck_spin_unlock(&ni->size_lock); + /* + * If we already have the attribute extent containing @vcn in + * @ctx, no need to look it up again. We slightly cheat in + * that if vcn exceeds the allocated size, we will refuse to + * map the runlist below, so there is definitely no need to get + * the right attribute extent. + */ + if (vcn >= allocated_size_vcn || (a->type == ni->type && + a->name_length == ni->name_len && + !bcmp((u8*)a + le16_to_cpu(a->name_offset), + ni->name, ni->name_len) && + sle64_to_cpu(a->lowest_vcn) <= vcn && + end_vcn >= vcn)) + ctx_needs_reset = FALSE; + else { + /* Save the old search context. */ + old_ctx = *ctx; + /* + * Reinitialize the search context so we can lookup the + * needed attribute extent. + */ + ntfs_attr_search_ctx_reinit(ctx); + ctx_needs_reset = TRUE; + } + } + if (ctx_needs_reset) { + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, vcn, + NULL, 0, ctx); + if (err) { + if (err == ENOENT) + err = EIO; + goto err; + } + if (!ctx->a->non_resident) + panic("%s(): !a->non_resident!\n", __FUNCTION__); + } + a = ctx->a; + /* + * Only decompress the mapping pairs if @vcn is inside it. Otherwise + * we get into problems when we try to map an out of bounds vcn because + * we then try to map the already mapped runlist fragment and + * ntfs_mapping_pairs_decompress() fails. + */ + end_vcn = sle64_to_cpu(a->highest_vcn) + 1; + if (vcn && vcn >= end_vcn) { + err = ENOENT; + goto err; + } + err = ntfs_mapping_pairs_decompress(ni->vol, a, &ni->rl); +err: + if (ctx_is_temporary) { + if (ctx) + ntfs_attr_search_ctx_put(ctx); + ntfs_mft_record_unmap(base_ni); + } else if (ctx_needs_reset) { + /* + * If there is no attribute list, restoring the search context + * is acomplished simply by copying the saved context back over + * the caller supplied context. If there is an attribute list, + * things are more complicated as we need to deal with mapping + * of mft records and resulting potential changes in pointers. + */ + if (NInoAttrList(base_ni)) { + /* + * If the currently mapped (extent) inode is not the + * one we had before, we need to unmap it and map the + * old one. + */ + if (ctx->ni != old_ctx.ni) { + /* + * If the currently mapped inode is not the + * base inode, unmap it. + */ + if (ctx->base_ni && ctx->ni != ctx->base_ni) { + ntfs_extent_mft_record_unmap(ctx->ni); + ctx->m = ctx->base_m; + if (!ctx->m) + panic("%s(): !ctx->m\n", + __FUNCTION__); + } + /* + * If the old mapped inode is not the base + * inode, map it. + */ + if (old_ctx.base_ni && old_ctx.ni != + old_ctx.base_ni) { + errno_t err2; +retry_map: + err2 = ntfs_mft_record_map(old_ctx.ni, + &ctx->m); + /* + * Something bad has happened. If out + * of memory retry till it succeeds. + * Any other errors are fatal and we + * return the error code in ctx->m. + * Let the caller deal with it... We + * just need to fudge things so the + * caller can reinit and/or put the + * search context safely. + */ + if (err2) { + if (err2 == ENOMEM) { + (void)thread_block( + THREAD_CONTINUE_NULL); + goto retry_map; + } + ctx->is_error = 1; + ctx->error = err2; + old_ctx.ni = old_ctx.base_ni; + } + } + } + if (ctx->is_error) { + old_ctx.is_error = 1; + old_ctx.error = ctx->error; + } else if (ctx->m != old_ctx.m) { + /* + * Update the changed pointers in the saved + * context. + */ + old_ctx.a = (ATTR_RECORD*)((u8*)ctx->m + + ((u8*)old_ctx.a - + (u8*)old_ctx.m)); + old_ctx.m = ctx->m; + } + } + /* Restore the search context to the saved one. */ + *ctx = old_ctx; + } +done: + ntfs_debug("Done (error %d).", (int)err); + return err; +} + +/** + * ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode + * @ni: ntfs inode of the attribute whose runlist to search + * @vcn: vcn to convert + * @write_locked: true if the runlist is locked for writing + * @clusters: optional destination for number of contiguous clusters + * + * Find the virtual cluster number @vcn in the runlist of the ntfs attribute + * described by the ntfs inode @ni and return the corresponding logical cluster + * number (lcn). + * + * If the @vcn is not mapped yet, the attempt is made to map the attribute + * extent containing the @vcn and the vcn to lcn conversion is retried. + * + * If @write_locked is true the caller has locked the runlist for writing and + * if false for reading. + * + * If @clusters is not NULL, on success (i.e. we return >= LCN_HOLE) we return + * the number of contiguous clusters after the returned lcn in *@clusters. + * + * Since lcns must be >= 0, we use negative return codes with special meaning: + * + * Return code Meaning / Description + * ========================================== + * LCN_HOLE Hole / not allocated on disk. + * LCN_ENOENT There is no such vcn in the runlist, i.e. @vcn is out of bounds. + * LCN_ENOMEM Not enough memory to map runlist. + * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc). + * + * Locking: - The runlist must be locked on entry and is left locked on return. + * - If @write_locked is FALSE, i.e. the runlist is locked for reading, + * the lock may be dropped inside the function so you cannot rely on + * the runlist still being the same when this function returns. + */ +LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, + const BOOL write_locked, s64 *clusters) +{ + LCN lcn; + BOOL need_lock_switch = FALSE; + BOOL is_retry = FALSE; + + ntfs_debug("Entering for mft_no 0x%llx, vcn 0x%llx, %s_locked.", + (unsigned long long)ni->mft_no, + (unsigned long long)vcn, + write_locked ? "write" : "read"); + if (!NInoNonResident(ni)) + panic("%s(): !NInoNonResident(ni)\n", __FUNCTION__); + if (vcn < 0) + panic("%s(): vcn < 0\n", __FUNCTION__); +retry_remap: + if (!ni->rl.elements) { + lck_spin_lock(&ni->size_lock); + if (!ni->allocated_size) { + lck_spin_unlock(&ni->size_lock); + lcn = LCN_ENOENT; + goto lcn_enoent; + } + lck_spin_unlock(&ni->size_lock); + if (!is_retry) + goto try_to_map; + lcn = LCN_EIO; + goto lcn_eio; + } + /* Convert vcn to lcn. If that fails map the runlist and retry once. */ + lcn = ntfs_rl_vcn_to_lcn(ni->rl.rl, vcn, clusters); + if (lcn >= LCN_HOLE) { + if (need_lock_switch) + lck_rw_lock_exclusive_to_shared(&ni->rl.lock); + ntfs_debug("Done (lcn 0x%llx, clusters 0x%llx).", + (unsigned long long)lcn, + clusters ? (unsigned long long)*clusters : 0); + return lcn; + } + if (lcn != LCN_RL_NOT_MAPPED) { + if (lcn != LCN_ENOENT) + lcn = LCN_EIO; + } else if (!is_retry) { + errno_t err; + +try_to_map: + if (!write_locked && !need_lock_switch) { + need_lock_switch = TRUE; + /* + * If converting the lock from shared to exclusive + * fails, need to take the lock for writing and retry + * in case the racing process did the mapping for us. + */ + if (!lck_rw_lock_shared_to_exclusive(&ni->rl.lock)) { + lck_rw_lock_exclusive(&ni->rl.lock); + goto retry_remap; + } + } + err = ntfs_map_runlist_nolock(ni, vcn, NULL); + if (!err) { + is_retry = TRUE; + goto retry_remap; + } + switch (err) { + case ENOENT: + lcn = LCN_ENOENT; + break; + case ENOMEM: + lcn = LCN_ENOMEM; + break; + default: + lcn = LCN_EIO; + } + } +lcn_eio: + if (need_lock_switch) + lck_rw_lock_exclusive_to_shared(&ni->rl.lock); + if (lcn == LCN_ENOENT) { +lcn_enoent: + ntfs_debug("Done (LCN_ENOENT)."); + } else + ntfs_error(ni->vol->mp, "Failed (error %lld).", (long long)lcn); + return lcn; +} + +/** + * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode + * @ni: ntfs inode of the attribute whose runlist to search + * @vcn: vcn to find + * @run: return pointer for the found runlist element + * @ctx: active attribute search context if present or NULL if not + * + * Find the virtual cluster number @vcn in the runlist of the ntfs attribute + * described by the ntfs inode @ni and return the address of the runlist + * element containing the @vcn in *@run. + * + * If the @vcn is not mapped yet, the attempt is made to map the attribute + * extent containing the @vcn and the vcn to lcn conversion is retried. + * + * If @ctx is specified, it is an active search context of @ni and its base mft + * record. This is needed when ntfs_attr_find_vcn_nolock() encounters unmapped + * runlist fragments and allows their mapping. If you do not have the mft + * record mapped, you can specify @ctx as NULL and ntfs_attr_find_vcn_nolock() + * will perform the necessary mapping and unmapping. + * + * Note, ntfs_attr_find_vcn_nolock() saves the state of @ctx on entry and + * restores it before returning. Thus, @ctx will be left pointing to the same + * attribute on return as on entry. However, the actual pointers in @ctx may + * point to different memory locations on return, so you must remember to reset + * any cached pointers from the @ctx, i.e. after the call to + * ntfs_attr_find_vcn_nolock(), you will probably want to do: + * m = ctx->m; + * a = ctx->a; + * Assuming you cache ctx->a in a variable @a of type ATTR_RECORD * and that + * you cache ctx->m in a variable @m of type MFT_RECORD *. + * Note you need to distinguish between the lcn of the returned runlist element + * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on + * read and allocate clusters on write. + * + * Return 0 on success and errno on error. + * + * The possible error return codes are: + * ENOENT - No such vcn in the runlist, i.e. @vcn is out of bounds. + * ENOMEM - Not enough memory to map runlist. + * EIO - Critical error (runlist/file is corrupt, i/o error, etc). + * + * WARNING: If @ctx is supplied, regardless of whether success or failure is + * returned, you need to check @ctx->is_error and if 1 the @ctx is no + * longer valid, i.e. you need to either call + * ntfs_attr_search_ctx_reinit() or ntfs_attr_search_ctx_put() on it. + * In that case @ctx->error will give you the error code for why the + * mapping of the old inode failed. + * Also if @ctx is supplied and the current attribute (or the mft + * record it is in) has been modified then the caller must call + * NInoSetMrecNeedsDirtying(ctx->ni); before calling + * ntfs_map_runlist_nolock() or the changes may be lost. + * + * Locking: - The runlist described by @ni must be locked for writing on entry + * and is locked on return. Note the runlist may be modified when + * needed runlist fragments need to be mapped. + * - If @ctx is NULL, the base mft record of @ni must not be mapped on + * entry and it will be left unmapped on return. + * - If @ctx is not NULL, the base mft record must be mapped on entry + * and it will be left mapped on return. + */ +errno_t ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, + ntfs_rl_element **run, ntfs_attr_search_ctx *ctx) +{ + ntfs_rl_element *rl; + errno_t err = 0; + BOOL is_retry = FALSE; + + ntfs_debug("Entering for mft_no 0x%llx, vcn 0x%llx, with%s ctx.", + (unsigned long long)ni->mft_no, + (unsigned long long)vcn, ctx ? "" : "out"); + if (!NInoNonResident(ni)) + panic("%s(): !NInoNonResident(ni)\n", __FUNCTION__); + if (vcn < 0) + panic("%s(): vcn < 0\n", __FUNCTION__); +retry_remap: + if (!ni->rl.elements) { + lck_spin_lock(&ni->size_lock); + if (!ni->allocated_size) { + lck_spin_unlock(&ni->size_lock); + return LCN_ENOENT; + } + lck_spin_unlock(&ni->size_lock); + if (!is_retry) + goto try_to_map; + err = EIO; + goto err; + } + rl = ni->rl.rl; + if (vcn >= rl[0].vcn) { + while (rl->length) { + if (vcn < rl[1].vcn) { + if (rl->lcn >= LCN_HOLE) { + ntfs_debug("Done."); + *run = rl; + return 0; + } + break; + } + rl++; + } + if (rl->lcn != LCN_RL_NOT_MAPPED) { + if (rl->lcn == LCN_ENOENT) + err = ENOENT; + else + err = EIO; + } + } + if (!err && !is_retry) { + /* + * If the search context is invalid we cannot map the unmapped + * region. + */ + if (ctx->is_error) + err = ctx->error; + else { +try_to_map: + /* + * The @vcn is in an unmapped region, map the runlist + * and retry. + */ + err = ntfs_map_runlist_nolock(ni, vcn, ctx); + if (!err) { + is_retry = TRUE; + goto retry_remap; + } + } + if (err == EINVAL) + err = EIO; + } else if (!err) + err = EIO; +err: + if (err != ENOENT) + ntfs_error(ni->vol->mp, "Failed (error %d).", err); + return err; +} + +/** + * ntfs_attr_search_ctx_reinit - reinitialize an attribute search context + * @ctx: attribute search context to reinitialize + * + * Reinitialize the attribute search context @ctx, unmapping an associated + * extent mft record if present, and initialize the search context again. + * + * This is used when a search for a new attribute is being started to reset + * the search context to the beginning. + * + * Note: We preserve the content of @ctx->is_mft_locked so that reinitializing + * a search context can also be done when dealing with the mft itself. + */ +void ntfs_attr_search_ctx_reinit(ntfs_attr_search_ctx *ctx) +{ + const BOOL mft_is_locked = ctx->is_mft_locked; + + if (!ctx->base_ni) { + /* No attribute list. */ + ctx->is_first = 1; + ctx->is_iteration = 0; + /* Sanity checks are performed elsewhere. */ + ctx->a = (ATTR_RECORD*)((u8*)ctx->m + + le16_to_cpu(ctx->m->attrs_offset)); + /* + * This needs resetting due to + * ntfs_attr_find_in_attribute_list() which can leave it set + * despite having zeroed ctx->base_ni. + */ + ctx->al_entry = NULL; + return; + } + /* Attribute list. */ + if (ctx->ni != ctx->base_ni) + ntfs_extent_mft_record_unmap(ctx->ni); + ntfs_attr_search_ctx_init(ctx, ctx->base_ni, ctx->base_m); + if (mft_is_locked) + ctx->is_mft_locked = 1; +} + +/** + * ntfs_attr_search_ctx_get - allocate and init a new attribute search context + * @ni: ntfs inode with which to initialize the search context + * @m: mft record with which to initialize the search context + * + * Allocate a new attribute search context, initialize it with @ni and @m, and + * return it. Return NULL if allocation failed. + */ +ntfs_attr_search_ctx *ntfs_attr_search_ctx_get(ntfs_inode *ni, MFT_RECORD *m) +{ + ntfs_attr_search_ctx *ctx; + + ctx = OSMalloc(sizeof(ntfs_attr_search_ctx), ntfs_malloc_tag); + if (ctx) + ntfs_attr_search_ctx_init(ctx, ni, m); + return ctx; +} + +/** + * ntfs_attr_search_ctx_put - release an attribute search context + * @ctx: attribute search context to free + * + * Release the attribute search context @ctx, unmapping an associated extent + * mft record if present. + */ +void ntfs_attr_search_ctx_put(ntfs_attr_search_ctx *ctx) +{ + if (ctx->base_ni && ctx->ni != ctx->base_ni) + ntfs_extent_mft_record_unmap(ctx->ni); + OSFree(ctx, sizeof(ntfs_attr_search_ctx), ntfs_malloc_tag); +} + +/** + * ntfs_attr_find_in_mft_record - find (next) attribute in mft record + * @type: attribute type to find + * @name: attribute name to find (optional, i.e. NULL means do not care) + * @name_len: attribute name length (only needed if @name present) + * @val: attribute value to find (optional, resident attributes only) + * @val_len: attribute value length (only needed if @val present) + * @ctx: search context with mft record and attribute to search from + * + * You should not need to call this function directly. Use ntfs_attr_lookup() + * instead. + * + * ntfs_attr_find_in_mft_record() takes a search context @ctx as parameter and + * searches the mft record specified by @ctx->m, beginning at @ctx->a, for an + * attribute of @type, optionally @name and @val. + * + * If the attribute is found, ntfs_attr_find_in_mft_record() returns 0 and + * @ctx->a is set to point to the found attribute. + * + * If the attribute is not found, ENOENT is returned and @ctx->a is set to + * point to the attribute before which the attribute being searched for would + * need to be inserted if such an action were to be desired. + * + * On actual error, ntfs_attr_find_in_mft_record() returns EIO. In this case + * @ctx->a is undefined and in particular do not rely on it not having changed. + * + * If @ctx->is_first is 1, the search begins with @ctx->a itself. If it is 0, + * the search begins after @ctx->a. + * + * If @ctx->is_iteration is 1 and @type is AT_UNUSED this is not a search but + * an iteration in which case each attribute in the mft record is returned in + * turn with each call to ntfs_attr_find_in_mft_record(). Note all attributes + * are returned including the attribute list attribute, unlike when + * @ctx->is_iteration is 0 when it is not returned unless it is specifically + * looked for. + * + * Similarly to the above, when @ctx->is_iterations is 1 and @type is not + * AT_UNUSED all attributes of type @type are returned one after the other. + * + * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present + * but not AT_UNNAMED search for a named attribute matching @name. Otherwise, + * match both named and unnamed attributes. + * + * Finally, the resident attribute value @val is looked for, if present. If + * @val is not present (NULL), @val_len is ignored. + * + * ntfs_attr_find_in_mft_record() only searches the specified mft record and it + * ignores the presence of an attribute list attribute (unless it is the one + * being searched for, obviously). If you need to take attribute lists into + * consideration, use ntfs_attr_lookup() instead (see below). This also means + * that you cannot use ntfs_attr_find_in_mft_record() to search for extent + * records of non-resident attributes, as extents with lowest_vcn != 0 are + * usually described by the attribute list attribute only. Note that it is + * possible that the first extent is only in the attribute list while the last + * extent is in the base mft record, so do not rely on being able to find the + * first extent in the base mft record. + * + * Warning: Never use @val when looking for attribute types which can be + * non-resident as this most likely will result in a crash! + * + * Note if the volume is mounted case sensitive we treat attribute names as + * being case sensitive and vice versa if the volume is not mounted case + * sensitive we treat attribute names as being case insensitive also. + */ +errno_t ntfs_attr_find_in_mft_record(const ATTR_TYPE type, + const ntfschar *name, const u32 name_len, + const void *val, const u32 val_len, ntfs_attr_search_ctx *ctx) +{ + ATTR_RECORD *a; + ntfs_volume *vol = ctx->ni->vol; + const ntfschar *upcase = vol->upcase; + const u32 upcase_len = vol->upcase_len; + const BOOL case_sensitive = NVolCaseSensitive(vol); + const BOOL is_iteration = ctx->is_iteration; + + /* + * Iterate over attributes in mft record starting at @ctx->a, or the + * attribute following that, if @ctx->is_first is true. + */ + if (ctx->is_first) { + a = ctx->a; + ctx->is_first = 0; + } else + a = (ATTR_RECORD*)((u8*)ctx->a + le32_to_cpu(ctx->a->length)); + for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) { + if ((u8*)a < (u8*)ctx->m || (u8*)a > (u8*)ctx->m + + le32_to_cpu(ctx->m->bytes_allocated)) + break; + ctx->a = a; + if (((!is_iteration || type != AT_UNUSED) && + le32_to_cpu(a->type) > le32_to_cpu(type)) || + a->type == AT_END) + return ENOENT; + if (!a->length) + break; + if (is_iteration) { + if (type == AT_UNUSED || type == a->type) + return 0; + } + if (a->type != type) *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-soc-all@FreeBSD.ORG Tue May 15 01:57:32 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id D4A25106564A for ; Tue, 15 May 2012 01:57:30 +0000 (UTC) (envelope-from exxo@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Tue, 15 May 2012 01:57:30 +0000 Date: Tue, 15 May 2012 01:57:30 +0000 From: exxo@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120515015730.D4A25106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r235781 - soc2012/exxo X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2012 01:57:33 -0000 Author: exxo Date: Tue May 15 01:57:30 2012 New Revision: 235781 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235781 Log: Fix: Fixed CVS coredump with inet6 support Added: soc2012/exxo/ soc2012/exxo/cvs-inet6.patch Added: soc2012/exxo/cvs-inet6.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/exxo/cvs-inet6.patch Tue May 15 01:57:30 2012 (r235781) @@ -0,0 +1,208 @@ +? src/patch-20110103-01-cvs-client-ipv6-pserver.diff +Index: src/client.c +=================================================================== +RCS file: /home/ncvs/src/contrib/cvs/src/client.c,v +retrieving revision 1.14 +diff -p -u -r1.14 client.c +--- src/client.c 19 Mar 2008 14:49:14 -0000 1.14 ++++ src/client.c 15 May 2012 01:47:06 -0000 +@@ -85,7 +85,7 @@ static Key_schedule sched; + /* This is needed for GSSAPI encryption. */ + static gss_ctx_id_t gcontext; + +-static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *)); ++static int connect_to_gserver PROTO((cvsroot_t *, int, const char *)); + + # endif /* HAVE_GSSAPI */ + +@@ -149,7 +149,7 @@ static void handle_notified PROTO((char + static size_t try_read_from_server PROTO ((char *, size_t)); + + static void auth_server PROTO ((cvsroot_t *, struct buffer *, struct buffer *, +- int, int, struct hostent *)); ++ int, int, const char *)); + + /* We need to keep track of the list of directories we've sent to the + server. This list, along with the current CVSROOT, will help us +@@ -3605,6 +3605,28 @@ init_sockaddr (name, hostname, port) + return hostinfo; + } + ++static void ++_inet_ntop(int af, struct sockaddr *sa, char *addr, socklen_t len) ++{ ++ struct sockaddr_in *sin; ++ struct sockaddr_in6 *sin6; ++ ++ addr[0] = '\0'; ++ assert(af == sa->sa_family); ++ switch (af) ++ { ++ case AF_INET6: ++ sin6 = (struct sockaddr_in6 *)sa; ++ inet_ntop(af, &sin6->sin6_addr, addr, len); ++ break; ++ case AF_INET: ++ sin = (struct sockaddr_in *)sa; ++ inet_ntop(af, &sin->sin_addr, addr, len); ++ break; ++ default: ++ break; ++ } ++} + + + /* Generic function to do port number lookup tasks. +@@ -3779,33 +3801,75 @@ connect_to_pserver (root, to_server_p, f + { + int sock; + int port_number; +- struct sockaddr_in client_sai; +- struct hostent *hostinfo; + struct buffer *to_server, *from_server; ++ struct addrinfo hints, *res, *res0, *ress; ++ int err, cause; ++ char ports[7], addr[INET6_ADDRSTRLEN]; + +- sock = socket (AF_INET, SOCK_STREAM, 0); +- if (sock == -1) +- { +- error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); +- } + port_number = get_cvs_port_number (root); +- hostinfo = init_sockaddr (&client_sai, root->hostname, port_number); +- if (trace) ++ snprintf(ports, sizeof(ports), "%d", port_number); ++ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_CANONNAME; ++ hints.ai_family = PF_UNSPEC; ++ hints.ai_socktype = SOCK_STREAM; ++ err = getaddrinfo(root->hostname, ports, &hints, &res0); ++ if (err) + { +- fprintf (stderr, " -> Connecting to %s(%s):%d\n", +- root->hostname, +- inet_ntoa (client_sai.sin_addr), port_number); ++ error(1, 0, "%s", gai_strerror(err)); ++ } ++ sock = -1; ++ cause = 0; ++ for (res = res0; res; res = res->ai_next) { ++ sock = socket(res->ai_family, res->ai_socktype, ++ res->ai_protocol); ++ if (sock < 0) { ++ cause = 1; ++ err = SOCK_ERRNO; ++ ress = res; ++ continue; ++ } ++ ++ if (trace) ++ { ++ _inet_ntop(res->ai_family, res->ai_addr, addr, sizeof(addr)); ++ fprintf (stderr, " -> Connecting to %s(%s):%d\n", ++ root->hostname, addr, port_number); ++ } ++ ++ if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { ++ cause = 2; ++ err = SOCK_ERRNO; ++ ress = res; ++ close(sock); ++ sock = -1; ++ continue; ++ } ++ ++ break; /* okay we got one */ ++ } ++ if (sock < 0) { ++ switch (cause) ++ { ++ case 1: ++ freeaddrinfo(res0); ++ error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); ++ case 2: ++ _inet_ntop(ress->ai_family, ress->ai_addr, addr, sizeof(addr)); ++ freeaddrinfo(res0); ++ error (1, 0, "connect to %s(%s):%d failed: %s", ++ root->hostname, addr, port_number, ++ SOCK_STRERROR (err)); ++ default: ++ freeaddrinfo(res0); ++ error (1, 0, "%s: unknown error", __func__); ++ } + } +- if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai)) +- < 0) +- error (1, 0, "connect to %s(%s):%d failed: %s", +- root->hostname, +- inet_ntoa (client_sai.sin_addr), +- port_number, SOCK_STRERROR (SOCK_ERRNO)); + + make_bufs_from_fds (sock, sock, 0, &to_server, &from_server, 1); + +- auth_server (root, to_server, from_server, verify_only, do_gssapi, hostinfo); ++ auth_server (root, to_server, from_server, verify_only, do_gssapi, res->ai_canonname); ++ freeaddrinfo(res0); + + if (verify_only) + { +@@ -3839,13 +3903,13 @@ connect_to_pserver (root, to_server_p, f + + + static void +-auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo) ++auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostname) + cvsroot_t *root; + struct buffer *lto_server; + struct buffer *lfrom_server; + int verify_only; + int do_gssapi; +- struct hostent *hostinfo; ++ const char *hostname; + { + char *username = ""; /* the username we use to connect */ + char no_passwd = 0; /* gets set if no password found */ +@@ -3875,7 +3939,7 @@ auth_server (root, lto_server, lfrom_ser + error (1, 0, "gserver currently only enabled for socket connections"); + } + +- if (! connect_to_gserver (root, fd, hostinfo)) ++ if (! connect_to_gserver (root, fd, hostname)) + { + error (1, 0, + "authorization failed: server %s rejected access to %s", +@@ -4076,6 +4140,7 @@ start_tcp_server (root, to_server, from_ + struct sockaddr_in sin; + char *hname; + ++ /* XXX Not IPv6 ready, but MIT Kerberos 4 code thou shall not touch. */ + s = socket (AF_INET, SOCK_STREAM, 0); + if (s < 0) + error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); +@@ -4176,10 +4241,10 @@ recv_bytes (sock, buf, need) + */ + #define BUFSIZE 1024 + static int +-connect_to_gserver (root, sock, hostinfo) ++connect_to_gserver (root, sock, hostname) + cvsroot_t *root; + int sock; +- struct hostent *hostinfo; ++ const char *hostname; + { + char *str; + char buf[BUFSIZE]; +@@ -4192,9 +4257,9 @@ connect_to_gserver (root, sock, hostinfo + if (send (sock, str, strlen (str), 0) < 0) + error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); + +- if (strlen (hostinfo->h_name) > BUFSIZE - 5) ++ if (strlen (hostname) > BUFSIZE - 5) + error (1, 0, "Internal error: hostname exceeds length of buffer"); +- sprintf (buf, "cvs@%s", hostinfo->h_name); ++ sprintf (buf, "cvs@%s", hostname); + tok_in.length = strlen (buf); + tok_in.value = buf; + gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE, From owner-svn-soc-all@FreeBSD.ORG Tue May 15 22:03:18 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 4CBA7106564A for ; Tue, 15 May 2012 22:03:17 +0000 (UTC) (envelope-from rudot@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Tue, 15 May 2012 22:03:17 +0000 Date: Tue, 15 May 2012 22:03:17 +0000 From: rudot@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120515220317.4CBA7106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r235809 - soc2012/rudot X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2012 22:03:18 -0000 Author: rudot Date: Tue May 15 22:03:17 2012 New Revision: 235809 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235809 Log: initial import Added: soc2012/rudot/ From owner-svn-soc-all@FreeBSD.ORG Tue May 15 22:32:06 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 456C2106567C for ; Tue, 15 May 2012 22:32:05 +0000 (UTC) (envelope-from gmiller@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Tue, 15 May 2012 22:32:05 +0000 Date: Tue, 15 May 2012 22:32:05 +0000 From: gmiller@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120515223205.456C2106567C@hub.freebsd.org> Cc: Subject: socsvn commit: r235810 - in soc2012/gmiller: . locking-head X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2012 22:32:06 -0000 Author: gmiller Date: Tue May 15 22:32:04 2012 New Revision: 235810 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235810 Log: GSoC 2012 Locking Profiling and Lock Order Verification project initial branch creation. Submitted by: Greg Miller (gmiller@) Added: soc2012/gmiller/ soc2012/gmiller/locking-head/ From owner-svn-soc-all@FreeBSD.ORG Tue May 15 22:33:21 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 3933E106566C for ; Tue, 15 May 2012 22:33:19 +0000 (UTC) (envelope-from gmiller@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Tue, 15 May 2012 22:33:19 +0000 Date: Tue, 15 May 2012 22:33:19 +0000 From: gmiller@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120515223320.3933E106566C@hub.freebsd.org> Cc: Subject: socsvn commit: r235811 - soc2012/gmiller/locking-head/head X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2012 22:33:21 -0000 Author: gmiller Date: Tue May 15 22:33:19 2012 New Revision: 235811 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235811 Log: GSoC Lock Profiling and Lock Order Verification project initial code commit to branch. Submitted by: Greg Miller (gmiller@) Added: soc2012/gmiller/locking-head/head/ (props changed) - copied from r235810, mirror/FreeBSD/head/ From owner-svn-soc-all@FreeBSD.ORG Tue May 15 22:36:08 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 900A4106566B for ; Tue, 15 May 2012 22:36:07 +0000 (UTC) (envelope-from gmiller@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Tue, 15 May 2012 22:36:07 +0000 Date: Tue, 15 May 2012 22:36:07 +0000 From: gmiller@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120515223607.900A4106566B@hub.freebsd.org> Cc: Subject: socsvn commit: r235812 - soc2012/gmiller/locking-head X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2012 22:36:08 -0000 Author: gmiller Date: Tue May 15 22:36:07 2012 New Revision: 235812 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235812 Log: Correcting location. Submitted by: Greg Miller (gmiller@) Deleted: soc2012/gmiller/locking-head/ From owner-svn-soc-all@FreeBSD.ORG Tue May 15 22:37:15 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id DC6471065672 for ; Tue, 15 May 2012 22:37:14 +0000 (UTC) (envelope-from gmiller@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Tue, 15 May 2012 22:37:14 +0000 Date: Tue, 15 May 2012 22:37:14 +0000 From: gmiller@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120515223714.DC6471065672@hub.freebsd.org> Cc: Subject: socsvn commit: r235813 - soc2012/gmiller/locking-head X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2012 22:37:16 -0000 Author: gmiller Date: Tue May 15 22:37:14 2012 New Revision: 235813 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235813 Log: Recreating branch files at the proper location. Submitted by: Greg Miller (gmiller@) Added: soc2012/gmiller/locking-head/ (props changed) - copied from r235812, mirror/FreeBSD/head/ From owner-svn-soc-all@FreeBSD.ORG Thu May 17 05:30:35 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 5863F106564A for ; Thu, 17 May 2012 05:30:34 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Thu, 17 May 2012 05:30:34 +0000 Date: Thu, 17 May 2012 05:30:34 +0000 From: ae@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120517053034.5863F106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r235858 - soc2012/ae X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 May 2012 05:30:35 -0000 Author: ae Date: Thu May 17 05:30:33 2012 New Revision: 235858 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235858 Log: Test my account. Added: soc2012/ae/ From owner-svn-soc-all@FreeBSD.ORG Thu May 17 21:04:38 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 6F009106566C for ; Thu, 17 May 2012 21:04:37 +0000 (UTC) (envelope-from scher@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Thu, 17 May 2012 21:04:37 +0000 Date: Thu, 17 May 2012 21:04:37 +0000 From: scher@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120517210437.6F009106566C@hub.freebsd.org> Cc: Subject: socsvn commit: r235897 - soc2012/scher X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 May 2012 21:04:38 -0000 Author: scher Date: Thu May 17 21:04:37 2012 New Revision: 235897 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235897 Log: Added: soc2012/scher/ From owner-svn-soc-all@FreeBSD.ORG Thu May 17 21:10:28 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id B381C106564A for ; Thu, 17 May 2012 21:10:27 +0000 (UTC) (envelope-from scher@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Thu, 17 May 2012 21:10:27 +0000 Date: Thu, 17 May 2012 21:10:27 +0000 From: scher@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120517211027.B381C106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r235898 - soc2012/scher/par_ports X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 May 2012 21:10:28 -0000 Author: scher Date: Thu May 17 21:10:27 2012 New Revision: 235898 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235898 Log: Added: soc2012/scher/par_ports/ From owner-svn-soc-all@FreeBSD.ORG Fri May 18 11:09:37 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 4C223106564A for ; Fri, 18 May 2012 11:09:36 +0000 (UTC) (envelope-from scher@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Fri, 18 May 2012 11:09:36 +0000 Date: Fri, 18 May 2012 11:09:36 +0000 From: scher@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120518110936.4C223106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r235936 - soc2012/scher/par_ports/head X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 May 2012 11:09:37 -0000 Author: scher Date: Fri May 18 11:09:36 2012 New Revision: 235936 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235936 Log: Added: soc2012/scher/par_ports/head/ From owner-svn-soc-all@FreeBSD.ORG Fri May 18 13:12:16 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id CA4C5106564A for ; Fri, 18 May 2012 13:12:15 +0000 (UTC) (envelope-from oleksandr@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Fri, 18 May 2012 13:12:15 +0000 Date: Fri, 18 May 2012 13:12:15 +0000 From: oleksandr@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120518131215.CA4C5106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r235939 - in soc2012/oleksandr: . udf-head X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 May 2012 13:12:16 -0000 Author: oleksandr Date: Fri May 18 13:12:15 2012 New Revision: 235939 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235939 Log: Added: soc2012/oleksandr/ soc2012/oleksandr/udf-head/ (props changed) - copied from r235938, mirror/FreeBSD/head/ From owner-svn-soc-all@FreeBSD.ORG Sat May 19 03:38:05 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 68EB2106566B for ; Sat, 19 May 2012 03:38:03 +0000 (UTC) (envelope-from jhagewood@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Sat, 19 May 2012 03:38:03 +0000 Date: Sat, 19 May 2012 03:38:03 +0000 From: jhagewood@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120519033803.68EB2106566B@hub.freebsd.org> Cc: Subject: socsvn commit: r235974 - in soc2012/jhagewood: . diff diff3 gabor_diff mdocml-1.9.9 sdiff X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 May 2012 03:38:05 -0000 Author: jhagewood Date: Sat May 19 03:38:02 2012 New Revision: 235974 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235974 Log: First import. Added: soc2012/jhagewood/Milestones soc2012/jhagewood/diff/ soc2012/jhagewood/diff/Makefile soc2012/jhagewood/diff/diff (contents, props changed) soc2012/jhagewood/diff/diff.1 soc2012/jhagewood/diff/diff.1.gz (contents, props changed) soc2012/jhagewood/diff/diff.c soc2012/jhagewood/diff/diff.h soc2012/jhagewood/diff/diffdir.c soc2012/jhagewood/diff/diffreg.c soc2012/jhagewood/diff/pathnames.h soc2012/jhagewood/diff3/ soc2012/jhagewood/diff3/Makefile soc2012/jhagewood/diff3/diff3.1 soc2012/jhagewood/diff3/diff3.ksh soc2012/jhagewood/diff3/diff3.sh soc2012/jhagewood/diff3/diff3prog.c soc2012/jhagewood/gabor_diff/ soc2012/jhagewood/gabor_diff/Makefile soc2012/jhagewood/gabor_diff/diff.1 soc2012/jhagewood/gabor_diff/diff.c soc2012/jhagewood/gabor_diff/diff.h soc2012/jhagewood/gabor_diff/diffdir.c soc2012/jhagewood/gabor_diff/diffreg.c soc2012/jhagewood/gabor_diff/pathnames.h soc2012/jhagewood/mdocml-1.9.9/ soc2012/jhagewood/mdocml-1.9.9/ChangeLog.xsl (contents, props changed) soc2012/jhagewood/mdocml-1.9.9/Makefile soc2012/jhagewood/mdocml-1.9.9/arch.c soc2012/jhagewood/mdocml-1.9.9/arch.in soc2012/jhagewood/mdocml-1.9.9/att.c soc2012/jhagewood/mdocml-1.9.9/att.in soc2012/jhagewood/mdocml-1.9.9/chars.c soc2012/jhagewood/mdocml-1.9.9/chars.h soc2012/jhagewood/mdocml-1.9.9/chars.in soc2012/jhagewood/mdocml-1.9.9/compat.c soc2012/jhagewood/mdocml-1.9.9/example.style.css soc2012/jhagewood/mdocml-1.9.9/external.png (contents, props changed) soc2012/jhagewood/mdocml-1.9.9/html.c soc2012/jhagewood/mdocml-1.9.9/html.h soc2012/jhagewood/mdocml-1.9.9/index.css soc2012/jhagewood/mdocml-1.9.9/index.sgml soc2012/jhagewood/mdocml-1.9.9/lib.c soc2012/jhagewood/mdocml-1.9.9/lib.in soc2012/jhagewood/mdocml-1.9.9/libman.h soc2012/jhagewood/mdocml-1.9.9/libmandoc.h soc2012/jhagewood/mdocml-1.9.9/libmdoc.h soc2012/jhagewood/mdocml-1.9.9/main.c soc2012/jhagewood/mdocml-1.9.9/main.h soc2012/jhagewood/mdocml-1.9.9/man.3 soc2012/jhagewood/mdocml-1.9.9/man.3.sgml soc2012/jhagewood/mdocml-1.9.9/man.7 soc2012/jhagewood/mdocml-1.9.9/man.7.sgml soc2012/jhagewood/mdocml-1.9.9/man.c soc2012/jhagewood/mdocml-1.9.9/man.h soc2012/jhagewood/mdocml-1.9.9/man_action.c soc2012/jhagewood/mdocml-1.9.9/man_argv.c soc2012/jhagewood/mdocml-1.9.9/man_hash.c soc2012/jhagewood/mdocml-1.9.9/man_html.c soc2012/jhagewood/mdocml-1.9.9/man_macro.c soc2012/jhagewood/mdocml-1.9.9/man_term.c soc2012/jhagewood/mdocml-1.9.9/man_validate.c soc2012/jhagewood/mdocml-1.9.9/mandoc (contents, props changed) soc2012/jhagewood/mdocml-1.9.9/mandoc.1 soc2012/jhagewood/mdocml-1.9.9/mandoc.1.sgml soc2012/jhagewood/mdocml-1.9.9/mandoc.c soc2012/jhagewood/mdocml-1.9.9/mandoc_char.7 soc2012/jhagewood/mdocml-1.9.9/mandoc_char.7.sgml soc2012/jhagewood/mdocml-1.9.9/manuals.7 soc2012/jhagewood/mdocml-1.9.9/manuals.7.sgml soc2012/jhagewood/mdocml-1.9.9/mdoc.3 soc2012/jhagewood/mdocml-1.9.9/mdoc.3.sgml soc2012/jhagewood/mdocml-1.9.9/mdoc.7 soc2012/jhagewood/mdocml-1.9.9/mdoc.7.sgml soc2012/jhagewood/mdocml-1.9.9/mdoc.c soc2012/jhagewood/mdocml-1.9.9/mdoc.h soc2012/jhagewood/mdocml-1.9.9/mdoc_action.c soc2012/jhagewood/mdocml-1.9.9/mdoc_argv.c soc2012/jhagewood/mdocml-1.9.9/mdoc_hash.c soc2012/jhagewood/mdocml-1.9.9/mdoc_html.c soc2012/jhagewood/mdocml-1.9.9/mdoc_macro.c soc2012/jhagewood/mdocml-1.9.9/mdoc_strings.c soc2012/jhagewood/mdocml-1.9.9/mdoc_term.c soc2012/jhagewood/mdocml-1.9.9/mdoc_validate.c soc2012/jhagewood/mdocml-1.9.9/msec.c soc2012/jhagewood/mdocml-1.9.9/msec.in soc2012/jhagewood/mdocml-1.9.9/out.c soc2012/jhagewood/mdocml-1.9.9/out.h soc2012/jhagewood/mdocml-1.9.9/st.c soc2012/jhagewood/mdocml-1.9.9/st.in soc2012/jhagewood/mdocml-1.9.9/style.css soc2012/jhagewood/mdocml-1.9.9/term.c soc2012/jhagewood/mdocml-1.9.9/term.h soc2012/jhagewood/mdocml-1.9.9/tree.c soc2012/jhagewood/mdocml-1.9.9/vol.c soc2012/jhagewood/mdocml-1.9.9/vol.in soc2012/jhagewood/sdiff/ soc2012/jhagewood/sdiff/Makefile soc2012/jhagewood/sdiff/common.c soc2012/jhagewood/sdiff/common.h soc2012/jhagewood/sdiff/edit.c soc2012/jhagewood/sdiff/extern.h soc2012/jhagewood/sdiff/sdiff.1 soc2012/jhagewood/sdiff/sdiff.c soc2012/jhagewood/svn-commit.2.tmp soc2012/jhagewood/svn-commit.tmp Added: soc2012/jhagewood/Milestones ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/jhagewood/Milestones Sat May 19 03:38:02 2012 (r235974) @@ -0,0 +1,30 @@ +May 21 - June 17 + + Implement all missing features of mdocml, including legacy features. + Testing of mdocml. + +June 18 - July 1 + + Complete diff + Debugging and testing of diff + +July 2 - July 18 + + Mid-term evaluations. + Complete sdiff + Debugging and testing of sdiff + +July 19 - August 5 + + Complete diff3 + Debugging and testing of diff3 + +August 6 – August 12 + + Thouroughly test and benchmark all utilities. + +August 13 - August 20 + + "Pencils down" period. + Finish cleaning up code and do any testing that might be left. + Write documentation. Added: soc2012/jhagewood/diff/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/jhagewood/diff/Makefile Sat May 19 03:38:02 2012 (r235974) @@ -0,0 +1,10 @@ +# $FreeBSD$ +# $OpenBSD: Makefile,v 1.2 2003/06/25 02:42:50 deraadt Exp $ + +DEBUG_FLAGS+= -g + +PROG= diff +SRCS= diff.c diffdir.c diffreg.c +CFLAGS+= -std=c99 -Wall -pedantic + +.include Added: soc2012/jhagewood/diff/diff ============================================================================== Binary file. No diff available. Added: soc2012/jhagewood/diff/diff.1 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/jhagewood/diff/diff.1 Sat May 19 03:38:02 2012 (r235974) @@ -0,0 +1,511 @@ +.\" $FreeBSD$ +.\" $OpenBSD: diff.1,v 1.33 2007/05/31 19:20:09 jmc Exp $ +.\" +.\" Copyright (c) 1980, 1990, 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. 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. +.\" +.\" @(#)diff.1 8.1 (Berkeley) 6/30/93 +.\" +.Dd Apr 7, 2008 +.Dt DIFF 1 +.Os +.Sh NAME +.Nm diff +.Nd differential file and directory comparator +.Sh SYNOPSIS +.Nm diff +.Op Fl abdilpqTtw +.Op Fl I Ar pattern +.Oo +.Fl c | e | f | +.Fl n | u +.Oc +.Op Fl L Ar label +.Ar file1 file2 +.Nm diff +.Op Fl abdilpqTtw +.Op Fl I Ar pattern +.Op Fl L Ar label +.Fl C Op Ar number +.Ar file1 file2 +.Nm diff +.Op Fl abdilqtw +.Op Fl I Ar pattern +.Fl D Ar string +.Ar file1 file2 +.Nm diff +.Op Fl abdilpqTtw +.Op Fl I Ar pattern +.Op Fl L Ar label +.Fl U Ar number +.Ar file1 file2 +.Nm diff +.Op Fl abdilNPpqrsTtw +.Op Fl I Ar pattern +.Oo +.Fl c | e | f | +.Fl n | u +.Oc +.Bk -words +.Op Fl L Ar label +.Op Fl S Ar name +.Op Fl X Ar file +.Op Fl x Ar pattern +.Ek +.Ar dir1 dir2 +.Nm diff +.Op Fl v +.Sh DESCRIPTION +The +.Nm +utility compares the contents of +.Ar file1 +and +.Ar file2 +and writes to the standard output the list of changes necessary to +convert one file into the other. +No output is produced if the files are identical. +.Pp +Output options (mutually exclusive): +.Bl -tag -width Ds +.It Fl C Op Ar number , Fl Fl context Ns = Ns Op Ar number +Like +.Fl c +but produces a diff with +.Ar number +lines of context. +.It Fl c +Produces a diff with 3 lines of context. +With +.Fl c +the output format is modified slightly: +the output begins with identification of the files involved and +their creation dates and then each change is separated +by a line with fifteen +.Li * Ns 's . +The lines removed from +.Ar file1 +are marked with +.Sq \&-\ \& ; +those added to +.Ar file2 +are marked +.Sq \+\ \& . +Lines which are changed from one file to the other are marked in +both files with +.Sq !\ \& . +Changes which lie within 3 lines of each other are grouped together on +output. +.It Fl D Ar string , Fl Fl ifdef Ns = Ns Ar string +Creates a merged version of +.Ar file1 +and +.Ar file2 +on the standard output, with C preprocessor controls included so that +a compilation of the result without defining +.Ar string +is equivalent to compiling +.Ar file1 , +while defining +.Ar string +will yield +.Ar file2 . +.It Fl e , Fl Fl ed +Produces output in a form suitable as input for the editor utility, +.Xr ed 1 , +which can then be used to convert file1 into file2. +.Pp +Extra commands are added to the output when comparing directories with +.Fl e , +so that the result is a +.Xr sh 1 +script for converting text files which are common to the two directories +from their state in +.Ar dir1 +to their state in +.Ar dir2 . +.It Fl f +Identical output to that of the +.Fl e +flag, but in reverse order. +It cannot be digested by +.Xr ed 1 . +.It Fl n , Fl Fl rcs +Produces a script similar to that of +.Fl e , +but in the opposite order and with a count of changed lines on each +insert or delete command. +This is the form used by +.Xr rcsdiff 1 . +.It Fl q , Fl Fl brief +Just print a line when the files differ. +Does not output a list of changes. +.It Fl U Op Ar number , Fl Fl unified Ns = Ns Op Ar number +Like +.Fl u +but produces a diff with +.Ar number +lines of context. +.It Fl u +Produces a +.Em unified +diff with 3 lines of context. +A unified diff is similar to the context diff produced by the +.Fl c +option. +However, unlike with +.Fl c , +all lines to be changed (added and/or removed) are present in +a single section. +.El +.Pp +Comparison options: +.Bl -tag -width Ds +.It Fl a , Fl Fl text +Treat all files as +.Tn ASCII +text. +Normally +.Nm +will simply print +.Dq Binary files ... differ +if files contain binary characters. +Use of this option forces +.Nm +to produce a diff. +.It Fl b , Fl Fl ignore-space-change +Causes trailing blanks (spaces and tabs) to be ignored, and other +strings of blanks to compare equal. +.It Fl d , Fl Fl minimal +Try very hard to produce a diff as small as possible. +This may consume a lot of processing power and memory when processing +large files with many changes. +.It Fl I Ar pattern , Fl Fl ignore-matching-lines Ns = Ns Ar pattern +Ignores changes, insertions, and deletions whose lines match the +extended regular expression +.Ar pattern . +Multiple +.Fl I +patterns may be specified. +All lines in the change must match some pattern for the change to be +ignored. +See +.Xr re_format 7 +for more information on regular expression patterns. +.It Fl i , Fl Fl ignore-case +Ignores the case of letters. +E.g., +.Dq A +will compare equal to +.Dq a . +.It Fl L Ar label +Print +.Ar label +instead of the first (and second, if this option is specified twice) +file name and time in the context or unified diff header. +.It Fl l , Fl Fl paginate +Long output format; each text file +.Nm diff Ns \'d +is piped through +.Xr pr 1 +to paginate it; +other differences are remembered and summarized +after all text file differences are reported. +.It Fl p , Fl Fl show-c-function +With unified and context diffs, show with each change +the first 40 characters of the last line before the context beginning +with a letter, an underscore or a dollar sign. +For C source code following standard layout conventions, this will +show the prototype of the function the change applies to. +.It Fl T , Fl Fl initial-tab +Print a tab rather than a space before the rest of the line for the +normal, context or unified output formats. +This makes the alignment of tabs in the line consistent. +.It Fl t , Fl Fl expand-tabs +Will expand tabs in output lines. +Normal or +.Fl c +output adds character(s) to the front of each line which may screw up +the indentation of the original source lines and make the output listing +difficult to interpret. +This option will preserve the original source's indentation. +.It Fl w , Fl Fl ignore-all-space +Is similar to +.Fl b +but causes whitespace (blanks and tabs) to be totally ignored. +E.g., +.Dq if (\ \&a == b \&) +will compare equal to +.Dq if(a==b) . +.El +.Pp +Directory comparison options: +.Bl -tag -width Ds +.It Fl N , Fl Fl new-file +If a file is found in only one directory, act as if it was found in the +other directory too but was of zero size. +.It Fl P +If a file is found only in +.Ar dir2 , +act as if it was found in +.Ar dir1 +too but was of zero size. +.It Fl r , Fl Fl recursive +Causes application of +.Nm +recursively to common sub7 directories encountered. +.It Fl S Ar name , Fl starting-file Ns = Ns Ar name +Re-starts a directory +.Nm +in the middle, beginning with file +.Ar name . +.It Fl s , Fl Fl report-identical-files +Causes +.Nm +to report files which are the same, which are otherwise not mentioned. +.It Fl X Ar file , Fl Fl exclude-from Ns = Ns Ar file +Exclude files and subdirectories from comparison whose basenames match +lines in +.Ar file . +Multiple +.Fl X +options may be specified. +.It Fl x Ar pattern , Fl Fl exclude Ns = Ns Ar pattern +Exclude files and subdirectories from comparison whose basenames match +.Ar pattern . +Patterns are matched using shell-style globbing via +.Xr fnmatch 3 . +Multiple +.Fl x +options may be specified. +.It Fl v , Fl Fl version +Print version ino. +.El +.Pp +If both arguments are directories, +.Nm +sorts the contents of the directories by name, and then runs the +regular file +.Nm +algorithm, producing a change list, +on text files which are different. +Binary files which differ, +common subdirectories, and files which appear in only one directory +are described as such. +In directory mode only regular files and directories are compared. +If a non-regular file such as a device special file or +.Tn FIFO +is encountered, a diagnostic message is printed. +.Pp +If only one of +.Ar file1 +and +.Ar file2 +is a directory, +.Nm +is applied to the non-directory file and the file contained in +the directory file with a filename that is the same as the +last component of the non-directory file. +.Pp +If either +.Ar file1 +or +.Ar file2 +is +.Sq Fl , +the standard input is +used in its place. +.Ss Output Style +The default (without +.Fl e , +.Fl c , +or +.Fl n +.\" -C +options) +output contains lines of these forms, where +.Va XX , YY , ZZ , QQ +are line numbers respective of file order. +.Pp +.Bl -tag -width "XX,YYcZZ,QQ" -compact +.It Li XX Ns Ic a Ns Li YY +At (the end of) line +.Va XX +of +.Ar file1 , +append the contents +of line +.Va YY +of +.Ar file2 +to make them equal. +.It Li XX Ns Ic a Ns Li YY,ZZ +Same as above, but append the range of lines, +.Va YY +through +.Va ZZ +of +.Ar file2 +to line +.Va XX +of file1. +.It Li XX Ns Ic d Ns Li YY +At line +.Va XX +delete +the line. +The value +.Va YY +tells to which line the change would bring +.Ar file1 +in line with +.Ar file1 . +.It Li XX,YY Ns Ic d Ns Li ZZ +Delete the range of lines +.Va XX +through +.Va YY +in +.Ar file1 . +.It Li XX Ns Ic c Ns Li YY +Change the line +.Va XX +in +.Ar file1 +to the line +.Va YY +in +.Ar file2 . +.It Li XX,YY Ns Ic c Ns Li ZZ +Replace the range of specified lines with the line +.Va ZZ . +.It Li XX,YY Ns Ic c Ns Li ZZ,QQ +Replace the range +.Va XX , Ns Va YY +from +.Ar file1 +with the range +.Va ZZ , Ns Va QQ +from +.Ar file2 . +.El +.Pp +These lines resemble +.Xr ed 1 +subcommands to convert +.Ar file1 +into +.Ar file2 . +The line numbers before the action letters pertain to +.Ar file1 ; +those after pertain to +.Ar file2 . +Thus, by exchanging +.Ic a +for +.Ic d +and reading the line in reverse order, one can also +determine how to convert +.Ar file2 +into +.Ar file1 . +As in +.Xr ed 1 , +identical +pairs (where num1 = num2) are abbreviated as a single +number. +.Sh ENVIRONMENT +.Bl -tag -width TMPDIR +.It Ev TMPDIR +If the environment variable +.Ev TMPDIR +exists, +.Nm +will use the directory specified by +.Ev TMPDIR +as the temporary directory. +.El +.Sh FILES +.Bl -tag -width /tmp/diff.XXXXXXXX -compact +.It Pa /tmp/diff. Ns Ar XXXXXXXX +Temporary file used when comparing a device or the standard input. +Note that the temporary file is unlinked as soon as it is created +so it will not show up in a directory listing. +.El +.Sh DIAGNOSTICS +The +.Nm +utility exits with one of the following values: +.Pp +.Bl -tag -width Ds -compact -offset indent +.It 0 +No differences were found. +.It 1 +Differences were found. +.It \*(Gt1 +An error occurred. +.El +.Sh SEE ALSO +.Xr cmp 1 , +.Xr comm 1 , +.Xr diff3 1 , +.Xr ed 1 , +.Xr pr 1 , +.Xr sdiff 1 , +.Xr fnmatch 3 , +.Xr re_format 7 +.Sh STANDARDS +The +.Nm +utility is compliant with the +St -p1003.1-2004 +specification. +.Pp +The flags +.Op Fl aDdIiLlNnPpqSsTtUuwXx +are extensions to that specification. +.Sh HISTORY +A +.Nm +command appeared in +.At v6 . +.Sh BUGS +When comparing directories with the +.Fl b , +.Fl w +or +.Fl i +options specified, +.Nm +first compares the files ala +.Xr cmp 1 , +and then decides to run the +.Nm +algorithm if they are not equal. +This may cause a small amount of spurious output if the files +then turn out to be identical because the only differences are +insignificant whitespace or case differences. Added: soc2012/jhagewood/diff/diff.1.gz ============================================================================== Binary file. No diff available. Added: soc2012/jhagewood/diff/diff.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/jhagewood/diff/diff.c Sat May 19 03:38:02 2012 (r235974) @@ -0,0 +1,599 @@ +/*- + * Copyright (c) 2003 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +#include + +#ifndef lint +#if 0 +__RCSID("$OpenBSD: diff.c,v 1.50 2007/05/29 18:24:56 ray Exp $"); +#else +__FBSDID("$FreeBSD$"); +#endif +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "diff.h" +#include "pathnames.h" + +int aflag, bflag, dflag, iflag, lflag, Nflag, Pflag, pflag, rflag; +int sflag, tflag, Tflag, wflag; +int Bflag, yflag; +int strip_cr, tabsize=8; +char ignore_file_case = 0; +int format, context, status; +char *start, *ifdefname, *diffargs, *label[2], *ignore_pats; +struct stat stb1, stb2; +struct excludes *excludes_list; +regex_t ignore_re; + +int flag_opts = 0; + +#define OPTIONS "0123456789aBbC:cdD:efhI:iL:lnNPpqrS:sTtU:uvwXy:x" + + +/* Options which exceed manageable alphanumeric assignments */ +enum +{ + OPT_IGN_FN_CASE = CHAR_MAX + 1, + OPT_NIGN_FN_CASE, + OPT_STRIPCR, + OPT_NORMAL, + OPT_LEFTC, + OT_SUPCL, + OPT_GTYPE, + OPT_LF, + OPT_LLF, + OPT_TSIZE, + OPT_UNINF, + OPT_FFILE, + OPT_TOFILE, + OPT_HLINES, + OPT_LFILES, + OPT_HELP, +}; + + +static struct option longopts[] = { +/* XXX: UNIMPLEMENTED + { "normal", no_argument, NULL, OPT_NORMAL }, + { "left-column", no_argument, NULL, OPT_LEFTC }, + { "suppress-common-lines", no_argument, NULL, OT_SUPCL }, + { "GTYPE-group-format", required_argument, NULL, OPT_GTYPE }, + { "line-format", required_argument, NULL, OPT_LF }, + { "LTYPE-line-format", required_argument, NULL, OPT_LLF }, + { "unidirectional-new-file", no_argument, NULL, OPT_UNINF }, + { "from-file", required_argument, NULL, OPT_FFILE }, + { "to-file", required_argument, NULL, OPT_TOFILE }, + { "horizon-lines", required_argument, NULL, OPT_HLINES }, + { "speed-large-files", no_argument, NULL, OPT_LFILES }, */ + { "tabsize", optional_argument, NULL, OPT_TSIZE }, + { "strip-trailing-cr", no_argument, NULL, OPT_STRIPCR }, + { "help", no_argument, NULL, OPT_HELP }, + { "ignore-file-name-case", no_argument, NULL, OPT_IGN_FN_CASE }, + { "no-ignore-file-name-case", no_argument, NULL, OPT_NIGN_FN_CASE }, + { "text", no_argument, NULL, 'a' }, +/* XXX: UNIMPLEMENTED */ + { "ignore-blank-lines", no_argument, NULL, 'B' }, + { "ignore-space-change", no_argument, NULL, 'b' }, +/* XXX: -c is incompatible with GNU version */ + { "context", optional_argument, NULL, 'C' }, + { "ifdef", required_argument, NULL, 'D' }, + { "minimal", no_argument, NULL, 'd' }, +/* XXX: UNIMPLEMENTED + { "ignore-tab-expansion", no_argument, NULL, 'E' }, */ + { "ed", no_argument, NULL, 'e' }, +/* XXX: UNIMPLEMENTED + { "show-function-line", required_argument, NULL, 'F' }, */ + { "forward-ed", no_argument, NULL, 'f' }, + { "ignore-matching-lines", required_argument, NULL, 'I' }, + { "ignore-case", no_argument, NULL, 'i' }, + { "label", required_argument, NULL, 'L' }, + { "paginate", no_argument, NULL, 'l' }, + { "new-file", no_argument, NULL, 'N' }, + { "rcs", no_argument, NULL, 'n' }, + { "unidirectional-new-file", no_argument, NULL, 'P' }, + { "show-c-function", no_argument, NULL, 'p' }, + { "brief", no_argument, NULL, 'q' }, + { "recursive", no_argument, NULL, 'r' }, + { "starting-file", required_argument, NULL, 'S' }, + { "report-identical-files", no_argument, NULL, 's' }, + { "initial-tab", no_argument, NULL, 'T' }, + { "expand-tabs", no_argument, NULL, 't' }, +/* XXX: -u is incompatible with GNU version */ + { "unified", optional_argument, NULL, 'U' }, + { "version", no_argument, NULL, 'v' }, +/* XXX: UNIMPLEMENTED + { "width", optional_argument, NULL, 'W' }, */ + { "ignore-all-space", no_argument, NULL, 'w' }, + { "exclude-from", required_argument, NULL, 'X' }, + { "exclude", required_argument, NULL, 'x' }, + { "side-by-side", no_argument, NULL, 'y' }, + { NULL, 0, NULL, '\0'} +}; + +static const char *help_msg[] = { +"-a --text treat files as ASCII text", +"-B --ignore-blank-lines Ignore blank newlines in the comparison", +"-b --ignore-space-change Ignore all changes due to whitespace", +"-C NUM --context=[NUM] Show NUM lines before and after change (default 3)", +"-D --ifdef=NAME", +NULL, +}; +char **help_strs = (char **)help_msg; + +void set_argstr(char **, char **); + + +void usage(void); +void push_excludes(char *); +void push_ignore_pats(char *); +void read_excludes_file(char *); + +int +main(int argc, char **argv) +{ + char *ep, **oargv; + long l; + int ch, lastch, gotstdin, prevoptind, newarg; + int oargc; + + oargv = argv; + oargc = argc; + gotstdin = 0; + + lastch = '\0'; + prevoptind = 1; + newarg = 1; + while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) { + switch (ch) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (newarg) + usage(); /* disallow -[0-9]+ */ + else if (lastch == 'c' || lastch == 'u') + context = 0; + else if (!isdigit(lastch) || context > INT_MAX / 10) + usage(); + context = (context * 10) + (ch - '0'); + break; + case 'a': + aflag = 1; + break; + case 'b': + bflag = 1; + break; + case 'B': + Bflag = 1; + break; + case 'C': + case 'c': + format = D_CONTEXT; + if (optarg != NULL) { + l = strtol(optarg, &ep, 10); + if (*ep != '\0' || l < 0 || l >= INT_MAX) + usage(); + context = (int)l; + } else + context = 3; + break; + case 'D': + format = D_IFDEF; + ifdefname = optarg; + break; + case 'd': + dflag = 1; + break; + case 'e': + format = D_EDIT; + break; + case 'f': + format = D_REVERSE; + break; + case 'h': + /* silently ignore for backwards compatibility */ + break; + case 'I': + push_ignore_pats(optarg); + break; + case 'i': + iflag = 1; + break; + case 'L': + if (label[0] == NULL) + label[0] = optarg; + else if (label[1] == NULL) + label[1] = optarg; + else + usage(); + break; + case 'l': + lflag = 1; + signal(SIGPIPE, SIG_IGN); + break; + case 'N': + Nflag = 1; + break; + case 'n': + format = D_NREVERSE; + break; + case 'P': + Pflag = 1; + break; + case 'p': + pflag = 1; + break; + case 'r': + rflag = 1; + break; + case 'q': + format = D_BRIEF; + break; + case 'S': + start = optarg; + break; + case 's': + sflag = 1; + break; + case 'T': + Tflag = 1; + break; + case 't': + tflag = 1; + break; + case 'U': + case 'u': + format = D_UNIFIED; + if (optarg != NULL) { + l = strtol(optarg, &ep, 10); + if (*ep != '\0' || l < 0 || l >= INT_MAX) + usage(); + context = (int)l; + } else + context = 3; + break; + case 'v': + printf("FreeBSD diff 2.8.7\n"); + exit(0); + case 'w': + wflag = 1; + break; + case 'X': + read_excludes_file(optarg); + break; + case 'x': + push_excludes(optarg); + break; + case 'y': + yflag = 1; + break; + case OPT_TSIZE: + if (optarg != NULL) { + l = strtol(optarg, &ep, 10); + if (*ep != '\0' || l < 1 || l >= INT_MAX) + usage(); + tabsize = (int)l; + } else + tabsize = 8; + break; + case OPT_STRIPCR: + strip_cr=1; + break; + case OPT_IGN_FN_CASE: + ignore_file_case = 1; + break; + case OPT_NIGN_FN_CASE: + ignore_file_case = 0; + break; + case OPT_HELP: + for(;*help_strs;help_strs++) + { + printf("%s\n", *help_strs); + } + exit(2); + break; + default: + usage(); + break; + } + lastch = ch; + newarg = optind != prevoptind; + prevoptind = optind; + } + argc -= optind; + argv += optind; + + if(yflag) { + /* remove y flag from args and call sdiff */ + for(argv=oargv; argv && strcmp(*argv, "-y") != 0; argv++); + while(argv != &oargv[oargc]){ + *argv=*(argv+1); + argv++; + } + oargv[0] = _PATH_SDIFF; + *argv= "\0"; + + execv(_PATH_SDIFF, oargv); + _exit(127); + } + + /* + * Do sanity checks, fill in stb1 and stb2 and call the appropriate + * driver routine. Both drivers use the contents of stb1 and stb2. + */ + if (argc != 2) + usage(); + if (ignore_pats != NULL) { + char buf[BUFSIZ]; + int error; + + if ((error = regcomp(&ignore_re, ignore_pats, + REG_NEWLINE | REG_EXTENDED)) != 0) { + regerror(error, &ignore_re, buf, sizeof(buf)); + if (*ignore_pats != '\0') + errx(2, "%s: %s", ignore_pats, buf); + else + errx(2, "%s", buf); + } + } + if (strcmp(argv[0], "-") == 0) { + fstat(STDIN_FILENO, &stb1); + gotstdin = 1; + } else if (stat(argv[0], &stb1) != 0) + err(2, "%s", argv[0]); + if (strcmp(argv[1], "-") == 0) { + fstat(STDIN_FILENO, &stb2); + gotstdin = 1; + } else if (stat(argv[1], &stb2) != 0) + err(2, "%s", argv[1]); + if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode))) + errx(2, "can't compare - to a directory"); + set_argstr(oargv, argv); + if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) { + if (format == D_IFDEF) + errx(2, "-D option not supported with directories"); + diffdir(argv[0], argv[1]); + } else { + if (S_ISDIR(stb1.st_mode)) { + argv[0] = splice(argv[0], argv[1]); + if (stat(argv[0], &stb1) < 0) + err(2, "%s", argv[0]); + } + if (S_ISDIR(stb2.st_mode)) { + argv[1] = splice(argv[1], argv[0]); + if (stat(argv[1], &stb2) < 0) + err(2, "%s", argv[1]); + } + print_status(diffreg(argv[0], argv[1], 0), argv[0], argv[1], + NULL); + } + exit(status); +} + +void * +emalloc(size_t n) +{ + void *p; + + if (n == 0) + errx(2, NULL); + + if ((p = malloc(n)) == NULL) + errx(2, NULL); + return (p); +} + +void * +erealloc(void *p, size_t n) +{ + void *q; + + if (n == 0) + errx(2, NULL); + if (p == NULL) + q = malloc(n); + else + q = realloc(p, n); + if (q == NULL) + errx(2, NULL); + return (q); +} + +int +easprintf(char **ret, const char *fmt, ...) +{ + int len; + va_list ap; + + va_start(ap, fmt); *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-soc-all@FreeBSD.ORG Sat May 19 03:40:49 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id C1CB01065672 for ; Sat, 19 May 2012 03:40:48 +0000 (UTC) (envelope-from jhagewood@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Sat, 19 May 2012 03:40:48 +0000 Date: Sat, 19 May 2012 03:40:48 +0000 From: jhagewood@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120519034048.C1CB01065672@hub.freebsd.org> Cc: Subject: socsvn commit: r235975 - soc2012/jhagewood X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 May 2012 03:40:49 -0000 Author: jhagewood Date: Sat May 19 03:40:48 2012 New Revision: 235975 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235975 Log: Deleted: soc2012/jhagewood/svn-commit.2.tmp From owner-svn-soc-all@FreeBSD.ORG Sat May 19 03:41:02 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 54525106566B for ; Sat, 19 May 2012 03:41:01 +0000 (UTC) (envelope-from jhagewood@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Sat, 19 May 2012 03:41:01 +0000 Date: Sat, 19 May 2012 03:41:01 +0000 From: jhagewood@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120519034101.54525106566B@hub.freebsd.org> Cc: Subject: socsvn commit: r235976 - soc2012/jhagewood X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 May 2012 03:41:02 -0000 Author: jhagewood Date: Sat May 19 03:41:01 2012 New Revision: 235976 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=235976 Log: Deleted: soc2012/jhagewood/svn-commit.tmp