mirror of
https://github.com/caperren/school_archives.git
synced 2025-11-09 13:41:13 +00:00
Added work from my other class repositories before deletion
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
This has some text in it.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
This file has some more text.
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -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
|
||||||
@@ -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));
|
||||||
@@ -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("*****");
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="automobile.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -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>
|
||||||
@@ -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 = '↑';
|
||||||
|
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 = '→';
|
||||||
|
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 = '←';
|
||||||
|
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 = '↓';
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
@@ -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>
|
||||||
@@ -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);
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<h1>Error 404 - Page Is Nowhere to be Found</h1>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<h1>Error 500 - Something Has Gone Terribly Wrong</h1>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Demo Page</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{{body}}}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<h1>Error 404 - Page Is Nowhere to be Found</h1>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<h1>Error 500 - Something Has Gone Terribly Wrong</h1>
|
||||||
@@ -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>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<h1>{{StatusHeader}}</h1>
|
||||||
|
<h2>Query Parameters</h2>
|
||||||
|
<ul>
|
||||||
|
{{#each query_data}}
|
||||||
|
<li>{{this.name}}: {{this.value}}
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
@@ -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>
|
||||||
@@ -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);
|
||||||
|
|
||||||
738
OSU Coursework/CS 340 - Intro to Databases/Final Project/app.js
Normal file
738
OSU Coursework/CS 340 - Intro to Databases/Final Project/app.js
Normal 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);
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
$db_host = 'oniddb.cws.oregonstate.edu';
|
||||||
|
$db_name = 'perrenc-db';
|
||||||
|
$db_user = 'perrenc-db';
|
||||||
|
$db_pass = 'rjqm1mGiAFpoEI8R';
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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(¤t_time_raw);
|
||||||
|
time_as_struct = localtime(¤t_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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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.
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
make clean
|
||||||
|
make build
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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'
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
THE RED GOOSE FLIES AT MIDNIGHT STOP
|
||||||
@@ -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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
IN THE BEGINNING
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
$*!(#*djs8301these-are-all-bad-characters
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
def kwic(document, listPairs=False, ignoreWords=[]):
|
||||||
|
return []
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
def kwic(document, listPairs=False, ignoreWords=[]):
|
||||||
|
if not document:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return [document]
|
||||||
@@ -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
|
||||||
@@ -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]
|
||||||
@@ -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
|
||||||
@@ -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]
|
||||||
@@ -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)
|
||||||
@@ -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
|
||||||
@@ -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)
|
||||||
@@ -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
|
||||||
@@ -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))
|
||||||
@@ -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
|
||||||
@@ -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, []))
|
||||||
@@ -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
|
||||||
@@ -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)
|
||||||
@@ -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
|
||||||
@@ -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.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
def kwic(document, listPairs=False, ignoreWords=[]):
|
||||||
|
return []
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
def kwic(document, listPairs=False, ignoreWords=[]):
|
||||||
|
if not document:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return [document]
|
||||||
@@ -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]
|
||||||
@@ -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]
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user