mirror of
https://github.com/javalsai/lidm.git
synced 2025-07-03 14:25:03 +02:00
feat: add users and sessions discovery
- also add clangd multi-file intellisense
This commit is contained in:
parent
4d8faa5b5f
commit
07d2842be0
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
li
|
li
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
|
.cache/
|
||||||
|
4
Makefile
4
Makefile
@ -8,10 +8,10 @@ CFLAGS=-I$(IDIR)
|
|||||||
|
|
||||||
LIBS=-lm
|
LIBS=-lm
|
||||||
|
|
||||||
_DEPS =
|
_DEPS = util.h users.h sessions.h
|
||||||
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
|
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
|
||||||
|
|
||||||
_OBJ = main.o
|
_OBJ = main.o util.o users.o sessions.o
|
||||||
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
|
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
|
||||||
|
|
||||||
$(ODIR)/%.o: $(CDIR)/%.c $(DEPS)
|
$(ODIR)/%.o: $(CDIR)/%.c $(DEPS)
|
||||||
|
50
compile_commands.json
Normal file
50
compile_commands.json
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"directory": "/home/javalsai/coding/li",
|
||||||
|
"arguments": [
|
||||||
|
"gcc",
|
||||||
|
"-c",
|
||||||
|
"-o",
|
||||||
|
"dist/main.o",
|
||||||
|
"src/main.c",
|
||||||
|
"-Iinclude"
|
||||||
|
],
|
||||||
|
"file": "src/main.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "/home/javalsai/coding/li",
|
||||||
|
"arguments": [
|
||||||
|
"gcc",
|
||||||
|
"-c",
|
||||||
|
"-o",
|
||||||
|
"dist/users.o",
|
||||||
|
"src/users.c",
|
||||||
|
"-Iinclude"
|
||||||
|
],
|
||||||
|
"file": "src/users.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "/home/javalsai/coding/li",
|
||||||
|
"arguments": [
|
||||||
|
"gcc",
|
||||||
|
"-c",
|
||||||
|
"-o",
|
||||||
|
"dist/sessions.o",
|
||||||
|
"src/sessions.c",
|
||||||
|
"-Iinclude"
|
||||||
|
],
|
||||||
|
"file": "src/sessions.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "/home/javalsai/coding/li",
|
||||||
|
"arguments": [
|
||||||
|
"gcc",
|
||||||
|
"-c",
|
||||||
|
"-o",
|
||||||
|
"dist/util.o",
|
||||||
|
"src/util.c",
|
||||||
|
"-Iinclude"
|
||||||
|
],
|
||||||
|
"file": "src/util.c"
|
||||||
|
}
|
||||||
|
]
|
13
include/sessions.h
Normal file
13
include/sessions.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
struct session {
|
||||||
|
char *name;
|
||||||
|
char *path;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sessions_list {
|
||||||
|
u_int16_t length;
|
||||||
|
struct session *sessions;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sessions_list *get_avaliable_sessions();
|
13
include/users.h
Normal file
13
include/users.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
struct user {
|
||||||
|
char *username;
|
||||||
|
char *display_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct users_list {
|
||||||
|
u_int16_t length;
|
||||||
|
struct user *users;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct users_list *get_human_users();
|
1
include/util.h
Normal file
1
include/util.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
void strcln(char **dest, const char *source);
|
22
src/main.c
22
src/main.c
@ -1,3 +1,23 @@
|
|||||||
|
#include <pwd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <sessions.h>
|
||||||
|
#include <users.h>
|
||||||
|
|
||||||
int main() {
|
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
97
src/sessions.c
Normal 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
61
src/users.c
Normal 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
9
src/util.c
Normal 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);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user