Exemplo n.º 1
0
/* per http://www.scit.wlv.ac.uk/cgi-bin/mansec?3C+dirname */
char* dirname(char* path)
{
  char* p;

  if (path == NULL || *path == '\0')
    return ".";
  p = path + strlen(path) - 1;
  while (IS_PATH_SEPARATOR(*p)) {
    if (p == path)
      return path;
    *p-- = '\0';
  }

  while (p >= path && !IS_PATH_SEPARATOR(*p))
    p--;

  if (p < path)
    return ".";

  if (p == path)
    return "/";

  *p = '\0';

  return path;
}
Exemplo n.º 2
0
/**
 * Callback function to process a file found while recursively traversing
 * a directory.
 *
 * @param filepath path to the file
 * @param type file attributes
 * @param data the paramater specified, when calling find_file(). It shall be
 *             non-zero for printing SFV header, zero for actual processing.
 */
static int find_file_callback(const char* filepath, int type, void* data)
{
	int res = 0;
	if( !(type & FIND_IFDIR) ) {
		if(data) {
			if(!file_mask_match(opt.files_accept, filepath)) return 0;
			if(filepath[0] == '.' && IS_PATH_SEPARATOR(filepath[1])) filepath += 2;
			/* TODO: get size, fill file struct */
			print_sfv_header_line(rhash_data.out, filepath, filepath);
			/* rhash_data.total_size += file.size */
		} else {
			/* only check an update modes use crc_accept mask */
			file_mask_array* masks = (opt.mode & (MODE_CHECK | MODE_UPDATE) ?
				opt.crc_accept : opt.files_accept);
			if(!file_mask_match(masks, filepath)) return 0;

			if(opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) {
				res = check_hash_file(filepath, 1);
			} else {
				if(opt.mode & MODE_UPDATE) {
					res = update_hash_file(filepath);
				} else {
					/* default mode: calculate hash */
					if(filepath[0] == '.' && IS_PATH_SEPARATOR(filepath[1])) filepath += 2;
					res = calculate_and_print_sums(rhash_data.out, filepath, filepath, NULL);
					rhash_data.processed++;
				}
			}
		}
	}
	if(res < 0) rhash_data.error_flag = 1;
	return 1;
}
Exemplo n.º 3
0
/**
 * Assemble a filepath from its directory and filename.
 *
 * @param dir_path directory path
 * @param filename file name
 * @return filepath
 */
char* make_path(const char* dir_path, const char* filename)
{
	char* buf;
	size_t len;
	assert(dir_path);
	assert(filename);

	/* remove leading path separators from filename */
	while (IS_PATH_SEPARATOR(*filename)) filename++;

	if (dir_path[0] == '.' && dir_path[1] == 0) {
		/* do not extend filename for dir_path="." */
		return rsh_strdup(filename);
	}

	/* copy directory path */
	len = strlen(dir_path);
	buf = (char*)rsh_malloc(len + strlen(filename) + 2);
	strcpy(buf, dir_path);

	/* separate directory from filename */
	if (len > 0 && !IS_PATH_SEPARATOR(buf[len-1])) {
		buf[len++] = SYS_PATH_SEPARATOR;
	}

	/* append filename */
	strcpy(buf+len, filename);
	return buf;
}
Exemplo n.º 4
0
static char *fi_dirname(char *path)
{
    char *p;

    if(path == NULL || *path == '\0')
        return fi_path_dot;

    p = path + strlen(path) - 1;
    while(IS_PATH_SEPARATOR(*p))
    {
        if(p == path)
            return path;
        *p-- = '\0';
    }

    while(p >= path && !IS_PATH_SEPARATOR(*p))
        p--;

    if(p < path)
        return fi_path_dot;

    if(p == path)
        return fi_path_root;

    *p = '\0';
    return path;
}
Exemplo n.º 5
0
/**
 * Expand wildcards in the given filepath and store results into vector.
 * If no wildcards are found then just the filepath is stored.
 * Note: only wildcards in the last filename of the path are expanded.
 *
 * @param vect the vector to receive wide-strings with file paths
 * @param filepath the filepath to process
 */
void expand_wildcards(vector_t* vect, wchar_t* filepath)
{
	int added = 0;
	size_t len = wcslen(filepath);
	size_t index = wcscspn(filepath, L"*?");

	/* if a wildcard has been found without a directory separator after it */
	if(index < len && wcscspn(filepath + index, L"/\\") >= (len - index))
	{
		wchar_t* parent;
		WIN32_FIND_DATAW d;
		HANDLE h;

		/* find directory separator */
		for(; index > 0 && !IS_PATH_SEPARATOR(filepath[index]); index--);
		parent = (IS_PATH_SEPARATOR(filepath[index]) ? filepath : 0);

		h = FindFirstFileW(filepath, &d);
		if(INVALID_HANDLE_VALUE != h) {
			do {
				wchar_t* wpath;
				char* cstr;
				int failed;
				if((0 == wcscmp(d.cFileName, L".")) || (0 == wcscmp(d.cFileName, L".."))) continue;
				if(NULL == (wpath = make_pathw(parent, index + 1, d.cFileName))) continue;
				cstr = wchar_to_cstr(wpath, WIN_DEFAULT_ENCODING, &failed);
				/* note: just quietly skip unconvertible file names */
				if(!cstr || failed) {
					free(cstr);
					free(wpath);
					continue;
				}
				rsh_vector_add_ptr(vect, cstr);
				added++;
			} while(FindNextFileW(h, &d));
			FindClose(h);
		}
	}

	if(added == 0) {
		wchar_t* wpath = make_pathw(0, 0, filepath);
		char* cstr = w2c(wpath);
		if(cstr) rsh_vector_add_ptr(vect, cstr);
	}
}
Exemplo n.º 6
0
uint32_t inode_get_idx_by_path(const char *path)
{
    struct inode_dir_ctx *dctx = inode_dir_ctx_get();
    uint32_t inode_idx = 0;
    struct ext4_inode inode;

    /* Paths from fuse are always absolute */
    assert(IS_PATH_SEPARATOR(path[0]));

    DEBUG("Looking up: %s", path);

    struct dcache_entry *dc_entry = get_cached_inode_num(&path);
    inode_idx = dcache_get_inode(dc_entry);

    DEBUG("Looking up after dcache: %s", path);

    do {
        uint32_t offset = 0;
        struct ext4_dir_entry_2 *dentry = NULL;

        path = skip_trailing_backslash(path);
        uint8_t path_len = get_path_token_len(path);

        if (path_len == 0) break;
        inode_get_by_number(inode_idx, &inode);

        inode_dir_ctx_reset(dctx, &inode);
        while ((dentry = inode_dentry_get(&inode, offset, dctx))) {
            offset += dentry->rec_len;

            if (!dentry->inode) continue;
            if (path_len != dentry->name_len) continue;
            if (memcmp(path, dentry->name, dentry->name_len)) continue;

            inode_idx = dentry->inode;
            DEBUG("Lookup following inode %d", inode_idx);

            if (S_ISDIR(inode.i_mode)) {
                dc_entry = dcache_insert(dc_entry, path, path_len, inode_idx);
            }
            break;
        }

        /* Couldn't find the entry at all */
        if (dentry == NULL) {
            break;
        }
    } while((path = strchr(path, '/')));

    inode_dir_ctx_put(dctx);
    return inode_idx;
}
Exemplo n.º 7
0
void CurrentTemplatePath(const char *pszPath, char *pszDest)
{
    int n = strlen(pszPath) - 1;

    while (n >= 0) {
        if (IS_PATH_SEPARATOR(*(pszPath + n))) {
            memcpy(pszDest, pszPath, n);
            pszDest[n] = 0;
            break;
        }
        n--;
    }
}
Exemplo n.º 8
0
/**
 * Return allocated buffer with the directory part of the path.
 * The buffer must be freed by calling free().
 *
 * @param path file path
 * @return directory
 */
char* get_dirname(const char* path)
{
	const char *p = path + strlen(path) - 1;
	char *res;
	for (; p > path && !IS_PATH_SEPARATOR(*p); p--);
	if ((p - path) > 1) {
		res = (char*)rsh_malloc(p-path+1);
		memcpy(res, path, p-path);
		res[p-path] = 0;
		return res;
	} else {
		return rsh_strdup(".");
	}
}
Exemplo n.º 9
0
/**
 * Assemble a filepath from its directory and filename.
 *
 * @param dir_path directory path
 * @param filename file name
 * @return filepath
 */
char* make_path(const char* dir_path, const char* filename)
{
	char* buf;
	size_t len;
	assert(dir_path);
	assert(filename);

	/* remove leading path separators from filename */
	while(IS_PATH_SEPARATOR(*filename)) filename++;

	/* copy directory path */
	len = strlen(dir_path);
	buf = (char*)rsh_malloc(len + strlen(filename) + 2);
	strcpy(buf, dir_path);

	/* separate directory from filename */
	if(len > 0 && !IS_PATH_SEPARATOR(buf[len-1]))
		buf[len++] = SYS_PATH_SEPARATOR;

	/* append filename */
	strcpy(buf+len, filename);
	return buf;
}
Exemplo n.º 10
0
/**
 * Callback function to process files while recursively traversing a directory.
 * It hashes, checks or updates a file according to the current work mode.
 *
 * @param file the file to process
 * @param preprocess non-zero when preprocessing files, zero for actual processing.
 */
static int find_file_callback(file_t* file, int preprocess)
{
	int res = 0;
	assert(!FILE_ISDIR(file));
	assert(opt.search_data);

	if (rhash_data.interrupted) {
		opt.search_data->options |= FIND_CANCEL;
		return 0;
	}

	if (preprocess) {
		if (!file_mask_match(opt.files_accept, file->path) || must_skip_file(file)) {
			return 0;
		}

		if (opt.fmt & FMT_SFV) {
			print_sfv_header_line(rhash_data.out, file, 0);
		}

		rhash_data.batch_size += file->size;
	} else {
		int not_root = !(file->mode & FILE_IFROOT);

		if (not_root) {
			/* only check and update modes use the crc_accept mask */
			file_mask_array* masks = (opt.mode & (MODE_CHECK | MODE_UPDATE) ?
				opt.crc_accept : opt.files_accept);
			if (!file_mask_match(masks, file->path)) return 0;
		}
		if (must_skip_file(file)) return 0;

		if (opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) {
			res = check_hash_file(file, not_root);
		} else {
			if (opt.mode & MODE_UPDATE) {
				res = update_hash_file(file);
			} else {
				/* default mode: calculate hash */
				const char* print_path = file->path;
				if (print_path[0] == '.' && IS_PATH_SEPARATOR(print_path[1])) print_path += 2;
				res = calculate_and_print_sums(rhash_data.out, file, print_path);
				if (rhash_data.interrupted) return 0;
				rhash_data.processed++;
			}
		}
	}
	if (res < 0) rhash_data.error_flag = 1;
	return 1;
}
Exemplo n.º 11
0
/* per http://www.scit.wlv.ac.uk/cgi-bin/mansec?3C+basename */
char* basename(char* s) {
	char* rv;

	if (!s || !*s)
		return ".";

	rv = s + strlen(s) - 1;

	do {
		if (IS_PATH_SEPARATOR(*rv))
			return rv + 1;
		--rv;
	} while (rv >= s);

	return s;
}
Exemplo n.º 12
0
/**
 * Search for a crc32 hash sum in the given file name.
 *
 * @param filepath the path to the file.
 * @param crc32 pointer to integer to receive parsed hash sum.
 * @return non zero if crc32 was found, zero otherwise.
 */
static int find_embedded_crc32(const char* filepath, unsigned* crc32_be)
{
	const char* e = filepath + strlen(filepath) - 10;

	/* search for the sum enclosed in brackets */
	for(; e >= filepath && !IS_PATH_SEPARATOR(*e); e--) {
		if((*e == '[' && e[9] == ']') || (*e == '(' && e[9] == ')')) {
			const char *p = e + 8;
			for(; p > e && IS_HEX(*p); p--);
			if(p == e) {
				rhash_hex_to_byte(e + 1, (char unsigned*)crc32_be, 8);
				return 1;
			}
			e -= 9;
		}
	}
	return 0;
}
Exemplo n.º 13
0
static char *fi_basename(char *s)
{
    char *rv;

    if(!s || !*s)
        return fi_path_dot;

    rv = s + strlen(s) - 1;

    do
    {
        if(IS_PATH_SEPARATOR(*rv))
            return rv + 1;
        --rv;
    }
    while(rv >= s);

    return s;
}
Exemplo n.º 14
0
/**
 * Print a file info line in SFV header format.
 *
 * @param out a stream to print info to
 * @param file the file info to print
 * @return 0 on success, -1 on fail with error code stored in errno
 */
int print_sfv_header_line(FILE* out, file_t* file, const char* printpath)
{
	char buf[24];

	if(!printpath) printpath = file->path;
	if(printpath[0] == '.' && IS_PATH_SEPARATOR(printpath[1])) printpath += 2;

#ifdef _WIN32
	/* skip file if it can't be opened with exclusive sharing rights */
	if(!can_open_exclusive(file->path)) {
		return 0;
	}
#endif

	sprintI64(buf, file->size, 12);
	fprintf(out, "; %s  ", buf);
	print_time64(out, file->mtime);
	fprintf(out, " %s\n", printpath);
	return 0;
}
Exemplo n.º 15
0
PVOID LibraryArg(PLUBECTX pCtx, MemberType member)
{
    char *p;

    p = pCtx->m_pLibrary + strlen(pCtx->m_pLibrary);
    while (p != pCtx->m_pLibrary && !IS_PATH_SEPARATOR(*(p - 1)))
        p--;

    switch (member) {
        case Member_None:
            return (PVOID)pCtx->m_pLibrary;
        case Member_Name:
            return p;
        case Member_Type:
            p = pCtx->m_pLibrary;
            while (0 != *p) {
                if ('.' == *p) return (PVOID)(p + 1);
                p++;
            }
        default:
            return NULL;
    }
}
Exemplo n.º 16
0
NET_API_STATUS
NetpIsRemote(
    IN  LPTSTR  ComputerName OPTIONAL,
    OUT LPDWORD LocalOrRemote,
    OUT LPTSTR  CanonicalizedName OPTIONAL,
    IN  DWORD   Flags
    )

/*++

Routine Description:

    Determines whether a computer name designates this machine or a renote
    one. Values of ComputerName which equate to the local machine are:

        NULL pointer to name
        pointer to NULL name
        pointer to non-NULL name which is lexically equivalent to this
        machine's name

    NB. This routine expects that the canonicalized version of ComputerName
        will fit into the buffer pointed at by CanonicalizedName. Since this
        is an INTERNAL function, this assumption is deemed valid

Arguments:

    IN  LPTSTR  ComputerName OPTIONAL
                    Pointer to computer name to check. May assume any of
                    the above forms
                    If a non-NULL string is passed in, then it may have
                    preceeding back-slashes. This is kind of expected since
                    this routine is called by remotable APIs and it is they
                    who specify that the form a computer name is \\<name>

    OUT LPDWORD LocalOrRemote
                    Points to the DWORD where the specifier for the
                    symbolic location will be returned. MUST NOT BE NULL. On
                    return will be one of:
                        ISLOCAL     The name defined by ComputerName specifies
                                    the local machine specifically or by default
                                    (ie. was NULL)
                        ISREMOTE    The name defined by ComputerName was non-NULL
                                    and was not the name of this machine

    OUT LPTSTR  CanonicalizedName OPTIONAL
                    Pointer to caller's buffer into which a copy of the
                    canonicalized name will be placed if requested. This
                    can then be used in subsequent calls, with the knowledge
                    that no further checking of the computer name is required.
                    Note that the format of this buffer will be \\<computername>
                    on return. The contents of this buffer will not be
                    modified unless this routine returns success

    IN  DWORD   Flags
                    A bitmap. Flags are:

                        NIRFLAG_MAPLOCAL    if set, will map (ie canonicalize)
                                            the NULL local name to this
                                            computer's name proper. Used in
                                            conjunction with CanonicalizedName
                                            This stops extraneous calls to
                                            NetpNameCanonicalize with the
                                            inherited CanonicalizedName
                                            parameter. See below for elucidation

Return Value:

    NET_API_STATUS
        Success = NERR_Success
        Failure = return code from:
                    NetpNameCanonicalize
                    NetWkstaGetInfo
                    NetpNameCompare
--*/

{
    LPBYTE  wksta_buffer_pointer;
    BOOL    map_local_name = FALSE;
    LONG    result;
    NET_API_STATUS  rc;

    //
    // BUGBUG
    // Computer names are defined as being 15 bytes which may mean 7 UNICODE
    // characters. Do we have to perform any UNICODE-ASCII mapping here?
    //

    TCHAR   name[MAX_PATH];     // canonicalized version of ComputerName
    LPTSTR  wksta_name_uncanon; // our computer name (from NetWkstaGetInfo)
    TCHAR   wksta_name_canon[MAX_PATH]; // our computer name (from canon)
    LPTSTR  canonicalized_name; // as returned to caller


    //
    // Assert that we have a valid pointer in LocalOrRemote
    //

    //
    // Once again, shouldn't have to do this, since this routine is internal
    // and there is no interpretation about inputs. However, lets catch any
    // possible problems...
    //

    NetpAssert(ARGUMENT_PRESENT(LocalOrRemote));

#ifdef CANONDBG
    DbgPrint("NetpIsRemote(%s, %x, %x, %x)\n",
        ComputerName,
        LocalOrRemote,
        CanonicalizedName,
        Flags
        );
#endif

    //
    // NB. It is important to check this case first, before we call any Netp
    // routines since these could call back to this routine and we may get
    // stuck in an infinite loop
    //

    if (!ARGUMENT_PRESENT(ComputerName) || (*ComputerName == TCHAR_EOS)) {

        //
        // in this case its probably an internal call from one of our routines
        // and we want to return as quickly as possible. This will be borne out
        // by the NIRFLAG_MAPLOCAL flag being reset in the Flags parameter
        //

        //
        // A note about NIRFLAG_MAPLOCAL
        // This routine makes local calls to NetpNameValidate and
        // NetpNameCompare. If the NIRFLAG_MAPLOCAL flag is not reset then
        // these routines in turn will cause the local name to be returned
        // (because they always pass in non-NULL CanonicalizedName parameter)
        // which in most cases is inefficient, since the name won't be used
        // so we always say (in the Netp routines) that we don't want local
        // name canonicalization
        // Therefore, if (local) name canonicalization is implied by non-NULL
        // CanonicalizedName, verify this by checking Flags.NIRFLAG_MAPLOCAL
        // If it, too, is set then local name canonicalization is performed
        //

        if (!ARGUMENT_PRESENT(CanonicalizedName) || !(Flags & NIRFLAG_MAPLOCAL)) {
            *LocalOrRemote = ISLOCAL;
#ifdef CANONDBG
            DbgPrint("NetpIsRemote(%s) - returning early\n", ComputerName);
#endif
            return NERR_Success;
        } else {

            //
            // signify that the input name was NULL or NUL string but that the
            // caller wants a canonicalized name returned (from NetWkstaGetInfo)
            //

            map_local_name = TRUE;
        }
    } else {

        //
        // if the computername starts with \\ or // or any combination thereof,
        // skip the path separators - the canonicalization routines expect
        // computer names NOT to have these (pretty stupid, eh?)
        //

        if (IS_PATH_SEPARATOR(ComputerName[0]) && IS_PATH_SEPARATOR(ComputerName[1])) {
            ComputerName += 2;
        }

        //
        // here's a use for canonicalization (!): ensure that we have been passed
        // a real and proper computer name and not some pale imitation
        //

        rc = NetpNameCanonicalize(
                NULL,                   // performed here, on our own premises
                ComputerName,           // this is input
                name,                   // this is output
                sizeof(name),           // how much buffer we have
                NAMETYPE_COMPUTER,      // what we think it is
                INNCA_FLAGS_FULL_BUFLEN // say that o/p buffer must be large
                                        // enough for maximum-sized computer
                                        // name. Why? you ask, well its a fair
                                        // cop - the reason is that we can't
                                        // get into trouble on the one time that
                                        // we exercise the maximum requirement
                );
        if (rc) {
            return rc;  // duff name (?)
        } else {
            canonicalized_name = name;
        }
    }

    //
    // get the name of this machine from the redirector. If we can't get the
    // name for whatever reason, return the error code.
    //

    if (rc = NetWkstaGetInfo(NULL, 102, &wksta_buffer_pointer)) {
#ifdef CANONDBG
        DbgPrint("error: NetWkstaGetInfo returns %lu\n", rc);
#endif
        return rc;  // didn't work
    }

    wksta_name_uncanon =
            ((LPWKSTA_INFO_102)wksta_buffer_pointer)->wki102_computername;

#ifdef CANONDBG
    DbgPrint("NetWkstaGetInfo returns level 102 computer name (uncanon)= %s\n",
            wksta_name_uncanon);
#endif
    rc = NetpNameCanonicalize(
            NULL,                       // performed here, on our own premises
            wksta_name_uncanon,         // this is input
            wksta_name_canon,           // this is output
            sizeof(wksta_name_canon),   // how much buffer we have
            NAMETYPE_COMPUTER,          // what we think it is
            INNCA_FLAGS_FULL_BUFLEN     // say that o/p buffer must be large
                                        // enough for maximum-sized computer
                                        // name. Why? you ask, well its a fair
                                        // cop - the reason is that we can't
                                        // get into trouble on the one time that
                                        // we exercise the maximum requirement
            );
    NetpAssert( rc == NERR_Success );

    //
    // compare our name and the name passed to us. NetpNameCompare returns
    // 0 if the names match else 1 or -1 (a la strcmp)
    //

    //
    // if the caller gave us a NULL computer name but wants a canonicalized
    // name output then get a pointer to the canonicalized name from
    // NetWkstaGetInfo
    //

    if (map_local_name) {
        canonicalized_name = wksta_name_canon;
    } else {

        //
        // otherwise, we have a non-NULL computername to compare with this
        // computer's name
        //

        result = NetpNameCompare(
                    NULL,   // performed here, on our own premises
                    name,   // canonicalized version of passed name
                    wksta_name_canon,  // name of our computer
                    NAMETYPE_COMPUTER,
                    INNC_FLAGS_NAMES_CANONICALIZED
                    );
    }

    //
    // if the specified name equates to our computer name then its still local
    //

    *LocalOrRemote = (DWORD)((result == 0) ? ISLOCAL : ISREMOTE);

    //
    // if the caller specified that the canonicalized name be returned, then
    // give it to 'em. Note that the returned name is prefixed with \\ - it
    // is assumed the name is then used in a call to eg NetRemoteComputerSupports
    //

    if (ARGUMENT_PRESENT(CanonicalizedName)) {
        STRCPY(CanonicalizedName, TEXT("\\\\"));
        STRCAT(CanonicalizedName, canonicalized_name);
    }

    //
    // free the buffer created by NetWkstaGetInfo
    //

    NetApiBufferFree(wksta_buffer_pointer);

    return NERR_Success;
}
Exemplo n.º 17
0
static const char *skip_trailing_backslash(const char *path)
{
    while (IS_PATH_SEPARATOR(*path)) path++;
    return path;
}
Exemplo n.º 18
0
/**
 * Return filename without path.
 *
 * @param path file path
 * @return filename
 */
const char* get_basename(const char* path)
{
	const char *p = path + strlen(path) - 1;
	for (; p >= path && !IS_PATH_SEPARATOR(*p); p--);
	return (p+1);
}
Exemplo n.º 19
0
/**
 * Rename given file inserting its crc32 sum enclosed into square braces
 * and placing it right before the file extension.
 *
 * @param info pointer to the data of the file to rename.
 * @return 0 on success, -1 on fail with error code in errno
 */
int rename_file_by_embeding_crc32(struct file_info *info)
{
	size_t len = strlen(info->full_path);
	const char* p = info->full_path + len;
	const char* c = p - 1;
	char* new_path;
	char* insertion_point;
	unsigned crc32_be;
	assert((info->rctx->hash_id & RHASH_CRC32) != 0);

	/* check if the filename contains a CRC32 hash sum */
	if(find_embedded_crc32(info->print_path, &crc32_be)) {
		unsigned char* c =
			(unsigned char*)rhash_get_context_ptr(info->rctx, RHASH_CRC32);
		unsigned actual_crc32 = ((unsigned)c[0] << 24) |
			((unsigned)c[1] << 16) | ((unsigned)c[2] << 8) | (unsigned)c[3];

		/* compare with calculated CRC32 */
		if(crc32_be != actual_crc32) {
			char crc32_str[9];
			rhash_print(crc32_str, info->rctx, RHASH_CRC32, RHPR_UPPERCASE);
			/* TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv */
			log_warning(_("wrong embedded CRC32, should be %s\n"), crc32_str);
		} else return 0;
	}

	/* find file extension (as the place to insert the hash sum) */
	for(; c >= info->full_path && !IS_PATH_SEPARATOR(*c); c--) {
		if(*c == '.') {
			p = c;
			break;
		}
	}

	/* now p is the point to insert delimiter + hash string in brackets */
	new_path = (char*)rsh_malloc(len + 12);
	insertion_point = new_path + (p - info->full_path);
	memcpy(new_path, info->full_path, p - info->full_path);
	if(opt.embed_crc_delimiter && *opt.embed_crc_delimiter) *(insertion_point++) = *opt.embed_crc_delimiter;
	rhash_print(insertion_point+1, info->rctx, RHASH_CRC32, RHPR_UPPERCASE);
	insertion_point[0] = '[';
	insertion_point[9] = ']'; /* ']' overrides '\0' inserted by rhash_print_sum() */
	strcpy(insertion_point + 10, p); /* append file extension */

	/* rename the file */
	if(rename(info->full_path, new_path) < 0) {
		log_error(_("can't move %s to %s: %s\n"), info->full_path, new_path,
			strerror(errno));
		free(new_path);
		return -1;
	}

	/* change file name in the file info structure */
	if(info->print_path >= info->full_path && info->print_path < p) {
		file_info_set_print_path(info, new_path + len - strlen(info->print_path));
	} else {
		file_info_set_print_path(info, new_path);
	}

	free(info->full_path);
	info->full_path = new_path;
	return 0;
}
Exemplo n.º 20
0
char *csExpandName (const char *iName)
{
  char outname [CS_MAXPATHLEN + 1];
  int inp = 0, outp = 0, namelen = strlen (iName);
  while ((outp < CS_MAXPATHLEN)
      && (inp < namelen))
  {
    char tmp [CS_MAXPATHLEN + 1];
    int ptmp = 0;
    while ((inp < namelen) && (!IS_PATH_SEPARATOR(iName[inp]) ))
      tmp [ptmp++] = iName [inp++];
    tmp [ptmp] = 0;

    if ((ptmp > 0)
     && (outp == 0)
#if defined (CS_PLATFORM_DOS) || defined (CS_PLATFORM_WIN32)
     && ((inp >= namelen)
      || (iName [inp] != ':'))
#endif
        )
    {
      if (getcwd (outname, sizeof (outname)) == 0)
      {
        csPrintfErr ("csExpandName(): getcwd() error for %s (errno = %d)!\n",
          outname, errno);
        return 0;
      }
      outp = strlen (outname);
      if (strcmp (tmp, "."))
        outname [outp++] = CS_PATH_SEPARATOR;
    } /* endif */

#if defined (CS_PLATFORM_DOS) || defined (CS_PLATFORM_WIN32)
    // If path starts with '/' (root), get current drive
    if ((ptmp == 0)
     && (outp == 0))
    {
      getcwd (outname, sizeof (outname));
      if (outname [1] == ':')
        outp = 2;
    } /* endif */
#endif

    if (strcmp (tmp, "..") == 0)
    {
      while ((outp > 0)
          && ((outname [outp - 1] == '/')
           || (outname [outp - 1] == CS_PATH_SEPARATOR)
#if defined (CS_PLATFORM_DOS) || defined (CS_PLATFORM_WIN32)
           || (outname [outp - 1] == ':')
#endif
             )
            )
        outp--;
      while ((outp > 0)
          && (outname [outp - 1] != '/')
          && (outname [outp - 1] != CS_PATH_SEPARATOR)
#if defined (CS_PLATFORM_DOS) || defined (CS_PLATFORM_WIN32)
          && (outname [outp - 1] != ':')
#endif
            )
        outp--;
    }
    else if (strcmp (tmp, ".") == 0)
    {
      // do nothing
    }
    else if (strcmp (tmp, "~") == 0)
    {
      // strip all output path; start from scratch
      strcpy (outname, "~/");
      outp = 2;
    }
    else
    {
      memcpy (&outname [outp], tmp, ptmp);
      outp += ptmp;
      if (inp < namelen)
      {
#if defined (CS_PLATFORM_DOS) || defined (CS_PLATFORM_WIN32)
        if ((inp == 1)
         && (iName [inp] == ':'))
          if ((iName [inp + 1] == '/')
           || (iName [inp + 1] == CS_PATH_SEPARATOR))
            outname [outp++] = ':';
          else
            outp += __getcwd (iName [inp - 1], outname + outp - 1,
	      sizeof (outname) - outp + 1) - 1;
        if ((outname [outp - 1] != '/')
         && (outname [outp - 1] != CS_PATH_SEPARATOR))
#endif
        outname [outp++] = CS_PATH_SEPARATOR;
      }
    } /* endif */
    while ((inp < namelen)
        && ((iName [inp] == '/')
         || (iName [inp] == CS_PATH_SEPARATOR)
#if defined (CS_PLATFORM_DOS) || defined (CS_PLATFORM_WIN32)
         || (iName [inp] == ':')
#endif
           )
          )
      inp++;
  } /* endwhile */

  char *ret = new char [outp + 1];
  memcpy (ret, outname, outp);
  ret [outp] = 0;
  return ret;
}
Exemplo n.º 21
0
/**
 * Check hash sums in a hash file.
 * Lines beginning with ';' and '#' are ignored.
 *
 * @param hash_file_path - the path of the file with hash sums to verify.
 * @param chdir - true if function should emulate chdir to directory of filepath before checking it.
 * @return zero on success, -1 on fail
 */
int check_hash_file(file_t* file, int chdir)
{
	FILE *fd;
	char buf[2048];
	size_t pos;
	const char *ralign;
	timedelta_t timer;
	struct file_info info;
	const char* hash_file_path = file->path;
	int res = 0, line_num = 0;
	double time;

	/* process --check-embedded option */
	if(opt.mode & MODE_CHECK_EMBEDDED) {
		unsigned crc32_be;
		if(find_embedded_crc32(hash_file_path, &crc32_be)) {
			/* initialize file_info structure */
			memset(&info, 0, sizeof(info));
			info.full_path = rsh_strdup(hash_file_path);
			info.file = file;
			file_info_set_print_path(&info, info.full_path);
			info.sums_flags = info.hc.hash_mask = RHASH_CRC32;
			info.hc.flags = HC_HAS_EMBCRC32;
			info.hc.embedded_crc32_be = crc32_be;

			res = verify_sums(&info);
			fflush(rhash_data.out);
			if(!rhash_data.interrupted) {
				if(res == 0) rhash_data.ok++;
				else if(res == -1 && errno == ENOENT) rhash_data.miss++;
				rhash_data.processed++;
			}

			free(info.full_path);
			file_info_destroy(&info);
		} else {
			log_warning(_("file name doesn't contain a CRC32: %s\n"), hash_file_path);
			return -1;
		}
		return 0;
	}

	/* initialize statistics */
	rhash_data.processed = rhash_data.ok = rhash_data.miss = 0;
	rhash_data.total_size = 0;

	if(file->mode & FILE_IFSTDIN) {
		fd = stdin;
		hash_file_path = "<stdin>";
	} else if( !(fd = rsh_fopen_bin(hash_file_path, "rb") )) {
		log_file_error(hash_file_path);
		return -1;
	}

	pos = strlen(hash_file_path)+16;
	ralign = str_set(buf, '-', (pos < 80 ? 80 - (int)pos : 2));
	fprintf(rhash_data.out, _("\n--( Verifying %s )%s\n"), hash_file_path, ralign);
	fflush(rhash_data.out);
	rhash_timer_start(&timer);

	/* mark the directory part of the path, by setting the pos index */
	if(chdir) {
		pos = strlen(hash_file_path);
		for(; pos > 0 && !IS_PATH_SEPARATOR(hash_file_path[pos]); pos--);
		if(IS_PATH_SEPARATOR(hash_file_path[pos])) pos++;
	} else pos = 0;

	/* read crc file line by line */
	for(line_num = 0; fgets(buf, 2048, fd); line_num++)
	{
		char* line = buf;
		char* path_without_ext = NULL;

		/* skip unicode BOM */
		if(line_num == 0 && buf[0] == (char)0xEF && buf[1] == (char)0xBB && buf[2] == (char)0xBF) line += 3;

		if(*line == 0) continue; /* skip empty lines */

		if(is_binary_string(line)) {
			log_error(_("file is binary: %s\n"), hash_file_path);
			if(fd != stdin) fclose(fd);
			return -1;
		}

		/* skip comments and empty lines */
		if(IS_COMMENT(*line) || *line == '\r' || *line == '\n') continue;

		memset(&info, 0, sizeof(info));

		if(!hash_check_parse_line(line, &info.hc, !feof(fd))) continue;
		if(info.hc.hash_mask == 0) continue;

		info.print_path = info.hc.file_path;
		info.sums_flags = info.hc.hash_mask;

		/* see if crc file contains a hash sum without a filename */
		if(info.print_path == NULL) {
			char* point;
			path_without_ext = rsh_strdup(hash_file_path);
			point = strrchr(path_without_ext, '.');

			if(point) {
				*point = '\0';
				file_info_set_print_path(&info, path_without_ext);
			}
		}

		if(info.print_path != NULL) {
			file_t file_to_check;
			int is_absolute = IS_PATH_SEPARATOR(info.print_path[0]);
			IF_WINDOWS(is_absolute = is_absolute || (info.print_path[0] && info.print_path[1] == ':'));

			/* if filename shall be prepended by a directory path */
			if(pos && !is_absolute) {
				size_t len = strlen(info.print_path);
				info.full_path = (char*)rsh_malloc(pos + len + 1);
				memcpy(info.full_path, hash_file_path, pos);
				strcpy(info.full_path + pos, info.print_path);
			} else {
				info.full_path = rsh_strdup(info.print_path);
			}
			memset(&file_to_check, 0, sizeof(file_t));
			file_to_check.path = info.full_path;
			rsh_file_stat(&file_to_check);
			info.file = &file_to_check;

			/* verify hash sums of the file */
			res = verify_sums(&info);

			fflush(rhash_data.out);
			rsh_file_cleanup(&file_to_check);
			file_info_destroy(&info);

			if(rhash_data.interrupted) {
				free(path_without_ext);
				break;
			}

			/* update statistics */
			if(res == 0) rhash_data.ok++;
			else if(res == -1 && errno == ENOENT) rhash_data.miss++;
			rhash_data.processed++;
		}
		free(path_without_ext);
	}
	time = rhash_timer_stop(&timer);

	fprintf(rhash_data.out, "%s\n", str_set(buf, '-', 80));
	print_check_stats();

	if(rhash_data.processed != rhash_data.ok) rhash_data.error_flag = 1;

	if(opt.flags & OPT_SPEED && rhash_data.processed > 1) {
		print_time_stats(time, rhash_data.total_size, 1);
	}

	rhash_data.processed = 0;
	res = ferror(fd); /* check that crc file has been read without errors */
	if(fd != stdin) fclose(fd);
	return (res == 0 ? 0 : -1);
}
Exemplo n.º 22
0
/* allocate and fill the file_search_data */
file_search_data* create_file_search_data(rsh_tchar** paths, size_t count, int max_depth)
{
	size_t i;

	file_search_data* data = (file_search_data*)rsh_malloc(sizeof(file_search_data));
	memset(data, 0, sizeof(file_search_data));
	rsh_blocks_vector_init(&data->root_files);
	data->max_depth = max_depth;

#ifdef _WIN32
	/* expand wildcards and fill the root_files */
	for (i = 0; i < count; i++)
	{
		int added = 0;
		size_t length, index;
		wchar_t* path = paths[i];
		wchar_t* p = wcschr(path, L'\0') - 1;

		/* strip trailing '\','/' symbols (if not preceded by ':') */
		for (; p > path && IS_PATH_SEPARATOR_W(*p) && p[-1] != L':'; p--) *p = 0;

		/* Expand a wildcard in the current file path and store results into data->root_files.
		 * If a wildcard is not found then just the file path is stored.
		 * NB, only wildcards in the last filename of the path are expanded. */

		length = p - path + 1;
		index = wcscspn(path, L"*?");

		if (index < length && wcscspn(path + index, L"/\\") >= (length - index))
		{
			/* a wildcard is found without a directory separator after it */
			wchar_t* parent;
			WIN32_FIND_DATAW d;
			HANDLE handle;

			/* find a directory separator before the file name */
			for (; index > 0 && !IS_PATH_SEPARATOR(path[index]); index--);
			parent = (IS_PATH_SEPARATOR(path[index]) ? path : 0);

			handle = FindFirstFileW(path, &d);
			if (INVALID_HANDLE_VALUE != handle)
			{
				do {
					file_t file;
					int failed;
					if (IS_CURRENT_OR_PARENT_DIRW(d.cFileName)) continue;

					memset(&file, 0, sizeof(file));
					file.wpath = make_pathw(parent, index + 1, d.cFileName);
					if (!file.wpath) continue;

					/* skip directories if not in recursive mode */
					if (data->max_depth == 0 && (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue;

					/* convert file name */
					file.path = wchar_to_cstr(file.wpath, WIN_DEFAULT_ENCODING, &failed);
					if (!failed) {
						failed = (file_statw(&file) < 0);
					}

					/* quietly skip unconvertible file names */
					if (!file.path || failed) {
						if (failed) {
							data->errors_count++;
						}
						free(file.path);
						free(file.wpath);
						continue;
					}

					/* fill the file information */
					file.mode |= FILE_IFROOT;
					add_root_file(data, &file);
					added++;
				} while (FindNextFileW(handle, &d));
				FindClose(handle);
			} else {
				/* report error on the specified wildcard */
				char * cpath = wchar_to_cstr(path, WIN_DEFAULT_ENCODING, NULL);
				set_errno_from_last_file_error();
				log_file_error(cpath);
				free(cpath);
				data->errors_count++;
			}
		}
		else
		{
			int failed;
			file_t file;
			memset(&file, 0, sizeof(file));

			/* if filepath is a dash string "-" */
			if ((path[0] == L'-' && path[1] == L'\0'))
			{
				file.mode = FILE_IFSTDIN;
				file.path = rsh_strdup("(stdin)");
			} else {
				file.path = wchar_to_cstr(path, WIN_DEFAULT_ENCODING, &failed);
				if (failed) {
					log_error(_("Can't convert the path to local encoding: %s\n"), file.path);
					free(file.path);
					data->errors_count++;
					continue;
				}
				file.wpath = path;
				if (file_statw(&file) < 0) {
					log_file_error(file.path);
					free(file.path);
					data->errors_count++;
					continue;
				}
			}

			/* mark the file as obtained from the command line */
			file.mode |= FILE_IFROOT;
			file.wpath = rsh_wcsdup(path);
			add_root_file(data, &file);
		}
	} /* for */
#else
	/* copy file paths */
	for (i = 0; i < count; i++)
	{
		file_t file;
		file_init(&file, paths[i], 0);

		if (IS_DASH_STR(file.path))
		{
			file.mode = FILE_IFSTDIN;
		}
		else if (file_stat2(&file, USE_LSTAT) < 0) {
			log_file_error(file.path);
			file_cleanup(&file);
			data->errors_count++;
			continue;
		}

		file.mode |= FILE_IFROOT;
		add_root_file(data, &file);
	}
#endif
	return data;
}