User Tools

Site Tools


blog:spring2016:tmosgrov:start

Tyler Mosgrove's spring2016 Opus

Introduction

I'm back for the semester of all semesters. I'm in four classes with only two teachers, and two class rooms to attend. Can't complain. This is the semester of semesters where I can truly dedicate myself to my major. I hope to fall down that rabbit hole once again, but find the other side and all the enlightenment that comes with it. I've touched Java for the first time (made my first hello_world prog), and I'm excited to be that jack of all trades that my HPC (or should I say System Admin?) background has taught me. Which reminds me of another thing yet to be excited about. Matt's rendition of Web Development, and me getting to experience PHP. It's going to be a great semester. 8-)

HPC Experience II Journal

Jan 25, 2016

Memory, memory, memory, and memory. Today, me and mister Matt Page played around with the towers that are pending the trash and or a new home. I got to see elementary OS which seems nice and shiny. We eventually found out the memory we were using did not support the systems we were testing. Thus we will have to retest the towers that we assumed were dead. Eventually I will get a workstation to use out of one of those systems. Once that happens I will probably revisit the USB project I had attempted last semester, and hopefully get to touch upon LFS once again.

FEB 01, 2016

Ah, Seems I've been neglecting my HPC opus shame on me. Hopefully Matt would say many of the things we are doing in systems programming and maybe the rest of my classes are in some way shape or form HPC related. Still keeping LFS, and USB activities in mind. Matt Page is setting up the samba file server at the moment and I can't wait to see it in action, and the configuration fun along the way.

FEB 02, 2016

Today Matt Page was relentlessly working on the server. He was smashing hard drives into the machine because they did not want to fit… Just kidding. Matt Page is rather gentle at nature. He turned to me seeking hardware advice regarding the issue, but little did he know the person he was talking to was border line stupid when it came to the subject. None the less I pretended like I had insight on this hard drive thing and I think he bought it, phew.

FEB 03, 2016

Today I've decided all my opus entries should be Matt Page's biography. Little is known about the Matt Page, and we are willing invest lots of research on the subject. Earlier this morning Matt had informed me he resolved the hard drive issue and that all it needed was a gentle nudge. After that we may have debated for a good hour (or so I felt) of what to do with the cd-drive seeing as how it is not needed. Eventually Matt (Matt the teacher, not you Matt Page) gave word that it did not need to be hooked up, but It should stay in the server. Then Matt (the teacher) broke out on some crazy RAID that rocked me and Matt Pages world. What felt like a hallucinogenic trip straight out of the 80s was really just the fact that I had no idea that you could sync drives up together in ridiculous ways.

RAID - Originally redundant array of inexpensive disks now redundant array of independent disks. RAID is a data storage virtualization technology that combines multiple physical disk devices into a single logical unit. This could be for data redundancy(back ups), performance, or both. The data is distributed in one of many ways across drives called RAID LEVELS.

In our case we were configuring a RAID1 which would mirror the hard disks creating a backup had one failed. So, both hard drives would contain the same data essentially whenever a write occurs it is propagated to both disks. To the outsider accessing the hard disks he/she is only seeing that one logical unit or “virtual device” that mdad created. Finally, if it wasn't enough the first time my world was rocked once more when Matt (teacher Matt) mentioned that you can review diagnostic data that a hard drive collects on itself.

S.M.A.R.T-Self-Monitoring, Analysis and Reporting Technology. A system included in a computer hard disk which detects and reports various indicators or drive readability. This enables the anticipation of future hardware failures.

I did not know this was a thing either! This eventually lead us to the tool smartctl which comes with the package smartmontools. Here's a sample screen of it's info output on my laptop's hard disk.

=== START OF INFORMATION SECTION ===
Model Family:     Western Digital Scorpio Blue Serial ATA (AF)
Device Model:     WDC WD3200BPVT-60JJ5T0
Serial Number:    WD-WXA1C12J3489
LU WWN Device Id: 5 0014ee 602387c5f
Firmware Version: 01.01A01
User Capacity:    320,072,933,376 bytes [320 GB]
Sector Sizes:     512 bytes logical, 4096 bytes physical
Rotation Rate:    5400 rpm
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   ATA8-ACS (minor revision not indicated)
SATA Version is:  SATA 2.6, 3.0 Gb/s
Local Time is:    Wed Feb  3 13:59:01 2016 EST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

Neat stuff!

FEB 08, 2016

Slow start today but we got moving. Me Matt & Matt Page configured samba on the server which seemed relatively portable and easy to configure to the untrained eye. Matt P setup some dummy user accounts for testing and we attempted to connect to the server which is still being worked out at the moment. Matt the instructor showed me his cool script for Barb to do minimal server maintenance mainly for adding and removing user's, but it seemed he put quite a bit more into it. I'm a big fan of those kind of solutions I love the idea of creating tools for less advanced users. A little bit old school actually. Well, because most of that kind of help comes bundled in an operating system these days and you don't see many people sitting in front of a command prompt. Not only that, but to come up with a less expensive solution is totally admirable.

SAMBA - provides file and print services for various clients and can integrate with a domain server or domain controller as a domain member.

Domain Controller - is a server that responds to security authentication requests (logging in, checking permissions, etc). A domain is concept where a user may be granted access to a number of computer resources with the use of a single username and password.

FEB 22, 2016

Well, break is over and I feel like I haven't done a damn thing or so it feels. However, one may say I managed to endeavor through a lot of HPC like activities during break. I started off the break by cranking half way through a C++ borland book which was my distraction while I waited for my new setup. Eventually it came after having had returned a previous laptop that was bunk to newegg the 14“ Dell e6410 arrived. Having been slightly disappointed with the lack of the back-lit keyboard that was in fact advertised It eventually grew on me. It was now time to setup my dream work station as I mentioned in an earlier entry. I wanted to deploy something relatively quick over break so I chose ol' trusty debian. I grabbed a debian live iso off the webs and made a decisions to start without a desktop. Which was a proud decision on my part, because all this time I have been saying how I'm going to throw out windows and become this hardcore linux user like Matt Page but It was all just talk and I'm still a poser, haha. However, I did what I said I was going to, and I did infact install debian… next to windows without a desktop environment (standard) for starters. The plan was to have i3, and I'm proud to say that is all I need these days. Now I know what you are thinking. Yes, saying that is quite a contradictory statement, but with the contrast I have learned how we take these things for granted. We take for granted all of the hardware that comes with a laptop out of the box. Most people don't even know what is inside their computer. Debian out of the box was like licking ice cream. I'm not sure what I mean by that, but it reminded me of summer or rather around the time I was first exposed to UNIX systems (via Matt's class). Back to taking things for granted. The moment I started the installation I had a driver issue with my wifi card which lead me down a road of research. I found out that not everything in life is free… By that I mean Debian being “free-software” was not going to come packaged with non-free software. I also found out that there are not many wifi nic vendors out there that support this notion of “free-software” and ongoing support/functionality. I eventually found the non-free drivers I was looking for, but it was as if Richard Stallman himself stomped on my foot. I already felt like I had stained my freshly installed system of “free-software” with non-free software. Oh well, I was already a sell out a long time ago. Too be continue…

So after the debian installation I eventually acquired the firmware/drivers for my wifi card via ethernet. This was a little confusing so I just haphazardly downloaded all the related broadcom drivers. Then, I found that configuring wifi through /etc/network/interfaces and wpa-supplement was easier said than done as I've experienced with most things. However, I've been learning that if it is an issue chances are you are not the only one experiencing it, and that there are packages out there to do all the work for you. After that the rest was making myself at home and getting other things up and running like system audio (thanks Matt Page). Heck, i3 was easier than I thought it would be to install. When reviewing various procedures online for installing X and i3 wm it seemed difficult, but as with most things it comes down to did you get all the right packages?, if certain permissions are granted per the user, and at the least modifying a .config file (.Xinitrc “exec i3”). After having made myself well at home the next thing I will be attempting eventually is shrinking the windows partition down and sharing a /home or “Documents” partition between windows and debian. If the fun was just about to end Matt also suggested I play around with wine… Which at the end of the day again reminded me how much I don't need windows, but regardless it is going nicely with my experiment.

FEB 24, 2016

This week has been rolling slowly, and I've been having the hardest time doing something HPC applicable (or getting into my school work at all as a matter of fact). So, I should decree to endeavour into a project. That project I do not know of yet so I will research right now… Too be continue.

FEB 25, 2016

Again this week has been the most unproductive week ever. I have so much on my mind I've been having trouble keeping up with my opus. Scratch the research I previously said I was going to do, I'm happily going to work on the samba admin management script with Matt Page. I love the idea of developing stuff like this for less tech savy peoples. It should be a blast! I'm working on getting the commands like adduser, and passwd to be pass-wordless so a script can execute them without needing to enter the appropriate sudoers password every time. This is done in one of the root config files that I have forgoten the name of at this moment. (etc/sudoers)

FEB 29, 2016

Alright, I'm done complaining about not getting work done and well I'm just going to get some work done. This is going to be a good week for me I can feel it. For starters, Friday before I left school I had played around with ideas for the script that can be found in /home/tmosgrov/src/. I kept stressing structure with something like this to keep the typing and confusion to a minimum once you throw in all the whiptail commands things get pretty cluttered. So, I was entertaining myself with $variable like settings (dimensions for whiptail screens), and a preventive from infinite loops that can be a pain when playing with whiptail. Once you are stuck in a loop since whiptail has high jacked stdin your in for the long ride. Also, prior to all this Matt Page successfully helped me set up nopasswd prompt for commands like adduser, and deluser. To be continued!

Mar 01, 2016

So… I lied I'm back to complaining about not getting any work done. I got distracted by configuring my new debian setup some more on my laptop. Fun stuff, bindingkeys and getting things to work as they should. Making myself at home has never felt so good. I also picked my first login manager (slim), and I'm digging the user/default themes that are out there. Anyways, suppose I should talk about something more HPC related, hehe. I've been thinking about me and Matt Pages project on the admin script. We have officially created our repo, and are now under way of the design phase. I'm very excited about this, because I love me some bash scripting. I'm going to pass this by Matt(The Teacher), and Matt(The Page) about copying Matt(The Teacher's) manage script to the repo as a base example. This would be convenient for me and Mr.Matt Page as we could dissect the script, and be more able to deliver what Hass is looking for. It would be a win win if I do say so myself. I'm also pumped about working with Matt Page, as I have already learned a bunch of HPC unix/linux related stuff from the dude himself. Dude is a great resource. Man I swear, I write these things as if no one will ever read them.

Mar 09, 2016

Today, Me and Matt Page got to brainstorming our script after a long-awaited adieu. I dropped my ideas on Matt Page like a shy school-girl on the first day of high-school. What's with all the hyphenated words? Beats me, So I showed Matt how I was feverishly looking for ways to decrease the cluttered code whiptail creates with just one call. Matt Page seemed to be digging the idea so I kept rolling with them. Then… He asked me why I didn't just add all my stuff to the repo in the first place. I was too embarrassed, I didn't want to thrust all my ideas on to Matt Page at one time. I was afraid of rejection. So, we've got a base to work with. There will be two needed menus accounts and services, and maybe even a help menu to make things fancy. We also contemplated the idea of having a shut-down/restart option for the user. More to come!

Mar 23, 2016

Today, me and Matt page swiftly put together our group “wipe” (name pending) feature in our manage script. This got our brains ticking so we added to our wish list a check-list box which would display all users set for removal within the student group. However, we are still working on variable menu options in whiptail which can be dicey. Little does Matt Page know I figured out a work around thanks to the internet, but there is another issue. Whiptail's check-list box appears to not be displaying messages or default text. I'm not sure if this is a bug, but I'm thinking it may be. More to come!

Apr, 04, 2016

I'm very proud of the work I have managed to get done today. I have many surprises for Matt Page when I see him again. I added the highly anticipated group wipe checklist where the administrator can specify the deletion of some or all (default) users within the student group. Second, I did a lot of restricting making things look pretty, and suppressing more output to /dev/null. I added the –notags flag on the whiptail menu commands to remove the unneeded menu tags. Finally, I removed the services folder because it has been decided that restarting services and the like should be right on the main menu. Also, I rigged up Matt Pages glorious loading bar for the sambarestart.sh. Things are coming together stay tuned!

Apr, 07, 2016

Me and Matt Page turned up the heat yesterday, and we managed to cook up a lot of good stuff. We now have a view users screen where the administrator can view all the users that have been added to the system. This conjured up a few more ideas such as viewing disk space usage, and log information. This is great because our menus look a little slim without many options to choose from. So much to do so little time.

Apr, 13, 2016

Seems things are coming down to cleaning up the manage script for deployment. We are still working on a view users log information, and adding a user with elevated privileges functionality. The rest of the foreseen work is polishing, and keep an ear out for suggestions of improvement. It's been nice getting to work with Mr.Page he's managed to show me a thing or two, and remind me of my inability to spell.

Web Development Journal

JAN 22, 2

Getting started with PHP

Server side scripting with php. PHP is a form of CGI (Common Gateway Interfacing) that enables a client to interface with executable programs remotely. As a pose to executing on the client side like Java Script PHP is executed again via server side. This leaves the possibility to create dynamic webpages based on a multitude of things even on a per user basis. The words server side scripting did mean much to me until I saw it in actions.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
     <head>
         <title>Home Page</title>
         <link rel="stylesheet" type="text/css" href="home.css">
     </head>
 
     <body>
             <?php
 
                 if (strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') != FALSE)
                 {
                     echo "The web browser you are using is Chrome!";
 
                 }
                 else
                 {
                     echo "Why you no use Chrome!?";
                }
      ?>
</body>
</html>

This php script (or file named home.php) looks more like an html file with php code embedded in it. However, the way the server treats this file is obviously different than that of an html file. With the extension .php the web server knows to treat the file as a php file, and all other html code accordingly.

NOTE: To begin the script encase all php code between these opening and closing brackets.

<?php
       echo "Your code here!"
?>

NOTE: PHP must be enabled on the web server to be able interpret php files.

NOTE: PHP has what are called super global variables that are accessible at any scope of a script.

    $GLOBALS
    $_SERVER
    $_GET
    $_POST
    $_FILES
    $_COOKIE
    $_SESSION
    $_REQUEST
    $_ENV

When we consider the possibilities with .php it can be overwhelming. PHP can not only be used to create dynamic webpages, but it has even more functionality. PHP can also be used to run server side routines or updates, and it can even access a database. Finally, the possibility of conditional statements and loops makes php even more of a power house.

JAN 25, 2016

Setting a variable

$var="string";
$var=10;
$var=10.5;

Call to rand

rand(min, max);

Echoing stuff

echo "<a href=\"home.html\">Plain text and $var</a>"

JAN 27, 2016

Seeing the ability of a “dynamic” web page is becoming more apparent with php. The CSS and HTML sprinkled along the way is a nice treat. Based off of Matt's presentation with the use of the rand function I have a mini web page which randomly generates a banner and body background color.

The code

<?php                                                  
$col_or=rand(0,999999);
echo "body {
background-color: #$col_or}";
?>

This php block is actually echoing css styling in the header generating a random color for the html body element.

The next thing I would like to tackle is revisit html forms and processing cookies with php. I will try to find something more thrilling along the way.

If Statements

if( $a == $b )
{
    echo "if";
}
else if($a != $b)
{
    echo "else if";
}
else
{
    echo "else";
}

The syntax of php is remarkably similar to c.

Denoting A Hex Value

$color=rand(0x0,0xFFFFFF);
echo "color=$color";

Again, remarkably similar to c.

FEB 01, 2016

Accomplished a checker bored via php today.

The Code

<!DOCTYPE html>
<html>
	<head>
		<title>Checker</title>
	</head>
<body>
<?php
$index=1;
$switch=0;
echo 	"<table border=1 style=\"margin: 40%;\" >";
 
	for($i=0; $i<8; $i++)
	{
		echo "<tr>";
		if($switch==1){$switch=0;}else{$switch=1;}
 
		for($k=0; $k<8; $k++)
		{
 
			if($switch==1){$var="white";}else{$var="black";}
			echo "<td style=\"background-color: $var; color: red;\"";
			if($index <= 8)
			{
				if($index%2){echo ">O</td>";}
				else{echo ">&nbsp;</td>";}
			}
			else if($index > 8 && $index <= 16)
			{
				if(!($index%2)){echo ">O</td>";}
				else{echo ">&nbsp;</td>";}
			}
			else if($index > 16 && $index <= 24)
			{
				if($index%2){echo ">O</td>";}
				else{echo ">&nbsp;</td>";}
			}
 
			else if($index<=40){echo ">&nbsp;</td>";}
			else if($index > 40 && $index <= 48)
			{
				if(!($index%2)){echo ">X</td>";}
				else{echo ">&nbsp;</td>";}
			}
			else if($index > 48 && $index <= 56)
			{
				if($index%2){echo ">X</td>";}
				else{echo ">&nbsp;</td>";}
			}
			else
			{
				if(!($index%2)){echo ">X</td>";}
				else{echo ">&nbsp;</td>";}
			}
 
 
			if($switch==1){$switch=0;}else{$switch=1;}
			$index++;
		}
 
		echo "</tr>";
 
	}
 
echo "</table>";
?>
</body>
</html>

Though not the most enlightening experience it was rather fun. I did not learn anything I did not know, but It is a great exercise to try and keep your html tags in order along with you php code. One loop alone can cause enormous confusion.

http://lab46.corning-cc.edu/~tmosgrov/webdev/checker.php

What would make this more interesting is attempting to make a functional checkers game. Maybe, add a user login to prevent multiple people from potential messing up the same game file. You move the page refreshes so on, and so forth. We'll see what happens. Time is the only enemy this semester.

In Class Notes

Arrays in PHP

$array_name = array("thing1", "thing2", "thing3");
//Old school php list initialization;
$test[5];
//This works too;
$test[0]="thing1";
//I'm sure this works too;

Loops in PHP

foreach ($things as $color)
//This is a neat one to increment through an array for each //recorded as $color
for($i; $i<5; i++)
//For loop just like c
while($i == "A")
//While
do{
}while($i=="foo");
//do while, don't forget the semicolon

FEB 03, 2016

Today we took a look at arrays in class, but more specifically the fact that an array in PHP is an ordered map. This construct has creates great flexibility when handling more complex arrays it seems.

PHP Manual - Arrays

Example #1 A simple array

<?php
$array = array(
    "foo" => "bar",
    "bar" => "foo",
);
 
// as of PHP 5.4
$array = [
    "foo" => "bar",
    "bar" => "foo",
];
?>

As you can see you can use both '[]' and '()' for handling arrays it appears they are interchangeable, but just in case you get suck into a time machine beware. Alos note the '⇒' key that two values that can be either string or integer. Couple assignment things to be aware of, when assigning most of the time strings containing valid integers gets casted to an integer. However, if the string number has a prefixed 0 as in “08” it will not be casted to an integer, but rather kept as a string. Floats will also be stored as integers where string “8.7” will be become “8”. For more see this.

  • If variables use the same key will override each other.
  • “PHP arrays can contain integer and string keys at the same time as PHP does not distinguish between indexed and associative arrays.”
  • The key is optional. If it is not specified, PHP will use the increment of the largest previously used integer key.

Anyways, what I find interesting about PHP's manual page is that they use a function called var_dump() which takes a variable of mixed expression who's name contents/values are dumped to the screen even showing key values when necessary.

Sample Code

<!DOCTYPE html>
<html>
<head><title>Array</title></head>
<body>
<?php
        $mythings = [
        "apples" => "$1.25",
        "pears" => "$3.14",
        "watermelons" => "$5.15"
        ];
 
var_dump($mythings);
?>
</body>
</html>

Sample Output

array(3) { 
["apples"]=> string(5) "$1.25" 
["pears"]=> string(5) "$3.14" 
["watermelons"]=> string(5) "$5.15" } 

Something that I'm beginning to like about PHP and that also has appealed to me in other languages is it's flexibility. I believe python is up there with those extremely user friendly scripting/programming languages, but I have yet to use it. I think one can find appreciation in this even more when working with a stricter language where the user is expected not to make mistakes, and is yelled at when they do by the compiler. Whereas “php” says “Eh, don't worry about it I know what you meant” On the other hand I appreciate stricter rules, because it compliments the part of my brain that want's to keep everything organized in a chaotic world with precise control.

FEB 08, 2016

Last Friday we went over functions, and how they are used. I was of course exploring, and listening at the same time… Functions in php are pretty straight forward as they are similar to most languages. What I was experimenting with while I was “listening” was how to use a functions with a variable number of arguments. Though I did not get it working I will try to demonstrate it here. To make up for my poor listening during class time. Please excuse me, I get excited about this stuff and get all these crazy ideas that I don't want to forget to try.

Average function with variable arguments

<!DOCTYPE html>
<html>
<head><title>functions</title></head>
<body>
<?php
	function average()
	{
		$sum=0;
		for($i=0; $i<func_num_args(); $i++)
		{
			$sum=$sum+func_get_arg($i);
		}
		$avg=$sum/func_num_args();
 
		return $avg;
	}
	echo (int)average(40, 50, 32, 80, 75, 50, 25);
?>
</body>
</html>

Let's just say I'm beginning to love php.

FEB 09, 2016

Yesterday, I started cranking out some php after having been inspired by Matt's use of HTTP GET with the GD library. It was then that I felt more comfortable possibly doing checkers, though there are still some unknowns answer. I'm playing it by year. What would have seem more like a HTML party last night I cranked out a pretty nice looking checkers board with php, but also entertained myself with the idea of reading and writing to a game file that would be named after a user's session ID using the session functions in php. The file would get read and the script would write pieces to the board accordingly. This is still highly theoretical, but what if each playing piece had a unique GET variable id in a form of a clickable link. Where once a piece is clicked the page refreshes with possible moves to make with that single piece if at all and so on and so forth. I'm not sure if I'm looking into the wrong direction with this, but it is a fun process to speculate on. I suppose I should look more into how to use fscanf and the $_GET variables.

My Checkers

More to come.

FEB 10, 2016

I've been spending a lot of time playing around with php… possibly to much time. I got around to installing apache2 and php5 locally on my laptop. I got around to configuring the error messages to print to the web client, but also working on getting those to link to a local copy of the documentation so I can go crazy with php. I've decided that I want a php t-shirt, haha.

MAR 22, 2016

I've been neglecting my web development opus, I know. However, I've been keeping my php arm strong. Today I smashed through our first project the Monte Carlo PI algorithm. Which implements an interesting probability element to calculating PI. As usual, I became consumed by “feature creep” and wanted too much at one time. In the beginning I was working on an auto refresh feature which proved to be more hazardous and annoying. After kicking that to the curb I settled for more realistic features, and It is working smoothly. Along the way I got to play with some interesting functions which I abused to my advantage. Predominately the shell_exec() function which allows you to execute shell commands within a php script.

APR 05, 2016

Yesterday, we were informed that we get to pick our next project. By that I mean we get to choose personally our own subject matter for said project. I'm not entirely sure what I will be exploring, but I have some Ideas. I've been looking back on my checkers board, and wanting to resurrect it. Maybe, I will do something OOP related with battle ship. I have no idea, games in PHP seem beyond the call of duty. I will be doing my research. So, I did some research and I think I will do something content management like starting with a secure login page. This process includes topics such ass encryption, storing passwords hashes, salt, and validating logins. This should be very interesting. Fortunately, php makes this very easy, and it seems their password_hash() function is relatively secure. You can even specify different algorithm options for encrypting passwords.

APR 13, 2016

I have been making way with my cms like web application. The distractions I have experienced has led me down a road of learning more CSS, and html as a pose to php. Which is nice, because regardless I'm piecing together a web app with a sleek design. I wanted to produce a user login with a password retrieval if needed. I figured since people need stuff to do when they login I have been contemplating, about finding a web chat that I could embed into my page. What really distracted me was creating dynamic content for the web. I found this website that would create a pixelated word bubble based on user input, and a submitted form. I wanted to automate this so bad for the character I had placed on my “homepage”. Finally, I got to play with wget and do so web automation. This is the kind of stuff I've been wanting to do, but previously had no idea where to start. It seems everything I have learned has lead me to this point. So, I constructed a script that would send form data to the site wigflip.com, and then that site would generate a word bubble in png format. I would then use grep to find the link provided for the generated content, and pull it down with wget. I entertained myself with the idea of doing it on a per user basis, but it was to much load on the page to launch this script. So, I rigged it up with a cronjob so the image would change every so often using fortune quotes.

The source

  1 #!/bin/bash                                                                                          
  2 
  3 ID="index"
  4 [[ -n "$1" ]] && ID="${1}"
  5 
  6 /usr/bin/wget --quiet --post-data="bubble-text=`/usr/games/fortune -s -n 20`&spike-direction=left&fil    e-type=png&background-color=%23FFFFFF&x=54&y=14" http://wigflip.com/ds/ -O "/home/tmosgrov/public_htm    l/webdev/cms/temp/${ID}.html"
  7 
  8 [[ "$ID" == "index" ]] && photo="wigflip"
  9 [[ "$ID" != "index" ]] && photo="$ID"
 10 /usr/bin/wget --quiet `grep -o 'http://l.wigflip.com/......../wigflip-ds.png' "/home/tmosgrov/public_    html/webdev/cms/temp/${ID}.html"|sed '1d'` -O /home/tmosgrov/public_html/webdev/cms/home_photos/${pho    to}.png
~                 

Systems Programming Journal

Jan 25, 2016

Parsing command line arguments with getopt

While attempting to construct cat in C things will become dicey when attempting to add command like arguments into the program. Many questions will arise, like how does a common program handle arguments prefixed with a dash ”-“, or what order does this all happen in. If my understanding is correct, this is where getopt comes into play. With the help of getopt all potential option/arguments will be parsed immediately (typically at the beginning of a program), and then stop when a target has been specified which the potential arguments will act on. Handing over all option handling to getopt takes away a lot of the what if scenarios, and lets one refocus on the program itself. If we wanted to make a program for parsing command line arguments that would be different story.

For increased understanding lets dissect the sample program provided in the man page.

Output with no arguments

lab46:~/src/sysprog$ ./getopt n
flags=0; tfnd=0; optind=1
name argument = n

This sample program is for displaying getopt in action. The program initiates some flag and index variables at the beginning, but the majority of this program is a while loop which relies on the output of getopt as a condition. On the inside of that while loop is a simple switch statement that sets flags according to the argument options given. The general output of this program are the flags set, number of options given, and the target argument/option provided. The program will yell accordingly if an invalid argument name is given, the argument is not used properly, or if a target is unspecified.

The source

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
 
int
main(int argc, char *argv[])
{
   int flags, opt;
   int nsecs, tfnd;
 
   nsecs = 0;
   tfnd = 0;
   flags = 0;
   while ((opt = getopt(argc, argv, "nt:")) != -1) {
           switch (opt) {
           case 'n':
                   flags = 1;
                   break;
           case 't':
                   nsecs = atoi(optarg);
                   tfnd = 1;
                   break;
           default: /* '?' */
                   fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
                                   argv[0]);
                   exit(EXIT_FAILURE);
           }
   }
 
   printf("flags=%d; tfnd=%d; optind=%d\n", flags, tfnd, optind);
 
   if (optind >= argc) {
           fprintf(stderr, "Expected argument after options\n");
           exit(EXIT_FAILURE);
   }
 
   printf("name argument = %s\n", argv[optind]);
 
   /* Other code omitted */
 
   exit(EXIT_SUCCESS);
}

Jan 27, 2016

Fixed some bugs in my getopt code that was giving me trouble. My switch statement for a single test argument was not working. What I found was that there seemed to be a syntax error with the main loop I was using whos condition relies on the output of getopt.

Before the fix

while( opt=getopt(argc, argv, "n") != -1){\\code}

The problem with this is not entirely clear at this moment, but I willing to bet the equal sign in that state is not setting a variable, but rather doing an evaluation between opt and the getopt function.

After the fix

while( (opt=getopt(argc, argv, "n")) != -1){\\code}

The solution was to encase the assignment with an extra set of parenthesis which would prevent the assumed conditional evaluation.

Some additional getopt variables to take note of

  • optind - an index variable that points to the current option.
  • optarg - a string variable that points to the target argument.
  • opterr - a variable flag that turns on off getopt error msg.
  • optopt - the string of a invalid option that causes ? error.

Jan 28, 2016

Today in class we explored the manual page for wtmp (who-temp or user-temp) this is where and how the system logs user login information. Manual page (5) are the specifications for file formats and standard conventions. In this case the wtmp specifications. This eventually lead us to the function getutent() and the struct utmp. Getutent and it's family members (getutid, getutline, pututline, setutent, endutent, utmpname) access utmp file entries. In getutent's case it will return a struct (utmp) based off of the current file pointer. After getutent is called successfully the file pointer increments to the next entry and the struct utmp is populated. If getutent fails or runs out of records to retrieve it returns NULL.

The code from class

#include <stdio.h>
#include <stdlib.h>
#include <utmp.h>
#include <time.h>
 
int main()
{
        struct utmp *entry;
        struct tm *mytime;
        char c;
        time_t *t = (time_t *) malloc(sizeof(time_t));;
        entry = getutent();
 
        while (entry != NULL)
        {
                fprintf(stdout, "ut_type: %hd\n", entry->ut_type);
                fprintf(stdout, "ut_pid: %d\n", entry->ut_pid);
                fprintf(stdout, "ut_line: %s\n", entry->ut_line);
                fprintf(stdout, "ut_user: %s\n", entry->ut_user);
                fprintf(stdout, "ut_host: %s\n", entry->ut_host);
                //fprintf(stdout, "time?: %d\n", entry->ut_tv.tv_sec);
 
                        *t = entry -> ut_tv.tv_sec;
                        mytime=localtime(t);
 
                        fprintf(stdout, "\nPress ENTER to continue. \n");
                        c = fgetc(stdin);
 
                        entry = getutent();
        }
 
        return 0;
}

The output

ut_type: 7
ut_pid: 15421
ut_line: pts/1
ut_user: mp010784
ut_host: 162.243.201.127 via mosh [15421]
 
Press ENTER to continue.

The output is for the most part is a given. The ut_type indicates the type of record entered as an integer if 0 the record is invalid, 1 denotes a change in system run level, 2 time of system boot, 3 time after system clock change, 4 time before system clock change, 5 process spawned by, 6 session leader process for login, 8 a terminated process, and 9 which is not implemented. The ut_pid is the process id *integer) that the process is running under. The ut_line is a string that gives the (pts) pseudo terminal the user is logged in on. The ut_user is a string that holds the username. Finally, the ut_host is a string of the remote network address of the user.

We did get to experiment with the ut_tv contained in the utmp struct that contains the time the user logged in, but we ran out of time. During which lots of exploration was done in the man pages regarding functions, and types contained in time.h which would be used to decode the ut_tv value in a more human readable format.

Back to the new_cat

I have been working feverishly on mimicking the utility cat's behaviors. One of the first observations that I made was that for the -n option a target argument (file) is completely optional. Complimenting my OCD like behaviors I wanted to find a way to rig that up with getopt. This lead me down a read of hitting my head on brick wall after brick wall until I sprawled upon a stackoverflow page which had all my answers… Or so I thought.

Consider the code

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
 
int main(int argc, char **argv)
{
 
        FILE *fp;
        int  num_flg=0, outstd_flg=0;
        const char *target=NULL;
        char opt;
        unsigned char c;
 
        while( (opt=getopt(argc, argv, ":n:")) != -1)
        {
                switch (opt){
 
                        case 'n':
 
                                num_flg=1;
 
                                break;
 
                        case ':':
 
                                        switch (optopt){
 
                                                case 'n':
 
                                                        outstd_flg=1;
                                                        target="stdin";
 
                                                break;
 
                                        }
 
                                break;
 
                        case '?':
 
                                printf("Try 'cat --help' for more information.\n");
 
                                break;
 
                }
                if(target == NULL)
                {
                        target=optarg;
                }
                printf("target=%s\n",target);
 
        }
 
 
 
        return 0;
}

What to do when given an empty target argument

while( (opt=getopt(argc, argv, ":n:")) != -1)

The while loop condition which powers the entirety of argument parsing looks like this. To enable the optional target argument for a given argument contained in the option string I had to prefix it with a ':'. This would cause opt to return ':' when a target argument was not provided with a given argument. For instance when cat is called with the -n argument and not target file/argument it defaults to “cating” stdin and outputing to stdout with line numbers. This was the feature I really wanted to tackle. I know it's splitting hairs, but it has caused me to learn precisely how getopt works. However, as much as I think I've figured out I still do not understand if the overall procedures of the utility itself should operate inside of getopt's while loop, or on the outside. There are two sides to this in my mind.

A.) If the utility's procedures occurs outside the loop one would have to supply an extra loop to re initiate getop's argument parsing for additional parameters for sequential runs. [Like cat -n foo -n bar]. One may also have to modify optind to point to the next argument assuming the getopt's loop always stops when a non-argument is given.

B.)If the procedures occur inside theoretically all arguments could be parsed and acted upon in one go, but this could get confusing with multiple arguments given on one target file. Also, if the utility is called with no arguments like when cat defaults to catting “stdin” getopt's loop returns -1 and never executes. Thus, dropping the program on the ground.

                switch (opt){
 
                        case 'n':
 
                                num_flg=1;
 
                                break;
 
                        case ':':
 
                                        switch (optopt){
 
                                                case 'n':
 
                                                        outstd_flg=1;
                                                        target="stdin";
 
                                                break;
 
                                        }
 
                                break;
 
                        case '?':
 
                                printf("Try 'cat --help' for more information.\n");
 
                                break;
 
                }

When this happens getopt returns a ':' and the switch statement catches it followed by another switch block who's conditions relies on the variable optopt that records the argument that received no target argument. This is where we can split hairs and say if there was no target argument our file pointer may point to stdin depending on the argument/s that did not recieve a target argument.

Feb 02, 2016

Today we revised our rendition of the who utility in class, and got to take a look at how the system accesses and handles file modes/permissions. This brought our attention the chmod man page which eventually brought us to the stat function. This function returns information about a file taking a file name, and populating a stat struct which contains an abundance of information on a file.

The Contents of The Stat Struct

struct stat{
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* inode number */
               mode_t    st_mode;        /* protection */
               nlink_t   st_nlink;       /* number of hard links */
               uid_t     st_uid;         /* user ID of owner */
               gid_t     st_gid;         /* group ID of owner */
               dev_t     st_rdev;        /* device ID (if special file) */
               off_t     st_size;        /* total size, in bytes */
               blksize_t st_blksize;     /* blocksize for filesystem I/O */
               blkcnt_t  st_blocks;      /* number of 512B blocks allocated */

More specifically our interest was focused on the mode_t st_mode within the stat struct. Coincidentally this value is an octal number that of the file permissions set on the file.

The octal values

           S_ISUID   0004000   set-user-ID bit
           S_ISGID   0002000   set-group-ID bit (see below)
           S_ISVTX   0001000   sticky bit (see below)
 
           S_IRWXU     00700   mask for file owner permissions
           S_IRUSR     00400   owner has read permission
           S_IWUSR     00200   owner has write permission
           S_IXUSR     00100   owner has execute permission
 
           S_IRWXG     00070   mask for group permissions
           S_IRGRP     00040   group has read permission
           S_IWGRP     00020   group has write permission
           S_IXGRP     00010   group has execute permission
 
           S_IRWXO     00007   mask  for  permissions for others
                               (not in group)
           S_IROTH     00004   others have read permission
           S_IWOTH     00002   others have write permission
           S_IXOTH     00001   others have execute permission

In our particular situation we wanted to know if the write bit was set on a user's terminal. The S_IWGRP defines an octal mask regarding the group write bit of a file “00020”. Thus we & the current file permissions set on a file with the S_IWGRP mask and voila if the condition is true the write bit is set else it is not.

The next round of systems programming will be a documented approach to recreating chmod using the same libraries/system calls, a chmod function, and the dreaded getopt function used for parsing command line arguments. Stay tuned for more coverage.

Feb 04, 2016

Today we dived right into the man pages while attempting our version of ls which came out quite nicely minus my compilation errors but I got the jist of it. We took a look at a new set of functions called the dirp family. This is the first time I have interacted with file directories so I was pretty excited about this. The first function we looked at was opendir() which takes a path name for a parameter and returns a pointer to a directory stream or in our case it returns a dirp.

opendir

DIR *dirp;
dirp=opendir("pathname");

Next after opening the directory we used the readdir() function to capture minimal directory information like it's inode, file type, and name. Readdir() take a dirp (DIR *) and returns a dirent struct which encapsulates additional information on the directory.

readdir

struct dirent *aderp;
 
aderp=readdir(dirp);
 
printf("name: %s", adirp->d_name);

Eventually we wanted more information so this lead us to the function scandir() which lo and behold was covered in double pointers, and heck even a triple pointer. Scandir() does as it sounds it scans a directory taking a directory path pointer, a triple pointer to a dirent structure (because we are essentially getting a dirent struct back for every directory entry) , a pointer to a filter function which also takes a dirent pointer, and a compare function that takes two dirent double pointers. Finally, after being supplied with the correct arguments readir() returns the number of directory entries within the directory pointer. This is very confusing so let's take a look.

scandir

n = scandir(argv[1], &aderp, NULL, alphasort);
//Now we have n number of dirent structs to review

After we got what we wanted we jumped back to the stat function, and began to parse and print the contents of the dirent structs data returned from scandir including a printing of the file permission set on said files. This was very long process and left me at a compilation error, but it was good fun.

Feb 09, 2016

Today we reverted back into reproducing ls. I Solved all my compilation errors before class ended, so that was reassuring. I was getting undefined errors because I was using c99 syntax as I do often eg. for(int i=0; i<var; i++) which was throwing me through a loop, because some of the symbolic constants supplied in the libraries we were using did not support c99 for whatever reason. Sadly I also had this and my eyes kept scanning over it while(int i=0; i<var; i++), no bueno. Finally after resolving all that I had a few more typos, and a segfault to look into. Eventually the pieces came together. Though being distracted I was able to catch up. We went right into printing out additional information as the real ls would.

Sample output from myls

lab46:~/src/sysprog$ ./myls .
drwxr-xr-x tmosgrov    lab46 name: ., inode: 0x96e03ee, type: 4
drwxr-xr-x tmosgrov    lab46 name: .., inode: 0x7f00c95, type: 4
-rwXr--r-- tmosgrov    lab46 name: .mychmod.c.swo, inode: 0x96e080e, type: 8
-rwXr--r-- tmosgrov    lab46 name: .nfs00000000096e04bf0000002d, inode: 0x96e04b                                                       f, type: 8
-rwxr-xr-x tmosgrov    lab46 name: cat, inode: 0x96e03e6, type: 8
-rwXr--r-- tmosgrov    lab46 name: cat.c, inode: 0x96e03fe, type: 8
-rwxr-xr-x tmosgrov    lab46 name: cat2, inode: 0x96e03b8, type: 8
-rwXr--r-- tmosgrov    lab46 name: cat2.c, inode: 0x96e03bb, type: 8
-rwxr-xr-x tmosgrov    lab46 name: cat3, inode: 0x96e03be, type: 8
-rwXr--r-- tmosgrov    lab46 name: cat3.c, inode: 0x96e0478, type: 8
-rwXr--r-- tmosgrov    lab46 name: cat4.c, inode: 0x96e050c, type: 8
-rwxr-xr-x tmosgrov    lab46 name: cust, inode: 0x96e03fa, type: 8
-rwXr--r-- tmosgrov    lab46 name: cust.h, inode: 0x96e04c4, type: 8
-rwxr-xr-x tmosgrov    lab46 name: getopt, inode: 0x96e05ba, type: 8
-rwXr--r-- tmosgrov    lab46 name: getopt.c, inode: 0x96e0552, type: 8
-rwXr--r-- tmosgrov    lab46 name: mycat.c, inode: 0x96e03d2, type: 8
-rwxr-xr-x tmosgrov    lab46 name: mychmod, inode: 0x96e075b, type: 8
-rwxr--r-- tmosgrov    lab46 name: mychmod.c, inode: 0x96e080b, type: 8
-rwxr-xr-x tmosgrov    lab46 name: myls, inode: 0x96e03cd, type: 8
-rwXr--r-- tmosgrov    lab46 name: myls.c, inode: 0x96e0814, type: 8
-rwxr-xr-x tmosgrov    lab46 name: new_cat, inode: 0x96e03b7, type: 8
-rwXr--r-- tmosgrov    lab46 name: new_cat.c, inode: 0x96e080d, type: 8
-rwXr--r-- tmosgrov    lab46 name: ut_tv.tv_sec, inode: 0x96e03a9, type: 8
-rwxr-xr-x tmosgrov    lab46 name: who, inode: 0x96e03a8, type: 8
-rwXr--r-- tmosgrov    lab46 name: who.c, inode: 0x96e0519, type: 8
-rwXr--r-- tmosgrov    lab46 name: who2.c, inode: 0x96e0571, type: 8

What was interesting was that we looked into two new libraries to derive the group, and username of the items being listed by ls pwd.h, and grp.h. Inside those libraries we looked at two new structs passwd, and group which in turn lead us to the functions getpwuid, and getgrgid. Obtaining the data from these functions was much like using the stat function which supplied file information. Eventually we got stuck at a segfault, because of scandir and opendir having two different perspectives as far as file paths go. So, eventually after opening the directory we would change into the directory with the function chdir then scandir would scan the current working directory. Whereas prior to that scandir was trying to scan for specific file information without being in that working directory which caused an off by one error in our loop I presume. A little confusing, but I think I got the gist.

Feb 25, 2016

Hello system programming my old friend. Today we wen't over the basic concepts of concurrency which if I might add is quite cool. Matt showed us some basic source of how to fork processes. This became even more interesting when one sees the master & slave the logic in action where your source will reflect tasks that the master or parent may perform (if the process ID is that of the parent do this), and the tasks that a child process may perform.(if the process ID is no that of the parent do this). This happens a lot with the things I learn or want to play with. Someone presents to me a super powerful tool but the tool is far to powerful, and someone at my level has no need to make optimizations like this. However, this will be fun to experiment with and attempt on our prime number implementations.

Function notes: fork(), wait(), and getpid();

Feb 29, 2016

A quick update. I have cranked out the primebrute.c, and primesquare.c. I'm now entering the research stage of a custom optimization. I've yet to do the research so stay tuned!

Mar 01, 2016

So, I thought I cranked out the primebrute.c, and the primesquare.c only to find out I was having not only a logical issue, but I was also including 1 as a prime which is is neither. Eventually I got those working properly and went back to work on my Sieve of Eratosthenes. Which was not too complicated, but it was very easy to get caught in a logical error. It had made me happy to know I was doing something that was proven to be efficient after Mattt gave me the low down so I got right to work.

The Sieve of Eratosthenes works like this. Lets say be have a range of numbers to check for primality up to 30. Like so.

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

The way this sieve works is that we start at the lowest number(first primes) and we cross out their multiples. Starting with multiples of two Like so.

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Now we will increment our position to the next number that is not crossed out. In this case it is 3! Now we jump by multiples of three crossing out all that follows. Like so.

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Once again we increment our position by one, but this time we have to skip four because it has been crossed out and thus it is composite. All multiples of two (even numbers) have already been evaluated as such. Our position now resides at 5, as we did before we cross out the following multiples of 5.

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Stop, going any further would be a waist of time. Using our square root rule we know that we only have to check up to the square root of the given range of numbers in question. In this case we finished our evaluation at 5 because 5*5 < 30 and is not out of range. Whereas 6*6 > 30 and assuming our implementation worked as expected we have all the information we need on the numbers in question. The numbers you are left with that have not been crossed out are prime.

2 3 5 7 11 13 17 19 23 29

There you have it, the Sieve of Eratosthenes.

Mar 09, 2016

Seems like a lot of time has passed since my last sysprog entry. I have been knee deep in forking child processes, and exploring the world of interprocess communications like multiplexing. I successfully finished pnc1 and for the first time I got to use pipes! Surprisingly very simple to use. When I tried to take things a step further with using select, poll, epoll in question I decided it was too complex for the task in hand. However, we are now approaching an area of programming I have been much curious about for a long time. Which is network programming. I yearn for the day at which I know how to create a simple client server program.

Mar 15, 2016

Today, we went over sockets. Actually, I'm pretty excited about exploring this myself because I love the connectivity side of things. This is something I would really like to get down for many reasons. We setup a server in C and tested it's connectivity using netcat (nc) and telnet. This blew my mind because it again opened up a whole new world for me. Matt has a tendency to do this to me. Just when I was getting comfortable with the stuff I was learning or currently know. I get hit with more toys to play with. I think my opus is due for a demo on sockets.

Mar 22, 2016

Socket programming is on my list of to dos…

Mar 24, 2016

Today we wen't over ioctl functions and commands which manipulates devices through special files. Doing so, we were able to manipulate the terminal with ease turning echo on and off, and returning the size of the window. We were also able to view how certain ioctl values change when, changes are made to the terminal. With this it is clearer as to how a device driver must communicate these value to the kernel.

APR 05, 2016

Pipes! We went over pipes today. I have played with pipes before in my prime finding project, but it was good review. Matt has a funny way of making me feel like I have no idea what I'm doing. Previously, I was trying to do absurd things with pipes, but Matt made it very clear that pipes are unidirectional meaning the parties involved with the interprocess communication must designate who is writing/reading not both. Otherwise, it would make sense to have two pipes so both parties can read and write. With this Matt has also made it clear that the unused ends of the pipe should be closed to prevent further confusions.

APR 07, 2016

Signals! We went over signals today. This was exceptionally cool because I began to contemplate more possibilities with inter process communication. Like what if a parent or child process could send a signal based on the writing/reading to a pipe so that each are more aware of when to act upon incoming/nonincoming information. However, this could be something that just sounds good on paper, but is not practical for the use of signals.

APR 13, 2016

Shared memory! We went over shared memory yesterday. This means of inter process communication seems to be very powerful. Seems this is like pipes, but on steroids and with more scalability. In class we attempted to make a ghetto chat client, but I got a little lost in the process. I would like to read up more on shared memory in the future.

blog/spring2016/tmosgrov/start.txt · Last modified: 2016/01/18 16:05 by 127.0.0.1