1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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);
}
|