259 lines
6.1 KiB
C
259 lines
6.1 KiB
C
#include "libp2p/os/utils.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
#ifndef __MINGW32__
|
|
#include <pwd.h>
|
|
#endif
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <dirent.h>
|
|
#include <time.h>
|
|
|
|
/**
|
|
* get an environment varible from the os
|
|
* @param variable the variable to look for
|
|
* @returns the results
|
|
*/
|
|
char* os_utils_getenv(const char* variable) {
|
|
return getenv(variable);
|
|
}
|
|
|
|
/**
|
|
* set an environment variable in the os
|
|
* @param variable the variable to set
|
|
* @param value the value to assign to the variable
|
|
* @param overwrite passing a non-zero will allow an existing value to be overwritten
|
|
* @returns true(1) on success
|
|
*/
|
|
int os_utils_setenv(const char* variable, const char* value, int overwrite) {
|
|
#ifdef __MINGW32__
|
|
return 0;
|
|
#else
|
|
setenv(variable, value, overwrite);
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* returns the user's home directory
|
|
* @returns the home directory
|
|
*/
|
|
char* os_utils_get_homedir() {
|
|
#ifndef __MINGW32__
|
|
struct passwd *pw = getpwuid(getuid());
|
|
return pw->pw_dir;
|
|
#endif
|
|
return ".";
|
|
}
|
|
|
|
/**
|
|
* join 2 pieces of a filepath, being careful about the slashes
|
|
* @param root the root part
|
|
* @param extension what should be concatenated
|
|
* @param results where to put the results
|
|
* @param max_len throw an error if the total is longer than max_len
|
|
*/
|
|
int os_utils_filepath_join(const char* root, const char* extension, char* results, unsigned long max_len) {
|
|
if (strlen(root) + strlen(extension) + 1 > max_len)
|
|
return 0;
|
|
strncpy(results, root, strlen(root) + 1);
|
|
// one of these should have a slash. If not, add one
|
|
if (root[strlen(root)-1] != '/' && extension[0] != '/') {
|
|
results[strlen(root)] = '/';
|
|
results[strlen(root)+1] = 0;
|
|
}
|
|
strncat(results, extension, strlen(extension)+1);
|
|
return 1;
|
|
}
|
|
|
|
int os_utils_file_exists(const char* file_name) {
|
|
if (access(file_name, F_OK) != -1)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
* See if the passed in directory exists, and is a directory
|
|
* @param directory_name the name to examine
|
|
* @returns true(1) if it exists, false(0) if not
|
|
*/
|
|
int os_utils_directory_exists(const char* directory_name) {
|
|
if (access(directory_name, F_OK) != -1 && os_utils_is_directory(directory_name))
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Determine if the passed in file name is a directory
|
|
* @param file_name the file name
|
|
* @returns true(1) if file_name is a directory
|
|
*/
|
|
int os_utils_is_directory(const char* file_name) {
|
|
struct stat path_stat;
|
|
stat(file_name, &path_stat);
|
|
return S_ISDIR(path_stat.st_mode) != 0;
|
|
}
|
|
|
|
int os_utils_split_filename(const char* in, char** path, char** filename) {
|
|
int len = strlen(in);
|
|
char* pos = strrchr(in, '/');
|
|
if (pos != NULL) {
|
|
pos++;
|
|
*path = (char*)malloc((pos - in) + 1);
|
|
strncpy(*path, in, pos-in-1);
|
|
(*path)[pos-in-1] = 0;
|
|
*filename = (char*)malloc(len - (pos-in) + 1);
|
|
strcpy(*filename, pos);
|
|
(*filename)[len - (pos-in)] = 0;
|
|
} else {
|
|
*filename = (char*)malloc(len+1);
|
|
strcpy(*filename, in);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
struct FileList* os_utils_list_directory(const char* path) {
|
|
DIR* dp;
|
|
struct dirent *ep;
|
|
struct FileList* first = NULL;
|
|
struct FileList* last = NULL;
|
|
struct FileList* next = NULL;
|
|
|
|
dp = opendir(path);
|
|
if (dp != NULL) {
|
|
while ( (ep = readdir(dp)) ) {
|
|
if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0) {
|
|
// grab the data
|
|
next = (struct FileList*)malloc(sizeof(struct FileList));
|
|
next->file_name = malloc(strlen(ep->d_name) + 1);
|
|
strcpy(next->file_name, ep->d_name);
|
|
next->next = NULL;
|
|
// put it in the appropriate spot
|
|
if (first == NULL) {
|
|
first = next;
|
|
last = next;
|
|
} else {
|
|
last->next = next;
|
|
last = next;
|
|
}
|
|
} // not dealing with . or ..
|
|
} // while
|
|
closedir(dp);
|
|
}
|
|
return first;
|
|
}
|
|
|
|
int os_utils_free_file_list(struct FileList* first) {
|
|
if (first != NULL) {
|
|
struct FileList* next = first;
|
|
struct FileList* last = NULL;
|
|
while (next != NULL) {
|
|
last = next->next;
|
|
if (next->file_name != NULL) {
|
|
free(next->file_name);
|
|
}
|
|
free(next);
|
|
next = last;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
int os_utils_directory_writeable(const char* path) {
|
|
int result = access(path, W_OK);
|
|
return result == 0;
|
|
}
|
|
|
|
int os_utils_file_size(const char* path) {
|
|
size_t file_size = 0;
|
|
// open file
|
|
FILE* in_file = fopen(path, "r");
|
|
if (in_file == NULL)
|
|
return 0;
|
|
// determine size
|
|
fseek(in_file, 0L, SEEK_END);
|
|
file_size = ftell(in_file);
|
|
fclose(in_file);
|
|
return file_size;
|
|
}
|
|
|
|
/***
|
|
* Get the current time in GMT (UTC) as seconds since epoch
|
|
* @returns seconds since epoch
|
|
*/
|
|
unsigned long long os_utils_gmtime() {
|
|
time_t local = time(NULL);
|
|
struct tm *gmt = gmtime(&local);
|
|
return (unsigned long long)mktime(gmt);
|
|
}
|
|
|
|
/**
|
|
* String search for platforms without it
|
|
* @haystack where to look
|
|
* @needle what you're looking for
|
|
* @len when to stop looking
|
|
* @returns a pointer to where the needle is found in the haystack or NULL if not found
|
|
*/
|
|
char *strnstr(const char *haystack, const char *needle, size_t len)
|
|
{
|
|
int i;
|
|
size_t needle_len;
|
|
|
|
if (0 == (needle_len = strnlen(needle, len)))
|
|
return (char *)haystack;
|
|
|
|
for (i=0; i<=(int)(len-needle_len); i++)
|
|
{
|
|
if ((haystack[0] == needle[0]) &&
|
|
(0 == strncmp(haystack, needle, needle_len)))
|
|
return (char *)haystack;
|
|
|
|
haystack++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/***
|
|
* Make a directory, as well as any directories not already there
|
|
* @param path the path to create
|
|
* @returns true(1) on success, false(0) otherwise
|
|
*/
|
|
int os_mkdir(char* dir) {
|
|
const mode_t mode = S_IRWXU;
|
|
char tmp[256];
|
|
char *p = NULL;
|
|
size_t len;
|
|
|
|
snprintf(tmp, sizeof(tmp),"%s",dir);
|
|
len = strlen(tmp);
|
|
if(tmp[len - 1] == '/')
|
|
tmp[len - 1] = 0;
|
|
for(p = tmp + 1; *p; p++) {
|
|
if(*p == '/') {
|
|
*p = 0;
|
|
#ifdef __MINGW32__
|
|
if (mkdir(tmp) != 0) {
|
|
#else
|
|
if (mkdir(tmp, mode) != 0 && errno != EEXIST) {
|
|
#endif
|
|
fprintf(stderr, "Unable to create directory %s.\n", tmp);
|
|
return 0;
|
|
}
|
|
*p = '/';
|
|
}
|
|
}
|
|
#ifdef __MINGW32__
|
|
if (mkdir(tmp) != 0) {
|
|
#else
|
|
if (mkdir(tmp, mode) != 0) {
|
|
#endif
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|