summaryrefslogtreecommitdiff
path: root/shm.c
diff options
context:
space:
mode:
authordaniel <daniel@planethacker.net>2025-05-07 09:45:50 -0700
committerdaniel <daniel@planethacker.net>2025-05-07 09:45:50 -0700
commiteeac69b2168c5a65f9608771006ccc43033cbd23 (patch)
tree1dc44a6016b607085a691768810d551045df9901 /shm.c
initial commitHEADmain
Diffstat (limited to 'shm.c')
-rw-r--r--shm.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/shm.c b/shm.c
new file mode 100644
index 0000000..c20d3c5
--- /dev/null
+++ b/shm.c
@@ -0,0 +1,114 @@
+/*
+ * LOKI3
+ *
+ * [ shm.c ]
+ *
+ * 1996/7 Guild Corporation Worldwide [daemon9]
+ */
+
+#include "loki.h"
+#include "client_db.h"
+#include "shm.h"
+
+extern struct loki rdg;
+extern int verbose;
+extern int destroy_shm;
+struct client_list *client = 0;
+
+int semid;
+
+
+/*
+ * Obfuscated strings
+ */
+extern estring S_MSG_SHM_DETACH_ERROR;
+extern estring S_MSG_CANNOT_DESTROY_SHMID;
+extern estring S_MSG_CANNOT_DESTROY_SEMAPHORE;
+extern estring S_MSG_SHM_SEGMENT_ERROR;
+extern estring S_MSG_SEMAPHORE_ALLOCATION_ERROR;
+extern estring S_MSG_CANNOT_LOCK_MEMORY;
+extern estring S_MSG_CANNOT_UNLOCK_MEMORY;
+
+/*
+ * Prepare shared memory and semaphoreg
+ */
+void prep_shm() {
+ key_t shmkey = SHM_KEY + getpid(); /* shared memory key ID */
+ key_t semkey = SEM_KEY + getpid(); /* semaphore key ID */
+ int shmid, len = sizeof(struct client_list) * MAX_CLIENT;
+
+ /* Request a shared memory segment */
+ if ((shmid = shmget(shmkey, len, IPC_CREAT)) < 0) {
+ err_exit(1, 1, verbose, decrypt(S_MSG_SHM_SEGMENT_ERROR));
+ }
+
+ /* Get SET_SIZE semaphore to perform shared memory locking with */
+ if ((semid = semget(semkey, SET_SIZE, (IPC_CREAT | SHM_PRM))) < 0) {
+ err_exit(1, 1, verbose, decrypt(S_MSG_SEMAPHORE_ALLOCATION_ERROR));
+ }
+
+ /* Attach pointer to the shared memory segment */
+ client = (struct client_list *) shmat(shmid, NULL, 0);
+
+ /* clear the database */
+ for (int i = 0; i < MAX_CLIENT; i++) {
+ bzero(&client[i], sizeof(client[i]));
+ }
+}
+
+
+/*
+ * Locks the semaphore so the caller can access the shared memory segment.
+ * This is an atomic operation.
+ */
+void locks() {
+ struct sembuf lock[2] = {
+ {0, 0, 0},
+ {0, 1, SEM_UNDO}
+ };
+
+ if (semop(semid, &lock[0], 2) < 0) {
+ err_exit(1, 1, verbose, decrypt(S_MSG_CANNOT_LOCK_MEMORY));
+ }
+}
+
+
+/*
+ * Unlocks the semaphore so the caller can access the shared memory segment.
+ * This is an atomic operation.
+ */
+void ulocks() {
+ struct sembuf ulock[1] = {
+ { 0, -1, (IPC_NOWAIT | SEM_UNDO) }
+ };
+
+ if (semop(semid, &ulock[0], 1) < 0) {
+ err_exit(1, 1, verbose, decrypt(S_MSG_CANNOT_UNLOCK_MEMORY));
+ }
+}
+
+
+/*
+ * Release the shared memory segment.
+ */
+void dump_shm() {
+ locks();
+
+ if ((shmdt((uint8_t *)client)) == -1) {
+ err_exit(1, 1, verbose, decrypt(S_MSG_SHM_DETACH_ERROR));
+ }
+
+ if (destroy_shm == OK) {
+ if ((shmctl(semid, IPC_RMID, NULL)) == -1) {
+ err_exit(1, 1, verbose, decrypt(S_MSG_CANNOT_DESTROY_SHMID));
+ }
+
+ if ((semctl(semid, IPC_RMID, 0, NULL)) == -1) {
+ err_exit(1, 1, verbose, decrypt(S_MSG_CANNOT_DESTROY_SEMAPHORE));
+ }
+ }
+
+ ulocks();
+}
+
+/* EOF */