Add suppor for finger -l

This commit is contained in:
Juhani Krekelä 2018-07-22 10:28:40 +00:00
parent 4365a00b2a
commit 3178216ade
1 changed files with 63 additions and 11 deletions

View File

@ -5,6 +5,7 @@
#include <poll.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -141,8 +142,20 @@ ssize_t writeall_str(int fd, const char *s) {
return writeall(fd, s, strlen(s));
}
void handle_userlist(int sock) {
bool handle_finger_response(int sock, const char *finger_response_file) {
(void)finger_response_file;
// TODO: Handle .finger-response
if(writeall_str(sock, "Lewd.\r\n") < 0) {
log_perror("writeall_str (lewd)");
return false;
}
return true;
}
void handle_userlist(int sock, bool force_multiline) {
// Go over users' home dirs and see if .finger-response is present
bool first_line = true;
for(;;) {
errno = 0;
struct passwd *passwd_entry = getpwent();
@ -160,18 +173,44 @@ void handle_userlist(int sock) {
char *finger_response_file;
if(asprintf(&finger_response_file, "%s/.finger-response", passwd_entry->pw_dir) < 0) {
log_perror("asprintf");
endpwent();
return;
}
if(access(finger_response_file, F_OK) == 0) {
if(force_multiline && !first_line) {
if(writeall_str(sock, "\r\n") < 0) {
log_perror("writeall_str (separating newline)");
endpwent();
return;
}
}
if(writeall_str(sock, passwd_entry->pw_name) < 0) {
log_perror("writeall_str");
log_perror("writeall_str (username)");
endpwent();
return;
}
if(writeall_str(sock, "\r\n") < 0) {
log_perror("writeall_str");
const char *suffix = "\r\n";
if(force_multiline) {
suffix = ":\r\n";
}
if(writeall_str(sock, suffix) < 0) {
log_perror("writeall_str (suffix)");
endpwent();
return;
}
if(force_multiline) {
if(handle_finger_response(sock, finger_response_file) == false) {
endpwent();
return;
}
}
first_line = false;
}
}
}
@ -199,15 +238,11 @@ void handle_query(int sock, const char *username) {
if(access(finger_response_file, F_OK) != 0) {
if(writeall_str(sock, "Can't finger\r\n") < 0) {
log_perror("writeall_str");
log_perror("writeall_str (not found error)");
return;
}
} else {
const char *response = "Lewd.\r\n";
if(writeall(sock, response, strlen(response)) < 0) {
log_perror("write");
}
handle_finger_response(sock, finger_response_file);
}
}
@ -247,14 +282,31 @@ void handle_connection(int sock) {
}
}
char *request_buffer = request;
request[request_size-2] = '\0';
// See if the multi-line format was requested
bool force_multiline = false;
if(request[0] == '/' && request[1] == 'W') {
if(request[2] == '\0') {
// Just "/W"
force_multiline = true;
request = &request[2];
} else if(request[2] == ' ') {
// "/W " as prefix
force_multiline = true;
request = &request[3];
}
}
if(!strcmp(request, "")) {
handle_userlist(sock);
handle_userlist(sock, force_multiline);
} else {
handle_query(sock, request);
}
free(request_buffer);
shutdown(sock, SHUT_RDWR);
close(sock);
}