mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 20:56:02 +00:00
119 lines
3.3 KiB
C++
119 lines
3.3 KiB
C++
//! @file getlinkcount.cpp
|
|
//! @author George FLeming <v-geflem@microsoft.com>
|
|
//! @brief Retrieve link count of a file
|
|
|
|
#include <errno.h>
|
|
#include <langinfo.h>
|
|
#include <locale.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <string>
|
|
#include <unicode/unistr.h>
|
|
#include <iostream>
|
|
#include "getlinkcount.h"
|
|
|
|
//! @brief GetLinkCount retrieves the file link count (number of hard links)
|
|
//! for the given file
|
|
//!
|
|
//! GetLinkCount
|
|
//!
|
|
//! @param[in] fileName
|
|
//! @parblock
|
|
//! A pointer to the buffer that contains the file name
|
|
//!
|
|
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
|
//! @endparblock
|
|
//!
|
|
//! @param[out] count
|
|
//! @parblock
|
|
//! This function returns the number of hard links associated with this file
|
|
//! @endparblock
|
|
//!
|
|
//! @exception errno Passes these errors via errno to GetLastError:
|
|
//! - ERROR_INVALID_PARAMETER: parameter is not valid
|
|
//! - ERROR_BAD_ENVIRONMENT: locale is not UTF-8
|
|
//! - ERROR_FILE_NOT_FOUND: file does not exist
|
|
//! - ERROR_ACCESS_DENIED: access is denied
|
|
//! - ERROR_FILE_NOT_FOUND: the system cannot find the file specified
|
|
//! - ERROR_INVALID_ADDRESS: attempt to access invalid address
|
|
//! - ERROR_STOPPED_ON_SYMLINK: the operation stopped after reaching a symbolic link
|
|
//! - ERROR_GEN_FAILURE: device attached to the system is not functioning
|
|
//! - ERROR_NO_SUCH_USER: there was no corresponding entry in the utmp-file
|
|
//! - ERROR_INVALID_NAME: filename, directory name, or volume label syntax is incorrect
|
|
//! - ERROR_BUFFER_OVERFLOW: file name is too long
|
|
//! - ERROR_INVALID_FUNCTION: incorrect function
|
|
//! - ERROR_BAD_PATH_NAME: pathname is too long, or contains invalid characters
|
|
//!
|
|
//! @retval TRUE If the function succeeds, the return value is a nonzero
|
|
//! value, and the variable pointed to by buffer contains infomation about the files
|
|
//! @retval FALSE If the function fails, the return value is zero. To get
|
|
//! extended error information, call GetLastError.
|
|
//!
|
|
|
|
BOOL GetLinkCount(char* fileName, LPDWORD count)
|
|
{
|
|
errno = 0;
|
|
|
|
// Check parameters
|
|
if (!fileName)
|
|
{
|
|
errno = ERROR_INVALID_PARAMETER;
|
|
return FALSE;
|
|
}
|
|
|
|
// Select locale from environment
|
|
setlocale(LC_ALL, "");
|
|
// Check that locale is UTF-8
|
|
if (nl_langinfo(CODESET) != std::string("UTF-8"))
|
|
{
|
|
errno = ERROR_BAD_ENVIRONMENT;
|
|
return FALSE;
|
|
}
|
|
|
|
struct stat statBuf;
|
|
|
|
int returnCode = lstat(fileName, &statBuf);
|
|
|
|
if (returnCode != 0)
|
|
{
|
|
switch(errno)
|
|
{
|
|
case EACCES:
|
|
errno = ERROR_ACCESS_DENIED;
|
|
break;
|
|
case EBADF:
|
|
errno = ERROR_FILE_NOT_FOUND;
|
|
break;
|
|
case EFAULT:
|
|
errno = ERROR_INVALID_ADDRESS;
|
|
break;
|
|
case ELOOP:
|
|
errno = ERROR_STOPPED_ON_SYMLINK;
|
|
break;
|
|
case ENAMETOOLONG:
|
|
errno = ERROR_GEN_FAILURE;
|
|
break;
|
|
case ENOENT:
|
|
errno = ERROR_FILE_NOT_FOUND;
|
|
break;
|
|
case ENOMEM:
|
|
errno = ERROR_NO_SUCH_USER;
|
|
break;
|
|
case ENOTDIR:
|
|
errno = ERROR_INVALID_NAME;
|
|
break;
|
|
case EOVERFLOW:
|
|
errno = ERROR_BUFFER_OVERFLOW;
|
|
break;
|
|
default:
|
|
errno = ERROR_INVALID_FUNCTION;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
*count = statBuf.st_nlink;
|
|
return TRUE;
|
|
|
|
}
|