Added work from my other class repositories before deletion

This commit is contained in:
2017-11-29 10:28:24 -08:00
parent cb0b5f4d25
commit 5ea24c81b5
198 changed files with 739603 additions and 0 deletions

View File

@@ -0,0 +1 @@
This has some text in it.

View File

@@ -0,0 +1 @@
This file has some more text.

View File

@@ -0,0 +1,135 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>CS 290 - Week 2 Assignment</title>
</head>
<body>
<table>
<caption>Comparison of Common Microcontroller Specifications</caption>
<thead>
<tr>
<th></th>
<th>Max Clock</th>
<th>Num I/O</th>
<th>Flash</th>
<th>Ram</th>
<th>EEPROM</th>
</tr>
</thead>
<tbody>
<tr>
<th>Atmel ATMEGA328P</th>
<td>16 MHz</td>
<td>23</td>
<td>32 KB</td>
<td>2 KB</td>
<td>1 KB</td>
</tr>
<tr>
<th>Atmel ATXMEGA256A3U</th>
<td>32 MHz</td>
<td>50</td>
<td>256 KB</td>
<td>16 KB</td>
<td>4 KB</td>
</tr>
<tr>
<th>Atmel ATSAMD21J18</th>
<td>48 MHz</td>
<td>52</td>
<td>256 KB</td>
<td>32 KB</td>
<td>N/A</td>
</tr>
<tr>
<th>TI MSP430F2131</th>
<td>16 MHz</td>
<td>16</td>
<td>8 KB</td>
<td>256 B</td>
<td>N/A</td>
</tr>
<tr>
<th>Microchip PIC16F1825</th>
<td>32 MHz</td>
<td>11</td>
<td>14 KB</td>
<td>1 KB</td>
<td>256 B</td>
</tr>
<tfoot>
<tr>
<td colspan=4>Important</td>
<td colspan=2>Also Important</td>
</tr>
</tfoot>
</tbody>
</table>
<dl>
<dt>Projects I've Done With Microcontrollers</dt>
<dd>OSU Robotics Club Mars Rover Team System Control Boards</dd>
<dd>Four Axis Stepper Motion Controller</dd>
<dd>E-Paper Business Card (In-Progress)</dd>
<dt>Embedded Languages I've Used</dt>
<dd>Embedded C</dd>
<dd>Embedded C++</dd>
<dt>Projects Where I've Fried a Microntroller in Development</dt>
<dd>Mars Rover Team Control Boards</dd>
<dd>Four Axis Motion Controller REV 1</dd>
<dd>75% Of My Microcontroller Based Projects</dd>
</dl>
<div class="outer-content">
<div class="inner-content">
<body><p>Needs More Micro</p></body>
</div>
</div>
<div class="post-div">
<fieldset>
<legend>Form for POST Submission</legend>
<form action="http://classes.engr.oregonstate.edu/eecs/winter2015/cs290-400/tools/class-content/form_tests/check_request.php" method="post">
<fieldset>
<p>Enter Text Here:<input type="text" name="text_input">
</fieldset>
<fieldset>
<p>Enter A Number Here:<input type="number" name="numerical_input">
</fieldset>
<fieldset>
<p>Enter A Password Here:<input type="password" name="password_input">
</fieldset>
<fieldset>
<p>Choose your favorite candy:</p>
<input type="radio" name="candy" value="Snickers" checked>Snickers<br>
<input type="radio" name="candy" value="Skittles">Skittles<br>
<input type="radio" name="candy" value="Mentos">Mentos<br>
<input type="submit">
</fieldset>
</form>
</fieldset>
</div>
<div class="get-div">
<fieldset>
<legend>Form for GET Submission</legend>
<form action="http://classes.engr.oregonstate.edu/eecs/winter2015/cs290-400/tools/class-content/form_tests/check_request.php" method="get">
<fieldset>
<p>Enter Text Here:<input type="text" name="text_input">
</fieldset>
<fieldset>
<p>Enter A Number Here:<input type="number" name="numerical_input">
</fieldset>
<fieldset>
<p>Enter A Password Here:<input type="password" name="password_input">
</fieldset>
<fieldset>
<p>Choose your favorite candy:</p>
<input type="radio" name="candy" value="Snickers" checked>Snickers<br>
<input type="radio" name="candy" value="Skittles">Skittles<br>
<input type="radio" name="candy" value="Mentos">Mentos<br>
<input type="submit">
</fieldset>
</form>
</fieldset>
</div>
</body>
</html>

View File

@@ -0,0 +1,58 @@
table>caption{
font-weight: bold;
}
table, th, td {
border-collapse: collapse;
border: 1px solid black;
text-align: left;
padding: 5px;
}
tbody>tr>th{
font-weight: normal;
font-style: italic;
}
tbody>tr:nth-of-type(even) {
background-color: lightsalmon;
}
tbody>tr:nth-of-type(odd) {
background-color: lightgreen;
}
.inner-content {
width: 75%;
margin-left: auto;
margin-right: auto;
background-color: lightblue;
text-align: center;
}
.outer-content {
float: left;
width: 75%;
background-color: pink;
margin-top: 20px;
}
.post-div{
margin-top: 100px;
clear: both;
}
.get-div{
margin-top: 20px;
}
form>fieldset{
margin: 5px;
}
input[type="submit"]{
margin-left: 5px;
margin-top: 15px;
}

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<script src="javascript_objects.js"></script>
</body>
</html>

View File

@@ -0,0 +1,33 @@
//////////////////////////////////////////////////////////////////////
// Call a function before it's declared
//////////////////////////////////////////////////////////////////////
//Function call and console logging BEFORE function decleration
console.log(simple_string_reverser("Here is some text to reverse!")); //Workss
function simple_string_reverser(input_word) {
if(typeof(input_word) != 'string'){
console.log("Error. Wrong input type.");
return;
}
var new_simple_string = "";
var input_length = input_word.length;
for(var i = 0 ; i < input_word.length ; i++) {
new_simple_string += input_word[input_length-1-i];
}
return new_simple_string;
}
//////////////////////////////////////////////////////////////////////
// Call a function assigned to a variable before it's declared
//////////////////////////////////////////////////////////////////////
console.log(one_year_ago_date_string()); //Doesn't work
var one_year_ago_date_string = function(){
var temp_date = new Date();
temp_date.setFullYear(temp_date.getFullYear()-1);
return temp_date.toDateString();
}
console.log(one_year_ago_date_string()); //Works

View File

@@ -0,0 +1,45 @@
function deepEqual(a, b){
if(((typeof(a) === 'object') && (a !== null)) &&
((typeof(b) === 'object') && (b !== null))){
var size_a = 0;
var size_b = 0;
for(prop in a){ size_a++; }
for(prop in b){ size_b++; }
if(size_a == size_b){
for(prop in a){
if(!b.hasOwnProperty(prop)){
return false;
}
}
for(prop in a){
if(!deepEqual(a[prop], b[prop])){
return false;
}
}
}else{
return false;
}
}else{
return (a === b);
}
return true;
}
var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
console.log(deepEqual(obj, {here: 1, asd: 2}));
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
//console.log(deepEqual(1, 2));
//console.log(deepEqual(2, 2));

View File

@@ -0,0 +1,95 @@
function Automobile( year, make, model, type ){
this.year = year; //integer (ex. 2001, 1995)
this.make = make; //string (ex. Honda, Ford)
this.model = model; //string (ex. Accord, Focus)
this.type = type; //string (ex. Pickup, SUV)
this.logMe = function(print_type){
if(print_type){
console.log(this.year + " " + this.make + " " + this.model + " " + this.type);
}else{
console.log(this.year + " " + this.make + " " + this.model);
}
}
}
var automobiles = [
new Automobile(1995, "Honda", "Accord", "Sedan"),
new Automobile(1990, "Ford", "F-150", "Pickup"),
new Automobile(2000, "GMC", "Tahoe", "SUV"),
new Automobile(2010, "Toyota", "Tacoma", "Pickup"),
new Automobile(2005, "Lotus", "Elise", "Roadster"),
new Automobile(2008, "Subaru", "Outback", "Wagon")
];
//Implemented insertion sort algorithm.
//Reversed [j] and [j-1] from traditional algorithm to sort max first
function sortArr( comparator, array ){
for(var i = 1 ; i < array.length ; i++){
var j = i;
while((j > 0) && (comparator(array[j], array[j-1]))){
var temp = array[j];
array[j] = array[j-1];
array[j-1] = temp;
j--;
}
}
}
function yearComparator(auto1, auto2){
if(auto1.year > auto2.year){
return true;
}else{
return false;
}
}
function makeComparator(auto1, auto2){
if(auto1.make.toLowerCase() < auto2.make.toLowerCase()){
return true;
}else{
return false;
}
}
function typeComparator(auto1, auto2){
var type_order = {'roadster': 4, 'pickup': 3, 'suv': 2, 'wagon': 1}
var auto1_type = type_order[auto1.type.toLowerCase()];
var auto2_type = type_order[auto2.type.toLowerCase()];
if(typeof(auto1_type) == 'undefined'){ auto1_type = 0; }
if(typeof(auto2_type) == 'undefined'){ auto2_type = 0; }
if(auto1_type == auto2_type){
return yearComparator(auto1, auto2);
}else if(auto1_type > auto2_type){
return true;
}else{
return false;
}
}
function print_auto_array(input_array, print_type){
for(index in input_array){
input_array[index].logMe(print_type);
}
}
var print_type = true;
console.log("*****");
console.log("The cars sorted by year are:");
sortArr(yearComparator, automobiles);
print_auto_array(automobiles, print_type);
console.log("\nThe cars sorted by make are:");
sortArr(makeComparator, automobiles);
print_auto_array(automobiles, print_type);
console.log("\nThe cars sorted by type are:");
sortArr(typeComparator, automobiles);
print_auto_array(automobiles, print_type);
console.log("*****");

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<script src="automobile.js"></script>
</body>
</html>

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CS 290 DOM Assignment - Week 5</title>
</head>
<body>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,160 @@
var current_col = 0;
var current_selected_cell;
function up_event_handler(current_event){
var prev_row_sib = current_selected_cell.parentElement.previousElementSibling;
if((typeof(prev_row_sib) == 'object') && (prev_row_sib != null)){
handle_new_cell_selection(prev_row_sib.children[current_col]);
}
}
function down_event_handler(current_event){
var next_row_sib = current_selected_cell.parentElement.nextElementSibling;
if((typeof(next_row_sib) == 'object') && (next_row_sib != null)){
handle_new_cell_selection(next_row_sib.children[current_col]);
}
}
function left_event_handler(current_event){
var prev_sib = current_selected_cell.previousSibling;
if((typeof(prev_sib) == 'object') && (prev_sib != null)){
current_col--;
handle_new_cell_selection(prev_sib);
}
}
function right_event_handler(current_event){
var next_sib = current_selected_cell.nextSibling;
if((typeof(next_sib) == 'object') && (next_sib != null)){
current_col++;
handle_new_cell_selection(next_sib);
}
}
function mark_event_handler(current_event){
current_selected_cell.style.backgroundColor = 'yellow';
}
function handle_new_cell_selection(new_cell){
current_selected_cell.style.border = '1px solid black';
current_selected_cell = new_cell;
current_selected_cell.style.border = '3px solid black';
}
function add_page_table(){
var page_body = document.body;
var new_table = document.createElement("table");
new_table.setAttribute('id', 'my_table_id');
new_table.style.border = '1px solid black';
new_table.style.borderCollapse = 'collapse';
new_table.style.marginLeft = 'auto';
new_table.style.marginRight = 'auto';
var new_thead = new_table.createTHead();
var new_tbody = new_table.createTBody();
var head_tr = new_thead.insertRow(0);
for(var i = 0 ; i < 4 ; i++){
var new_header_cell = head_tr.insertCell(i);
new_header_cell.style.border = '1px solid black';
new_header_cell.textContent = 'Header ' + (i+1);
}
for(var i = 0 ; i < 3 ; i++){
var curr_row = new_tbody.insertRow(i);
for(var j = 0 ; j < 4 ; j++){
var curr_cell = curr_row.insertCell(j);
curr_cell.style.border = '1px solid black';
curr_cell.textContent = (j+1).toString() + ", " + (i+1).toString();
}
}
new_table.appendChild(new_thead);
new_table.appendChild(new_tbody);
page_body.appendChild(new_table);
}
function add_page_buttons(){
var page_body = document.body;
var new_table = document.createElement("table");
new_table.style.marginTop = '20px';
new_table.style.marginLeft = 'auto';
new_table.style.marginRight = 'auto';
var new_tbody = new_table.createTBody();
//Make row 0
var curr_row = new_tbody.insertRow(0);
//Make row 0 with up arrow
curr_row.insertCell(0);
var curr_cell = curr_row.insertCell(1);
var curr_button = document.createElement('Button');
curr_button.innerHTML = '&uarr;';
curr_button.addEventListener("click", up_event_handler);
curr_cell.appendChild(curr_button);
curr_row.insertCell(2); //Final cell for 3x3
//Make row 1
var curr_row = new_tbody.insertRow(1);
//Create right, Mark, and Left Buttons
var curr_cell = curr_row.insertCell(0);
var curr_button = document.createElement('Button');
curr_button.innerHTML = '&rarr;';
curr_button.addEventListener("click", right_event_handler);
curr_cell.appendChild(curr_button);
var curr_cell = curr_row.insertCell(0);
var curr_button = document.createElement('Button');
curr_button.textContent = 'Mark Cell';
curr_button.addEventListener("click", mark_event_handler);
curr_cell.appendChild(curr_button);
var curr_cell = curr_row.insertCell(0);
var curr_button = document.createElement('Button');
curr_button.innerHTML = '&larr;';
curr_button.addEventListener("click", left_event_handler);
curr_cell.appendChild(curr_button);
//Make row 2
var curr_row = new_tbody.insertRow(2);
//Add down arrow
curr_row.insertCell(0);
var curr_cell = curr_row.insertCell(1);
var curr_button = document.createElement('Button');
curr_button.innerHTML = '&darr;';
curr_button.addEventListener("click", down_event_handler);
curr_cell.appendChild(curr_button);
curr_row.insertCell(2); //Final cell for 3x3
//Center all buttons in table
var all_td = new_table.getElementsByTagName('td');
for(var i = 0 ; i < all_td.length ; i++) {
all_td[i].style.textAlign = 'center';
}
//Add nested element and add to page
new_table.appendChild(new_tbody);
page_body.appendChild(new_table);
}
function select_cell_1_1(){
var main_table = document.getElementById('my_table_id');
current_selected_cell = main_table.children[1].children[0].firstElementChild;
current_selected_cell.style.border = '3px solid black';
}
add_page_table();
add_page_buttons();
select_cell_1_1();

View File

@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="http://openlayers.org/api/OpenLayers.js"></script> <!-- Needed for maps if I do it... -->
<title>CS 290 Ajax Interactions - Week 6</title>
<link href="style.css" rel=stylesheet type="text/css">
</head>
<body>
<div id="open_weather_main">
<p class="section_titles">Open Weather Maps Test</p>
<div id="weather_data_container">
<p><span id="location_header">Location: </span><span id="location"></span></p>
<p><span class="weather_data_headers">Current Conditions: </span><span id="current_conditions"></span></p>
<p><span class="weather_data_headers">Temp: </span><span id="current_temp"></span></p>
<p><span class="weather_data_headers">Pressure: </span><span id="current_pressure"></span></p>
<p><span class="weather_data_headers">Humidity: </span><span id="current_humidity"></span></p>
<p><span class="weather_data_headers">Recent Rainfall: </span><span id="current_recent_rainfall"></span></p>
<p><span class="weather_data_headers">Open Weather Request Details: </span><span id="request_details"></span></p>
</div>
<div id="open_weather_form">
<fieldset>
<p>Enter City or Zipcode: <input type="text" id="open_weather_input">
<input id="weather_submit_button" type="submit">
</fieldset>
</div>
</div>
<div id="post_bin_main">
<p class="section_titles">HTTPBIN Submission Test</p>
<div id="httpbin_response_container">
<p><span style="font-weight: bold;">Response in JSON: </span><span id="httpbin_reponse_json"></span></p>
<p><span style="font-weight: bold;">Response data: </span><span id="httpbin_reponse"></span></p>
</div>
<div id="httpbin_form">
<fieldset>
<p>Enter Data to Send to HTTPBIN: <input type="text" id="httpbin_input">
<input id="httpbin_submit_button" type="submit">
</fieldset>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,108 @@
var openweather_api_string = '&APPID=4f5bcff87da17d71fc4f89eb44c1a8da';
var openweather_url = 'http://api.openweathermap.org/data/2.5/weather?';
function on_openweather_submit_pressed(event){
var search = document.getElementById("open_weather_input").value;
if(isNaN(parseInt(search))){
var payload = encodeURI("q=" + search);
}else{
var payload = encodeURI("zip=" + search + ",us")
}
var req = new XMLHttpRequest();
var full_url = openweather_url + payload + openweather_api_string;
req.open('GET', full_url, true);
req.addEventListener('load', on_openweather_response_received);
req.send(null);
console.log(full_url);
event.preventDefault();
}
function on_openweather_response_received(response){
var location = document.getElementById("location");
var conditions = document.getElementById("current_conditions");
var temp = document.getElementById("current_temp");
var pressure = document.getElementById("current_pressure");
var humidity = document.getElementById("current_humidity");
var rainfall = document.getElementById("current_recent_rainfall");
var details = document.getElementById("request_details");
var text_box = document.getElementById("open_weather_input");
text_box.value = "";
var req_status = response.srcElement.status;
console.log(response);
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(response_json.cod == 404){
location.textContent = "";
conditions.textContent = "";
temp.textContent = "";
pressure.textContent = "";
humidity.textContent = "";
rainfall.textContent = "";
details.textContent = "City Not Found!";
}else{
location.textContent = response_json.name;
conditions.textContent = response_json.weather[0].main;
temp.textContent = (parseFloat(response_json.main.temp) - 273.15).toFixed(2).toString() + " °C";
pressure.textContent = response_json.main.pressure + " hPa";
humidity.textContent = response_json.main.humidity + "%";
var rainfall_data = response_json.rain;
if(typeof(rainfall_data) == 'undefined'){
rainfall.textContent = "";
}else{
rainfall.textContent = response_json.rain['3h'].toFixed(1) + "mm in the last 3 hours";
}
details.textContent = "City Found Sucessfully!";
}
}else{
location.textContent = "";
conditions.textContent = "";
temp.textContent = "";
pressure.textContent = "";
humidity.textContent = "";
rainfall.textContent = "";
details.textContent = "Failed communications with Open Weather Server!";
}
}
function on_httpbin_submit_pressed(event){
var text_input = document.getElementById("httpbin_input").value;
var req = new XMLHttpRequest();
var payload = {'mydata': text_input};
req.open('POST', "http://httpbin.org/post", true);
req.setRequestHeader('Content-Type', 'application/json');
req.addEventListener('load', on_httpbin_response_receieved);
req.send(JSON.stringify(payload));
event.preventDefault();
}
function on_httpbin_response_receieved(response){
var response_span_json = document.getElementById("httpbin_reponse_json");
var response_span_data = document.getElementById("httpbin_reponse");
var parsed_json = JSON.parse(response.srcElement.responseText);
response_span_json.textContent = parsed_json.data;
response_span_data.textContent = parsed_json.json.mydata;
}
function setup_events(){
document.getElementById("weather_submit_button").addEventListener("click", on_openweather_submit_pressed);
document.getElementById("httpbin_submit_button").addEventListener("click", on_httpbin_submit_pressed);
}
document.addEventListener('DOMContentLoaded', setup_events);

View File

@@ -0,0 +1,33 @@
#open_weather_main{
width: 100%;
height 40%;
}
.section_titles {
font-size: x-large;
font-weight: bold;
}
#location_header {
font-size: large;
font-weight: bold;
padding-left: 5px;
}
.weather_data_headers {
font-weight: bold;
padding-left: 5px;
}
#open_weather_form {
width: 100%;
}
#post_bin_main {
margin-top: 80px;
}
#httpbin_response_container {
padding-bottom: 5px;
margin-bottom: 5px;
}

View File

@@ -0,0 +1,18 @@
{
"name": "CS290_Week7",
"version": "1.0.0",
"description": "Week 7 content.",
"main": "week7.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Corwin Perren",
"license": "ISC",
"dependencies": {
"body-parser": "^1.13.3",
"express": "^4.13.2",
"express-handlebars": "^2.0.1",
"express-session": "^1.11.3",
"mysql": "^2.8.0"
}
}

View File

@@ -0,0 +1 @@
<h1>Error 404 - Page Is Nowhere to be Found</h1>

View File

@@ -0,0 +1 @@
<h1>Error 500 - Something Has Gone Terribly Wrong</h1>

View File

@@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<title>Demo Page</title>
</head>
<body>
{{{body}}}
</body>
</html>

View File

@@ -0,0 +1,18 @@
{
"name": "CS290_Week7",
"version": "1.0.0",
"description": "Week 7 content.",
"main": "week7.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Corwin Perren",
"license": "ISC",
"dependencies": {
"body-parser": "^1.15.0",
"express": "^4.13.2",
"express-handlebars": "^2.0.1",
"express-session": "^1.11.3",
"mysql": "^2.8.0"
}
}

View File

@@ -0,0 +1 @@
<h1>Error 404 - Page Is Nowhere to be Found</h1>

View File

@@ -0,0 +1 @@
<h1>Error 500 - Something Has Gone Terribly Wrong</h1>

View File

@@ -0,0 +1,10 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>CS 290 Get and Post Checker - Week 7</title>
</head>
<body>
{{{body}}}
</body>
</html>

View File

@@ -0,0 +1,7 @@
<h1>{{StatusHeader}}</h1>
<h2>Query Parameters</h2>
<ul>
{{#each query_data}}
<li>{{this.name}}: {{this.value}}
{{/each}}
</ul>

View File

@@ -0,0 +1,14 @@
<h1>{{StatusHeader}}</h1>
<h2>Query Parameters</h2>
<ul>
{{#each query_data}}
<li>{{this.name}}: {{this.value}}
{{/each}}
</ul>
<h2>Body Property Values</h2>
<ul>
{{#each body_data}}
<li>{{this.name}}: {{this.value}}
{{/each}}
</ul>

View File

@@ -0,0 +1,69 @@
//Base code copied with permission from https://github.com/wolfordj/CS290-Server-Side-Examples
var express = require('express');
var app = express();
var handlebars = require('express-handlebars').create({defaultLayout:'main'});
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('port', 3000);
function get_data_array(data){
params = [];
for(par in data){
params.push({'name':par, 'value':data[par]});
}
return params;
}
function generateContext_GET(req){
var dynamic_page_contents = {};
dynamic_page_contents.StatusHeader = req.method + " Request Received";
dynamic_page_contents.query_data = get_data_array(req.query);
return dynamic_page_contents;
}
function generateContext_POST(req){
var dynamic_page_contents = {};
dynamic_page_contents.StatusHeader = req.method + " Request Received";
dynamic_page_contents.query_data = get_data_array(req.query);
dynamic_page_contents.body_data = get_data_array(req.body);
return dynamic_page_contents;
}
function my_get(req,res){
res.render('week7_GET', generateContext_GET(req));
}
app.get('/', my_get);
app.post('/', function(req,res){
res.render('week7_POST', generateContext_POST(req));
});
app.use(function(req,res){
res.status(404);
res.render('404');
});
app.use(function(err, req, res, next){
console.error(err.stack);
res.type('plain/text');
res.status(500);
res.render('500');
});
function on_listen(){
console.log('Express started on http://localhost:' + app.get('port') + '; press Ctrl-C to terminate.');
}
app.listen(app.get('port'), on_listen);

View File

@@ -0,0 +1,738 @@
var root_url = '/~perrenc/CS340_Final_Website/';
var get_members_url = 'db_interactions/get_members.php';
var get_positions_url = root_url + 'db_interactions/get_positions.php';
var get_teams_url = root_url + 'db_interactions/get_teams.php';
var get_skills_url = root_url + 'db_interactions/get_skills.php';
var add_new_mem_url = root_url + 'db_interactions/add_member.php';
var del_mem_url = root_url + 'db_interactions/del_member.php';
var assign_skill_mem_url = root_url + 'db_interactions/assign_skill.php';
var assign_team_mem_url = root_url + 'db_interactions/assign_team.php';
var add_new_skill_url = root_url + 'db_interactions/add_new_skill.php';
var add_new_team_url = root_url + 'db_interactions/add_new_team.php';
var add_new_position_url = root_url + 'db_interactions/add_new_position.php';
var find_with_skill_url = root_url + 'db_interactions/find_with_skill.php';
var find_with_team_url = root_url + 'db_interactions/find_with_team.php';
var find_with_position_url = root_url + 'db_interactions/find_with_position.php';
////////// Function to reset inputs //////////
function reset_inputs() {
document.getElementById('mem_add_first_name').value = "";
document.getElementById('mem_add_last_name').value = "";
document.getElementById('mem_add_position_drop').selectedIndex = 0;
document.getElementById('mem_add_superior_drop').selectedIndex = 0;
document.getElementById('mem_add_email').value = "";
document.getElementById('mem_add_phone').value = "";
document.getElementById('mem_add_osuid').value = "";
document.getElementById('mem_add_rfid').value = "";
document.getElementById('mem_del_first_name').value = "";
document.getElementById('mem_del_last_name').value = "";
document.getElementById('assign_skill_first_name').value = "";
document.getElementById('assign_skill_last_name').value = "";
document.getElementById('assign_skill_position_drop').selectedIndex = 0;
document.getElementById('add_team_first_name').value = "";
document.getElementById('add_team_last_name').value = "";
document.getElementById('add_team_position_drop').selectedIndex = 0;
document.getElementById('skill_add_name').value = "";
document.getElementById('skill_add_description').value = "";
document.getElementById('team_add_name').value = "";
document.getElementById('team_add_description').value = "";
document.getElementById('position_add_name').value = "";
document.getElementById('position_add_description').value = "";
document.getElementById('show_with_skill_drop').selectedIndex = 0;
document.getElementById('show_with_team_drop').selectedIndex = 0;
document.getElementById('show_with_position_drop').selectedIndex = 0;
}
////////// Functions to show position search //////////
function show_with_position() {
var position_name = document.getElementById('show_with_position_drop').value;
var req = new XMLHttpRequest();
req.open('POST', find_with_position_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_show_with_position_response_received);
req.send("name=" + position_name);
}
function on_show_with_position_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var header_data = ["First Name", "Last Name", "Position"];
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var members = response_json.members;
generate_table_and_show("Members Position Search", header_data, members);
status_box.textContent = "Members position list shown successfully!"
}else{
err_box.textContent = "MEMBERS POSITION SHOW: Unknown error with request. Please consult logs.";
}
}else{
err_box.textContent = "MEMBERS POSITION SHOW: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Functions to show team search //////////
function show_with_team() {
var team_name = document.getElementById('show_with_team_drop').value;
var req = new XMLHttpRequest();
req.open('POST', find_with_team_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_show_with_team_response_received);
req.send("name=" + team_name);
}
function on_show_with_team_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var header_data = ["First Name", "Last Name", "Team"];
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var members = response_json.members;
generate_table_and_show("Members Team Search", header_data, members);
status_box.textContent = "Members team list shown successfully!"
}else{
err_box.textContent = "MEMBERS TEAM SHOW: Unknown error with request. Please consult logs.";
}
}else{
err_box.textContent = "MEMBERS TEAM SHOW: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Functions to show skill search //////////
function show_with_skill() {
var skill_name = document.getElementById('show_with_skill_drop').value;
var req = new XMLHttpRequest();
req.open('POST', find_with_skill_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_show_with_skill_response_received);
req.send("name=" + skill_name);
}
function on_show_with_skill_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var header_data = ["First Name", "Last Name", "Skill"];
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var members = response_json.members;
generate_table_and_show("Members Skill Search", header_data, members);
status_box.textContent = "Members skill list shown successfully!"
}else{
err_box.textContent = "MEMBERS SKILLS SHOW: Unknown error with request. Please consult logs.";
}
}else{
err_box.textContent = "MEMBERS SKILLS SHOW: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Functions to show positions //////////
function show_positions() {
var req = new XMLHttpRequest();
req.open('POST', get_positions_url, true);
req.addEventListener('load', on_show_positions_response_received);
req.send(null);
}
function on_show_positions_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var header_data = ["Name", "Description"];
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var positions = response_json.positions;
generate_table_and_show("Positions List", header_data, positions);
status_box.textContent = "Positions list shown successfully!"
}else{
err_box.textContent = "POSITIONS SHOW: Unknown error with request. Please consult logs.";
}
}else{
err_box.textContent = "POSITIONS SHOW: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Functions to show teams //////////
function show_teams() {
var req = new XMLHttpRequest();
req.open('POST', get_teams_url, true);
req.addEventListener('load', on_show_teams_response_received);
req.send(null);
}
function on_show_teams_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var header_data = ["Name", "Description"];
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var teams = response_json.teams;
generate_table_and_show("Teams List", header_data, teams);
status_box.textContent = "Teams list shown successfully!"
}else{
err_box.textContent = "TEAMS SHOW: Unknown error with request. Please consult logs.";
}
}else{
err_box.textContent = "TEAMS SHOW: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Functions to show skills //////////
function show_skills() {
var req = new XMLHttpRequest();
req.open('POST', get_skills_url, true);
req.addEventListener('load', on_show_skills_response_received);
req.send(null);
}
function on_show_skills_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var header_data = ["Name", "Description"];
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var skills = response_json.skills;
generate_table_and_show("Skills List", header_data, skills);
status_box.textContent = "Skills list shown successfully!"
}else{
err_box.textContent = "SKILLS SHOW: Unknown error with request. Please consult logs.";
}
}else{
err_box.textContent = "SKILLS SHOW: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Functions to show members //////////
function show_members() {
var req = new XMLHttpRequest();
req.open('POST', get_members_url, true);
req.addEventListener('load', on_show_members_response_received);
req.send(null);
}
function on_show_members_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var header_data = ["First Name", "Last Name", "Position", "Superior", "Email", "Phone", "OSU ID #", "RFID #"];
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var members = response_json.members;
generate_table_and_show("Members List", header_data, members);
status_box.textContent = "Members list shown successfully!"
}else{
err_box.textContent = "MEMBER SHOW: Unknown error with request. Please consult logs.";
}
}else{
err_box.textContent = "MEMBER SHOW: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Generate table and show //////////
function generate_table_and_show(title, headers, array_data) {
var table_div = document.getElementById('main_output_content');
table_div.innerHTML = "";
var new_h2 = document.createElement("h2");
new_h2.textContent = title;
table_div.appendChild(new_h2);
var table = document.createElement("table");
var table_header = table.createTHead();
var row = table_header.insertRow(0);
for(var head_iter in headers){
var cell = row.insertCell(head_iter);
cell.textContent = headers[head_iter];
}
row.style.fontWeight = "bold";
for(var row_iter in array_data){
var cur_row = array_data[row_iter];
row = table.insertRow(parseInt(row_iter) + 1);
for(var col_iter in cur_row){
cell = row.insertCell(col_iter);
cell.textContent = array_data[row_iter][col_iter];
}
}
table_div.appendChild(table);
}
////////// Add new position on_click_handler //////////
function on_add_new_position_clicked() {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var name = document.getElementById('position_add_name').value;
var description = document.getElementById('position_add_description').value;
if(!name){
status_box.textContent = "";
err_box.textContent = "Name must be present!";
return;
}
var param_string = "name=" + name;
if (description) { param_string += "&description=" + description; }
var req = new XMLHttpRequest();
req.open('POST', add_new_position_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_add_change_delete_response_received);
req.send(param_string);
}
////////// Add new team on_click_handler //////////
function on_add_new_team_clicked() {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var name = document.getElementById('team_add_name').value;
var description = document.getElementById('team_add_description').value;
if(!name){
status_box.textContent = "";
err_box.textContent = "Name must be present!";
return;
}
var param_string = "name=" + name;
if (description) { param_string += "&description=" + description; }
var req = new XMLHttpRequest();
req.open('POST', add_new_team_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_add_change_delete_response_received);
req.send(param_string);
}
////////// Add new skill on_click_handler //////////
function on_add_new_skill_clicked() {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var name = document.getElementById('skill_add_name').value;
var description = document.getElementById('skill_add_description').value;
if(!name){
status_box.textContent = "";
err_box.textContent = "Name must be present!";
return;
}
var param_string = "name=" + name;
if (description) { param_string += "&description=" + description; }
var req = new XMLHttpRequest();
req.open('POST', add_new_skill_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_add_change_delete_response_received);
req.send(param_string);
}
////////// Assign team to member on_click_handler //////////
function on_assign_team_to_member_clicked() {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var first = document.getElementById('add_team_first_name').value;
var last = document.getElementById('add_team_last_name').value;
var team = document.getElementById('add_team_position_drop').value;
if(!first || !last){
status_box.textContent = "";
err_box.textContent = "First and last must be present!";
return;
}
var param_string = "first_name=" + first + "&last_name=" + last + "&team=" + team;
var req = new XMLHttpRequest();
req.open('POST', assign_team_mem_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_add_change_delete_response_received);
req.send(param_string);
}
////////// Assign skill to member on_click_handler //////////
function on_assign_skill_to_member_clicked() {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var first = document.getElementById('assign_skill_first_name').value;
var last = document.getElementById('assign_skill_last_name').value;
var skill = document.getElementById('assign_skill_position_drop').value;
if(!first || !last){
status_box.textContent = "";
err_box.textContent = "First and last must be present!";
return;
}
var param_string = "first_name=" + first + "&last_name=" + last + "&skill=" + skill;
var req = new XMLHttpRequest();
req.open('POST', assign_skill_mem_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_add_change_delete_response_received);
req.send(param_string);
}
////////// Delete member on_click_handler //////////
function on_delete_member_clicked() {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var first = document.getElementById('mem_del_first_name').value;
var last = document.getElementById('mem_del_last_name').value;
if(!first || !last){
status_box.textContent = "";
err_box.textContent = "First and last must be present!";
return;
}
var param_string = "first_name=" + first + "&last_name=" + last
var req = new XMLHttpRequest();
req.open('POST', del_mem_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_add_change_delete_response_received);
req.send(param_string);
}
////////// Add member on_click_handler //////////
function on_add_member_clicked() {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
status_box.textContent = "";
err_box.textContent = "";
var first = document.getElementById('mem_add_first_name').value;
var last = document.getElementById('mem_add_last_name').value;
var position = document.getElementById('mem_add_position_drop').value;
var superior = document.getElementById('mem_add_superior_drop').value;
var email = document.getElementById('mem_add_email').value;
var phone = document.getElementById('mem_add_phone').value;
var osuid = document.getElementById('mem_add_osuid').value;
var rfid = document.getElementById('mem_add_rfid').value;
if(!first || !last || !position || !email || !osuid){
status_box.textContent = "";
err_box.textContent = "First, last, position, email, and OSU ID must be present!";
return;
}
var param_string = "first_name=" + first + "&last_name=" + last + "&position=" + position;
if (superior != "--") { param_string += "&superior=" + superior; }
param_string += "&email=" + email;
if (phone) { param_string += "&phone=" + phone; }
param_string += "&osu_num=" + osuid;
if (rfid) { param_string += "&rfid_num=" + rfid; }
var req = new XMLHttpRequest();
req.open('POST', add_new_mem_url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.addEventListener('load', on_add_change_delete_response_received);
req.send(param_string);
}
////////// Functions for updating club skill dropdowns //////////
function update_skill_dropdowns() {
var req = new XMLHttpRequest();
req.open('POST', get_skills_url, true);
req.addEventListener('load', on_update_skills_response_received);
req.send(null);
}
function on_update_skills_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
//status_box.textContent = "";
//err_box.textContent = "";
var assign_skill = document.getElementById('assign_skill_position_drop');
var skill_search = document.getElementById('show_with_skill_drop');
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var skills = response_json.skills;
assign_skill.innerHTML = "";
populate_select_with_options(assign_skill, skills);
skill_search.innerHTML = "";
populate_select_with_options(skill_search, skills);
}else {
//err_box.textContent = "SKILLS UPDATE: Unknown error with request. Please consult logs.";
}
}else{
//err_box.textContent = "SKILLS UPDATE: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Functions for updating club team dropdowns //////////
function update_team_dropdowns() {
var req = new XMLHttpRequest();
req.open('POST', get_teams_url, true);
req.addEventListener('load', on_update_teams_response_received);
req.send(null);
}
function on_update_teams_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
//status_box.textContent = "";
//err_box.textContent = "";
var add_to_team = document.getElementById('add_team_position_drop');
var team_search = document.getElementById('show_with_team_drop');
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var teams = response_json.teams;
add_to_team.innerHTML = "";
populate_select_with_options(add_to_team, teams);
team_search.innerHTML = "";
populate_select_with_options(team_search, teams);
}else {
//err_box.textContent = "TEAMS UPDATE: Unknown error with request. Please consult logs.";
}
}else{
//err_box.textContent = "TEAMS UPDATE: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Functions for updating club position dropdowns //////////
function update_position_dropdowns() {
var req = new XMLHttpRequest();
req.open('POST', get_positions_url, true);
req.addEventListener('load', on_update_positions_response_received);
req.send(null);
}
function on_update_positions_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
//status_box.textContent = "";
//err_box.textContent = "";
var pos_add = document.getElementById('mem_add_position_drop');
var sup_add = document.getElementById('mem_add_superior_drop');
var pos_search = document.getElementById('show_with_position_drop');
var req_status = response.srcElement.status;
if(req_status >=200 && req_status < 400){
var response_json = JSON.parse(response.srcElement.responseText);
if(!response_json.is_error){
var positions = response_json.positions;
clear_dropdown(pos_add);
populate_select_with_options(pos_add, positions);
clear_dropdown(sup_add);
populate_select_with_options(sup_add, [["--"]]);
populate_select_with_options(sup_add, positions);
clear_dropdown(pos_search);
populate_select_with_options(pos_search, positions);
}else {
//err_box.textContent = "POSITIONS UPDATE: Unknown error with request. Please consult logs.";
}
}else{
//err_box.textContent = "POSITIONS UPDATE: Failed to contact server for request. Please verify webserver is up and files exist.";
}
}
////////// Generic use functions //////////
function populate_select_with_options(select_element, option_array){
for(var option_iter in option_array){
var option = document.createElement("option");
option.textContent = option_array[option_iter][0];
select_element.add(option);
}
}
function on_add_change_delete_response_received(response) {
var status_box = document.getElementById('header_status_bar');
var err_box = document.getElementById('header_error_bar');
var response_json = JSON.parse(response.srcElement.responseText);
if(response.is_error){
err_box.textContent = "Full failure. Please verify that the entry does not already exist, or check the backend code!"
}else{
if(response_json.affected_rows > 0){
status_box.textContent = "Request completed successfully!"
}else if (response_json.affected_rows == -1){
err_box.textContent = "This entry already exists. Please make a unique entry!"
}else{
err_box.textContent = "No records exist, or a large error has occurred!"
}
}
populate_page_and_show_members();
}
function clear_dropdown(dropdown) {
while(dropdown.options.length > 0){
dropdown.remove(0);
}
}
////////// Load listener to populate page with data //////////
function populate_page_and_show_members(){
update_skill_dropdowns();
update_team_dropdowns();
update_position_dropdowns();
reset_inputs();
show_members();
}
function assign_window_event_handlers() {
document.getElementById('mem_add_submit').addEventListener('click', on_add_member_clicked);
document.getElementById('mem_del_submit').addEventListener('click', on_delete_member_clicked);
document.getElementById('assign_skill_submit').addEventListener('click', on_assign_skill_to_member_clicked);
document.getElementById('add_team_submit').addEventListener('click', on_assign_team_to_member_clicked);
document.getElementById('skill_add_submit').addEventListener('click', on_add_new_skill_clicked);
document.getElementById('team_add_submit').addEventListener('click', on_add_new_team_clicked);
document.getElementById('position_add_submit').addEventListener('click', on_add_new_position_clicked);
document.getElementById('show_members_submit').addEventListener('click', show_members);
document.getElementById('show_skills_submit').addEventListener('click', show_skills);
document.getElementById('show_teams_submit').addEventListener('click', show_teams);
document.getElementById('show_positions_submit').addEventListener('click', show_positions);
document.getElementById('skill_search_submit').addEventListener('click', show_with_skill);
document.getElementById('team_search_submit').addEventListener('click', show_with_team);
document.getElementById('position_search_submit').addEventListener('click', show_with_position);
}
function setup_page_on_load() {
populate_page_and_show_members();
assign_window_event_handlers();
}
window.addEventListener("load", setup_page_on_load);

View File

@@ -0,0 +1,5 @@
<?php
$db_host = 'oniddb.cws.oregonstate.edu';
$db_name = 'perrenc-db';
$db_user = 'perrenc-db';
$db_pass = 'rjqm1mGiAFpoEI8R';

View File

@@ -0,0 +1,57 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'On');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
INSERT INTO members(first_name, last_name, position, superior, email, phone, osu_num, rfid_num)
VALUES (
?,
?,
(SELECT id FROM club_positions cp WHERE cp.name = ?),
(SELECT id FROM club_positions cp WHERE cp.name = ?),
?,
?,
?,
?
)
QUERY_STRING
);
$db_query->bind_param("ssssssii", $_POST['first_name'], $_POST['last_name'], $_POST['position'],
$_POST['superior'], $_POST['email'], $_POST['phone'], $_POST['osu_num'], $_POST['rfid_num']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$resp_arr['affected_rows'] = $db_query->affected_rows;
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,46 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'On');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
INSERT INTO club_positions(name, description) VALUES (?, ?)
QUERY_STRING
);
$db_query->bind_param("ss", $_POST['name'], $_POST['description']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$resp_arr['affected_rows'] = $db_query->affected_rows;
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,46 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'On');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
INSERT INTO club_skills(name, description) VALUES (?, ?)
QUERY_STRING
);
$db_query->bind_param("ss", $_POST['name'], $_POST['description']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$resp_arr['affected_rows'] = $db_query->affected_rows;
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,46 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'On');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
INSERT INTO club_teams(name, description) VALUES (?, ?)
QUERY_STRING
);
$db_query->bind_param("ss", $_POST['name'], $_POST['description']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$resp_arr['affected_rows'] = $db_query->affected_rows;
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,50 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'On');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
INSERT INTO member_skills_relations(member_id, skills_id)
VALUES (
(SELECT id FROM members m WHERE m.first_name = ? AND m.last_name = ?),
(SELECT id from club_skills cs WHERE cs.name = ?)
)
QUERY_STRING
);
$db_query->bind_param("sss", $_POST['first_name'], $_POST['last_name'], $_POST['skill']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$resp_arr['affected_rows'] = $db_query->affected_rows;
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,50 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'On');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
INSERT INTO member_teams_relations(member_id, team_id)
VALUES (
(SELECT id FROM members m WHERE m.first_name = ? AND m.last_name = ?),
(SELECT id from club_teams ct WHERE ct.name = ?)
)
QUERY_STRING
);
$db_query->bind_param("sss", $_POST['first_name'], $_POST['last_name'], $_POST['team']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$resp_arr['affected_rows'] = $db_query->affected_rows;
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,115 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'Off');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
$affected_rows_total = 0;
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
########## DELETION FROM MEMBER SKILLS RELATIONS ##########
$db_query = $robo_db->prepare(<<<QUERY_STRING
DELETE FROM member_skills_relations
WHERE member_id IN (
SELECT id FROM members m
WHERE m.first_name = ? AND m.last_name = ?
)
QUERY_STRING
);
$db_query->bind_param("ss", $_POST['first_name'], $_POST['last_name']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$affected_rows_total += $db_query->affected_rows;
}
########## DELETION FROM MEMBER TEAMS RELATIONS ##########
$db_query = $robo_db->prepare(<<<QUERY_STRING
DELETE FROM member_teams_relations
WHERE member_id IN (
SELECT id FROM members m
WHERE m.first_name = ? AND m.last_name = ?
)
QUERY_STRING
);
$db_query->bind_param("ss", $_POST['first_name'], $_POST['last_name']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$affected_rows_total += $db_query->affected_rows;
}
########## DELETION FROM MEMBERS ##########
$db_query = $robo_db->prepare(<<<QUERY_STRING
DELETE FROM members
WHERE first_name = ? AND last_name = ?
QUERY_STRING
);
$db_query->bind_param("ss", $_POST['first_name'], $_POST['last_name']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$affected_rows_total += $db_query->affected_rows;
$resp_arr['affected_rows'] = $affected_rows_total;
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,55 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'Off');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
SELECT m.first_name, m.last_name, cp.name
FROM club_positions cp
INNER JOIN members m ON m.position = cp.id
WHERE cp.name = ?;
QUERY_STRING
);
$db_query->bind_param("s", $_POST['name']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$db_query->bind_result($first_name, $last_name, $position);
while($entry = $db_query->fetch()){
$resp_arr['members'][] = array($first_name, $last_name, $position);
}
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,56 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'Off');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
SELECT om.first_name, om.last_name, cs.name
FROM members om
INNER JOIN member_skills_relations msr ON om.id = msr.member_id
INNER JOIN club_skills cs ON cs.id = msr.skills_id
WHERE cs.name = ?
QUERY_STRING
);
$db_query->bind_param("s", $_POST['name']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$db_query->bind_result($first_name, $last_name, $skill);
while($entry = $db_query->fetch()){
$resp_arr['members'][] = array($first_name, $last_name, $skill);
}
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,56 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'Off');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
SELECT om.first_name, om.last_name, ct.name
FROM members om
INNER JOIN member_teams_relations mtr ON om.id = mtr.member_id
INNER JOIN club_teams ct ON ct.id = mtr.team_id
WHERE ct.name = ?
QUERY_STRING
);
$db_query->bind_param("s", $_POST['name']);
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Parameter bind failed!";
echo json_encode($resp_arr);
return;
}
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$db_query->bind_result($first_name, $last_name, $team);
while($entry = $db_query->fetch()){
$resp_arr['members'][] = array($first_name, $last_name, $team);
}
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,56 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'Off');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
SELECT
om.first_name,
om.last_name,
(SELECT name FROM club_positions cp
INNER JOIN members m ON m.position = cp.id
WHERE m.first_name = om.first_name AND m.last_name = om.last_name),
(SELECT name FROM club_positions cp
INNER JOIN members m ON m.superior = cp.id
WHERE m.first_name = om.first_name AND m.last_name = om.last_name),
om.email,
om.phone,
om.osu_num,
om.rfid_num
FROM members om;
QUERY_STRING
);
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$db_query->bind_result($first_name, $last_name, $position, $superior, $email, $phone, $osu_num, $rfid_num);
while($entry = $db_query->fetch()){
$resp_arr['members'][] = array($first_name, $last_name, $position, $superior, $email, $phone, $osu_num, $rfid_num);
}
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,43 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'Off');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
SELECT name, description from club_positions GROUP BY id DESC
QUERY_STRING
);
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$db_query->bind_result($position_name, $position_description);
while($entry = $db_query->fetch()){
$resp_arr['positions'][] = array($position_name, $position_description);
}
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,43 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'On');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
SELECT name, description from club_skills GROUP BY id ASC
QUERY_STRING
);
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$db_query->bind_result($skill_name, $skill_description);
while($entry = $db_query->fetch()){
$resp_arr['skills'][] = array($skill_name, $skill_description);
}
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,43 @@
<?php
include '../db_creds.php';
ini_set('display_errors', 'On');
$robo_db = new mysqli($db_host, $db_user, $db_pass, $db_name);
$resp_arr = array();
if($robo_db->connect_errno){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Failed to connect to database!";
echo json_encode($resp_arr);
return;
}else{
$db_query = $robo_db->prepare(<<<QUERY_STRING
SELECT name, description from club_teams GROUP BY id ASC
QUERY_STRING
);
$db_query->execute();
if(!$db_query){
$resp_arr['is_error'] = true;
$resp_arr['error_reason'] = "Database query failed!";
$resp_arr['mysqli_errno'] = $db_query->errno;
$resp_arr['mysqli_error'] = $db_query->error;
echo json_encode($resp_arr);
return;
}else{
$resp_arr['is_error'] = false;
$db_query->bind_result($team_name, $team_description);
while($entry = $db_query->fetch()){
$resp_arr['teams'][] = array($team_name, $team_description);
}
echo json_encode($resp_arr);
}
}

View File

@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CS340 Final Website - Corwin Perren</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="app.js"></script>
</head>
<body>
<div id="page_header">
<h1>CS 340 Robotics Club User Management System</h1>
</div>
<div>
<span id="status_header">Status: </span><span id="header_status_bar"></span>
</div>
<div>
<span id="error_header">Errors: </span><span id="header_error_bar"></span>
</div>
<div id="mem_man_div">
<h2>Member Management</h2>
<span class="man_row_titles">MEMBER ADD: </span>
<span>First: </span><input class="mem_man_text_input" type="text" id="mem_add_first_name">
<span>Last: </span><input class="mem_man_text_input" type="text" id="mem_add_last_name">
<span>Position: </span><select id="mem_add_position_drop"></select>
<span>Superior: </span><select id="mem_add_superior_drop"></select>
<span>Email: </span><input class="mem_man_text_input" type="text" id="mem_add_email">
<span>Phone #: </span><input class="mem_man_text_input" type="text" id="mem_add_phone">
<span>OSU ID: </span><input class="mem_man_text_input" type="number" id="mem_add_osuid">
<span>RFID #: </span><input class="mem_man_text_input" type="number" id="mem_add_rfid">
<button id="mem_add_submit" type="button">Add</button>
<br><br>
<span class="man_row_titles">MEMBER DEL: </span>
<span>First: </span><input class="mem_man_text_input" type="text" id="mem_del_first_name">
<span>Last: </span><input class="mem_man_text_input" type="text" id="mem_del_last_name">
<button id="mem_del_submit" type="button">Delete</button>
<br><br>
<span class="man_row_titles">ASSIGN SKILL: </span>
<span>First: </span><input class="mem_man_text_input" type="text" id="assign_skill_first_name">
<span>Last: </span><input class="mem_man_text_input" type="text" id="assign_skill_last_name">
<span>Skill: </span><select id="assign_skill_position_drop"></select>
<button id="assign_skill_submit" type="button">Assign</button>
<br><br>
<span class="man_row_titles">ADD TO TEAM: </span>
<span>First: </span><input class="mem_man_text_input" type="text" id="add_team_first_name">
<span>Last: </span><input class="mem_man_text_input" type="text" id="add_team_last_name">
<span>Team: </span><select id="add_team_position_drop"></select>
<button id="add_team_submit" type="button">Add</button>
</div>
<div id="infra_man_div">
<h2>Infrastructure Management</h2>
<span class="man_row_titles">SKILL ADD: </span>
<span>Name: </span><input class="mem_man_text_input" type="text" id="skill_add_name">
<span>Description: </span><input class="mem_man_text_input" type="text" id="skill_add_description">
<button id="skill_add_submit" type="button">Add</button>
<br><br>
<span class="man_row_titles">TEAM ADD: </span>
<span>Name: </span><input class="mem_man_text_input" type="text" id="team_add_name">
<span>Description: </span><input class="mem_man_text_input" type="text" id="team_add_description">
<button id="team_add_submit" type="button">Add</button>
<br><br>
<span class="man_row_titles">POSITION ADD: </span>
<span>Name: </span><input class="mem_man_text_input" type="text" id="position_add_name">
<span>Description: </span><input class="mem_man_text_input" type="text" id="position_add_description">
<button id="position_add_submit" type="button">Add</button>
</div>
<div id="queries_div">
<h2>Display Controls</h2>
<div id="queries_left">
<span class="man_row_titles">SHOW MEMBERS: </span>
<button id="show_members_submit" type="button">SHOW</button>
<br><br>
<span class="man_row_titles">SHOW SKILLS: </span>
<button id="show_skills_submit" type="button">SHOW</button>
<br><br>
<span class="man_row_titles">SHOW TEAMS: </span>
<button id="show_teams_submit" type="button">SHOW</button>
<br><br>
<span class="man_row_titles">SHOW POSITIONS: </span>
<button id="show_positions_submit" type="button">SHOW</button>
</div>
<div id="queries_right">
<br><br>
<span class="man_row_titles">FIND MEMBERS WITH SKILL: </span>
<span>Skill: </span><select id="show_with_skill_drop"></select>
<button id="skill_search_submit" type="button">SEARCH</button>
<br><br>
<span class="man_row_titles">FIND MEMBERS WITH TEAM: </span>
<span>Team: </span><select id="show_with_team_drop"></select>
<button id="team_search_submit" type="button">SEARCH</button>
<br><br>
<span class="man_row_titles">FIND MEMBERS WITH POSITION: </span>
<span>Position: </span><select id="show_with_position_drop"></select>
<button id="position_search_submit" type="button">SEARCH</button>
</div>
</div>
<div id="main_output_div">
<div id="main_output_content">
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,52 @@
body {
background-color: #353535 ;
color: #e6e6e6;
margin: 0;
padding: 0;
}
#error_header {
color: #ff0001;
}
#page_header {
margin-top: 0;
margin-left: 0;
margin-right: 0;
text-align: center;
background-color: black;
color: #10ac25;
}
#page_header h1 {
margin: 0;
padding: 0;
}
.man_row_titles {
color: #10ac25;
padding-right: 20px;
}
.mem_man_text_input {
width: 75px;
}
#queries_left {
float: left;
}
#queries_right {
margin-left: 300px;
}
#main_output_div {
border-top: 2px solid #10ac25;
margin-top: 25px;
}
.results_table table, th, td{
border: 1px solid #e6e6e6;
padding: 2px;
border-collapse: collapse;
}

View File

@@ -0,0 +1,301 @@
#!/bin/bash
#
# Program 1
#
# To create a test run of your program put this file and your stats
# program, which must be named "stats", together in a directory. Then run
# this command, which will take perhaps 15 seconds:
#
# % p1gradingscript > p1results
#
# Your whole program must be contained in the single file named "stats".
#
LS=/bin/ls
RM=rm
PS=/bin/ps
TESTDIR=assign1.test.$$
STATS=./stats
if test -d $TESTDIR
then
echo Please rename or remove $TESTDIR
exit 1
fi
mkdir $TESTDIR 2>&1
cp stats $TESTDIR 2>&1
cd $TESTDIR 2>&1
chmod +x stats 2>&1
echo --------------------------------------------------------------------------
echo Creating file1 file2 file3 file4 file5
echo
cat > file1 <<EOF
93 93 93 93 93 93 93 93 100
73 84 95 83 72 86 80 97 100
85 0 82 75 88 79 80 81 100
85 0 87 73 88 79 80 71 100
80 81 83 63 100 85 63 68 100
53 57 61 53 70 61 73 50 100
55 54 41 63 63 45 33 41 100
53 55 43 44 63 75 35 21 100
100 100 100 100 100 100 100 100 100
EOF
cat > file2 <<EOF
97 95 93 91
86 80 97 99
61 73 50 100
95 94 93 92
EOF
cat > file3 <<EOF
17
EOF
cat > file4 <<EOF
EOF
i=0
while [ $i -lt 50000 ]
do
echo "$i `expr $i \* 2`"
i=`expr $i + 100`
done > file5
echo
$LS -l 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 1 Statistics by Rows: 1 point per correct number: 18
echo
$STATS -rows file1 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo Check for Temporary Files: 5 points if no temp files
echo
$LS 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 1 Statistics by Cols: 1 point per correct number: 18
echo
$STATS -cols file1 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo Check for Temporary Files: 5 points if no temp files
echo
$LS 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 2 Statistics by Rows: 1 point per correct number: 8
echo
$STATS -rows file2 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 2 Statistics by Cols: 1 point per correct number: 8
echo
$STATS -cols file2 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 3 Statistics by Rows: 1 point per correct number: 2
echo
$STATS -rows file3 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 3 Statistics by Cols: 1 point per correct number: 2
echo
$STATS -cols file3 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 4 Statistics by Rows: lose 3 points if response not something like FILE IS EMPTY
echo
$STATS -rows file4 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 4 Statistics by Cols: lose 3 points if response not something like FILE IS EMPTY
echo
$STATS -cols file4 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo File 5 Statistics by Cols: 1 point per number: 4
echo
$STATS -cols file5 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo Check for Temporary Files: 5 points if no temp files
echo
$LS 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo Good Syntax
echo
echo Standard Input on Rows: 2 points for exit value 0, 1 point for no error text
$STATS -rows < file2 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo Standard Input on Cols: 2 points for exit value 0, 1 point for no error text
$STATS -cols < file2 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo Option -cols: 2 points for exit value 0, 1 point for no error text
$STATS -cols file2 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo Option -rrrrrr: 2 points for exit value 0, 1 point for no error text
$STATS -rrrrrr file2 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo Option -cccccc: 3 points for exit value 0
$STATS -cccccc file2 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo Option -r: 3 points for exit value 0
$STATS -r file2 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo
echo --------------------------------------------------------------------------
echo Bad Syntax
echo
echo Too Few Arguments: 1 point for usage text, 2 points for exit value 1
$STATS 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo Too Many Arguments: 1 point for usage text, 2 points for exit value 1
$STATS -r file1 file2 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo Wrong Format: 1 point for usage text, 2 points for exit value 1
$STATS file1 file2 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo Bad Option: 1 point for usage text, 2 points for exit value 1
$STATS -x file1 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
echo
echo --------------------------------------------------------------------------
echo File Not Readable: 2 points for error msg, 2 points for program halting
echo
chmod 000 file3 2>&1
echo
$STATS -r file3 2> err.out
echo Exit Value: $?
echo Error Message:
cat err.out
echo
$RM -f err.out 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo Check for Temporary Files: 5 points for no temp files
echo
$LS 2>&1
echo
echo
echo --------------------------------------------------------------------------
echo Simultaneous Runs
echo
$STATS -rows < file1 > simrun1.out 2>&1 &
PID1=$!
$STATS -rows < file1 > simrun2.out 2>&1 &
PID2=$!
$STATS -rows < file1 > simrun3.out 2>&1 &
PID3=$!
sleep 2
echo
echo Before Finishing
$LS 2>&1
echo
while ($PS | egrep "^ *($PID1)|($PID2)|($PID3)" > /dev/null)
do
echo waiting...
sleep 5
done
echo
echo Run 1 Output: 5 points for succesful run 1
cat simrun1.out 2>&1
echo
echo Run 2 Output: 5 points for succesful run 2
cat simrun2.out 2>&1
echo
echo Run 3 Output: 5 points for succesful run 3
cat simrun3.out 2>&1
echo
$RM -f simrun[123].out 2>&1
echo
echo After Finishing: 5 points if no temp file
$LS 2>&1
echo
echo
echo Trap Signals
echo
$STATS -rows < file5 > /dev/null &
PID=$!
sleep 2
echo
echo Before Kill
$LS 2>&1
echo
$PS
echo
kill $PID
sleep 5
echo
echo After Kill: 8 points if no temp files
$LS 2>&1
echo
$PS
echo
echo
cd ..
$RM -rf $TESTDIR 2>&1

View File

@@ -0,0 +1,32 @@
stats {-rows|-cols} [input_file]
DONE: Numbers are separated by tabs, lines by newlines
DONE: Check for the correct number of arguments, failure to standard error
DONE: Check whether file is readable, or exists, stderr if not
DONE: -rows and -cols should work for anything that starts with its character eg. -rad would do rows
Stats output to stdout
Exit value for errors should be 1
You can assume each row will be less than 1000 bytes long, unix limits this, but unlimited numbers of rows
DONE: If using temp files, make sure they include process id's in name to allow for simultaneous runs. Remove files when done.
DONE: Use the trap command to catch interrupt, hangup, and terminate signals to remove temp files if terminates unexpectedly
Values and results must be whole numbers, round like normal, 7.5 to 8, 7.4 to 7
DONE: Calculations must be done with expr or commandline tools. No other languages
DONE: For median, sort values and take the middle value. If even, take the larger of the middle two values.
DONE: Must be in a single file.
DONE: You can return an error if there is no input file
HINTS

View File

@@ -0,0 +1,35 @@
% cat test_file
1 1 1 1 1
9 3 4 5 5
6 7 8 9 7
3 6 8 9 1
3 4 2 1 4
6 4 4 7 7
% stats -rows test_file
Average Median
1 1
5 5
7 7
5 6
3 3
6 6
% cat test_file | stats c
Averages:
5 4 5 5 4
Medians:
6 4 4 7 5
% echo $?
0
% stats
Usage: stats {-rows|-cols} [file]
% stats -r test_file nya-nya-nya
Usage: stats {-rows|-cols} [file]
% stats -both test_file
Usage: stats {-rows|-cols} [file]
% chmod -r test_file
% stats -columns test_file
stats: cannot read test_file
% stats -columns no_such_file
stats: cannot read no_such_file
% echo $?
1

View File

@@ -0,0 +1,235 @@
#!/bin/bash
########## Programmer Info ############
# Name: Corwin Perren
# OSU ID: 931759527
# Assignment: Assignment 1 - stats
# Filename: stats
########## Global Variables ############
# Used for transposing the axis on a two dimensional array
awk_transpose='{
for ( i=1; i <= NF; i++ )
row[i] = row[i]((row[i])?" ":"")$i
}
END{
for ( x = 1; x <= length(row) ; x++ )
print row[x]
}'
# Used to properly round the floating point values
awk_proper_rounding='
{printf("%d\n",$1 + 0.5)}
'
# Stores the PID used to name and delete temp files
master_pid=$!
########## Functions ###########
# Error function for when user input is wrong
show_usage_error ()
{
echo "Usage: stats {-rows|-cols} [file]" >&2
exit 1
}
# Error function for when a user feeds in an empty file
show_empty_file_error ()
{
echo "stats: Input empty. Please provide valid input." >&2
exit 1
}
# Error function for when the file doesn't exist or can't be accessed
show_invalid_file_error ()
{
echo "stats: Cannot read file. Please verify file exists or check permissions." >&2
exit 1
}
# Function to delete temporary files
remove_temp_if_exist ()
{
rm -f ${master_pid}"_"transposed
rm -f ${master_pid}"_"temp
}
# Function to handle file cleanup and returning an error when an interrupt happens
handle_unexpected_termination_error ()
{
remove_temp_if_exist
echo "CTRL+C received. Exiting." >&2
exit 1
}
#####################################################
#####################################################
########## "stats" script "main"-ish code ###########
# Handle unexpected termination
trap handle_unexpected_termination_error INT HUP TERM
# Determine if we're getting data from stdin or a file, error if neither
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
show_usage_error
elif [ $# -eq 1 ]; then
is_stdin=1
elif [ $# -eq 2 ]; then
is_stdin=0
fi
# Determine if we're doing statistics based on columns or rows, error if neither
if [[ $1 == -r* ]]; then
is_rows=1
elif [[ $1 == -c* ]]; then
is_rows=0
else
show_usage_error
fi
# If the input is a file, make sure we can open it and that it exists
if [ ${is_stdin} -eq 0 ]; then
if [ ! -e $2 ] || [ ! -r $2 ] || [ ! -f $2 ]; then
show_invalid_file_error
fi
fi
# If stats should be on columns, transpose the table so the columns are the new rows and rows are the new columns
# This will make it so the same stats math can be used to generate the correct data
# If the data is coming from stdin and needs to be columns, it makes a temp file, stores the data in it, and then
# transposes it just as if it were a file being fed in as an argument
# If the flags here are anything but a standard in piping with rows, it opens the file with a file descriptor for access
# This also handles showing an error if the input from stdin with -cols is empty
if [ ${is_rows} -eq 0 ] && [ ${is_stdin} -eq 0 ]; then
cat $2 | awk "${awk_transpose}" > ${master_pid}"_"transposed
exec 3<> ${master_pid}"_"transposed
elif [ ${is_rows} -eq 0 ] && [ ${is_stdin} -eq 1 ]; then
line_count=0
while read current_line
do
echo -e ${current_line} >> ${master_pid}"_"temp
((line_count = line_count + 1))
done
if [ ${line_count} -eq 0 ]; then
show_empty_file_error
fi
cat ${master_pid}"_"temp | awk "${awk_transpose}" > ${master_pid}"_"transposed
exec 3<> ${master_pid}"_"transposed
is_stdin=0
elif [ ${is_rows} -eq 1 ] && [ ${is_stdin} -eq 0 ]; then
exec 3<> $2
fi
# Now we perform the stats math operations on the data
line_count=0
declare -a averages
declare -a medians
while [ 1 ];
do
# We read in the current line
if [ ${is_stdin} -eq 1 ]; then
read current_line
else
read -u 3 current_line
fi
# Here we get the result code from read, which tells us if there's data left
read_result=$?
# If there was no data, and we haven't looped yet, the file is empty and we error
# Otherwise, it means we've reached the end of the file and it's time to leave the loop
if [ ${read_result} -eq 1 ] && [ ${line_count} -eq 0 ]; then
show_empty_file_error
elif [ ${read_result} -eq 1 ]; then
break
fi
# Initialize variables for doing the calculations
sum=0
count=0
avg=0
newline="\n"
numbers_string=""
# This part does the summing and adds the numbers to a new string so it can be parsed by sort
for word in ${current_line}
do
numbers_string=${numbers_string}${newline}${word}
((sum = word + sum))
((count = count + 1))
done
# Here we use bc and awk to handle the floating point results of division and proper rounding
# The avg then gets added to the average array for display later
avg=$(echo "(${sum}/${count})" | bc -l | awk "${awk_proper_rounding}")
averages[${line_count}]=${avg}
# Now the new string we created is sorted numerically so we can easily find the median
sorted=$(echo -e ${numbers_string} | sort -n)
# Then we find and add the median number to our medians array
i=0
for word in ${sorted}
do
if [ ${i} == $(((count/2))) ]; then
medians[${line_count}]=${word}
break
fi
((i = i + 1))
done
# Here we increment our line count so we can properly handle empty files
((line_count = line_count + 1))
done
# For rows display, we print out the header then one value from averages and count, separated by tabs
if [ ${is_rows} -eq 1 ]; then
echo -e "Average\tMedian"
count=0
for word in ${averages[*]}
do
echo -e "${averages[count]}\t${medians[count]}"
((count = count + 1))
done
# For cols display, we print a header, then all the contents of average, another header, and the contents of median
# Takes a little more work to print this one and not have extra tabs left over
else
echo -e "Averages:"
first=1
for word in ${averages[*]}
do
if [ ${first} -eq 1 ]; then
echo -e -n "${word}"
first=0
else
echo -e -n "\t${word}"
fi
((count = count + 1))
done
echo
echo -e "Medians:"
first=1
for word in ${medians[*]}
do
if [ ${first} -eq 1 ]; then
echo -e -n "${word}"
first=0
else
echo -e -n "\t${word}"
fi
((count = count + 1))
done
echo
fi
# Assuming we make it this far, the trap handler will not have taken care of our temp files, so we do that now
remove_temp_if_exist
# Again, having made it this far the program has completed successfully. Exit with no error.
exit 0

View File

@@ -0,0 +1,128 @@
#
# There exist several targets which are by default empty and which can be
# used for execution of your targets. These targets are usually executed
# before and after some main targets. They are:
#
# .build-pre: called before 'build' target
# .build-post: called after 'build' target
# .clean-pre: called before 'clean' target
# .clean-post: called after 'clean' target
# .clobber-pre: called before 'clobber' target
# .clobber-post: called after 'clobber' target
# .all-pre: called before 'all' target
# .all-post: called after 'all' target
# .help-pre: called before 'help' target
# .help-post: called after 'help' target
#
# Targets beginning with '.' are not intended to be called on their own.
#
# Main targets can be executed directly, and they are:
#
# build build a specific configuration
# clean remove built files from a configuration
# clobber remove all built files
# all build all configurations
# help print help mesage
#
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
# .help-impl are implemented in nbproject/makefile-impl.mk.
#
# Available make variables:
#
# CND_BASEDIR base directory for relative paths
# CND_DISTDIR default top distribution directory (build artifacts)
# CND_BUILDDIR default top build directory (object files, ...)
# CONF name of current configuration
# CND_PLATFORM_${CONF} platform name (current configuration)
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
#
# NOCDDL
# Environment
MKDIR=mkdir
CP=cp
CCADMIN=CCadmin
# build
build: .build-post
.build-pre:
# Add your pre 'build' code here...
.build-post: .build-impl
# Add your post 'build' code here...
# clean
clean: .clean-post
.clean-pre:
# Add your pre 'clean' code here...
.clean-post: .clean-impl
# Add your post 'clean' code here...
# clobber
clobber: .clobber-post
.clobber-pre:
# Add your pre 'clobber' code here...
.clobber-post: .clobber-impl
# Add your post 'clobber' code here...
# all
all: .all-post
.all-pre:
# Add your pre 'all' code here...
.all-post: .all-impl
# Add your post 'all' code here...
# build tests
build-tests: .build-tests-post
.build-tests-pre:
# Add your pre 'build-tests' code here...
.build-tests-post: .build-tests-impl
# Add your post 'build-tests' code here...
# run tests
test: .test-post
.test-pre: build-tests
# Add your pre 'test' code here...
.test-post: .test-impl
# Add your post 'test' code here...
# help
help: .help-post
.help-pre:
# Add your pre 'help' code here...
.help-post: .help-impl
# Add your post 'help' code here...
# include project implementation makefile
include nbproject/Makefile-impl.mk
# include project make variables
include nbproject/Makefile-variables.mk

View File

@@ -0,0 +1,673 @@
/* ///////////////////////////////////////// */
/* ///////// Includes and Defines ////////// */
/* ///////////////////////////////////////// */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <assert.h>
#include <time.h>
/* ///////////////////////////////////// */
/* ///////// Global Variables ////////// */
/* ///////////////////////////////////// */
/* Room variables */
char* room_filenames[] = {
"room_1.txt",
"room_2.txt",
"room_3.txt",
"room_4.txt",
"room_5.txt",
"room_6.txt",
"room_7.txt"
};
char* rooms_directory_base = "perrenc.rooms.";
char rooms_directory_full[255];
char *potential_room_names[10] = {
"Dearborn",
"Graf",
"Rogers",
"Covell",
"Batcheller",
"Kidder",
"Valley Library",
"Memorial Union",
"Gilbert",
"Weniger"
};
unsigned int min_connections = 3;
unsigned int max_connections = 6;
char* current_room_filename;
char path_taken[255][15];
unsigned int num_steps = 0;
/* File access variables */
FILE *file_pointer_main;
FILE *file_pointer_time;
/* Threading variables */
pthread_t time_thread_ID;
bool time_written = false;
char* time_file_name = "currentTime.txt";
pthread_mutex_t time_mutex;
/* State Handling Variables */
bool game_over = false;
bool delete_folder_and_files = true;
/* State Variables */
bool valid_input = false;
bool first_print = true;
/* //////////////////////////////////////// */
/* ///////// Function Prototypes ////////// */
/* //////////////////////////////////////// */
/* Initialization functions */
void program_init(void);
void generate_rooms(void);
/* User Input and Printing Functions */
void print_current_room_and_prompt(void);
void get_user_input_and_process(void);
void print_game_over(void);
/* Room Specific Functions*/
void create_room(char *room_filename, char *room_name, char* room_type);
void add_connection_to_room(char *room_filename, char *room_name_to_add);
unsigned int get_number_of_connections_from_room(char *room_filename);
bool is_room_used(char* room_name);
bool is_end_room(char* room_filename);
void get_room_name(char* room_filename, char* room_name_buffer);
int get_room_index_from_name(char* room_name);
int get_used_indexes(char* room_filename, int* output_list);
/* Threading Functions */
void print_time(void);
/* Threading Functions */
void* get_time(void *arguments);
/* Helper Functions */
FILE *open_file_local_folder(char *file_name, char *mode);
int delete_file_local_folder(char *file_name);
/* ///////////////////////// */
/* ///////// Main ////////// */
/* ///////////////////////// */
int main(int argc, char** argv) {
program_init();
generate_rooms();
while(!game_over){
print_current_room_and_prompt();
while(!valid_input){
get_user_input_and_process();
}
valid_input = false;
}
print_game_over();
return (EXIT_SUCCESS);
}
/* ///////////////////////////////////////////// */
/* ///////// Initialization Functions ////////// */
/* ///////////////////////////////////////////// */
void program_init(void){
char pid_buffer[20];
memset(pid_buffer, '\0', 20);
/* Initialize our mutex */
assert(pthread_mutex_init(&time_mutex, NULL) == 0);
/* Make the rooms directory string we'll be using */
memset(rooms_directory_full, '\0', 255);
sprintf(pid_buffer, "%d", getpid());
strcat(rooms_directory_full, rooms_directory_base);
strcat(rooms_directory_full, pid_buffer);
/* Create the directory now that we have the string */
mkdir(rooms_directory_full, 0770);
/* Select the start room as the start point */
current_room_filename = room_filenames[0];
}
void generate_rooms(void){
time_t t;
bool start_used = false;
bool end_used = false;
char num_rooms = sizeof(room_filenames) / sizeof(room_filenames[0]);
srand((unsigned) time(&t));
/* Generate base rooms with room name and room type */
int i;
for(i = 0 ; i < num_rooms ; i++){
/* Get a random room name */
int random_num_name = rand() % 10;
char* current_room_name = potential_room_names[random_num_name];
/* If that name is already used, generate a unique one */
while(is_room_used(current_room_name)){
random_num_name = rand() % 10;
current_room_name = potential_room_names[random_num_name];
}
/* Make the start room if it hasn't been made yet */
if(!start_used){
create_room(room_filenames[i], current_room_name, "START_ROOM");
start_used = true;
/* Make the end room if it hasn't been made yet */
}else if(!end_used){
create_room(room_filenames[i], current_room_name, "END_ROOM");
end_used = true;
/* Make the middle rooms, if the start and ends rooms are made */
}else{
create_room(room_filenames[i], current_room_name, "MID_ROOM");
}
}
/* Generate the room connections for each room */
for(i = 0 ; i < num_rooms ; i++){
char buffer[255];
int used_rooms[6];
/* Initialize used rooms array with invalid numbers */
int l;
for(l = 0 ; l < 6 ; l++){
used_rooms[l] = -1;
}
/* Get random number between min and max connections */
int num_connections = (rand() % 4) + min_connections - \
get_number_of_connections_from_room(room_filenames[i]);
/* Generate the connections for an individual room */
int j;
for(j = 0 ; j < num_connections ; j++){
int room_to_add;
bool unused_found = false;
/* Generate connections, making sure they're not itself or other
rooms that have already been used */
while(!unused_found){
room_to_add = rand() % 7;
/* Skip if room is itself */
if(room_to_add == i){
continue;
}
/* Make sure that we're not adding a room that's already a
connection */
bool already_exists = false;
get_used_indexes(room_filenames[i], used_rooms);
int k;
for(k = 0 ; k < 6 ; k++){
if(used_rooms[k] == room_to_add){
already_exists = true;
break;
}
}
/* Make sure the connecting room can handle the reverse
connection */
if(get_number_of_connections_from_room(\
room_filenames[room_to_add]) == max_connections){
already_exists = true;
}
/* If all is good, set flag to exit loop */
if(!already_exists){
unused_found = true;
}
}
/* Once a connection has been deemed valid, add forward and
backwards connections */
memset(buffer, '\0', 255);
get_room_name(room_filenames[room_to_add], buffer);
add_connection_to_room(room_filenames[i], buffer);
memset(buffer, '\0', 255);
get_room_name(room_filenames[i], buffer);
add_connection_to_room(room_filenames[room_to_add], buffer);
}
}
}
/* //////////////////////////////////////////////// */
/* ///////// User Input and Printing Functions //// */
/* //////////////////////////////////////////////// */
void print_current_room_and_prompt(void){
char current_line[255];
char print_buffer[255];
char* tokenized;
memset(current_line, '\0', 255);
memset(print_buffer, '\0', 255);
file_pointer_main = open_file_local_folder(current_room_filename, "r");
/* Print location header */
if(first_print){
printf("CURRENT LOCATION: ");
first_print = false;
}else{
printf("\nCURRENT LOCATION: ");
}
/* Strip out and print current room name */
fgets(current_line, 255, file_pointer_main);
tokenized = strtok(current_line, ":");
tokenized = strtok(NULL, " \n");
bool first_entry = true;
while(tokenized != NULL){
if(first_entry){
first_entry = false;
}else{
printf(" ");
}
printf("%s", tokenized);
tokenized = strtok(NULL, " \n");
}
/* Print possible connections header */
printf("\nPOSSIBLE CONNECTIONS: ");
/* Loop through connections and print names with separators */
bool printing_connections = true;
bool printed_first_connection = false;
while(printing_connections){
fgets(current_line, 255, file_pointer_main);
tokenized = strtok(current_line, " ");
if(strcmp(tokenized, "CONNECTION") != 0){
printing_connections = false;
break;
}
if(printed_first_connection){
printf(", ");
}else{
printed_first_connection = true;
}
tokenized = strtok(NULL, ":");
tokenized = strtok(NULL, " \n");
bool first_entry = true;
while(tokenized != NULL){
if(first_entry){
first_entry = false;
}else{
printf(" ");
}
printf("%s", tokenized);
tokenized = strtok(NULL, " \n");
}
}
printf(".");
fclose(file_pointer_main);
}
void get_user_input_and_process(void){
char buffer[255];
memset(buffer, '\0', 255);
/* Print where to header */
printf("\nWHERE TO? >");
/* Read in newline terminated string from user, and strip out the newline*/
fgets(buffer, 255, stdin);
buffer[strlen(buffer)-1] = '\0';
/* Check input to determine if valid and what it should do*/
int room_index = get_room_index_from_name(buffer);
if(room_index != -1){
/* Room change is valid, change room and log */
strcpy(path_taken[num_steps], buffer);
num_steps++;
current_room_filename = room_filenames[room_index];
valid_input = true;
}else if(strcmp(buffer, "time") == 0){
/* Request was to print time, do so */
print_time();
}else{
/* Bad input was entered, print input error message */
printf("\nHUH? I DON'T UNDERSTAND THAT ROOM. TRY AGAIN.\n");
valid_input = true;
}
/* Set game over flag to the result of whether we're in the end room */
game_over = is_end_room(current_room_filename);
}
void print_game_over(void){
/* Print game over header */
printf("\nYOU HAVE FOUND THE END ROOM. CONGRATULATIONS!");
printf("\nYOU TOOK %u STEPS. YOUR PATH TO VICTORY WAS:", num_steps);
/* Print path taken to game over*/
int i;
for(i = 0 ; i < num_steps ; i++){
printf("\n%s", path_taken[i]);
}
printf("\n");
}
/* ////////////////////////////////////// */
/* ///////// Room Specific Functions //// */
/* ////////////////////////////////////// */
void create_room(char *room_filename, char *room_name, char* room_type){
file_pointer_main = open_file_local_folder(room_filename, "w");
assert(file_pointer_main != NULL);
/* Print line for the room name */
fputs("ROOM NAME: ", file_pointer_main);
fputs(room_name, file_pointer_main);
fputs("\n", file_pointer_main);
/* Print line for the room type */
fputs("ROOM TYPE: ", file_pointer_main);
fputs(room_type, file_pointer_main);
fclose(file_pointer_main);
}
void add_connection_to_room(char *room_filename, char *room_name_to_add){
char output_string_buffer[255];
char room_type_save_buffer[255];
unsigned int newline_count = 0;
unsigned int line_to_insert_at = 0;
long insertion_position = 0;
memset(output_string_buffer, '\0', 255);
memset(room_type_save_buffer, '\0', 255);
/* Determine where the new connection line will sit */
line_to_insert_at = get_number_of_connections_from_room(room_filename);
/* Add one to skip room name line */
line_to_insert_at++;
file_pointer_main = open_file_local_folder(room_filename, "r+");
/* Count out way to where we insert the new connection */
while(newline_count != line_to_insert_at){
if(fgetc(file_pointer_main) == '\n'){
newline_count++;
}
}
/* Save insertion position and make backup of line that will be wiped out */
insertion_position = ftell(file_pointer_main);
fgets(room_type_save_buffer, 255, file_pointer_main);
fseek(file_pointer_main, insertion_position, SEEK_SET);
/* Save new connection line and add the saved one after it */
sprintf(output_string_buffer, "CONNECTION %u: %s\n", line_to_insert_at, \
room_name_to_add);
fputs(output_string_buffer, file_pointer_main);
fputs(room_type_save_buffer, file_pointer_main);
fclose(file_pointer_main);
}
unsigned int get_number_of_connections_from_room(char *room_filename){
char current_line[255];
char* tokenized;
unsigned int number_of_rooms = 0;
memset(current_line, '\0', 255);
file_pointer_main = open_file_local_folder(room_filename, "r");
/* Loop through the lines and count the number of connections we have */
while(fgets(current_line, 255, file_pointer_main) != NULL){
tokenized = strtok(current_line, " ");
if(strcmp("CONNECTION", tokenized) == 0){
number_of_rooms++;
}
}
fclose(file_pointer_main);
return number_of_rooms;
}
bool is_room_used(char* room_name){
char num_rooms = sizeof(room_filenames) / sizeof(room_filenames[0]);
char room_name_buffer[255];
/* Loop through all files and strcmp to see if it's been used already */
int i;
for(i = 0 ; i < num_rooms ; i++){
memset(room_name_buffer, '\0', 255);
get_room_name(room_filenames[i], room_name_buffer);
/* printf("Comparing %s to %s\n", room_name, room_name_buffer); */
if(strcmp(room_name_buffer, room_name) == 0){
return true;
}
}
return false;
}
bool is_end_room(char* room_filename){
char current_line[255];
char* tokenized;
memset(current_line, '\0', 255);
file_pointer_main = open_file_local_folder(room_filename, "r");
/* Run through file until room type, check if room is end room*/
while(fgets(current_line, 255, file_pointer_main) != NULL){
tokenized = strtok(current_line, ":");
if(strcmp("ROOM TYPE", tokenized) == 0){
tokenized = strtok(NULL, " \n");
if(strcmp(tokenized, "END_ROOM") == 0){
fclose(file_pointer_main);
return true;
}
}
}
fclose(file_pointer_main);
return false;
}
void get_room_name(char* room_filename, char* room_name_buffer){
char current_line[255];
char* tokenized;
memset(current_line, '\0', 255);
file_pointer_main = open_file_local_folder(room_filename, "r");
/* Return immediately if file does not yet exist */
if(file_pointer_main == NULL){
strcpy(room_name_buffer, "___NOT_A_ROOM_NAME____");
return;
}
/* Run through file and get room name with special handling for spaces */
while(fgets(current_line, 255, file_pointer_main) != NULL){
/*strcpy(current_line_backup, current_line);*/
tokenized = strtok(current_line, ":");
bool first_entry = true;
if(strcmp("ROOM NAME", tokenized) == 0){
tokenized = strtok(NULL, " \n");
while(tokenized != NULL){
if(first_entry){
first_entry = false;
}else{
strcat(room_name_buffer, " ");
}
strcat(room_name_buffer, tokenized);
tokenized = strtok(NULL, " \n");
}
break;
}
}
fclose(file_pointer_main);
}
int get_room_index_from_name(char* room_name){
char num_rooms = sizeof(room_filenames) / sizeof(room_filenames[0]);
char room_name_buffer[255];
/* Loop through files until the room name is found, return index*/
int i;
for(i = 0 ; i < num_rooms ; i++){
memset(room_name_buffer, '\0', 255);
get_room_name(room_filenames[i], room_name_buffer);
if(strcmp(room_name_buffer, room_name) == 0){
return i;
}
}
return -1;
}
int get_used_indexes(char* room_filename, int* output_list){
char current_line[255];
char used_names[6][15];
char* tokenized;
int return_index = 0;
memset(current_line, '\0', 255);
file_pointer_main = open_file_local_folder(room_filename, "r");
/* Loop through and get names of all connections in file */
while(fgets(current_line, 255, file_pointer_main) != NULL){
tokenized = strtok(current_line, " ");
if(strcmp("CONNECTION", tokenized) == 0){
tokenized = strtok(NULL, ":");
tokenized = strtok(NULL, " \n");
bool first_entry = true;
while(tokenized != NULL){
if(first_entry){
first_entry = false;
}else{
strcat(used_names[return_index], " ");
}
strcat(used_names[return_index], tokenized);
tokenized = strtok(NULL, " \n");
}
return_index++;
}
}
fclose(file_pointer_main);
/* Get indices from names, and return */
int i;
for(i = 0 ; i < return_index ; i++){
output_list[i] = get_room_index_from_name(used_names[i]);
}
return return_index;
}
/* /////////////////////////////////// */
/* ///////// Time Functions ////////// */
/* /////////////////////////////////// */
void print_time(void){
/* Make and run the thread. Join to block until the other thread is done. */
assert(pthread_create(&time_thread_ID, NULL, get_time, NULL) == 0);
assert(pthread_join(time_thread_ID, NULL) == 0);
/* Lock and get a copy of whether time was written. Set original to false. */
pthread_mutex_lock(&time_mutex);
bool time_was_written = time_written;
time_written = false;
pthread_mutex_unlock(&time_mutex);
/* Make sure that the time was written, otherwise massive error... */
assert(time_was_written);
/* Open file with time information and print it. */
file_pointer_main = open_file_local_folder(time_file_name, "r");
assert(file_pointer_main != NULL);
printf("\n");
char c = fgetc(file_pointer_main);
while(c != EOF){
printf("%c", c);
c = fgetc(file_pointer_main);
}
printf("\n");
fclose(file_pointer_main);
/* Delete this temporary file */
delete_file_local_folder(time_file_name);
}
/* //////////////////////////////////////// */
/* ///////// Threading Functions ////////// */
/* //////////////////////////////////////// */
void* get_time(void *arguments){
time_t current_time_raw;
struct tm *time_as_struct;
char buffer_size = 50;
char buffer[buffer_size];
memset(buffer, '\0', buffer_size);
/* Get current time */
time(&current_time_raw);
time_as_struct = localtime(&current_time_raw);
/* Format per specification */
strftime(buffer, buffer_size, "%-l:%M%P, %A, %B %-e, %Y", time_as_struct);
/* Write formatted time to file */
file_pointer_time = open_file_local_folder(time_file_name, "w");
fprintf(file_pointer_time, "%s", buffer);
fclose(file_pointer_time);
/* Lock, update, and unlock mutex variable */
pthread_mutex_lock(&time_mutex);
time_written = true;
pthread_mutex_unlock(&time_mutex);
return NULL;
}
/* ///////////////////////////////////// */
/* ///////// Helper Functions ////////// */
/* ///////////////////////////////////// */
FILE *open_file_local_folder(char *file_name, char *mode){
/* Makes common concatenation of file with full path easier */
char full_path[255];
memset(full_path, '\0', 255);
strcat(full_path, rooms_directory_full);
strcat(full_path, "/");
strcat(full_path, file_name);
return fopen(full_path, mode);
}
int delete_file_local_folder(char *file_name){
/* Easy delete that handles concatenation for time file */
char full_path[255];
memset(full_path, '\0', 255);
strcat(full_path, rooms_directory_full);
strcat(full_path, "/");
strcat(full_path, file_name);
return remove(full_path);
}

View File

@@ -0,0 +1,8 @@
all: build
clean:
rm -f smallsh
build:
dos2unix smallsh.c > /dev/null 2>&1
gcc smallsh.c -o smallsh -std=c99

View File

@@ -0,0 +1,6 @@
To compile, run the below command in the folder with smallsh.c and the makefile.
make clean build
This will remove the existing compiled binary, if it exists, and then
recompile the source into a new binary executable.

View File

@@ -0,0 +1,386 @@
/////////////////////////////
////////// SMALLSH //////////
/////// Corwin Perren ///////
/////////////////////////////
//////////////////////////////////////////
////////// Includes and Defines //////////
//////////////////////////////////////////
//Includes
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stdbool.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
//Defines
#define INPUT_LENGTH_MAX 2048
#define INPUT_ARGS_MAX 513 //Includes one extra for the program itself
#define BACKGROUND_WAIT_COUNT 100000
/////////////////////////////////////////
////////// Function Prototypes //////////
/////////////////////////////////////////
void interrupt_signal_handler(int signal_number);
void terminate_signal_handler(int signal_number);
void check_background_processes(int* status);
bool is_blank_input_string(char* input_string);
int split_input_to_array(char* input_string, char** output_array);
void clean_newline(char* input_string);
void clean_array(char** to_clean);
bool check_if_run_in_background(char** arguments_array, int* args_count);
bool check_if_output_redirect(char** arguments_array, int* args_count, \
char* output_filename);
bool check_if_input_redirect(char** arguments_array, int* args_count, \
char* input_filename);
void clean_extra_args(char** arguments_array, int args_count);
//////////////////////////
////////// Main //////////
//////////////////////////
int main() {
////////// SMALLSH Management Variables //////////
char user_input_string[INPUT_LENGTH_MAX];
int input_arg_count = 0;
char** user_input_array = malloc(INPUT_ARGS_MAX * sizeof(char*));
static int smallsh_status = 0;
//Assign initial pointers to NULL so cleaning functions are happy
//This is for user_input_array
for(int i = 0 ; i < INPUT_ARGS_MAX ; i++){
user_input_array[i] = NULL;
}
////////// SMALLSH Process Spawn Variables //////////
bool spawn_in_background = false;
bool redirect_output = false;
bool redirect_input = false;
char output_filename[INPUT_LENGTH_MAX];
char input_filename[INPUT_LENGTH_MAX];
int spawn_id = 0;
////////// SMALLSH Initialization //////////
//Assign signal handlers
signal(SIGINT, interrupt_signal_handler);
signal(SIGTERM, terminate_signal_handler);
////////// Print welcome screen //////////
printf("----------------------\n");
printf("Welcome to Small Shell\n");
printf("http://caperren.com\n");
printf("----------------------\n");
////////// Main program code //////////
while(1){
//Reset process management variables
spawn_in_background = false;
redirect_output = false;
redirect_input = false;
//Process child processes
check_background_processes(&smallsh_status);
//Print prompt
printf(": ");
fflush(stdout);
//Clear input buffer and read in new command
memset(user_input_string, '\0', INPUT_LENGTH_MAX);
fgets(user_input_string, INPUT_LENGTH_MAX, stdin);
//Check if input is blank
if(is_blank_input_string(user_input_string)){
continue;
}
//Clean off newline
clean_newline(user_input_string);
//Break input string into an array of the arguments
input_arg_count = split_input_to_array(user_input_string, \
user_input_array);
//Check what kind of input we got
if(strcmp(user_input_array[0], "exit") == 0){
//We should clean up malloc'd memory and exit
clean_array(user_input_array);
free(user_input_array);
exit(EXIT_SUCCESS);
}else if(strcmp(user_input_array[0], "status") == 0){
//Print our exit status variable, and continue
printf("exit value %d\n", WEXITSTATUS(smallsh_status));
fflush(stdout);
continue;
}else if(strcmp(user_input_array[0], "cd") == 0){
//Check if we're going to the home directory, or somewhere else
if((user_input_array[1] == NULL) || \
(strcmp(user_input_array[1], "~/") == 0) || \
(strcmp(user_input_array[1], "~") == 0)){
//Change to the user's home directory as requested
chdir(getenv("HOME"));
}else{
//Change to the user's requested directory, error is not
//accessible, or doesn't exist
int chdir_result = chdir(user_input_array[1]);
if(chdir_result == -1){
printf("Cannot change to directory \"%s\"\n", \
user_input_array[1]);
fflush(stdout);
}
}
continue;
}else if(user_input_array[0][0] == '#'){
//We got a comment line, so do nothing and continue
continue;
}
//If we've gotten here, that means the command given is one we're
//going to be spawning using an exec call.
//First check is to see whether it should be foreground or not.
spawn_in_background = check_if_run_in_background(user_input_array, \
&input_arg_count);
//Now check whether or not we need to redirect output
redirect_output = check_if_output_redirect(user_input_array, \
&input_arg_count, \
output_filename);
//Then the same, but for redirection of input from file
redirect_input = check_if_input_redirect(user_input_array, \
&input_arg_count, \
input_filename);
//Clean out these input/output args we don't want passed to our process
clean_extra_args(user_input_array, input_arg_count);
//Time to fork for our new process
spawn_id = fork();
if(spawn_id == 0){
//We're the child process, get ready to execute.
if(spawn_in_background){
//If we're supposed to be in the background, set stdin and
//stdout file descriptors for the process to /dev/null
int null_rw = open("/dev/null", O_RDWR);
int null_read = open("/dev/null", O_RDONLY);
dup2(null_read, 0);
dup2(null_rw, 1);
}
if(redirect_input){
//Even if background, if we redirect input, attempt to open
//file and pass it in
int input_fd = open(input_filename, O_RDONLY, 0644);
if(input_fd < 0){
printf("File %s cannot be accessed.\n", input_filename);
fflush(stdout);
continue;
}
dup2(input_fd, 0);
}
if(redirect_output){
//Even if background, attempt to make output file and redirect
int output_fd = open(output_filename, \
O_WRONLY | O_CREAT | O_TRUNC, 0644);
if(output_fd < 0){
printf("File %s cannot be accessed.\n", input_filename);
fflush(stdout);
continue;
}
dup2(output_fd, 1);
}
//Execute the command, including searching the path variable
execvp(user_input_array[0], user_input_array);
printf("Failed to run program: %s\n", user_input_array[0]);
fflush(stdout);
exit(EXIT_FAILURE);
}else{
//We're the parent
if(spawn_in_background){
//Print the process id, and return to prompt
printf("background pid is %d\n", spawn_id);
fflush(stdout);
}else{
//Wait for the process to die, as this is foreground
spawn_id = waitpid(spawn_id, &smallsh_status, 0);
}
}
}
exit(EXIT_SUCCESS);
}
///////////////////////////////////////////
////////// Function Declarations //////////
///////////////////////////////////////////
void interrupt_signal_handler(int signal_number){
printf("terminated by signal %d\n", signal_number);
signal(SIGINT, interrupt_signal_handler);
}
void terminate_signal_handler(int signal_number){
printf("terminated by signal %d\n", signal_number);
exit(EXIT_FAILURE);
signal(SIGTERM, terminate_signal_handler);
}
void check_background_processes(int* status){
int temp_pid = 0;
int temp_count = 0;
//Loop through a bunch of times and print out child exit statuses
while(temp_count < BACKGROUND_WAIT_COUNT){
temp_pid = waitpid(-1, status, WNOHANG);
if(temp_pid > 0){
if(WIFEXITED(*status)){
printf("process %d exited with exit value %d", temp_pid, \
WEXITSTATUS(*status));
}
if(WIFSIGNALED(*status)){
printf("process %d terminated by signal %d", temp_pid, \
WTERMSIG(*status));
}
printf("\n");
fflush(stdout);
}
temp_count++;
}
}
bool is_blank_input_string(char* input_string){
//This does a simple check as to whether we have no input on a line
int length = strlen(input_string);
char current_char = '\0';
for(int i = 0 ; i < length ; i++){
current_char = input_string[i];
if((current_char != ' ') && (current_char != '\0') && \
(current_char != '\n')){
return false;
}
}
return true;
}
int split_input_to_array(char* input_string, char** output_array){
int args_count = 0;
char* token_result;
//Clean the array first so we don't memory leak
clean_array(output_array);
for(args_count = 0 ; args_count < INPUT_ARGS_MAX ; args_count++){
//Get the current tokenizer result
if(args_count == 0){
token_result = strtok(input_string, " ");
}else{
token_result = strtok(NULL, " ");
}
//Check if we're done parsing input string
if(token_result == NULL){
break;
}
//Allocate space for next string
output_array[args_count] = malloc((strlen(token_result) + 1) * \
sizeof(char));
//Copy the current string into this allocated space
strcpy(output_array[args_count], token_result);
}
return args_count;
}
void clean_newline(char* input_string){
input_string[strlen(input_string) - 1] = '\0';
}
void clean_array(char** to_clean){
for(int i = 0 ; i < INPUT_ARGS_MAX ; i++){
if(to_clean[i] != NULL){
free(to_clean[i]);
to_clean[i] = NULL;
}else{
break;
}
}
}
bool check_if_run_in_background(char** arguments_array, int* args_count){
if(strcmp(arguments_array[*args_count-1], "&") == 0){
*args_count -= 1;
return true;
}else{
return false;
}
}
bool check_if_output_redirect(char** arguments_array, int* args_count, \
char* output_filename){
memset(output_filename, '\0', INPUT_LENGTH_MAX);
//Check for output redirect. If found, copy the filename and lower
//argument count so we don't process it later
for(int i = 0 ; i < *args_count ; i++){
if(strcmp(arguments_array[i], ">") == 0){
strcpy(output_filename, arguments_array[i + 1]);
*args_count -= 2;
return true;
}
}
return false;
}
bool check_if_input_redirect(char** arguments_array, int* args_count, \
char* input_filename){
memset(input_filename, '\0', INPUT_LENGTH_MAX);
//Check for input redirect. If found, copy the filename and lower
//argument count so we don't process it later
for(int i = 0 ; i < *args_count ; i++){
if(strcmp(arguments_array[i], "<") == 0){
strcpy(input_filename, arguments_array[i + 1]);
*args_count -= 2;
return true;
}
}
return false;
}
void clean_extra_args(char** arguments_array, int args_count){
//This clean up the rest on the input line, after our redirects if they
//happened
for(int i = args_count ; i < INPUT_ARGS_MAX ; i++){
if(arguments_array[i] != NULL){
free(arguments_array[i]);
arguments_array[i] = NULL;
}else{
break;
}
}
}

View File

@@ -0,0 +1,3 @@
#!/bin/bash
make clean
make build

View File

@@ -0,0 +1,51 @@
/*
* File: keygen.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:27 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define ASCII_START 65
int main(int argc, char** argv) {
//Some error handling for bad inputs
if(argc < 2){
fprintf(stderr, "No arguments entered. Please try again.\n");
exit(PROGRAM_FAILURE);
}else if (argc > 2){
fprintf(stderr, "Extra arguments entered. Ignoring all but the "
"first.\n");
}else if(atoi(argv[1]) <= 0){
fprintf(stderr, "Key length too small. Number must be greater than "
"zero.\n");
exit(PROGRAM_FAILURE);
}
time_t t;
srand((unsigned) time(&t));
//Get the number passed in as an argument
int key_length = atoi(argv[1]);
//Loop through and output a new character based on the number generated
for(int i = 0 ; i < key_length ; i++){
int rand_char = rand() % 27;
if(rand_char == 26){
printf(" ");
}else{
printf("%c", (char)(rand_char + ASCII_START));
}
}
//Print the final newline and exit successfully.
printf("\n");
exit(PROGRAM_SUCCESS);
}

View File

@@ -0,0 +1,15 @@
all: build
clean:
rm -f otp_dec
rm -f otp_dec_d
rm -f otp_enc
rm -f otp_enc_d
rm -f keygen
build:
gcc otp_dec.c -o otp_dec -std=c99
gcc otp_dec_d.c -o otp_dec_d -std=c99
gcc otp_enc.c -o otp_enc -std=c99
gcc otp_enc_d.c -o otp_enc_d -std=c99
gcc keygen.c -o keygen -std=c99

View File

@@ -0,0 +1,296 @@
/*
* File: otp_enc.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define PROGRAM_FAILURE_PORT 2
#define PORT_MAX 65535
#define PORT_MIN 0
#define OTP_ENC_IDENT "#"
#define OTP_DEC_IDENT "$"
#define TEXT_DONE "@@"
#define OTP_FAILURE "%"
#define OTP_CONTINUE "&"
#define LETTER_OPTIONS 27
int letter_number_assignment[LETTER_OPTIONS][2] = {
'A', 10,
'B', 11,
'C', 12,
'D', 13,
'E', 14,
'F', 15,
'G', 16,
'H', 17,
'I', 18,
'J', 19,
'K', 20,
'L', 21,
'M', 22,
'N', 23,
'O', 24,
'P', 25,
'Q', 26,
'R', 0,
'S', 1,
'T', 2,
'U', 3,
'V', 4,
'W', 5,
'X', 6,
'Y', 7,
'Z', 8,
' ', 9
};
int get_mapped_num_from_char(char letter);
int main(int argc, char** argv) {
int comms_sfd;
unsigned long int comms_port_number; //0 - 65535
struct hostent *server;
struct sockaddr_in server_address;
FILE *input_file;
FILE *key_file;
//Verify correct number of arguments
if(argc < 4){
fprintf(stderr, "Not enough arguments provided. Exiting...\n");
fprintf(stderr, "Correct usage: "
"%s input_file key_file port\n", argv[0]);
exit(PROGRAM_FAILURE);
}else if(argc > 4){
fprintf(stderr, "Extra arguments entered. Ignoring all but the first "
"three.\n");
}
//Get port number, and make sure it's valid
comms_port_number = atoi(argv[3]);
if((comms_port_number > PORT_MAX) || (comms_port_number < PORT_MIN)){
fprintf(stderr, "Port out of range! Please choose a different port! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Open the files
input_file = fopen(argv[1], "r");
key_file = fopen(argv[2], "r");
//Make sure they opened successfully
if(input_file == NULL){
fprintf(stderr, "Input file does not exist or cannot be read! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}else if(key_file == NULL){
fprintf(stderr, "Key file does not exist or cannot be read! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Read in input file
char* temp_buffer = malloc(sizeof(char) * 1000000);
memset(temp_buffer, '\0', sizeof(char) * 1000000);
fgets(temp_buffer, 1000000, input_file);
char* input_text = malloc(sizeof(char) * (strlen(temp_buffer) + 1));
memset(input_text, '\0', sizeof(char) * (strlen(temp_buffer) + 1));
strcpy(input_text, temp_buffer);
//Remove input file newline
int input_str_len = strlen(input_text);
if(input_text[input_str_len - 1] == '\n'){
input_text[input_str_len - 1] = '\0';
}
//Read in key file
memset(temp_buffer, '\0', sizeof(char) * 1000000);
fgets(temp_buffer, 1000000, key_file);
char* key_text = malloc(sizeof(char) * (strlen(temp_buffer) + 1));
memset(key_text, '\0', sizeof(char) * (strlen(temp_buffer) + 1));
strcpy(key_text, temp_buffer);
//Remove input file newline
input_str_len = strlen(key_text);
if(key_text[input_str_len - 1] == '\n'){
key_text[input_str_len - 1] = '\0';
}
free(temp_buffer);
//Exit as error is input_string is longer than the key
if(strlen(input_text) > strlen(key_text)){
fprintf(stderr, "Key file too small. Please try again with larger "
"file. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Check files for bad characters
for(unsigned long i = 0 ; i < strlen(input_text) ; i ++){
if(get_mapped_num_from_char(input_text[i]) == -1){
fprintf(stderr, "Bad characters in input text. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}
for(unsigned long i = 0 ; i < strlen(key_text) ; i ++){
if(get_mapped_num_from_char(key_text[i]) == -1){
fprintf(stderr, "Bad characters in key text. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}
//Create listening socket, check if created successfully
comms_sfd = socket(AF_INET, SOCK_STREAM, 0);
if(comms_sfd < 0){
fprintf(stderr, "Could not create comms socket! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Get localhost as server, check if valid
server = gethostbyname("localhost");
if(server == NULL){
fprintf(stderr, "localhost is not a valid host! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Set up comms parameters for the server we're connecting to.
memset((char *)&server_address, '\0', sizeof(server_address));
server_address.sin_port = htons(comms_port_number);
memcpy(&server_address.sin_addr, server->h_addr_list[0], server->h_length);
server_address.sin_family = AF_INET;
//Make the server connection and verify it didn't fail.
int connect_result = connect(comms_sfd, \
(struct sockaddr *)&server_address, \
sizeof(server_address));
if(connect_result < 0){
fprintf(stderr, "Connection failed! Is the port correct? Exiting...\n");
exit(PROGRAM_FAILURE_PORT);
}
//Set up writing and reading variables
int read_return;
int write_return;
unsigned int concat_index = 0;
char read_buffer[10];
char* concat_buffer = malloc(sizeof(char) * 1000000);
memset(read_buffer, '\0', 1);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Write message to tell the daemon what program we are
write_return = write(comms_sfd, OTP_DEC_IDENT TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Read the servers response to our message
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
if(strstr(concat_buffer, OTP_CONTINUE TEXT_DONE) != NULL){
//In this case, the response from the server is to continue
//We write the input text to the daemon
write_return = write(comms_sfd, input_text, strlen(input_text));
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Then we write the ending characters
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Now we write the key file to the daemon
write_return = write(comms_sfd, key_text, strlen(key_text));
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//And the ending characters again
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in the response from the daemon
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
int input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Print out the cleaned up response from the daemon
for(int i = 0 ; i < strlen(concat_buffer) ; i++){
printf("%c", concat_buffer[i]);
}
printf("\n");
}else if(strstr(concat_buffer, OTP_FAILURE TEXT_DONE) != NULL){
//Print an error if we try to connect to the wrong daemon
fprintf(stderr, "OTP_DEC may NOT connect to OTP_ENC_D. Exiting...\n");
exit(PROGRAM_FAILURE);
}else{
//Print an error if we get erroneous data.
fprintf(stderr, "Got bad data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
exit(PROGRAM_SUCCESS);
}
int get_mapped_num_from_char(char letter){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(letter == letter_number_assignment[i][0]){
return letter_number_assignment[i][1];
}
}
return -1;
}

View File

@@ -0,0 +1,309 @@
/*
* File: otp_enc_d.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define PORT_MAX 65535
#define PORT_MIN 0
#define OTP_ENC_IDENT "#"
#define OTP_DEC_IDENT "$"
#define TEXT_DONE "@@"
#define OTP_FAILURE "%"
#define OTP_CONTINUE "&"
#define LETTER_OPTIONS 27
int letter_number_assignment[LETTER_OPTIONS][2] = {
'A', 10,
'B', 11,
'C', 12,
'D', 13,
'E', 14,
'F', 15,
'G', 16,
'H', 17,
'I', 18,
'J', 19,
'K', 20,
'L', 21,
'M', 22,
'N', 23,
'O', 24,
'P', 25,
'Q', 26,
'R', 0,
'S', 1,
'T', 2,
'U', 3,
'V', 4,
'W', 5,
'X', 6,
'Y', 7,
'Z', 8,
' ', 9
};
int get_mapped_num_from_char(char letter);
char get_mapped_char_from_num(int number);
char encode_character(char letter, char key_letter);
char decode_character(char input_letter, char key_letter);
int main(int argc, char** argv) {
int listen_sfd; //sfd == socked_file_descriptor
int comms_sfd;
unsigned long int listen_port_number; //0 - 65535
socklen_t client_length;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
//Check if we have enough arguments, error and exit if not.
if(argc < 2){
fprintf(stderr, "No port provided! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Create our listening socket, check if created successfully
listen_sfd = socket(AF_INET, SOCK_STREAM, 0);
if(listen_sfd < 0){
fprintf(stderr, "Could not create listening socket! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Get port number, and make sure it's valid
listen_port_number = atoi(argv[1]);
if((listen_port_number > PORT_MAX) || (listen_port_number < PORT_MIN)){
fprintf(stderr, "Port out of range! Please choose a different port! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Set up listening parameters
memset((char *)&server_address, '\0', sizeof(server_address));
server_address.sin_port = htons(listen_port_number);
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_family = AF_INET;
//Bind server to settings set above, let system know we're ready
int bind_result = bind(listen_sfd, (struct sockaddr *)&server_address, \
sizeof(server_address));
if(bind_result < 0){
fprintf(stderr, "Failed to bind listening port! "
"Please choose a different port! Exiting...\n");
exit(PROGRAM_FAILURE);
}
while(1){
//Call waitpid to kill off any zombie processes. Don't let it block.
static int process_status;
waitpid(-1, &process_status, WNOHANG);
//Listen to the port, and allow up to five connections
listen(listen_sfd, 5); //Listen to the port
//Block until a valid connection is made, then accept it.
//Also make sure it's accepted correctly
socklen_t client_length = sizeof(client_address);
comms_sfd = accept(listen_sfd, (struct sockaddr *) &client_address, \
&client_length);
if (comms_sfd < 0){
fprintf(stderr, "Client accept failed. Trying next "
"connection...\n");
}else{
//We've made a valid connection, so spawn off a new process to
//handle it to free up the main thread for accepting a new client.
pid_t spawned_pid;
spawned_pid = fork();
//Only run the child code if it's a child process
if(spawned_pid == 0){
//Initialize read write variables
int read_return;
int write_return;
unsigned int concat_index = 0;
char read_buffer[10];
char* concat_buffer = malloc(sizeof(char) * 1000000);
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read initial message telling us who the client is
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Choose a response appropriate for who is communicating
if(strstr(concat_buffer, OTP_DEC_IDENT TEXT_DONE) != NULL){
//In this case, the client/server match and we can continue
//Write a message to the client that we'll continue
write_return = write(comms_sfd, OTP_CONTINUE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in first input file from client
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
int input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Store input text for later use
char* input_text = malloc(sizeof(char) * \
(strlen(concat_buffer) + 1));
memset(input_text, '\0', sizeof(char) * \
(strlen(concat_buffer) + 1));
strcpy(input_text, concat_buffer);
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in key file from client
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Store key file for later
char* key_text = malloc(sizeof(char) * \
(strlen(concat_buffer) + 1));
memset(key_text, '\0', sizeof(char) * \
(strlen(concat_buffer) + 1));
strcpy(key_text, concat_buffer);
free(concat_buffer);
//Write the decrypted data to the client
for(unsigned long int i = 0 ; i < strlen(input_text) ;\
i++){
char new_char = decode_character(input_text[i], \
key_text[i]);
write_return = write(comms_sfd, &new_char, 1);
}
//Write the end of text marker
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}else if(strstr(concat_buffer, OTP_ENC_IDENT TEXT_DONE) \
!= NULL){
//In this case, client and server don't match
//Write failure message so client exits
write_return = write(comms_sfd, OTP_FAILURE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
}
exit(PROGRAM_FAILURE);
}else{
//Error and messages for erroneous data
fprintf(stderr, "Got bad data. Alerting sender and "
"exiting...\n");
write_return = write(comms_sfd, OTP_FAILURE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
}
exit(PROGRAM_FAILURE);
}
//Since this is a child process, once it's done it should die.
exit(PROGRAM_SUCCESS);
}
}
}
close(listen_sfd);
exit(PROGRAM_SUCCESS);
}
int get_mapped_num_from_char(char letter){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(letter == letter_number_assignment[i][0]){
return letter_number_assignment[i][1];
}
}
return -1;
}
char get_mapped_char_from_num(int number){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(number == letter_number_assignment[i][1]){
return letter_number_assignment[i][0];
}
}
return -1;
}
char encode_character(char input_letter, char key_letter){
int letter_mapped = get_mapped_num_from_char(input_letter);
int key_mapped = get_mapped_num_from_char(key_letter);
int summed = (letter_mapped + key_mapped);
if(summed >= LETTER_OPTIONS){
summed -= LETTER_OPTIONS;
}
return get_mapped_char_from_num(summed);
}
char decode_character(char input_letter, char key_letter){
int letter_mapped = get_mapped_num_from_char(input_letter);
int key_mapped = get_mapped_num_from_char(key_letter);
int subbed = (letter_mapped - key_mapped);
if(subbed < 0){
subbed += LETTER_OPTIONS;
}
return get_mapped_char_from_num(subbed);
}

View File

@@ -0,0 +1,294 @@
/*
* File: otp_enc.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define PROGRAM_FAILURE_PORT 2
#define PORT_MAX 65535
#define PORT_MIN 0
#define OTP_ENC_IDENT "#"
#define OTP_DEC_IDENT "$"
#define TEXT_DONE "@@"
#define OTP_FAILURE "%"
#define OTP_CONTINUE "&"
#define LETTER_OPTIONS 27
int letter_number_assignment[LETTER_OPTIONS][2] = {
'A', 10,
'B', 11,
'C', 12,
'D', 13,
'E', 14,
'F', 15,
'G', 16,
'H', 17,
'I', 18,
'J', 19,
'K', 20,
'L', 21,
'M', 22,
'N', 23,
'O', 24,
'P', 25,
'Q', 26,
'R', 0,
'S', 1,
'T', 2,
'U', 3,
'V', 4,
'W', 5,
'X', 6,
'Y', 7,
'Z', 8,
' ', 9
};
int get_mapped_num_from_char(char letter);
int main(int argc, char** argv) {
int comms_sfd;
unsigned long int comms_port_number; //0 - 65535
struct hostent *server;
struct sockaddr_in server_address;
FILE *input_file;
FILE *key_file;
//Verify correct number of arguments
if(argc < 4){
fprintf(stderr, "Not enough arguments provided. Exiting...\n");
fprintf(stderr, "Correct usage: "
"%s input_file key_file port\n", argv[0]);
exit(PROGRAM_FAILURE);
}else if(argc > 4){
fprintf(stderr, "Extra arguments entered. Ignoring all but the first "
"three.\n");
}
//Get port number, and make sure it's valid
comms_port_number = atoi(argv[3]);
if((comms_port_number > PORT_MAX) || (comms_port_number < PORT_MIN)){
fprintf(stderr, "Port out of range! Please choose a different port! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Open the files
input_file = fopen(argv[1], "r");
key_file = fopen(argv[2], "r");
//Make sure they opened successfully
if(input_file == NULL){
fprintf(stderr, "Input file does not exist or cannot be read! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}else if(key_file == NULL){
fprintf(stderr, "Key file does not exist or cannot be read! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Read in input file
char* temp_buffer = malloc(sizeof(char) * 1000000);
memset(temp_buffer, '\0', sizeof(char) * 1000000);
fgets(temp_buffer, 1000000, input_file);
char* input_text = malloc(sizeof(char) * (strlen(temp_buffer) + 1));
memset(input_text, '\0', sizeof(char) * (strlen(temp_buffer) + 1));
strcpy(input_text, temp_buffer);
//Remove input file newline
int input_str_len = strlen(input_text);
if(input_text[input_str_len - 1] == '\n'){
input_text[input_str_len - 1] = '\0';
}
//Read in key file
memset(temp_buffer, '\0', sizeof(char) * 1000000);
fgets(temp_buffer, 1000000, key_file);
char* key_text = malloc(sizeof(char) * (strlen(temp_buffer) + 1));
memset(key_text, '\0', sizeof(char) * (strlen(temp_buffer) + 1));
strcpy(key_text, temp_buffer);
//Remove input file newline
input_str_len = strlen(key_text);
if(key_text[input_str_len - 1] == '\n'){
key_text[input_str_len - 1] = '\0';
}
free(temp_buffer);
//Exit as error is input_string is longer than the key
if(strlen(input_text) > strlen(key_text)){
fprintf(stderr, "Key file too small. Please try again with larger "
"file. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Check files for bad characters
for(unsigned long i = 0 ; i < strlen(input_text) ; i ++){
if(get_mapped_num_from_char(input_text[i]) == -1){
fprintf(stderr, "Bad characters in input text. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}
for(unsigned long i = 0 ; i < strlen(key_text) ; i ++){
if(get_mapped_num_from_char(key_text[i]) == -1){
fprintf(stderr, "Bad characters in key text. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}
//Create listening socket, check if created successfully
comms_sfd = socket(AF_INET, SOCK_STREAM, 0);
if(comms_sfd < 0){
fprintf(stderr, "Could not create comms socket! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Get localhost as server, check if valid
server = gethostbyname("localhost");
if(server == NULL){
fprintf(stderr, "localhost is not a valid host! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Set up comms parameters for the server we're connecting to.
memset((char *)&server_address, '\0', sizeof(server_address));
server_address.sin_port = htons(comms_port_number);
memcpy(&server_address.sin_addr, server->h_addr_list[0], server->h_length);
server_address.sin_family = AF_INET;
//Make the server connection and verify it didn't fail.
int connect_result = connect(comms_sfd, \
(struct sockaddr *)&server_address, \
sizeof(server_address));
if(connect_result < 0){
fprintf(stderr, "Connection failed! Is the port correct? Exiting...\n");
exit(PROGRAM_FAILURE_PORT);
}
//Set up writing and reading variables
int read_return;
int write_return;
unsigned int concat_index = 0;
char read_buffer[10];
char* concat_buffer = malloc(sizeof(char) * 1000000);
memset(read_buffer, '\0', 1);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Write message to tell the daemon what program we are
write_return = write(comms_sfd, OTP_ENC_IDENT TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Read the servers response to our message
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
if(strstr(concat_buffer, OTP_CONTINUE TEXT_DONE) != NULL){
//In this case, the response from the server is to continue
//We write the input text to the daemon
write_return = write(comms_sfd, input_text, strlen(input_text));
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Then we write the ending characters
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Now we write the key file to the daemon
write_return = write(comms_sfd, key_text, strlen(key_text));
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//And the ending characters again
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in the response from the daemon
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
int input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Print out the cleaned up response from the daemon
for(int i = 0 ; i < strlen(concat_buffer) ; i++){
printf("%c", concat_buffer[i]);
}
printf("\n");
}else if(strstr(concat_buffer, OTP_FAILURE TEXT_DONE) != NULL){
//Print an error if we try to connect to the wrong daemon
fprintf(stderr, "OTP_ENC may NOT connect to OTP_DEC_D. Exiting...\n");
exit(PROGRAM_FAILURE);
}else{
//Print an error if we get erroneous data.
fprintf(stderr, "Got bad data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
exit(PROGRAM_SUCCESS);
}
int get_mapped_num_from_char(char letter){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(letter == letter_number_assignment[i][0]){
return letter_number_assignment[i][1];
}
}
return -1;
}

View File

@@ -0,0 +1,310 @@
/*
* File: otp_enc_d.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define PORT_MAX 65535
#define PORT_MIN 0
#define OTP_ENC_IDENT "#"
#define OTP_DEC_IDENT "$"
#define TEXT_DONE "@@"
#define OTP_FAILURE "%"
#define OTP_CONTINUE "&"
#define LETTER_OPTIONS 27
int letter_number_assignment[LETTER_OPTIONS][2] = {
'A', 10,
'B', 11,
'C', 12,
'D', 13,
'E', 14,
'F', 15,
'G', 16,
'H', 17,
'I', 18,
'J', 19,
'K', 20,
'L', 21,
'M', 22,
'N', 23,
'O', 24,
'P', 25,
'Q', 26,
'R', 0,
'S', 1,
'T', 2,
'U', 3,
'V', 4,
'W', 5,
'X', 6,
'Y', 7,
'Z', 8,
' ', 9
};
int get_mapped_num_from_char(char letter);
char get_mapped_char_from_num(int number);
char encode_character(char letter, char key_letter);
char decode_character(char input_letter, char key_letter);
int main(int argc, char** argv) {
int listen_sfd; //sfd == socked_file_descriptor
int comms_sfd;
unsigned long int listen_port_number; //0 - 65535
socklen_t client_length;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
//Check if we have enough arguments, error and exit if not.
if(argc < 2){
fprintf(stderr, "No port provided! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Create our listening socket, check if created successfully
listen_sfd = socket(AF_INET, SOCK_STREAM, 0);
if(listen_sfd < 0){
fprintf(stderr, "Could not create listening socket! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Get port number, and make sure it's valid
listen_port_number = atoi(argv[1]);
if((listen_port_number > PORT_MAX) || (listen_port_number < PORT_MIN)){
fprintf(stderr, "Port out of range! Please choose a different port! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Set up listening parameters
memset((char *)&server_address, '\0', sizeof(server_address));
server_address.sin_port = htons(listen_port_number);
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_family = AF_INET;
//Bind server to settings set above, let system know we're ready
int bind_result = bind(listen_sfd, (struct sockaddr *)&server_address, \
sizeof(server_address));
if(bind_result < 0){
fprintf(stderr, "Failed to bind listening port! "
"Please choose a different port! Exiting...\n");
exit(PROGRAM_FAILURE);
}
while(1){
//Call waitpid to kill off any zombie processes. Don't let it block.
static int process_status;
waitpid(-1, &process_status, WNOHANG);
//Listen to the port, and allow up to five connections
listen(listen_sfd, 5); //Listen to the port
//Block until a valid connection is made, then accept it.
//Also make sure it's accepted correctly
socklen_t client_length = sizeof(client_address);
comms_sfd = accept(listen_sfd, (struct sockaddr *) &client_address, \
&client_length);
if (comms_sfd < 0){
fprintf(stderr, "Client accept failed. Trying next "
"connection...\n");
}else{
//We've made a valid connection, so spawn off a new process to
//handle it to free up the main thread for accepting a new client.
pid_t spawned_pid;
spawned_pid = fork();
//Only run the child code if it's a child process
if(spawned_pid == 0){
//Initialize read write variables
int read_return;
int write_return;
unsigned int concat_index = 0;
char read_buffer[10];
char* concat_buffer = malloc(sizeof(char) * 1000000);
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read initial message telling us who the client is
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Choose a response appropriate for who is communicating
if(strstr(concat_buffer, OTP_ENC_IDENT TEXT_DONE) != NULL){
//In this case, the client/server match and we can continue
//Write a message to the client that we'll continue
write_return = write(comms_sfd, OTP_CONTINUE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in first input file from client
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
int input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Store this for later use
char* input_text = malloc(sizeof(char) * \
(strlen(concat_buffer) + 1));
memset(input_text, '\0', sizeof(char) * \
(strlen(concat_buffer) + 1));
strcpy(input_text, concat_buffer);
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in key file from client
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Store key file for later
char* key_text = malloc(sizeof(char) * \
(strlen(concat_buffer) + 1));
memset(key_text, '\0', sizeof(char) * \
(strlen(concat_buffer) + 1));
strcpy(key_text, concat_buffer);
free(concat_buffer);
//Write the encrypted data to the client
for(unsigned long int i = 0 ; i < strlen(input_text) ;\
i++){
char new_char = encode_character(input_text[i], \
key_text[i]);
write_return = write(comms_sfd, &new_char, 1);
}
//Write the end of text marker
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}else if(strstr(concat_buffer, OTP_DEC_IDENT TEXT_DONE) \
!= NULL){
//In this case, client and server don't match
//Write failure message so client exits
write_return = write(comms_sfd, OTP_FAILURE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
}
exit(PROGRAM_FAILURE);
}else{
//Error and messages for erroneous data
fprintf(stderr, "Got bad data. Alerting sender and "
"exiting...\n");
write_return = write(comms_sfd, OTP_FAILURE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
}
exit(PROGRAM_FAILURE);
}
//Since this is a child process, once it's done it should die.
exit(PROGRAM_SUCCESS);
}
}
}
close(listen_sfd);
exit(PROGRAM_SUCCESS);
}
int get_mapped_num_from_char(char letter){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(letter == letter_number_assignment[i][0]){
return letter_number_assignment[i][1];
}
}
return -1;
}
char get_mapped_char_from_num(int number){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(number == letter_number_assignment[i][1]){
return letter_number_assignment[i][0];
}
}
return -1;
}
char encode_character(char input_letter, char key_letter){
int letter_mapped = get_mapped_num_from_char(input_letter);
int key_mapped = get_mapped_num_from_char(key_letter);
int summed = (letter_mapped + key_mapped);
if(summed >= LETTER_OPTIONS){
summed -= LETTER_OPTIONS;
}
return get_mapped_char_from_num(summed);
}
char decode_character(char input_letter, char key_letter){
int letter_mapped = get_mapped_num_from_char(input_letter);
int key_mapped = get_mapped_num_from_char(key_letter);
int subbed = (letter_mapped - key_mapped);
if(subbed < 0){
subbed += LETTER_OPTIONS;
}
return get_mapped_char_from_num(subbed);
}

View File

@@ -0,0 +1,142 @@
#!/bin/bash
# FYI, this command removes file abc if it is empty: [ -s abc ] || rm -f abc
usage="usage: $0 encryptionport decryptionport"
#use the standard version of echo
echo=/bin/echo
#Make sure we have the right number of arguments
if test $# -gt 2 -o $# -lt 2
then
${echo} $usage 1>&2
exit 1
fi
#Clean up any previous runs
${echo} '#Initializing - Cleaning up - ignore Operation Not Permitted errors'
killall -q -u $USER otp_*
rm -f ciphertext*
rm -f plaintext*_*
rm -f key20
rm -f key70000
#Record the ports passed in
encport=$1
decport=$2
#Run the daemons
otp_enc_d $encport &
otp_dec_d $decport &
sleep 5
${echo}
${echo} '#-----------------------------------------'
${echo} '#START OF GRADING SCRIPT'
${echo} '#keygen 20 > key20'
keygen 20 > key20
${echo} "#5 POINTS: key20 must exist"
[ -s key20 ] || rm -f key20
if [ -f key20 ]; then ${echo} 'key20 exists!'; else ${echo} 'key20 DOES NOT EXIST'; fi
${echo}
${echo} "#-----------------------------------------"
${echo} "#5 POINTS: Number of characters in key20, should be 21:"
wc -m key20
${echo}
${echo} "#-----------------------------------------"
${echo} '#keygen 70000 > key70000'
keygen 70000 > key70000
${echo} "#5 POINTS: Number of characters in key70000, should be 70001:"
[ -s key70000 ] || rm -f key70000
wc -m key70000
${echo}
${echo} "#-----------------------------------------"
${echo} '#otp_enc plaintext1 key20 $encport'
${echo} "#10 POINTS: Should return error about too-short key"
otp_enc plaintext1 key20 $encport
${echo}
${echo} "#-----------------------------------------"
${echo} '#otp_enc plaintext1 key70000 $encport'
${echo} "#20 POINTS: Should return encrypted version of plaintext1"
otp_enc plaintext1 key70000 $encport
${echo}
${echo} '#-----------------------------------------'
${echo} '#otp_enc plaintext1 key70000 $encport > ciphertext1'
otp_enc plaintext1 key70000 $encport > ciphertext1
${echo} "#10 POINTS: ciphertext1 must exist"
[ -s ciphertext1 ] || rm -f ciphertext1
if [ -f ciphertext1 ]; then ${echo} 'ciphertext1 exists!'; else ${echo} 'ciphertext1 DOES NOT EXIST'; fi
${echo}
${echo} '#-----------------------------------------'
${echo} '#10 POINTS: ciphertext1 must be same number of chars as source'
${echo} '#wc -m plaintext1'
wc -m plaintext1
${echo} '#Should be same: wc -m ciphertext1'
wc -m ciphertext1
${echo}
${echo} '#-----------------------------------------'
${echo} '#5 POINTS: ciphertext1 should look encrypted'
cat ciphertext1
${echo}
${echo} '#-----------------------------------------'
${echo} '#otp_dec ciphertext1 key70000 $encport'
${echo} '#5 POINTS: Should fail giving error that otp_dec cannot use otp_enc_d'
otp_dec ciphertext1 key70000 $encport
${echo}
${echo} '#-----------------------------------------'
${echo} '#20 POINTS: should return decrypted ciphertext1 that matches source'
${echo} '#cat plaintext1'
cat plaintext1
${echo} '#otp_dec ciphertext1 key70000 $decport'
otp_dec ciphertext1 key70000 $decport
${echo}
${echo} '#-----------------------------------------'
${echo} '#otp_dec ciphertext1 key70000 $decport > plaintext1_a'
otp_dec ciphertext1 key70000 $decport > plaintext1_a
${echo} "#10 POINTS: plaintext1_a must exist"
[ -s plaintext1_a ] || rm -f plaintext1_a
if [ -f plaintext1_a ]; then ${echo} 'plaintext1_a exists!'; else ${echo} 'plaintext1_a DOES NOT EXIST'; fi
${echo}
${echo} '#-----------------------------------------'
${echo} '#cmp plaintext1 plaintext1_a'
${echo} '#5 POINTS: plaintext1 must be the same as plaintext1_a:'
cmp plaintext1 plaintext1_a
${echo} '#echo $? should be == 0, which means the cmp succeeded!'
echo $?
${echo}
${echo} '#-----------------------------------------'
${echo} '#20 POINTS: concurrent test of encryption - look for 4 properly-sized ciphertext# files, or 5 where the 5th is 0 bytes'
${echo} '#5 POINTS: Should be only one error about plaintext5 being bad'
rm -f ciphertext*
rm -f plaintext*_*
otp_enc plaintext1 key70000 $encport > ciphertext1 &
otp_enc plaintext2 key70000 $encport > ciphertext2 &
otp_enc plaintext3 key70000 $encport > ciphertext3 &
otp_enc plaintext4 key70000 $encport > ciphertext4 &
otp_enc plaintext5 key70000 $encport > ciphertext5 &
${echo} 'Ten second sleep, your program must complete in this time'
sleep 10
ls -pla
${echo}
${echo} '#-----------------------------------------'
${echo} '#15 POINTS: concurrent test of decryption - look for 4 plaintext#_a files that match the plaintext# files'
otp_dec ciphertext1 key70000 $decport > plaintext1_a &
otp_dec ciphertext2 key70000 $decport > plaintext2_a &
otp_dec ciphertext3 key70000 $decport > plaintext3_a &
otp_dec ciphertext4 key70000 $decport > plaintext4_a &
${echo} '#Ten second sleep, your program must complete in this time'
sleep 10
ls -pla
#Clean up
${echo}
${echo} '#-----------------------------------------'
${echo} '#Cleaning up - ignore Operation Not Permitted errors'
killall -q -u $USER otp_*
rm -f ciphertext*
rm -f plaintext*_*
rm -f key20
rm -f key70000
${echo}
${echo} '#SCRIPT COMPLETE'

View File

@@ -0,0 +1 @@
THE RED GOOSE FLIES AT MIDNIGHT STOP

View File

@@ -0,0 +1 @@
CAVERNA POWER GRID SPACE CADETS STARSHIP TROOPERS DIXIT DOMINION ARKHAM HORROR MAGIC FALLING BANE ECLIPSE ACQUIRE CORE WORLDS REVOLUTION LORDS OF WATERDEEP MICE AND MYSTICS PATHFINDER ACG MUNCHKIN SMASHUP TWILIGHT STRUGGLE PUERTO RICO SMALL WORLD PANDEMIC SEVEN WONDERS ROBORALLY DIPLOMACY DEADWOOD KILL DOCTOR LUCKY

View File

@@ -0,0 +1 @@
IN THE BEGINNING

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
$*!(#*djs8301these-are-all-bad-characters

View File

@@ -0,0 +1,57 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg) { perror(msg); exit(0); } // Error function used for reporting issues
int main(int argc, char *argv[])
{
int socketFD, portNumber, charsWritten, charsRead;
struct sockaddr_in serverAddress;
struct hostent* serverHostInfo;
char buffer[256];
if (argc < 3) { fprintf(stderr,"USAGE: %s hostname port\n", argv[0]); exit(0); } // Check usage & args
// Set up the server address struct
memset((char*)&serverAddress, '\0', sizeof(serverAddress)); // Clear out the address struct
portNumber = atoi(argv[2]); // Get the port number, convert to an integer from a string
serverAddress.sin_family = AF_INET; // Create a network-capable socket
serverAddress.sin_port = htons(portNumber); // Store the port number
serverHostInfo = gethostbyname(argv[1]); // Convert the machine name into a special form of address
if (serverHostInfo == NULL) { fprintf(stderr, "CLIENT: ERROR, no such host\n"); exit(0); }
memcpy((char*)&serverAddress.sin_addr.s_addr, (char*)serverHostInfo->h_addr, serverHostInfo->h_length); // Copy in the address
// Set up the socket
socketFD = socket(AF_INET, SOCK_STREAM, 0); // Create the socket
if (socketFD < 0) error("CLIENT: ERROR opening socket");
// Connect to server
if (connect(socketFD, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) // Connect socket to address
error("CLIENT: ERROR connecting");
// Get input message from user
printf("CLIENT: Enter text to send to the server, and then hit enter: ");
memset(buffer, '\0', sizeof(buffer)); // Clear out the buffer array
fgets(buffer, sizeof(buffer) - 1, stdin); // Get input from the user, trunc to buffer - 1 chars, leaving \0
buffer[strcspn(buffer, "\n")] = '\0'; // Remove the trailing \n that fgets adds
// Send message to server
charsWritten = send(socketFD, buffer, strlen(buffer), 0); // Write to the server
if (charsWritten < 0) error("CLIENT: ERROR writing to socket");
if (charsWritten < strlen(buffer)) printf("CLIENT: WARNING: Not all data written to socket!\n");
// Get return message from server
memset(buffer, '\0', sizeof(buffer)); // Clear out the buffer again for reuse
charsRead = recv(socketFD, buffer, sizeof(buffer) - 1, 0); // Read data from the socket, leaving \0 at end
if (charsRead < 0) error("CLIENT: ERROR reading from socket");
printf("CLIENT: I received this from the server: \"%s\"\n", buffer);
close(socketFD); // Close the socket
return 0;
}

View File

@@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(const char *msg) { perror(msg); exit(1); } // Error function used for reporting issues
int main(int argc, char *argv[])
{
int listenSocketFD, establishedConnectionFD, portNumber, charsRead;
socklen_t sizeOfClientInfo;
char buffer[256];
struct sockaddr_in serverAddress, clientAddress;
if (argc < 2) { fprintf(stderr,"USAGE: %s port\n", argv[0]); exit(1); } // Check usage & args
// Set up the address struct for this process (the server)
memset((char *)&serverAddress, '\0', sizeof(serverAddress)); // Clear out the address struct
portNumber = atoi(argv[1]); // Get the port number, convert to an integer from a string
serverAddress.sin_family = AF_INET; // Create a network-capable socket
serverAddress.sin_port = htons(portNumber); // Store the port number
serverAddress.sin_addr.s_addr = INADDR_ANY; // Any address is allowed for connection to this process
// Set up the socket
listenSocketFD = socket(AF_INET, SOCK_STREAM, 0); // Create the socket
if (listenSocketFD < 0) error("ERROR opening socket");
// Enable the socket to begin listening
if (bind(listenSocketFD, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) // Connect socket to port
error("ERROR on binding");
listen(listenSocketFD, 5); // Flip the socket on - it can now receive up to 5 connections
// Accept a connection, blocking if one is not available until one connects
sizeOfClientInfo = sizeof(clientAddress); // Get the size of the address for the client that will connect
establishedConnectionFD = accept(listenSocketFD, (struct sockaddr *)&clientAddress, &sizeOfClientInfo); // Accept
if (establishedConnectionFD < 0) error("ERROR on accept");
// Get the message from the client and display it
memset(buffer, '\0', 256);
charsRead = recv(establishedConnectionFD, buffer, 255, 0); // Read the client's message from the socket
if (charsRead < 0) error("ERROR reading from socket");
printf("SERVER: I received this from the client: \"%s\"\n", buffer);
// Send a Success message back to the client
charsRead = send(establishedConnectionFD, "I am the server, and I got your message", 39, 0); // Send success back
if (charsRead < 0) error("ERROR writing to socket");
close(establishedConnectionFD); // Close the existing socket which is connected to the client
close(listenSocketFD); // Close the listening socket
return 0;
}

View File

@@ -0,0 +1,56 @@
# Assignment 5 - Python Exploration
# Corwin Perren
import os
import random
ASCII_MIN = ord('a')
ASCII_MAX = ord('z')
NUM_MIN = 1
NUM_MAX = 42
def make_file_with_random_letters(filename):
file = open(filename, "w")
for _ in range(10):
character_decimal = random.randint(ASCII_MIN, ASCII_MAX)
file.write(chr(character_decimal))
file.write('\n')
file.close()
def print_out_file(filename):
file = open(filename, "r")
lines = file.readlines()
for line in lines:
print "File \"" + filename + "\" contains: " + line,
file.close()
if __name__ == "__main__":
current_pid = os.getpid()
filenames = [
str(current_pid) + "_1.txt",
str(current_pid) + "_2.txt",
str(current_pid) + "_3.txt"
]
print "Generating files with names:"
for name in filenames:
make_file_with_random_letters(name)
print name
print "\nContents of files are:"
for name in filenames:
print_out_file(name)
print "\nGenerating two random numbers:"
first_number = random.randint(NUM_MIN, NUM_MAX)
second_number = random.randint(NUM_MIN, NUM_MAX)
print "First number is: " + str(first_number)
print "Second number is: " + str(second_number)
print "Product of the two numbers is: " + str(first_number*second_number)

View File

@@ -0,0 +1,2 @@
def kwic(document, listPairs=False, ignoreWords=[]):
return []

View File

@@ -0,0 +1,6 @@
from kwic import kwic
document = "" # Input no data
if __name__ == "__main__":
assert(kwic(document) == []) # Ensure that results are empty because there's no data

View File

@@ -0,0 +1,5 @@
def kwic(document, listPairs=False, ignoreWords=[]):
if not document:
return []
return [document]

View File

@@ -0,0 +1,8 @@
from kwic import kwic
empty_document = ""
design_words_doc = "Design is hard.\nLet's just implement."
if __name__ == "__main__":
assert(kwic(empty_document) == []) # Ensure empty input gives empty output
assert(kwic(design_words_doc) != []) # Ensure real input does not produce empty output

View File

@@ -0,0 +1,7 @@
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
split_into_sentences = document.splitlines()
return [split_into_sentences]

View File

@@ -0,0 +1,12 @@
from kwic import kwic
empty_document = ""
design_words_doc = "Design is hard.\nLet's just implement."
goodbye_buddy_doc = "Hello there.\nHello there, buddy.\nHello and goodbye, buddy.\nHello is like buddy Goodbye!"
if __name__ == "__main__":
assert(kwic(empty_document) == []) # Ensure empty input gives empty output
assert(kwic(design_words_doc) != []) # Ensure real input does not produce empty output
assert(len(kwic(design_words_doc)[0]) == 2) # [(), ()] Make sure it's broken into two lines
assert(len(kwic(goodbye_buddy_doc)[0]) == 4) # [(), ()] Make sure it's broken into four lines

View File

@@ -0,0 +1,10 @@
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
if periodsToBreaks:
split_into_sentences = document.split(".")
else:
split_into_sentences = document.splitlines()
return [split_into_sentences]

View File

@@ -0,0 +1,25 @@
from kwic import kwic
empty_document = ""
design_words_doc = "Design is hard.\nLet's just implement."
goodbye_buddy_doc = "Hello there.\nHello there, buddy.\nHello and goodbye, buddy.\nHello is like buddy Goodbye!"
hello_buddy_periods = "Hello there. Hello there, buddy. Hello and goodbye, buddy. Hello is like buddy Goodbye!"
if __name__ == "__main__":
# Ensure empty input gives empty output
assert(kwic(empty_document) == [])
# Ensure real input does not produce empty output
assert(kwic(design_words_doc) != [])
# Make sure it's broken into two lines
assert(len(kwic(design_words_doc)[0]) == 2)
# Make sure it's broken into four line
assert(len(kwic(goodbye_buddy_doc)[0]) == 4)
# Make sure line with just periods only shows up as one normally
assert(len(kwic(hello_buddy_periods)[0]) == 1)
# Make sure it's broken into four lines once it's broken by periods instead
assert(len(kwic(hello_buddy_periods, periodsToBreaks=True)[0]) == 4)

View File

@@ -0,0 +1,29 @@
def split_by_periods(document):
output_array = []
sentence_array_temp = ""
for current_char in document:
if current_char != "\n":
sentence_array_temp += current_char
if current_char == ".":
output_array.append(sentence_array_temp)
sentence_array_temp = ""
if sentence_array_temp:
output_array.append(sentence_array_temp)
return output_array
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
if periodsToBreaks:
split_into_sentences = split_by_periods(document)
else:
split_into_sentences = document.splitlines()
return split_into_sentences

View File

@@ -0,0 +1,29 @@
from kwic import kwic
empty_document = ""
design_words_doc = "Design is hard.\nLet's just implement."
goodbye_buddy_doc = "Hello there.\nHello there, buddy.\nHello and goodbye, buddy.\nHello is like buddy Goodbye!"
hello_buddy_periods = "Hello there. Hello there, buddy. Hello and goodbye, buddy. Hello is like buddy Goodbye!"
hello_buddy_periods_output = ["Hello there.", " Hello there, buddy.", " Hello and goodbye, buddy.",
" Hello is like buddy Goodbye!"]
if __name__ == "__main__":
# Ensure empty input gives empty output
assert(kwic(empty_document) == [])
# Ensure real input does not produce empty output
assert(kwic(design_words_doc) != [])
# Make sure it's broken into two lines
assert(len(kwic(design_words_doc)) == 2)
# Make sure it's broken into four line
assert(len(kwic(goodbye_buddy_doc)) == 4)
# Make sure line with just periods shows up as itself
assert(kwic(hello_buddy_periods)[0] == hello_buddy_periods)
# Make sure it's broken into four lines once it's broken by periods instead
# Also, this time it keeps the ending period like it's supposed to
assert(kwic(hello_buddy_periods, periodsToBreaks=True) == hello_buddy_periods_output)

View File

@@ -0,0 +1,44 @@
def split_by_periods(document):
output_array = []
sentence_array_temp = ""
for current_char in document:
if current_char != "\n":
sentence_array_temp += current_char
if current_char == ".":
output_array.append(sentence_array_temp)
sentence_array_temp = ""
if sentence_array_temp:
output_array.append(sentence_array_temp)
return output_array
def split_by_word_as_tuples(sentence_array):
output_array = []
index_incrementer = 0
for sentence in sentence_array:
words_array = sentence.split(" ")
words_array = filter(None, words_array)
output_array.append((words_array, index_incrementer))
index_incrementer += 1
return output_array
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
if periodsToBreaks:
split_into_sentences = split_by_periods(document)
else:
split_into_sentences = document.splitlines()
split_into_word_tuples = split_by_word_as_tuples(split_into_sentences)
return split_into_word_tuples

View File

@@ -0,0 +1,33 @@
from kwic import kwic
empty_document = ""
design_words_doc = "Design is hard.\nLet's just implement."
goodbye_buddy_doc = "Hello there.\nHello there, buddy.\nHello and goodbye, buddy.\nHello is like buddy Goodbye!"
hello_buddy_periods = "Hello there. Hello there, buddy. Hello and goodbye, buddy. Hello is like buddy Goodbye!"
hello_buddy_periods_output = [(["Hello", "there.", "Hello", "there,", "buddy.", "Hello", "and", "goodbye,", "buddy.",
"Hello", "is", "like", "buddy", "Goodbye!"], 0)]
hello_buddy_word_tuples_output = [(["Hello", "there."], 0),
(["Hello", "there,", "buddy."], 1),
(["Hello", "and", "goodbye,", "buddy."], 2),
(["Hello", "is", "like", "buddy", "Goodbye!"], 3)]
if __name__ == "__main__":
# Ensure empty input gives empty output
assert(kwic(empty_document) == [])
# Ensure real input does not produce empty output
assert(kwic(design_words_doc) != [])
# Make sure it's broken into two lines
assert(len(kwic(design_words_doc)) == 2)
# Make sure it's broken into four line
assert(len(kwic(goodbye_buddy_doc)) == 4)
# Make sure array contains same elements from kwic vs test output
assert(any(x in kwic(hello_buddy_periods) for x in hello_buddy_periods_output))
# Make sure arrays contain the same elements from kwic vs test, even with periods for breaks...
assert(any(x in kwic(hello_buddy_periods, periodsToBreaks=True) for x in hello_buddy_word_tuples_output))

View File

@@ -0,0 +1,61 @@
def split_by_periods(document):
output_array = []
sentence_array_temp = ""
for current_char in document:
if current_char != "\n":
sentence_array_temp += current_char
if current_char == ".":
output_array.append(sentence_array_temp)
sentence_array_temp = ""
if sentence_array_temp:
output_array.append(sentence_array_temp)
return output_array
def split_by_word_as_tuples(sentence_array):
output_array = []
index_incrementer = 0
for sentence in sentence_array:
words_array = sentence.split(" ")
words_array = filter(None, words_array)
output_array.append((words_array, index_incrementer))
index_incrementer += 1
return output_array
def array_circular_shift(input_array, rotate_val):
output_array = input_array[rotate_val:] + input_array[:rotate_val]
return output_array
def fill_with_circular_shifts_and_original(sentence_array):
output_array = []
for current_tuple in sentence_array:
for index, _ in enumerate(current_tuple[0]):
output_array.append((array_circular_shift(current_tuple[0], index), current_tuple[1]))
return output_array
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return [], []
if periodsToBreaks:
split_into_sentences = split_by_periods(document)
else:
split_into_sentences = document.splitlines()
split_into_word_tuples = split_by_word_as_tuples(split_into_sentences)
output_tuple = (fill_with_circular_shifts_and_original(split_into_word_tuples), [])
return output_tuple

View File

@@ -0,0 +1,55 @@
import kwic
empty_document = ""
design_words_doc = "Design is hard.\nLet's just implement."
goodbye_buddy_doc = "Hello there.\nHello there, buddy.\nHello and goodbye, buddy.\nHello is like buddy Goodbye!"
hello_buddy_periods = "Hello there. Hello there, buddy. Hello and goodbye, buddy. Hello is like buddy Goodbye!"
this_is_split_periods_circular_output = [
(['This', 'is', 'something', 'split', 'by', 'periods.'], 0),
(['is', 'something', 'split', 'by', 'periods.', 'This'], 0),
(['something', 'split', 'by', 'periods.', 'This', 'is'], 0),
(['split', 'by', 'periods.', 'This', 'is', 'something'], 0),
(['by', 'periods.', 'This', 'is', 'something', 'split'], 0),
(['periods.', 'This', 'is', 'something', 'split', 'by'], 0),
(['Not', 'newlines.'], 1),
(['newlines.', 'Not'], 1)
]
if __name__ == "__main__":
# Ensure empty input gives empty output
assert(kwic.kwic(empty_document) == ([], []))
# Ensure real input does not produce empty output
assert(kwic.kwic(design_words_doc) != ([], []))
# Make sure it's broken into two lines
assert(len(kwic.kwic(design_words_doc)[0]) == 6)
# Make sure it's broken into four line
assert(len(kwic.kwic(goodbye_buddy_doc)[0]) == 14)
# Just realized I can check each individual function, so here is the check to split by periods
assert(kwic.split_by_periods("This is something split \nby periods. Not \n newlines.") ==
["This is something split by periods.", " Not newlines."])
# This checks to make sure a sentence gets split into words properly
assert(kwic.split_by_word_as_tuples(["This is something split by periods.", " Not newlines."]) ==
[(['This', 'is', 'something', 'split', 'by', 'periods.'], 0), (['Not', 'newlines.'], 1)])
# These check to make sure that the circular shift function is rotating properly
assert(kwic.array_circular_shift(["One", "Two", "Three", "Four", "Five"], 0) ==
["One", "Two", "Three", "Four", "Five"])
assert (kwic.array_circular_shift(["One", "Two", "Three", "Four", "Five"], 2) ==
["Three", "Four", "Five", "One", "Two"])
# This checks to make sure than circularly shifted versions of all sentences are correct
assert(kwic.fill_with_circular_shifts_and_original([(['This', 'is', 'something', 'split', 'by', 'periods.'], 0),
(['Not', 'newlines.'], 1)]) ==
this_is_split_periods_circular_output)
# This gives a bit of a sanity check. It's making sure the circular shift works, and that the output is formatted
# correctly...
assert(kwic.kwic("This is something split \nby periods. Not \n newlines.", periodsToBreaks=True) ==
(this_is_split_periods_circular_output, []))

View File

@@ -0,0 +1,64 @@
def split_by_periods(document):
output_array = []
sentence_array_temp = ""
for current_char in document:
if current_char != "\n":
sentence_array_temp += current_char
if current_char == ".":
output_array.append(sentence_array_temp)
sentence_array_temp = ""
if sentence_array_temp:
output_array.append(sentence_array_temp)
return output_array
def split_by_word_as_tuples(sentence_array):
output_array = []
index_incrementer = 0
for sentence in sentence_array:
words_array = sentence.split(" ")
words_array = filter(None, words_array)
output_array.append((words_array, index_incrementer))
index_incrementer += 1
return output_array
def array_circular_shift(input_array, rotate_val):
output_array = input_array[rotate_val:] + input_array[:rotate_val]
return output_array
def fill_with_circular_shifts_and_original(sentence_array):
output_array = []
for current_tuple in sentence_array:
for index, _ in enumerate(current_tuple[0]):
output_array.append((array_circular_shift(current_tuple[0], index), current_tuple[1]))
return output_array
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
if periodsToBreaks:
split_into_sentences = split_by_periods(document)
else:
split_into_sentences = document.split('\n')
split_into_word_tuples = split_by_word_as_tuples(split_into_sentences)
if listPairs:
output_data = (fill_with_circular_shifts_and_original(split_into_word_tuples), [])
else:
output_data = fill_with_circular_shifts_and_original(split_into_word_tuples)
return output_data

View File

@@ -0,0 +1,55 @@
import kwic
empty_document = ""
design_words_doc = "Design is hard.\nLet's just implement."
goodbye_buddy_doc = "Hello there.\nHello there, buddy.\nHello and goodbye, buddy.\nHello is like buddy Goodbye!"
hello_buddy_periods = "Hello there. Hello there, buddy. Hello and goodbye, buddy. Hello is like buddy Goodbye!"
this_is_split_periods_circular_output = [
(['This', 'is', 'something', 'split', 'by', 'periods.'], 0),
(['is', 'something', 'split', 'by', 'periods.', 'This'], 0),
(['something', 'split', 'by', 'periods.', 'This', 'is'], 0),
(['split', 'by', 'periods.', 'This', 'is', 'something'], 0),
(['by', 'periods.', 'This', 'is', 'something', 'split'], 0),
(['periods.', 'This', 'is', 'something', 'split', 'by'], 0),
(['Not', 'newlines.'], 1),
(['newlines.', 'Not'], 1)
]
if __name__ == "__main__":
# Ensure empty input gives empty output
assert(kwic.kwic(empty_document) == ([]))
# Ensure real input does not produce empty output
assert(kwic.kwic(design_words_doc) != ([]))
# Make sure it's broken into two lines
assert(len(kwic.kwic(design_words_doc)) == 6)
# Make sure it's broken into four line
assert(len(kwic.kwic(goodbye_buddy_doc)) == 14)
# Just realized I can check each individual function, so here is the check to split by periods
assert(kwic.split_by_periods("This is something split \nby periods. Not \n newlines.") ==
["This is something split by periods.", " Not newlines."])
# This checks to make sure a sentence gets split into words properly
assert(kwic.split_by_word_as_tuples(["This is something split by periods.", " Not newlines."]) ==
[(['This', 'is', 'something', 'split', 'by', 'periods.'], 0), (['Not', 'newlines.'], 1)])
# These check to make sure that the circular shift function is rotating properly
assert(kwic.array_circular_shift(["One", "Two", "Three", "Four", "Five"], 0) ==
["One", "Two", "Three", "Four", "Five"])
assert (kwic.array_circular_shift(["One", "Two", "Three", "Four", "Five"], 2) ==
["Three", "Four", "Five", "One", "Two"])
# This checks to make sure than circularly shifted versions of all sentences are correct
assert(kwic.fill_with_circular_shifts_and_original([(['This', 'is', 'something', 'split', 'by', 'periods.'], 0),
(['Not', 'newlines.'], 1)]) ==
this_is_split_periods_circular_output)
# This gives a bit of a sanity check. It's making sure the circular shift works, and that the output is formatted
# correctly...
assert(kwic.kwic("This is something split \nby periods. Not \n newlines.", periodsToBreaks=True) ==
this_is_split_periods_circular_output)

View File

@@ -0,0 +1,64 @@
def split_by_periods(document):
output_array = []
sentence_array_temp = ""
for current_char in document:
if current_char != "\n":
sentence_array_temp += current_char
if current_char == ".":
output_array.append(sentence_array_temp)
sentence_array_temp = ""
if sentence_array_temp:
output_array.append(sentence_array_temp)
return output_array
def split_by_word_as_tuples(sentence_array):
output_array = []
index_incrementer = 0
for sentence in sentence_array:
words_array = sentence.split(" ")
words_array = filter(None, words_array)
output_array.append((words_array, index_incrementer))
index_incrementer += 1
return output_array
def array_circular_shift(input_array, rotate_val):
output_array = input_array[rotate_val:] + input_array[:rotate_val]
return output_array
def fill_with_circular_shifts_and_original(sentence_array):
output_array = []
for current_tuple in sentence_array:
for index, _ in enumerate(current_tuple[0]):
output_array.append((array_circular_shift(current_tuple[0], index), current_tuple[1]))
return output_array
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
if periodsToBreaks:
split_into_sentences = split_by_periods(document)
else:
split_into_sentences = document.splitlines()
split_into_word_tuples = split_by_word_as_tuples(split_into_sentences)
if listPairs:
output_data = (fill_with_circular_shifts_and_original(split_into_word_tuples), [])
else:
output_data = fill_with_circular_shifts_and_original(split_into_word_tuples)
return output_data

View File

@@ -0,0 +1,31 @@
1. How did you decide what to test first? Would your final code change significantly if you changed the order of tests?
The process for deciding what to test mostly had to do with a logical breakdown of the core parts of the code so that
things that relied on others to work were done after those pre-requisites. So, for example, before we could do anything
first the document had to be broken down into sentences, then words. In that part, you could also change whether or not
the sentence breaks were handled with newlines or periods. Afterwards, you could then deal with rearranging the words as
necessary, handling determining pairs, and then excluding any words that were given as arguments. I don't feel like the
code would have been massively different if it'd been done in reverse, but it definitely would have been more difficult
to write. On top of that, you'd still have to think all the way through how the code would need to function, regardless
of the order in which you wrote it, in order to know what needed to be written in the first place. Also, if you
literally reversed the order of the tests, it could lead to you skipping the whole point of using tests (if you did it
incorrectly). Again, for an example, if you wrote a test that produced the final output of the program as the initial
input and expected a correct output, you'd either have to hard code many many values in to the resulting code while you
implemented them for real, or you'd end up writing all necessary code at once, which would defeat the purpose.
2. What did you think of test driven development, for this problem? What are the strengths and weaknesses of the
approach? Does it encourage/discourage certain kinds of program designs?
I'm torn about it. I feel that for this particular problem, it may have been overkill and actually hampered design
progress at times. The main issue was that for each major step, the output of the code often changed enough that many
of the tests had to be modified or rewritten to match. The definite strengths of this approach are that you can easily
tell when you change something that breaks the functionality of your code, and it will immediately produce an exception.
On the flip side, it does take much longer to write functional code depend on what exactly you're writing. I would
argue that the larger the application being written, the more important it would be to do this kind of testing.
Without it, you might be digging through hundreds of thousands to millions of lines of code to figure out what is
breaking. I can definitely appreciate the fact that taking the time to write the tests helps guarantee that it's doing
what you want, but I feel like it would be more useful in other programming contexts, like the one just mentioned.
I'd say this style of coding encourages program designs that have a consistent output even if the underlying code
changes often. For example, I feel like it'd be ideal for developing an API where once a standard has been created,
that API should function identically for a long time, even if the backend is changing constantly. In general, this way
of programming also encourages full coverage of edge cases, as you'll easily and quickly be able to test for them.

View File

@@ -0,0 +1,2 @@
def kwic(document, listPairs=False, ignoreWords=[]):
return []

View File

@@ -0,0 +1,5 @@
def kwic(document, listPairs=False, ignoreWords=[]):
if not document:
return []
return [document]

View File

@@ -0,0 +1,7 @@
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
split_into_sentences = document.splitlines()
return [split_into_sentences]

View File

@@ -0,0 +1,10 @@
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
if periodsToBreaks:
split_into_sentences = document.split(".")
else:
split_into_sentences = document.splitlines()
return [split_into_sentences]

View File

@@ -0,0 +1,29 @@
def split_by_periods(document):
output_array = []
sentence_array_temp = ""
for current_char in document:
if current_char != "\n":
sentence_array_temp += current_char
if current_char == ".":
output_array.append(sentence_array_temp)
sentence_array_temp = ""
if sentence_array_temp:
output_array.append(sentence_array_temp)
return output_array
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
if periodsToBreaks:
split_into_sentences = split_by_periods(document)
else:
split_into_sentences = document.splitlines()
return split_into_sentences

View File

@@ -0,0 +1,44 @@
def split_by_periods(document):
output_array = []
sentence_array_temp = ""
for current_char in document:
if current_char != "\n":
sentence_array_temp += current_char
if current_char == ".":
output_array.append(sentence_array_temp)
sentence_array_temp = ""
if sentence_array_temp:
output_array.append(sentence_array_temp)
return output_array
def split_by_word_as_tuples(sentence_array):
output_array = []
index_incrementer = 0
for sentence in sentence_array:
words_array = sentence.split(" ")
words_array = filter(None, words_array)
output_array.append((words_array, index_incrementer))
index_incrementer += 1
return output_array
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return []
if periodsToBreaks:
split_into_sentences = split_by_periods(document)
else:
split_into_sentences = document.splitlines()
split_into_word_tuples = split_by_word_as_tuples(split_into_sentences)
return split_into_word_tuples

View File

@@ -0,0 +1,61 @@
def split_by_periods(document):
output_array = []
sentence_array_temp = ""
for current_char in document:
if current_char != "\n":
sentence_array_temp += current_char
if current_char == ".":
output_array.append(sentence_array_temp)
sentence_array_temp = ""
if sentence_array_temp:
output_array.append(sentence_array_temp)
return output_array
def split_by_word_as_tuples(sentence_array):
output_array = []
index_incrementer = 0
for sentence in sentence_array:
words_array = sentence.split(" ")
words_array = filter(None, words_array)
output_array.append((words_array, index_incrementer))
index_incrementer += 1
return output_array
def array_circular_shift(input_array, rotate_val):
output_array = input_array[rotate_val:] + input_array[:rotate_val]
return output_array
def fill_with_circular_shifts_and_original(sentence_array):
output_array = []
for current_tuple in sentence_array:
for index, _ in enumerate(current_tuple[0]):
output_array.append((array_circular_shift(current_tuple[0], index), current_tuple[1]))
return output_array
def kwic(document, listPairs=False, ignoreWords=None, periodsToBreaks=False):
if not document:
return [], []
if periodsToBreaks:
split_into_sentences = split_by_periods(document)
else:
split_into_sentences = document.splitlines()
split_into_word_tuples = split_by_word_as_tuples(split_into_sentences)
output_tuple = (fill_with_circular_shifts_and_original(split_into_word_tuples), [])
return output_tuple

Some files were not shown because too many files have changed in this diff Show More