2 * utils.c - Part of the Linux-NTFS project.
4 * Copyright (c) 2002 Richard Russon
6 * A set of shared functions for ntfs utilities
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program (in the main directory of the Linux-NTFS
20 * distribution in the file COPYING); if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <sys/types.h>
42 const char *ntfs_bugs = "Please report bugs to linux-ntfs-dev@lists.sourceforge.net\n";
43 const char *ntfs_home = "Linux NTFS homepage: http://linux-ntfs.sourceforge.net\n";
44 const char *ntfs_gpl = "This program is free software, released under the GNU "
45 "General Public License\nand you are welcome to redistribute it under "
46 "certain conditions. It comes with\nABSOLUTELY NO WARRANTY; for "
47 "details read the GNU General Public License to be\nfound in the file "
48 "\"COPYING\" distributed with this program, or online at:\n"
49 "http://www.gnu.org/copyleft/gpl.html\n";
51 #define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600 * 10000000)
53 /* These utilities require the following functions */
54 extern int Eprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
55 extern int Vprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
56 extern int Qprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
61 int utils_set_locale (void)
65 locale = setlocale (LC_ALL, "");
67 locale = setlocale (LC_ALL, NULL);
68 Eprintf ("Failed to set locale, using default '%s'.\n", locale);
71 Vprintf ("Using locale '%s'.\n", locale);
77 * utils_valid_device - Perform some safety checks on the device, before we start
78 * @name: Full pathname of the device/file to work with
79 * @force: Continue regardless of problems
81 * Check that the name refers to a device and that is isn't already mounted.
82 * These checks can be overridden by using the force option.
84 * Return: 1 Success, we can continue
85 * 0 Error, we cannot use this device
87 int utils_valid_device (const char *name, int force)
89 unsigned long mnt_flags = 0;
92 if (stat (name, &st) == -1) {
93 if (errno == ENOENT) {
94 Eprintf ("The device %s doesn't exist\n", name);
96 Eprintf ("Error getting information about %s: %s\n", name, strerror (errno));
101 if (!S_ISBLK (st.st_mode)) {
102 Vprintf ("%s is not a block device.\n", name);
104 Eprintf ("Use the force option to work with files.\n");
107 Vprintf ("Forced to continue.\n");
110 /* Make sure the file system is not mounted. */
111 if (ntfs_check_if_mounted (name, &mnt_flags)) {
112 Vprintf ("Failed to determine whether %s is mounted: %s\n", name, strerror (errno));
114 Eprintf ("Use the force option to ignore this error.\n");
117 Vprintf ("Forced to continue.\n");
118 } else if (mnt_flags & NTFS_MF_MOUNTED) {
119 Vprintf ("The device %s, is mounted.\n", name);
121 Eprintf ("Use the force option to work a mounted filesystem.\n");
124 Vprintf ("Forced to continue.\n");
133 ntfs_volume * utils_mount_volume (const char *device, unsigned long flags, BOOL force)
140 if (!utils_valid_device (device, force))
143 vol = ntfs_mount (device, MS_RDONLY);
145 Eprintf ("Couldn't mount device '%s': %s\n", device, strerror (errno));
149 if (vol->flags & VOLUME_IS_DIRTY) {
150 Qprintf ("Volume is dirty.\n");
152 Eprintf ("Run chkdsk and try again, or use the --force option.\n");
153 ntfs_umount (vol, FALSE);
156 Qprintf ("Forced to continue.\n");
163 * utils_parse_size - Convert a string representing a size
164 * @value: String to be parsed
168 * Read a string and convert it to a number. Strings may be suffixed to scale
169 * them. Any number without a suffix is assumed to be in bytes.
171 * Suffix Description Multiple
172 * [tT] Terabytes 10^12
173 * [gG] Gigabytes 10^9
174 * [mM] Megabytes 10^6
175 * [kK] Kilobytes 10^3
178 * Only the first character of the suffix is read.
179 * The multipliers are decimal thousands, not binary: 1000, not 1024.
180 * If parse_size fails, @size will not be changed
183 * 0 Error, the string was malformed
185 int utils_parse_size (const char *value, s64 *size, BOOL scale)
193 Dprintf ("Parsing size '%s'.\n", value);
195 result = strtoll (value, &suffix, 10);
196 if (result < 0 || errno == ERANGE) {
197 Eprintf ("Invalid size '%s'.\n", value);
202 Eprintf ("Internal error, strtoll didn't return a suffix.\n");
208 case 't': case 'T': result *= 1000;
209 case 'g': case 'G': result *= 1000;
210 case 'm': case 'M': result *= 1000;
211 case 'k': case 'K': result *= 1000;
215 Eprintf ("Invalid size suffix '%s'. Use T, G, M, or K.\n", suffix);
219 if ((suffix[0] != '-') && (suffix[0] != 0)) {
220 Eprintf ("Invalid number '%.*s'.\n", (suffix - value + 1), value);
225 Dprintf ("Parsed size = %lld.\n", result);
231 * utils_parse_range - Convert a string representing a range of numbers
232 * @string: The string to be parsed
233 * @start: The beginning of the range will be stored here
234 * @finish: The end of the range will be stored here
236 * Read a string of the form n-m. If the lower end is missing, zero will be
237 * substituted. If the upper end is missing LONG_MAX will be used. If the
238 * string cannot be parsed correctly, @start and @finish will not be changed.
240 * Return: 1 Success, a valid string was found
241 * 0 Error, the string was not a valid range
243 int utils_parse_range (const char *string, s64 *start, s64 *finish, BOOL scale)
248 if (!string || !start || !finish)
251 middle = strchr (string, '-');
252 if (string == middle) {
253 Dprintf ("Range has no beginning, defaulting to 0.\n");
256 if (!utils_parse_size (string, &a, scale))
261 if (middle[1] == 0) {
262 b = LONG_MAX; // XXX ULLONG_MAX
263 Dprintf ("Range has no end, defaulting to %lld.\n", b);
265 if (!utils_parse_size (middle+1, &b, scale))
272 Dprintf ("Range '%s' = %lld - %lld\n", string, a, b);
280 * ntfs2utc - Convert an NTFS time to Unix time
281 * @time: An NTFS time in 100ns units since 1601
283 * NTFS stores times as the number of 100ns intervals since January 1st 1601 at
284 * 00:00 UTC. This system will not suffer from Y2K problems until ~57000AD.
286 * Return: n A Unix time (number of seconds since 1970)
288 time_t ntfs2utc (s64 time)
290 return (time - (NTFS_TIME_OFFSET)) / 10000000;
294 * utc2ntfs - convert Linux time to NTFS time
295 * @time: Linux time to convert to NTFS
297 * Convert the Linux time @time to its corresponding NTFS time.
299 * Linux stores time in a long at present and measures it as the number of
300 * 1-second intervals since 1st January 1970, 00:00:00 UTC.
302 * NTFS uses Microsoft's standard time format which is stored in a s64 and is
303 * measured as the number of 100 nano-second intervals since 1st January 1601,
306 * Return: n An NTFS time (100ns units since Jan 1601)
308 s64 utc2ntfs (time_t time)
310 /* Convert to 100ns intervals and then add the NTFS time offset. */
311 return (s64)time * 10000000 + NTFS_TIME_OFFSET;
315 * find_attribute - Find an attribute of the given type
316 * @type: An attribute type, e.g. AT_FILE_NAME
317 * @ctx: A search context, created using ntfs_get_attr_search_ctx
319 * Using the search context to keep track, find the first/next occurrence of a
320 * given attribute type.
322 * N.B. This will return a pointer into @mft. As long as the search context
323 * has been created without an inode, it won't overflow the buffer.
325 * Return: Pointer Success, an attribute was found
326 * NULL Error, no matching attributes were found
328 ATTR_RECORD * find_attribute (const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
333 if (ntfs_attr_lookup(type, NULL, 0, 0, 0, NULL, 0, ctx) != 0) {
334 Dprintf ("find_attribute didn't find an attribute of type: 0x%02x.\n", type);
335 return NULL; /* None / no more of that type */
338 Dprintf ("find_attribute found an attribute of type: 0x%02x.\n", type);
343 * find_first_attribute - Find the first attribute of a given type
344 * @type: An attribute type, e.g. AT_FILE_NAME
345 * @mft: A buffer containing a raw MFT record
347 * Search through a raw MFT record for an attribute of a given type.
348 * The return value is a pointer into the MFT record that was supplied.
350 * N.B. This will return a pointer into @mft. The pointer won't stray outside
351 * the buffer, since we created the search context without an inode.
353 * Return: Pointer Success, an attribute was found
354 * NULL Error, no matching attributes were found
356 ATTR_RECORD * find_first_attribute (const ATTR_TYPES type, MFT_RECORD *mft)
358 ntfs_attr_search_ctx *ctx;
364 ctx = ntfs_attr_get_search_ctx (NULL, mft);
366 Eprintf ("Couldn't create a search context.\n");
370 rec = find_attribute (type, ctx);
371 ntfs_attr_put_search_ctx (ctx);
373 Dprintf ("find_first_attribute: found attr of type 0x%02x.\n", type);
375 Dprintf ("find_first_attribute: didn't find attr of type 0x%02x.\n", type);
380 * utils_inode_get_name
386 * if parent is 5 (/) stop
387 * get inode of parent
389 int utils_inode_get_name (ntfs_inode *inode, char *buffer, int bufsize)
391 // XXX option: names = posix/win32 or dos
392 // flags: path, filename, or both
393 const int max_path = 20;
396 ntfs_attr_search_ctx *ctx;
398 FILE_NAME_ATTR *attr;
400 MFT_REF parent = FILE_root;
401 char *names[max_path + 1];// XXX malloc? and make max bigger?
402 int i, len, offset = 0;
404 if (!inode || !buffer)
409 //printf ("sizeof (char*) = %d, sizeof (names) = %d\n", sizeof (char*), sizeof (names));
410 memset (names, 0, sizeof (names));
412 for (i = 0; i < max_path; i++) {
414 ctx = ntfs_attr_get_search_ctx (inode, NULL);
416 Eprintf ("Couldn't create a search context.\n");
420 //printf ("i = %d, inode = %p (%lld)\n", i, inode, inode->mft_no);
423 while ((rec = find_attribute (AT_FILE_NAME, ctx))) {
424 /* We know this will always be resident. */
425 attr = (FILE_NAME_ATTR *) ((char *) rec + le16_to_cpu (rec->value_offset));
427 if (attr->file_name_type >= name_space) { //XXX find the ...
431 name_space = attr->file_name_type;
432 parent = le64_to_cpu (attr->parent_directory);
439 if (ntfs_ucstombs (attr->file_name, attr->file_name_length,
440 &names[i], attr->file_name_length) < 0) {
442 Eprintf ("Couldn't translate filename to current locale.\n");
446 snprintf (temp, 30, "<MFT%lld>", inode->mft_no);
450 //printf ("names[%d] %s\n", i, names[i]);
451 //printf ("parent = %lld\n", MREF (parent));
454 ntfs_attr_put_search_ctx(ctx);
456 if (i > 0) /* Don't close the original inode */
457 ntfs_inode_close (inode);
459 if (MREF (parent) == FILE_root) { /* The root directory, stop. */
460 //printf ("inode 5\n");
464 inode = ntfs_inode_open (vol, parent);
466 Eprintf ("Couldn't open inode %lld.\n", MREF (parent));
472 /* If we get into an infinite loop, we'll end up here. */
473 Eprintf ("The directory structure is too deep (over %d) nested directories.\n", max_path);
477 /* Assemble the names in the correct order. */
478 for (i = max_path; i >= 0; i--) {
482 len = snprintf (buffer + offset, bufsize - offset, "%c%s", PATH_SEP, names[i]);
483 if (len >= (bufsize - offset)) {
484 Eprintf ("Pathname was truncated.\n");
491 /* Free all the allocated memory */
492 for (i = 0; i < max_path; i++)
495 Dprintf ("Pathname: %s\n", buffer);
501 * utils_attr_get_name
503 int utils_attr_get_name (ntfs_volume *vol, ATTR_RECORD *attr, char *buffer, int bufsize)
505 int len, namelen, offset = 0;
509 // flags: attr, name, or both
510 if (!attr || !buffer)
513 attrdef = ntfs_attr_find_in_attrdef (vol, attr->type);
515 namelen = ntfs_ucsnlen (attrdef->name, sizeof (attrdef->name));
516 if (ntfs_ucstombs (attrdef->name, namelen, &name, namelen) < 0) {
517 Eprintf ("Couldn't translate attribute type to current locale.\n");
521 len = snprintf (buffer, bufsize, "%s", name);
523 Eprintf ("Unknown attribute type 0x%02x\n", attr->type);
524 len = snprintf (buffer, bufsize, "<UNKNOWN>");
527 if (len >= bufsize) {
528 Eprintf ("Attribute type was truncated.\n");
534 if (!attr->name_length) {
538 namelen = attr->name_length;
539 if (ntfs_ucstombs ((uchar_t *)((char *)attr + attr->name_offset),
540 namelen, &name, namelen) < 0) {
541 Eprintf ("Couldn't translate attribute name to current locale.\n");
546 len = snprintf (buffer + offset, bufsize - offset, "(%s)", name);
549 if ((len + offset) >= bufsize) {
550 Eprintf ("Attribute name was truncated.\n");
558 * utils_cluster_in_use - Determine if a cluster is in use
559 * @vol: An ntfs volume obtained from ntfs_mount
560 * @lcn: The Logical Cluster Number to test
562 * The metadata file $Bitmap has one binary bit representing each cluster on
563 * disk. The bit will be set for each cluster that is in use. The function
564 * reads the relevant part of $Bitmap into a buffer and tests the bit.
566 * This function has a static buffer in which it caches a section of $Bitmap.
567 * If the lcn, being tested, lies outside the range, the buffer will be
570 * Return: 1 Cluster is in use
571 * 0 Cluster is free space
574 int utils_cluster_in_use (ntfs_volume *vol, long long lcn)
576 static unsigned char buffer[512];
577 static long long bmplcn = -sizeof (buffer) - 1; /* Which bit of $Bitmap is in the buffer */
585 /* Does lcn lie in the section of $Bitmap we already have cached? */
586 if ((lcn < bmplcn) || (lcn >= (bmplcn + (sizeof (buffer) << 3)))) {
587 Dprintf ("Bit lies outside cache.\n");
588 attr = ntfs_attr_open (vol->lcnbmp_ni, AT_DATA, NULL, 0);
590 Eprintf ("Couldn't open $Bitmap: %s\n", strerror (errno));
594 /* Mark the buffer as in use, in case the read is shorter. */
595 memset (buffer, 0xFF, sizeof (buffer));
596 bmplcn = lcn & (~((sizeof (buffer) << 3) - 1));
598 if (ntfs_attr_pread (attr, (bmplcn>>3), sizeof (buffer), buffer) < 0) {
599 Eprintf ("Couldn't read $Bitmap: %s\n", strerror (errno));
600 ntfs_attr_close (attr);
604 Dprintf ("Reloaded bitmap buffer.\n");
605 ntfs_attr_close (attr);
608 bit = 1 << (lcn & 7);
609 byte = (lcn >> 3) & (sizeof (buffer) - 1);
610 Dprintf ("cluster = %lld, bmplcn = %lld, byte = %d, bit = %d, in use %d\n",
611 lcn, bmplcn, byte, bit, buffer[byte] & bit);
613 return (buffer[byte] & bit);
617 * utils_mftrec_in_use - Determine if a MFT Record is in use
618 * @vol: An ntfs volume obtained from ntfs_mount
619 * @mref: MFT Reference (inode number)
621 * The metadata file $BITMAP has one binary bit representing each record in the
622 * MFT. The bit will be set for each record that is in use. The function
623 * reads the relevant part of $BITMAP into a buffer and tests the bit.
625 * This function has a static buffer in which it caches a section of $BITMAP.
626 * If the mref, being tested, lies outside the range, the buffer will be
629 * Return: 1 MFT Record is in use
630 * 0 MFT Record is unused
633 int utils_mftrec_in_use (ntfs_volume *vol, MFT_REF mref)
635 static u8 buffer[512];
636 static s64 bmpmref = -sizeof (buffer) - 1; /* Which bit of $BITMAP is in the buffer */
643 /* Does mref lie in the section of $Bitmap we already have cached? */
644 if ((mref < bmpmref) || (mref >= (bmpmref + (sizeof (buffer) << 3)))) {
645 Dprintf ("Bit lies outside cache.\n");
647 /* Mark the buffer as not in use, in case the read is shorter. */
648 memset (buffer, 0, sizeof (buffer));
649 bmpmref = mref & (~((sizeof (buffer) << 3) - 1));
651 if (ntfs_attr_pread (vol->mftbmp_na, (bmpmref>>3), sizeof (buffer), buffer) < 0) {
652 Eprintf ("Couldn't read $MFT/$BITMAP: %s\n", strerror (errno));
656 Dprintf ("Reloaded bitmap buffer.\n");
659 bit = 1 << (mref & 7);
660 byte = (mref >> 3) & (sizeof (buffer) - 1);
661 Dprintf ("cluster = %lld, bmpmref = %lld, byte = %d, bit = %d, in use %d\n",
662 mref, bmpmref, byte, bit, buffer[byte] & bit);
664 return (buffer[byte] & bit);
670 inline unsigned int hweight32(unsigned int w)
672 unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
673 res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
674 res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
675 res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
676 return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
679 inline unsigned int hweight16(unsigned int w)
681 unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
682 res = (res & 0x3333) + ((res >> 2) & 0x3333);
683 res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
684 return (res & 0x00FF) + ((res >> 8) & 0x00FF);
687 inline unsigned int hweight8(unsigned int w)
689 unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
690 res = (res & 0x33) + ((res >> 2) & 0x33);
691 return (res & 0x0F) + ((res >> 4) & 0x0F);
694 inline int set_bit(int nr,long * addr)
699 mask = 1 << (nr & 0x1f);
700 retval = (mask & *addr) != 0;
705 inline int clear_bit(int nr, long * addr)
710 mask = 1 << (nr & 0x1f);
711 retval = (mask & *addr) != 0;
716 inline int test_bit(int nr, long * addr)
721 mask = 1 << (nr & 0x1f);
722 return ((mask & *addr) != 0);