John T. Rine's Fall 2011 Opus (in d minor)
My last semester at Corning Community College :(
<html><center><marquee width=400 loop=“infinite”><font color=red size=5><b>Today, March 31, 2012, my grandson Gabriel Alexander Barlow was born!</b></font></marquee></center></html>
My other pages are:
My name is John Rine. I have four children: Erica, David, Gretchen, and Nathan. I also have <html><strike style='color:red'>three</strike> four </html> grandchildren: Victor jr., Lilianna, Daniela, and <html> Gabriel</html>!
On August 6, 2009, the anniversary of the dropping of the A bomb on Hiroshima, I was separated from the company where I worked for 12 years. Since I was unemployed, I found that I qualified for educational benefits and enrolled for the Fall semester 2009 at Corning Community College. In December 2010, I graduated with an A.A.S. in Electrical Technology-Electronics and a A.S. in LAS General Studies program each with a 3.85 accumulated GPA. At the same time I have been enrolled in the IT-HPC and Computer Science programs. Since graduating from the Electrical Technology program, however, I have been seeking employment as being unemployed has taken a heavy toll on my family's financial situation. On July 15, 2011, I was hired as a Process Technician at Corning, Incorporated's Sullivan Park Research and Development facility. This semester will be interesting. I will be employed full time and attempt a full course load. I can, however, see the light at the end of the tunnel as this is my last semester. If I am successful, I will graduate with an A.A.S. in IT-HPC and a A.S. in Computer Science.
Data Structures Topics
http://lab46.corning-cc.edu/haas/fall2011/data
The following is a list of the major topics being covered in this course:
System Programming Topics
http://lab46.corning-cc.edu/haas/fall2011/sysprog
The following is a list of the major topics being covered in this course:
HPC I Experience Topics
http://lab46.corning-cc.edu/haas/fall2011/hpc1
The following is a list of the major topics being covered in this course:
Remember that 4 is just the minimum number of entries. Feel free to have more.
I set up my repository using the instructions at:
http://lab46.corning-cc.edu/haas/spring2011/cprog/tasks/task0 .
lab46:~$ mv src src1.bak lab46:~$ mkdir src lab46:~$ mkdir -p src/data lab46:~$ mkdir -p src/sysprog lab46:~$ svn import src http://lab46.corning-cc.edu/svn/jr018429/src -m "Initial import" Authentication realm: <http://lab46.corning-cc.edu:80> Lab46 User Subversion Repository Password for 'jr018429': Adding src/sysprog Adding src/data ----------------------------------------------------------------------- ATTENTION! Your password for authentication realm: <http://lab46.corning-cc.edu:80> Lab46 User Subversion Repository can only be stored to disk unencrypted! You are advised to configure your system so that Subversion can store passwords encrypted, if possible. See the documentation for details. You can avoid future appearances of this warning by setting the value of the 'store-plaintext-passwords' option to either 'yes' or 'no' in '/home/jr018429/.subversion/servers'. ----------------------------------------------------------------------- Store password unencrypted (yes/no)? y Please type 'yes' or 'no': yes Committed revision 1. lab46:~$ mv src src2.bak lab46:~$ svn co http://lab46.corning-cc.edu/svn/jr018429/src src A src/sysprog A src/data Checked out revision 1. lab46:~$
I joined the data class mailing list by navigating to the web page at:
http://lab46.corning-cc.edu/mailman/listinfo/data , and following the directions on the page.
Soon thereafter, I received a confirmation e-mail requiring that either I navigate to a URL or send a reply.
I sent a reply.
Date: Sun, 04 Sep 2011 16:35:40 -0400 From: data-request@lab46.corning-cc.edu To: jr018429@lab46.corning-cc.edu Subject: confirm cb14554e157fd7a8eeb720a791b0d77f96f43081 Mailing list subscription confirmation notice for mailing list DATA We have received a request from 10.80.2.18 for subscription of your email address, "jr018429@lab46.corning-cc.edu", to the data@lab46.corning-cc.edu mailing list. To confirm that you want to be added to this mailing list, simply reply to this message, keeping the Subject: header intact. Or visit this web page: http://lab46.corning-cc.edu/mailman/confirm/data/cb14554e157fd7a8eeb720a791b0d77f96f43081 Or include the following line -- and only the following line -- in a message to data-request@lab46.corning-cc.edu: confirm cb14554e157fd7a8eeb720a791b0d77f96f43081 Note that simply sending a `reply' to this message should work from most mail readers, since that usually leaves the Subject: line in the right form (additional "Re:" text in the Subject: is okay). If you do not wish to be subscribed to this list, please simply disregard this message. If you think you are being maliciously subscribed to the list, or have any other questions, send them to data-owner@lab46.corning-cc.edu. Include original message in Reply? y
I then received an e-mail message welcoming me to the data structures course e-mail list.
Date: Sun, 04 Sep 2011 16:39:07 -0400 From: data-request@lab46.corning-cc.edu To: jr018429@lab46.corning-cc.edu Subject: Welcome to the "DATA" mailing list Welcome to the DATA@lab46.corning-cc.edu mailing list! To post to this list, send your email to: data@lab46.corning-cc.edu General information about the mailing list is at: http://lab46.corning-cc.edu/mailman/listinfo/data If you ever want to unsubscribe or change your options (eg, switch to or from digest mode, change your password, etc.), visit your subscription page at: http://lab46.corning-cc.edu/mailman/options/data/jr018429%40lab46.corning-cc.edu You can also make such adjustments via email by sending a message to: DATA-request@lab46.corning-cc.edu with the word `help' in the subject or body (don't include the quotes), and you will get back a message with instructions. You must know your password to change your options (including changing the password, itself) or to unsubscribe. It is: XXXXXXXXXXXX Normally, Mailman will remind you of your lab46.corning-cc.edu mailing list passwords once every month, although you can disable this if you prefer. This reminder will also include instructions on how to unsubscribe or change your account options. There is also a button on your options page that will email your current password to you.
I also joined the data class mailing list by navigating to the web page at:
http://lab46.corning-cc.edu/mailman/listinfo/sys , and following the directions on the page.
Afterwards, I received a confirmation e-mail requiring that either I navigate to a URL or send a reply.
I sent a reply.
Date: Sun, 04 Sep 2011 16:37:08 -0400 From: sys-request@lab46.corning-cc.edu To: jr018429@lab46.corning-cc.edu Subject: confirm 54d6ee7883bcf277a46b04538af54893b4ed2421 Mailing list subscription confirmation notice for mailing list SYS We have received a request from 10.80.2.18 for subscription of your email address, "jr018429@lab46.corning-cc.edu", to the sys@lab46.corning-cc.edu mailing list. To confirm that you want to be added to this mailing list, simply reply to this message, keeping the Subject: header intact. Or visit this web page: http://lab46.corning-cc.edu/mailman/confirm/sys/54d6ee7883bcf277a46b04538af54893b4ed2421 Or include the following line -- and only the following line -- in a message to sys-request@lab46.corning-cc.edu: confirm 54d6ee7883bcf277a46b04538af54893b4ed2421 Note that simply sending a `reply' to this message should work from most mail readers, since that usually leaves the Subject: line in the right form (additional "Re:" text in the Subject: is okay). If you do not wish to be subscribed to this list, please simply disregard this message. If you think you are being maliciously subscribed to the list, or have any other questions, send them to sys-owner@lab46.corning-cc.edu. Include original message in Reply? y
I soon received an e-mail message welcoming me to the system programming course e-mail list.
Date: Sun, 04 Sep 2011 16:41:07 -0400 From: sys-request@lab46.corning-cc.edu To: jr018429@lab46.corning-cc.edu Subject: Welcome to the "SYS" mailing list Welcome to the SYS@lab46.corning-cc.edu mailing list! To post to this list, send your email to: sys@lab46.corning-cc.edu General information about the mailing list is at: http://lab46.corning-cc.edu/mailman/listinfo/sys If you ever want to unsubscribe or change your options (eg, switch to or from digest mode, change your password, etc.), visit your subscription page at: http://lab46.corning-cc.edu/mailman/options/sys/jr018429%40lab46.corning-cc.edu You can also make such adjustments via email by sending a message to: SYS-request@lab46.corning-cc.edu with the word `help' in the subject or body (don't include the quotes), and you will get back a message with instructions. You must know your password to change your options (including changing the password, itself) or to unsubscribe. It is: XXXXXXXXXXXX Normally, Mailman will remind you of your lab46.corning-cc.edu mailing list passwords once every month, although you can disable this if you prefer. This reminder will also include instructions on how to unsubscribe or change your account options. There is also a button on your options page that will email your current password to you.
Next, I joined the Data Structures course IRC channel.
lab46:~$ screen -r
Irssi v0.8.15 - http://www.irssi.org 19:15 -!- I have 11 users, 0 services and 1 servers 19:15 -!- 11 11 Current local users: 11, Max: 11 19:15 -!- 11 11 Current global users: 11, Max: 11 19:15 -!- - irc.offbyone.lan message of the day 19:15 -!- - ************************************************** 19:15 -!- - * irc.offbyone.lan - LAIR IRC server * 19:15 -!- - * * 19:15 -!- - * If you know your class channel(s), you may * 19:15 -!- - * "/join CHANNEL_NAME" them now. * 19:15 -!- - * * 19:15 -!- - * For help, /join lab46 * 19:15 -!- - * * 19:15 -!- - * Regular rules apply: Play nice or go home. * 19:15 -!- - ************************************************** 19:15 -!- End of MOTD command 19:15 -!- Mode change [+i] for user jr018429 19:24 Irssi commands: 19:24 accept die knock note rping unban 19:24 action disconnect knockout notice save unignore 19:24 admin echo lastlog notify sconnect unload 19:24 alias eval layout op script unnotify 19:24 away exec links oper scrollback unquery 19:24 ban flushbuffer list part server unsilence 19:24 beep foreach load ping servlist upgrade 19:24 bind format log query set uping 19:24 cat hash lusers quit sethost uptime 19:24 cd help map quote silence userhost 19:24 channel hilight me rawlog squery ver 19:24 clear ignore mircdcc recode squit version 19:24 completion info mode reconnect stats voice 19:24 connect invite motd redraw statusbar wait 19:24 ctcp ircnet msg rehash time wall 19:24 cycle ison names reload toggle wallops 19:24 dcc join nctcp resize topic who 19:24 dehilight kick netsplit restart trace whois 19:24 deop kickban network rmreconns ts whowas 19:24 devoice kill nick rmrejoins unalias window Day changed to 01 Sep 2011 Day changed to 02 Sep 2011 Day changed to 03 Sep 2011 Day changed to 04 Sep 2011 [17:37] [jr018429(+i)] [1:irc (change with ^X)] [(status)] /join #data
17:23 -!- jr018429 [~jr018429@lab46.corning-cc.edu] has joined #data 17:23 [Users #data] 17:23 [@dschoeff] [ jr018429] 17:23 -!- Irssi: #data: Total of 2 nicks [1 ops, 0 halfops, 0 voices, 1 normal] 17:23 -!- Irssi: Join to #data was synced in 1 secs [17:37] [jr018429(+i)] [5:irc/#data] [#data]
I also joined the System Programming course IRC channel.
17:23 -!- jr018429 [~jr018429@lab46.corning-cc.edu] has joined #data 17:23 [Users #data] 17:23 [@dschoeff] [ jr018429] 17:23 -!- Irssi: #data: Total of 2 nicks [1 ops, 0 halfops, 0 voices, 1 normal] 17:23 -!- Irssi: Join to #data was synced in 1 secs [17:38] [jr018429(+i)] [5:irc/#data] [#data] /join #sys
17:22 -!- jr018429 [~jr018429@lab46.corning-cc.edu] has joined #sys 17:22 [Users #sys] 17:22 [@dschoeff] [ jr018429] 17:22 -!- Irssi: #sys: Total of 2 nicks [1 ops, 0 halfops, 0 voices, 1 normal] 17:22 -!- Irssi: Join to #sys was synced in 1 secs 17:22 < jr018429> hello all! [17:39] [jr018429(+i)] [4:irc/#sys] [#sys]
I added my first linked list source file to the Subversion repositiory:
lab46:~/src/data$ svn add linkedList1-jr.c A linkedList1-jr.c
Next, I commited the file to the Subversion repository:
lab46:~/src/data$ svn commit -m "Committing first linked list source file-to be used in further development-JR" Adding data/linkedList1-jr.c Transmitting file data . Committed revision 2.
I experimented with void pointers; the resulting file is voidptr.c. I added it to the code repository and then committed it.
lab46:~/src/data$ svn add voidptr.c A voidptr.c lab46:~/src/data$ svn commit -m "Added voidptr.c; voidptr.c is a c source file used to experiemtn with a void pointer" Adding data/voidptr.c Transmitting file data . Committed revision 3. lab46:~/src/data$
I added and committed the beginning cpu interface code.
lab46:~/src/sysprog$ svn add interface.c A interface.c lab46:~/src/sysprog$ svn commit -m "Added and committed the start of cpu interface -JR" Adding sysprog/interface.c Transmitting file data . Committed revision 4.
I posed a question regarding memory allocation and deallocation to the data mailing list at: data@lab46.corning-cc.edu .
I asked the following questions:
Date: Sun, 18 Sep 2011 20:52:56 -0400 (EDT) From: John Rine <jr018429@lab46.corning-cc.edu> To: data@lab46.corning-cc.edu Subject: Deallocating dynamically allocated memory All, Regarding deallocating memory when finished with a linked list, isn't it a good idea to first copy the pointer to the next address into a temporary pointer variable and then set all pointers within a node to NULL and finally deallocate the memory rather than deallocating the memory and then setting pointers to NULL? Is deallocated memory available to the system immediately after being deallocated? The code I have seen, frees and then sets pointers to NULL. Example: while(temp != NULL) { temp2 = temp->next; temp->prev = NULL; temp->next = NULL; free(temp); temp = temp2; } John T. Rine CSIT 1320 HPC Fundamentals CSIT 2048 HPC Experience II CSIT 2320 HPC Systems & Networking CSCS 2650 Computer Organization Graduate Electrical Technology-Electronics Graduate General Studies --- Lab46: Penguin Powered
I received the following reply to my question from the course instructor.
Date: Mon, 19 Sep 2011 08:31:00 -0400 From: Matthew Haas <wedge@lab46.corning-cc.edu> Reply-To: CSCS2320 Class Discussion List <data@lab46.corning-cc.edu> To: data@lab46.corning-cc.edu Subject: Re: [DATA] Deallocating dynamically allocated memory On 09/18/2011 08:52 PM, John Rine wrote: > Is deallocated memory available to the system immediately after being deallocated? Excellent question, that would make a great experiment... What do you think is the case? Why? How would you test this? For starters, what if you printed out the address a pointer points to before and after freeing? Does it remain the same? If you free memory and it returns it for system use, would that not mean the memory is no longer allocated to you, and therefore you would no longer have access to that memory? What happens when you try to access memory outside your process space? That would be a great experiment to try, whether or not it is successful. -Matthew -- Matthew Haas Lab46 System Administrator Instructor of Computer& Information Science http://lab46.corning-cc.edu/haas/home/ _______________________________________________ DATA mailing list DATA@lab46.corning-cc.edu http://lab46.corning-cc.edu/mailman/listinfo/data [ Note: This message contains email list management information ]
I posed the following questions regarding curses and keyboard keys to the system programming class e-mailing list at: sys@lab46.corning-cc.edu .
Date: Sun, 18 Sep 2011 21:25:29 -0400 (EDT) From: John Rine <jr018429@lab46.corning-cc.edu> To: sys@lab46.corning-cc.edu Subject: Trouble with Curses recognizing F keys and other keyboard keys All, I am having trouble with curses recognizing function keys and the escape key. I am using code like this: #include<curses.h> int main() { int c; initscr(); keypad(stdscr,TRUE); noecho(); move(0,0); c=getch(); while(c != KEY_F(1) && c != 'q') { move(0,0); printw("%c\n",c); refresh(); c=getch(); } endwin(); return 0; } it will exit with 'q' but not KEY_F(1) or the F1 key. Also, the esc key is not recognized when using the KEY_EXIT constant. Anyone have any ideas as to how to get function keys and the escape key to work with curses? thanks, John T. Rine --- Lab46: Penguin Powered
The instructor provided the following reply to my curses/keyboard keys questions.
Date: Mon, 19 Sep 2011 08:43:07 -0400 From: Matthew Haas <wedge@lab46.corning-cc.edu> Reply-To: "\\\"Systems\\\" Classes Discussion List" <sys@lab46.corning-cc.edu> To: sys@lab46.corning-cc.edu Subject: Re: [SYS] Trouble with Curses recognizing F keys and other keyboard keys On 09/18/2011 09:25 PM, John Rine wrote: > > I am having trouble with curses recognizing function keys and the escape key. > I am using code like this: > #include<curses.h> > > int main() > { > int c; > initscr(); > keypad(stdscr,TRUE); > noecho(); > move(0,0); > c=getch(); > while(c != KEY_F(1) && c != 'q') > { > move(0,0); > printw("%c\n",c); > refresh(); > c=getch(); > } > endwin(); > return 0; > } > it will exit with 'q' but not KEY_F(1) or the F1 key. Also, the esc key is not recognized when using the KEY_EXIT constant. Anyone have any ideas as to how to get > function keys and the escape key to work with curses? I've never played with the function keys... so that would take some experimenting. Escape, even though there may not be a #define for it (all the keys available to you are #define'd in /usr/include/curses.h, check it out), has a value. The trick is, what is it? Hmm... this could be another experiment. If you know that pretty much every key on the keyboard has a value (which ones do not have a direct value?), how could we figure out what the values of keys are? What is the data type of the 'c' variable in the program above? What type of data are we displaying in the printw() function call above? Could you perhaps CHANGE the format specifier to match the actual data type of the 'c' variable? What would happen then? If you then compile and run the program and start pressing keys, what happens? What do you see when you press 'a', 'A', spacebar? Do you know what these values correspond to? What do you think happens when you start pressing some keys that do not directly have printable characters associated with them, like... escape. What does it display? -Matthew -- Matthew Haas Lab46 System Administrator Instructor of Computer& Information Science http://lab46.corning-cc.edu/haas/home/ _______________________________________________ SYS mailing list SYS@lab46.corning-cc.edu http://lab46.corning-cc.edu/mailman/listinfo/sys [ Note: This message contains email list management information ]
After modifying my code in linkedList1-jr.c, my experimental file, I compiled it.
lab46:~/src/data$ gcc linkedList1-jr.c -o linkedList1-jr lab46:~/src/data$
Next, I ran the code and found that it executed perfectly.
lab46:~/src/data$ ./linkedList1-jr 1 2 3 4 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1 lab46:~/src/data$
I then committed it to the Subversion repository.
lab46:~/src$ svn commit -m "Added linked-list deletion routines to linkedList1-jr.c" Sending data/linkedList1-jr.c Transmitting file data . Committed revision 5. lab46:~/src$
I added 2 functions to my linked list experimental file, linkedList1-jr.c, which return the size of a list; one that starts at the head, and the other that starts at the tail.
First, I compiled the modified file.
lab46:~/src/data$ gcc linkedList1-jr.c -o linkedList1-jr
I then executed the file to verify that it worked as expected.
lab46:~/src/data$ ./linkedList1-jr Head = 25c0010 Size of the list is: 10 Head = 25c0010 1 2 3 4 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1 Size of the list is: 25 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 lab46:~/src/data$
I committed the file to the Subversion repository.
lab46:~/src/data$ cd .. lab46:~/src$ svn commit -m "Updated linkedList1-jr.c to include 2 functions to return the size of a linked list, one starting at the head and the other starting at the tail" Sending data/linkedList1-jr.c Transmitting file data . Committed revision 6. lab46:~/src$
I chose Null Pointers as a data topic. I wrote a simple program, nullPtr.c, to demonstrate them. After compiling and executing the program, I then added it and committed it to the Subversion repository.
lab46:~/src/data$ svn add nullPtr.c A nullPtr.c lab46:~/src/data$ svn commit -m "Added and committed the nullPtr.c which demonstrates Null Pointers -JR" Adding data/nullPtr.c Transmitting file data . Committed revision 7. lab46:~/src/data$
I asked the question “Is deallocated memory available to the system immediately after being deallocated?” Which became a subject for my first experiment. For deatils, see experiment 1 below.
lab46:~/src/data$ svn add deallocTest.c A deallocTest.c lab46:~/src/data$ svn commit -m" Added and committed deallocTest.c for experiement 1 -JR" Adding data/deallocTest.c Transmitting file data . Committed revision 8. lab46:~/src/data$
I wrote a program, argv.c, to demonstrate the use of pointers to pointers for the data topic. I compiled the program and ran it successfully. I then added and committed it to the Subversion repository.
lab46:~/src/data$ svn add argv.c A argv.c lab46:~/src/data$ svn commit -m "argv.c is a program which demonstrates the use of pointers to pointers -JR" Adding data/argv.c Transmitting file data . Committed revision 9. lab46:~/src/data$
This is my first Opus entry for IT-HPC.
I was enrolled in this course during the Fall 2011 semester but due to a number of personal issues, and with the consent of the instructor, I took am incomplete for the course at the end of the Fall semester. I am now completing the course.
For Christmas, the family received a wireless router which I set up and now administer. The router make and model are: Cisco Linksys E1200 Wireless router.
I installed a network adapter in my E machine. When I installed it, I noticed that the edge connector on the network adapter didn't fill the entire PCI slot. Usually, this is an indication that the device wasn't designed to be plugged into this type of slot, however, the network adapter was advertised as being a PCI device and the slot I was plugging it into was also advertised as being PCI. Further, the conductive “fingers” on the network adapter edge connector did line up with the pins in the slot, and the polarizing key in the slot matched up with the cutout on the network adapter's edge connector, so decided to install it and see if I could get it to work. On boot-up, however, my system returned a resource conflict error. I let the system boot. Once Windows started, it nformed me that there was new hardware. I Opened the System utility in Control Panel and navigated to Device Manager. In Device Manager, I
I met with the instructor in the Lair to discuss possible projects. I told the instructor that I intended to install Debian Linux on an E Machine which my family has had for several years and that I planned to use use this platform to carry out my HPC 1 projects. He thought this was a good idea.
I brought my computer and network card to the lair with the purpose of getting assistance with the installation of the network adapter. While the instructor taught class, I borrowed a key board and mouse and installed the network card, this time in the other PCI slot. I also removed the modem card from its slot. I booted up the computer and noticed that there was no notification from the operating system of new hardware. I looked in device manager and noticed that there was a network adapter listed. I hooked up the adapter to a switch and rebooted the computer. Once the Windows desktop was displayed, I opened Internet Explorer and then pointed it to Google. Success! the Google logo was displayed.
Once the network adapter installed, it was time to install an operating system. I am partial to Debian so I downloaded a Debian CD image from:
http://cdimage.debian.org/debian-cd/6.0.4/i386/bt-cd/
as per the instructions, I only needed to install CD 1 so I burned CD number one of the set of Debian installation CDs. One the CD was burned, I placed it into the CD drive and rebooted the computer. When the computer rebooted, the Debian install menu was displayed. When I selected any of the installation selections, however, the monitor screen began to flicker and the installation froze. I searched the Internet for a solution but found none, so I began to search for live CD information. While searching for live CD information, I came across information about “Damn Small Linux”. I decided to gicve Damn Small Linux or DSL a try. I downloaded a CD image and then burned a CD. I installed it in the CD Drive and then rebooted the computer. Success! I was able to navigate around and to open a terminal window and move through the directory structure. I powered down the computer and connected my router to the computer's network adapter and then rebooted with the DSL CD in the CD drive. Once the computer booted, I opened Firefox, the Web browser which comes with DSL and pointed it to Google. Success! the Google logo was displayed.
I wrote the instructor about my experiences so far:
Date: Sat, 4 Feb 2012 13:02:43 -0500 (EST) From: John Rine <jr018429@lab46.corning-cc.edu> To: wedge@lab46.corning-cc.edu Subject: Linux install Matt, Well I have made progress with my Linux install on my E machine. As you know, I go my Network adapter installed successfully, short edge connector and all. Once I got the computer home, I checked out the CD drive in preparation for the OS installation. I could get the door open; a CD was jammed in it. I removed the drive from the computer and took it apart and after working patiently for an hour or so, I go the CD out and the drive still worked! My family had gigs worth of files on the hard drive which I go off. Once the computer was ready for Linux, I found a Debian CD image which I downloaded and burned to a CD. I then installed the CD into the drive and boot the computer. On boot up an installation menu was displayed, so far, so good. When I selected an installation option-any installation option it turns out, however, the installation stalls and the screen begins to flicker. I burned another CD, but the installation again locked up and the screen flickered. I searched the Internet for similar occurrences but found none, so I thought I would try a live CD. In my search for live Cd's, I came across DSL, or Damn Small Linux. Intrigued, I read a little about DSL. After reading, I thought I would give it a try so I burned a CD. I installed the CD and then booted the E machine. To my surprise it worked! Once I navigated around for a little while, I connected the computer to the network and rebooted. I was able to use the Firefox browser to surf the Web! My question to you is, that if the live CD worked, shouldn't an install disk work? When researching the Debian install, the documentation described possible issues with CD drivers. My bios supports booting from a CD. The CD drive that is in the computer, however, is not the origninal. The original could only read disks, so I replaced it with one that could also write. Do you have any ideas? I have one more option, well two really. The first option would be to bring the computer back and install it from the Lab46 network which is fine by me. The second option is to install Damn small Linux from a CD into a partition on the hard drive. This option is also fins by me. My only reservation about this option is if I would be able to control hardware and if I could install the Arduino IDE. The Arduino IDE doesn't have to reside on the computer, it just makes development easier. I just wanted to update you on my progress and see if you had any ideas. After learning the course subject matter last semester (Thanks for being a great instructor, Joe too!), I am even more interested in using Linux for control applications. I came across a ladder IDE which is used to program microcontrollers rather than PLCs. It is open source. I downloaded the source and began to figure out how to compile it. I figured out how to use the Microsoft command line C/C++ compiler batch file in order to use Make (the source came with a Make batch file). The install, however, calls a Perl script which apparently is used to configure language options. My next step is to install Perl. Once I have installed Perl, I should be able to compile the source. The next step will be to learn the source and start modifying it. Well got to go, John T. Rine
The following Web page describes which packages are part of Damn Small Linux:
http://www.damnsmalllinux.org/packages.html
Issues having to do with package installation are described on the following Web page:
http://www.damnsmalllinux.org/f/topic-3-9-15019-0.html
On the same day, I received a reply to my e-mail from the instructor:
Date: Sat, 04 Feb 2012 15:53:17 -0500 From: Matthew Haas <wedge@lab46.corning-cc.edu> To: John Rine <jr018429@lab46.corning-cc.edu> Subject: Re: Linux install [ The following text is in the "UTF-8" character set. ] [ Your display is set for the "ISO-8859-1" character set. ] [ Some characters may be displayed incorrectly. ] On Sat, 2012-02-04 at 13:02 -0500, John Rine wrote: > > When I selected an installation option-any > installation option it turns out, however, the installation stalls and the > screen begins to flicker. I burned another CD, but the installation again > locked up and the screen flickered. Sounds like it could be a driver issue... not necessarily (but not excluding) a lack of proper support (I have some video cards in the LAIR that were once supported and are not in current releases). It likely is that the hardware auto-detection scripts are not successful in properly IDing you graphics hardware so it ends up not properly switching out of console VGA modes. > I searched the Internet for similar occurrences but found none, so I > thought I would try a live CD. In my search for live Cd's, I came across > DSL, or Damn Small Linux. Intrigued, I read a little about DSL. After > reading, I thought I would give it a try so I burned a CD. I installed the > CD and then booted the E machine. To my surprise it worked! Once I > navigated around for a little while, I connected the computer to the > network and rebooted. I was able to use the Firefox browser to surf the > Web! Different distros can have this effect. It could just be that it was able to better detect your hardware where Debian could not. You could poke around DSL to get the config info you need and then reapply it to Debian and get it working. For graphics (X), take a look at /var/log/Xorg.0.log... that should contain some telling information about what it is doing to fire up X, including what driver (or X server) it is using, and maybe even some indication of particular options being utilized (note that it will NOT tell you everything though). > My question to you is, that if the live CD worked, shouldn't an install > disk work? When researching the Debian install, the documentation > described possible issues with CD drivers. My bios supports booting > from a CD. The CD drive that is in the computer, however, is not the > original. The original could only read disks, so I replaced it > with one that could also write. Do you have any ideas? Yep, see above paragraph. Live CDs have a higher focus on getting it right out of the box... at the cost of customization or other flexibility. They are designed to be used, not administered. > I have one more option, well two really. The first option would be to > bring the computer back and install it from the Lab46 network which is > fine by me. The second option is to install Damn small Linux from a CD > into a partition on the hard drive. This option is also fins by me. My > only reservation about this option is if I would be able to control You are welcome to do so... Pressly or I could also poke at it and see if we can see any obvious indications of what it is trying to do for graphics and "get it to work". > hardware and if I could install the Arduino IDE. The Arduino IDE doesn't > have to reside on the computer, it just makes development easier. > I just wanted to update you on my progress and see if you had any > ideas. I would say that no matter what distro you end up with, that you have a working package management system so you could install the necessarily prerequisites the Arduino IDE might need. Also, it looks like your degree audit has been fixed for HPC... I took a look last week as I was filling out waivers, and it looks like all you need is to just finish HPC1 so the incomplete turns into a grade. Take a look and let me know if you see otherwise. -Matthew -- Matthew Haas Lab46 System Administrator Instructor of Computer & Information Science http://lab46.corning-cc.edu/haas/home/
After reading the following excerpt: “Now for the warning: Damn Small is not derived purely from Debian, if you 'apt-get install' the wrong application you may break something, for instance, the X servers.
If you want an easy and compact way to get Debian on your hard drive check out Bonzai”
http://www.damnsmalllinux.org/dsl-hd-install.html
I decided that it probably wasn't a good distribution to use for my application.
Below is an e-mail I sent to the instructor after reading about loading packages on DSL.
Date: Sun, 5 Feb 2012 19:04:54 -0500 (EST) From: John Rine <jr018429@lab46.corning-cc.edu> To: wedge@lab46.corning-cc.edu Subject: HPC 1 Progress Matt, On the DSL(Damn Small Linux) page, I found that it is a bad idea to install things on a DSL based system because: "Now for the warning: Damn Small is not derived purely from Debian, if you 'apt-get install' the wrong application you may break something, for instance, the X servers." http://www.damnsmalllinux.org/dsl-hd-install.html The page went on to say: "If you want an easy and compact way to get Debian on your hard drive check out Bonzai" So I decided to give Bonzai a try. I burned a CD. It is installing right now. We'll see what happens. John T. Rine
After making the decision to not use “Damn Small Linux” or DSL for any of my projects, I looked for another distribution to load. I found another compact one called “Bonzai”.
I was able to load it on my E-Machine. SSH, however, wasn't loaded, so I loaded it so that I could connect with lab46. The Bonzai Linux home page is located at:
http://developer.berlios.de/projects/bonzai/.
The latest version can be downloaded from:
http://developer.berlios.de/project/showfiles.php?group_id=825&release_id=1910.
Before installing SSH, however, I couldn't even connect to theInternet. So I researched what was required to do so. I found that I had to load a driver for my network adapter, start the eth0 device, and start the DHCP client. Of course, this last step isn't required if the IP address, etc. are assigned statically. I wanted my network to assign these things dynamically, so that I wouldn't have manage them; that is the point of the DHCP protocol.
In order be able to connect to the Internet, I had to perform the tasks mentioned above on the system so I opened a terminal window.
First, to connect to the Internet, I had to manual load a hardware specific driver for my network adapter:
Bonzai:~$ modprobe 8138too
Next, I brought device eth0 up:
Bonzai:~$ ifconfig eth0 up
Lastley, I started the DHCP client so I didn't have to statically assign the IP address, etc:
Bonzai:~$ dhclient
After I performed these tasks, I was able to view web pages. Next, I opened a terminal window and attempted to SSH into lab46 but was unable because SSH hadn't been loaded. So, with the terminal window open, I performed an apt-get install ssh:
apt-get install ssh
Because the sources.list file pointed to the installation CD, I was prompted to insert the CD. I did and SSH loaded successfully on my Bonzai Linux system.
After loading SSH, I was able to SSH into lab46 and send the instructor an e-mail.
Below is the e-mail I sent to the instructor informing him that after loading Bonzai Linux and configuring the system, I was able to connect to lab46 via SSH and send him an e-mail.
Date: Thu, 9 Feb 2012 19:23:24 -0500 (EST) From: John Rine <jr018429@lab46.corning-cc.edu> To: wedge@lab46.corning-cc.edu Subject: Coming to you from my E Machine Bonzai Linux Box! Banzai! Banzai! Banzai! This is coming to you from my Bonzai or Banzai or should I say Bonsai (small) E-Machine Linux box! Man, it was a pain! First, no network! I read and read and experimented, finally, I got it working by doing the following after boot-up: modprobe 8138too //loads the driver for my Network adapter ifconfig eth0 up //starts up eth0 dhclient //starts DHCP so that I can get IPaddress, etc. Where do I put these commands? Startup script? Next step, install Arduino. Also, no SSH, I had to figuare out how to install it. Luckly, it was on the Banzai (or Bonzai) CD. Now I can experiment with all kinds of stuff. John T. Rine
Bonzai Linux also has issues. It is a small distribution of “Woody” debian. Woody is old. After commenting out the line in sources.list that causes packages to be loaded from the installation CD, I added a line pointing to the Woody Debian repository. When I attempted to install certain packages from that repository I found that they could not be located. I was unable, therefore, to install Arduino as per the instructions on the following Web page: http://arduino.cc/playground/Linux/Debian.
I decided to try Ubantu 11.10 which is the latest version of the Ubantu distribution. I made an installation CD and was able to get it loaded. I was also able to get Arduino installed. I also got the Apache 2 Web server and PHP5 installed.
I worked on HPC1 topics. I added HPC1 topic content to my opus.
I worked on HPC1 topics; I added topic content to my Opus.
I studied HPC1 topic material; I then added topic material to my Opus.
I installed Open SSH on my emachine desktop computer so that I could administer it remotely using SSH. Having the ability to administer it remotely should accelerate development of my second project, controlling hardware remotely. To administer a remote machine, only the SSH server needs to be installed, however, if I wanted to connect to another machine from the taarget machine, I would also need the ssh-client to be installed.
First, I attempted to install the ssh-client:
jr018429@emachine:~$ sudo apt-get install openssh-client [sudo] password for jr018429: Reading package lists... Done Building dependency tree Reading state information... Done openssh-client is already the newest version. 0 upgraded, 0 newly installed, 0 to remove and 355 not upgraded.
I found, however, that the client was already installed so no new installation and no upgrades were performed.
Next, I installed the ssh-server on my emachine.
jr018429@emachine:~$ sudo apt-get install openssh-server Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: ssh-import-id Suggested packages: rssh molly-guard openssh-blacklist openssh-blacklist-extra monkeysphere The following NEW packages will be installed: openssh-server ssh-import-id 0 upgraded, 2 newly installed, 0 to remove and 355 not upgraded. Need to get 345 kB of archives. After this operation, 971 kB of additional disk space will be used. Do you want to continue [Y/n]? y Get:1 http://us.archive.ubuntu.com/ubuntu/ oneiric/main openssh-server i386 1:5.8p1-7ubuntu1 [339 kB] Get:2 http://us.archive.ubuntu.com/ubuntu/ oneiric/main ssh-import-id all 2.5-0ubuntu2 [6,148 B] Fetched 345 kB in 1s (213 kB/s) Preconfiguring packages ... Selecting previously deselected package openssh-server. (Reading database ... 127343 files and directories currently installed.) Unpacking openssh-server (from .../openssh-server_1%3a5.8p1-7ubuntu1_i386.deb) ... Selecting previously deselected package ssh-import-id. Unpacking ssh-import-id (from .../ssh-import-id_2.5-0ubuntu2_all.deb) ... Processing triggers for man-db ... Processing triggers for ureadahead ... ureadahead will be reprofiled on next reboot Processing triggers for ufw ... Setting up openssh-server (1:5.8p1-7ubuntu1) ... Creating SSH2 RSA key; this may take some time ... Creating SSH2 DSA key; this may take some time ... Creating SSH2 ECDSA key; this may take some time ... ssh start/running, process 2792 Setting up ssh-import-id (2.5-0ubuntu2) ... jr018429@emachine:~$
To open an SSH connection to a target machine, one needs to know either the domain name or the IP address of the remote host, so on the host on which I was going to install Open SSH, I performed an ifconfig on the target machine to get its IP address:
jr018429@emachine:~$ ifconfig eth0 Link encap:Ethernet HWaddr 00:e0:4c:ff:12:b2 inet addr:192.168.1.113 Bcast:192.168.1.255 Mask:255.255.255.0 inet6 addr: fe80::2e0:4cff:feff:12b2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1094 errors:0 dropped:0 overruns:0 frame:0 TX packets:669 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1485876 (1.4 MB) TX bytes:54388 (54.3 KB) Interrupt:16 Base address:0x3000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) jr018429@emachine:~$
Using the IP adrress, username and password of my emachine, I opened putty on a Windows laptop and attempted to log into it:
login as: jr018429 jr018429@192.168.1.113's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ Last login: Mon Mar 19 20:01:36 2012 from 192.168.1.111 jr018429@emachine:~$
Success! I was able to log into my emachine remotely.
Next, using Filezilla on my Windows laptop, I tried to transfer a file from the emachine running Ubuntu, to my Windows 7 desktop, so I entered the IP address, username, password and port number for the connection. Success! I was able to transfer a file from the emachine to my laptop.
I wanted to create a root user and password so I performed the following via pUTTY:
login as: jr018429 jr018429@192.168.1.113's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ Last login: Mon Mar 19 20:12:00 2012 from 192.168.1.111 jr018429@emachine:~$ sudo passwd root [sudo] password for jr018429: Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully jr018429@emachine:~$
Next, I configured the emachine running Ubuntu 11.10 with a static IP address. First, I logged in remotely using pUTTY:
login as: jr018429 jr018429@192.168.1.113's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ 359 packages can be updated. 96 updates are security updates. Last login: Mon Mar 19 20:58:16 2012 from 192.168.1.111 jr018429@emachine:~$ su Password:
Next, I edited /etc/network/interfaces file:
root@emachine:/home/jr018429# nano /etc/network/interfaces
I added the section beginning with the line “auto eth0” to the /etc/network/interfaces file:
auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 192.168.1.2 network 192.168.1.0 netmask 255.255.255.0 broadcast 192.168.1.255 gateway 192.168.1.1
Lastly, I restarted networking:
root@emachine:/home/jr018429# /etc/init.d/networking restart
I then logged into the emachine from pUTTY using the new IP address:
login as: jr018429 jr018429@192.168.1.2's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ 359 packages can be updated. 96 updates are security updates. Last login: Mon Mar 19 21:17:06 2012 from 192.168.1.111 jr018429@emachine:~$
I logged into the Linksys E1200 router and forwarded port 22 (SSH) to the emachine's static IP address. Next, I forwarded port 80 (HTTP) to the emachine's static IP address. I then used putty to access the IP address assigned to the router's port by my ISP. Success!
I installed Apache2 and PHP5 on my emachine remotely using pUTTY. First I installed Apache2:
login as: jr018429 jr018429@192.168.1.2's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ 359 packages can be updated. 96 updates are security updates. Last login: Mon Mar 19 21:49:14 2012 from 192.168.1.1 jr018429@emachine:~$ sudo apt-get install apache2 [sudo] password for jr018429: Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap Suggested packages: apache2-doc apache2-suexec apache2-suexec-custom The following NEW packages will be installed: apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap 0 upgraded, 9 newly installed, 0 to remove and 355 not upgraded. Need to get 3,131 kB of archives. After this operation, 10.3 MB of additional disk space will be used. Do you want to continue [Y/n]? y Get:1 http://us.archive.ubuntu.com/ubuntu/ oneiric/main libapr1 i386 1.4.5-1 [90.5 kB] Get:2 http://us.archive.ubuntu.com/ubuntu/ oneiric/main libaprutil1 i386 1.3.12+dfsg-2 [75.4 kB] Get:3 http://us.archive.ubuntu.com/ubuntu/ oneiric/main libaprutil1-dbd-sqlite3 i386 1.3.12+dfsg-2 [10.3 kB] Get:4 http://us.archive.ubuntu.com/ubuntu/ oneiric/main libaprutil1-ldap i386 1.3.12+dfsg-2 [7,988 B] Get:5 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main apache2.2-bin i386 2.2.20-1ubuntu1.2 [2,636 kB] Get:6 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main apache2-utils i386 2.2.20-1ubuntu1.2 [84.3 kB] Get:7 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main apache2.2-common i386 2.2.20-1ubuntu1.2 [223 kB] Get:8 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main apache2-mpm-worker i386 2.2.20-1ubuntu1.2 [2,282 B] Get:9 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main apache2 i386 2.2.20-1ubuntu1.2 [1,484 B] Fetched 3,131 kB in 5s (610 kB/s) Selecting previously deselected package libapr1. (Reading database ... 127369 files and directories currently installed.) Unpacking libapr1 (from .../libapr1_1.4.5-1_i386.deb) ... Selecting previously deselected package libaprutil1. Unpacking libaprutil1 (from .../libaprutil1_1.3.12+dfsg-2_i386.deb) ... Selecting previously deselected package libaprutil1-dbd-sqlite3. Unpacking libaprutil1-dbd-sqlite3 (from .../libaprutil1-dbd-sqlite3_1.3.12+dfsg-2_i386.deb) ... Selecting previously deselected package libaprutil1-ldap. Unpacking libaprutil1-ldap (from .../libaprutil1-ldap_1.3.12+dfsg-2_i386.deb) ... Selecting previously deselected package apache2.2-bin. Unpacking apache2.2-bin (from .../apache2.2-bin_2.2.20-1ubuntu1.2_i386.deb) ... Selecting previously deselected package apache2-utils. Unpacking apache2-utils (from .../apache2-utils_2.2.20-1ubuntu1.2_i386.deb) ... Selecting previously deselected package apache2.2-common. Unpacking apache2.2-common (from .../apache2.2-common_2.2.20-1ubuntu1.2_i386.deb) ... Selecting previously deselected package apache2-mpm-worker. Unpacking apache2-mpm-worker (from .../apache2-mpm-worker_2.2.20-1ubuntu1.2_i386.deb) ... Selecting previously deselected package apache2. Unpacking apache2 (from .../apache2_2.2.20-1ubuntu1.2_i386.deb) ... Processing triggers for man-db ... Processing triggers for ufw ... Processing triggers for ureadahead ... Setting up libapr1 (1.4.5-1) ... Setting up libaprutil1 (1.3.12+dfsg-2) ... Setting up libaprutil1-dbd-sqlite3 (1.3.12+dfsg-2) ... Setting up libaprutil1-ldap (1.3.12+dfsg-2) ... Setting up apache2.2-bin (2.2.20-1ubuntu1.2) ... Setting up apache2-utils (2.2.20-1ubuntu1.2) ... Setting up apache2.2-common (2.2.20-1ubuntu1.2) ... Enabling site default. Enabling module alias. Enabling module autoindex. Enabling module dir. Enabling module env. Enabling module mime. Enabling module negotiation. Enabling module setenvif. Enabling module status. Enabling module auth_basic. Enabling module deflate. Enabling module authz_default. Enabling module authz_user. Enabling module authz_groupfile. Enabling module authn_file. Enabling module authz_host. Enabling module reqtimeout. Setting up apache2-mpm-worker (2.2.20-1ubuntu1.2) ... * Starting web server apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] Setting up apache2 (2.2.20-1ubuntu1.2) ... Processing triggers for libc-bin ... ldconfig deferred processing now taking place jr018429@emachine:~$
Next, I installed PHP5:
jr018429@emachine:~$ sudo apt-get install php5 Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: apache2-mpm-prefork libapache2-mod-php5 php5-cli php5-common Suggested packages: php-pear php5-suhosin The following packages will be REMOVED: apache2-mpm-worker The following NEW packages will be installed: apache2-mpm-prefork libapache2-mod-php5 php5 php5-cli php5-common 0 upgraded, 5 newly installed, 1 to remove and 355 not upgraded. Need to get 6,614 kB of archives. After this operation, 17.7 MB of additional disk space will be used. Do you want to continue [Y/n]? y Get:1 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main apache2-mpm-prefork i386 2.2.20-1ubuntu1.2 [2,398 B] Get:2 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main php5-common i386 5.3.6-13ubuntu3.6 [416 kB] Get:3 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main libapache2-mod-php5 i386 5.3.6-13ubuntu3.6 [3,109 kB] Get:4 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main php5 all 5.3.6-13ubuntu3.6 [1,108 B] Get:5 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/main php5-cli i386 5.3.6-13ubuntu3.6 [3,086 kB] Fetched 6,614 kB in 12s (540 kB/s) dpkg: apache2-mpm-worker: dependency problems, but removing anyway as you requested: apache2 depends on apache2-mpm-worker (= 2.2.20-1ubuntu1.2) | apache2-mpm-prefork (= 2.2.20-1ubuntu1.2) | apache2-mpm-event (= 2.2.20-1ubuntu1.2) | apache2-mpm-itk (= 2.2.20-1ubuntu1.2); however: Package apache2-mpm-worker is to be removed. Package apache2-mpm-prefork is not installed. Package apache2-mpm-event is not installed. Package apache2-mpm-itk is not installed. (Reading database ... 127945 files and directories currently installed.) Removing apache2-mpm-worker ... * Stopping web server apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName ... waiting [ OK ] Selecting previously deselected package apache2-mpm-prefork. (Reading database ... 127941 files and directories currently installed.) Unpacking apache2-mpm-prefork (from .../apache2-mpm-prefork_2.2.20-1ubuntu1.2_i386.deb) ... Setting up apache2-mpm-prefork (2.2.20-1ubuntu1.2) ... * Starting web server apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] Selecting previously deselected package php5-common. (Reading database ... 127946 files and directories currently installed.) Unpacking php5-common (from .../php5-common_5.3.6-13ubuntu3.6_i386.deb) ... Selecting previously deselected package libapache2-mod-php5. Unpacking libapache2-mod-php5 (from .../libapache2-mod-php5_5.3.6-13ubuntu3.6_i386.deb) ... Selecting previously deselected package php5. Unpacking php5 (from .../php5_5.3.6-13ubuntu3.6_all.deb) ... Selecting previously deselected package php5-cli. Unpacking php5-cli (from .../php5-cli_5.3.6-13ubuntu3.6_i386.deb) ... Processing triggers for man-db ... Setting up php5-common (5.3.6-13ubuntu3.6) ... Setting up libapache2-mod-php5 (5.3.6-13ubuntu3.6) ... Creating config file /etc/php5/apache2/php.ini with new version * Reloading web server config apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] Setting up php5 (5.3.6-13ubuntu3.6) ... Setting up php5-cli (5.3.6-13ubuntu3.6) ... Creating config file /etc/php5/cli/php.ini with new version update-alternatives: using /usr/bin/php5 to provide /usr/bin/php (php) in auto mode.
I then installed a library for php5:
jr018429@emachine:~$ sudo apt-get install libapache2-mod-php5 Reading package lists... Done Building dependency tree Reading state information... Done libapache2-mod-php5 is already the newest version. libapache2-mod-php5 set to manually installed. 0 upgraded, 0 newly installed, 0 to remove and 355 not upgraded. jr018429@emachine:~$ sudo /etc/init.d/apache2 restart * Restarting web server apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName ... waiting apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] jr018429@emachine:~$
I plugged in the IP address assigned by the ISP into Internet Explorer on my laptop running Windows 7. Success! The default Web page is displayed. I now have Web server running and accessible to the outside world.
I wanted to configure Apache to also listen at port 8080; sometimes there are port confilcts and an administer is sometimes required to resolve those conflicts. I configured Apache to listen also at port 8080 through pUTTY (remote administeration). In /etc/apache2/ports.conf, I added the line “Listen 8080” immediately after the “Listen 80” line.
ports.conf:
# If you just change the port or add more ports here, you will likely also # have to change the VirtualHost statement in # /etc/apache2/sites-enabled/000-default # This is also true if you have upgraded from before 2.2.9-3 (i.e. from # Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz and # README.Debian.gz NameVirtualHost *:80 Listen 80 Listen 8080 <IfModule mod_ssl.c> # If you add NameVirtualHost *:443 here, you will also have to change # the VirtualHost statement in /etc/apache2/sites-available/default-ssl # to <VirtualHost *:443> # Server Name Indication for SSL named virtual hosts is currently not # supported by MSIE on Windows XP. Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule>
Simply adding the Listen 8080 line to the /etc/apache2/ports.conf file didn't cause Apache2 to react to requests on port 8080. I also had to make a change to the /etc/apache2/sites-available/default file. I had to change the first line from <VirtualHost *:80> to <VirtualHost *:80 *:8080>.
default:
<VirtualHost *:80 *:8080> ServerAdmin webmaster@localhost DocumentRoot /var/www <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews FollowSymLinks AllowOverride None Order deny,allow Deny from all Allow from 127.0.0.0/255.0.0.0 ::1/128 </Directory> </VirtualHost>
I then restarted Apache2.
root@emachine:/etc/apache2# /etc/init.d/apache2 restart * Restarting web server apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName ... waiting apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] root@emachine:/etc/apache2#
Success! accessing the 8080 port through HTTP requests from a Web browser causes a Web page to be returned. Now I can either configure Apache to only listen on port 8080, or only forward the 8080 port from the Linksys router.
Next, since I installed PHP, I wanted to verify that PHP scripting worked, so I logged into the emachine remotely and created a web page with PHP script which calls the phpinfo function. The phpinfo function returns php configuration information:
login as: root root@192.168.1.2's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ Last login: Tue Mar 20 19:01:16 2012 from 192.168.1.111 root@emachine:~# cd /var/www root@emachine:/var/www nano phpinfo.php root@emachine:/var/www#
The phpinfo,.php looks like this:
<html> <title>PHP Information</title> <?php phpinfo(); ?> </html>
I tested the phpinfo.php file by entering the static IP address I assigned to the emachine earlier followed by the php page name, 192.168.1.2:8080/phpinfo.php, into a Web browser. Success! The page was returned.
I worked on my “Controlling Hardware via the Web” project, however, the Arduino package wouldn't install:
root@emachine:/home/jr018429# apt-get install arduino Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: arduino-core avr-libc avrdude binutils-avr extra-xdg-menus gcc-avr libjna-java librxtx-java Suggested packages: avrdude-doc task-c-devel gcc-doc gcc-4.2 libjna-java-doc The following NEW packages will be installed: arduino arduino-core avr-libc avrdude binutils-avr extra-xdg-menus gcc-avr libjna-java librxtx-java 0 upgraded, 9 newly installed, 0 to remove and 18 not upgraded. Need to get 18.8 MB of archives. After this operation, 77.6 MB of additional disk space will be used. Do you want to continue [Y/n]? y Err http://us.archive.ubuntu.com/ubuntu/ oneiric/universe libjna-java i386 3.2.7-4 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com/ubuntu/ oneiric/universe librxtx-java i386 2.2pre2-8 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com/ubuntu/ oneiric/universe binutils-avr i386 2.20.1-2 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com/ubuntu/ oneiric/universe gcc-avr i386 1:4.5.3-2 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com/ubuntu/ oneiric/universe avrdude i386 5.10-3 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com/ubuntu/ oneiric/universe avr-libc all 1:1.7.1-2 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/universe arduino-core all 0022+dfsg-4ubuntu0.1 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/universe arduino all 0022+dfsg-4ubuntu0.1 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com/ubuntu/ oneiric/universe extra-xdg-menus all 1.0-4 Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/libj/libjna-java/libjna-java_3.2.7-4_i386.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/r/rxtx/librxtx-java_2.2pre2-8_i386.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/b/binutils-avr/binutils-avr_2.20.1-2_i386.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/g/gcc-avr/gcc-avr_4.5.3-2_i386.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/a/avrdude/avrdude_5.10-3_i386.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/a/avr-libc/avr-libc_1.7.1-2_all.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/a/arduino/arduino-core_0022+dfsg-4ubuntu0.1_all.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/a/arduino/arduino_0022+dfsg-4ubuntu0.1_all.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/universe/e/extra-xdg-menus/extra-xdg-menus_1.0-4_all.deb Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing? root@emachine:/home/jr018429#
Furthermore, I found that apt-get update didn't work either:
root@emachine:/home/jr018429# apt-get update Ign http://extras.ubuntu.com oneiric InRelease Ign http://security.ubuntu.com oneiric-security InRelease Err http://extras.ubuntu.com oneiric Release.gpg Something wicked happened resolving 'extras.ubuntu.com:http' (-5 - No address associated with hostname) Err http://security.ubuntu.com oneiric-security Release.gpg Something wicked happened resolving 'security.ubuntu.com:http' (-5 - No address associated with hostname) Ign http://us.archive.ubuntu.com oneiric InRelease Ign http://extras.ubuntu.com oneiric Release Ign http://security.ubuntu.com oneiric-security Release Ign http://us.archive.ubuntu.com oneiric-updates InRelease Ign http://us.archive.ubuntu.com oneiric-backports InRelease Ign http://security.ubuntu.com oneiric-security/main Sources/DiffIndex Ign http://extras.ubuntu.com oneiric/main Sources/DiffIndex Err http://us.archive.ubuntu.com oneiric Release.gpg Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Err http://us.archive.ubuntu.com oneiric-updates Release.gpg Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Ign http://security.ubuntu.com oneiric-security/restricted Sources/DiffIndex Ign http://security.ubuntu.com oneiric-security/universe Sources/DiffIndex Ign http://security.ubuntu.com oneiric-security/multiverse Sources/DiffIndex Ign http://extras.ubuntu.com oneiric/main i386 Packages/DiffIndex Ign http://extras.ubuntu.com oneiric/main TranslationIndex Err http://us.archive.ubuntu.com oneiric-backports Release.gpg Something wicked happened resolving 'us.archive.ubuntu.com:http' (-5 - No address associated with hostname) Ign http://us.archive.ubuntu.com oneiric Release Ign http://security.ubuntu.com oneiric-security/main i386 Packages/DiffIndex Ign http://security.ubuntu.com oneiric-security/restricted i386 Packages/DiffIndex Ign http://security.ubuntu.com oneiric-security/universe i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric-updates Release Ign http://us.archive.ubuntu.com oneiric-backports Release Ign http://security.ubuntu.com oneiric-security/multiverse i386 Packages/DiffIndex Ign http://security.ubuntu.com oneiric-security/main TranslationIndex Ign http://us.archive.ubuntu.com oneiric/main Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric/restricted Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric/universe Sources/DiffIndex Ign http://security.ubuntu.com oneiric-security/multiverse TranslationIndex Ign http://security.ubuntu.com oneiric-security/restricted TranslationIndex Ign http://security.ubuntu.com oneiric-security/universe TranslationIndex Ign http://us.archive.ubuntu.com oneiric/multiverse Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric/main i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric/restricted i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric/universe i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric/multiverse i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric/main TranslationIndex Ign http://us.archive.ubuntu.com oneiric/multiverse TranslationIndex Err http://extras.ubuntu.com oneiric/main Sources Something wicked happened resolving 'extras.ubuntu.com:http' (-5 - No address associated with hostname) Ign http://us.archive.ubuntu.com oneiric/restricted TranslationIndex Ign http://us.archive.ubuntu.com oneiric/universe TranslationIndex Err http://extras.ubuntu.com oneiric/main i386 Packages Something wicked happened resolving 'extras.ubuntu.com:http' (-5 - No address associated with hostname) Err http://extras.ubuntu.com oneiric/main Translation-en_US Something wicked happened resolving 'extras.ubuntu.com:http' (-5 - No address associated with hostname) Ign http://us.archive.ubuntu.com oneiric-updates/main Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric-updates/restricted Sources/DiffIndex Err http://extras.ubuntu.com oneiric/main Translation-en Something wicked happened resolving 'extras.ubuntu.com:http' (-5 - No address associated with hostname) Ign http://us.archive.ubuntu.com oneiric-updates/universe Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric-updates/multiverse Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric-updates/main i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric-updates/restricted i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric-updates/universe i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric-updates/multiverse i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric-updates/main TranslationIndex Ign http://us.archive.ubuntu.com oneiric-updates/multiverse TranslationIndex Ign http://us.archive.ubuntu.com oneiric-updates/restricted TranslationIndex Ign http://us.archive.ubuntu.com oneiric-updates/universe TranslationIndex Ign http://us.archive.ubuntu.com oneiric-backports/main Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric-backports/restricted Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric-backports/universe Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric-backports/multiverse Sources/DiffIndex Ign http://us.archive.ubuntu.com oneiric-backports/main i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric-backports/restricted i386 Packages/DiffIndex Ign http://us.archive.ubuntu.com oneiric-backports/universe i386 Packages/DiffIndex 22% [Connecting to security.ubuntu.com]^C root@emachine:/home/jr018429#
I researched the issue, tried several things suggested in various articles published on the Web, but nothing worked. Finally, I searched the Web for information regarding the error message “Something wicked happened resolving 'extras.ubuntu.com ” which was one of the error messages returned during the apt-get update. I found the following two articles: http://ubuntuforums.org/showthread.php?t=1692331 and http://code.google.com/speed/public-dns/docs/using.html which together suggest adding two lines, nameserver 8.8.8.8 and nameserver 8.8.8.8 to the /etc/resolv.conf file:
# Generated by NetworkManager nameserver 8.8.8.8 nameserver 8.8.4.4
After making these changes to the /etc/resolv.conf file, apt-get update worked:
login as: jr018429 jr018429@192.168.1.2's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ Last login: Sat Mar 22 11:56:55 2012 from 192.168.1.101 jr018429@emachine:~$ sudo apt-get update [sudo] password for jr018429: Ign http://security.ubuntu.com oneiric-security InRelease Ign http://us.archive.ubuntu.com oneiric InRelease Ign http://extras.ubuntu.com oneiric InRelease Ign http://us.archive.ubuntu.com oneiric-updates InRelease Ign http://us.archive.ubuntu.com oneiric-backports InRelease Get:1 http://security.ubuntu.com oneiric-security Release.gpg [198 B] Get:2 http://us.archive.ubuntu.com oneiric Release.gpg [198 B] Get:3 http://extras.ubuntu.com oneiric Release.gpg [72 B] Get:4 http://us.archive.ubuntu.com oneiric-updates Release.gpg [198 B] Get:5 http://security.ubuntu.com oneiric-security Release [40.8 kB] Get:6 http://extras.ubuntu.com oneiric Release [9,759 B] Get:7 http://us.archive.ubuntu.com oneiric-backports Release.gpg [198 B] Hit http://us.archive.ubuntu.com oneiric Release Get:8 http://us.archive.ubuntu.com oneiric-updates Release [40.8 kB] Get:9 http://extras.ubuntu.com oneiric/main Sources [2,260 B] Get:10 http://security.ubuntu.com oneiric-security/main Sources [34.5 kB] Get:11 http://us.archive.ubuntu.com oneiric-backports Release [40.8 kB] Get:12 http://extras.ubuntu.com oneiric/main i386 Packages [3,711 B] Ign http://extras.ubuntu.com oneiric/main TranslationIndex Hit http://us.archive.ubuntu.com oneiric/main Sources Hit http://us.archive.ubuntu.com oneiric/restricted Sources Hit http://us.archive.ubuntu.com oneiric/universe Sources Hit http://us.archive.ubuntu.com oneiric/multiverse Sources Hit http://us.archive.ubuntu.com oneiric/main i386 Packages Hit http://us.archive.ubuntu.com oneiric/restricted i386 Packages Hit http://us.archive.ubuntu.com oneiric/universe i386 Packages Hit http://us.archive.ubuntu.com oneiric/multiverse i386 Packages Hit http://us.archive.ubuntu.com oneiric/main TranslationIndex Get:13 http://security.ubuntu.com oneiric-security/restricted Sources [14 B] Get:14 http://security.ubuntu.com oneiric-security/universe Sources [13.3 kB] Get:15 http://security.ubuntu.com oneiric-security/multiverse Sources [1,654 B] Hit http://us.archive.ubuntu.com oneiric/multiverse TranslationIndex Hit http://us.archive.ubuntu.com oneiric/restricted TranslationIndex Hit http://us.archive.ubuntu.com oneiric/universe TranslationIndex Get:16 http://us.archive.ubuntu.com oneiric-updates/main Sources [132 kB] Get:17 http://security.ubuntu.com oneiric-security/main i386 Packages [90.5 kB] Get:18 http://security.ubuntu.com oneiric-security/restricted i386 Packages [14 B] Get:19 http://security.ubuntu.com oneiric-security/universe i386 Packages [31.4 kB] Get:20 http://security.ubuntu.com oneiric-security/multiverse i386 Packages [3,363 B] Get:21 http://security.ubuntu.com oneiric-security/main TranslationIndex [73 B] Get:22 http://security.ubuntu.com oneiric-security/multiverse TranslationIndex [72 B] Get:23 http://security.ubuntu.com oneiric-security/restricted TranslationIndex [70 B] Get:24 http://security.ubuntu.com oneiric-security/universe TranslationIndex [73 B] Ign http://extras.ubuntu.com oneiric/main Translation-en_US Get:25 http://security.ubuntu.com oneiric-security/main Translation-en [50.7 kB] Ign http://extras.ubuntu.com oneiric/main Translation-en Get:26 http://us.archive.ubuntu.com oneiric-updates/restricted Sources [1,337 B] Get:27 http://us.archive.ubuntu.com oneiric-updates/universe Sources [48.8 kB] Hit http://security.ubuntu.com oneiric-security/multiverse Translation-en Hit http://security.ubuntu.com oneiric-security/restricted Translation-en Get:28 http://us.archive.ubuntu.com oneiric-updates/multiverse Sources [3,648 B] Get:29 http://us.archive.ubuntu.com oneiric-updates/main i386 Packages [305 kB] Get:30 http://security.ubuntu.com oneiric-security/universe Translation-en [22.1 kB] Get:31 http://us.archive.ubuntu.com oneiric-updates/restricted i386 Packages [2,968 B] Get:32 http://us.archive.ubuntu.com oneiric-updates/universe i386 Packages [105 kB] Get:33 http://us.archive.ubuntu.com oneiric-updates/multiverse i386 Packages [6,367 B] Get:34 http://us.archive.ubuntu.com oneiric-updates/main TranslationIndex [74 B] Get:35 http://us.archive.ubuntu.com oneiric-updates/multiverse TranslationIndex [72 B] Get:36 http://us.archive.ubuntu.com oneiric-updates/restricted TranslationIndex [71 B] Get:37 http://us.archive.ubuntu.com oneiric-updates/universe TranslationIndex [73 B] Hit http://us.archive.ubuntu.com oneiric/main Translation-en Get:38 http://us.archive.ubuntu.com oneiric-backports/main Sources [2,742 B] Get:39 http://us.archive.ubuntu.com oneiric-backports/restricted Sources [14 B] Get:40 http://us.archive.ubuntu.com oneiric-backports/universe Sources [7,964 B] Get:41 http://us.archive.ubuntu.com oneiric-backports/multiverse Sources [14 B] Get:42 http://us.archive.ubuntu.com oneiric-backports/main i386 Packages [3,296 B] Get:43 http://us.archive.ubuntu.com oneiric-backports/restricted i386 Packages [14 B] Get:44 http://us.archive.ubuntu.com oneiric-backports/universe i386 Packages [9,291 B] Get:45 http://us.archive.ubuntu.com oneiric-backports/multiverse i386 Packages [14 B] Get:46 http://us.archive.ubuntu.com oneiric-backports/main TranslationIndex [72 B] Get:47 http://us.archive.ubuntu.com oneiric-backports/multiverse TranslationIndex [70 B] Get:48 http://us.archive.ubuntu.com oneiric-backports/restricted TranslationIndex [70 B] Get:49 http://us.archive.ubuntu.com oneiric-backports/universe TranslationIndex [72 B] Hit http://us.archive.ubuntu.com oneiric/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric/restricted Translation-en Hit http://us.archive.ubuntu.com oneiric/universe Translation-en Get:50 http://us.archive.ubuntu.com oneiric-updates/main Translation-en [142 kB] Hit http://us.archive.ubuntu.com oneiric-updates/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/restricted Translation-en Get:51 http://us.archive.ubuntu.com oneiric-updates/universe Translation-en [62.9 kB] Hit http://us.archive.ubuntu.com oneiric-backports/main Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/restricted Translation-en Get:52 http://us.archive.ubuntu.com oneiric-backports/universe Translation-en [7,860 B] Fetched 1,227 kB in 8s (153 kB/s) Reading package lists... Done jr018429@emachine:~$
Also after changing the /etc/resolv.conf file as described above, the Arduino package installed perfectly:
root@emachine:/home/jr018429# apt-get install arduino Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: arduino-core avr-libc avrdude binutils-avr extra-xdg-menus gcc-avr libjna-java librxtx-java Suggested packages: avrdude-doc task-c-devel gcc-doc gcc-4.2 libjna-java-doc The following NEW packages will be installed: arduino arduino-core avr-libc avrdude binutils-avr extra-xdg-menus gcc-avr libjna-java librxtx-java 0 upgraded, 9 newly installed, 0 to remove and 18 not upgraded. Need to get 18.8 MB of archives. After this operation, 77.6 MB of additional disk space will be used. Do you want to continue [Y/n]? y Get:1 http://us.archive.ubuntu.com/ubuntu/ oneiric/universe libjna-java i386 3.2.7-4 [414 kB] Get:2 http://us.archive.ubuntu.com/ubuntu/ oneiric/universe librxtx-java i386 2.2pre2-8 [175 kB] Get:3 http://us.archive.ubuntu.com/ubuntu/ oneiric/universe binutils-avr i386 2.20.1-2 [4,347 kB] Get:4 http://us.archive.ubuntu.com/ubuntu/ oneiric/universe gcc-avr i386 1:4.5.3-2 [7,699 kB] Get:5 http://us.archive.ubuntu.com/ubuntu/ oneiric/universe avrdude i386 5.10-3 [199 kB] Get:6 http://us.archive.ubuntu.com/ubuntu/ oneiric/universe avr-libc all 1:1.7.1-2 [4,665 kB] Get:7 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/universe arduino-core all 0022+dfsg-4ubuntu0.1 [602 kB] Get:8 http://us.archive.ubuntu.com/ubuntu/ oneiric-updates/universe arduino all 0022+dfsg-4ubuntu0.1 [678 kB] Get:9 http://us.archive.ubuntu.com/ubuntu/ oneiric/universe extra-xdg-menus all 1.0-4 [12.8 kB] Fetched 18.8 MB in 35s (525 kB/s) Selecting previously deselected package libjna-java. (Reading database ... 128091 files and directories currently installed.) Unpacking libjna-java (from .../libjna-java_3.2.7-4_i386.deb) ... Selecting previously deselected package librxtx-java. Unpacking librxtx-java (from .../librxtx-java_2.2pre2-8_i386.deb) ... Selecting previously deselected package binutils-avr. Unpacking binutils-avr (from .../binutils-avr_2.20.1-2_i386.deb) ... Selecting previously deselected package gcc-avr. Unpacking gcc-avr (from .../gcc-avr_1%3a4.5.3-2_i386.deb) ... Selecting previously deselected package avrdude. Unpacking avrdude (from .../avrdude_5.10-3_i386.deb) ... Selecting previously deselected package avr-libc. Unpacking avr-libc (from .../avr-libc_1%3a1.7.1-2_all.deb) ... Selecting previously deselected package arduino-core. Unpacking arduino-core (from .../arduino-core_0022+dfsg-4ubuntu0.1_all.deb) ... Selecting previously deselected package arduino. Unpacking arduino (from .../arduino_0022+dfsg-4ubuntu0.1_all.deb) ... Selecting previously deselected package extra-xdg-menus. Unpacking extra-xdg-menus (from .../extra-xdg-menus_1.0-4_all.deb) ... Processing triggers for doc-base ... Processing 2 added doc-base files... Registering documents with scrollkeeper... Processing triggers for man-db ... Processing triggers for desktop-file-utils ... Processing triggers for bamfdaemon ... Rebuilding /usr/share/applications/bamf.index... Processing triggers for gnome-menus ... Processing triggers for hicolor-icon-theme ... Setting up libjna-java (3.2.7-4) ... Setting up librxtx-java (2.2pre2-8) ... Setting up binutils-avr (2.20.1-2) ... Setting up gcc-avr (1:4.5.3-2) ... Setting up avrdude (5.10-3) ... Setting up avr-libc (1:1.7.1-2) ... Setting up arduino-core (0022+dfsg-4ubuntu0.1) ... Setting up arduino (0022+dfsg-4ubuntu0.1) ... Setting up extra-xdg-menus (1.0-4) ... Processing triggers for libc-bin ... ldconfig deferred processing now taking place root@emachine:/home/jr018429#
I worked on experiment 2(HPC1). My hypothesis regarding port forwarding from my router and use of the Linux firewall to disallow ports was that I could simply not forward port 80 (HTTP) to cause HTTP traffic from reaching my Web server or disallow port 80 at the firewall. I was correct (see experiment 2-HPC1 for details)!
I worked on HPC1 topics related to remote administration. Topics I worked on include: Remote administration, Telnet, SSH, FTP, Linux Remote desktop applications.
I wrote up an HPC1 Objective; I described what it took to put together a home network and then answered the questions posed by the instructor in the template for the course objective; the answers were specific to the subject matter.
I wrote up another HPC1 Objective; I described what it took to install, configure and test a Web server and related software. I then answered the questions posed by the instructor in the template for the course objective; the answers were specific to the subject matter.
My grandson Gabriel Alexander Barlow was born today!
I worked on the topic ufw or Uncomplicated Firewall. I read and experimented to figure out how to use ufw to manage my emachine's firewall.
First, I executed ufw status, however, I found out I had to be logged in as root so that I could use ufw.
jr018429@emachine:~$ ufw status ERROR: You need to be root to run this script jr018429@emachine:~$
Once I was logged in as root, I found, throught the use of 'ufw status', that by default, ufw was disabled.
root@emachine:/home/jr018429# ufw status Status: inactive
Once I enabled ufw, I found, once again through the use of 'ufw status', that by default no rules were set. Only the message 'Status: active' was returned
root@emachine:/home/jr018429# ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429#
Next, I tested 'ufw disable' functionality.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw disable Firewall stopped and disabled on system startup root@emachine:/home/jr018429#
I reenabled ufw and then tried setting a ufw allow option with port and protocol parameters to see how it worked.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow 22/tcp Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 22/tcp ALLOW Anywhere (v6) root@emachine:/home/jr018429#
After trying ufw with the allow option, I figured the next logical thing to try was the deny option with a port parameter.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw deny 23 Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 23 DENY Anywhere 23 DENY Anywhere (v6) root@emachine:/home/jr018429#
The ufw's syntax for removing a rule is very simple. Simply use the syntax for the rule but place the option 'delete' between ufw and the remaining options.
root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 23 DENY Anywhere 23 DENY Anywhere (v6) root@emachine:/home/jr018429# ufw delete deny 23 Rule deleted Rule deleted (v6) root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429#
It is possible to create firewall rules for services. Next, I tried 'ufw allow' with a service parameter.
root@emachine:/home/jr018429# ufw allow ssh Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 22 ALLOW Anywhere 22 ALLOW Anywhere (v6) root@emachine:/home/jr018429#
To deny a service using its service name, use the 'deny' option with the service parameter.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw deny telnet Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 23/tcp DENY Anywhere 23/tcp DENY Anywhere (v6) root@emachine:/home/jr018429#
Next, I experimented with allowing and denying IP addresses. In this case I used 'deny'.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow from 192.168.1.1 Rule added root@emachine:/home/jr018429#
Using ufw, it is possible to allow or deny a protocol from an IP address or network IP address and gateway to an ip address (target IP address) on a certain port. I experimented with these options and their parameters. Note that 'any' means any target IP address.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow proto tcp from 192.168.1.134 to any port 22 Rule added root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW 192.168.1.134 root@emachine:/home/jr018429#
Since I used the 'any' parameter in the last experiment, I wanted to see how using a target IP address worked.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow proto tcp from 192.168.1.134 to 192.168.1.2 port 22 Rule added root@emachine:/home/jr018429#
A range of IP addresses can be specified through the use of the network address and a subnet mask. I experimented with these parameters.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow proto tcp from 192.168.1.0/24 to 192.168.1.2 port 22 Rule added root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 192.168.1.2 22/tcp ALLOW 192.168.1.0/24 root@emachine:/home/jr018429#
I wanted to know how to restore default states to ufw. After reading several Web pages, I found ufw's 'reset' option. I experimented with it by setting some rules and then resetting ufw to see what the result of the reset would be. After resetting ufw, I performed 'ufw status'.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow 22/tcp Rule added Rule added (v6) root@emachine:/home/jr018429# ufw deny 23 Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 23 DENY Anywhere 22/tcp ALLOW Anywhere (v6) 23 DENY Anywhere (v6) root@emachine:/home/jr018429# ufw reset Resetting all rules to installed defaults. This may disrupt existing ssh connections. Proceed with operation (y|n)? y Backing up 'user.rules' to '/lib/ufw/user.rules.20120331_153139' Backing up 'after6.rules' to '/etc/ufw/after6.rules.20120331_153139' Backing up 'user6.rules' to '/lib/ufw/user6.rules.20120331_153139' Backing up 'before6.rules' to '/etc/ufw/before6.rules.20120331_153139' Backing up 'after.rules' to '/etc/ufw/after.rules.20120331_153139' Backing up 'before.rules' to '/etc/ufw/before.rules.20120331_153139' root@emachine:/home/jr018429# ufw status Status: inactive root@emachine:/home/jr018429#
ufw has logging capability. I is enabled by default, or at least on my system it was.
root@emachine:/home/jr018429# ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing) New profiles: skip root@emachine:/home/jr018429#
I turned logging on.
root@emachine:/home/jr018429# ufw logging on Logging enabled root@emachine:/home/jr018429#
Next, I turned logging off.
root@emachine:/home/jr018429# ufw logging off Logging disabled root@emachine:/home/jr018429#
I worked at getting a Web interface to communicate with my Arduino Duemilanove via USB. The Web interface is PHP.
Once the Web server was up and running, I was ready to develop the Web interface which will be used to both command the Arduino to control hardware, but also return data.
I found HTML and PHP code snippets on the Web which demonstrate the following:
I combined these code snippets to get the Arduino to return analog data to the Web interface. I then logged in as root and uploaded the php file to /var/www, the Web server directory.
Next, I compiled and uploaded some simple Arduino code to read analog input pin 0 and then write its value to the serial port.
Before, I could use the serial port, I had to add www-data to group dialout, the owner of ttyUSB0, the serial port.
root@emachine:/var/www# adduser www-data dialout
Lastly, I had to restart the Web server.
root@emachine:/var/www# /etc/init.d/apache2 restart
Here is the Web page with data returned from the Arduino. The Arduino has 10-bit A/D converters. This means that the value returned from the Arduino can range from 0 to 1023 dec. In order to give this range of values meaning, the values might need to be offset and scaled using what is known as zero-span. Zero-span or offset and scaling can be performed either by hardware (Op-amps) or software. After scaling and offsetting (if required) units must be attached to the value.
I found some PHP code on the Web which demonstrates how to open and read or write to a serial port. The link is posted on my <html><a href=“http://lab46.corning-cc.edu/user/jr018429/portfolio/WebServerandArduino.html”>Controlling Hardware Remotely via the Web</a></html>
Project page.
This is my rdArd.php file which does get analog data from pin 0 of my Arduino Duemilanove.
<html> <body> <form action="<?=$_SERVER['PHP_SELF'];?>" method="post"> <input type="submit" name="submit" value="Get A/D 0 Value"> </form> <?php if(isset($_POST['submit'])) { $fp = fopen("/dev/ttyUSB0", "r"); sleep(2); $data = intval(fgets($fp)); print $data; fclose($fp); } ?> </body> </html>
Here is the Web page with data returned from the Arduino. The Arduino has 10-bit A/D converters. This means that the value returned from the Arduino can range from 0 to 1023 dec.
When I logged in remotely to my emachine today, I noticed that there were 28 packages to be updated, 18 of which are security updates. I decided to perform an 'apt-get update, and then an apt-get upgrade. Updating an dupgrading the system is a common system maintenance task. Unfortunately, I was interrupted and didn't get to capture the 'apt-get upgrade':
login as: jr018429 jr018429@67.251.79.214's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ 28 packages can be updated. 18 updates are security updates. Last login: Mon Apr 2 06:51:40 2012 from portal.corning.com jr018429@emachine:~$ su Password: root@emachine:/home/jr018429# apt-get update Ign http://security.ubuntu.com oneiric-security InRelease Ign http://extras.ubuntu.com oneiric InRelease Ign http://us.archive.ubuntu.com oneiric InRelease Ign http://us.archive.ubuntu.com oneiric-updates InRelease Ign http://us.archive.ubuntu.com oneiric-backports InRelease Hit http://security.ubuntu.com oneiric-security Release.gpg Get:1 http://extras.ubuntu.com oneiric Release.gpg [72 B] Hit http://us.archive.ubuntu.com oneiric Release.gpg Hit http://us.archive.ubuntu.com oneiric-updates Release.gpg Hit http://security.ubuntu.com oneiric-security Release Hit http://us.archive.ubuntu.com oneiric-backports Release.gpg Hit http://us.archive.ubuntu.com oneiric Release Hit http://extras.ubuntu.com oneiric Release Hit http://us.archive.ubuntu.com oneiric-updates Release Hit http://us.archive.ubuntu.com oneiric-backports Release Hit http://security.ubuntu.com oneiric-security/main Sources Hit http://us.archive.ubuntu.com oneiric/main Sources Hit http://extras.ubuntu.com oneiric/main Sources Hit http://security.ubuntu.com oneiric-security/restricted Sources Hit http://security.ubuntu.com oneiric-security/universe Sources Hit http://security.ubuntu.com oneiric-security/multiverse Sources Hit http://security.ubuntu.com oneiric-security/main i386 Packages Hit http://security.ubuntu.com oneiric-security/restricted i386 Packages Hit http://us.archive.ubuntu.com oneiric/restricted Sources Hit http://us.archive.ubuntu.com oneiric/universe Sources Hit http://us.archive.ubuntu.com oneiric/multiverse Sources Hit http://us.archive.ubuntu.com oneiric/main i386 Packages Hit http://us.archive.ubuntu.com oneiric/restricted i386 Packages Hit http://us.archive.ubuntu.com oneiric/universe i386 Packages Hit http://security.ubuntu.com oneiric-security/universe i386 Packages Hit http://security.ubuntu.com oneiric-security/multiverse i386 Packages Hit http://security.ubuntu.com oneiric-security/main TranslationIndex Hit http://security.ubuntu.com oneiric-security/multiverse TranslationIndex Hit http://security.ubuntu.com oneiric-security/restricted TranslationIndex Hit http://extras.ubuntu.com oneiric/main i386 Packages Ign http://extras.ubuntu.com oneiric/main TranslationIndex Hit http://security.ubuntu.com oneiric-security/universe TranslationIndex Hit http://us.archive.ubuntu.com oneiric/multiverse i386 Packages Hit http://us.archive.ubuntu.com oneiric/main TranslationIndex Hit http://us.archive.ubuntu.com oneiric/multiverse TranslationIndex Hit http://us.archive.ubuntu.com oneiric/restricted TranslationIndex Hit http://us.archive.ubuntu.com oneiric/universe TranslationIndex Hit http://us.archive.ubuntu.com oneiric-updates/main Sources Hit http://us.archive.ubuntu.com oneiric-updates/restricted Sources Hit http://us.archive.ubuntu.com oneiric-updates/universe Sources Hit http://security.ubuntu.com oneiric-security/main Translation-en Hit http://security.ubuntu.com oneiric-security/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/multiverse Sources Hit http://us.archive.ubuntu.com oneiric-updates/main i386 Packages Hit http://us.archive.ubuntu.com oneiric-updates/restricted i386 Packages Hit http://us.archive.ubuntu.com oneiric-updates/universe i386 Packages Hit http://us.archive.ubuntu.com oneiric-updates/multiverse i386 Packages Hit http://us.archive.ubuntu.com oneiric-updates/main TranslationIndex Hit http://us.archive.ubuntu.com oneiric-updates/multiverse TranslationIndex Hit http://us.archive.ubuntu.com oneiric-updates/restricted TranslationIndex Hit http://security.ubuntu.com oneiric-security/restricted Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/universe TranslationIndex Hit http://us.archive.ubuntu.com oneiric-backports/main Sources Hit http://us.archive.ubuntu.com oneiric-backports/restricted Sources Hit http://us.archive.ubuntu.com oneiric-backports/universe Sources Hit http://us.archive.ubuntu.com oneiric-backports/multiverse Sources Hit http://us.archive.ubuntu.com oneiric-backports/main i386 Packages Hit http://us.archive.ubuntu.com oneiric-backports/restricted i386 Packages Hit http://security.ubuntu.com oneiric-security/universe Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/universe i386 Packages Hit http://us.archive.ubuntu.com oneiric-backports/multiverse i386 Packages Hit http://us.archive.ubuntu.com oneiric-backports/main TranslationIndex Hit http://us.archive.ubuntu.com oneiric-backports/multiverse TranslationIndex Hit http://us.archive.ubuntu.com oneiric-backports/restricted TranslationIndex Hit http://us.archive.ubuntu.com oneiric-backports/universe TranslationIndex Hit http://us.archive.ubuntu.com oneiric/main Translation-en Hit http://us.archive.ubuntu.com oneiric/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric/restricted Translation-en Hit http://us.archive.ubuntu.com oneiric/universe Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/main Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/restricted Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/universe Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/main Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/restricted Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/universe Translation-en Ign http://extras.ubuntu.com oneiric/main Translation-en_US Ign http://extras.ubuntu.com oneiric/main Translation-en Fetched 72 B in 2s (33 B/s) Reading package lists... Done root@emachine:/home/jr018429#
I wanted to automate apt-get update and apt-get upgrade if possible. I did not want to perform these tasks manually, and I wanted do perform this task on a regular schedule. I did use a tool in HPC0 to check if a process, an irc robot, was running and if it was not, to restart it. I used crontab successfully to perform this task. I thought ccontab would be the perfect candidate for this project.
I researched the following articles and blogs to figure out how best to carry out automating apt-get update and upgrade:
I e-mailed my instructor regarding the use of crontab to automate apt-get update and apt-get upgrade. Here is his reply:
Me: On Apr 3, 2012, at 7:02 AM, Rine, John T wrote: I am running Ubuntu 11.10 on my emachine. I get annoyed being told, when I log on the command line, that there are security and other updates pending. Yes, one could simply perform an apt-get update and apt-get upgrade, however, we are being trained to be systems analysists, etc. So why not automate these tasks?? Matt: John, The only risk with auto-updating, is if there is a problem, or something that requires a restart or relaunching of an app, it could appear to cause stability problems, and becomes an unknown variable when trying to figure out just what has changed. There's also the notion that just because there are updates, that does not necessitate the need to immediately apply them. The current setup isn't obsolete, it still works as well as it did before knowledge of the update was available.\\ Me: In fact, Ubuntu has tools specifically for automating updates, but I would rather go old school….I want to use crontab. My crontab, however, has an issue. It doesn’t like ‘root’. Matt: Depending on what crontab you are updating (system-wide?), the syntax with respect to the user is different. If you are editing root's personal crontab (via running "crontab -e" as root), you do NOT need to put in "root". Me: For example if I do this: * * * * * root echo “cron was here on $(date)” >> /home/jr018429/myLog Matt: Careful... "* * * * *" means run EVERY minute of EVERY hour of EVERY day of EVERY month, EVERY day of the week. At the very least, be more conservative on the hours and minutes... perhaps just once a day... 25 */12 * * * (echo “cron was here on $(date)” >> /home/jr018429/myLog) This will run it on the 25th minute every 12 hours. -Matthew -- Matthew Haas Instructor Corning Community College Computer & Information Science http://lab46.corning-cc.edu/haas/home/ "Thinking ... is no more and no less an organ of perception than the eye or ear. Just as the eye perceives colours and the ear sounds, so thinking perceives ideas." -- Rudolf Steiner
I did in fact know that I was asking cron to perform an action every minute. I was testing and I didn't want to wait. I believe that the actual time to perform an apt-get update on my system took less than one minute. If I were to have cron perform apt-get update on a regular basis, I would set cron to perform it once every 24 hours and only at a time when I wouldn't be using the system. Later, I increased one minute to five.
Okay, maybe it isn't a good idea to automate these apt-gets, but the fact remains, I couldn't get crontab to execute anything requiring root privleges. So I continued to use apt-get update as an instrument for testing of cron as I could not think of any other Linux command requiring root access to use.
It turns out that there are three different types of crontab files; there are regular user, root user, and system crontab. The system crontab is located in /etc/crontab.
This is what a system croontab looks like:
# /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --repo$ 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --repo$ 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --repo$ #
This is my root crontab I used to experiment with using a crontab to perform a command requiring root privleges:
# Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any').# # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command #* * * * * echo "Hello test 1, 2" >> /home/jr018429/myLog #*/5 * * * * /usr/bin/apt-get update > /dev/null 2>&1 */3 * * * * /usr/bin/apt-get update > /home/jr018429/cronUpdate 2> /home/jr018429/cronUpdateErr
This is the contents of the 'cronUpdate' file after the root cron executed:
Ign http://security.ubuntu.com oneiric-security InRelease Ign http://us.archive.ubuntu.com oneiric InRelease Ign http://us.archive.ubuntu.com oneiric-updates InRelease Ign http://extras.ubuntu.com oneiric InRelease Ign http://us.archive.ubuntu.com oneiric-backports InRelease Hit http://security.ubuntu.com oneiric-security Release.gpg Hit http://us.archive.ubuntu.com oneiric Release.gpg Hit http://extras.ubuntu.com oneiric Release.gpg Hit http://security.ubuntu.com oneiric-security Release Hit http://us.archive.ubuntu.com oneiric-updates Release.gpg Hit http://extras.ubuntu.com oneiric Release Hit http://us.archive.ubuntu.com oneiric-backports Release.gpg Hit http://security.ubuntu.com oneiric-security/main Sources Hit http://us.archive.ubuntu.com oneiric Release Hit http://extras.ubuntu.com oneiric/main Sources Hit http://security.ubuntu.com oneiric-security/restricted Sources Hit http://security.ubuntu.com oneiric-security/universe Sources Hit http://security.ubuntu.com oneiric-security/multiverse Sources Hit http://security.ubuntu.com oneiric-security/main i386 Packages Hit http://security.ubuntu.com oneiric-security/restricted i386 Packages Hit http://us.archive.ubuntu.com oneiric-updates Release Hit http://extras.ubuntu.com oneiric/main i386 Packages Ign http://extras.ubuntu.com oneiric/main TranslationIndex Hit http://security.ubuntu.com oneiric-security/universe i386 Packages Hit http://security.ubuntu.com oneiric-security/multiverse i386 Packages Hit http://security.ubuntu.com oneiric-security/main TranslationIndex Hit http://security.ubuntu.com oneiric-security/multiverse TranslationIndex Hit http://security.ubuntu.com oneiric-security/restricted TranslationIndex Hit http://us.archive.ubuntu.com oneiric-backports Release Hit http://security.ubuntu.com oneiric-security/universe TranslationIndex Hit http://us.archive.ubuntu.com oneiric/main Sources Hit http://us.archive.ubuntu.com oneiric/restricted Sources Hit http://us.archive.ubuntu.com oneiric/universe Sources Hit http://us.archive.ubuntu.com oneiric/multiverse Sources Hit http://us.archive.ubuntu.com oneiric/main i386 Packages Hit http://us.archive.ubuntu.com oneiric/restricted i386 Packages Hit http://security.ubuntu.com oneiric-security/main Translation-en Hit http://security.ubuntu.com oneiric-security/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric/universe i386 Packages Hit http://us.archive.ubuntu.com oneiric/multiverse i386 Packages Hit http://us.archive.ubuntu.com oneiric/main TranslationIndex Hit http://us.archive.ubuntu.com oneiric/multiverse TranslationIndex Hit http://us.archive.ubuntu.com oneiric/restricted TranslationIndex Hit http://us.archive.ubuntu.com oneiric/universe TranslationIndex Hit http://us.archive.ubuntu.com oneiric-updates/main Sources Hit http://us.archive.ubuntu.com oneiric-updates/restricted Sources Hit http://security.ubuntu.com oneiric-security/restricted Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/universe Sources Hit http://us.archive.ubuntu.com oneiric-updates/multiverse Sources Hit http://us.archive.ubuntu.com oneiric-updates/main i386 Packages Hit http://us.archive.ubuntu.com oneiric-updates/restricted i386 Packages Hit http://us.archive.ubuntu.com oneiric-updates/universe i386 Packages Hit http://security.ubuntu.com oneiric-security/universe Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/multiverse i386 Packages Hit http://us.archive.ubuntu.com oneiric-updates/main TranslationIndex Hit http://us.archive.ubuntu.com oneiric-updates/multiverse TranslationIndex Hit http://us.archive.ubuntu.com oneiric-updates/restricted TranslationIndex Hit http://us.archive.ubuntu.com oneiric-updates/universe TranslationIndex Hit http://us.archive.ubuntu.com oneiric-backports/main Sources Hit http://us.archive.ubuntu.com oneiric-backports/restricted Sources Hit http://us.archive.ubuntu.com oneiric-backports/universe Sources Hit http://us.archive.ubuntu.com oneiric-backports/multiverse Sources Hit http://us.archive.ubuntu.com oneiric-backports/main i386 Packages Hit http://us.archive.ubuntu.com oneiric-backports/restricted i386 Packages Hit http://us.archive.ubuntu.com oneiric-backports/universe i386 Packages Hit http://us.archive.ubuntu.com oneiric-backports/multiverse i386 Packages Hit http://us.archive.ubuntu.com oneiric-backports/main TranslationIndex Hit http://us.archive.ubuntu.com oneiric-backports/multiverse TranslationIndex Ign http://extras.ubuntu.com oneiric/main Translation-en_US Hit http://us.archive.ubuntu.com oneiric-backports/restricted TranslationIndex Hit http://us.archive.ubuntu.com oneiric-backports/universe TranslationIndex Hit http://us.archive.ubuntu.com oneiric/main Translation-en Hit http://us.archive.ubuntu.com oneiric/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric/restricted Translation-en Ign http://extras.ubuntu.com oneiric/main Translation-en Hit http://us.archive.ubuntu.com oneiric/universe Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/main Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/restricted Translation-en Hit http://us.archive.ubuntu.com oneiric-updates/universe Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/main Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/multiverse Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/restricted Translation-en Hit http://us.archive.ubuntu.com oneiric-backports/universe Translation-en Reading package lists...
So as one can see, the root crontab did in fact perform the apt-get update.
Futhermore, there were no errors as the cronUpdateErr file was empty.
Also as an extra check,I looked at the output to the /var/log/syslog file (look at the last lines):
Apr 3 20:26:43 emachine crontab[15052]: (root) BEGIN EDIT (root) Apr 3 20:26:54 emachine crontab[15052]: (root) REPLACE (root) Apr 3 20:26:54 emachine crontab[15052]: (root) END EDIT (root) Apr 3 20:27:01 emachine cron[865]: (root) RELOAD (crontabs/root) Apr 3 20:27:01 emachine CRON[15065]: (root) CMD (/usr/bin/apt-get update > /home/jr018429/cronUpdate 2> /home/jr018429/cronUpdateErr) Apr 3 20:28:01 emachine kernel: [135808.618520] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:28:08 emachine kernel: [135815.048854] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:30:01 emachine CRON[15089]: (root) CMD (/usr/bin/apt-get update > /home/jr018429/cronUpdate 2> /home/jr018429/cronUpdateErr) Apr 3 20:30:06 emachine kernel: [135933.631203] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:30:12 emachine kernel: [135939.421560] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:32:11 emachine kernel: [136058.643422] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:32:14 emachine kernel: [136060.693473] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:33:01 emachine CRON[15113]: (root) CMD (/usr/bin/apt-get update > /home/jr018429/cronUpdate 2> /home/jr018429/cronUpdateErr) Apr 3 20:34:17 emachine kernel: [136183.656518] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:34:18 emachine kernel: [136185.486488] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:36:01 emachine CRON[15137]: (root) CMD (/usr/bin/apt-get update > /home/jr018429/cronUpdate 2> /home/jr018429/cronUpdateErr) Apr 3 20:36:22 emachine kernel: [136308.670378] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:36:22 emachine kernel: [136308.830270] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:38:27 emachine kernel: [136433.684046] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:38:27 emachine kernel: [136434.193908] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:39:01 emachine CRON[15172]: (root) CMD (/usr/bin/apt-get update > /home/jr018429/cronUpdate 2> /home/jr018429/cronUpdateErr) Apr 3 20:39:01 emachine CRON[15173]: (root) CMD ( [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete) Apr 3 20:40:32 emachine kernel: [136558.696954] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:40:37 emachine kernel: [136564.377236] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:42:01 emachine CRON[15201]: (root) CMD (/usr/bin/apt-get update > /home/jr018429/cronUpdate 2> /home/jr018429/cronUpdateErr) Apr 3 20:42:37 emachine kernel: [136683.709958] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:42:46 emachine kernel: [136692.800715] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:44:42 emachine kernel: [136808.723407] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:01:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:44:50 emachine kernel: [136816.973882] [UFW BLOCK] IN=eth0 OUT= MAC=01:00:5e:00:00:fb:58:6d:8f:ad:97:af:08:00 SRC=192.168.1.1 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=2 Apr 3 20:45:01 emachine CRON[15225]: (root) CMD (/usr/bin/apt-get update > /home/jr018429/cronUpdate 2> /home/jr018429/cronUpdateErr)
As one can see, the root crontab executed without errors.
Regarding my <html><a href=“http://lab46.corning-cc.edu/user/jr018429/portfolio/WebServerandArduino.html”>Controlling Hardware Remotely via the Web</a></html> I have been experiencing issues with the serial communication between my microcontroller and the Web server. I have to place a delay in the PHP file to get the microcontroller to return an analog value. I found some information on the Web regaring this issue.
I researched the following articles and blogs to find out about serial communications and related issues:
My web server machine had been off for a few days, and I wanted to get back to working with PHP, HTML, and my Arduino.
I found however, that I couldn't get the Arduino to return data via PHP.
I checked the port parameters for the Arduino in Linux:
root@emachine:/var/www# stty -F /dev/ttyUSB0 speed 115200 baud; line = 0; eof = ^A; min = 1; time = 0; -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke
My arduino's serial port is set to 9600 baud but the serial port on the Linux side is set to 115200 baud so I decided to write a test PHP file to set the serial port baud rate:
<? //Valid baud rates: //110 //150 //300 //600 //1200 //2400 //4800 //9600 //19200 //38400 //57600 //115200 exec("stty -F /dev/ttyUSB0 9600"); ?>
When I exectued this PHP file from my Web browser and then checked the serial port attached to the Arduino again, I found that it had chenged.
root@emachine:/var/www# stty -F /dev/ttyUSB0 speed 9600 baud; line = 0; eof = ^A; min = 1; time = 0; -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke root@emachine:/var/www#
After changing the baud rate be execting my php file via the Web browser, http://192.168.1.2/setBaudPHP.php, I was able to get data again! I added the contents of the setBaudPHP.php to the my original PHP file rdArd.php:
<html> <body> <form action="<?=$_SERVER['PHP_SELF'];?>" method="post"> <input type="submit" name="submit" value="Get A/D 0 Value"> </form> <?php if(isset($_POST['submit'])) { //Valid baud rates: //110 //150 //300 //600 //1200 //2400 //4800 //9600 //19200 //38400 //57600 //115200 exec("stty -F /dev/ttyUSB0 9600"); $fp = fopen("/dev/ttyUSB0", "r"); //sleep(2); $data = intval(fgets($fp)); print $data; fclose($fp); } ?> </body> </html>
To verify that the revised rdArd.php file actually works, I changed the serial port back to 115200 baud:
root@emachine:/var/www# stty -F /dev/ttyUSB0 speed 9600 baud; line = 0; eof = ^A; min = 1; time = 0; -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke root@emachine:/var/www# stty -F /dev/ttyUSB0 115200 root@emachine:/var/www# stty -F /dev/ttyUSB0 speed 115200 baud; line = 0; eof = ^A; min = 1; time = 0; -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke root@emachine:/var/www#
Next, I executed the rdArd.php file from my Web browser and found that analog data was returned and the baud rate of serial port connected to the Arduino was changed to match the baud rate set in the Arduino:
root@emachine:/var/www# stty -F /dev/ttyUSB0 speed 115200 baud; line = 0; eof = ^A; min = 1; time = 0; -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke root@emachine:/var/www# stty -F /dev/ttyUSB0 speed 9600 baud; line = 0; eof = ^A; min = 1; time = 0; -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke root@emachine:/var/www#
I noticed that sometimes the analog value returned is 0, usually after it hasn't been queried for a while. Normally the data returned without anything input to analog pin 0 on the Arduino is between 500 and 700.
I wanted to see if I could cat the serial device, ttyUSB0, so I tried:
root@emachine:/var/www# cat /dev/ttyUSB0 4Sj)ÿ46Lá4Cá4LCá4¦SHü43Cá4NCá42Cá42MCá4Cá^C
Typical serial port parameters are 8N1 or databits-8, No parity, and 1 stop bit. I experimented with combinations of data, and stop bits as well as changing parity setting so that I could possibly explain the gibberish.
Setting data bits to 7:
root@emachine:/var/www# stty -F /dev/ttyUSB0 cs7 root@emachine:/var/www# cat /dev/ttyUSB0 474 459 447 441 ^C root@emachine:/var/www#
No more gibberish!
After getting the PHP to return data from my Arduino Duelimenove, I noticed that the data returned varied from 400's to 700's (The arduino has 10-bit analog inputs which can vary from 0 to 1023 (decimal)). Furthermore, I noticed that the data read from the Arduino using 'cat /dev/ttyUSB0' differed from what was returned via PHP; the PHP data varying by a power of 2 in some cases. I could not explain what was causing these issues but I read that there was an issue with the serial communications between the Arduino and other devices:
I decided to give the modification described on Arduino.cc's 'DisablingAutoRestOnDerialConnection' Web page a try.
After installing a 120 ohm resistor between reset and +5v header pins, the values read from the Arduino via the USB port using 'cat /dev/ttyUSB0' closely matched the values returned using PHP, and the values returned using PHP were consitently in the 400 range; no more data ranging from 400's to 700's.
I e-mailed my instructor to let him know what I found.
from: John Rine jr018429@lab46.corning-cc.edu to: wedge@lab46.corning-cc.edu, haas@corning-cc.edu, JohnRineTech@gmail.com, rinejt@corning.com date: Sun, Apr 8, 2012 at 1:16 PM subject: Microcontrollers, Radio Shack, and other stuff Matt, Radio Shack has seen the light, they are carrying Arduino: http://www.radioshack.com/uc/index.jsp?page=researchLibraryArticle&articleUrl=../graphics/uc/rsk/USContent/HTML/pages/microcontroller.html&noBc=true http://www.radioshack.com/family/index.jsp?categoryId=12360923&ab=microcontrollerLP http://www.radioshack.com/family/index.jsp?categoryId=12316880&ab=microcontrollerLP Not that I would buy from them, but you have to give 'em credit.. Besides Arduino, they have Parallax products: http://www.radioshack.com/uc/index.jsp?page=researchLibraryArticle&articleUrl=../graphics/uc/rsk/USContent/HTML/pages/microcontroller.html&noBc=true PS, I got my Arduino to return analog data correctly through my Web server using PHP. To do so, I had to load a Web server on a machine local to my network. Since I was using PHP, I also had to load PHP5. Next, since I wanted Web access outside my network, I had to forward a port, port 80, to my Web serving machine. I wanted to also remotely administer this machine via SSH, so I forwarded port 22 to this machine as well. I also wanted security so I enabled utw. Since by default ufw blocks everything, I had to allow ports 80 and 22. Next, I wrote and loaded a sketch to my Arduino. The sketch reads an analog port pin, stores its value in a variable, and writes it to the serial port; next, it waits one second and begins again. My Arduino file, rdAna.pde: int anaVal = 0; void setup() { Serial.begin(9600); } void loop() { anaVal = analogRead(0); //pin 0 Serial.println(anaVal); delay(1000); } my PHP file, rdArd.php: <?php $fp = fopen("/dev/ttyUSB0", "r"); //intval() causes "" to be returned as 0 $data = intval(fgets($fp))`; print $data; fclose($fp); ?> Next, plug the address and file into the Web browser: 192.168.1.2/rdArd.php To read the next value, simply refresh the browser. At first, this didn't work. I couldn't even cat /dev/ttyUSB0 to read data from the Arduino. I performed a stty -F /dev/ttyUSB0 and found that the default port baud rate for ttyUSB0 was 115200. I changed the port parameters for ttyUSB0 to 9600/8N1 using the folloing invocations of stty: stty 9600 cs8 -parenb -cstopb < /dev/ttyUSB0 or stty -F /dev/ttyUSB0 9600 cs8 -parenb -cstop After setting the port, I was able to 'cat /dev/ttyUSB0' and get data from the PHP page, however, the data at the php page didn't match the data returned from 'cat'. It differed by one 2^x order of magnitude! Next, I found that my Arduino Duelimanove has an autoreset feature which when serial communications occur with the Arduino, it performs an autoreset of its microcontroller! This feature causes the microcontroller to be reset after a sketch has been uploaded so that the boot loader will be invoked, and will cause the sketch to run immediately in the Arduino. If the Arduino is being used for serial communication, and if the autorest feature is causing issues with serial communications, it is recommended that the autoreset feature be disabled. One way to disable the autoreset feature is to place a 120 ohm resistor between 'Reset' and '+5' on the Arduino's edge connector (there are other ways as well). It didn't seem to me that would have an effect, as I could get data from cat /dev/ttyUSB0 and from my PHP page, but it after I added the 120 resistor to my Arduino, the data matched the data from cat, and the data from cat was more consistent than before. Success!!!!!!!!!!! I don't know what to do next. I see there is an Ethernet shield for the Arduino. why have a Web server on a PC?? If your application is small enough, use an Arduino with an Ethernet shield. If you get the Ethernet Shield, you can learn more about the hardware. The shield I read, has a slot for a camera memory stick, COOL!!!! I want to hook up my Arduino Mega to the Web server (it has an LCD, Keypad, Stepper driver/motor) and drive the motor from the Web. Simple modifications. Arduino only has a serial.read function so you have to repeadily read into an array or concatenate a string I suppose and then do an atoi(string) to convert the string to integer data to pass to the motor stepping function. Another cool thing about this project, is that one can get data from the Arduino over the Internet using a smart phone of tablet without an Ap, correct? John T. Rine --- Lab46: Penguin Powered
I downloaded and installed the Arduino 1.0 IDE for Windows. Next, I assembled the Arduino Uno and the Ethernet shield. I plugged one end of the USB programming cable into the Arduino Uno and the other end into the computer on which I installed the Arduino 1.0 IDE. Installing the device driver is a little bit on a pain; after plugging the Arduino's USB cable into the computer used to develop sketches, let the driver install fail, then go to device manager, select the unknown device, select browse the computer for the device driver. On this pop-up, enter the path to the Arduino driver library (and not the FTDI folder-this is an Uno and does not use the FTDI chip) and let it find the driver. After successfully installing the driver for the Arduino Uno, I opened one of the example sketches, File→Examples→Basics→Blink. Next, I complied this 'sketch',
sketch→verify/compile. Lastely, I uploaded the compiled sketch to the Arduino, file→upload. The Arduino's yellow led blinked once per second, success!
Next, I found a Ethernet example, file→examples→Ethernet→Web server, and opend it in the Arduino IDE. I changed the mach address to the address listed on the sticker on the front of the Ethernet shield's container. I also changed the IP address tio an open address on my home network-192.168.1.3. I complied the sketch and uploaded it to the Arduino. I plugged one end
of a spare Ethernet cable into the router; I plugged the other end of the cable into Ethernet shield. Lastly, I plugged a power supply (wall wart) into the Arduino's power connector. The LEDs on the Arduino and Ethernet shield came on. I pointed my broswer to the Arduino. I read values returned from 4 of the Arduino's analog inputs, Cool!!!
I haven't yet forwarded a port to the Arduino Web server to expose it to the outside world; right now, it is only accessible from inside my network.
After getting the Arduino Web server to work, I added it as a new project to my portfolio. I plan to add hardware control and improve the server. The Ethernet shield also has a connector for an SD card on which data can be stored.
A void pointer is a generic pointer that can be used to point to any datatype.
Because it is a generic pointer, before it can be dereferenced, it must be cast to the appropriate type.
Also because a void pointer is a generic pointer, no pointer arithmetic may be performed on it.
In C++ void references are not allowed.
//voidptr.c //John T. Rine //September 17, 2011 #include<stdio.h> int main(int argc, char **argv) { void *pVoid; int *pInteger; float *pFloatingPoint; char *pCharacter; int integer; float floatingPoint; char character; integer = -5; floatingPoint = 1298.1234; character = 'Z'; pVoid = &integer; pInteger = (int *)pVoid; printf("%d\n",*pInteger); pVoid = &floatingPoint; pFloatingPoint = (float *)pVoid; printf("%4.4f\n",*pFloatingPoint); pVoid = &character; pCharacter = (char *)pVoid; printf("%c\n",*pCharacter); return 0; }
lab46:~/src/data$ gcc voidptr.c -o voidptr lab46:~/src/data$ ./voidptr -5 1298.1234 Z lab46:~/src/data$
A Null Pointer is a pointer which has been set to a specific value, known as NULL, that is not a valid address on a target system.
Pointers can be tested for null. Doing so is used to indicate whether a pointer points to a valid memory address or not. The success of testing pointers for NULL is dependent on the programmer setting pointers to null when they are not pointing to a valid memory address. Some programming languages automatically set pointers to null when they are declared.
//nulPtr.c //John T. Rine //September 24, 2011 #include<stdio.h> int main(int argc, char **argv) { int *iptr; int i = 10; printf("iptr value after declaring it: 0x%x\n", iptr); iptr = NULL; printf("iptr value after setting to NULL: 0x%x\n", iptr); iptr = &i; printf("iptr value after setting to address of i: 0x%x\n", iptr); printf("The value pointed to by iptr is: %d\n", *iptr); iptr = NULL; printf("iptr value after setting to back to NULL: 0x%x\n", iptr); return 0; }
lab46:~/src/data$ gcc nullPtr.c -o nullPtr lab46:~/src/data$ ./nullPtr iptr value after declaring it: 0x0 iptr value after setting to NULL: 0x0 iptr value after setting to address of i: 0x488c58c4 The value pointed to by iptr is: 10 iptr value after setting to back to NULL: 0x0 lab46:~/src/data$
Pointers to pointers are pointers which hold the address of another pointer. In other words, a pointer to a pointer points to another pointer. When a pointer to a pointer is dereferenced once, the address pointed to is returned. When it is dereferenced again, the value at the address pointed to by the pointer being pointed to by the pointer to a pointer is returned. See the code and console output below.
//pToP.c //John T. Rine //September 27, 2011 #include<stdio.h> int main(int argc, char **argv) { char **p = NULL; char *q = NULL; char i = 25; q = &i; p = &q; printf("Address of i = 0x%x\n", &i); printf("Value in i = %d\n", i); printf("Address of q = 0x%x\n",&q); printf("Value in q = 0x%x\n", q); printf("Value pointed to by q = %d\n", *q); printf("Address of p = 0x%x\n", &p); printf("The value in p = 0x%x\n", p); printf("Value in *p = 0x%x\n", *p); printf("value pointed to through double indirection = %d\n",**p); getchar(); return 0; }
address of i = 0x22ff47 Value in i = 25 Address of q = 0x22ff48 Value in q = 0x22ff47 Value pointed to by q = 25 Address of p = 0x22ff4c The value in p = 0x22ff48 Value in *p = 0x22ff47 value pointed to through double indirection = 25
Pointers to pointers can be used as a function parameter when a function must change the address contained in a pointer external to the function. Pointers to pointers can also be used to access individual elements of a multidimensional array, an array of strings for example.
//argv.c //John T. Rine //9/26/2011 #include<stdio.h> int main(int argc, char **argv) { int i; char * inputString = NULL; if (argc > 1) { for(i = 1; i < argc; i++) { int count = 0; while(*(*(argv + i) + count) != '\0') { printf("%c\n",*(*(argv + i) + count)); ++count; } } } else printf("No command line arguments were supplied after the file name\n"); return(0); }
C:\MinGW\programs-jr>argv.exe dog cat d o g c a t C:\MinGW\programs-jr>
Pointers may be incremented, decremented, added to or subtracted from, compared and assigned. When incrementation is performed, the address pointed to afterwards is current address plus the data type size in bytes. When decrementation is performed, the address pointed to afterwards is current address minus the data type size in bytes. When a pointer is added to by an integer type, the address pointed to afterwards is the current address plus the number being added multiplied by the data type size in bytes. When a pointer is being subtracted from, the address pointed to afterwards is the current address plus the number being subtracted multiplied by the data type size in bytes. When an assignment is being carried out, the value of the pointer afterward is the value being assigned.
//ptrMath.c //John T. Rine //September 29, 2011 #include<stdio.h> int main(int argc, char **argv) { int integer = 12345; printf("integer = %d\n", integer); printf("The address of integer is 0x%x\n", &integer); printf("\n"); printf("Assigning NULL to intPtr...\n"); int * intPtr = NULL; printf("Checking the value of intPtr...\n"); if(intPtr == NULL) printf("intPtr == NULL\n"); else printf("intPtr != NULL\n"); printf("\n"); printf("Setting intPtr to the address of integer...\n"); intPtr = &integer; printf("The address of intPtr is 0x%x\n", intPtr); printf("\n"); printf("The size of the int data type is %d\n", sizeof(int)); printf("Incrementing intPtr...\n"); intPtr++; printf("The address of intPtr is 0x%x\n", intPtr); printf("\n"); printf("Decrementing intPtr...\n"); intPtr--; printf("The address of intPtr is 0x%x\n", intPtr); printf("\n"); printf("Adding 10 to intPtr...\n"); intPtr += 10; printf("The address of intPtr is 0x%x\n", intPtr); printf("\n"); printf("Subtracting 10 from intPtr...\n"); intPtr -= 10; printf("The address of intPtr is 0x%x\n", intPtr); return 0; }
C:\MinGW\programs-jr>gcc ptrMath.c -o ptrMath C:\MinGW\programs-jr>ptrMath integer = 12345 The address of integer is 0x22ff18 Assigning NULL to intPtr... Checking the value of intPtr... intPtr == NULL Setting intPtr to the address of integer... The address of intPtr is 0x22ff18 The size of the int data type is 4 Incrementing intPtr... The address of intPtr is 0x22ff1c Decrementing intPtr... The address of intPtr is 0x22ff18 Adding 10 to intPtr... The address of intPtr is 0x22ff40 Subtracting 10 from intPtr... The address of intPtr is 0x22ff18 C:\MinGW\programs-jr>
Structure pointers contain the addresses of structures. The address of a structure may be obtained in the same way as an address of any other data type, through the use of the address of operator (ampersand). There are two forms of syntax with which to derefence the members of a structure: struct→member, or (*struct).member.
Structure pointers are very important in programmming as they are the linking mechanism used to connect nodes of a data structure. For usage of structure pointers, assignment and dereferencing, see the code and console output below.
//John T. Rine //September 28, 2011 //structPtr.c #include<stdio.h> struct Test { char c; int i; float f; }; typedef struct Test test; int main(int argc, char **argv) { test * structPtr; test testStruct; testStruct.c = 'Z'; testStruct.i = 54321; testStruct.f = 123.4567; structPtr = &testStruct; printf("The address of testStruct is 0x%x\n", structPtr); printf("The address of testStruct.c (&testStruct.c) is 0x%x\n", &testStruct.c); printf("The value at the address dereferenced by (*strucktPtr).c is %c\n", (*structPtr).c ); printf("The value at the address dereferenced by strucPtr->c is %c\n", structPtr->c); printf("\n"); printf("The address of testStruct.i (&testStruct.i) is 0x%x\n", &testStruct.i); printf("The value at the address dereferenced by (*strucktPtr).i is %c\n", (*structPtr).i ); printf("The value at the address dereferenced by strucPtr->i is %c\n", structPtr->i); printf("\n"); printf("The address of testStruct.f (&testStruct.f) is 0x%x\n", &testStruct.f); printf("The value at the address dereferenced by (*strucktPtr).f is %f\n", (*structPtr).f ); printf("The value at the address dereferenced by strucPtr->f is %f\n", structPtr->f); getchar(); //Keep the console window open in Windows return 0; }
C:\MinGW\programs-jr>gcc structPtr.c -o structPtr C:\MinGW\programs-jr>structPtr The address of testStruct is 0x22ff10 The address of testStruct.c (&testStruct.c) is 0x22ff10 The value at the address dereferenced by (*strucktPtr).c is Z The value at the address dereferenced by strucPtr->c is Z The address of testStruct.i (&testStruct.i) is 0x22ff14 The value at the address dereferenced by (*strucktPtr).i is 1 The value at the address dereferenced by strucPtr->i is 1 The address of testStruct.f (&testStruct.f) is 0x22ff18 The value at the address dereferenced by (*strucktPtr).f is 123.456703 The value at the address dereferenced by strucPtr->f is 123.456703
A function pointer points to a function rather than data. Function pointers are used to simplify code to select a function to execute based on values during run-time. Function pointers can be used
to replace switch/if-statements. An important rule regarding function pointers is that the functions a function pointer points to must have the same signature and return type.
Pushing is the act of placing a value into the top of the stack and incrementing the stack pointer to point to the next address. When the push function is performed on the stack, the address pointed to by the stack pointer gets data, it will become the new top of the stack and the stack pointer is incremented to point to the next address. With linked-list implemented stacks, if no list exists a node is created and the data to be pushed is placed into it. If a list exists, a new node is tacked onto the end of the list, head or tail, and the data to be pushed is polaced into it. This node becomes the new head or tail.
Popping is the act of copying the value at the top of the stack and decrementing the stack pointer to point to the last address. When the pop function is performed on the stack, data at the location pointed to by the stack pointer is copied from the stack and the stack pointer is decremented to point to the address from where the data was just copied. This location becomes the new top of the stack. With linked-list implemented stacks, after the data has been retrieved, the node that was the top of the stack is freed and the node that was pointed to by the node that was just freed becomes the new top of the stack; it also becomes the new head or tail of the list depending on which end of the list things are being pushed to and popped from.
The definition of user space is the area of system memory in which user processes execute. It is does not include the part of system memory where the kernel, or the operating system's core, runs. In fact, the kernel manages system resources and is the interface between user processes and the system's hardware.
The definition of Kernel space is the area of system memory where the Kernel, the system manager, executes. User processes (applications) do not have direct access to the system's hardware; they have to request access from the Kernel. In this way, user processes cannot interfere with each other or the Kernel for that matter.
A thread is the smallest unit of computing that can be assigned to a process by the operating system. Muliple threads can execute within a single process. A process being an instance of a computer application or program being executed by an operating system that has the ability to execute multiple programs at the same time. Threads were created to so that a process would have the capability of performing several actions at the same time.
Multithreading is the ability of an operating system to run a few or several parts of a computer application at the same time. Through the use of multithreading, can be used to control multiple streams of input to an application. Further, tasks that have a low priority can be run in a thread in the background.
A Semaphore is an operating system variable which all processes executing on the system have access to. It prevents processes from using system resources at the same time. A process using a system resource sets a semaphore and when other processes are preparing to use that resource, they check the state of the semaphore, if it is set, they wait until the process using the resource resets the semaphore signaling that the resource is now available.
Streams are input and output channels between computer applications, the operating system and I/O devices. The three I/O channels are called: standard input (stdin), standard output (stdout) and standard error (stderr).
A file descriptor is a connection between a process and a file. In Unix/Linux operating systems, it is created through the open system call.
The file descriptor is an index into an operating system data structure which encapsulates the details of all open files.
A process that has completed execution but still has an entry in the process table.
Maintenance is performed by checking the system (logs etc.) to verify that the system is functioning properly and then performing any required updates and upgrades; maintenance is usually carried out on a regular or semi-regular basis.
Common Linux maintenance tasks include:
Logging is the act of collecting information or data through automated means; data can be collected only when particular events occur or it can be collected periodically. Once the data has been collected it is usually stored in a non-volatile storage medium such a hard drive. Once the data has been stored, it can be analysed at a later time.
Most log files are located in the /var/log directory (and subdirectories). An adminstrator must be the root user in order to gain access to this directory.
To navigate to the logs directory, use the following cd command command line invocation: # cd /var/logs
To view log file messages, use any one of the following command line command invocations:
# tail -f /var/log/messages
# less /var/log/messages
# more -f /var/log/messages
# vi /var/log/messages
Typical Linux log files and their paths are:
/var/log/message-General message and system related stuff
/var/log/auth.log-Authenication logs
/var/log/kern.log-Kernel logs
/var/log/cron.log-Crond logs (cron job)
/var/log/maillog-Mail server logs
/var/log/qmail/-Qmail log directory (more files inside this directory)
/var/log/httpd/-Apache access and error logs directory
/var/log/lighttpd-Lighttpd access and error logs directory
/var/log/boot.log-System boot log
/var/log/mysqld.log-MySQL database server log file
/var/log/secure-Authentication log
/var/log/utmp or /var/log/wtmp-Login records file
/var/log/yum.log-Yum log files
In summary, /var/log is the location where you should find most Linux logs file. However, for example, some applications such as httpd have their own directories within /var/log/ for their own log files.
To help with the administration of log files, one can use the following applications:
Troubleshooting is the act of fault finding. Particular to this course, it is fault finding within a computer's operating system. Operating system fault finding methods include:
Common problems with Linux and how to fix them:
The term “Internal security”, as it relates to a course in information technology, is a general term used to refer to all of the built-in or add-on features available to a computer system to secure it against unauthorized use. The following topics define and describe these features.
The definition of the word “upgrade” as taken from the free dictionary online is as follows: “To replace (a software program) with a more recently released, enhanced version.”, and “To replace (a hardware device) with one that provides better performance.”
Backing up data on a computer system means to archive a copy of the data in a different location for safe keeping. Once the data has been archived in a different location, the original data can be removed to save space. The archive can be compressed in order to save space.
On Linux systems, use the following commands to back up data:
The free on line dictionary defines the word “documentation” as follows: “Computer Science The organized collection of records that describe the structure, purpose, operation, maintenance, and data requirements for a computer program, operating system, or hardware device.”
Documentation concerning Linux:
Of the term 'remote administration', Wikipedia says the following: “Remote administration refers to any method of controlling a computer from a remote location.” Besides meaning PC (personal computer), the word 'computer' in the preceding sentence can also mean 'server', 'switch', or 'router'.
All of these network components can be administered remotely.
Common methods of administering Linux systems remotely include the following:
An SSH clinet using the SSH protocol is typically used with a terminal emulator to open a command line interface remotely and securely. Secure shell is just that-secure, whereas telnet is not. In order to access a remote machine using SSH, an SSH server must be installed on the target machine. One such Linux server is Open SSH. One uses a terminal emulator to access the target machine on secure shell's well known port, 22. pUTTY is an implementation of the Telnet and SSH protocols for Windows and Unix platforms and includes an xterm terminal emulator. Applications such as pUTTY are used to access a machine via SSH or Telnet to perform administrative services remotely.
A Telnet client using the Telnet protocol is typically used with a terminal emulator to open a command line interface remotely. Unlike SSH, Telnet is not a secure communications protocol. In order to access a remote machine using Telnet, a Telnet server must be installed on the target machine. One such Linux server is telnetd. One uses a terminal emulator to access the target machine on Telnets's well known port, 23. pUTTY is an implementation of the Telnet and SSH protocols for Windows and Unix platforms and includes an xterm terminal emulator. Applications such as pUTTY are used to access a machine via Telnet or SSH to perform administrative services remotely.
The File Transfer Protocol or FTP is a standard network protocol used to transfer files from one host to another host over a TCP-based network, such as the Internet. In order to access a remote machine using FTP, an FTP server must be installed on the target machine. One such Linux server is VSFTPd. vsftpd, stands for “Very Secure FTP Daemon”. One uses to access the target machine on FTP's well known ports, 20 and 21; Port 20 is data, port 21 is control. Once the FTP server software has been installed and the system has been configured, FTP can be used to download files from or upload files to a target machine. In order for the network administrator or other users to use communicate with the FTP server on the target machine, the /etc/vsftpd.conf file must be modified. On a Linux machine by default users can download files but cannot upload. To upload, once again the /etc/vsftpd.conf file must be modified. Like any other server, once its configuration files have been modified, the server must be restarted for the new configuration to take effect. To actually upload and download files, a user must use an FTP client. Well known FTP clients include Filezilla and CuteFTP.
A firewall is an object, set of objects or software designed to allow or deny network communication based on a set of rules; a firewall is used to protect networks from unauthorized access while permitting legitimate communications to pass.
Most modern operating systems include software-based firewalls to protect against malicious communications from the public Internet. Besides hosts, most routers also contain firewalls. It is interesting to note that many firewalls can perform certain routing functions.
Firewall and router distributions for Linux include:
Ufw or Uncomplicated Firewall is an application for managing the netfilter firewall. The Linux kernel in Ubuntu provides a packet filtering system, netfilter. The traditional interface for configuring netfilter is iptables. iptables while both highly configurable and highly flexible is complicated to use. ufw was created to make managing netfilter uncomplicated. By default, ufw is disabled.
ufw status-shows the status of the firewall and ufw managed rules. Use status verbose for extra information.
Executing 'ufw status' without being the root yields the following output:
jr018429@emachine:~$ ufw status ERROR: You need to be root to run this script jr018429@emachine:~$
If 'ufw status' is executed and ufw has not been enabled previously, the user receives the following output:
root@emachine:/home/jr018429# ufw status Status: inactive
Once ufw has been enabled, when 'ufw status' is executed, if no rules have been set, or 'ufw reset' has just been executed, the output from 'ufw status' is 'Status: active'.
root@emachine:/home/jr018429# ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429#
ufw enable-reloads firewall and enables it on boot-up.
root@emachine:/home/jr018429# ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup root@emachine:/home/jr018429#
ufw disable- unloads the firewall and disables it on boot-up.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw disable Firewall stopped and disabled on system startup root@emachine:/home/jr018429#
ufw allow port/optional: protocol-add the allow rule defined by the allow argument.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow 22/tcp Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 22/tcp ALLOW Anywhere (v6) root@emachine:/home/jr018429#
ufw deny port/optional: protocol-add deny rule defined by the deny argument.
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw deny 23 Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 23 DENY Anywhere 23 DENY Anywhere (v6) root@emachine:/home/jr018429#
ufw delete allow/deny port/optional:protocol-deletes the corresponding rule.
root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 23 DENY Anywhere 23 DENY Anywhere (v6) root@emachine:/home/jr018429# ufw delete deny 23 Rule deleted Rule deleted (v6) root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429#
ufw allow/deny service/optional: port-ufw allow or deny can be used to allow or deny sevices. to allow or deny services, ufw reads from /etc/services. To see get a list of services, execute the following command line: 'less /etc/services'.
root@emachine:/home/jr018429# ufw allow ssh Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 22 ALLOW Anywhere 22 ALLOW Anywhere (v6) root@emachine:/home/jr018429#
To deny a service using its service name do the following:
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw deny telnet Rule added Rule added (v6) root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 23/tcp DENY Anywhere 23/tcp DENY Anywhere (v6) root@emachine:/home/jr018429#
ufw allow/deny from a source IPaddress/optional: subnet mask
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow from 192.168.1.1 Rule added root@emachine:/home/jr018429#
ufw allow/deny proto <protocol> from <ip address/optional:subnet mask> to <ip address> port <port number>
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow proto tcp from 192.168.1.134 to any port 22 Rule added root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW 192.168.1.134 root@emachine:/home/jr018429#
An example using a 'to' ip address, the IP address of the destination machine:
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow proto tcp from 192.168.1.134 to 192.168.1.2 port 22 Rule added root@emachine:/home/jr018429#
An example using source IP address and subnet mask and 'to' or destination IP address:
root@emachine:/home/jr018429# ufw status Status: active root@emachine:/home/jr018429# ufw allow proto tcp from 192.168.1.0/24 to 192.168.1.2 port 22 Rule added root@emachine:/home/jr018429# ufw status Status: active To Action From -- ------ ---- 192.168.1.2 22/tcp ALLOW 192.168.1.0/24 root@emachine:/home/jr018429#
ufw reset-disables and resets the firewall to installation defaults. Furthermore, after resetting the firewall, it disables it. However, once it is enabled again, one can see that the rules created earlier are now gone; ufw is back to its default state.
root@emachine:~# ufw status Status: active root@emachine:~# ufw allow 22/tcp Rule added Rule added (v6) root@emachine:~# ufw deny 23 Rule added Rule added (v6) root@emachine:~# ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 23 DENY Anywhere 22/tcp ALLOW Anywhere (v6) 23 DENY Anywhere (v6) root@emachine:~# ufw reset Resetting all rules to installed defaults. This may disrupt existing ssh connections. Proceed with operation (y|n)? y Backing up 'user.rules' to '/lib/ufw/user.rules.20120409_185826' Backing up 'after6.rules' to '/etc/ufw/after6.rules.20120409_185826' Backing up 'user6.rules' to '/lib/ufw/user6.rules.20120409_185826' Backing up 'before6.rules' to '/etc/ufw/before6.rules.20120409_185826' Backing up 'after.rules' to '/etc/ufw/after.rules.20120409_185826' Backing up 'before.rules' to '/etc/ufw/before.rules.20120409_185826' root@emachine:~# ufw status Status: inactive root@emachine:~# ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup root@emachine:~# ufw status Status: active root@emachine:~#
ufw logging feature
By appending the 'verbose' to 'ufw status' the state of logging is returned:
root@emachine:/home/jr018429# ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing) New profiles: skip root@emachine:/home/jr018429#
ufw logging on.off-turns logging on or off.
root@emachine:/home/jr018429# ufw logging on Logging enabled root@emachine:/home/jr018429# ufw logging off Logging disabled root@emachine:/home/jr018429#
The ufw log files are located in '/var/log/'. To get a list of ufw related logs, invoke ls with the following arguments: ls /var/log/ufw*.
root@emachine:/home/jr018429# ls /var/log/ufw* /var/log/ufw.log /var/log/ufw.log.1 root@emachine:/home/jr018429#
If you do not have logs, invoke 'ufw status' with the verbose option. If logging is off then turn it on.
root@emachine:/home/jr018429# ufw status verbose Status: active Logging: off Default: deny (incoming), allow (outgoing) New profiles: skip root@emachine:/home/jr018429# ufw logging on Logging enabled root@emachine:/home/jr018429# ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing) New profiles: skip root@emachine:/home/jr018429#
If there are no log files then check if rsyslogd is running.
root@emachine:/home/jr018429# service rsyslog status rsyslog start/running, process 453 root@emachine:/home/jr018429#
If it is not running, try to start it.
root@emachine:/home/jr018429# service rsyslog restart rsyslog start/running, process 5591 root@emachine:/home/jr018429#
Lastly, see man ufw for even more information. ufw is a powerful firewall management tool!
iptables is a command line program used by a system adminstrator to configure the tables provided by the Linux kernel firewall and the chains and rules stored by it. Because iptables is targeted to the system administrator, it must be executed by the root user. Different kernel modules and programs are currently used for different protocols. iptables applies to IPv4, ip6tables to IPv6, arptables to ARP, and ebtables to Ethernet frames. According to the Ubuntu IptablesHowTo (see references), on installation iptables allows all traffic by default.
iptable Commands:
Executing iptable -L without being the root yields the following output:
jr018429@emachine:~$ iptables -L iptables v1.4.10: can't initialize iptables table `filter': Permission denied (you must be root) Perhaps iptables or your kernel needs to be upgraded.
If you have just set up your computer, you will have no rules, and you will see the following output:
login as: jr018429 jr018429@192.168.1.2's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ 28 packages can be updated. 18 updates are security updates. Last login: Sat Mar 24 17:24:32 2012 from 192.168.1.1 su jr018429@emachine:~$ su Password: root@emachine:/home/jr018429# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination root@emachine:/home/jr018429#
Next, since iptables allows all traffic by default, we allow certain ports, ect. and then drop everything else.
First, make sure ufw is disabled so there is no interaction; is there any interaction? Sounds like a great experiment.
root@emachine:~# ufw status Status: inactive root@emachine:~#
Next, verify that there are no rules set.
root@emachine:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
It is a good idea to allow port 22, the ssh port, before performing a general 'DROP'. This is to prevent being accidentally locked out when working on remote systems over an SSH connection.
root@emachine:~# iptables -A INPUT -p tcp --dport 22 -j ACCEPT root@emachine:~#
Next, verify that the rule is in effect.
root@emachine:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp -- anywhere anywhere tcp dpt:ssh Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination root@emachine:~#
This is an example of how to use iptables to create a general rule to 'DROP' all incoming traffic.
root@emachine:~# iptables -P INPUT DROP root@emachine:~#
Verify that the general rule is in effect.
root@emachine:~# iptables -L Chain INPUT (policy DROP) target prot opt source destination ACCEPT tcp -- anywhere anywhere tcp dpt:ssh Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination root@emachine:~#
At this point I verified that the Web browser could not connect with the Web server on the emachine, but that I could connect to it using pUTTY on port 22.
login as: jr018429 jr018429@192.168.1.2's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686) * Documentation: https://help.ubuntu.com/ 24 packages can be updated. 22 updates are security updates. Last login: Sat Apr 7 23:23:09 2012 from 192.168.1.135 jr018429@emachine:~$
The following commands together, reset iptables, that is, return iptables to its default state, the state before any rules were created:
root@emachine:~# iptables -P INPUT DROP root@emachine:~# iptables -L Chain INPUT (policy DROP) target prot opt source destination ACCEPT tcp -- anywhere anywhere tcp dpt:ssh Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination root@emachine:~# iptables -F root@emachine:~# iptables -X root@emachine:~# iptables -t nat -F root@emachine:~# iptables -t nat -X root@emachine:~# iptables -t mangle -F root@emachine:~# iptables -t mangle -X root@emachine:~# iptables -P INPUT ACCEPT root@emachine:~# iptables -P FORWARD ACCEPT root@emachine:~# iptables -P OUTPUT ACCEPT root@emachine:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination root@emachine:~#
root@emachine:/# iptables-save > /root/working.iptables.rules root@emachine:/#
Check that the rules were actually saved to a file.
root@emachine:/# cd /root root@emachine:~# ls working.iptables.rules root@emachine:~# nano working.iptables.rules # Generated by iptables-save v1.4.10 on Mon Apr 9 19:50:54 2012 *mangle :PREROUTING ACCEPT [1162:84209] :INPUT ACCEPT [1162:84209] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [963:156432] :POSTROUTING ACCEPT [972:157080] COMMIT # Completed on Mon Apr 9 19:50:54 2012 # Generated by iptables-save v1.4.10 on Mon Apr 9 19:50:54 2012 *nat :PREROUTING ACCEPT [7:1086] :INPUT ACCEPT [4:392] :OUTPUT ACCEPT [5:358] :POSTROUTING ACCEPT [5:358] COMMIT # Completed on Mon Apr 9 19:50:54 2012 # Generated by iptables-save v1.4.10 on Mon Apr 9 19:50:54 2012 *filter :INPUT DROP [18:540] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :ufw-after-forward - [0:0] :ufw-after-input - [0:0] :ufw-after-logging-forward - [0:0] :ufw-after-logging-input - [0:0] :ufw-after-logging-output - [0:0] :ufw-after-output - [0:0] :ufw-before-forward - [0:0] :ufw-before-input - [0:0] :ufw-before-logging-forward - [0:0] :ufw-before-logging-input - [0:0] :ufw-before-logging-output - [0:0] :ufw-before-output - [0:0] :ufw-logging-allow - [0:0] :ufw-logging-deny - [0:0] :ufw-not-local - [0:0] :ufw-reject-forward - [0:0] :ufw-reject-input - [0:0] :ufw-reject-forward - [0:0] :ufw-reject-input - [0:0] :ufw-reject-output - [0:0] :ufw-skip-to-policy-forward - [0:0] :ufw-skip-to-policy-input - [0:0] :ufw-skip-to-policy-output - [0:0] :ufw-track-input - [0:0] :ufw-track-output - [0:0] :ufw-user-forward - [0:0] :ufw-user-input - [0:0] :ufw-user-limit - [0:0] :ufw-user-limit-accept - [0:0] :ufw-user-logging-forward - [0:0] :ufw-user-logging-input - [0:0] :ufw-user-logging-output - [0:0] :ufw-user-output - [0:0] -A INPUT -j ufw-before-logging-input -A INPUT -j ufw-before-input -A INPUT -j ufw-after-input -A INPUT -j ufw-after-logging-input -A INPUT -j ufw-reject-input -A INPUT -j ufw-track-input -A FORWARD -j ufw-before-logging-forward -A FORWARD -j ufw-before-forward -A FORWARD -j ufw-after-forward -A FORWARD -j ufw-after-logging-forward -A FORWARD -j ufw-reject-forward -A OUTPUT -j ufw-before-logging-output -A OUTPUT -j ufw-before-output -A OUTPUT -j ufw-after-output -A OUTPUT -j ufw-after-logging-output -A OUTPUT -j ufw-reject-output -A OUTPUT -j ufw-track-output -A ufw-after-input -p udp -m udp --dport 137 -j ufw-skip-to-policy-input -A ufw-after-input -p udp -m udp --dport 138 -j ufw-skip-to-policy-input -A ufw-after-input -p tcp -m tcp --dport 139 -j ufw-skip-to-policy-input -A ufw-after-input -p tcp -m tcp --dport 445 -j ufw-skip-to-policy-input -A ufw-after-input -p udp -m udp --dport 67 -j ufw-skip-to-policy-input -A ufw-after-input -p udp -m udp --dport 68 -j ufw-skip-to-policy-input -A ufw-after-input -p udp -m udp --dport 67 -j ufw-skip-to-policy-input -A ufw-after-input -p udp -m udp --dport 68 -j ufw-skip-to-policy-input -A ufw-after-input -m addrtype --dst-type BROADCAST -j ufw-skip-to-policy-input -A ufw-after-logging-forward -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] " -A ufw-after-logging-input -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] " -A ufw-before-forward -j ufw-user-forward -A ufw-before-input -i lo -j ACCEPT -A ufw-before-input -m state --state RELATED,ESTABLISHED -j ACCEPT -A ufw-before-input -m state --state INVALID -j ufw-logging-deny -A ufw-before-input -m state --state INVALID -j DROP -A ufw-before-input -p icmp -m icmp --icmp-type 3 -j ACCEPT -A ufw-before-input -p icmp -m icmp --icmp-type 4 -j ACCEPT -A ufw-before-input -p icmp -m icmp --icmp-type 11 -j ACCEPT -A ufw-before-input -p icmp -m icmp --icmp-type 12 -j ACCEPT -A ufw-before-input -p icmp -m icmp --icmp-type 8 -j ACCEPT -A ufw-before-input -p udp -m udp --sport 67 --dport 68 -j ACCEPT -A ufw-before-input -j ufw-not-local -A ufw-before-input -d 224.0.0.251/32 -p udp -m udp --dport 5353 -j ACCEPT -A ufw-before-input -d 239.255.255.250/32 -p udp -m udp --dport 1900 -j ACCEPT -A ufw-before-input -j ufw-user-input -A ufw-before-output -o lo -j ACCEPT -A ufw-before-output -m state --state RELATED,ESTABLISHED -j ACCEPT -A ufw-before-output -j ufw-user-output -A ufw-logging-allow -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW ALLOW] " -A ufw-logging-deny -m state --state INVALID -m limit --limit 3/min --limit-burst 10 -j RETURN -A ufw-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] " -A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN -A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN -A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN -A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny -A ufw-not-local -j DROP -A ufw-skip-to-policy-forward -j DROP -A ufw-skip-to-policy-input -j DROP -A ufw-skip-to-policy-output -j ACCEPT -A ufw-track-output -p tcp -m state --state NEW -j ACCEPT -A ufw-track-output -p udp -m state --state NEW -j ACCEPT -A ufw-user-input -p tcp -m tcp --dport 22 -j ACCEPT -A ufw-user-input -p tcp -m tcp --dport 80 -j ACCEPT -A ufw-user-input -p udp -m udp --dport 80 -j ACCEPT -A ufw-user-input -p tcp -m tcp --dport 80 -j ACCEPT -A ufw-user-input -p udp -m udp --dport 80 -j ACCEPT -A ufw-user-limit -m limit --limit 3/min -j LOG --log-prefix "[UFW LIMIT BLOCK] " -A ufw-user-limit -j REJECT --reject-with icmp-port-unreachable -A ufw-user-limit-accept -j ACCEPT COMMIT # Completed on Mon Apr 9 19:50:54 2012 root@emachine:/#
root@emachine:~# iptables-restore < /root/working.iptables.rules root@emachine:~#
To restore iptables rules on reboot automatically, add the iptables-restore line to the /etc/rc.local file. Make sure that the full path to 'iptables-restore' is used: '/sbin/iptables-restore < /root/working.iptables.rules' .
Besides 'iptables -A INPUT -p XXX –dport XX -j ACCEPT' and 'iptables -P INPUT DROP', there are some other common invocations of iptables which are worth knowing:
netstat or network statistics is a command-line interface application that displays network connections, incoming and outgoing, routing tables, and other network interface data. It is available on Unix, Unix-like, and Windows NT-based operating systems.
To learn about the Linked-Lists data structures and the operations that can be performed on them.
One way to measure academic achievement is through the grading system. I will track my grades.
To learn about and use stack data structures and the operations that can be performed on them.
I will use the grading system to measure academic success.
To learn about the queue data structurte and the operations that can be performed on them.
I will use the grading system to measure academic success.
To learn about and write programs utilizing threads.
I will use the grading system to measure academic success.
To learn about and write server/client applications.
I will use the grading system to measure academic success.
To learn about fork and use it to create child processes.
I will use the grading system to measure academic success.
To gain proactical experience with computer networks by setting up a home network for personal use, but also to conduct experiments and develop project for HPC1.
Whether or not I can setup the network and get it to work, that will be the criteria I use to judge whether or not this project is a success. I will also use my course grade as a measure of my success.
At Christmas time, I purchased a Cisco Linksys E1200 Wireless Router/Switch with which to connect my laptop which has wireless. I connected the router and configured it, using the software which came with it, and got it to 'talk' to it successfully. Next, I wanted to add a PC with which to conduct experimets and develop HPC1 projects. Unfortunately the PC I have is an emachine T1096 with 512MB of memory and a Celeron processor. Furthermore, it didn't have a network adapter; it also had a CD drive which didn't work. Its resident operating system was Windows XP Home Edition; I wanted to change it to a Linux distribution. I was able to perform the following tasks to get the emachine to function on my Ethernet network:
I was able to complete all of the steps required to assemble and configure a home network having more than one type of operating system on its hosts. Furthermore, these hosts were connected to the network using more than one type of communication medium. In the case of the emachine, I loaded an operating distribution, configured it so that the operating system could use it (loaded a driver), and turned on its DHCP client so that it could receive its IP address, subnet mask, and default gateway from the router/switch's DHCP server.
To gain experience with, and learn more about Web servers and related packages by loading them on one of my home network's hosts (emachine desktop pc).
Whether or not I can setup and configure a Web server along with related packages and get them to work, that will be the criteria I use to judge whether or not this project is a success. I will also use my course grade as a measure of my success.
I loaded, via the command line, the Apache2 Web server successfully. I configured the Web server to also listen at port 8080. I tested this functionality by placing the IP address of the Webserver into a web browser of a remote computer also on the network, and submitted an http request. Success! the default Web page was returned. I then appended the Web address of th Web server with :8080 in the Web browser and again submitted an http request. Success! the default Web page was returned. Next, I also loaded PHP5 via the command line successfully. I tested PHP by first creating a PHP document which contained php scripting; the scripting consisted of a call of the phpinfo() function. I then entered the IP address of the Web server into the Web browser and appended the address with the name of the PHP document (/phpinfo.php). Success! the PHP information was returned. In order to write and test PHP scripting on my laptop. I found Wamp Server. Wamp Server s a Windows web development environment. One can create web applications with Apache2, PHP and a MySQL database. Wamp Server is available http://www.wampserver.com/en/ .
I was able to complete all of the steps required to install and configure a Web server and related packages. I plan to use the Web server and PHP to control hardware remotely.
State the course objective; define what that objective entails.
State the method you will use for measuring successful academic/intellectual achievement of this objective.
Follow your method and obtain a measurement. Document the results here.
Reflect upon your results of the measurement to ascertain your achievement of the particular course objective.
The code I have seen, frees dynamically allocated memory and then sets pointers to NULL. Is deallocated memory available to the system immediately after being deallocated?
I believe that once the dynamically allocated memory has been freed, it immediately becomes availble to the system for reallocation. Further, because the memory is managed by the kernel, Once the memory has been deallocated, a write to the memory location without reallocating will probably return a segfault.
I wrote the following program to verify how the system (the kernel) manages dynamically allocated memory.
//deallocTest.c //John T. Rine //September 26, 2011 #include<stdio.h> #include<stdlib.h> struct Node { int data; struct Node * prev; struct Node * next; }; typedef struct Node node; void createList(node **, node **, int); void deallocListHead(node *); node *array[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; int main(int argc, char **argv) { node *head, *tail; head = NULL; tail = NULL; printf("Creating a linked list of 10 nodes...\n"); createList(&head, &tail, 10); int i = 0; for(i = 0; i < 10; i++) printf("Address stored in array[%d]is: 0x%x\n",i, array[i]); i = 1; node *temp; temp = head; while(temp != NULL) { temp-> data = i; temp = temp->next; i++; } printf("Printing addresses of nodes before freeing...\n"); int counter = 0; temp = head; while(temp != NULL) { printf("Address of node %d is 0x%x\n", counter, temp); printf("Data of this node is %d\n", temp->data); counter++; temp = temp->next; } printf("Preparing to deallocat list memory allocated previously...\n"); deallocListHead(head); printf("Printing addresses of nodes after freeing...\n"); counter = 0; temp = head; while(temp != NULL) { printf("Address of node %d is 0x%x\n", counter, temp); printf("Data of this node is %d\n", temp->data); counter++; temp = temp->next; } printf("Will now attempt to put data into the nodes...\n"); for (i = 0; i < 10; i++) { array[i]->data = i; printf("array[%d] = 0x%x\tarray[%d]->data = %d\n", i, array[i], i, array[i]->data); } getchar();//to hold the console window open in Windows I am using MinGW! } void createList(node **headd, node **taill, int elements) { int i; int counter = 1; node *new, *head, *tail; new = head = tail = NULL; for(i = 1; i<=elements; i++) { if (head == NULL) { head = (node *) malloc(sizeof(node)); tail = head; array[0] = head; head->prev = NULL; head->next = NULL; } else { new = (node *) malloc(sizeof(node)); array[counter] = new; counter++; new->prev = tail; new->next = NULL; tail->next = new; tail = new; } } *headd = head; *taill = tail; } void deallocListHead(node *head) { node *temp; node *temp2; temp = NULL; temp2 = NULL; temp = head; while(temp != NULL) { temp2 = temp->next; free(temp); temp = temp2; } }
I collected data for this experiment from the output of the program listed above.
lab46:~/src/data$ ./deallocTest Creating a linked list of 10 nodes... Address stored in array[0]is: 0x7ea010 Address stored in array[1]is: 0x7ea030 Address stored in array[2]is: 0x7ea050 Address stored in array[3]is: 0x7ea070 Address stored in array[4]is: 0x7ea090 Address stored in array[5]is: 0x7ea0b0 Address stored in array[6]is: 0x7ea0d0 Address stored in array[7]is: 0x7ea0f0 Address stored in array[8]is: 0x7ea110 Address stored in array[9]is: 0x7ea130 Printing addresses of nodes before freeing... Address of node 0 is 0x7ea010 Data of this node is 1 Address of node 1 is 0x7ea030 Data of this node is 2 Address of node 2 is 0x7ea050 Data of this node is 3 Address of node 3 is 0x7ea070 Data of this node is 4 Address of node 4 is 0x7ea090 Data of this node is 5 Address of node 5 is 0x7ea0b0 Data of this node is 6 Address of node 6 is 0x7ea0d0 Data of this node is 7 Address of node 7 is 0x7ea0f0 Data of this node is 8 Address of node 8 is 0x7ea110 Data of this node is 9 Address of node 9 is 0x7ea130 Data of this node is 10 Preparing to deallocat list memory allocated previously... Printing addresses of nodes after freeing... Address of node 0 is 0x7ea010 Data of this node is 0 Address of node 1 is 0x7ea030 Data of this node is 8298496 Address of node 2 is 0x7ea050 Data of this node is 8298528 Address of node 3 is 0x7ea070 Data of this node is 8298560 Address of node 4 is 0x7ea090 Data of this node is 8298592 Address of node 5 is 0x7ea0b0 Data of this node is 8298624 Address of node 6 is 0x7ea0d0 Data of this node is 8298656 Address of node 7 is 0x7ea0f0 Data of this node is 8298688 Address of node 8 is 0x7ea110 Data of this node is 8298720 Address of node 9 is 0x7ea130 Data of this node is 8298752 Will now attempt to put data into the nodes... array[0] = 0x7ea010 array[0]->data = 0 array[1] = 0x7ea030 array[1]->data = 1 array[2] = 0x7ea050 array[2]->data = 2 array[3] = 0x7ea070 array[3]->data = 3 array[4] = 0x7ea090 array[4]->data = 4 array[5] = 0x7ea0b0 array[5]->data = 5 array[6] = 0x7ea0d0 array[6]->data = 6 array[7] = 0x7ea0f0 array[7]->data = 7 array[8] = 0x7ea110 array[8]->data = 8 array[9] = 0x7ea130 array[9]->data = 9
Because the data in the memory locations after freeing is different, one can surmise that yes, after being deallocated, memory is free for use by the system (kernel).
Before deallocation:
Printing addresses of nodes before freeing... Address of node 0 is 0x7ea010 Data of this node is 1 Address of node 1 is 0x7ea030 Data of this node is 2 Address of node 2 is 0x7ea050 Data of this node is 3 Address of node 3 is 0x7ea070 Data of this node is 4 Address of node 4 is 0x7ea090 Data of this node is 5 Address of node 5 is 0x7ea0b0 Data of this node is 6 Address of node 6 is 0x7ea0d0 Data of this node is 7 Address of node 7 is 0x7ea0f0 Data of this node is 8 Address of node 8 is 0x7ea110 Data of this node is 9 Address of node 9 is 0x7ea130 Data of this node is 10
After deallocation of memory:
Preparing to deallocat list memory allocated previously... Printing addresses of nodes after freeing... Address of node 0 is 0x7ea010 Data of this node is 0 Address of node 1 is 0x7ea030 Data of this node is 8298496 Address of node 2 is 0x7ea050 Data of this node is 8298528 Address of node 3 is 0x7ea070 Data of this node is 8298560 Address of node 4 is 0x7ea090 Data of this node is 8298592 Address of node 5 is 0x7ea0b0 Data of this node is 8298624 Address of node 6 is 0x7ea0d0 Data of this node is 8298656 Address of node 7 is 0x7ea0f0 Data of this node is 8298688 Address of node 8 is 0x7ea110 Data of this node is 8298720 Address of node 9 is 0x7ea130 Data of this node is 8298752
Furthermore, I was able to successfully write data to the former memory locations of the nodes. The first column of data contains the addresses of the nodes. The second column contains the data read immediately after writing it to the data fields of the former nodes.
Will now attempt to put data into the nodes... array[0] = 0x7ea010 array[0]->data = 0 array[1] = 0x7ea030 array[1]->data = 1 array[2] = 0x7ea050 array[2]->data = 2 array[3] = 0x7ea070 array[3]->data = 3 array[4] = 0x7ea090 array[4]->data = 4 array[5] = 0x7ea0b0 array[5]->data = 5 array[6] = 0x7ea0d0 array[6]->data = 6 array[7] = 0x7ea0f0 array[7]->data = 7 array[8] = 0x7ea110 array[8]->data = 8 array[9] = 0x7ea130 array[9]->data = 9
In conclusion, dynamically allocated memory that has been freed can be used by the kernel immediately after it has been freed. Also, even though dynamically allocated memory has been freed it is possible to write to it without causing a segmentation fault.
Can communications on well known ports be blocked and if so how?
After much research I found that ports are blocked by the router by default, however, they can be forwarded to a particular IP address as required. Also, at the machine, ports can be allowed or disallowed access.
I believe it is possible to block communications on well known ports by not forwarding the port from the router to a particular IP address; I also believe it is possible to disallow communications on ports at a particular machine.
I will attempt to access the well known HTTP port (80) on which my Web server is running using my Web browser. I will attempt to connect to the Web server under all sets of conditions of forwarding and not forwarding ports from the switch and allowing/disallowing communications on a particular port at the machine running the Web server. To block communications on a particular port at the machine running the Web server, I will use a Ubuntu tool called UFW (Uncomplicated Fire Wall) which makes working with iptables easier.
Data from ufw experiment:
Once ufw was enabled without any rules, I noticed that ssh communication to port 22 was blocked whereas http communication to port 80 and port 8080 seemed to not be blocked. I think the web pages that are returned are in the cache. I cleared the cache and retested ports 80 and 8080 using a Web browser. Once the cache had been cleared, no Web pages were returned (compare steps 4 and 6 to steps 7 and 9 above).
Data from port forwarding experiment:
With ufw enabled and with rules to allow communication to ports 22, 80 and 8080, I tested port forwarding from the router. Before performing tests using http on ports 80 and 8080 the Web broser cache was cleared each time.
To summarize how ufw functions, with ufw disabled, connections via ssh on port 22, and http connections via ports 80 and 8080 are possible, that is these ports are not blocked.
with ufw enabled with no rules, connections via port 22, and http connection via 80 and 8080 cannot be established, that is they are blocked.
If the browser cache is not cleared and there are pages stored from the IP address and port to which a connection is being attempted, Web pages will be returned to the browser.
With ufw enabled and rules established to allow communications to the individual ports, connections can be established on these ports.
If port 22 is allowed, an ssh connection on port 22 (pUTTY) to the target machine is possible.
If port 80 is allowed, an http connection on port 80 to the target machine is possible.
If port 8080 is allowed, and the Web server is listening on it, an http connection on port 8080 to the target machine is possible.
After testing ufw functionality and router port forwarding one can conclude that in order to use ports 22, 80, or 8080, the individual port must be forwarded from the router to the target machine's IP address.
Also, either ufw must be disabled, or rules to allow the individual ports must be created.
It is interesting to note that if web browser is being used to test ports 80 and 8080, that the browser cache must be cleared before testing otherwise, if an old Web page is in the cache, it will be returned rather than the browser making requests to the target IP address and port.
What is the question you'd like to pose for experimentation? State it here.
Collect information and resources (such as URLs of web resources), and comment on knowledge obtained that you think will provide useful background information to aid in performing the experiment.
Based on what you've read with respect to your original posed question, what do you think will be the result of your experiment (ie an educated guess based on the facts known). This is done before actually performing the experiment.
State your rationale.
How are you going to test your hypothesis? What is the structure of your experiment?
Perform your experiment, and collect/document the results here.
Based on the data collected:
What can you ascertain based on the experiment performed and data collected? Document your findings here; make a statement as to any discoveries you've made.
If you're doing an experiment instead of a retest, delete this section.
If you've opted to test the experiment of someone else, delete the experiment section and steps above; perform the following steps:
Whose existing experiment are you going to retest? Prove the URL, note the author, and restate their question.
Evaluate their resources and commentary. Answer the following questions:
State their experiment's hypothesis. Answer the following questions:
Follow the steps given to recreate the original experiment. Answer the following questions:
Publish the data you have gained from your performing of the experiment here.
Answer the following:
Answer the following:
I updated my linked list development, and committed it to the Subversion repository.
There is an
lab46:~/src/data$ svn commit -m "Updated linkedLinst1-jr.c to include delete node, append, ans insert. Thes functions need work as they do not handle the end node or the next to end node correctly -jr" Sending data/linkedList1-jr.c Transmitting file data . Committed revision 10.
After verifying my linked list library, I then added the linkedListLibrary directory and its files to the Subversion repository.
lab46:~/src/data$ svn add linkedListLibrary A linkedListLibrary A linkedListLibrary/linkedListLib.c A linkedListLibrary/linkedList-jr.c A linkedListLibrary/linkedListLib.h A linkedListLibrary/linkedListTest.c A (bin) linkedListLibrary/linkedListTest lab46:~/src/data$
After adding the linked list library files to the Subversion repository, I committed them as well.
lab46:~/src/data$ svn commit -m "linked list library, linkedListLib.a, contains the following functions: createList, destroyListHead, destroyListTail, listSizeHead, listSizeTail, printIntDataHead, insert, append, deleteNode, void loadListData, loadNode, createNode, copyList, findData, which have all been verified -John Rine" Sending data/linkedList1-jr.c Adding data/linkedListLibrary Adding data/linkedListLibrary/linkedList-jr.c Adding data/linkedListLibrary/linkedListLib.c Adding data/linkedListLibrary/linkedListLib.h Adding (bin) data/linkedListLibrary/linkedListTest Adding data/linkedListLibrary/linkedListTest.c Transmitting file data ...... Committed revision 11. lab46:~/src/data$
I am now finalizing my linked list project page which is at:
http://lab46.corning-cc.edu/user/jr018429/portfolio/libdll .
I learned to use a single .h file to prototye all of my functions and the node structure for all of my library files. Below is a record of the steps I went through to get there.
I successfully created and used a static linked list library, or so I thought, when I finalized my linked list project. However, when it came to implementing a static library of stack routines and associated data type, I had a horrible time. every library file wanted a node structure in it however when I linked the library files together, I got error messages! I had to figure out a way to have only one node struct reference that I could share with the library files. I appealed to the instructor for help!
Date: Wed, 12 Oct 2011 19:54:26 -0400 (EDT) From: John Rine <jr018429@lab46.corning-cc.edu> To: wedge@lab46.corning-cc.edu, haas@corning-cc.edu Subject: static library HELP!!!!! I am trying to finish my stack library and mange all the crap going on in my personal life and it ain't going very good. I think I got lucky compiling and linking the linked List library. I am having a time with the stack. I took a different approach with it. I am having many library files with names describing the functions inside. For example: createFixedStack.c createFixedStack.h listStackSize.c listStackSize.h destroyFixedStack.c destroyFixedStack.h I also have a test program named: stackTest.c please look closely at the #include "..." in the files, also look closely at the way I created the static library. What am I doing wrong????? I can't find any good examples on the Internet. My issues are compounded by having a struct. please look closely at how the struct is included in the includes. I took copious notes. From you class, I got: main #include "mything.h" how does "mything.h in the test program relate to multiple include files?? I also got the following: ar rcs libdll.a *.o How does libdll relate to "mything.h" in the test program? I am missing something!!!! in stackTest.c I am declaring the individual .h files: #include "createFixedStack.h" #include "destroyFixedStack.h" #include "listStackSize.h" I successfully created .o files for these libraries using the following: lab46:~/Stack$ gcc -c createFixedStack.c -o createFixedStack.o lab46:~/Stack$ gcc -c destroyFixedStack.c -o destroyFixedStack.o lab46:~/Stack$ gcc -c listStackSize.c -o listStackSize.o Then I can successfully create a static library using: lab46:~/Stack$ ar rcs libStackJRdll.a *.o Code and includes //createFixedStack.h //John T. Rine //October 12, 2011 #ifndef _CREATEFIXEDSTACK_JR_H #define _CREATEFIXEDSTACK_JR_H #include<stdio.h> #include<stdlib.h> struct Node { int data; struct Node * prev; struct Node * next; }; typedef struct Node node; void createFiixedStackList(node **, node **, int); #endif //createFixedStack.c //John T. Rine //October 12, 2011 #include<stdlib.h> #include<stdio.h> #include"createFixedStack.h" void createFixedStack(node **head, node **tail, int elements) { int i; node *new; new = NULL; *head = *tail = NULL; for(i = 1; i<=elements; i++) { if (*head == NULL) { *head = (node *) malloc(sizeof(node)); *tail = *head; (*head)->prev = NULL; (*head)->next = NULL; } else { new = (node *) malloc(sizeof(node)); new->prev = *tail; new->next = NULL; (*tail)->next = new; *tail = new; } } } //destroyFixedStack.h //John T. Rine //October 12, 2011 #ifndef _DESTROYFIXEDSTACK_JR_H #define _DESTROYFIXEDSTACK_JR_H #include<stdio.h> #include<stdlib.h> struct Node { int data; struct Node * prev; struct Node * next; }; typedef struct Node node; void destroyFixedStackHead(node *); void destroyFixedStackTail(node *); #endif //destroyFixedStack.c //John T. Rine //October 12, 2011 #include<stdlib.h> #include<stdio.h> #include "destroyFixedStack.h" void destroyFixedStackHead(node *head) { node *temp; node *temp2; temp = NULL; temp2 = NULL; temp = head; while(temp != NULL) { temp2 = temp->next; if (temp->prev != NULL) temp->prev = NULL; if (temp->next != NULL) temp->next = NULL; free(temp); temp = temp2; } } void destroyFixedStackTail(node *tail) { node *temp; node *temp2; temp = NULL; temp2 = NULL; temp = tail; while(temp != NULL) { temp2 = temp->prev; if (temp->prev != NULL) temp->prev = NULL; if (temp->next != NULL) temp->next = NULL; free(temp); temp = temp2; } } //listStackSize.h //John T. Rine //October 12, 2011 #ifndef _LISTSTACKSIZE_JR_H #define _LISTSTACKSIZE_JR_H #include<stdio.h> #include<stdlib.h> struct Node { int data; struct Node * prev; struct Node * next; }; typedef struct Node node; int listStackSizeHead(node *); int listStackSizeTail(node *); #endif //listrStackSize.c //John T. Rine //October 12, 2011 #include<stdlib.h> #include<stdio.h> #include"listStackSize.h" int listStackSizeHead(node *head) { int size = 0; while (head != NULL) { head = head->next; size++; } return size; } int listStackSizeTail(node *tail) { int size = 0; while (tail != NULL) { tail = tail->prev; size++; } return size; } //stackTest.c //Author: John T. Rine //Date: October 12, 2011 #include "createFixedStack.h" #include "destroyFixedStack.h" #include "listStackSize.h" int main(int argc, char **argv) { node *head, *tail; head = tail = NULL; printf("Creating a list of 10 nodes...\n"); createFixedStack(&head, &tail, 10); getchar(); //Holds the console window open on a Windows machine } However when I try to create the test executable, it bombs-HELP!!! John T. Rine Graduate Electrical Technology-Electronics Graduate General Studies --- Lab46: Penguin Powered
I finally figured that I could create a struct .h file to define the node structure and then include that .h file in my lother library files. Sure enough, it worked!
Date: Thu, 13 Oct 2011 10:40:10 -0400 From: Matthew Haas <wedge@lab46.corning-cc.edu> To: John Rine <jr018429@lab46.corning-cc.edu> Subject: Re: static library HELP!!!!! (fwd) On Oct 12, 2011, at 11:34 PM, John Rine wrote: I got it. The issue is that the structure used as a node is shared throughout all of the functions. When you break them up, you can't include the structure in every .h file, so what you do is to creat e a structure.h file and include that in the broken up files. Its seems you also need it in the test file as well. Man did that was driving me crazy.
</cli> My instructor pointed out, however, that I could have simply made one .h file for all of my library files! Why didn't I think of that?
Date: Thu, 13 Oct 2011 10:40:10 -0400 From: Matthew Haas <wedge@lab46.corning-cc.edu> To: John Rine <jr018429@lab46.corning-cc.edu> Subject: Re: static library HELP!!!!! (fwd) Parts/Attachments: 1 OK ~61 lines Text 2 Shown ~62 lines Text ---------------------------------------- On Oct 12, 2011, at 11:34 PM, John Rine wrote: I got it. The issue is that the structure used as a node is shared throughout all of the functions. When you break them up, you can't include the structure in every .h file, so what you do is to creat e a structure.h file and include that in the broken up files. Its seems you also need it in the test file as well. Man did that was driving me crazy. John, You may have appeared to resolve the issue, but I think the situation is still inordinately complex and can be simplified. For your stack library, you should be able to get away with just 1 header file, let's call it: stack.h stack.h can look as follows: ------------------------------------- #ifndef _STACK_H #define _STACK_H #include "linkedlist.h" struct stack { struct list *data; struct node *top; }; typedef struct stack Stack; Node *pop(Stack *); int push(Stack *, Node *); Node *peek(Stack *); int isEmpty(Stack *); #endif ------------------------------------- All your .c files can just #include "stack.h", which will take care of all the function prototypes, struct definition, and even pull in the linked list stuff for you (the linkedlist.h file will similarly have #ifndef _LINKED_LIST_H guards). With so many header files, the way you seem to be approaching it might be creating a lot more managerial work for yourself... let the preprocessor take care of it for you. Is this code on Lab46? I took a quick peek and couldn't find it. -Matthew -- Matthew Haas Lab46 System Administrator Instructor of Computer & Information Science http://lab46.corning-cc.edu/haas/home/ [lab46.corning-cc.edu]
I finally finished my doubly linked stack library project :) !!!
It is available at:
http://lab46.corning-cc.edu/user/jr018429/portfolio/stack
I learned about implementing stacks using doubly linked structure
node structures. I also learned how to use a single .h file for
all library function prototypes and the library node structure definition.
I also learned that another more complicated way of implementing the library would
be to create a strucure .h file which defines the node structure and then
including that in the other library files, assuming one is using a .h
file per library .c file. Yet another way might be to include the node
structure definition in each .h file but wrap it in a #ifndef, #define,
#endif block as follows:
#ifndef _NODESTRUCT_H #define _NODESTRUCT_H struct Node { int data; node *next; node *prev; } #endif
State machines are ubiquitous in programming and in hardware design-synchronous digital logic design. I found a very good tutorial on statemachine design at: http://johnsantic.com/comp/state.html .
I shared this link and what I know about state-machines with my Data Structures and Systems Programming classes.
Date: Wed, 19 Oct 2011 23:06:46 -0400 (EDT) From: John Rine <jr018429@lab46.corning-cc.edu> To: data@lab46.corning-cc.edu, sys@lab46.corning-cc.edu Subject: State Machines in Programming Check out this link on state machines: http://johnsantic.com/comp/state.html State machines are a very import concept in both hardware and software design. Stae machines are either, in the case of hardware, clock driven or in software, loop, or interrupt driven. State machines store their last state and then compare this last state to input and if defined in their design, will change state when triggered by a clock, loop, or interrupt. State machines implemented in software can be used to perform hardware control, for example machine tool and robotics software. Soft state machines can be used in game design such that game flow changes based on the game's previous state and input from the player. One way to implement state machines in software by combining loop and selecttion structures. In hardware they are implemented using a register (flip-flops) and decoding logic. Why even discuss a hardware implement here? Well as we learned last sememmster in Computer Organizations, hardware can be simulated in software! The decoding logic of a hardware defined state machine decodes the outputs of the state register (output and state storage) and input and caauses the state register's state to change when the output state and inputs change to some value defined by the design. Even though a synchronous counter is not considered to be a state machine, it may be helpful as an analogy to understanding them. A synchronous counter is reset when firat powered up. The decoding circuitry sees 0 on the out put of the counter and decodes this value to be 1 on the input. On the next clock pulse, the counter changes to 1 on its output. now the decoding circuitry sees 1 on the output and decodes this to 2 on the input. When the next clock tick occurs, the output changes to 3 and so on... To get to a state machine from a synchronous counter, simply add inouts from the outside to the ddecoding circuitry. Now consider a hardware state machine, on power up the state machine's outputs are set to 0. Now if a sensor on an input changes state, when the next clock pulse occurs and if the decoding circuitry is designed to do so, a state machine output will change in response to the sensor's input. This output will maintain its state until the decoding logic coupled with certain input states associate with the decoding design and a clock pulse causes it to change. There are two types of hardware state machines: 1. Moore, and 2. Meally At least one author has described the cpu as a state machine. I am sure I have made the subject of state machines as clear as mud. John T. Rine Graduate Electrical Technology-Electronics Graduate General Studies --- Lab46: Penguin Powered
I added and committed my forkExample.c program to the Subversion repository.
lab46:~/src/sysprog$ svn add forkExample.c A forkExample.c lab46:~/src/sysprog$ svn commit -m "Added and commited a simple example of using fork -John Rine" Adding sysprog/forkExample.c Transmitting file data . Committed revision 16.
I added and committed my useMalloc.c program to the Subversion repository.
lab46:~/src/data$ svn add useMalloc.c A useMalloc.c lab46:~/src/data$ svn commit -m "Added and committed useMalloc.c, an example program demonstrating dynamic memory allocation of structures and arrays -John Rine" Sending data/Stack/libdll.a Adding data/useMalloc.c Transmitting file data .. Committed revision 17. lab46:~/src/data$
I conducted and documented an experiment to determine if a string literal could be assigned to a pointer pointing to dynamically allocated memory and then be used in a program, then when the data is no longer needed, deallocate it.
The experiment is documented in Part II, experiment 1.
I added and committed the code I wrote to implement an array-based stack data structure.
lab46:~/src/data$ svn add arrayStack.c A arrayStack.c lab46:~/src/data$ svn commit -m "Added and committed an array-based stack program. -John Rine" Adding data/arrayStack.c Sending data/useMalloc.c Transmitting file data .. Committed revision 18. lab46:~/src/data$
I added and committed the code I wrote to design and test doubly-linked list functions.
lab46:~/src/data$ svn add linkedListDev.c A linkedListDev.c lab46:~/src/data$ svn commit -m "Added and committed linkedListDev.c, a linked list development program -John Rine" Adding data/linkedListDev.c Transmitting file data . Committed revision 19. lab46:~/src/data$
I added and committed the code I wrote to learn about threads.
lab46:~/src/sysprog$ svn add threadTest.c A threadTest.c lab46:~/src/sysprog$ svn commit -m "Added and committed threadTest.c a program to illustrate thread creation and termination -John Rine" Sending sysprog/interface.c Adding sysprog/threadTest.c Transmitting file data .. Committed revision 20. lab46:~/src/sysprog$
I added and committed the code I wrote to implement an array-based queue.
lab46:~/src/data$ svn add queueTest.c A queueTest.c lab46:~/src/data$ svn commit -m "Added and committed an array-based example of a queue -John T. Rine" Adding data/queueTest.c Transmitting file data . Committed revision 21. lab46:~/src/data$
I entered my part deux (II) course objectives for systems programming and data structures courses. I also completed my third experiment for part II. I also wrote system programming topic information for the synchronization methods mutex, and barrier.
malloc is a c library function for dynamically allocating memory in the “heap”.
dynamically allocated memory is memory that has been set aside for use during the execution of the program, also know as “run time”.
malloc can be used to dynamically allocate variables as well as arrays, including multidimensional arrays and structures. The malloc function becomes available for use in a program after the stdlib.h header has been added to the program.
//useMalloc.c //John T. Rine //October 23, 2011 #include<stdlib.h> #include<stdio.h> struct Test { char *message1; char *message2; }; typedef struct Test test; int main(int argc, char **argv) { //malloc a struct test *testPTR; testPTR = (test *)malloc(sizeof(test)); testPTR->message1 = "Hello "; testPTR->message2 = "world!"; printf("Message1 = %s, message2 = %s\n", testPTR->message1, testPTR->message2); free(testPTR); //malloc a char array int i = 0; int ii = 0; char * inputString = "John T. Rine\0"; char * string = NULL; printf("input string contains %s\n", inputString); while(*(inputString + i) != '\0') i++; printf("Character count = %d\n", i); string = (char *)malloc(sizeof(char) * (i + 1)); for(ii = 0; ii <= (i + 1); ii++) *(string + ii) = *(inputString + ii); printf("Dynamically allocated array contains %s\n", string); free(string); return 0; }
Compilation and execution of useMalloc.c were successful as seen below.
lab46:~/src/data$ ./useMalloc Message1 = Hello , message2 = world! input string contains John T. Rine Character count = 12 Dynamically allocated array contains John T. Rine lab46:~/src/data$
Since the data structures class is now making copious use of dynamically allocated memory using malloc and free to allocate and deallocate memory to make, manage, and destroy linked lists, stacks, quesues and so on, wouldn't it be a good idea to understand what the heap is, and how its used?
Dynamically allocated memory is usually allocated from a pool of unused memory known as the “heap” or “free store”. Because the exact memory address of a dynamic memory allocation is not known in advance, dynamically allocated memory is accessed indirectly through the use of pointers.
The exact method used to organize the heap and allocate and deallocate parts of it is hidden behind an abstract interface.
The stack is a last in, first out (LIFO) data structure. A stack can have any data type, including structures as elements, but has only a few basic operations which can be performed on it: initialize or create, push, pop and peek. The initialize or create operation creates a stack and initializes it. The push operation adds a new item to the top of the stack. The pop operation removes an item from the top of the stack. The stack peek operation gets the data from the top of the stack without deleting it or changing the stack pointer.
//arrayStack.c //John T. Rine //October 28, 2011 #include<stdio.h> #include<stdlib.h> struct Stack { char *array; int top; int size; }; typedef struct Stack stack; int cntChars(char *); void createStack(stack *, int); void push(stack *, char); char pop(stack *); int isEmpty(stack *); int isFull(stack *); int main(int argc, char **argv) { int i; int count; stack newStack; char stringArray[200]; printf("Enter a string: "); gets(stringArray); count = cntChars(stringArray); createStack(&newStack, count); if(isEmpty(&newStack)) printf("Stack is empty\n"); else printf("Stack is not empty\n"); for(i = 0; i < count; i++) { push(&newStack,stringArray[i]); printf("The character going into tos is: %c\n", newStack.array[i]); } if(isEmpty(&newStack)) printf("Stack is empty\n"); else printf("Stack is not empty\n"); for(i = 0; i < count; i++) printf("The character in tos is: %c\n", pop(&newStack)); for(i = 0; i < count; i++) { push(&newStack,stringArray[i]); printf("The character going into tos is: %c\n", newStack.array[i]); } push(&newStack,'H'); return 0; } int cntChars(char *inputString) { // returned value "count" does not include '\0' int count = 0; while(*(inputString + count) != '\0') ++count; return(count); } void createStack(stack *stackVar, int size) { char *array; array = (char *)malloc(sizeof(char) * size); if (array == NULL) { fprintf(stderr, "Not enough memory to create the stack.\n"); exit(1); } stackVar->array = array; stackVar->size = size; stackVar->top = -1; } int isEmpty(stack *stackVar) { return stackVar->top < 0; } int isFull(stack *stackVar) { return stackVar->top >= stackVar->size - 1; } void push(stack *stackVar, char element) { if (isFull(stackVar)) { fprintf(stderr, "Can't push on the stack is full\n"); exit(1); } stackVar->array[++stackVar->top] = element; } char pop(stack *stackVar) { if (isEmpty(stackVar)) { fprintf(stderr, "Can't pop from stack; stack is empty\n"); exit(1); } return stackVar->array[stackVar->top--]; }
Execution of the source code listed above with the string “Oh no! I have just been Rick rolled!” as input.
lab46:~/src/data$ gcc arrayStack.c -o arrayStack /tmp/cczFb9N2.o: In function `main': arrayStack.c:(.text+0x35): warning: the `gets' function is dangerous and should not be used. lab46:~/src/data$ ./arrayStack Enter a string: Oh no! I have just been Rick rolled! Stack is empty The character going into tos is: O The character going into tos is: h The character going into tos is: The character going into tos is: n The character going into tos is: o The character going into tos is: ! The character going into tos is: The character going into tos is: I The character going into tos is: The character going into tos is: h The character going into tos is: a The character going into tos is: v The character going into tos is: e The character going into tos is: The character going into tos is: j The character going into tos is: u The character going into tos is: s The character going into tos is: t The character going into tos is: The character going into tos is: b The character going into tos is: e The character going into tos is: e The character going into tos is: n The character going into tos is: The character going into tos is: R The character going into tos is: i The character going into tos is: c The character going into tos is: k The character going into tos is: The character going into tos is: r The character going into tos is: o The character going into tos is: l The character going into tos is: l The character going into tos is: e The character going into tos is: d The character going into tos is: ! Stack is not empty The character in tos is: ! The character in tos is: d The character in tos is: e The character in tos is: l The character in tos is: l The character in tos is: o The character in tos is: r The character in tos is: The character in tos is: k The character in tos is: c The character in tos is: i The character in tos is: R The character in tos is: The character in tos is: n The character in tos is: e The character in tos is: e The character in tos is: b The character in tos is: The character in tos is: t The character in tos is: s The character in tos is: u The character in tos is: j The character in tos is: The character in tos is: e The character in tos is: v The character in tos is: a The character in tos is: h The character in tos is: The character in tos is: I The character in tos is: The character in tos is: ! The character in tos is: o The character in tos is: n The character in tos is: The character in tos is: h The character in tos is: O The character going into tos is: O The character going into tos is: h The character going into tos is: The character going into tos is: n The character going into tos is: o The character going into tos is: ! The character going into tos is: The character going into tos is: I The character going into tos is: The character going into tos is: h The character going into tos is: a The character going into tos is: v The character going into tos is: e The character going into tos is: The character going into tos is: j The character going into tos is: u The character going into tos is: s The character going into tos is: t The character going into tos is: The character going into tos is: b The character going into tos is: e The character going into tos is: e The character going into tos is: n The character going into tos is: The character going into tos is: R The character going into tos is: i The character going into tos is: c The character going into tos is: k The character going into tos is: The character going into tos is: r The character going into tos is: o The character going into tos is: l The character going into tos is: l The character going into tos is: e The character going into tos is: d The character going into tos is: ! Can't push on the stack is full lab46:~/src/data$
A linked list is a data structure whose elements each contain pointers to other elements in the linked list. There are singly-linked lists whose pointers only point in one direction, and doubly-linked lists which has pointers pointing in the direction of head and pointers which point in the direction of the tail. The list is traversed using the pointers contained in the node.
For example, a list can be traversed from the head using the “next” pointer as follows:
temp = head; while(temp != NULL) //while temp is not at the end of the list { printf("%d ",temp->data); //printf the value of the data in the current node temp = temp->next; //load temp with the address of the next node }
//linkedListDev.c //John T. Rine //October 28, 2011 #include<stdio.h> #include<stdlib.h> struct Node { int data; struct Node * prev; struct Node * next; }; typedef struct Node node; void createList(node **, node **, int); void destroyListHead(node *); void destroyListTail(node *); int listSizeHead(node *); int listSizeTail(node *); void printIntDataHead(node *); void insert(node **, node **, int, int); void append(node **, node **, int, int); void deleteNode(node **, node **, int); void loadListData(node *); void loadNode(node *, int, int); void createNode(node*, node*); void copyList(node *, node **, node **); int findData(node *, int); int main(int argc, char **argv) { node *head, *tail, *copyHead, *copyTail, *temp; head = tail = copyHead = copyTail = NULL; int i = 1; printf("Creating a list of 4 nodes...\n"); createList(&head, &tail, 4); printf("Size of the list is: %d\n", listSizeHead(head)); printf("Load list data\n"); loadListData(head); printIntDataHead(head); printf("Inserting node 0 with data of 3200 before head node...\n"); insert(&head, &tail, 0, 3200); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); printf("Inserting node with data of -3200 before tail node...\n"); insert(&head, &tail, listSizeHead(head) - 1, -3200); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); printf("Appending node with data of 2300 after head node...\n"); append(&head, &tail, 0, 2300); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); printf("Appending node with data of -2300 after tail node...\n"); append(&head, &tail, listSizeHead(head) - 1, -2300); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); printf("Loading node 0 with data of 0...\n"); loadNode(head, 0, 0); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); printf("Loading tail node with data of 255...\n"); loadNode(head, listSizeHead(head) - 1, 255); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); printf("Deleting head node...\n"); deleteNode(&head, &tail, 0); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); printf("Deleting tail node...\n"); deleteNode(&head, &tail, listSizeHead(head) - 1); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); printf("Deleting node 2...\n"); deleteNode(&head, &tail, 2); printf("Size of the list is: %d\n", listSizeHead(head)); printIntDataHead(head); copyList(head, ©Head, ©Tail); printf("Size of the list is: %d\n", listSizeHead(copyHead)); printIntDataHead(copyHead); printf("The node location of 3 is %d\n", findData(copyHead, 3)); destroyListHead(head); return 0; } void createList(node **headd, node **taill, int elements) { int i; node *new, *head, *tail; new = head = tail = NULL; for(i = 1; i<=elements; i++) { if (head == NULL) { head = (node *) malloc(sizeof(node)); tail = head; head->prev = NULL; head->next = NULL; } else { new = (node *) malloc(sizeof(node)); new->prev = tail; new->next = NULL; tail->next = new; tail = new; } } *headd = head; *taill = tail; } void destroyListHead(node *head) { node *temp; node *temp2; temp = NULL; temp2 = NULL; temp = head; while(temp != NULL) { temp2 = temp->next; if (temp->prev != NULL) temp->prev = NULL; if (temp->next != NULL) temp->next = NULL; free(temp); temp = temp2; } } void destroyListTail(node *tail) { node *temp; node *temp2; temp = NULL; temp2 = NULL; temp = tail; while(temp != NULL) { temp2 = temp->prev; if (temp->prev != NULL) temp->prev = NULL; if (temp->next != NULL) temp->next = NULL; free(temp); temp = temp2; } } int listSizeHead(node *head) { int size = 0; while (head != NULL) { head = head->next; size++; } return size; } int listSizeTail(node *tail) { int size = 0; while (tail != NULL) { tail = tail->prev; size++; } return size; } void printIntDataHead(node * head) { node * temp = NULL; temp = head; while(temp != NULL) { printf("%d ",temp->data); temp = temp->next; } printf("\n"); } void insert(node ** head, node ** tail, int position, int data) { int i; node *temp, *temp2; temp = temp2 = NULL; temp = *head; for(i = 0; i < position; i++) { temp = temp -> next; } if (*head == NULL) { *head = (node *) malloc(sizeof(node)); *tail = *head; (*head)->prev = NULL; (*head)->next = NULL; (*head)->data = data; } else if (*head == temp) { temp2 = (node *) malloc (sizeof(node)); temp2->next = *head; (*head)->prev = temp2; *head = (*head)->prev; (*head)->prev = NULL; (*head)->data = data; } else { temp2 = (node *) malloc (sizeof(node)); temp2->next = temp; temp2->prev = temp->prev; temp->prev->next = temp2; temp->prev = temp2; temp2->data = data; } } void append(node **head, node **tail, int position, int data) { int i; node *temp, *temp2; temp = temp2 = NULL; temp = *head; for(i = 0; i < position; i++) { temp = temp -> next; } if (*head == NULL) { *head = (node *) malloc(sizeof(node)); *tail = *head; (*head)->prev = NULL; (*head)->next = NULL; (*head)->data = data; } else if (*tail == temp) { temp2 = (node *) malloc (sizeof(node)); temp2->prev = *tail; temp2->next = NULL; (*tail)->next = temp2; *tail = temp2; (*tail)->data = data; } else { temp2 = (node *) malloc (sizeof(node)); temp2->prev = temp; temp2->next = temp->next; temp->next->prev = temp2; temp->next = temp2; temp2->data = data; } } void deleteNode(node **head, node **tail, int position) { int i; node * temp = NULL; temp = *head; for(i = 0; i < position; i++) { temp = temp->next; } if(temp != *head && temp != *tail) { temp->next->prev = temp->prev; temp->prev->next = temp->next; temp->prev = NULL; temp->next = NULL; } else if (temp == *head) { temp->next->prev = NULL; *head = temp->next; temp->next = NULL; } else { temp->prev->next = NULL; *tail = temp->prev; temp->prev = NULL; } free(temp); } void loadListData(node *head) { int i = 0; node *temp = NULL; temp = head; printf("Enter a value or -1 to quit: "); scanf("%d", &i); while(i != -1) { temp->data = i; temp = temp->next; if(temp == NULL) { printf("List is full of data!\n"); break; } printf("Enter a value or -1 to quit: "); scanf("%d", &i); } } void loadNode(node *head, int position, int value) { int i; node *temp = NULL; temp = head; temp = head; for(i = 0; i < position; i++) { temp = temp->next; } temp->data = value; } void createNode(node* head, node* tail) { head = (node *) malloc(sizeof(node)); tail = head; head->prev = NULL; head->next = NULL; } void copyList(node *head, node **copyHead, node **copyTail) { node *new, *temp; new = *copyHead = *copyTail = temp = NULL; temp = head; while(temp != NULL) { if (*copyHead == NULL) { *copyHead = (node *) malloc(sizeof(node)); *copyTail = *copyHead; (*copyHead)->prev = NULL; (*copyHead)->next = NULL; (*copyHead)->data = temp->data; } else { new = (node *) malloc(sizeof(node)); new->prev = *copyTail; new->next = NULL; (*copyTail)->next = new; *copyTail = new; (*copyTail)->data = temp->data; } temp = temp->next; } } int findData(node *head, int data) { int counter = 0; while(head != NULL) { if(head->data == data) break; counter++; head = head->next; } return counter; }
lab46:~/src/data$ ./linkedListDev Creating a list of 4 nodes... Size of the list is: 4 Load list data Enter a value or -1 to quit: 1 Enter a value or -1 to quit: 2 Enter a value or -1 to quit: 3 Enter a value or -1 to quit: 4 List is full of data! 1 2 3 4 Inserting node 0 with data of 3200 before head node... Size of the list is: 5 3200 1 2 3 4 Inserting node with data of -3200 before tail node... Size of the list is: 6 3200 1 2 3 -3200 4 Appending node with data of 2300 after head node... Size of the list is: 7 3200 2300 1 2 3 -3200 4 Appending node with data of -2300 after tail node... Size of the list is: 8 3200 2300 1 2 3 -3200 4 -2300 Loading node 0 with data of 0... Size of the list is: 8 0 2300 1 2 3 -3200 4 -2300 Loading tail node with data of 255... Size of the list is: 8 0 2300 1 2 3 -3200 4 255 Deleting head node... Size of the list is: 7 2300 1 2 3 -3200 4 255 Deleting tail node... Size of the list is: 6 2300 1 2 3 -3200 4 Deleting node 2... Size of the list is: 5 2300 1 3 -3200 4 Size of the list is: 5 2300 1 3 -3200 4 The node location of 3 is 2 lab46:~/src/data$
The element of the stack data structure which is available for stack operations (see the data structures topic “Stack” for details of stack operations) is known as the top of TOS (top of stack).
The stack position top may have data “pushed” (see the data topic “Pushing” for details of the stack operation push) into it at which point the stack pointer, a pointer pointing to the stack element which is available for stack operations, is incremented so as to expose the next stack element for stack operations.
The stack position top may also have data “popped” (see the data topic “Popping” for details of the stack operation pop) from it at which point the stack pointer, is decremented to expose the next stack element for stack operations.
If, a data structure such as a stack is full and cannot accept (store) anymore data, it is considered to be in an overflow state.
If, a data structure, such as a stack, is empty, no more data can be taken from it; it cannot be “popped” again as the data retreived would be erroneous, and the data structure position pointer, the stack pointer in the case of stacks, would be manipulated to point to some memory location which is no longer part of the data structure; this is considered to be the “underflow” state.
The function free, is used to release heap (see the data topic “Heap” for details) memory which was previously allocated dynamically, that is at run time, through the use of one of the memory allocation functions. free takes a single pointer argument; it releases the memory pointed to by its argument.
A structure or record is a collection of variables grouped together under a single identifier. The data are related somehow, that is the point of a structure or record. A classic example of a structure or record is that of an employee. Character array or string members of an employee structure or record might be the employee's first and last names, street, address, city, and state of residence. Integer members of the employee structure or record might be employee number, age, etc. The structure data type, also known as an abstract data type, provides an elegant and powerful way for keeping related data together.
A queue is a FIFO (see the data topic “FILO/FIFO” for details) type data structure. That is, data is taken from the queue in the same order that it was placed into it.
Enqueuing
Dequeue
The following program demonstrates an array-based queue.
//queueTest.c //John T. Rine //October 29, 2011 #include<stdio.h> #include<stdlib.h> struct Queue { char *queueArray; int count; int size; int startIndex; }; typedef struct Queue queue; void createQueue(queue *, int); void destroyQueue(queue *); void enqueue(queue *, char); void printQueue(queue *); int queueCount(queue *); char dequeue(queue *); int main(int argc, char **argv) { queue newQueue; createQueue(&newQueue, 25); destroyQueue(&newQueue); enqueue(&newQueue, 'J'); enqueue(&newQueue, 'o'); enqueue(&newQueue, 'h'); enqueue(&newQueue, 'n'); printf("Calling printQueue(&newQueue)...\n"); printQueue(&newQueue); printf("Calling and printing return value from dequeue...\n"); printf("%c, ", dequeue(&newQueue)); printf("%c, ", dequeue(&newQueue)); printf("\n"); printf("Calling printQueue(&newQueue)...\n"); printQueue(&newQueue); return 0; } void createQueue(queue *queuePTR, int size) { char *queueArrayPTR = NULL; queueArrayPTR = (char *)malloc(sizeof(char) * size); queuePTR->queueArray = queueArrayPTR; queuePTR->size = size; queuePTR->count = 0; queuePTR->startIndex = 0; } void destroyQueue(queue *queuePTR) { free(queuePTR->queueArray); } void enqueue(queue *queuePTR, char data) { int queueArrayIndex; if(queuePTR->count < queuePTR->size) { queueArrayIndex = queuePTR->startIndex + queuePTR->count; queuePTR->queueArray[queueArrayIndex] = data; queuePTR->count++; } else printf("Queue is full!\n"); } void printQueue(queue *queuePTR) { int i; for(i = 0; i < queuePTR->count; i++) printf("%c, ",queuePTR->queueArray[(queuePTR->startIndex + i)%queuePTR->size]); printf("\n"); } int queueCount(queue *queuePTR) { return queuePTR->count; } char dequeue(queue *queuePTR) { char ret; if(queuePTR->count == 0) { printf("queue is empty!\n"); exit(1); } ret = queuePTR->queueArray[queuePTR->startIndex]; queuePTR->count--; queuePTR->startIndex = (queuePTR->startIndex + 1)%queuePTR->size; return ret; }
This is the output of the queueTest.c program:
lab46:~/src/data$ gcc queueTest.c -o queueTest lab46:~/src/data$ ./queueTest Calling printQueue(&newQueue)... J, o, h, n, Calling and printing return value from dequeue... J, o, Calling printQueue(&newQueue)... h, n, lab46:~/src/data$
An array is a set of similar data type data stored in a contiguous section of memory. Since data contained in a array is packaged in similar sized memory blocks and stored in contiguous memory locations, it becomes possible to simply add an array element offset to the base address of the array to access data at a specific element withing the array. The following program illustrates the use off an index to access elements of an array.
//arrayTest.c //John T. Rine //October 29, 2011 #include<stdio.h> int main(int argc, char **argv) { char array[26] = {0}; int i; printf("Enter a string (<= 25 character) to place into a character array\n"); gets(array); printf("array contains %s\n", array); i = 0; while(array[i] != '\0') { printf("array[%d] = %c\n", i, array[i]); printf("*(array + %d) = %c\n", i, *(array + i)); i++; } return 0; }
This is the output of the arrayTest.c program listed above.
lab46:~/src/data$ ./arrayTest Enter a string (<= 25 character) to place into a character array John T. Rine array contains John T. Rine array[0] = J *(array + 0) = J array[1] = o *(array + 1) = o array[2] = h *(array + 2) = h array[3] = n *(array + 3) = n array[4] = *(array + 4) = array[5] = T *(array + 5) = T array[6] = . *(array + 6) = . array[7] = *(array + 7) = array[8] = R *(array + 8) = R array[9] = i *(array + 9) = i array[10] = n *(array + 10) = n array[11] = e *(array + 11) = e lab46:~/src/data$
LIFO is an acronym for “Last In, First Out”; FIFO is an acronym for “First In, First Out”. The stack is a last in, first out or LIFO data structure whereas the queue is a first in, first out or FIFO data structure. Due to the nature of the stack, one use is to reverse the order of data items. The data items to be reveresed are pushed onto the stack, and then to reverse them, they are popped off.
Identification and definition of the chosen keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
The fork() system call takes no arguments and returns a process ID.
fork() is used to create new processes which are child processes of the caller. Once a child process has been created both processes will execute the next instruction following the fork call. The returned PID value is the only way to distinguish between the child and the parent.
If calling fork is successfully executed, Unix/Linux will make two identical copies of address spaces, one for the parent and the other for the child.
Both processes will start their execution at the next statement following fork.
Regarding fork's return value, the man page says the following:
from man fork: RETURN VALUE On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
The following code asks the user to enter the number of iterations that the parent and child processes should execute. Next, fork is called with fork assigning its return value of type pid_t to pid. Once fork is called, fork's return value is used to determine whether what is being printed currently is the child or the parent. If the return value is 0, then its the child, if its some positive value greater than 0, then its the parent.
//forkExample.c //John T. Rine //October 23, 2011 #include <sys/types.h> #include <stdlib.h> #include<stdio.h> #define CHILD 0 int globalTestVar = 0; char *child(int *); char *parent(); char *error(); int main(int argc, char **argv) { char * procID = '\0'; int localTestVar = 0; int *localTestVarPTR = NULL; localTestVarPTR = &localTestVar; pid_t pid; printf("Enter a global variable value\n"); scanf("%d", &globalTestVar); printf("Enter a local variable value\n"); scanf("%d", &localTestVar); pid = fork(); //Error, failed to fork if (pid < CHILD) procID = error(); //child else if (pid == CHILD) procID = child(localTestVarPTR); //parent else procID = parent(); //Executed by both parent and child. printf("procID = %s\n", procID); printf("Global variable = %d\n", globalTestVar); printf("Local variable = %d\n", localTestVar); } char *child(int *localTestVarPtr) { char *procID; procID = "Child Process: "; ++*localTestVarPtr; ++globalTestVar; return procID; } char *parent() { char *procID; procID = "Parent Process:"; return procID; } char *error() { char *procID; procID = "Failed to fork"; return procID; }
Execution of forkExample.c
lab46:~/src/sysprog$ ./forkExample Enter a global variable value 2 Enter a local variable value 3 procID = Parent Process: Global variable = 2 Local variable = 3 procID = Child Process: Global variable = 3 Local variable = 4 lab46:~/src/sysprog$
The main comprises a single, default thread. All other threads must be explicitly created by the programmer.
The function pthread_create creates a new thread and makes it executable. This routine can be called any number of times from anywhere within your code. The maximum number of threads that may be created by a process is implementation dependent.
For example, the code below uses the number of arguments other than the file name (argc - 1) to create a given number of threads in the program.
There are many ways in which a thread may be terminated. The thread returns normally from its starting routine. It's work is done. The thread makes a call to the pthread_exit whether its work is done or not. The thread is canceled by another thread via the pthread_cancel routine. The entire process is terminated due to making a call to either the exec() or exit(). If main() finishes first, without calling pthread_exit explicitly itself.
The program below uses the following pthread library functions:
pthread_exit() enables the programmer to specify an optional termination status parameter. This optional parameter is typically returned to threads “joining” the terminated thread.
Regarding the calling of pthread_exit from main, there is a problem if main finishes before the threads it created if pthread_exit() isn't called explicitly. All of the threads it created will terminate because main is done and no longer exists to support the threads.
By having main explicitly call pthread_exit as the last thing it does, main will kept alive to support the threads it created until they are done.
//threadTest.c //John T. Rine //October 29, 2011 #include <pthread.h> #include <stdio.h> #include <stdlib.h> void *PrintMessage(void *message) { printf("%s\n", message); pthread_exit(NULL); } int main(int argc, char **argv) { if(argc == 1) { printf("No threads specified, exiting...\n"); exit(1); } pthread_t threads[argc - 1]; int rc, t; for(t=0;t<argc - 1;t++) { printf("In main: creating thread %ld\n", t); rc = pthread_create(&threads[t], NULL, PrintMessage, *(argv + t + 1)); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_exit(NULL); }
Compilation, linking, and execution of the code listed above:
lab46:~/src/sysprog$ gcc threadTest.c -o threadTest -lpthread lab46:~/src/sysprog$ ./threadTest No threads specified, exiting... lab46:~/src/sysprog$ ./threadTest John In main: creating thread 0 John lab46:~/src/sysprog$ ./threadTest John Thomas In main: creating thread 0 In main: creating thread 1 John Thomas lab46:~/src/sysprog$ ./threadTest John Thomas Rine In main: creating thread 0 In main: creating thread 1 John In main: creating thread 2 Thomas Rine lab46:~/src/sysprog$
POSIX is an acronym for “Portable Operating System Interface for UniX”. POSIX is the name of a set of related standards specified by the IEEE to define the application programming interface (API), along with shell and utilities interfaces, for software compatible with variants of the Unix operating system, although the standard can apply to any operating system. POSIX support guarantees code is portable from system to system and it is increasingly becoming a requirement that applications conform to POSIX standards. For example, the USA's Joint Technical Architecture—Army (JTA-A) standards set specifies that conformance to the POSIX standard is critical to support software interoperability.
Wikipedia (http://en.wikipedia.org/wiki/POSIX) lists items addressed in the various versions of POSIX: Parts before 1997, POSIX comprised several standards: POSIX.1, Core Services (incorporates Standard ANSI C) (IEEE Std 1003.1-1988) * Process Creation and Control * Signals * Floating Point Exceptions * Segmentation / Memory Violations * Illegal Instructions * Bus Errors * Timers * File and Directory Operations * Pipes * C Library (Standard C) * I/O Port Interface and Control * Process Triggers POSIX.1b, Real-time extensions (IEEE Std 1003.1b-1993) * Priority Scheduling * Real-Time Signals * Clocks and Timers * Semaphores * Message Passing * Shared Memory * Asynch and Synch I/O * Memory Locking Interface POSIX.1c, Threads extensions (IEEE Std 1003.1c-1995) * Thread Creation, Control, and Cleanup * Thread Scheduling * Thread Synchronization * Signal Handling POSIX.2, Shell and Utilities (IEEE Std 1003.2-1992) * Command Interpreter * Utility Programs Versions after 1997, the Austin Group developed the POSIX revisions. The specifications are known under the name Single UNIX Specification, before they become a POSIX standard when formally approved by the ISO. POSIX:2001 or IEEE Std 1003.1-2001 equates to the Single UNIX Specification version 3[5] This standard consisted of: * the Base Definitions, Issue 6, * the System Interfaces and Headers, Issue 6, * the Commands and Utilities, Issue 6. POSIX:2004 or IEEE Std 1003.1-2004 involved a minor update of POSIX:2001. It incorporated two technical corrigenda.[6] Its contents are available on the web.[7] POSIX:2008 As of 2009[update] POSIX:2008 or IEEE Std 1003.1-2008 represents the current version.[8][9] A free online copy is available.[10] This standard consists of: * the Base Definitions, Issue 7, * the System Interfaces and Headers, Issue 7, * the Commands and Utilities, Issue 7.
The semaphore is a synchronization method. A semaphore is a kernel variable that is accessible by all of the processes currently executing on the system.
Processes use semaphores to coordinate access to shared system resources between them. A semaphore is a counter; when it is zero, the semaphore can block a thread’s execution using sem_wait until another thread increments the counter using sem_post.
The following example code came from http://pages.cs.wisc.edu/~travitch/pthreads_primer.html
This is the result of compiling, linking and then executing the example code listed above:
#include <semaphore.h> #include <pthread.h> #include <stdio.h> #define THREADS 20 sem_t OKToBuyMilk; int milkAvailable; void* buyer(void *); int main(int argc, char **argv) { int i; pthread_t threads[THREADS]; milkAvailable = 0; // Initialize the semaphore with a value of 1. // Note the second argument: passing zero denotes // that the semaphore is shared between threads (and // not processes). if(sem_init(&OKToBuyMilk, 0, 1)) { printf("Could not initialize a semaphore\n"); return -1; } for(i = 0; i < THREADS; ++i) { if(pthread_create(&threads[i], NULL, &buyer, NULL)) { printf("Could not create thread %d\n", i); return -1; } } for(i = 0; i < THREADS; ++i) { if(pthread_join(threads[i], NULL)) { printf("Could not join thread %d\n", i); return -1; } } sem_destroy(&OKToBuyMilk); // Make sure we don't have too much milk. printf("Total milk: %d\n", milkAvailable); return 0; } void* buyer(void *arg) { // P() sem_wait(&OKToBuyMilk); if(!milkAvailable) { // Buy some milk ++milkAvailable; } // V() sem_post(&OKToBuyMilk); return NULL; }
lab46:~/src/sysprog$ gcc testSemaphore.c -o testSemaphore -lpthread lab46:~/src/sysprog$ ./testSemaphore Total milk: 1 lab46:~/src/sysprog$
The mutex is a synchronization method. The word mutex means mutual exclusion (between threads in this usage) and is a combination of the two words as follows: MUTual EXclusion. A mutex is used cooperatively between threads to guarantee that only one of the threads is allowed to access shared memory or run certain application code at a time.
The barrier is a synchronization method. A barrier for a set of threads or processes makes any thread or process stop at mutex and cannot continue until the remaining threads or processes reach this barrier.
File locking is a device that controls access to a file by allowing only one process to access it at one time.
Asynchronous input, is a non-blocking type of I/O that allows other processing to continue while input is being received.
First, Linux utilizes permissions bits to control file access. There are three types of access: read, write, and execute.
Also there is file locking which is a device that controls access to a file by allowing only one process to access it at one time.
Kernel space is protected, nothing contained in it can be used in a program (called) directly. There are therefore services which are provided to act as interfaces between applications in user space and the kernel. A system call is the only way a programmer may use these services.
Individual bits within a larger data package, a byte for instance, can be used to represent something.
So rather than having a variable hold a value that represents only one thing, each bit within the variable can represent something.
One example of the use of bit sets would be using chmod to set file permissions.
Bit masks are used to manipulate only certain bits within a larger data package. Bit masking of data is carried out using two things, a bit mask, and a bitwise logical operation.
Bit masks are used to either select or deselect which bits are set or changed; bitwise operations actually change the data based on the bit mask value.
For example, data bits can be set using the bitwise or:
data = 00000000 mask = 01010101 data = data | bit mask data = 01010101
Data bits can be reset using bitwise and:
data = 11111111 mask = 01010101 data = data & bit mask data = 01010101
Other bitwise operations which can be used to bit mask and bit set repectively are exclusive or and complement.
A signal is a software interrupt delivered to a process when an event occurs.
The code below was taken from http://www.c.happycodings.com/Gnu-Linux/code18.html and is used to demonstrate how signals work in a program.
//http://www.c.happycodings.com/Gnu-Linux/code18.html //Signal, catch Ctrl-C #include <stdio.h> #include <unistd.h> /* sleep(1) */ #include <signal.h> void ex_program(int sig); int main(void) { (void) signal(SIGINT, ex_program); while(1) printf("sleeping .. ZZZzzzz ....\n"), sleep(1); return 0; } void ex_program(int sig) { printf("Wake up call ... !!! - Catched signal: %d ... !!\n", sig); (void) signal(SIGINT, SIG_DFL); }
Executing the code listed above produces the following output:
lab46:~/src/sysprog$ gcc sigTest.c -o sigTest lab46:~/src/sysprog$ ./sigTest sleeping .. ZZZzzzz .... sleeping .. ZZZzzzz .... sleeping .. ZZZzzzz .... sleeping .. ZZZzzzz .... sleeping .. ZZZzzzz .... sleeping .. ZZZzzzz .... ^CWake up call ... !!! - Catched signal: 2 ... !! sleeping .. ZZZzzzz .... sleeping .. ZZZzzzz .... sleeping .. ZZZzzzz .... sleeping .. ZZZzzzz .... ^C lab46:~/src/sysprog$
I would like to become more familiar with the various data structures, specific uses for each and be able to use them in applications.
I will learn more about linked-lists, stacks, queues, graphs and trees by:
Research and analysis of experimental results: see “Pushing” and “Popping” Part I Data Structures topics, also see “Overflow”, “Underflow”, “Linked list”, “Queues”, “malloc”, “free” Part II Data Structures topics for details.
I have written linked list and stack libraries using linked nodes. I have also written array-based stacks and queues, each have dynamically-sized arrays all which compiled, linked, and executed successfully.led, linked and executed successfully.
State the course objective; define what that objective entails.
State the method you will use for measuring successful academic/intellectual achievement of this objective.
Follow your method and obtain a measurement. Document the results here.
Reflect upon your results of the measurement to ascertain your achievement of the particular course objective.
I would like to understand fork, what its purpose for being is and about spawning child processes in more detail.
I would also like to understand mutltithreading, thread synchronization in more detail. I would like to understand more about parallel computing and how fork and multithreading play a part
I will learn more about concurrency, fork, child processes, multithreading, and thread synchronization by:
Research and analysis of experimental results: see “Threads”, ““Multithreading”, and “Semaphore” under Part I of the System programming topics, also see “Threads part deux”, “Semiphores” and “Mutexes” Part II Systeme programming topics for details.
I wrote a simple mulithreaded application which compiled, linked and executed successfully. Regarding semaphores, I experimented with code which I found on the Internet. I was able, after modifying it, to compile, link and execute it. I worked with functions from both pthreads.h and semaphore.h.
Is it possible to assign a string literal (using double-quotation marks), to a block of memory that has been dynamically allocated but has not had data yet assigned to it?
Since it is possible to assign a string literal to a character pointer and then use it in a program (i.e.print out the data it points to), it should be possible to assign a string literal to pointer, pointing to a dynamically-allocated block of memory which hasn't yet been assigned data and then when the data is no longer needed, free it.
For example:
//testStringLiteral.c //John T. Rine //October 24, 2011 #include<stdio.h> int main(int argc, char **argv) { char * nameStringPTR = NULL; nameStringPTR = "John T. Rine"; printf("nameStringPTR points to: %s\n:", nameStringPTR); return 0; }
And the execution:
lab46:~/src/data$ gcc testStringLiteral.c -o testStringLiteral lab46:~/src/data$ ./testStringLiteral nameStringPTR points to: John T. Rine lab46:~/src/data$
This version of the testMalloc.c program corresponds to the first set of program output in the data section below.
//testMalloc.c //John T. Rine //October 24, 2011 #include<stdlib.h> #include<stdio.h> int main(int argc, char **argv) { //malloc a char array char *arrayPTR = NULL; arrayPTR = malloc(sizeof(char) * 10); arrayPTR = "John Rine\0"; printf("My name is: %s\n", arrayPTR); free(arrayPTR); return 0; }
This version of the testMalloc.c program, with free commented out, corresponds to the second set of program output listed in the data section below.
//testMalloc.c //John T. Rine //October 24, 2011 #include<stdlib.h> #include<stdio.h> int main(int argc, char **argv) { //malloc a char array char *arrayPTR = NULL; arrayPTR = malloc(sizeof(char) * 10); arrayPTR = "John Rine\0"; printf("My name is: %s\n", arrayPTR); //free(arrayPTR); return 0; }
This version of the testMalloc.c program, also with free commented out, corresponds to the third set of program output listed in the data section below. Note that printf function calls have been added to check the address contained in arrayPTR before and after assigning the string to the character pointer.
//testMalloc.c //John T. Rine //October 24, 2011 #include<stdlib.h> #include<stdio.h> int main(int argc, char **argv) { //malloc a char array char *arrayPTR = NULL; arrayPTR = malloc(sizeof(char) * 10); printf("The address contained in arrayPTR before assigning a string is: 0x%x\n", arrayPTR); arrayPTR = "John Rine\0"; printf("The address contained in arrayPTR before assigning a string is: 0x%x\n", arrayPTR); printf("My name is: %s\n", arrayPTR); //free(arrayPTR); return 0; }
This last version of testMalloc.c assigns the individual characters in the string to the character-sized memory locations pointed to by the character pointer assigned to point to the dynamically allocated memory.
//testMalloc.c //John T. Rine //October 23, 2011 #include<stdlib.h> #include<stdio.h> int main(int argc, char **argv) { //malloc a char array int i = 0; int ii = 0; char * inputString = "John T. Rine\0"; char * string = NULL; printf("input string contains %s\n", inputString); while(*(inputString + i) != '\0') i++; printf("Character count = %d\n", i); string = (char *)malloc(sizeof(char) * (i + 1)); for(ii = 0; ii <= (i + 1); ii++) *(string + ii) = *(inputString + ii); printf("Dynamically allocated array contains %s\n", string); free(string); return 0; }
Program output after assigning a string to a character pointer which points to a set of dynamically allocated character sized memory locations, printing out the contents pointed to, and then the freeing the memory. This output was created by the first version of the testMalloc.c program listed in the Experiment section listed above.
lab46:~/src/data$ gcc testMalloc.c -o testMalloc lab46:~/src/data$ ./testMalloc My name is: John Rine *** glibc detected *** ./testMalloc: free(): invalid pointer: 0x00000000004006cc *** ======= Backtrace: ========= /lib/libc.so.6(+0x71ad6)[0x7f9874d51ad6] /lib/libc.so.6(cfree+0x6c)[0x7f9874d5684c] ./testMalloc[0x4005d6] /lib/libc.so.6(__libc_start_main+0xfd)[0x7f9874cfec4d] ./testMalloc[0x4004c9] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 00:11 2147645911 /home/jr018429/src/data/testMalloc 00600000-00601000 rw-p 00000000 00:11 2147645911 /home/jr018429/src/data/testMalloc 01f1e000-01f3f000 rw-p 00000000 00:00 0 [heap] 7f9870000000-7f9870021000 rw-p 00000000 00:00 0 7f9870021000-7f9874000000 ---p 00000000 00:00 0 7f9874aca000-7f9874ae0000 r-xp 00000000 ca:01 57346 /lib/libgcc_s.so.1 7f9874ae0000-7f9874cdf000 ---p 00016000 ca:01 57346 /lib/libgcc_s.so.1 7f9874cdf000-7f9874ce0000 rw-p 00015000 ca:01 57346 /lib/libgcc_s.so.1 7f9874ce0000-7f9874e38000 r-xp 00000000 ca:01 57396 /lib/libc-2.11.2.so 7f9874e38000-7f9875037000 ---p 00158000 ca:01 57396 /lib/libc-2.11.2.so 7f9875037000-7f987503b000 r--p 00157000 ca:01 57396 /lib/libc-2.11.2.so 7f987503b000-7f987503c000 rw-p 0015b000 ca:01 57396 /lib/libc-2.11.2.so 7f987503c000-7f9875041000 rw-p 00000000 00:00 0 7f9875041000-7f987505f000 r-xp 00000000 ca:01 57564 /lib/ld-2.11.2.so 7f987524c000-7f987524f000 rw-p 00000000 00:00 0 7f987525b000-7f987525e000 rw-p 00000000 00:00 0 7f987525e000-7f987525f000 r--p 0001d000 ca:01 57564 /lib/ld-2.11.2.so 7f987525f000-7f9875260000 rw-p 0001e000 ca:01 57564 /lib/ld-2.11.2.so 7f9875260000-7f9875261000 rw-p 00000000 00:00 0 7fffca6cc000-7fffca6e1000 rw-p 00000000 00:00 0 [stack] 7fffca6f3000-7fffca6f4000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted lab46:~/src/data$
Program output with free commented out. This output was created by the second version of the testMalloc.c program listed in the experiment section above.
lab46:~/src/data$ ./testMalloc My name is: John Rine lab46:~/src/data$
Program output with free commented out and with printf function calls to print out the address contained in arrayPTR before and after assigning the string to the character pointer. This program output was created by the third version of the testMalloc program listed in the experiment section above.
lab46:~/src/data$ gcc testMalloc.c -o testMalloc lab46:~/src/data$ ./testMalloc The address contained in arrayPTR before assigning a string is: 0x86d010 The address contained in arrayPTR before assigning a string is: 0x4006f6 My name is: John Rine lab46:~/src/data$
This last set of program output corresponds the the last incarnation of the testMalloc.c program listed above in the experiment section.
lab46:~/src/data$ gcc testMalloc.c -o testMalloc lab46:~/src/data$ ./testMalloc input string contains John T. Rine Character count = 12 Dynamically allocated array contains John T. Rine lab46:~/src/data$
Based on the data collected, my hypothesis was proven to not be correct.
The first verision of the testMalloc.c program crashed when free executed which seemed to indicate that the issue seemed to be misuse of the free function.
The second version of the program, in which free was commented out, ran flawlessly reinforcing the notion that the issue has to do with free.
The third version of the program introduced printf calls to print out the address of arrayPTR before and after the assignment of the string literal to it. This version of the program demonstrates that assigning a string literal to a pointer pointing to newly allocated and not yet used memory causes the address stored in the pointer to no longer point to the dynamically llocated memory, but to the beginning address of the string literal. Therefore, when free attempted to free memory no longer being pointed to, it caused an exception to be thrown.
The fourth and final version of the testMalloc.c program demonstrates that the proper way to assign a string to dynamically allocated memory in C is to do it character by character.
In C, even though it is possible to assign a string literal to a pointer and then use it, it is not possible to assign a string literal directly to a pointer pointing to dynamically allocated memory. This is because assigning a string literal to it changes the address stored in it so that when the memory is later freed, an exception is thrown because the pointer no longer points to the dynamically allocated memory.
Is it possible to use curses library input functions to handle and/or get function (F) keys in the same way that other key characters are handledretrieved?
Currently, for my system programming projects, I am developing a GUI (Graphical User Interface) interface, with which to program and display the results of operations (register values), for the 8085 CPU project begun in Computer Organization last sememster.
The GUI is to be developed using curses. I started with a function to read keyboardin input, however, the curses input function, getch, could not recognize the function (F) keys for some reason.
Date: Sun, 18 Sep 2011 21:25:29 -0400 (EDT) From: John Rine <jr018429@lab46.corning-cc.edu> Reply-To: "\\\"Systems\\\" Classes Discussion List" <sys@lab46.corning-cc.edu> To: sys@lab46.corning-cc.edu Subject: [SYS] Trouble with Curses recognizing F keys and other keyboard keys All, I am having trouble with curses recognizing function keys and the escape key. I am using code like this: #include<curses.h> int main() { int c; initscr(); keypad(stdscr,TRUE); noecho(); move(0,0); c=getch(); while(c != KEY_F(1) && c != 'q') { move(0,0); printw("%c\n",c); refresh(); c=getch(); } endwin(); return 0; } it will exit with 'q' but not KEY_F(1) or the F1 key. Also, the esc key is not recognized when using the KEY_EXIT constant. Anyone have any ideas as to how to get function keys and the escape key to work with curses? thanks, John T. Rine --- Lab46: Penguin Powered
The instructor stated that he didn't have experience with curses and functions keys, but that this question could be the basis for an experiment; he challenged me to, using the scientific method, put together a hypothesis and a set of experiments whose outcome would help me answer the question posed.
Date: Mon, 19 Sep 2011 08:43:07 -0400 From: Matthew Haas <wedge@lab46.corning-cc.edu> Reply-To: "\\\"Systems\\\" Classes Discussion List" <sys@lab46.corning-cc.edu> To: sys@lab46.corning-cc.edu Subject: Re: [SYS] Trouble with Curses recognizing F keys and other keyboard keys On 09/18/2011 09:25 PM, John Rine wrote: > > I am having trouble with curses recognizing function keys and the escape key. > I am using code like this: > #include<curses.h> > > int main() > { > int c; > initscr(); > keypad(stdscr,TRUE); > noecho(); > move(0,0); > c=getch(); > while(c != KEY_F(1) && c != 'q') > { > move(0,0); > printw("%c\n",c); > refresh(); > c=getch(); > } > endwin(); > return 0; > } > it will exit with 'q' but not KEY_F(1) or the F1 key. Also, the esc key is not recognized when using the KEY_EXIT constant. Anyone have any ideas as to how to get > function keys and the escape key to work with curses? I've never played with the function keys... so that would take some experimenting. Escape, even though there may not be a #define for it (all the keys available to you are #define'd in /usr/include/curses.h, check it out), has a value. The trick is, what is it? Hmm... this could be another experiment. If you know that pretty much every key on the keyboard has a value (which ones do not have a direct value?), how could we figure out what the values of keys are? What is the data type of the 'c' variable in the program above? What type of data are we displaying in the printw() function call above? Could you perhaps CHANGE the format specifier to match the actual data type of the 'c' variable? What would happen then? If you then compile and run the program and start pressing keys, what happens? What do you see when you press 'a', 'A', spacebar? Do you know what these values correspond to? What do you think happens when you start pressing some keys that do not directly have printable characters associated with them, like... escape. What does it display? -Matthew -- Matthew Haas Lab46 System Administrator Instructor of Computer& Information Science http://lab46.corning-cc.edu/haas/home/ _______________________________________________ SYS mailing list SYS@lab46.corning-cc.edu http://lab46.corning-cc.edu/mailman/listinfo/sys
Based on what I've read, it should be possible to uses curses library functions to handle function key input.
Since I was having trouble getting curses functions to recognize function (F) keys, I designed a simple program to read keyboard input using a curses function and then printed out the results. The program has the minium required to read and verify keyboard input.
//curseskeys.c //John T. Rine //October 29, 2011 #include <ncurses.h> int main() { int ch; initscr(); raw(); keypad(stdscr, TRUE); noecho(); printw("Type any character\n"); ch = getch(); if(ch == KEY_F(1)) printw("F1 Key pressed"); else { printw("The pressed key is "); printw("%c", ch); } refresh(); getch(); endwin(); return 0; }
Since the F keys were not being recognized by the curses getch function, I wrote a program that gets keyboard input from stdin and stores it in an array. I then print out the characters stored in the array.
//getFkeys.c //John T. Rine //October 29, 2011 #include<stdio.h> int main(int argc, char **argv) { char array[10] = { 0 }; int i; char c; fgets(array,9,stdin); for (i = 0; i < 10; i++) printf("Array[%d] = %d\n", i, array[i]); return 0; }
curseskeys.c execution with puTTY keyboard function and keyboard keys set to ESC[n~.
Result of entering the character 'a':
Type any character The pressed key is a
Result of entering the F1 key:
lab46:~/src/sysprog$ ./curseskeys lab46:~/src/sysprog$ ~
curseskeys.c execution with puTTY keyboard function and keyboard keys set to VT100+.
Result of entering the 'a' key:
Type any character The pressed key is a
Result of entering the F1 key:
Type any character F1 Key pressed
getFkeys.c execution with puTTY keyboard function and keyboard keys set to ESC[n~.
Result of entering the character 'a':
lab46:~/src/sysprog$ ./getFkeys a Array[0] = 97 Array[1] = 10 Array[2] = 0 Array[3] = 0 Array[4] = 0 Array[5] = 0 Array[6] = 0 Array[7] = 0 Array[8] = 0 Array[9] = 0
Result of entering the F1 key:
lab46:~/src/sysprog$ ./getFkeys ^[[11~ Array[0] = 27 Array[1] = 91 Array[2] = 49 Array[3] = 49 Array[4] = 126 Array[5] = 10 Array[6] = 0 Array[7] = 0 Array[8] = 0 Array[9] = 0 lab46:~/src/sysprog$
getFkeys.c execution with puTTY keyboard function and keyboard keys set to VT100+.
Result of entering the character 'a':
lab46:~/src/sysprog$ ./getFkeys a Array[0] = 97 Array[1] = 10 Array[2] = 0 Array[3] = 0 Array[4] = 0 Array[5] = 0 Array[6] = 0 Array[7] = 0 Array[8] = 0 Array[9] = 0 lab46:~/src/sysprog$
Result of entering the F1 key:
lab46:~/src/sysprog$ ./getFkeys ^[OP Array[0] = 27 Array[1] = 79 Array[2] = 80 Array[3] = 10 Array[4] = 0 Array[5] = 0 Array[6] = 0 Array[7] = 0 Array[8] = 0 Array[9] = 0 lab46:~/src/sysprog$
The data (program output from curseskeys.c) indicates that in order to use the curses getch function to get function (F) key input, the keyboard setting in puTTY must be set to something other than ESC[n~. The program executions that were able to read function (F) key input in this experiment were performed with the keyboad setting st to VT100+. The data collected from the the program output of getFkeys.c indicates that the keyboard/terminal settings do infact influence what is returned from a function (F) key keypress. With the puTTY keyboard/function key setting set to ESC[n~, the output of getFkeys.c with a character input of 'a' is:
a Array[0] = 97 Array[1] = 10 Array[2] = 0 Array[3] = 0 Array[4] = 0 Array[5] = 0 Array[6] = 0 Array[7] = 0 Array[8] = 0 Array[9] = 0
whereas the output with the puTTY keyboard/function key setting set as above, the output of getFkeys.c with a keyboard input of F1 is:
^[[11~ Array[0] = 27 Array[1] = 91 Array[2] = 49 Array[3] = 49 Array[4] = 126 Array[5] = 10 Array[6] = 0 Array[7] = 0 Array[8] = 0 Array[9] = 0
With the puTTY keyboard/function key setting set to VT100+, the output of getFkeys.c with a character input of 'a' is:
a Array[0] = 97 Array[1] = 10 Array[2] = 0 Array[3] = 0 Array[4] = 0 Array[5] = 0 Array[6] = 0 Array[7] = 0 Array[8] = 0 Array[9] = 0
whereas the output with the puTTY keyboard/function key setting set as above, the output of getFkeys.c with a keyboard input of F1 is:
^[OP Array[0] = 27 Array[1] = 79 Array[2] = 80 Array[3] = 10 Array[4] = 0 Array[5] = 0 Array[6] = 0 Array[7] = 0 Array[8] = 0 Array[9] = 0
indicating that the keyboard/terminal settings do NOT influence what is returned when a character key is pressed, but do influence what is returned when a function (F) key is pressed.
Since it appears that the terminal keyboard/function key setting does influence what is returned when a function (F) key is pressed, it would be a good idea to guarantee termminal settings before an applications, using function keys, executes. This could, or should be able to be accomplished either through the use of a shell script, modifying a system configuration file, or through the use of a programming library.
If the library header file for functions used in a program is included in a source file, shouldn't compiling the source file alone cause the creation of an executable (that is linking is automatic, after all, the header file for the library was included in the source file)?
Based on what I've read it should not link successfuly because standard c libraries are located in libc.so, while the math library is located in libm.so. The standard c libraries are linked by default, whereas the math library is not.
I used the following program to collect data for the experiment. This file has math.h and stdio.h headers file included in the source file.
//mathTest.c ///John T. Rine //October 30, 2011 #include <math.h> #include <stdio.h> int main (int argc, char **argv) { double x = 0; printf("Enter a value to takes its square root\n"); scanf("%lf", &x); printf ("The square root of %lf is %lf\n", x, sqrt(x)); return 0; }
These are the results of the first attempt at compiling mathTest.c; the exact invocation of the gcc compiler uses was: gcc mathTest.c -o mathTest
lab46:~/src/sysprog$ gcc mathTest.c -o mathTest /tmp/ccJHwf08.o: In function `main': mathTest.c:(.text+0x51): undefined reference to `sqrt' collect2: ld returned 1 exit status lab46:~/src/sysprog$
These are the results of the second attempt at compiling mathTest.c; the exact invocation of the gcc compiler used was: gcc mathTest.c -o mathTest -lm
lab46:~/src/sysprog$ gcc mathTest.c -o mathTest -lm lab46:~/src/sysprog$
This are the results of executing the program after successfully compiling and linking it.
lab46:~/src/sysprog$ ./mathTest Enter a value to takes its square root 144 The square root of 144.000000 is 12.000000 lab46:~/src/sysprog$
My hypothesis was correct as can be seen from the data collected from the experiment. If the math library is not linked, no executable is created, however, if the math library is linked, them the executable is created successfully.
If a library is not part of the C standard library, when the program is being compiled and linked there must be something to indicate what should be linked.
Since curses is not part of the C standard library, what happened while compiling and linking the math library will also occur when a curses program is compiled and linked.
For example compiling and linking a curses program without indicating what should be linked:
lab46:~/src/sysprog$ gcc curseskeys.c -o curseskeys /tmp/cco3mJn0.o: In function `main': curseskeys.c:(.text+0x9): undefined reference to `initscr' curseskeys.c:(.text+0xe): undefined reference to `raw' curseskeys.c:(.text+0x15): undefined reference to `stdscr' curseskeys.c:(.text+0x22): undefined reference to `keypad' curseskeys.c:(.text+0x27): undefined reference to `noecho' curseskeys.c:(.text+0x36): undefined reference to `printw' curseskeys.c:(.text+0x3d): undefined reference to `stdscr' curseskeys.c:(.text+0x45): undefined reference to `wgetch' curseskeys.c:(.text+0x60): undefined reference to `printw' curseskeys.c:(.text+0x71): undefined reference to `printw' curseskeys.c:(.text+0x85): undefined reference to `printw' curseskeys.c:(.text+0x8c): undefined reference to `stdscr' curseskeys.c:(.text+0x94): undefined reference to `wrefresh' curseskeys.c:(.text+0x9b): undefined reference to `stdscr' curseskeys.c:(.text+0xa3): undefined reference to `wgetch' curseskeys.c:(.text+0xa8): undefined reference to `endwin' collect2: ld returned 1 exit status lab46:~/src/sysprog$
Compiling and linking a curses program with an indication of what should be linked:
lab46:~/src/sysprog$ gcc curseskeys.c -o curseskeys -lcurses lab46:~/src/sysprog$
It is an interesting observation that the math library is linked as -lm and its dynamic library file name is libm.so. The curses library is linked as -lcurses; this implies that the curses dynamic library file name should be libcurses.so.
Since the math library is included in a source file as #include<math.h>, and since the curses library is included in a source file as #include<curses.h>, then these dynamic libraries should be in the same path and also be in the same path as the c standard library (libc.so). A search for libcurses.so, therefore, int the c library path should be successful; there should be a dynamic library file by the name of libcurses.so in the c library path.
I added and committed queue data structure library project files after completing the project.
lab46:~/src/data$ svn add queue A queue A queue/createFixedQueue.c A queue/deQueue.c A queue/copyQueue.c A queue/destroyFixedQueue.c A queue/isEmpty.c A queue/enQueue.c A queue/listQueueSize.c A queue/makeQueue.bat A queue/queue.h A queue/queueTest.c A queue/makeQueue.old A queue/makeQueue.sh A (bin) queue/queueTest lab46:~/src/data$ svn commit -m "Added and committed queue files -John T. Rine" Sending data/Stack/libdll.a Adding data/queue Adding data/queue/copyQueue.c Adding data/queue/createFixedQueue.c Adding data/queue/deQueue.c Adding data/queue/destroyFixedQueue.c Adding data/queue/enQueue.c Adding data/queue/isEmpty.c Adding data/queue/listQueueSize.c Adding data/queue/makeQueue.bat Adding data/queue/makeQueue.old Adding data/queue/makeQueue.sh Adding data/queue/queue.h Adding (bin) data/queue/queueTest Adding data/queue/queueTest.c Transmitting file data .............. Committed revision 24. lab46:~/src/data$
I cleaned up (finalized) my queue library and then committed it to the Subversion repository.
lab46:~/src/data/queue$ svn commit -m "Cleaned up queue library -John T. Rine" Sending queue/deQueue.c Sending queue/queueTest Sending queue/queueTest.c Transmitting file data ... Committed revision 25. lab46:~/src/data/queue$
I worked on data and system programming topics.
I worked on data and system programming topics.
Once again, I worked on data and system programming topics. In particular, I wrote selection and bubble sorting code for data topics. I then added and committed the code to the Subversion repository:
lab46:~/src/data$ svn add selection* A selection.bat A selection.c lab46:~/src/data$ svn add bubble* A bubble.bat A bubble.c lab46:~/src/data$ svn commit -m "Added and committed selection and bubble sort example code -John T. Rine" Adding data/bubble.bat Adding data/bubble.c Adding data/selection.bat Adding data/selection.c Transmitting file data .... Committed revision 26.
I worked on data and system programming topics. In particular, I wrote insertion sorting code for data topics. I then added and committed the code to the Subversion repository:
lab46:~/src/data$ svn add insertion* A insertion.bat A insertion.c lab46:~/src/data$ svn commit -m "Added and committed insertion sort files -John T. Rine" Adding data/insertion.bat Adding data/insertion.c Transmitting file data .. Committed revision 27. lab46:~/src/data$
Next, I updated the insertion.c file and then re-committed it.
lab46:~/src/data$ svn commit -m "Updated insertion sort file -John T. Rine" Sending data/insertion.c Transmitting file data . Committed revision 28. lab46:~/src/data$
For one of my data topics, I wrote, compiled, and executed a file demonstrating the binary search algorithm.
lab46:~/src/data/binarySearch$ gcc binarySearch.c -o binarySearch lab46:~/src/data/binarySearch$ ./binarySearch ABCDEFGHIJKLMNOPQRSTUVWXYZ U 0 25 Now performing a binary search for element U, between elements 0 and 25 left = 0, right = 25, middle = 0, element = -1, value = U left = 13, right = 25, middle = 12, element = -1, value = U left = 20, right = 25, middle = 19, element = -1, value = U left = 20, right = 21, middle = 22, element = -1, value = U The element containing the value is 20 (-1 indicates element not found) lab46:~/src/data/binarySearch$ cd .. lab46:~/src/data$ svn add binarySearch A binarySearch A binarySearch/binarySearch.c A (bin) binarySearch/binarySearch.exe A binarySearch/binarySearch.bat A (bin) binarySearch/binarySearch lab46:~/src/data$ svn commit -m "Added and committed binary search files -John T. Rine" Adding data/binarySearch Adding (bin) data/binarySearch/binarySearch Adding data/binarySearch/binarySearch.bat Adding data/binarySearch/binarySearch.c Adding (bin) data/binarySearch/binarySearch.exe Transmitting file data .... Committed revision 29. lab46:~/src/data$
I added and committed sorting source files to the Subversion repository.
lab46:~/src/data$ svn add sorting A sorting A sorting/bubble.bat A sorting/bubble.c A (bin) sorting/bubble.exe A sorting/insertion.bat A sorting/insertion.c A (bin) sorting/insertion.exe A sorting/selection.bat A sorting/selection.c A (bin) sorting/selection.exe A sorting/quick.bat A sorting/quick.c lab46:~/src/data$ svn commit -m "Added and committed sorting source files -John T. Rine" Adding data/sorting Adding data/sorting/bubble.bat Adding data/sorting/bubble.c Adding (bin) data/sorting/bubble.exe Adding data/sorting/insertion.bat Adding data/sorting/insertion.c Adding (bin) data/sorting/insertion.exe Adding data/sorting/quick.bat Adding data/sorting/quick.c Adding data/sorting/selection.bat Adding data/sorting/selection.c Adding (bin) data/sorting/selection.exe Transmitting file data ........... lab46:~/src/data$ svn commit "Added and committed sorting source files -John T. Rine"
I researched and documented the following system programming topics: file system structure, directories, links, re-entrant code, and interval timers.
Version control software manages changes to documents, programs, and other information stored as files on a computer. It is most commonly used among software development teams, where more than one person may modify the same files. Changes are usually identified by a designator known as the “revision number”, “revision level”, or simply “revision”.
The selection sort is conceptually the most simple of all the sorting algorithms. It works by selecting the smallest (or largest, if you want to sort from big to small) element of the array and placing it at the head of the array. Then the process is repeated for the remainder of the array; the next largest element is selected and put into the next slot, and so on down the line. Since a selection sort looks at progressively smaller part of an array each time through the loop, a selection sort is a little faster than bubble sort.
//selection.c //John T. Rine //November 14, 2011 #include<stdio.h> #include<stdlib.h> int cntChars(char *); int main(int argc, char **argv) { int x, y; int n; if(argc != 2) { printf("usage: selection string_to_sort\n"); exit(1); } n = cntChars(*(argv + 1)); //for (x = 0; x < n; x++) printf("%c", *(*(argv + 1) + x)); //printf("\n"); char *charPTR; charPTR = malloc(sizeof(char) * (n + 1)); for (x = 0; x <= n; x++) *(charPTR + x) = *(*(argv + 1) + x); printf("Before sorting: "); printf("%s\n", charPTR); for(x = 0; x < n; x++) { int min = x; for(y = x; y < n; y++) if(*(charPTR + min) > *(charPTR + y)) min = y; /*Swap*/ char temp = *(charPTR + x); *(charPTR + x) = *(charPTR + min); *(charPTR + min) = temp; } /*print after sorting*/ printf("After sorting: "); for(x = 0; x < n; x++) printf("%c", *(charPTR + x)); printf("\n"); free(charPTR); return 0; } int cntChars(char *inputString) { // returned value "count" does not include '\0' int count = 0; while(*(inputString + count) != '\0') ++count; return(count); }
rem selection.bat rem John T. Rine rem November 14, 2011 gcc selection.c -o selection pause selection "badcfeghijklnmoprqsutvwxzy" pause
C:\Users\John\Desktop\New Folder>gcc selection.c -o selection C:\Users\John\Desktop\New Folder>pause Press any key to continue . . . C:\Users\John\Desktop\New Folder>selection "badcfeghijklnmoprqsutvwxzy" Before sorting: badcfeghijklnmoprqsutvwxzy After sorting: abcdefghijklmnopqrstuvwxyz C:\Users\John\Desktop\New Folder>pause Press any key to continue . . .
The simplest sorting algorithm of all is the bubble sort. The bubble sort works by comparing each pair of array elements and swapping their positions, if necessary, to order them by value. This process is repeated as many times as necessary, until the array is sorted. Since the worst case scenario is that the array is in reverse order, and that the first element in sorted array is the last element in the starting array, the most swaps that will be necessary are equal to the length of the array.
//bubble.c //John T. Rine //November 14, 2011 #include<stdio.h> #include<stdlib.h> int cntChars(char *); int main(int argc, char **argv) { int x, y, n; char temp; if(argc != 2) { printf("usage: bubble string_to_sort\n"); exit(1); } n = cntChars(*(argv + 1)); char *charPTR; charPTR = malloc(sizeof(char) * (n + 1)); for (x = 0; x <= n; x++) *(charPTR + x) = *(*(argv + 1) + x); printf("Before sorting: "); printf("%s\n", charPTR); for(x = 0; x < n; x++) { for(y = 0; y < n - 1; y++) { if(*(charPTR + y) > *(charPTR + y + 1)) { /*sort*/ temp = *(charPTR + y + 1); *(charPTR + y + 1) = *(charPTR + y); *(charPTR + y) = temp; } } } /*print after sorting*/ printf("After sorting: "); for(x = 0; x < n; x++) printf("%c", *(charPTR + x)); printf("\n"); free(charPTR); return 0; } int cntChars(char *inputString) { // returned value "count" does not include '\0' int count = 0; while(*(inputString + count) != '\0') ++count; return(count); }
rem bubble.bat rem John T. Rine rem November 14, 2011 gcc bubble.c -o bubble pause bubble "badcfeghijklnmoprqsutvwxzy" pause
C:\Users\John\Desktop\New Folder>gcc bubble.c -o bubble C:\Users\John\Desktop\New Folder>pause Press any key to continue . . . C:\Users\John\Desktop\New Folder>bubble "badcfeghijklnmoprqsutvwxzy" Before sorting: badcfeghijklnmoprqsutvwxzy After sorting: abcdefghijklmnopqrstuvwxyz C:\Users\John\Desktop\New Folder>pause Press any key to continue . . .
An insertion sort is performed by repeatedly taking the next item to be sorted and inserting it into the array in its proper order with respect to items already inserted
//insertion.c //John T. Rine //November 15, 2011 #include<stdio.h> #include<stdlib.h> int cntChars(char *); int main(int argc, char **argv) { int x, y, n; char temp; if(argc != 2) { printf("usage: insertion string_to_sort\n"); exit(1); } n = cntChars(*(argv + 1)); char *charPTR; charPTR = malloc(sizeof(char) * (n + 1)); for (x = 0; x <= n; x++) *(charPTR + x) = *(*(argv + 1) + x); printf("Before sorting: "); printf("%s\n", charPTR); for (x = 1; x < n; x++) { y = x; while (y > 0 && *(charPTR + y - 1) > *(charPTR + y)) { temp = *(charPTR + y); *(charPTR + y) = *(charPTR + y - 1); *(charPTR + y - 1) = temp; y--; } } /*print after sorting*/ printf("After sorting: "); for(x = 0; x < n; x++) printf("%c", *(charPTR + x)); printf("\n"); free(charPTR); return 0; } int cntChars(char *inputString) { // returned value "count" does not include '\0' int count = 0; while(*(inputString + count) != '\0') ++count; return(count); }
rem insertion.bat rem John T. Rine rem November 15, 2011 gcc insertion.c -o insertion pause insertion "badcfeghijklnmoprqsutvwxzy" pause
C:\Users\John\Desktop\New Folder>rem insertion.bat C:\Users\John\Desktop\New Folder>rem John T. Rine C:\Users\John\Desktop\New Folder>rem November 15, 2011 C:\Users\John\Desktop\New Folder>gcc insertion.c -o insertion C:\Users\John\Desktop\New Folder>pause Press any key to continue . . . C:\Users\John\Desktop\New Folder>insertion "badcfeghijklnmoprqsutvwxzy" Before sorting: badcfeghijklnmoprqsutvwxzy After sorting: abcdefghijklmnopqrstuvwxyz C:\Users\John\Desktop\New Folder>pause Press any key to continue . . .
The quick sort uses the “divide and conquer” strategy to sort a list. It doesn't require extra memory to perform the sort and is said to perform the sort “in place”.
The quick sort algorithm is composed of the following steps:
//quick.c //John T. Rine //November 25, 2011 #include <stdio.h> #include <stdlib.h> int cntChars(char *); void quickSort(char[], int, int) ; int main(int argc, char **argv) { int x, n; if(argc != 2) { printf("usage: quick string_to_sort\n"); exit(1); } n = cntChars(*(argv + 1)); char *charPTR; charPTR = malloc(sizeof(char) * (n + 1)); for (x = 0; x <= n; x++) *(charPTR + x) = *(*(argv + 1) + x); printf("Before sorting: "); printf("%s\n", charPTR); quickSort(charPTR, 0, n - 1); printf("After sorting: "); printf("%s\n", charPTR); free(charPTR); return 0; } int cntChars(char *inputString) { // returned value "count" does not include '\0' int count = 0; while(*(inputString + count) != '\0') ++count; return(count); } void quickSort(char array[], int m, int n) { int i,j,k; char temp, pivot; if(m < n) { k = (m + n) / 2; temp = *(array + m); *(array + m) = *(array + n); *(array + n) = temp; pivot = *(array + m); i = m + 1; j = n; while(i <= j) { while((i <= n) && (*(array + i) <= pivot)) i++; while((j >= m) && (*(array + j) > pivot)) j--; if(i < j) { temp = *(array + i); *(array + i) = *(array + j); *(array + j) = temp; } } temp = *(array + m); *(array + m) = *(array + j); *(array + j) = temp; quickSort(array, m, j - 1); quickSort(array, j + 1, n); } }
I wrote the following Windows batch file to automate compilation and execution, with command line arguments, of the source file-quick.c.
rem quick.bat rem John T. Rine rem November 25, 2011 gcc quick.c -o quick pause quick eafbgchdikjlnmopqsrtvwuyxz pause
These are the results of compiling and executing the source file, quick.c, using the character string “eafbgchdikjlnmopqsrtvwuyxz” as its only commandline argument.
C:\Users\John\Desktop\sorting>rem quick.bat C:\Users\John\Desktop\sorting>rem John T. Rine C:\Users\John\Desktop\sorting>rem November 25, 2011 C:\Users\John\Desktop\sorting>gcc quick.c -o quick C:\Users\John\Desktop\sorting>pause Press any key to continue . . . C:\Users\John\Desktop\sorting>quick eafbgchdikjlnmopqsrtvwuyxz Before sorting: eafbgchdikjlnmopqsrtvwuyxz After sorting: abcdefghijklmnopqrstuvwxyz C:\Users\John\Desktop\sorting>pause Press any key to continue . . .
The merge sort is a divide and conquer algorithm just like the quick sort, however, unlike the quick sort, it requires extra memory to perform the sort.
The binary search algorithm is a way to locate an element having a certain value within a list of sorted elements. The binary search algorithm eliminates half of the elements searched with each comparison.
//binarySearch.c //John T. Rine //November 25, 2011 #include<stdio.h> #include<stdlib.h> int main(int argc, char **argv) { int i, n; int left, right, middle, element = -1; char value; char temp; if(argc != 5) { printf("usage: binarySearch string_to_search element_to_search_for left_element right_element\n"); exit(1); } left = atoi(*(argv + 3)); right = atoi(*(argv + 4)); value = *(*(argv + 2) + 0); printf("Now performing a binary search for element %c, between elements %d and %d\n", value, left, right); while (left <= right) { printf("left = %d, right = %d, middle = %d, element = %d, value = %c\n", left,right,middle,element,value); middle = (left + right) / 2; if (*(*(argv + 1) + middle) == value) { element = middle; break; } else if (*(*(argv + 1) + middle) > value) right = middle - 1; else left = middle + 1; } printf("The element containing the value is %d (-1 indicates element not found)\n", element); return 0; }
I wrote a batch file to automate compilation and execution with command line arguments of the binarySearch.c source file.
rem binarySearch.bat rem John T. Rine rem November 25, 2011 gcc binarySearch.c -o binarySearch pause binarySearch abcdefghhijklmnopqrstuvwxyz b 0 25 pause
Here is the execution of the binary search algorithm on Windows with the lower case alphabet as the string to be searched, 'b' as the value to be found, left index as 0, and the right index as 25.
C:\Users\John\Desktop\binarySearch>rem binarySearch.bat C:\Users\John\Desktop\binarySearch>rem John T. Rine C:\Users\John\Desktop\binarySearch>rem November 25, 2011 C:\Users\John\Desktop\binarySearch>gcc binarySearch.c -o binarySearch C:\Users\John\Desktop\binarySearch>pause Press any key to continue . . . C:\Users\John\Desktop\binarySearch>binarySearch abcdefghhijklmnopqrstuvwxyz b 0 25 Now performing a binary search for element b, between elements 0 and 25 left = 0, right = 25, middle = 212, element = -1, value = b left = 0, right = 11, middle = 12, element = -1, value = b left = 0, right = 4, middle = 5, element = -1, value = b left = 0, right = 1, middle = 2, element = -1, value = b left = 1, right = 1, middle = 0, element = -1, value = b The element containing the value is 1 (-1 indicates element not found) C:\Users\John\Desktop\binarySearch>pause Press any key to continue . . .
Here is the execution of the binary search algorithm on Linux with the upper case alphabet as the string to be searched, 'U' as the value to be found, left index as 0, and the right index as 25.
lab46:~/src/data/binarySearch$ gcc binarySearch.c -o binarySearch lab46:~/src/data/binarySearch$ ./binarySearch ABCDEFGHIJKLMNOPQRSTUVWXYZ U 0 25 Now performing a binary search for element U, between elements 0 and 25 left = 0, right = 25, middle = 0, element = -1, value = U left = 13, right = 25, middle = 12, element = -1, value = U left = 20, right = 25, middle = 19, element = -1, value = U left = 20, right = 21, middle = 22, element = -1, value = U The element containing the value is 20 (-1 indicates element not found) lab46:~/src/data/binarySearch$
Big O or Big Omicron represents the upper bound of asymptotic complexity.
Big O notation describes the relative complexity of an algorithm by reducing the growth rate to the key factors when the key factor tends towards infinity, all other factors being ignored. This is why the phrase “asymptotic complexity” is used to describe its behavior.
Listed below are common examples of big O notation; included is an explaination of what each example means:
Describes an algorithm whose number of operations, the complexity, is always the same regardless of the size of the input data set.
The complexity, the number of operations, is directly proportional to the size of the data. This is called linear complexity.
Describes an algorithm whose number of operations,the complexity, is directly proportional to the square of the size of the input data set. This is common with algorithms that consist of nested loops over the data set. Deeper nested loops result in big O (n to higher powers).
O(2^n) describes an algorithm whose growth will double with each additional element in the input data set.
Binary trees are so called because when drawn pictorial look like inverted trees. Binary trees are made up of nodes that contain data and pointers to other nodes just like linked-list implementations. Binary trees, however, have “left” and “right” pointers rather than “next” and “previous” pointers.
Also similar to linked lists, binary trees use null pointers to indicate an end of a tree; in a binary tree, however, it is the end of a branch or subtree. Since binary trees branch out, that is they spread out rather than being one node after another like a list, so binary trees are fast at searching for data.
Identification and definition of the chosen keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Identification and definition of the chosen keyword. Substitute “keyword” with the actual keyword.
If you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
In Unix/Linux operating systems, users can be categorized together into groups. File permissons in POSIX compliant and Unix/Linux operating systems are organized into three classes, user, group, and others. The use of groups as the name implies, allows groups of users access to files and other system resources. A group identifier or GID, is a numeric value used to represent a specific group. The range of values for a GID varies among different operating systems; at minimum, a GID can be between 0 (0x0000) and 32,767 (0x7fff), with one restriction:
The GID is used to refer to groups in the /etc/passwd and /etc/group files or their equivalents. Shadow password files and Network Information Service also refer to GIDs. The GID is a necessary component of Unix file systems and processes.
In Unix/Linux operating systems, users are identified within the kernel by an unsigned integer value called a user identifier or UID.
The range of UID values varies among different operating systems; at mimimum, a UID can be between 0 (0x0000) and 32767 (0x7fff), but with the following restrictions:
The UID references users in the /etc/passwd file. Shadow password files and Network Information Service also refer to UIDs. The UID has become a necessary component of Unix file systems and processes.
A file system is used to organize and store data on non-volatile media such as disk drives. The file system includes security features used to control access to data. The file system also provides man-readable aliases called file names with which to access data on non-volatile memory devices. File system structure looks like an inverted tree. At the top of the tree is the root directory. In this directory are files and subdirectories, each directory containing other directories and, or files which make up the “branches” of the tree.
Directories appear to the user of an operating system as a container of files and other directories, however, a directory is actually a file that has an entry for each item contained within the directory. Each entry in a directory contains only the name of the item, and a numerical reference to the location of the item. The reference is called an i-number, and is an index into a table called the i-list. The i-list is a complete list of all the storage space available to a particular file system.
A link is a pointer to another file. A directory entry can be a hard link, in which the i-number points directly to another file. A hard link to a file cannot be distinguished from the file itself. When a hard link is created, the i-numbers of two different directory file entries point to the same inode. For this reason, hard links cannot span file systems. A symbolic link provides an indirect pointer to a file. A symbolic link is implemented as a directory file entry containing a pathname. Soft links are distinguishable from files, and can span across file systems. Note that some versions of UNIX do not support symbolic links.
The I-List.
Differences between hard and symbolic links:
An atomic operation guarantees that one or more machine instructions are executed sequentially, without interruption. Without intervention, any sequence of two or more machine instructions isn't atomic since the operating system may suspend the execution of the current sequence of instructions in favor of some other task. To ensure that a sequence of operations will in fact be atomic some form of synchronization is required. Without that, the only guarantee you have is that a single machine instruction is always atomic; the CPU can not interrupt a single instruction in the middle.
Re-entrant code is written so that none of it can be modified, further, it does not keep track of anything. Programs calling re-entrant code keep track of their own variables, flags, etc., therefore, one copy of a re-entrant routine can be shared by any number of processes.
State the course objective; define what that objective entails.
State the method you will use for measuring successful academic/intellectual achievement of this objective.
Follow your method and obtain a measurement. Document the results here.
Reflect upon your results of the measurement to ascertain your achievement of the particular course objective.
State the course objective; define what that objective entails.
State the method you will use for measuring successful academic/intellectual achievement of this objective.
Follow your method and obtain a measurement. Document the results here.
Reflect upon your results of the measurement to ascertain your achievement of the particular course objective.
State the course objective; define what that objective entails.
State the method you will use for measuring successful academic/intellectual achievement of this objective.
Follow your method and obtain a measurement. Document the results here.
Reflect upon your results of the measurement to ascertain your achievement of the particular course objective.
What is the question you'd like to pose for experimentation? State it here.
Collect information and resources (such as URLs of web resources), and comment on knowledge obtained that you think will provide useful background information to aid in performing the experiment.
Based on what you've read with respect to your original posed question, what do you think will be the result of your experiment (ie an educated guess based on the facts known). This is done before actually performing the experiment.
State your rationale.
How are you going to test your hypothesis? What is the structure of your experiment?
Perform your experiment, and collect/document the results here.
Based on the data collected:
What can you ascertain based on the experiment performed and data collected? Document your findings here; make a statement as to any discoveries you've made.
What is the question you'd like to pose for experimentation? State it here.
Collect information and resources (such as URLs of web resources), and comment on knowledge obtained that you think will provide useful background information to aid in performing the experiment.
Based on what you've read with respect to your original posed question, what do you think will be the result of your experiment (ie an educated guess based on the facts known). This is done before actually performing the experiment.
State your rationale.
How are you going to test your hypothesis? What is the structure of your experiment?
Perform your experiment, and collect/document the results here.
Based on the data collected:
What can you ascertain based on the experiment performed and data collected? Document your findings here; make a statement as to any discoveries you've made.
If you're doing an experiment instead of a retest, delete this section.
If you've opted to test the experiment of someone else, delete the experiment section and steps above; perform the following steps:
Whose existing experiment are you going to retest? Prove the URL, note the author, and restate their question.
Evaluate their resources and commentary. Answer the following questions:
State their experiment's hypothesis. Answer the following questions:
Follow the steps given to recreate the original experiment. Answer the following questions:
Publish the data you have gained from your performing of the experiment here.
Answer the following:
Answer the following: