Created
April 22, 2014 03:41
-
-
Save elliottsj/11164690 to your computer and use it in GitHub Desktop.
CSC209 Excercise 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all : validate checkpasswd | |
validate : validate.c | |
gcc -Wall -g -o validate validate.c | |
checkpasswd : checkpasswd.c | |
gcc -Wall -g -o checkpasswd checkpasswd.c | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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