diff options
| author | daniel <daniel@planethacker.net> | 2025-05-07 09:45:50 -0700 |
|---|---|---|
| committer | daniel <daniel@planethacker.net> | 2025-05-07 09:45:50 -0700 |
| commit | eeac69b2168c5a65f9608771006ccc43033cbd23 (patch) | |
| tree | 1dc44a6016b607085a691768810d551045df9901 /shm.c | |
Diffstat (limited to 'shm.c')
| -rw-r--r-- | shm.c | 114 |
1 files changed, 114 insertions, 0 deletions
@@ -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 */ |
