-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmute.c
269 lines (224 loc) · 5.84 KB
/
mute.c
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
_
_ __ ___ _ _| |_ ___ ___
| '_ ` _ \| | | | __/ _ \ / __|
| | | | | | |_| | || __/| (__
|_| |_| |_|\__,_|\__\___(_)___|
*/
/* includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
/* defines */
/* this seems to be about right on OS X, Pi reckons bigger */
#define MAX_CMD_SIZE 262144
#define USAGE (0)
#define ARMED (1)
/* YYYYMMDD plus null terminator = 9 */
#define COPYSIZE (size_t)(9)
/* Let's get boolean */
#define TRUE (0 == 0)
#define FALSE (!(TRUE))
/* helper functions */
int getdatenow(char *destbuf, size_t destbufsz)
{
time_t t_now;
struct tm *locnow;
int rv;
t_now = time(NULL);
if(t_now == (time_t)-1) {
fprintf(stderr, "Can't get current time\n");
exit(EXIT_FAILURE);
}
locnow = localtime(&t_now);
if(locnow == NULL) {
fprintf(stderr, "Local time conversion failed\n");
exit(EXIT_FAILURE);
}
rv = strftime(destbuf, destbufsz, "%Y%m%d", locnow);
if(!rv) {
fprintf(stderr, "Local time formatting failed\n");
exit(EXIT_FAILURE);
} else {
return(0);
}
}
int getparameterfilename(char *p_buf, const char *fname)
{
int rv = 0;
char *homedir = getenv("HOME");
int fnamlen = strlen(fname) + 1; // allow for extra path separator
if(homedir != NULL) { //environment method
if(!p_buf) {
rv = strlen(homedir) + fnamlen;
} else {
rv = EXIT_SUCCESS;
strcpy(p_buf, homedir);
strcat(p_buf, "/");
strcat(p_buf, fname);
}
} else { //fallback PW method
uid_t useruid = getuid();
struct passwd *pw = getpwuid(useruid);
if(pw == NULL) {
fprintf(stderr, "Couldn't get home directory from userid\n");
exit(EXIT_FAILURE);
}
if(!p_buf) {
rv = strlen((pw->pw_dir) + fnamlen);
} else {
rv = EXIT_SUCCESS;
strcpy(p_buf, pw->pw_dir);
strcat(p_buf, "/");
strcat(p_buf, fname);
}
}
return(rv);
}
int validate_date(char *pdate)
{
int rv = FALSE;
int dd, mm, yy;
int slen = 0;
slen = strlen(pdate);
if(9 != slen) {
return(FALSE);
}
// now we know we have 8 characters plus '\n', so sscanf should be safe
sscanf(pdate, "%4d%2d%2d", &yy, &mm, &dd); //gak
struct tm input = {
.tm_mday = dd,
.tm_mon = mm - 1,
.tm_year = yy - 1900,
};
time_t t = mktime (&input);
struct tm *output = localtime(&t);
rv = TRUE;
rv = rv && (yy == (output->tm_year + 1900));
rv = rv && (mm == (output->tm_mon + 1));
rv = rv && (dd == (output->tm_mday));
return(rv);
}
int getmutedatefromfile(char *destbuf, size_t destbfsz)
{
/* read out of file system file */
/* beware rather non-portable specification of file name */
FILE *fmutefile;
char *fline = NULL;
const char *mfile = ".muterc";
char actualfname[512];
size_t linelen = 0;
int rv = EXIT_FAILURE;
if(destbfsz < COPYSIZE) {
fprintf(stderr, "Copy buffer size too small: %zu specified, %zu needed\n", destbfsz, COPYSIZE);
exit(EXIT_FAILURE);
}
if(getparameterfilename(NULL, mfile) > 512) {
fprintf(stderr, "Parameter file size is likely insane!\n");
exit(EXIT_FAILURE);
}
rv = getparameterfilename((char *)actualfname, mfile);
if(rv == EXIT_FAILURE) {
fprintf(stderr, "Failed getting param file name for %s\n", mfile);
exit(EXIT_FAILURE);
}
fmutefile = fopen(actualfname, "r");
if (NULL == fmutefile) {
fprintf(stderr, "Couldn't open %s for reading\n", actualfname);
exit(EXIT_FAILURE);
}
linelen = getline(&fline, &linelen, fmutefile);
fclose(fmutefile);
if(TRUE == validate_date(fline)) {
strncpy(destbuf, fline, COPYSIZE);
destbuf[COPYSIZE-1] = '\0'; /* strncpy does not promise to null-terminate */
rv = EXIT_SUCCESS;
} else {
fprintf(stderr, "%s contains invalid date specification ]%s[\n", mfile, fline);
rv = EXIT_FAILURE;
}
if(fline) {
free(fline);
}
return(rv);
}
int buildandruncmd(int argc, char *argv[])
{
int argptr = 0, curcmdlen = 0, slen = 0, rv = 0;
char newclistring[MAX_CMD_SIZE];
newclistring[0] = '\0';
for (argptr = 1; argptr < argc; argptr++) {
slen = strlen(argv[argptr]);
if((curcmdlen + slen) > MAX_CMD_SIZE) {
fprintf(stderr, "Command line too long!\n");
exit(EXIT_FAILURE);
}
strcat(newclistring, argv[argptr]);
strncat(newclistring, " ", 1);
curcmdlen += slen;
}
printf("About to exec ]%s[\n", newclistring);
rv = system(newclistring);
return(rv);
}
int notmuted(int p_status)
{
char datenow[20], datemute[20], paramfile[512];
int rv, cmpv;
rv = getparameterfilename(paramfile, ".muterc");
if(EXIT_FAILURE == rv) {
fprintf(stderr, "Couldn't get parameter file name");
exit(EXIT_FAILURE);
}
if(p_status == USAGE)
printf("Using parameter file: %s\n", paramfile);
getdatenow(datenow, sizeof(datenow));
if(p_status == USAGE)
printf("Date now: %s\n", datenow);
rv = getmutedatefromfile(datemute, sizeof(datemute));
if((p_status == USAGE) && (EXIT_SUCCESS == rv))
printf("Mute Date: %s\n", datemute);
else
exit(EXIT_FAILURE);
cmpv = strncmp(datenow, datemute, 8);
return(cmpv >= 0);
}
/* standard processing - do we mute or not? */
int process(int p_argc, char *p_argv[])
{
int rv = 0, cmpv = -1;
cmpv = notmuted(ARMED);
if(cmpv)
rv = buildandruncmd(p_argc, p_argv);
else
rv = EXIT_SUCCESS; // muted - mute date greater than today so do nothing
return(rv);
}
/* helptext */
int helptext(void)
{
int rv;
rv = notmuted(USAGE);
if(rv)
printf("Actions currently active\n");
else
printf("Actions currently muted\n");
// printf("%d\n", rv);
return(EXIT_SUCCESS);
}
/* main */
int main(int argc, char *argv[])
{
/* so, what is argc? */
int rv;
if(argc == 1) {
rv = helptext();
} else {
rv = process(argc, argv);
}
return(rv);
}