#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
static char *files[5];
__attribute__((nonnull, access(write_only, 1)))
static bool getInt(size_t *n)
{
return 1 == scanf("%lu", n);
}
__attribute__((nonnull, access(write_only, 1)))
static bool getIndex(size_t *n)
{
const size_t count = sizeof(files) / sizeof(*files);
size_t index;
printf("index: ");
if(!getInt(&index)) {
fprintf(stderr, "Could not read index\n");
return false;
}
if(index >= count) {
fprintf(stderr, "Index out of bounds\n");
return false;
}
*n = index;
return true;
}
static void menu(void)
{
puts("1. prepare a file");
puts("2. clean a file");
puts("3. handle a file");
puts("4. leave");
printf("> ");
}
static void prepare(void)
{
size_t index;
if(!getIndex(&index))
return;
size_t size;
printf("size: ");
if(!getInt(&size)) {
fprintf(stderr, "Could not read size\n");
return;
}
char *buffer = malloc(size + 1);
if(NULL == buffer) {
perror("malloc");
return;
}
memset(buffer, 0, size + 1);
fgetc(stdin);
printf("file name: ");
if(NULL == fgets(buffer, size + 1, stdin)) {
perror("fgets");
free(buffer);
return;
}
buffer[strcspn(buffer, "\n")] = 0;
files[index] = buffer;
}
static void clean(void)
{
size_t index;
if(!getIndex(&index))
return;
free(files[index]);
}
static void handle(void)
{
size_t index;
if(!getIndex(&index))
return;
static const char *const modes[] = {
"r",
"r+",
"a"
};
printf("Mode:\n");
puts("1. read-only");
puts("2. read + write");
puts("3. read + write + create + append");
size_t mode;
if(!getInt(&mode))
return;
FILE *fp = fopen(files[index], modes[mode - 1]);
if(NULL == fp)
return perror("fopen");
if(0 != fclose(fp))
return perror("fclose");
puts("Permission check passed!");
}
int main(void)
{
if(NULL == getenv("LD_BIND_NOW")) {
fprintf(stderr, "LD_BIND_NOW is not set!\n");
return EXIT_FAILURE;
}
setbuf(stdout, NULL);
while(1) {
menu();
size_t choice;
if(!getInt(&choice)) {
fprintf(stderr, "Error: could not read integer\n");
return EXIT_FAILURE;
}
choice--;
static void (*const f[])(void) = {
prepare,
clean,
handle,
};
const size_t count = sizeof(f) / sizeof(*f);
if(count == choice)
return EXIT_SUCCESS;
if(choice < count)
f[choice]();
}
}