summaryrefslogtreecommitdiff
path: root/src/util/shared.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/shared.c')
-rw-r--r--src/util/shared.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/util/shared.c b/src/util/shared.c
new file mode 100644
index 0000000..c5c22e9
--- /dev/null
+++ b/src/util/shared.c
@@ -0,0 +1,134 @@
+#include "shared.h"
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/stat.h>
+
+void error(const char* format, ...) {
+ va_list list;
+ va_start(list, format);
+
+ vfprintf(stderr, format, list);
+ fprintf(stderr, "\n");
+ exit(EXIT_FAILURE);
+}
+
+FILE* get_file_s(const char* path, const char* type) {
+ struct stat s;
+ if (lstat(path, &s) < 0) {
+ if (type[0] != 'r') goto read;
+ fprintf(stderr, "error: failed to read %s: %s\n", path, strerror(errno));
+ return NULL;
+ }
+ if (S_ISDIR(s.st_mode)) {
+ fprintf(stderr, "error: %s is a directory\n", path);
+ return NULL;
+ }
+
+ FILE* file;
+read:
+ file = fopen(path, type);
+ if (file == NULL) {
+ fprintf(stderr, "error: failed to open file %s: %s\n", path, strerror(errno));
+ }
+ return file;
+}
+
+FILE* get_file(const char* path, const char* type) {
+ if (streql("-", path) && type[0] == 'r') {
+ clearerr(stdin);
+ return stdin;
+ }
+ 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("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("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("error: invalid bkm type %c", *end);
+ }
+ // shouldnt get here anyways
+ return 0;
+}
+
+bool streql(const char* a, const char* b) {
+ if (*a != *b) return false;
+ int n = 0;
+ 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 = 0;
+ float next = bytes;
+ while (true) {
+ if (next < 1000) {
+ break;
+ }
+ if (index == 5) {
+ printf("999P");
+ return;
+ };
+ next /= 1024;
+ index++;
+ }
+
+ int 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;
+ info = localtime(&mills);
+ int 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);
+}