refactor
This commit is contained in:
parent
b1364be7e2
commit
d8f2c10b71
44 changed files with 697 additions and 549 deletions
19
.clangd
19
.clangd
|
@ -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
|
|
8
Makefile
8
Makefile
|
@ -1,12 +1,14 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
|
|
||||||
SOURCE = src
|
SOURCE = src
|
||||||
|
SOURCE += lib
|
||||||
|
SOURCE += command
|
||||||
|
|
||||||
MAJOR = 0
|
MAJOR = 0
|
||||||
MINOR = 0
|
MINOR = 0
|
||||||
PATCH = 1
|
PATCH = 1
|
||||||
|
|
||||||
INCFLAGS = $(shell echo $(SOURCE) | xargs printf -- '-I%s')
|
INCFLAGS = $(shell echo $(SOURCE) | xargs printf -- '-I%s ')
|
||||||
|
|
||||||
CCFLAGS = -std=c89 -Wall -Wextra -pedantic -O2
|
CCFLAGS = -std=c89 -Wall -Wextra -pedantic -O2
|
||||||
CCFLAGS += -D_DEFAULT_SOURCE -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH) -DCHECK_LINK
|
CCFLAGS += -D_DEFAULT_SOURCE -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH) -DCHECK_LINK
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
@ -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>
|
||||||
|
|
|
@ -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");
|
|
@ -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;
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
@ -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);
|
|
@ -1,4 +1,7 @@
|
||||||
#include "../command.h"
|
#include "command.h"
|
||||||
|
#include "lslib.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
int count;
|
int count;
|
|
@ -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);
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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 {
|
|
@ -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");
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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");
|
|
@ -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;
|
|
@ -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
15
compile_flags.txt
Normal 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
111
lib/args.c
Normal 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
18
lib/args.h
Normal 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
60
lib/buffer.c
Normal 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
16
lib/buffer.h
Normal 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
126
lib/convert.c
Normal 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
20
lib/convert.h
Normal 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
31
lib/def.h
Normal 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
35
lib/error.c
Normal 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
13
lib/error.h
Normal 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
63
lib/file.c
Normal 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
14
lib/file.h
Normal 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
16
lib/lslib.h
Normal 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
|
|
@ -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 */
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
10
src/main.c
10
src/main.c
|
@ -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")) {
|
||||||
|
|
|
@ -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, "..");
|
|
||||||
}
|
|
|
@ -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
|
|
Loading…
Reference in a new issue