commits
tags
#include "util.h"
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
void safe_strcpy(char *dst, size_t dst_size, const char *src) {
if (dst_size == 0) return;
size_t n = strlen(src);
if (n >= dst_size) n = dst_size - 1;
memcpy(dst, src, n);
dst[n] = '\0';
}
static int is_illegal_dirname_char(unsigned char c) {
if (c < 0x20) return 1;
switch (c) {
case '<': case '>': case ':': case '"':
case '/': case '\\': case '|': case '?': case '*':
return 1;
default:
return 0;
}
}
void sanitize_dirname(const char *name, char *dst, size_t dst_size) {
if (dst_size == 0) return;
char tmp[1024];
size_t out = 0;
int last_was_space = 0;
for (const unsigned char *p = (const unsigned char *)name; *p && out + 1 < sizeof(tmp); p++) {
unsigned char c = *p;
if (is_illegal_dirname_char(c)) c = '_';
if (isspace(c)) {
if (last_was_space) continue;
last_was_space = 1;
tmp[out++] = ' ';
} else {
last_was_space = 0;
tmp[out++] = (char)c;
}
}
tmp[out] = '\0';
/* strip leading/trailing spaces and dots */
char *start = tmp;
while (*start == ' ' || *start == '.') start++;
char *end = start + strlen(start);
while (end > start && (end[-1] == ' ' || end[-1] == '.')) end--;
*end = '\0';
if (*start == '\0') {
safe_strcpy(dst, dst_size, "playlist");
} else {
safe_strcpy(dst, dst_size, start);
}
}
int mkdir_p(const char *path) {
char tmp[1024];
safe_strcpy(tmp, sizeof(tmp), path);
size_t len = strlen(tmp);
if (len == 0) {
errno = EINVAL;
return -1;
}
if (tmp[len - 1] == '/') tmp[len - 1] = '\0';
for (char *p = tmp + 1; *p; p++) {
if (*p == '/') {
*p = '\0';
if (mkdir(tmp, 0755) != 0 && errno != EEXIST) return -1;
*p = '/';
}
}
if (mkdir(tmp, 0755) != 0 && errno != EEXIST) return -1;
return 0;
}