Skip to content

Commit

Permalink
librc-user.c: new library api
Browse files Browse the repository at this point in the history
Adds a set of apis to manipulate user options.

Signed-off-by: Anna (navi) Figueiredo Gomes <[email protected]>
  • Loading branch information
navi-desu committed May 24, 2024
1 parent 1e004f7 commit 49bd7f0
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 49 deletions.
8 changes: 8 additions & 0 deletions src/librc/librc-depend.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,14 @@ rc_deptree_update_needed(time_t *newest, char *file)
free(dir);
}

/* Users directory is system-wide only */
if (!rc_is_user()) {
xasprintf(&dir, "%s/users", service_dir);
if (mkdir(dir, 0755) != 0 && errno != EEXIST)
fprintf(stderr, "mkdir '%s': %s\n", dir, strerror(errno));
free(dir);
}

/* Quick test to see if anything we use has changed and we have
* data in our deptree. */
xasprintf(&deptree_cache, "%s/%s", service_dir, RC_DEPTREE_CACHE);
Expand Down
60 changes: 60 additions & 0 deletions src/librc/librc-user.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <stdlib.h>

#include "librc.h"
#include "einfo.h"

RC_STRINGLIST *
rc_users_list(void)
{
if (rc_is_user())
return rc_stringlist_new();
return ls_dir(RC_SVCDIR "/users", 0);
}

char *
rc_user_value_get(const char *user, const char *option)
{
char *file, *buffer = NULL;
size_t len;

if (rc_is_user())
return NULL;

xasprintf(&file, "%s/users/%s/%s", rc_service_dir(), user, option);
rc_getfile(file, &buffer, &len);
free(file);

return buffer;
}

bool
rc_user_value_set(const char *user, const char *option, const char *value)
{
char *dir, *file;
FILE *fp;

if (rc_is_user())
return false;

xasprintf(&dir, "%s/users/%s", rc_service_dir(), user);
if (mkdir(file, 0755) != 0 && errno != EEXIST) {
free(dir);
return false;
}

xasprintf(&file, "%s/%s", dir, option);
free(dir);

if (!value) {
unlink(file);
} else if ((fp = fopen(file, "w"))) {
fprintf(fp, "%s", value);
fclose(fp);
} else {
free(file);
return false;
}

free(file);
return true;
}
49 changes: 0 additions & 49 deletions src/librc/librc.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,55 +68,6 @@ static const rc_service_state_name_t rc_service_state_names[] = {
{ 0, NULL}
};

#define LS_INITD 0x01
#define LS_DIR 0x02
static RC_STRINGLIST *
ls_dir(const char *dir, int options)
{
DIR *dp;
struct dirent *d;
RC_STRINGLIST *list = NULL;
struct stat buf;
size_t l;
char file[PATH_MAX];
int r;

list = rc_stringlist_new();
if ((dp = opendir(dir)) == NULL)
return list;
while (((d = readdir(dp)) != NULL)) {
if (d->d_name[0] != '.') {
if (options & LS_INITD) {
/* Check that our file really exists.
* This is important as a service maybe in a
* runlevel, but could have been removed. */
snprintf(file, sizeof(file), "%s/%s",
dir, d->d_name);
r = stat(file, &buf);
if (r != 0)
continue;

/* .sh files are not init scripts */
l = strlen(d->d_name);
if (l > 2 && d->d_name[l - 3] == '.' &&
d->d_name[l - 2] == 's' &&
d->d_name[l - 1] == 'h')
continue;
}
if (options & LS_DIR) {
snprintf(file, sizeof(file), "%s/%s",
dir, d->d_name);
if (stat(file, &buf) != 0 ||
!S_ISDIR(buf.st_mode))
continue;
}
rc_stringlist_add(list, d->d_name);
}
}
closedir(dp);
return list;
}

static bool
rm_dir(const char *pathname, bool top)
{
Expand Down
3 changes: 3 additions & 0 deletions src/librc/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ librc_sources = [
'librc.c',
'librc-daemon.c',
'librc-depend.c',
'librc-user.c',
'librc-misc.c',
'librc-stringlist.c',
misc_c,
version_h
]

rc_h = configure_file(input : 'rc.h.in', output : 'rc.h',
Expand Down
5 changes: 5 additions & 0 deletions src/librc/rc.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ typedef TAILQ_HEAD(rc_stringlist, rc_string) RC_STRINGLIST;
void rc_set_user(void);
bool rc_is_user(void);

char *rc_user_value_get(const char *, const char *);
bool rc_user_value_set(const char *, const char *, const char *);

RC_STRINGLIST *rc_users_list(void);

/*! Return the current runlevel.
* @return the current runlevel */
char *rc_runlevel_get(void);
Expand Down
48 changes: 48 additions & 0 deletions src/shared/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#endif

#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
Expand Down Expand Up @@ -526,6 +527,53 @@ pid_t get_pid(const char *applet,const char *pidfile)
return pid;
}

RC_STRINGLIST *
ls_dir(const char *dir, int options)
{
DIR *dp;
struct dirent *d;
RC_STRINGLIST *list = NULL;
struct stat buf;
size_t l;
char file[PATH_MAX];
int r;

list = rc_stringlist_new();
if ((dp = opendir(dir)) == NULL)
return list;
while (((d = readdir(dp)) != NULL)) {
if (d->d_name[0] != '.') {
if (options & LS_INITD) {
/* Check that our file really exists.
* This is important as a service maybe in a
* runlevel, but could have been removed. */
snprintf(file, sizeof(file), "%s/%s",
dir, d->d_name);
r = stat(file, &buf);
if (r != 0)
continue;

/* .sh files are not init scripts */
l = strlen(d->d_name);
if (l > 2 && d->d_name[l - 3] == '.' &&
d->d_name[l - 2] == 's' &&
d->d_name[l - 1] == 'h')
continue;
}
if (options & LS_DIR) {
snprintf(file, sizeof(file), "%s/%s",
dir, d->d_name);
if (stat(file, &buf) != 0 ||
!S_ISDIR(buf.st_mode))
continue;
}
rc_stringlist_add(list, d->d_name);
}
}
closedir(dp);
return list;
}

#ifndef HAVE_CLOSE_RANGE
static inline int close_range(int first RC_UNUSED,
int last RC_UNUSED,
Expand Down
4 changes: 4 additions & 0 deletions src/shared/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ int is_writable(const char *);
#define service_start(service) exec_service(service, "start");
#define service_stop(service) exec_service(service, "stop");

#define LS_INITD 0x01
#define LS_DIR 0x02

int parse_mode(mode_t *, char *);

/* Handy function so we can wrap einfo around our deptree */
Expand All @@ -67,6 +70,7 @@ RC_SERVICE lookup_service_state(const char *service);
void from_time_t(char *time_string, time_t tv);
time_t to_time_t(char *timestring);
pid_t get_pid(const char *applet, const char *pidfile);
RC_STRINGLIST *ls_dir(const char *dir, int options);

void cloexec_fds_from(int);

Expand Down

0 comments on commit 49bd7f0

Please sign in to comment.