This commit is contained in:
Freya Murphy 2023-05-06 00:39:44 -04:00
parent b1364be7e2
commit d8f2c10b71
44 changed files with 697 additions and 549 deletions

19
.clangd
View file

@ -1,19 +0,0 @@
If:
PathMatch:
- .*\.c
- .*\.h
CompileFlags:
Add:
- -xc
- -std=c89
- -Isrc
- -Wall
- -Wextra,
- -pedantic
- -O2
- -ferror-limit=0
- -D_DEFAULT_SOURCE
- -D_CHECK_LINK
Compiler: clang

View file

@ -1,6 +1,8 @@
CC = gcc CC = gcc
SOURCE = src SOURCE = src
SOURCE += lib
SOURCE += command
MAJOR = 0 MAJOR = 0
MINOR = 0 MINOR = 0
@ -21,9 +23,9 @@ SRC = $(shell find $(SOURCE) -name "*.c")
DIR = $(shell find $(SOURCE) -type d) DIR = $(shell find $(SOURCE) -type d)
OBJ = $(SRC:%.c=$(BIN)/%.o) OBJ = $(SRC:%.c=$(BIN)/%.o)
.PHONY: dirs run clean build install uninstall .PHONY: empty dirs run clean build install uninstall
EOF: clean build empty: clean build
dirs: dirs:
echo $(DIR) | xargs printf -- '$(BIN)/%s\n' | xargs mkdir -p echo $(DIR) | xargs printf -- '$(BIN)/%s\n' | xargs mkdir -p

View file

@ -1,6 +1,8 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <ctype.h> #include <ctype.h>
#include <stdlib.h>
static struct { static struct {
bool number_lines; bool number_lines;

View file

@ -1,7 +1,12 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <dirent.h> #include <dirent.h>
#include <errno.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>

View file

@ -1,4 +1,7 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <stdlib.h>
static void help(void) { static void help(void) {
printf("Usage: dd [if=FILE] [of=FILE] [bs=N] [count=N]\n\n"); printf("Usage: dd [if=FILE] [of=FILE] [bs=N] [count=N]\n\n");

View file

@ -1,4 +1,7 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <stdlib.h>
static struct { static struct {
bool escape_codes; bool escape_codes;

View file

@ -1,5 +1,8 @@
#include "../command.h" #include "command.h"
#include "../util//regex.h" #include "lslib.h"
#include <stdlib.h>
#include <string.h>
#define INPUT_LEN 1024 #define INPUT_LEN 1024

View file

@ -1,5 +1,9 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
static struct { static struct {
bool filename_prefix; bool filename_prefix;

View file

@ -1,21 +1,42 @@
#include "../command.h" #include "args.h"
#include "command.h"
#include "lslib.h"
#include <errno.h>
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
COMMAND_EMPTY(groups) { static void help (void) {
printf("Usage: groups [USER]\n\n");
printf("Print the groups USER is in\n");
}
COMMAND(groups) {
uid_t uid; uid_t uid;
int ngroups, i; int ngroups, i;
gid_t* groups; gid_t* groups;
struct passwd* pw; struct passwd* pw;
uid = getuid(); parse_help(argc, argv, help);
if (argc < 1) {
uid = getuid();
pw = getpwuid(uid); pw = getpwuid(uid);
} else {
pw = getpwnam(argv[0]);
}
if(pw == NULL){ if(pw == NULL){
if (errno == 0) {
error("user not found");
} else {
error("failed to fetch groups: %s", strerror(errno)); error("failed to fetch groups: %s", strerror(errno));
} }
}
ngroups = 0; ngroups = 0;
getgrouplist(pw->pw_name, pw->pw_gid, NULL, &ngroups); getgrouplist(pw->pw_name, pw->pw_gid, NULL, &ngroups);

View file

@ -1,4 +1,7 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <stdlib.h>
static struct { static struct {
int count; int count;

View file

@ -1,9 +1,20 @@
#include "../command.h" #include "args.h"
#include "command.h"
#include "lslib.h"
#include <errno.h>
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
COMMAND_EMPTY(user_id) { static void help (void) {
printf("Usage: id [USER]\n\n");
printf("Print information about the USER\n");
}
COMMAND(user_id) {
uid_t uid; uid_t uid;
gid_t gid, *groups; gid_t gid, *groups;
@ -11,13 +22,24 @@ COMMAND_EMPTY(user_id) {
struct passwd* pw; struct passwd* pw;
struct group* ugr; struct group* ugr;
uid = getuid(); parse_help(argc, argv, help);
gid = getgid();
if (argc < 1) {
uid = getuid();
pw = getpwuid(uid); pw = getpwuid(uid);
} else {
pw = getpwnam(argv[0]);
}
if(pw == NULL){ if(pw == NULL){
if (errno == 0) {
error("user not found");
} else {
error("failed to fetch groups: %s", strerror(errno)); error("failed to fetch groups: %s", strerror(errno));
} }
}
uid = pw->pw_uid;
ngroups = 0; ngroups = 0;
getgrouplist(pw->pw_name, pw->pw_gid, NULL, &ngroups); getgrouplist(pw->pw_name, pw->pw_gid, NULL, &ngroups);
@ -25,6 +47,7 @@ COMMAND_EMPTY(user_id) {
groups = malloc(sizeof(gid_t) * ngroups); groups = malloc(sizeof(gid_t) * ngroups);
getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
gid = pw->pw_gid;
ugr = getgrgid(gid); ugr = getgrgid(gid);
printf("uid=%d(%s) gid=%d(%s) ", printf("uid=%d(%s) gid=%d(%s) ",
uid, ugr->gr_name, gid, ugr->gr_name); uid, ugr->gr_name, gid, ugr->gr_name);

View file

@ -1,11 +1,16 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
#include <dirent.h> #include <dirent.h>
#include <ftw.h> #include <ftw.h>
#include <limits.h> #include <limits.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define FILE_COLOR ANSCII BLACK COLOR #define FILE_COLOR ANSCII BLACK COLOR
#define DIR_COLOR ANSCII BOLD NEXT NORMAL BLUE COLOR #define DIR_COLOR ANSCII BOLD NEXT NORMAL BLUE COLOR
@ -17,6 +22,12 @@
#define BLK_COLOR ANSCII BOLD NEXT NORMAL YELLOW COLOR #define BLK_COLOR ANSCII BOLD NEXT NORMAL YELLOW COLOR
#define SOCK_COLOR ANSCII BOLD NEXT NORMAL MAGENTA COLOR #define SOCK_COLOR ANSCII BOLD NEXT NORMAL MAGENTA COLOR
enum When {
YES,
NO,
AUTO
};
static struct { static struct {
bool hidden; bool hidden;
bool hide_dot; bool hide_dot;

View file

@ -1,4 +1,9 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
static struct { static struct {
bool make_parent; bool make_parent;

View file

@ -1,4 +1,9 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
static struct { static struct {
bool prompt; bool prompt;

View file

@ -1,4 +1,7 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <stdlib.h>
static long cast_long(const char* arg) { static long cast_long(const char* arg) {
char* end; char* end;

View file

@ -1,5 +1,9 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <dirent.h> #include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
static struct { static struct {

View file

@ -1,8 +1,10 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <time.h>
static void help(void) { static void help(void) {
printf("Usage: tac [FILE]...\n\n"); printf("Usage: tac [FILE]...\n\n");

View file

@ -1,4 +1,9 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static struct { static struct {
bool lines; bool lines;

View file

@ -1,6 +1,8 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <signal.h> #include <signal.h>
#include <stdlib.h>
static struct { static struct {
bool append; bool append;

View file

@ -1,6 +1,8 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <ctype.h> #include <ctype.h>
#include <stdlib.h>
static struct { static struct {
bool newlines; bool newlines;

View file

@ -1,6 +1,9 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <pwd.h> #include <pwd.h>
#include <stdlib.h>
#include <unistd.h>
static void help(void) { static void help(void) {
printf("Usage: whoami\n\n"); printf("Usage: whoami\n\n");

View file

@ -1,6 +1,11 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h>
static struct { static struct {
bool null_seperated; bool null_seperated;

View file

@ -1,4 +1,5 @@
#include "../command.h" #include "command.h"
#include "lslib.h"
static void help(void) { static void help(void) {
printf("Usage: yes [STRING]\n\n"); printf("Usage: yes [STRING]\n\n");

15
compile_flags.txt Normal file
View file

@ -0,0 +1,15 @@
-c
-std=c89
-Wall
-Wextra
-pedantic
-O2
-Isrc
-Icommand
-Ilib
-D_DEFAULT_SOURCE
-DMAJOR=0
-DMINOR=0
-DPATCH=0
-DCHECK_LINK

111
lib/args.c Normal file
View file

@ -0,0 +1,111 @@
#include "args.h"
#include "error.h"
#include "convert.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef MAJOR
#define MAJOR 0
#endif
#ifndef MINOR
#define MINOR 0
#endif
#ifndef PATCH
#define PATCH 0
#endif
void check_arg (char* arg) {
if (arg == NULL) {
error("expected another argument after option");
}
}
void global_help(void (*help)(void)) {
printf("LazySphere v%d.%d.%d multi-call binary.\n\n", MAJOR, MINOR, PATCH);
help();
exit(EXIT_SUCCESS);
}
void parse_help(int argc, char** argv, void (*help)(void)) {
int i;
if (argc < 1) return;
for (i = 0; i < argc; i++) {
if (!prefix("-", argv[i]) || streql("-", argv[i])) break;
if (help != NULL && streql("--help", argv[i])) global_help(help);
}
}
int parse_args(int argc, char** argv, void (*help)(void), int (*short_arg)(char, char*), int (*long_arg)(char*, char*)) {
int start, i, current;
char* next_arg;
if (argc < 1) return 0;
start = 0;
for (i = 0; i < argc; i++) {
if (!prefix("-", argv[i]) || streql("-", argv[i])) break;
if (help != NULL && streql("--help", argv[i])) global_help(help);
if (i + 1 == argc) {
next_arg = NULL;
} else {
next_arg = argv[i+1];
}
current = i;
if (prefix("--", argv[i])) {
int r;
if (long_arg == NULL) {
goto exit;
}
r = long_arg(argv[current], next_arg);
if (r == ARG_USED) {
i++;
start++;
} else if (r == ARG_IGNORE) {
goto exit;
} else if (r == ARG_INVALID) {
error("invalid argument %s", argv[current]);
}
} else {
size_t j;
int r;
if (short_arg == NULL) {
goto exit;
}
for (j = 1; j < strlen(argv[current]); j++) {
r = short_arg(argv[current][j], next_arg);
if (r == ARG_USED) {
i++;
start++;
} else if (r == ARG_IGNORE) {
goto exit;
} else if (r == ARG_INVALID) {
error("invalid argument -%c", argv[current][j]);
}
}
}
start++;
}
exit:
return start;
}

18
lib/args.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef ARGS_H
#define ARGS_H
#define UNUSED(x) (void)(x)
#define ARG_UNUSED 0
#define ARG_USED 1
#define ARG_IGNORE 2
#define ARG_INVALID 3
void check_arg (char* arg);
void global_help(void (*help)(void));
void parse_help (int argc, char** argv, void (*help)(void));
int parse_args (int argc, char** argv, void (*help)(void), int (*short_arg)(char, char*), int (*long_arg)(char*, char*));
#endif

60
lib/buffer.c Normal file
View file

@ -0,0 +1,60 @@
#include "buffer.h"
#include "convert.h"
#include <limits.h>
#include <string.h>
static int push_path_buffer_b(char* buf, int* index, const char* string) {
int save, string_len;
save = *index;
if (*index > 1 || (*index == 1 && buf[0] != '/')) {
buf[(*index)++] = '/';
}
string_len = strlen(string);
memcpy(buf + *index, string, string_len + 1);
*index += string_len;
return save;
}
static void pop_path_buffer_b(char* buf, int* index, int i) {
*index = i;
buf[*index] = '\0';
}
static char path_buffer[PATH_MAX + 1];
static int path_buffer_index = 0;
char* get_path_buffer(void) {
return path_buffer;
}
int push_path_buffer(const char* string) {
return push_path_buffer_b(path_buffer, &path_buffer_index, string);
}
void pop_path_buffer(int i) {
pop_path_buffer_b(path_buffer, &path_buffer_index, i);
}
static char path_buffer_2[PATH_MAX + 1];
static int path_buffer_index_2 = 0;
char* get_path_buffer_2(void) {
return path_buffer_2;
}
int push_path_buffer_2(const char* string) {
return push_path_buffer_b(path_buffer_2, &path_buffer_index_2, string);
}
void pop_path_buffer_2(int i) {
pop_path_buffer_b(path_buffer_2, &path_buffer_index_2, i);
}
bool is_dot_dir(const char* path) {
return streql(path, ".") || streql(path, "..");
}

16
lib/buffer.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef BUFFER_H
#define BUFFER_H
#include "def.h"
char* get_path_buffer(void);
int push_path_buffer(const char* string);
void pop_path_buffer(int i);
char* get_path_buffer_2(void);
int push_path_buffer_2(const char* string);
void pop_path_buffer_2(int i);
bool is_dot_dir(const char* path);
#endif

126
lib/convert.c Normal file
View file

@ -0,0 +1,126 @@
#include "convert.h"
#include "error.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
long int get_number(const char* text) {
char* end;
long int n = strtol(text, &end, 10);
if (text == end) {
error("%s is not a valid number", text);
}
return n;
}
long int get_blkm(const char* text) {
char* end;
long int n = strtol(text, &end, 10);
if (text == end) {
error("%s is not a valid bkm", text);
}
if (*end == '\0') return n;
switch (*end) {
case 'K':
case 'k':
return n * 1024;
case 'B':
case 'b':
return n * 512;
case 'M':
case 'm':
return n * 1024 * 1204;
default:
error("invalid bkm type %c", *end);
}
/* shouldnt get here anyways */
return 0;
}
mode_t get_mode(const char* next) {
char* end = NULL;
mode_t mode = (mode_t)strtol(next, &end, 8);
if (!end) return 0;
while(isspace(*end)) end++;
if (*end != '\0' || (unsigned) mode < 010000) {
error("invalid file mode: `%s`", next);
}
return mode;
}
bool streql(const char* a, const char* b) {
int n = 0;
if (*a != *b) return false;
while (true) {
if (*(a+n) != *(b+n)) return false;
if (*(a+n) == '\0') return true;
++n;
}
}
bool prefix(const char* pre, const char* str) {
return strncmp(pre, str, strlen(pre)) == 0;
}
static char fs_types[5] = {'K','M','G','T','P'};
void print_file_size(size_t bytes, char buf[5]) {
int index, n;
float next;
index = 0;
next = bytes;
while (true) {
if (next < 1000) {
break;
}
if (index == 5) {
printf("999P");
return;
}
next /= 1024;
index++;
}
n = snprintf(buf, 4, "%u", (int)(next+.5));
if (index > 0) {
buf[n] = (fs_types[index - 1]);
n++;
}
buf[n] = '\0';
}
static char* months[12] =
{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
void print_date_time(time_t mills, char buf[13]) {
struct tm* info;
int n;
info = localtime(&mills);
n = snprintf(buf, 5, "%s ", months[info->tm_mon]);
if (info->tm_mday < 10) {
buf[n] = ' ';
n++;
}
snprintf(buf + n, 13 - n, "%d %02d:%02d ", info->tm_mday, info->tm_hour, info->tm_sec);
}
void print_file_path(char* path) {
if (streql("-", path)) {
printf("(standard input)");
} else {
printf("%s", path);
}
}

20
lib/convert.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef CONVERT_H
#define CONVERT_H
#include "def.h"
#include <sys/stat.h>
#include <stddef.h>
long int get_number(const char* text);
long int get_blkm(const char* text);
mode_t get_mode(const char* text);
bool streql(const char* a, const char* b);
bool prefix(const char* pre, const char* str);
void print_file_size(size_t bytes, char buf[5]);
void print_date_time(time_t mills, char buf[13]);
void print_file_path(char* path);
#endif

31
lib/def.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef COLOR_H
#define COLOR_H
#include <stdint.h>
#define ANSCII "\x1b["
#define NEXT ";"
#define RESET "0"
#define BOLD "1"
#define NORMAL "3"
#define BACKGROUND "4"
#define HIGHLIGHT "9"
#define BLACK "0"
#define RED "1"
#define GREEN "2"
#define YELLOW "3"
#define BLUE "4"
#define MAGENTA "5"
#define TURQUOISE "6"
#define WHITE "7"
#define COLOR "m"
typedef uint8_t bool;
#define true 1
#define false 0
#endif

35
lib/error.c Normal file
View file

@ -0,0 +1,35 @@
#include "error.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
extern char* cmd;
void error_s(const char *format, ...) {
va_list list;
va_start(list, format);
fprintf(stderr, "%s: ", cmd);
vfprintf(stderr, format, list);
fprintf(stderr, "\n");
}
void error(const char *format, ...) {
va_list list;
va_start(list, format);
fprintf(stderr, "%s: ", cmd);
vfprintf(stderr, format, list);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
void output(const char *format, ...) {
va_list list;
va_start(list, format);
fprintf(stdout, "%s: ", cmd);
vfprintf(stdout, format, list);
fprintf(stdout, "\n");
}

13
lib/error.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef ERROR_H
#define ERROR_H
__attribute__ ((__format__(printf, 1, 2)))
void error_s(const char* format, ...);
__attribute__ ((__format__(printf, 1, 2)))
void error(const char* format, ...);
__attribute__ ((__format__(printf, 1, 2)))
void output(const char* format, ...);
#endif

63
lib/file.c Normal file
View file

@ -0,0 +1,63 @@
#include "file.h"
#include "error.h"
#include "convert.h"
#include <paths.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
FILE* get_file_s(const char* path, const char* type) {
struct stat s;
FILE* file;
if (streql("-", path) && type[0] == 'r') {
clearerr(stdin);
fflush(stdin);
return stdin;
}
if (lstat(path, &s) < 0) {
if (type[0] != 'r') goto read;
error_s("failed to read %s: %s", path, strerror(errno));
return NULL;
}
if (S_ISDIR(s.st_mode)) {
error_s("%s is a directory", path);
return NULL;
}
read:
file = fopen(path, type);
if (file == NULL) {
error_s("failed to %s file %s: %s", type[0] == 'r' ? "read" : "write", path, strerror(errno));
}
return file;
}
FILE* get_file(const char* path, const char* type) {
FILE* file = get_file_s(path, type);
if (file == NULL) exit(EXIT_FAILURE);
return file;
}
int get_tty (void) {
int fd = open(_PATH_TTY, O_RDONLY);
if (fd < 0) error("failed to get tty: %s", strerror(errno));
return fd;
}
FILE* get_tty_stream(char* type) {
int fd = get_tty();
FILE* file = fdopen(fd, type);
if (file == NULL) {
error("failed to open tty stream: %s", strerror(errno));
}
return file;
}

14
lib/file.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef FILE_H
#define FILE_H
#include <stdio.h>
FILE* get_file_s(const char* path, const char* type);
FILE* get_file(const char* path, const char* type);
int get_tty(void);
FILE* get_tty_stream(char* type);
#endif

16
lib/lslib.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef SHARED_H
#define SHARED_H
#include <stdint.h>
#include <stdio.h>
#include "args.h"
#include "buffer.h"
#include "def.h"
#include "convert.h"
#include "error.h"
#include "file.h"
#include "regex.h"
#include "stack.h"
#endif

View file

@ -36,16 +36,9 @@
#define RE_DOT_MATCHES_NEWLINE 1 #define RE_DOT_MATCHES_NEWLINE 1
#endif #endif
#ifdef __cplusplus
extern "C"{
#endif
/* Typedef'd pointer to get abstract datatype. */ /* Typedef'd pointer to get abstract datatype. */
typedef struct regex_t* re_t; typedef struct regex_t* re_t;
/* Compile regex string pattern to a regex_t-array. */ /* Compile regex string pattern to a regex_t-array. */
re_t re_compile(const char* pattern); re_t re_compile(const char* pattern);
@ -58,8 +51,4 @@ int re_matchp(re_t pattern, const char* text, int* matchlength);
int re_match(const char* pattern, const char* text, int* matchlength); int re_match(const char* pattern, const char* text, int* matchlength);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _TINY_REGEX_C */ #endif /* ifndef _TINY_REGEX_C */

View file

@ -1,7 +1,7 @@
#ifndef STACK_H #ifndef STACK_H
#define STACK_H #define STACK_H
#include "shared.h" #include "def.h"
#include <stddef.h> #include <stddef.h>

View file

@ -1,32 +1,17 @@
#ifndef COMMAND_H #ifndef COMMAND_H
#define COMMAND_H #define COMMAND_H
#include "util/shared.h"
#include "util/stack.h"
#include "util/regex.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#define ARGUMENTS int argc, char** argv #define ARGUMENTS int argc, char** argv
#define NEXT_ARGS argc - 1, &argv[1] #define NEXT_ARGS argc - 1, &argv[1]
#define COMMAND(name) int name (ARGUMENTS) #define COMMAND(name) int name (ARGUMENTS)
#define COMMAND_EMPTY(name) int name (void)
COMMAND(dd); COMMAND(dd);
COMMAND(cat); COMMAND(cat);
COMMAND(yes); COMMAND(yes);
COMMAND(echo); COMMAND(echo);
COMMAND(print); COMMAND(print);
COMMAND_EMPTY(groups); COMMAND(groups);
COMMAND_EMPTY(user_id); COMMAND(user_id);
COMMAND(ls); COMMAND(ls);
COMMAND(tail); COMMAND(tail);
COMMAND(head); COMMAND(head);

View file

@ -1,12 +1,8 @@
#include "util/shared.h"
#include "command.h" #include "command.h"
#include "lslib.h"
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
char* cmd; char* cmd;
@ -51,9 +47,9 @@ int main (ARGUMENTS) {
} else if (streql(cmd, "printf")) { } else if (streql(cmd, "printf")) {
return print(NEXT_ARGS); return print(NEXT_ARGS);
} else if (streql(cmd, "groups")) { } else if (streql(cmd, "groups")) {
return groups(); return groups(NEXT_ARGS);
} else if (streql(cmd, "id")) { } else if (streql(cmd, "id")) {
return user_id(); return user_id(NEXT_ARGS);
} else if (streql(cmd, "ls") || streql(cmd, "dir")) { } else if (streql(cmd, "ls") || streql(cmd, "dir")) {
return ls(NEXT_ARGS); return ls(NEXT_ARGS);
} else if (streql(cmd, "lsd")) { } else if (streql(cmd, "lsd")) {

View file

@ -1,372 +0,0 @@
#include "shared.h"
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <paths.h>
extern char* cmd;
void error_s(const char *format, ...) {
va_list list;
va_start(list, format);
fprintf(stderr, "%s: ", cmd);
vfprintf(stderr, format, list);
fprintf(stderr, "\n");
}
void error(const char *format, ...) {
va_list list;
va_start(list, format);
fprintf(stderr, "%s: ", cmd);
vfprintf(stderr, format, list);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
void output(const char *format, ...) {
va_list list;
va_start(list, format);
fprintf(stdout, "%s: ", cmd);
vfprintf(stdout, format, list);
fprintf(stdout, "\n");
}
FILE* get_file_s(const char* path, const char* type) {
struct stat s;
FILE* file;
if (streql("-", path) && type[0] == 'r') {
clearerr(stdin);
fflush(stdin);
return stdin;
}
if (lstat(path, &s) < 0) {
if (type[0] != 'r') goto read;
error_s("failed to read %s: %s", path, strerror(errno));
return NULL;
}
if (S_ISDIR(s.st_mode)) {
error_s("%s is a directory", path);
return NULL;
}
read:
file = fopen(path, type);
if (file == NULL) {
error_s("failed to %s file %s: %s", type[0] == 'r' ? "read" : "write", path, strerror(errno));
}
return file;
}
FILE* get_file(const char* path, const char* type) {
FILE* file = get_file_s(path, type);
if (file == NULL) exit(EXIT_FAILURE);
return file;
}
long int get_number(const char* text) {
char* end;
long int n = strtol(text, &end, 10);
if (text == end) {
error("%s is not a valid number", text);
}
return n;
}
long int get_blkm(const char* text) {
char* end;
long int n = strtol(text, &end, 10);
if (text == end) {
error("%s is not a valid bkm", text);
}
if (*end == '\0') return n;
switch (*end) {
case 'K':
case 'k':
return n * 1024;
case 'B':
case 'b':
return n * 512;
case 'M':
case 'm':
return n * 1024 * 1204;
default:
error("invalid bkm type %c", *end);
}
/* shouldnt get here anyways */
return 0;
}
mode_t get_mode(const char* next) {
char* end = NULL;
mode_t mode = (mode_t)strtol(next, &end, 8);
if (!end) return 0;
while(isspace(*end)) end++;
if (*end != '\0' || (unsigned) mode < 010000) {
error("invalid file mode: `%s`", next);
}
return mode;
}
bool streql(const char* a, const char* b) {
int n = 0;
if (*a != *b) return false;
while (true) {
if (*(a+n) != *(b+n)) return false;
if (*(a+n) == '\0') return true;
++n;
}
}
bool prefix(const char* pre, const char* str) {
return strncmp(pre, str, strlen(pre)) == 0;
}
static char fs_types[5] = {'K','M','G','T','P'};
void print_file_size(size_t bytes, char buf[5]) {
int index, n;
float next;
index = 0;
next = bytes;
while (true) {
if (next < 1000) {
break;
}
if (index == 5) {
printf("999P");
return;
}
next /= 1024;
index++;
}
n = snprintf(buf, 4, "%u", (int)(next+.5));
if (index > 0) {
buf[n] = (fs_types[index - 1]);
n++;
}
buf[n] = '\0';
}
static char* months[12] =
{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
void print_date_time(time_t mills, char buf[13]) {
struct tm* info;
int n;
info = localtime(&mills);
n = snprintf(buf, 5, "%s ", months[info->tm_mon]);
if (info->tm_mday < 10) {
buf[n] = ' ';
n++;
}
snprintf(buf + n, 13 - n, "%d %02d:%02d ", info->tm_mday, info->tm_hour, info->tm_sec);
}
void print_file_path(char* path) {
if (streql("-", path)) {
printf("(standard input)");
} else {
printf("%s", path);
}
}
#ifndef MAJOR
#define MAJOR 0
#endif
#ifndef MINOR
#define MINOR 0
#endif
#ifndef PATCH
#define PATCH 0
#endif
void check_arg (char* arg) {
if (arg == NULL) {
error("expected another argument after option");
}
}
void global_help(void (*help)(void)) {
printf("LazySphere v%d.%d.%d multi-call binary.\n\n", MAJOR, MINOR, PATCH);
help();
exit(EXIT_SUCCESS);
}
void parse_help(int argc, char** argv, void (*help)(void)) {
int i;
if (argc < 1) return;
for (i = 0; i < argc; i++) {
if (!prefix("-", argv[i]) || streql("-", argv[i])) break;
if (help != NULL && streql("--help", argv[i])) global_help(help);
}
}
int parse_args(int argc, char** argv, void (*help)(void), int (*short_arg)(char, char*), int (*long_arg)(char*, char*)) {
int start, i, current;
char* next_arg;
if (argc < 1) return 0;
start = 0;
for (i = 0; i < argc; i++) {
if (!prefix("-", argv[i]) || streql("-", argv[i])) break;
if (help != NULL && streql("--help", argv[i])) global_help(help);
if (i + 1 == argc) {
next_arg = NULL;
} else {
next_arg = argv[i+1];
}
current = i;
if (prefix("--", argv[i])) {
int r;
if (long_arg == NULL) {
goto exit;
}
r = long_arg(argv[current], next_arg);
if (r == ARG_USED) {
i++;
start++;
} else if (r == ARG_IGNORE) {
goto exit;
} else if (r == ARG_INVALID) {
error("invalid argument %s", argv[current]);
}
} else {
size_t j;
int r;
if (short_arg == NULL) {
goto exit;
}
for (j = 1; j < strlen(argv[current]); j++) {
r = short_arg(argv[current][j], next_arg);
if (r == ARG_USED) {
i++;
start++;
} else if (r == ARG_IGNORE) {
goto exit;
} else if (r == ARG_INVALID) {
error("invalid argument -%c", argv[current][j]);
}
}
}
start++;
}
exit:
return start;
}
int get_tty (void) {
int fd = open(_PATH_TTY, O_RDONLY);
if (fd < 0) error("failed to get tty: %s", strerror(errno));
return fd;
}
FILE* get_tty_stream(char* type) {
int fd = get_tty();
FILE* file = fdopen(fd, type);
if (file == NULL) {
error("failed to open tty stream: %s", strerror(errno));
}
return file;
}
static int push_path_buffer_b(char* buf, int* index, const char* string) {
int save, string_len;
save = *index;
if (*index > 1 || (*index == 1 && buf[0] != '/')) {
buf[(*index)++] = '/';
}
string_len = strlen(string);
memcpy(buf + *index, string, string_len + 1);
*index += string_len;
return save;
}
static void pop_path_buffer_b(char* buf, int* index, int i) {
*index = i;
buf[*index] = '\0';
}
static char path_buffer[PATH_MAX + 1];
static int path_buffer_index = 0;
char* get_path_buffer(void) {
return path_buffer;
}
int push_path_buffer(const char* string) {
return push_path_buffer_b(path_buffer, &path_buffer_index, string);
}
void pop_path_buffer(int i) {
pop_path_buffer_b(path_buffer, &path_buffer_index, i);
}
static char path_buffer_2[PATH_MAX + 1];
static int path_buffer_index_2 = 0;
char* get_path_buffer_2(void) {
return path_buffer_2;
}
int push_path_buffer_2(const char* string) {
return push_path_buffer_b(path_buffer_2, &path_buffer_index_2, string);
}
void pop_path_buffer_2(int i) {
pop_path_buffer_b(path_buffer_2, &path_buffer_index_2, i);
}
bool is_dot_dir(const char* path) {
return streql(path, ".") || streql(path, "..");
}

View file

@ -1,86 +0,0 @@
#ifndef SHARED_H
#define SHARED_H
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#define ANSCII "\x1b["
#define NEXT ";"
#define RESET "0"
#define BOLD "1"
#define NORMAL "3"
#define BACKGROUND "4"
#define HIGHLIGHT "9"
#define BLACK "0"
#define RED "1"
#define GREEN "2"
#define YELLOW "3"
#define BLUE "4"
#define MAGENTA "5"
#define TURQUOISE "6"
#define WHITE "7"
#define COLOR "m"
typedef uint8_t bool;
#define true 1
#define false 0
enum When {
YES,
NO,
AUTO
};
__attribute__ ((__format__(printf, 1, 2)))
void error_s(const char* format, ...);
__attribute__ ((__format__(printf, 1, 2)))
void error(const char* format, ...);
__attribute__ ((__format__(printf, 1, 2)))
void output(const char* format, ...);
FILE* get_file_s(const char* path, const char* type);
FILE* get_file(const char* path, const char* type);
long int get_number(const char* text);
long int get_blkm(const char* text);
mode_t get_mode(const char* next);
bool streql(const char* a, const char* b);
bool prefix(const char* pre, const char* str);
void print_file_size(size_t bytes, char buf[5]);
void print_date_time(time_t mills, char buf[13]);
void print_file_path(char* path);
#define UNUSED(x) (void)(x)
#define ARG_UNUSED 0
#define ARG_USED 1
#define ARG_IGNORE 2
#define ARG_INVALID 3
void check_arg (char* arg);
void global_help(void (*help)(void));
void parse_help (int argc, char** argv, void (*help)(void));
int parse_args (int argc, char** argv, void (*help)(void), int (*short_arg)(char, char*), int (*long_arg)(char*, char*));
int get_tty(void);
FILE* get_tty_stream(char* type);
char* get_path_buffer(void);
int push_path_buffer(const char* string);
void pop_path_buffer(int i);
char* get_path_buffer_2(void);
int push_path_buffer_2(const char* string);
void pop_path_buffer_2(int i);
bool is_dot_dir(const char* path);
#endif