Skip to content

Instantly share code, notes, and snippets.

@elliottsj
Created April 22, 2014 03:41
Show Gist options
  • Save elliottsj/11164690 to your computer and use it in GitHub Desktop.
Save elliottsj/11164690 to your computer and use it in GitHub Desktop.
CSC209 Excercise 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
/* Read a user id and password from standard input,
- create a new process to run the validate program
- use exec (probably execlp) to load the validate program.
- send 'validate' the user id and password on a pipe,
- print a message
"Password verified" if the user id and password matched,
"Invalid password", or
"No such user"
depending on the return value of 'validate'.
Setting the character arrays to have a capacity of 256 when we are only
expecting to get 10 bytes in each is a cheesy way of preventing most
overflow problems.
*/
#define MAXLINE 256
#define MAXPASSWD 10
void strip(char *str, int capacity) {
char *ptr;
if((ptr = strchr(str, '\n')) == NULL) {
str[capacity - 1] = '\0';
} else {
*ptr = '\0';
}
}
int main(void) {
char userid[MAXLINE];
char password[MAXLINE];
/* Read a user id and password from stdin */
printf("User id:\n");
if((fgets(userid, MAXLINE, stdin)) == NULL) {
fprintf(stderr, "Could not read from stdin\n");
exit(1);
}
strip(userid, MAXPASSWD);
printf("Password:\n");
if((fgets(password, MAXLINE, stdin)) == NULL) {
fprintf(stderr, "Could not read from stdin\n");
exit(1);
}
strip(password, MAXPASSWD);
int fd[2];
int status;
pipe(fd);
int child_pid = fork();
if (child_pid > 0) { // Parent
// Close the 'reading' end of the pipe
close(fd[0]);
// Write the userid to the pipe
write(fd[1], userid, MAXPASSWD);
// Write the password to the pipe
write(fd[1], password, MAXPASSWD);
if (wait(&status) != -1) {
if (WIFEXITED(status)) {
// Child exited successfully
switch (WEXITSTATUS(status)) {
case 0: // userid and password match
printf("Password verified\n");
break;
case 1: // an error occured during validation
printf("Error occured during validation\n");
break;
case 2: // userid found, but password didn't match
printf("Invalid password\n");
break;
case 3: // userid was not found in the file
printf("No such user\n");
break;
default: // unknown status
break;
}
}
} else {
perror("Failed to wait for child");
exit(1);
}
// Close the 'writing' end of the pipe
close(fd[1]);
} else if (child_pid == 0) { // Child
// Close the 'writing' end of the pipe
close(fd[1]);
// Set stdin to read from pipe
dup2(fd[0], fileno(stdin));
// Close the 'reading' end of the pipe
close(fd[0]);
execlp("./validate", "validate", NULL);
}
return 0;
}
all : validate checkpasswd
validate : validate.c
gcc -Wall -g -o validate validate.c
checkpasswd : checkpasswd.c
gcc -Wall -g -o checkpasswd checkpasswd.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define MAXLINE 256
#define PASSWORD_FILE "pass.txt"
/* Reads two chunks from stdin, and checks if they match a user id
and password pair from a password file. The first chunk (10 bytes)
will contain a user id, and the second chunk (10 bytes) will contain a password.
The program exits with a value of 0 if the user id and password match,
1 if there is an error, 2 if the user id is found but the password does not match, and 3 if the user id is not found in the password file. */
int main(void){
int n, user_length;
char userid[30];
char password[11];
if((n = read(STDIN_FILENO, userid, 10)) == -1) {
perror("read");
exit(1);
} else if(n == 0) {
fprintf(stderr, "Error: could not read from stdin");
exit(1);
}
fprintf(stderr, "read %d bytes\n", n);
userid[n] ='\0';
if (userid[strlen(userid) - 1] == '\n')
userid[strlen(userid) - 1] = '\0';
if((n = read(STDIN_FILENO, password, 10)) == -1) {
perror("read");
exit(1);
} else if(n == 0) {
fprintf(stderr, "Error: could not read from stdin");
exit(1);
}
password[n] = '\0';
if (password[strlen(password) - 1] == '\n')
password[strlen(password) - 1] = '\0';
strcat(userid, ":");
user_length = strlen(userid);
strcat(userid, password);
fprintf(stderr, "Searching for |%s|\n", userid);
FILE *fp = fopen(PASSWORD_FILE, "r");
if (!fp) {
perror("fopen");
exit(1);
}
char line[MAXLINE];
while(fgets(line, sizeof(line) - 1, fp)) {
line[strlen(line) - 1] = '\0';
if(strcmp(userid, line) == 0) {
exit(0); // found match
} else if(strncmp(userid, line, user_length) == 0) {
exit(2); // invalid password
}
}
exit(3); // no such user
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment