void mc_destroy_cache(mc_cache* pcache) { assert(pcache); assert( (pcache->capacity>0) && (pcache->unitsize>0)); // initialize hash table ul_free(pcache->hashtable.table); ul_free(pcache->pnodelist); ul_free(pcache->pinfolist); ul_free(pcache); return; }
int main() { /* Variables */ int fd; int stdout_fileno; char *username; char *home; char *conf_file_name; /* Initialize variables */ afterlist = ul_create(8); beforelist = ul_create(8); stdout_fileno = fileno(stdout); /* Get our username */ struct passwd *p = getpwuid(getuid()); if(p == NULL) fatalperror("getpwuid"); /* warning - username will now point to a static area, subsequent getpwuid calls may overwite it */ username = p->pw_name; /* Get our home directory */ home = getenv("HOME"); if(home == NULL) fatalerror("$HOME is not set.\n"); conf_file_name = malloc(strlen(home) + 1 + strlen(conf_file_basename) + 1); strcpy(conf_file_name, home); strcat(conf_file_name, "/"); strcat(conf_file_name, conf_file_basename); /* Set up atexit */ atexit(free_mem_on_exit); /* Read conf file */ config = load_config(conf_file_name); /* If we are supposed to print a user list upon startup, do it now, before fork()ing */ if(config->initialshow) { struct userlist *ls = ul_create(8); ul_populate(ls); ul_sort(ls); if(ls->array[0] == NULL) { printf("No users logged in.\n"); } else { printf("Users logged in: "); for(int i = 0; ls->array[i] != NULL; i++) { if(i > 0 && !strcmp(ls->array[i], ls->array[i-1])) continue; printf("%s, ", ls->array[i]); } printf("\b\b \n"); } ul_free(ls); } /* If we aren't supposed to listen to INs *or* OUTs, no point in continuing */ if(!config->listen_ins && !config->listen_outs) exit(EXIT_SUCCESS); /* If we are forking, fork() and then exit the parent */ if(config->forking) { pid_t pid = fork(); if(pid > 0) exit(0); else if(pid == -1) fatalperror("fork"); /* This setpgid() call changes the process-group ID so 'w' reports the shell (not us!) as the current command */ setpgid(getpid(),getpid()); /* Close stdin, and hang up the TTY, since we really can't access them from the "background" */ close(STDIN_FILENO); vhangup(); } /* Set up child-reaping for login-command */ signal(SIGCHLD, SIG_IGN); /* Start and setup inotify */ fd = inotify_init(); if(fd < 0) fatalperror("inotify_init"); if(inotify_add_watch(fd, _PATH_UTMP, IN_MODIFY) < 0) fatalperror("inotify_add_watch"); while(1) { ul_populate(beforelist); /* If we are fork()ing, we want to monitor stdout, which requires us to use select() with a timeout */ if(config->forking) { watch_and_wait(fd, stdout_fileno); } struct inotify_event evt; if(read(fd, &evt, sizeof(struct inotify_event)) < 0) fatalperror("read"); ul_populate(afterlist); int firstlen = ul_count(beforelist); int secondlen = ul_count(afterlist); if(firstlen == secondlen) { continue; } else if(firstlen > secondlen) { char *r = ul_subtract(beforelist, afterlist); if(r == NULL) continue; if(!strcmp(r, username)) continue; if(config->listen_outs) on_logout(r); } else { char *r = ul_subtract(afterlist, beforelist); if(r == NULL) continue; if(!strcmp(r, username)) continue; if(config->listen_ins) on_login(r); } if(config->oneshot) { exit(0); } } exit(SUCCESS); }
void free_mem_on_exit(void) { ul_free(beforelist); ul_free(afterlist); }
int ul_pack_free(ul_package_t *ppack) { ul_free(ppack); return 0; }