Skip to content

Commit

Permalink
chore: reorganize struct defs
Browse files Browse the repository at this point in the history
  • Loading branch information
exbotanical committed Oct 20, 2023
1 parent 107ef9f commit a4ffd48
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 92 deletions.
27 changes: 26 additions & 1 deletion src/fs.c → src/crontab.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
#include "fs.h"
#include "crontab.h"

#include <dirent.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#include "defs.h"
#include "job.h"
#include "log.h"
#include "parser.h"
#include "utils.h"

/*
* Because crontab/at files may be owned by their respective users we
* take extreme care in opening them. If the OS lacks the O_NOFOLLOW
* we will just have to live without it. In order for this to be an
* issue an attacker would have to subvert group CRON_GROUP.
* TODO: comment
*/
#ifndef O_NOFOLLOW
#define O_NOFOLLOW 0
#endif

#define ALL_PERMS 07777
#define OWNER_RW_PERMS 0600

#define MAXENTRIES 256
#define RW_BUFFER 1024

array_t* get_filenames(char* dpath) {
DIR* dir;

Expand Down
17 changes: 16 additions & 1 deletion src/fs.h → src/crontab.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
#ifndef FS_H
#define FS_H

#include "defs.h"
#include <stdbool.h>
#include <time.h>

#include "libhash/libhash.h"
#include "libutil/libutil.h"

// TODO: check dir mtime as well?
typedef struct {
char *name;
bool is_root;
} DirConfig;

typedef struct {
array_t *jobs;
time_t mtime;
} Crontab;

array_t *get_filenames(char *dpath);
Crontab *new_crontab(int crontab_fd, bool is_root, time_t curr_time,
Expand Down
8 changes: 7 additions & 1 deletion src/daemon.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
#include "defs.h"
#include "daemon.h"

#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>

#define DEV_NULL_DEVICE "/dev/null"
#define TERMINAL_DEVICE "/dev/tty"
Expand Down
2 changes: 1 addition & 1 deletion src/daemon.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef DAEMON_H
#define DAEMON_H

#include "defs.h"
#include "utils.h"

RETVAL daemonize();

Expand Down
70 changes: 0 additions & 70 deletions src/defs.h
Original file line number Diff line number Diff line change
@@ -1,89 +1,19 @@
#ifndef DEFS_H
#define DEFS_H

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pcre.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include "ccronexpr/ccronexpr.h"
#include "libhash/libhash.h"
#include "libutil/libutil.h"

#define X(e) [e] = #e

#ifndef SYS_CRONTABS_DIR
#define SYS_CRONTABS_DIR "/etc/cron.d"
#endif
#ifndef CRONTABS_DIR
#define CRONTABS_DIR "/var/spool/cron/crontabs"
#endif

/*
* Because crontab/at files may be owned by their respective users we
* take extreme care in opening them. If the OS lacks the O_NOFOLLOW
* we will just have to live without it. In order for this to be an
* issue an attacker would have to subvert group CRON_GROUP.
*/
#ifndef O_NOFOLLOW
#define O_NOFOLLOW 0
#endif

#define ALL_PERMS 07777
#define OWNER_RW_PERMS 0600

#define ROOT_USER "root"
#define ROOT_UID 0

#define MAXENTRIES 256
#define RW_BUFFER 1024
// Basically whether we support seconds (7)
#define SPACES_BEFORE_CMD 5

typedef enum {
PENDING,
RUNNING,
EXITED,
} JobStatus;

typedef enum { OK, ERR } RETVAL;

typedef struct {
cron_expr *expr;
char *schedule;
char *cmd;
char *owner_uname;
time_t next;
pid_t pid;
JobStatus status;
int ret;
unsigned int id;
} Job;

typedef struct {
array_t *jobs;
time_t mtime;
} Crontab;

// TODO: check dir mtime as well?
typedef struct {
char *name;
bool is_root;
} DirConfig;

extern const char *job_status_names[];
extern array_t *job_queue;

Expand Down
5 changes: 5 additions & 0 deletions src/job.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include "job.h"

#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

#include "defs.h"
#include "libutil/libutil.h"
#include "log.h"
#include "parser.h"
#include "utils.h"
Expand Down
22 changes: 21 additions & 1 deletion src/job.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
#ifndef JOB_H
#define JOB_H

#include "defs.h"
#include <time.h>

#include "ccronexpr/ccronexpr.h"

typedef enum {
PENDING,
RUNNING,
EXITED,
} JobStatus;

typedef struct {
cron_expr *expr;
char *schedule;
char *cmd;
char *owner_uname;
time_t next;
pid_t pid;
JobStatus status;
int ret;
unsigned int id;
} Job;

Job *new_job(char *raw, time_t curr, char *uname);

Expand Down
7 changes: 6 additions & 1 deletion src/log.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include "log.h"

#include "defs.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "libutil/libutil.h"

#define LOG_BUFFER 2048
#define TIMESTAMP_FMT "%Y-%m-%d %H:%M:%S"
Expand Down
7 changes: 5 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#define _POSIX_C_SOURCE 199309L

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "crontab.h"
#include "daemon.h"
#include "defs.h"
#include "fs.h"
#include "job.h"
#include "log.h"
#include "utils.h"
Expand All @@ -13,7 +17,6 @@ extern pid_t daemon_pid;
pid_t daemon_pid;

const char* job_status_names[] = {X(PENDING), X(RUNNING), X(EXITED)};

// Desired interval in seconds between loop iterations
const short loop_interval = 60;

Expand Down
9 changes: 8 additions & 1 deletion src/parser.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#include "parser.h"

#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#include "defs.h"
#include "libutil/libutil.h"
#include "log.h"

// Basically whether we support seconds (7)
#define SPACES_BEFORE_CMD 5

// TODO: static fns
char* until_nth_of_char(const char* str, char c, int n) {
int count = 0;
Expand Down
5 changes: 4 additions & 1 deletion src/parser.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#ifndef PARSER_H
#define PARSER_H

#include "defs.h"
#include <stdbool.h>

#include "job.h"
#include "utils.h"

void strip_comment(char *str);
char *until_nth_of_char(const char *str, char c, int n);
Expand Down
3 changes: 2 additions & 1 deletion src/utils.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include <stdlib.h>
#include <uuid/uuid.h>

#include "defs.h"
#include "libutil/libutil.h"
#include "log.h"

void* xmalloc(size_t sz) {
void* ptr;
Expand Down
4 changes: 4 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

#include <time.h>

#define X(e) [e] = #e

typedef enum { OK, ERR } RETVAL;

/**
* xmalloc is a malloc wrapper that exits the program if out of memory
*/
Expand Down
24 changes: 13 additions & 11 deletions t/unit/fs_test.c → t/unit/crontab_test.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#include "fs.h"
#include "crontab.h"

#include "defs.h"
#include <fcntl.h>
#include <string.h>

#include "job.h"
#include "tap.c/tap.h"
#include "tests.h"
#include "utils.h"

static char* setup_test_directory() {
char template[] = "/tmp/tap_test_dir.XXXXXX";
Expand Down Expand Up @@ -60,9 +64,7 @@ static void cleanup_test_file(char* dirname, char* fname) {
}

// TODO: close?
static int get_fd(char* fpath) {
return open(fpath, O_RDONLY | O_NONBLOCK | O_NOFOLLOW, 0);
}
static int get_fd(char* fpath) { return open(fpath, O_RDONLY | O_NONBLOCK, 0); }

static void validate_job(Job* job, Job* expected) {
is(expected->cmd, job->cmd, "Expect cmd '%s'", expected->cmd);
Expand Down Expand Up @@ -149,9 +151,9 @@ void test_scan_crontabs() {

ok(db->count == 3, "Two crontab files should have been processed");

Crontab* ct1 = ht_get(db, "user1");
Crontab* ct2 = ht_get(db, "user2");
Crontab* ct3 = ht_get(db, "user3");
Crontab* ct1 = (Crontab*)ht_get(db, "user1");
Crontab* ct2 = (Crontab*)ht_get(db, "user2");
Crontab* ct3 = (Crontab*)ht_get(db, "user3");

ok(ct1 != NULL, "user1's crontab should exist in the database");
ok(ct2 != NULL, "user2's crontab should exist in the database");
Expand All @@ -171,9 +173,9 @@ void test_scan_crontabs() {
modify_test_file(usr_dirname, "user3", "* * * * * echo 'sup dud'\n");
scan_crontabs(db, usr_dir, now);

ct1 = ht_get(db, "user1");
ct2 = ht_get(db, "user2");
ct3 = ht_get(db, "user3");
ct1 = (Crontab*)ht_get(db, "user1");
ct2 = (Crontab*)ht_get(db, "user2");
ct3 = (Crontab*)ht_get(db, "user3");

ok(ct1 != NULL, "user1's crontab should exist in the database");
ok(ct2 == NULL, "user2's crontab was deleted from the database");
Expand Down
File renamed without changes.

0 comments on commit a4ffd48

Please sign in to comment.