feat: add users and sessions discovery

- also add clangd multi-file intellisense
This commit is contained in:
2024-07-10 23:24:51 +02:00
parent 4d8faa5b5f
commit 07d2842be0
11 changed files with 272 additions and 3 deletions

View File

@@ -1,3 +1,23 @@
#include <pwd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sessions.h>
#include <users.h>
int main() {
return 2;
struct users_list *users = get_human_users();
struct sessions_list *sessions = get_avaliable_sessions();
printf("users(%hu) sessions(%hu)\n", users->length, sessions->length);
for (uint i = 0; i < users->length; i++)
printf("u[%d]: %s %s\n", i, users->users[i].username,
users->users[i].display_name);
for (uint i = 0; i < sessions->length; i++)
printf("s[%d]: %s %s\n", i, sessions->sessions[i].name,
sessions->sessions[i].path);
return 0;
}

97
src/sessions.c Normal file
View File

@@ -0,0 +1,97 @@
#include <ftw.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sessions.h>
#include <util.h>
static const char *sources[] = {"/usr/share/xsessions",
"/usr/share/wayland-sessions"};
static const size_t sources_size = sizeof(sources) / sizeof(sources[0]);
static struct session __new_session(char *name, const char *path) {
struct session __session;
strcln(&__session.name, name);
strcln(&__session.path, path);
return __session;
}
static const u_int8_t bs = 16;
static const u_int8_t unit_size = sizeof(struct session);
static u_int16_t alloc_size = bs;
static u_int16_t used_size = 0;
static struct session *sessions = NULL;
static struct sessions_list *__sessions_list = NULL;
static int fn(const char *fpath, const struct stat *sb, int typeflag) {
// practically impossible to reach this
// but will prevent break
if (used_size == 0xffff)
return 0;
if (!S_ISREG(sb->st_mode))
return 0;
FILE *fd = fopen(fpath, "r");
if (fd == NULL) {
fprintf(stderr, "error opening file (r) %s", fpath);
return 0;
}
bool found = false;
size_t alloc_size = sb->st_blksize;
char *buf = malloc(sb->st_blksize);
while (true) {
buf = realloc(buf, sb->st_blksize);
ssize_t read_size = getline(&buf, &alloc_size, fd);
if (read_size == -1)
break;
uint read;
if ((read = sscanf(buf, "Name=%s\n", buf)) != 0) {
found = true;
buf = realloc(buf, read);
break;
}
}
// just add this to the list
if (found) {
if (used_size >= alloc_size) {
alloc_size += bs;
sessions = realloc(sessions, alloc_size * unit_size);
}
sessions[used_size] = __new_session(buf, fpath);
used_size++;
}
free(buf);
return 0;
}
static struct sessions_list __list;
// This code is designed to be run purely sinlge threaded
struct sessions_list *get_avaliable_sessions() {
if (sessions != NULL)
return __sessions_list;
else
sessions = malloc(alloc_size * unit_size);
for (uint i = 0; i < sources_size; i++) {
ftw(sources[i], &fn, 1);
}
sessions = realloc(sessions, used_size * unit_size);
__list.length = used_size;
__list.sessions = sessions;
return __sessions_list = &__list;
}

61
src/users.c Normal file
View File

@@ -0,0 +1,61 @@
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <users.h>
#include <util.h>
static struct user __new_user(struct passwd *p) {
struct user __user;
strcln(&__user.username, p->pw_name);
if (p->pw_gecos[0] == '\0')
__user.display_name = __user.username;
else
strcln(&__user.display_name, p->pw_gecos);
return __user;
}
static const u_int8_t bs = 16;
static const u_int8_t unit_size = sizeof(struct user);
static u_int16_t alloc_size = bs;
static u_int16_t used_size = 0;
static struct user *users = NULL;
static struct users_list *__users_list = NULL;
struct users_list __list;
// This code is designed to be run purely sinlge threaded
struct users_list *get_human_users() {
if (users != NULL)
return __users_list;
else
users = malloc(alloc_size * unit_size);
struct passwd *pwd;
while ((pwd = getpwent()) != NULL) {
// practically impossible to reach this (== 0xffff)
// but will prevent break
if (used_size == 0xffff ||
!(pwd->pw_dir && strncmp(pwd->pw_dir, "/home/", 6) == 0))
continue;
if (used_size >= alloc_size) {
alloc_size += bs;
users = realloc(users, alloc_size * unit_size);
}
users[used_size] = __new_user(pwd);
used_size++;
}
users = realloc(users, used_size * unit_size);
__list.length = used_size;
__list.users = users;
return __users_list = &__list;
}

9
src/util.c Normal file
View File

@@ -0,0 +1,9 @@
#include <stdlib.h>
#include <string.h>
#include <util.h>
void strcln(char **dest, const char *source) {
*dest = malloc(strlen(source) + sizeof(char));
strcpy(*dest, source);
}