#include #include #include #include #include #include #include #include #include using namespace std; char* getoutput(const char* command); vector get_userlist(){ char* userlist = getoutput("who | cut -d ' ' -f 1 | sort -u"); char* current_beginning = userlist; vector list; for(int i = 0; userlist[i]; i++) if(userlist[i] == '\n'){ userlist[i] = 0; list.push_back(current_beginning); current_beginning = userlist + i; while(!isalpha(*current_beginning)){ current_beginning++; if(!*current_beginning) break; } } free(userlist); return list; } bool is_in_vector(vector haystack, string target){ for(auto s : haystack) if(s == target) return true; return false; } int main(){ pid_t pid = fork(); if(pid) return 0; setsid(); int logfd = open("daemon_log", O_WRONLY | O_CREAT | O_APPEND, 0644); if(logfd == -1){ perror("open"); return 1; } dup2(logfd, 1); vector userlist = get_userlist(); while(1){ vector new_userlist = get_userlist(); time_t now = time(0); char *nowstr = ctime(&now); nowstr[strlen(nowstr) - 1] = 0; for(string &new_user : new_userlist) if(!is_in_vector(userlist, new_user)) printf("New User: %s (%s)\n", new_user.c_str(), nowstr); for(string &old_user : userlist) if(!is_in_vector(new_userlist, old_user)) printf("User logged out: %s (%s)\n", old_user.c_str(), nowstr); userlist = new_userlist; fflush(stdout); sleep(1); } return 0; } char* getoutput(const char* command){ int pipe_fds[2]; char *buffer = (char*)malloc(16); pipe(pipe_fds); pid_t child = fork(); if(!child){ dup2(pipe_fds[1], 1); execl("/bin/sh", "sh", "-c", command, (char *) 0); perror("exec"); exit(1); } else { size_t sofar = 0; close(pipe_fds[1]); for(;;) { ssize_t readlen = read(pipe_fds[0], buffer + sofar, 16); if(readlen <= 0) break; sofar += readlen; buffer = (char*)realloc(buffer, sofar + 16); } buffer[sofar] = 0; return buffer; } }