Adapted to ntfs-3g.1.2812
							parent
							
								
									ca9e62559a
								
							
						
					
					
						commit
						499e106341
					
				
							
								
								
									
										1
									
								
								AUTHORS
								
								
								
								
							
							
						
						
									
										1
									
								
								AUTHORS
								
								
								
								
							|  | @ -5,6 +5,7 @@ Jean-Pierre Andre | |||
| Alon Bar-Lev | ||||
| Dominique L Bouix | ||||
| Csaba Henk | ||||
| Bernhard Kaindl | ||||
| Erik Larsson | ||||
| Alejandro Pulver | ||||
| Szabolcs Szakacsits | ||||
|  |  | |||
|  | @ -186,7 +186,8 @@ struct _ntfs_attr { | |||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * enum ntfs_attr_state_bits - bits for the state field in the ntfs_attr structure | ||||
|  * enum ntfs_attr_state_bits - bits for the state field in the ntfs_attr | ||||
|  * structure | ||||
|  */ | ||||
| typedef enum { | ||||
| 	NA_Initialized,		/* 1: structure is initialized. */ | ||||
|  |  | |||
|  | @ -27,13 +27,20 @@ | |||
| #include "config.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WINDOWS | ||||
| 
 | ||||
| #ifndef HAVE_FFS | ||||
| #define HAVE_FFS | ||||
| extern int ffs(int i); | ||||
| #endif /* HAVE_FFS */ | ||||
| 
 | ||||
| #ifndef HAVE_DAEMON | ||||
| extern int daemon(int nochdir, int noclose); | ||||
| #endif /* HAVE_DAEMON */ | ||||
| 
 | ||||
| #ifndef HAVE_STRSEP | ||||
| extern char *strsep(char **stringp, const char *delim); | ||||
| #endif /* HAVE_STRSEP */ | ||||
| 
 | ||||
| #ifdef WINDOWS | ||||
| 
 | ||||
| #define HAVE_STDIO_H		/* mimic config.h */ | ||||
| #define HAVE_STDARG_H | ||||
| 
 | ||||
|  |  | |||
|  | @ -128,12 +128,14 @@ struct _ntfs_inode { | |||
| 					   inode of the base mft record. */ | ||||
| 	}; | ||||
| 
 | ||||
| 	/* Temp: for directory handling */ | ||||
| 	void *private_data;	/* ntfs_dt containing this inode */ | ||||
| 	int ref_count; | ||||
| 
 | ||||
| 	/* Below fields are valid only for base inode. */ | ||||
| 	s64 data_size;		/* Data size stored in the filename index. */ | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * These two fields are used to sync filename index and guaranteed to be | ||||
| 	 * correct, however value in index itself maybe wrong (windows itself | ||||
| 	 * do not update them properly). | ||||
| 	 */ | ||||
| 	s64 data_size;		/* Data size of unnamed DATA attribute. */ | ||||
| 	s64 allocated_size;	/* Allocated size stored in the filename
 | ||||
| 				   index. (NOTE: Equal to allocated size of | ||||
| 				   the unnamed data attribute for normal or | ||||
|  | @ -141,6 +143,11 @@ struct _ntfs_inode { | |||
| 				   of the unnamed data attribute for sparse or | ||||
| 				   compressed files.) */ | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * These four fields are copy of relevant fields from | ||||
| 	 * STANDARD_INFORMATION attribute and used to sync it and FILE_NAME | ||||
| 	 * attribute in the index. | ||||
| 	 */ | ||||
| 	time_t creation_time; | ||||
| 	time_t last_data_change_time; | ||||
| 	time_t last_mft_change_time; | ||||
|  |  | |||
|  | @ -239,10 +239,6 @@ struct _ntfs_volume { | |||
| 	struct CACHE_HEADER *legacy_cache; | ||||
| #endif | ||||
| 
 | ||||
| 	/* Temp: for directory handling */ | ||||
| 	void *private_data;	/* ntfs_dir for . */ | ||||
| 	void *private_bmp1;	/* ntfs_bmp for $MFT/$BITMAP */ | ||||
| 	void *private_bmp2;	/* ntfs_bmp for $Bitmap */ | ||||
| }; | ||||
| 
 | ||||
| extern ntfs_volume *ntfs_volume_alloc(void); | ||||
|  |  | |||
|  | @ -506,7 +506,7 @@ void ntfs_attr_close(ntfs_attr *na) | |||
|  * @na:		ntfs attribute for which to map (part of) a runlist | ||||
|  * @vcn:	map runlist part containing this vcn | ||||
|  * | ||||
|  * Map the part of a runlist containing the @vcn of an the ntfs attribute @na. | ||||
|  * Map the part of a runlist containing the @vcn of the ntfs attribute @na. | ||||
|  * | ||||
|  * Return 0 on success and -1 on error with errno set to the error code. | ||||
|  */ | ||||
|  | @ -549,8 +549,8 @@ int ntfs_attr_map_runlist(ntfs_attr *na, VCN vcn) | |||
|  * ntfs_attr_map_whole_runlist - map the whole runlist of an ntfs attribute | ||||
|  * @na:		ntfs attribute for which to map the runlist | ||||
|  * | ||||
|  * Map the whole runlist of an the ntfs attribute @na.  For an attribute made | ||||
|  * up of only one attribute extent this is the same as calling | ||||
|  * Map the whole runlist of the ntfs attribute @na.  For an attribute made up | ||||
|  * of only one attribute extent this is the same as calling | ||||
|  * ntfs_attr_map_runlist(na, 0) but for an attribute with multiple extents this | ||||
|  * will map the runlist fragments from each of the extents thus giving access | ||||
|  * to the entirety of the disk allocation of an attribute. | ||||
|  | @ -2998,7 +2998,7 @@ int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx) | |||
| 		NInoAttrListClearDirty(base_ni); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Free MFT record, if it isn't contain attributes. */ | ||||
| 	/* Free MFT record, if it doesn't contain attributes. */ | ||||
| 	if (le32_to_cpu(ctx->mrec->bytes_in_use) - | ||||
| 			le16_to_cpu(ctx->mrec->attrs_offset) == 8) { | ||||
| 		if (ntfs_mft_record_free(ni->vol, ni)) { | ||||
|  | @ -3260,9 +3260,9 @@ rm_attr_err_out: | |||
| 			(ATTR_RECORD*)((u8*)attr_ni->mrec + offset), 0)) | ||||
| 		ntfs_log_perror("Failed to remove just added attribute #2"); | ||||
| free_err_out: | ||||
| 	/* Free MFT record, if it isn't contain attributes. */ | ||||
| 	/* Free MFT record, if it doesn't contain attributes. */ | ||||
| 	if (le32_to_cpu(attr_ni->mrec->bytes_in_use) - | ||||
| 			le32_to_cpu(attr_ni->mrec->attrs_offset) == 8) | ||||
| 			le16_to_cpu(attr_ni->mrec->attrs_offset) == 8) | ||||
| 		if (ntfs_mft_record_free(attr_ni->vol, attr_ni)) | ||||
| 			ntfs_log_perror("Failed to free MFT record"); | ||||
| err_out: | ||||
|  | @ -4325,7 +4325,7 @@ retry: | |||
| 			 */ | ||||
| 			first_lcn = ntfs_rl_vcn_to_lcn(na->rl, stop_vcn); | ||||
| 			if (first_lcn == LCN_EINVAL) { | ||||
| 				err = EIO; | ||||
| 				errno = EIO; | ||||
| 				ntfs_log_perror("Bad runlist"); | ||||
| 				goto put_err_out; | ||||
| 			} | ||||
|  | @ -4349,8 +4349,7 @@ retry: | |||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		err = ntfs_attr_update_meta(a, na, m, ctx); | ||||
| 		switch (err) { | ||||
| 		switch (ntfs_attr_update_meta(a, na, m, ctx)) { | ||||
| 			case -1: return -1; | ||||
| 			case -2: goto retry; | ||||
| 			case -3: goto put_err_out; | ||||
|  | @ -4360,7 +4359,6 @@ retry: | |||
| 		mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, na->rl, | ||||
| 								stop_vcn); | ||||
| 		if (mp_size <= 0) { | ||||
| 			err = errno; | ||||
| 			ntfs_log_perror("%s: get MP size failed", __FUNCTION__); | ||||
| 			goto put_err_out; | ||||
| 		} | ||||
|  | @ -4419,8 +4417,8 @@ retry: | |||
| 			if (ntfs_attr_record_resize(m, a, | ||||
| 					le16_to_cpu(a->mapping_pairs_offset) + | ||||
| 					mp_size)) { | ||||
| 				errno = EIO; | ||||
| 				ntfs_log_perror("Failed to resize attribute"); | ||||
| 				err = EIO; | ||||
| 				goto put_err_out; | ||||
| 			} | ||||
| 		} | ||||
|  | @ -4444,7 +4442,6 @@ retry: | |||
| 				stop_vcn, &stop_vcn)) | ||||
| 			finished_build = TRUE; | ||||
| 		if (!finished_build && errno != ENOSPC) { | ||||
| 			err = errno; | ||||
| 			ntfs_log_perror("Failed to build mapping pairs"); | ||||
| 			goto put_err_out; | ||||
| 		} | ||||
|  | @ -4452,7 +4449,6 @@ retry: | |||
| 	} | ||||
| 	/* Check whether error occurred. */ | ||||
| 	if (errno != ENOENT) { | ||||
| 		err = errno; | ||||
| 		ntfs_log_perror("%s: Attribute lookup failed", __FUNCTION__); | ||||
| 		goto put_err_out; | ||||
| 	} | ||||
|  | @ -4468,14 +4464,12 @@ retry: | |||
| 				continue; | ||||
| 			/* Remove unused attribute record. */ | ||||
| 			if (ntfs_attr_record_rm(ctx)) { | ||||
| 				err = errno; | ||||
| 				ntfs_log_perror("Could not remove unused attr"); | ||||
| 				goto put_err_out; | ||||
| 			} | ||||
| 			ntfs_attr_reinit_search_ctx(ctx); | ||||
| 		} | ||||
| 		if (errno != ENOENT) { | ||||
| 			err = errno; | ||||
| 			ntfs_log_perror("%s: Attr lookup failed", __FUNCTION__); | ||||
| 			goto put_err_out; | ||||
| 		} | ||||
|  | @ -4492,14 +4486,12 @@ retry: | |||
| 		mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, | ||||
| 						na->rl, stop_vcn); | ||||
| 		if (mp_size <= 0) { | ||||
| 			err = errno; | ||||
| 			ntfs_log_perror("%s: get mp size failed", __FUNCTION__); | ||||
| 			goto put_err_out; | ||||
| 		} | ||||
| 		/* Allocate new mft record. */ | ||||
| 		ni = ntfs_mft_record_alloc(na->ni->vol, base_ni); | ||||
| 		if (!ni) { | ||||
| 			err = errno; | ||||
| 			ntfs_log_perror("Could not allocate new MFT record"); | ||||
| 			goto put_err_out; | ||||
| 		} | ||||
|  | @ -4524,6 +4516,7 @@ retry: | |||
| 			ntfs_log_perror("Could not add attribute extent"); | ||||
| 			if (ntfs_mft_record_free(na->ni->vol, ni)) | ||||
| 				ntfs_log_perror("Could not free MFT record"); | ||||
| 			errno = err; | ||||
| 			goto put_err_out; | ||||
| 		} | ||||
| 		a = (ATTR_RECORD*)((u8*)m + err); | ||||
|  | @ -4536,6 +4529,7 @@ retry: | |||
| 			ntfs_log_perror("Failed to build MP"); | ||||
| 			if (ntfs_mft_record_free(na->ni->vol, ni)) | ||||
| 				ntfs_log_perror("Couldn't free MFT record"); | ||||
| 			errno = err; | ||||
| 			goto put_err_out; | ||||
| 		} | ||||
| 		a->highest_vcn = cpu_to_sle64(stop_vcn - 1); | ||||
|  | @ -4551,7 +4545,6 @@ out: | |||
| put_err_out: | ||||
| 	if (ctx) | ||||
| 		ntfs_attr_put_search_ctx(ctx); | ||||
| 	errno = err; | ||||
| 	goto out; | ||||
| } | ||||
| #undef NTFS_VCN_DELETE_MARK | ||||
|  | @ -4916,7 +4909,7 @@ rollback: | |||
| 		ntfs_log_perror("Couldn't truncate runlist. Rollback failed"); | ||||
| 	} else { | ||||
| 		/* Prepare to mapping pairs update. */ | ||||
| 		na->allocated_size = org_alloc_size << vol->cluster_size_bits; | ||||
| 		na->allocated_size = org_alloc_size; | ||||
| 		/* Restore mapping pairs. */ | ||||
| 		if (ntfs_attr_update_mapping_pairs(na, 0 /*na->allocated_size >>
 | ||||
| 					vol->cluster_size_bits*/)) { | ||||
|  |  | |||
|  | @ -20,16 +20,12 @@ | |||
|  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
| 
 | ||||
| #ifdef WINDOWS | ||||
| 
 | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #include "config.h" | ||||
| #endif | ||||
| 
 | ||||
| #include "compat.h" | ||||
| 
 | ||||
| /* TODO: Add check for FFS in the configure script... (AIA) */ | ||||
| 
 | ||||
| #ifndef HAVE_FFS | ||||
| /**
 | ||||
|  * ffs - Find the first set bit in an int | ||||
|  | @ -69,5 +65,186 @@ int ffs(int x) | |||
| } | ||||
| #endif /* HAVE_FFS */ | ||||
| 
 | ||||
| #endif /* WINDOWS */ | ||||
| #ifndef HAVE_DAEMON | ||||
| /* ************************************************************
 | ||||
|  *  From: src.opensolaris.org | ||||
|  *  src/lib/libresolv2/common/bsd/daemon.c | ||||
|  */ | ||||
| /*
 | ||||
|  * Copyright (c) 1997-2000 by Sun Microsystems, Inc. | ||||
|  * All rights reserved. | ||||
|  */ | ||||
| 
 | ||||
| #if defined(LIBC_SCCS) && !defined(lint) | ||||
| static const char sccsid[] = "@(#)daemon.c	8.1 (Berkeley) 6/4/93"; | ||||
| static const char rcsid[] = "$Id: compat.c,v 1.1.1.1.2.1 2008-08-16 15:17:44 jpandre Exp $"; | ||||
| #endif /* LIBC_SCCS and not lint */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Copyright (c) 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. All advertising materials mentioning features or use of this software | ||||
|  *    must display the following acknowledgement: | ||||
|  *	This product includes software developed by the University of | ||||
|  *	California, Berkeley and its contributors. | ||||
|  * 4. Neither the name of the University nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| #ifdef HAVE_FCNTL_H | ||||
| #include <fcntl.h> | ||||
| #endif | ||||
| #ifdef HAVE_UNISTD_H | ||||
| #include <unistd.h> | ||||
| #endif | ||||
| 
 | ||||
| int daemon(int nochdir, int noclose) { | ||||
| 	int fd; | ||||
| 
 | ||||
| 	switch (fork()) { | ||||
| 	case -1: | ||||
| 		return (-1); | ||||
| 	case 0: | ||||
| 		break; | ||||
| 	default: | ||||
| 		_exit(0); | ||||
| 	} | ||||
| 
 | ||||
| 	if (setsid() == -1) | ||||
| 		return (-1); | ||||
| 
 | ||||
| 	if (!nochdir) | ||||
| 		(void)chdir("/"); | ||||
| 
 | ||||
| 	if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) { | ||||
| 		(void)dup2(fd, 0); | ||||
| 		(void)dup2(fd, 1); | ||||
| 		(void)dup2(fd, 2); | ||||
| 		if (fd > 2) | ||||
| 			(void)close (fd); | ||||
| 	} | ||||
| 	return (0); | ||||
| } | ||||
| /* 
 | ||||
|  *  End: src/lib/libresolv2/common/bsd/daemon.c | ||||
|  *************************************************************/ | ||||
| #endif /* HAVE_DAEMON */ | ||||
| 
 | ||||
| #ifndef HAVE_STRSEP | ||||
| /* ************************************************************
 | ||||
|  *  From: src.opensolaris.org | ||||
|  *  src/lib/libresolv2/common/bsd/strsep.c | ||||
|  */ | ||||
| /*
 | ||||
|  * Copyright (c) 1997, by Sun Microsystems, Inc. | ||||
|  * All rights reserved. | ||||
|  */ | ||||
| 
 | ||||
| #if defined(LIBC_SCCS) && !defined(lint) | ||||
| static const char sccsid[] = "strsep.c	8.1 (Berkeley) 6/4/93"; | ||||
| static const char rcsid[] = "$Id: compat.c,v 1.1.1.1.2.1 2008-08-16 15:17:44 jpandre Exp $"; | ||||
| #endif /* LIBC_SCCS and not lint */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Copyright (c) 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. All advertising materials mentioning features or use of this software | ||||
|  *    must display the following acknowledgement: | ||||
|  *	This product includes software developed by the University of | ||||
|  *	California, Berkeley and its contributors. | ||||
|  * 4. Neither the name of the University nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| #ifdef HAVE_STRING_H | ||||
| #include <string.h> | ||||
| #endif | ||||
| #ifdef HAVE_STDIO_H | ||||
| #include <stdio.h> | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Get next token from string *stringp, where tokens are possibly-empty | ||||
|  * strings separated by characters from delim.   | ||||
|  * | ||||
|  * Writes NULs into the string at *stringp to end tokens. | ||||
|  * delim need not remain constant from call to call. | ||||
|  * On return, *stringp points past the last NUL written (if there might | ||||
|  * be further tokens), or is NULL (if there are definitely no more tokens). | ||||
|  * | ||||
|  * If *stringp is NULL, strsep returns NULL. | ||||
|  */ | ||||
| char *strsep(char **stringp, const char *delim) { | ||||
| 	char *s; | ||||
| 	const char *spanp; | ||||
| 	int c, sc; | ||||
| 	char *tok; | ||||
| 
 | ||||
| 	if ((s = *stringp) == NULL) | ||||
| 		return (NULL); | ||||
| 	for (tok = s;;) { | ||||
| 		c = *s++; | ||||
| 		spanp = delim; | ||||
| 		do { | ||||
| 			if ((sc = *spanp++) == c) { | ||||
| 				if (c == 0) | ||||
| 					s = NULL; | ||||
| 				else | ||||
| 					s[-1] = 0; | ||||
| 				*stringp = s; | ||||
| 				return (tok); | ||||
| 			} | ||||
| 		} while (sc != 0); | ||||
| 	} | ||||
| 	/* NOTREACHED */ | ||||
| } | ||||
| 
 | ||||
| /* 
 | ||||
|  *  End: src/lib/libresolv2/common/bsd/strsep.c | ||||
|  *************************************************************/ | ||||
| #endif /* HAVE_STRSEP */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -1419,21 +1419,21 @@ static int ntfs_ib_split(ntfs_index_context *icx, INDEX_BLOCK *ib) | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* JPA static */ | ||||
| int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie) | ||||
| { | ||||
| 	INDEX_HEADER *ih; | ||||
| 	int allocated_size, new_size; | ||||
| 	int ret = STATUS_ERROR; | ||||
| 
 | ||||
| 	 | ||||
| #ifdef DEBUG | ||||
| /* removed by JPA to make function usable for security indexes
 | ||||
| 	char *fn; | ||||
| 	 | ||||
| 	fn = ntfs_ie_filename_get(ie); | ||||
| 	ntfs_log_trace("file: '%s'\n", fn); | ||||
| 	ntfs_attr_name_free(&fn); | ||||
| */ | ||||
| #endif | ||||
| 	 | ||||
| 	while (1) { | ||||
| 				 | ||||
|  |  | |||
|  | @ -275,6 +275,8 @@ err_out: | |||
|  * If it is an extent inode, we disconnect it from its base inode before we | ||||
|  * destroy it. | ||||
|  * | ||||
|  * It is OK to pass NULL to this function, it is just noop in this case. | ||||
|  * | ||||
|  * Return 0 on success or -1 on error with errno set to the error code. On | ||||
|  * error, @ni has not been freed. The user should attempt to handle the error | ||||
|  * and call ntfs_inode_close() again. The following error codes are defined: | ||||
|  |  | |||
|  | @ -52,6 +52,10 @@ typedef struct ntfs_volume ntfs_volume; | |||
| #include "types.h" | ||||
| #include "device.h" | ||||
| 
 | ||||
| #ifndef MAX_PATH | ||||
| #define MAX_PATH 1024 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef NTFS_BLOCK_SIZE | ||||
| #define NTFS_BLOCK_SIZE		512 | ||||
| #define NTFS_BLOCK_SIZE_BITS	9 | ||||
|  |  | |||
							
								
								
									
										116
									
								
								src/ntfs-3g.c
								
								
								
								
							
							
						
						
									
										116
									
								
								src/ntfs-3g.c
								
								
								
								
							|  | @ -75,6 +75,14 @@ | |||
| #include <sys/xattr.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_MKDEV_H | ||||
| #include <sys/mkdev.h> | ||||
| #endif | ||||
| 
 | ||||
| #include "compat.h" | ||||
| #include "attrib.h" | ||||
| #include "inode.h" | ||||
| #include "volume.h" | ||||
|  | @ -376,18 +384,16 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf) | |||
| 	int res = 0; | ||||
| 	ntfs_inode *ni; | ||||
| 	ntfs_attr *na; | ||||
| 	ntfs_volume *vol; | ||||
| 	char *path = NULL; | ||||
| 	ntfschar *stream_name; | ||||
| 	int stream_name_len; | ||||
| 	struct SECURITY_CONTEXT security; | ||||
| 
 | ||||
| 	vol = ctx->vol; | ||||
| 	stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name); | ||||
| 	if (stream_name_len < 0) | ||||
| 		return stream_name_len; | ||||
| 	memset(stbuf, 0, sizeof(struct stat)); | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) { | ||||
| 		res = -errno; | ||||
| 		goto exit; | ||||
|  | @ -630,15 +636,13 @@ static int ntfs_fuse_readdir(const char *path, void *buf, | |||
| 		struct fuse_file_info *fi __attribute__((unused))) | ||||
| { | ||||
| 	ntfs_fuse_fill_context_t fill_ctx; | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni; | ||||
| 	s64 pos = 0; | ||||
| 	int err = 0; | ||||
| 
 | ||||
| 	vol = ctx->vol; | ||||
| 	fill_ctx.filler = filler; | ||||
| 	fill_ctx.buf = buf; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) | ||||
| 		return -errno; | ||||
| 	if (ntfs_readdir(ni, &pos, &fill_ctx, | ||||
|  | @ -653,7 +657,6 @@ static int ntfs_fuse_readdir(const char *path, void *buf, | |||
| static int ntfs_fuse_open(const char *org_path, | ||||
| 		struct fuse_file_info *fi) | ||||
| { | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni; | ||||
| 	ntfs_attr *na; | ||||
| 	int res = 0; | ||||
|  | @ -666,8 +669,7 @@ static int ntfs_fuse_open(const char *org_path, | |||
| 	stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name); | ||||
| 	if (stream_name_len < 0) | ||||
| 		return stream_name_len; | ||||
| 	vol = ctx->vol; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (ni) { | ||||
| 		na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len); | ||||
| 		if (na) { | ||||
|  | @ -765,7 +767,6 @@ exit: | |||
| static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size, | ||||
| 		off_t offset, struct fuse_file_info *fi __attribute__((unused))) | ||||
| { | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni = NULL; | ||||
| 	ntfs_attr *na = NULL; | ||||
| 	char *path = NULL; | ||||
|  | @ -777,8 +778,7 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size, | |||
| 		res = stream_name_len; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	vol = ctx->vol; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) { | ||||
| 		res = -errno; | ||||
| 		goto exit; | ||||
|  | @ -789,17 +789,18 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size, | |||
| 		goto exit; | ||||
| 	} | ||||
| 	while (size) { | ||||
| 		res = ntfs_attr_pwrite(na, offset, size, buf); | ||||
| 		if (res < (s64)size) | ||||
| 			ntfs_log_perror("ntfs_attr_pwrite partial write (%lld: " | ||||
| 				"%lld <> %d)", (long long)offset, (long long)size, res); | ||||
| 		if (res <= 0) { | ||||
| 		s64 ret = ntfs_attr_pwrite(na, offset, size, buf); | ||||
| 		if (0 <= ret && ret < (s64)size) | ||||
| 			ntfs_log_perror("ntfs_attr_pwrite partial write to '%s'" | ||||
| 				" (%lld: %lld <> %lld)", path, (long long)offset, | ||||
| 				(long long)size, ret); | ||||
| 		if (ret <= 0) { | ||||
| 			res = -errno; | ||||
| 			goto exit; | ||||
| 		} | ||||
| 		size -= res; | ||||
| 		offset += res; | ||||
| 		total += res; | ||||
| 		size   -= ret; | ||||
| 		offset += ret; | ||||
| 		total  += ret; | ||||
| 	} | ||||
| 	res = total; | ||||
| 	if (res > 0) | ||||
|  | @ -822,7 +823,6 @@ out: | |||
| 
 | ||||
| static int ntfs_fuse_trunc(const char *org_path, off_t size, BOOL chkwrite) | ||||
| { | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni = NULL; | ||||
| 	ntfs_attr *na = NULL; | ||||
| 	int res; | ||||
|  | @ -834,8 +834,7 @@ static int ntfs_fuse_trunc(const char *org_path, off_t size, BOOL chkwrite) | |||
| 	stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name); | ||||
| 	if (stream_name_len < 0) | ||||
| 		return stream_name_len; | ||||
| 	vol = ctx->vol; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) | ||||
| 		goto exit; | ||||
| 
 | ||||
|  | @ -1166,29 +1165,7 @@ static int ntfs_fuse_create_stream(const char *path, | |||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| static int ntfs_fuse_create_file(const char *org_path, mode_t mode,  | ||||
| 			struct fuse_file_info *fi __attribute__((unused))) | ||||
| { | ||||
| 	char *path = NULL; | ||||
| 	ntfschar *stream_name; | ||||
| 	int stream_name_len; | ||||
| 	int res; | ||||
| 
 | ||||
| 	stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name); | ||||
| 	if (stream_name_len < 0) | ||||
| 		return stream_name_len; | ||||
| 	if (!stream_name_len) | ||||
| 		res = ntfs_fuse_create(path, mode, 0, NULL); | ||||
| 	else | ||||
| 		res = ntfs_fuse_create_stream(path, stream_name, | ||||
| 				stream_name_len); | ||||
| 	free(path); | ||||
| 	if (stream_name_len) | ||||
| 		free(stream_name); | ||||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| static int ntfs_fuse_mknod(const char *org_path, mode_t mode, dev_t dev) | ||||
| static int ntfs_fuse_mknod_common(const char *org_path, mode_t mode, dev_t dev) | ||||
| { | ||||
| 	char *path = NULL; | ||||
| 	ntfschar *stream_name; | ||||
|  | @ -1214,6 +1191,17 @@ exit: | |||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| static int ntfs_fuse_mknod(const char *path, mode_t mode, dev_t dev) | ||||
| { | ||||
| 	return ntfs_fuse_mknod_common(path, mode, dev); | ||||
| } | ||||
| 
 | ||||
| static int ntfs_fuse_create_file(const char *path, mode_t mode, | ||||
| 			    struct fuse_file_info *fi __attribute__((unused))) | ||||
| { | ||||
| 	return ntfs_fuse_mknod_common(path, mode, 0); | ||||
| } | ||||
| 
 | ||||
| static int ntfs_fuse_symlink(const char *to, const char *from) | ||||
| { | ||||
| 	if (ntfs_fuse_is_named_data_stream(from)) | ||||
|  | @ -1616,17 +1604,13 @@ static const int nf_ns_xattr_preffix_len = 5; | |||
| static int ntfs_fuse_listxattr(const char *path, char *list, size_t size) | ||||
| { | ||||
| 	ntfs_attr_search_ctx *actx = NULL; | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni; | ||||
| 	char *to = list; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	if (ctx->streams != NF_STREAMS_INTERFACE_XATTR) | ||||
| 		return -EOPNOTSUPP; | ||||
| 	vol = ctx->vol; | ||||
| 	if (!vol) | ||||
| 		return -ENODEV; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) | ||||
| 		return -errno; | ||||
| 	actx = ntfs_attr_get_search_ctx(ni, NULL); | ||||
|  | @ -1680,17 +1664,13 @@ static int ntfs_fuse_getxattr_windows(const char *path, const char *name, | |||
| 				char *value, size_t size) | ||||
| { | ||||
| 	ntfs_attr_search_ctx *actx = NULL; | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni; | ||||
| 	char *to = value; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	if (strcmp(name, "ntfs.streams.list")) | ||||
| 		return -EOPNOTSUPP; | ||||
| 	vol = ctx->vol; | ||||
| 	if (!vol) | ||||
| 		return -ENODEV; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) | ||||
| 		return -errno; | ||||
| 	actx = ntfs_attr_get_search_ctx(ni, NULL); | ||||
|  | @ -1746,7 +1726,6 @@ exit: | |||
| static int ntfs_fuse_getxattr(const char *path, const char *name, | ||||
| 				char *value, size_t size) | ||||
| { | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni; | ||||
| 	ntfs_attr *na = NULL; | ||||
| 	ntfschar *lename = NULL; | ||||
|  | @ -1759,10 +1738,7 @@ static int ntfs_fuse_getxattr(const char *path, const char *name, | |||
| 	if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) || | ||||
| 			strlen(name) == (size_t)nf_ns_xattr_preffix_len) | ||||
| 		return -ENODATA; | ||||
| 	vol = ctx->vol; | ||||
| 	if (!vol) | ||||
| 		return -ENODEV; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) | ||||
| 		return -errno; | ||||
| 	lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename); | ||||
|  | @ -1796,7 +1772,6 @@ exit: | |||
| static int ntfs_fuse_setxattr(const char *path, const char *name, | ||||
| 				const char *value, size_t size, int flags) | ||||
| { | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni; | ||||
| 	ntfs_attr *na = NULL; | ||||
| 	ntfschar *lename = NULL; | ||||
|  | @ -1807,10 +1782,7 @@ static int ntfs_fuse_setxattr(const char *path, const char *name, | |||
| 	if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) || | ||||
| 			strlen(name) == (size_t)nf_ns_xattr_preffix_len) | ||||
| 		return -EACCES; | ||||
| 	vol = ctx->vol; | ||||
| 	if (!vol) | ||||
| 		return -ENODEV; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) | ||||
| 		return -errno; | ||||
| 	lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename); | ||||
|  | @ -1854,7 +1826,6 @@ exit: | |||
| 
 | ||||
| static int ntfs_fuse_removexattr(const char *path, const char *name) | ||||
| { | ||||
| 	ntfs_volume *vol; | ||||
| 	ntfs_inode *ni; | ||||
| 	ntfschar *lename = NULL; | ||||
| 	int res = 0, lename_len; | ||||
|  | @ -1865,10 +1836,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name) | |||
| 	if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) || | ||||
| 			strlen(name) == (size_t)nf_ns_xattr_preffix_len) | ||||
| 		return -ENODATA; | ||||
| 	vol = ctx->vol; | ||||
| 	if (!vol) | ||||
| 		return -ENODEV; | ||||
| 	ni = ntfs_pathname_to_inode(vol, NULL, path); | ||||
| 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); | ||||
| 	if (!ni) | ||||
| 		return -errno; | ||||
| 	lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename); | ||||
|  | @ -2579,7 +2547,7 @@ static void setup_logging(char *parsed_options) | |||
| 			opts.device, (ctx->ro) ? "Read-Only" : "Read-Write", | ||||
| 			ctx->vol->vol_name, ctx->vol->major_ver, | ||||
| 			ctx->vol->minor_ver); | ||||
| 	ntfs_log_info("Cmdline options: %s\n", opts.options); | ||||
| 	ntfs_log_info("Cmdline options: %s\n", opts.options ? opts.options : ""); | ||||
| 	ntfs_log_info("Mount options: %s\n", parsed_options); | ||||
| } | ||||
| 
 | ||||
|  | @ -2645,15 +2613,17 @@ int main(int argc, char *argv[]) | |||
| 	if (drop_privs()) | ||||
| 		goto err_out; | ||||
| #endif	 | ||||
| 	 | ||||
| 	if (stat(opts.device, &sbuf)) { | ||||
| 		ntfs_log_perror("Failed to access '%s'", opts.device); | ||||
| 		err = NTFS_VOLUME_NO_PRIVILEGE; | ||||
| 		goto err_out; | ||||
| 	} | ||||
| 
 | ||||
| #if !(defined(__sun) && defined (__SVR4)) | ||||
| 	/* Always use fuseblk for block devices unless it's surely missing. */ | ||||
| 	if (S_ISBLK(sbuf.st_mode) && (fstype != FSTYPE_FUSE)) | ||||
| 		ctx->blkdev = TRUE; | ||||
| #endif | ||||
| 
 | ||||
| #ifndef FUSE_INTERNAL | ||||
| 	if (getuid() && ctx->blkdev) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue