first commit

This commit is contained in:
Your Name 2024-07-01 13:23:00 +03:00
commit 21be7fd279
156 changed files with 6939 additions and 0 deletions

48
include/libmu/duration.h Normal file
View file

@ -0,0 +1,48 @@
#ifndef _DURATION_H
#define _DURATION_H
#include <string.h>
unsigned long long parse_uint(const char *str) {
char *p = NULL;
unsigned long long res = strtoull(str, &p, 0);
/* Parse suffix */
if (*p) {
switch (p[0]) {
case 'm':
res *= 60;
break;
case 'h':
res *= 3600;
break;
case 'd':
res *= 86400;
break;
case 's':
default:
break;
}
}
return res;
}
unsigned long long mu_parse_duration(const char *arg) {
if (strchr(arg, '.')) {
/* TODO */
}
else {
/* Sec */
return parse_uint(arg) * 1000000;
}
return 0;
}
#endif

39
include/libmu/get_stat.h Normal file
View file

@ -0,0 +1,39 @@
#ifndef _GET_STAT_H
#define _GET_STAT_H
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
int mu_get_stat(const char *prog_name, const char *path, struct stat *stat_path) {
if (stat(path, stat_path)) {
if (prog_name != NULL)
fprintf(stderr, "%s: %s: %s\n", prog_name, path, strerror(errno));
return 1;
}
return 0;
}
int mu_get_lstat(const char *prog_name, const char *path, struct stat *stat_path) {
if (lstat(path, stat_path)) {
if (prog_name != NULL)
fprintf(stderr, "%s: %s: %s\n", prog_name, path, strerror(errno));
return 1;
}
return 0;
}
int mu_get_stats(const char *prog_name, int flag, const char *path, struct stat *stat_path) {
if (flag)
return mu_get_lstat(prog_name, path, stat_path);
else
return mu_get_stat(prog_name, path, stat_path);
}
#endif

30
include/libmu/human.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef _HUMAN_H
#define _HUMAN_H
#include <stdlib.h>
#include <stdint.h>
#define MU_HUMAN_BUF_SIZE 16
char *mu_humansize(off_t n, off_t block) {
static char mu_hs_buf[MU_HUMAN_BUF_SIZE + 1];
memset(mu_hs_buf, '\0', sizeof(mu_hs_buf));
char *postfixes = "BKMGTPE";
double size = n;
size_t i;
for (i = 0; i < strlen(postfixes) && size >= block; i++)
size /= block;
if (i)
snprintf(mu_hs_buf, sizeof(mu_hs_buf), "%.1f%c", size, postfixes[i]);
else
snprintf(mu_hs_buf, sizeof(mu_hs_buf), "%ju", n);
return mu_hs_buf;
}
#endif

39
include/libmu/make_path.h Normal file
View file

@ -0,0 +1,39 @@
#ifndef _MAKE_PATH_H
#define _MAKE_PATH_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *mu_make_path(const char *prog_name, const char *src, const char *dst) {
int flag = 0;
if (src == NULL) {
flag = 1;
src = "";
}
if (dst == NULL) {
flag = 1;
dst = "";
}
size_t len = strlen(src) + strlen(dst) + 2;
char *full_path = malloc(len + 1);
if (full_path == NULL) {
if (prog_name != NULL)
fprintf(stderr, "%s: malloc() failed\n", prog_name);
return NULL;
}
if (flag || src[strlen(src) - 1] == '/')
snprintf(full_path, len, "%s%s", src, dst);
else
snprintf(full_path, len, "%s/%s", src, dst);
return full_path;
}
#endif

View file

@ -0,0 +1,57 @@
#ifndef _MODE_TO_STR_H
#define _MODE_TO_STR_H
#include <stdio.h>
#include <sys/stat.h>
char *mu_mode_2_str(mode_t file_mode) {
static char mode[11];
snprintf(mode, sizeof(mode), "----------");
if (file_mode & S_IRUSR)
mode[1] = 'r';
if (file_mode & S_IRGRP)
mode[4] = 'r';
if (file_mode & S_IROTH)
mode[7] = 'r';
if (file_mode & S_IWUSR)
mode[2] = 'w';
if (file_mode & S_IWGRP)
mode[5] = 'w';
if (file_mode & S_IWOTH)
mode[8] = 'w';
if (file_mode & S_IXUSR)
mode[3] = 'x';
if (file_mode & S_IXGRP)
mode[6] = 'x';
if (file_mode & S_IXOTH)
mode[9] = 'x';
if (file_mode & S_ISUID) {
if (file_mode & S_IXUSR)
mode[3] = 's';
else
mode[3] = 'S';
}
if (file_mode & S_ISGID) {
if (file_mode & S_IRGRP)
mode[6] = 's';
else
mode[6] = 'S';
}
return mode;
}
#endif

View file

@ -0,0 +1,99 @@
#ifndef _PARSE_MODE_H
#define _PARSE_MODE_H
#include <sys/stat.h>
#include <string.h>
#define U (S_ISUID | S_IRWXU)
#define G (S_ISGID | S_IRWXG)
#define O (S_IRWXO)
#define A (U | G | O)
#define WR_PERM (S_IWUSR | S_IWGRP | S_IWOTH)
#define EX_PERM (S_IXUSR | S_IXGRP | S_IXOTH)
#define RD_PERM (S_IRUSR | S_IRGRP | S_IROTH)
#define SU_PERM (S_ISUID | S_ISGID | S_ISVTX)
#define FULL_PERM (WR_PERM | EX_PERM | RD_PERM)
mode_t mu_parse_mode(const char *s, mode_t cur_mode) {
char *p = NULL;
mode_t mode = (mode_t)strtol(s, &p, 8);
if (!*p && mode < 07777U)
return mode;
else if (mode > 07777U)
return 0;
mode = 0;
/* Default + */
char append = 1;
mode_t mask = 0;
for (size_t i = 0; i < strlen(s); i++) {
switch (s[i]) {
case 'r':
mode |= RD_PERM;
break;
case 'w':
mode |= WR_PERM;
break;
case 'x':
mode |= EX_PERM;
break;
case 's':
mode |= SU_PERM;
break;
case '+':
append = 1;
break;
case '-':
append = 0;
break;
case '=':
append = 2;
break;
case 'g':
mask |= G;
break;
case 'u':
mask |= U;
break;
case 'o':
mask |= O;
break;
case 'a':
mask |= A;
break;
default:
return 0;
}
}
if (mask == 0)
mask = U;
mask &= mode;
if (append == 0)
mode = ~mode;
if (append == 2)
return mode & mask;
else
return (cur_mode & ~mask) | (mode & mask);
}
#endif

View file

@ -0,0 +1,72 @@
#ifndef _PARSE_MOUNT_H
#define _PARSE_MOUNT_H
#include <string.h>
typedef struct {
char *opt;
char *notopt;
char *desc;
unsigned int val;
} MU_MOUNT_OPTS;
MU_MOUNT_OPTS mu_options[] = {
{"defaults", NULL, NULL, 0},
{"ro", "rw", "Read only / Read and write", MS_RDONLY},
{"remount", NULL, "Remount a mounted filesystem", MS_REMOUNT},
{"sync", "async", "Writes are [a]synchronous", MS_SYNCHRONOUS},
{"nodev", "dev", "(Dis)allow use of special device files", MS_NODEV},
{"bind", "rbind", "Bind a file or directory", MS_BIND},
{"noexec", "exec", "(Dis)allow use of executable files", MS_NOEXEC},
{"noatime", "atime", "Disable/enable updates to inode access times", MS_NOATIME}
};
unsigned long mu_parse_opts(char *str, char *data, const size_t data_size) {
memset(data, '\0', data_size);
unsigned long opt = 0;
size_t data_len = 0;
char *token = strtok(str, ",");
while (token != NULL) {
int invalidopt = 1;
for (size_t i = 0; i < sizeof(mu_options) / sizeof(mu_options[0]); i++) {
if (mu_options[i].opt && !strcmp(token, mu_options[i].opt)) {
opt |= mu_options[i].val;
invalidopt = 0;
break;
}
if (mu_options[i].notopt && !strcmp(token, mu_options[i].notopt)) {
opt &= ~mu_options[i].val;
invalidopt = 0;
break;
}
}
/* Unknow opt, pass in mount() */
size_t len = strlen(token);
if (invalidopt && len > 0) {
/* Copy token string */
for (size_t i = 0; i < len; i++) {
if (data_len + 1 >= data_size)
break;
else {
data[data_len] = token[i];
data_len++;
}
}
if (data_len && data_len + 1 < data_size)
data[data_len++] = ',';
}
token = strtok(NULL, ",");
}
if (data_len > 0)
data[data_len - 1] = '\0';
return opt;
}
#endif

59
include/libmu/pw_check.h Normal file
View file

@ -0,0 +1,59 @@
#ifndef _PW_CHECK_H
#define _PW_CHECK_H
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "config.h"
void dec_salt(void) {
size_t i;
for (i = 0; i < sizeof(MU_SALT_ENC) / sizeof(int); i++)
MU_SALT_BUF[i] = MU_SALT_ENC[i];
MU_SALT_BUF[i + 1] = '\0';
}
/* Using not only there */
char *enc_password(const char *prog_name, const char *pass, const char *salt) {
if (salt == NULL)
dec_salt();
char *cpass = crypt(pass, (salt == NULL) ? MU_SALT_BUF : salt);
if (cpass == NULL) {
if (prog_name != NULL)
fprintf(stderr, "%s: %s\n", prog_name, strerror(errno));
return NULL;
}
return cpass;
}
int pw_check(const char *prog_name, const struct passwd *pw, const char *pass) {
if (pw->pw_passwd[0] == '\0' && pass[0] == '\0')
return 0;
if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') {
if (prog_name != NULL)
fprintf(stderr, "%s: Access denied\n", prog_name);
return 1;
}
char *cpass = enc_password(prog_name, pass, NULL);
if (cpass == NULL)
return 1;
if (!strcmp(pw->pw_passwd, cpass))
return 0;
if (prog_name != NULL)
fprintf(stderr, "%s: Incorrect password\n", prog_name);
return 1;
}
#endif

54
include/libmu/recurse.h Normal file
View file

@ -0,0 +1,54 @@
#ifndef _RECURSE_H
#define _RECURSE_H
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include "make_path.h"
#include "get_stat.h"
int mu_recurse(const char *restrict prog_name, int link_flag, const char *restrict path, void *restrict arg, int (*file_act)(const char *path, void *p), int (*dir_act)(const char *path, void *p)) {
struct stat sb;
if (mu_get_stats(prog_name, link_flag, path, &sb))
return 1;
if (!S_ISDIR(sb.st_mode) || S_ISLNK(sb.st_mode)) {
if (file_act != NULL)
return file_act(path, arg);
}
DIR *dir = opendir(path);
if (dir == NULL) {
if (prog_name != NULL)
fprintf(stderr, "%s: %s: Can`t open directory\n", prog_name, path);
return 1;
}
int ret = 0;
struct dirent *ep;
while ((ep = readdir(dir)) != NULL) {
if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
continue;
char *full_path = mu_make_path(prog_name, path, ep->d_name);
if (full_path == NULL)
continue;
if (mu_recurse(prog_name, link_flag, full_path, arg, file_act, dir_act))
ret = 1;
free(full_path);
}
closedir(dir);
if (dir_act != NULL)
if (dir_act(path, arg))
ret = 1;
return ret;
}
#endif

6
include/libmu/unused.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef _UNUSED_H
#define _UNUSED_H
#define UNUSED(p) ((void)p)
#endif

View file

@ -0,0 +1,13 @@
#ifndef _UTF8_STRLEN
#define _UTF8_STRLEN
size_t utf8_strlen(const char *s) {
size_t i = 0;
while (*s++)
i += (*s & 0xC0) != 0x80;
return i;
}
#endif