For the UNIX course I currently enrolled in i have created a IRC bot phenny.It's pretty cool, once you get going it becomes alot of fun. Creating a phenny bot is significant because it allows you to script a bot and based on some conditions the bot does things.In the begining i had some difficulty with scripting but this activity helped me.
GNU debugger when you compile code use -g along with regular compile which looks like this gcc -g -o acs2 acs2.c
then run your program in the debugger:
gdb ./acs2 to fully use this debugger set breaking points such as break main break 11 break 17 once breaking points are set then you can run the program by typing “run” type “n” for next line you can also print values of variables if you type print “the variable name”
this is a very useful tool for finding possible mistakes or to fix mistakes. this is a very basic use of gnu debugger this debugger is capible of much more so please explore.
C++ OOP-Object-Oriented Programming to make a C++ file type .cc after you file instead of .c compile with g++ -o hello1 hello.cc
C++ class notes Classes & Objects Inheritance/Multiple Inheritance Polymorphism Templates
class notes on struct
struct person{ char *name;//or --char name[20]; unsigned char age; short int weight; float gpa; }; //struct differ from union bec struct allocate memory for each and dont share $ typedef struct person P; P p1,p2,p3,p4,p5; struct person p1; struct person p2; struct person p3,p4,p5; p1.age = 29;
Standard I/O (STDIO, STDOUT, STDERR)…xxxx ■ logic and operators (and, or, not, xor)
■ Scope (Block, Local, Global, File)
■ Type Casting
■ Structures (Declaration, Accessing Elements, Pointers to)
■ typedef, enum, union
■ Functions, Parameters (Pass by: Value, Address, Reference), Return Types, Recursion, Command-line arguments
■ Compiler, Preprocessor, Flags, Assembler, Linker, Multi-file programs (how to structure, how to compile)……x
■ I/O Streams (cin, cout, cerr, stream operators) [C++]……xxx
■ Namespaces [C++]…xxx
■ Type Casting Operators, Const-Volatility Specifiers (const, volatile) [C++]
■ Classes (Objects, Constructor, Destructor, Access Control, Public, Protected, Private, Friend, “this” pointer) [C++]…..xxxxx
■ Inheritance (single, multiple Inheritance), Polymorphism/Virtual Functions, Abstract Base Class [C++]
■ Overloading (Functions, Operators) [C++]
■ Exception Handing (throw, try, catch) [C++]
■ Templates, STL (Standard Template Library) [C++]
Flags In programming, a flag is a predefined bit or bit sequence that holds a binary value. Typically, a program uses a flag to know when a data stream ends and new data begins. good example is flags used in networking. For example: 1010100 (flag to say hey begin recording) 0101101 (data) 0111011 (data) 0101011(flag to say hey end of data stream)
assembler Is a program that takes basic text in a programing laguage and translates it into bits the processor uses for excution of task. is you are engineer that builds computers you would most likly know assembly laguage.
Binary Code code made of 0's and 1's known as low level programming, called machine language that most programmers don't work with but compiler use.(Assembly language)
Preprocessor program started by the compiler as the first part of translation,it handles #include, #define, and #if.by replaceing #include with stdlib.h or other hearder files you have listed example #include <stdlib.h>
I/O Streams (cin, cout, cerr, stream operators) [C++]
in c you use stdin, stdout, and stderr. in C++ you use cin, cout, and cerr. cout- is an object of class that represents the standard output stream. cin- Standard input stream (object) cerr- Standard output stream for errors (object)
<iostream> in C++ example while (true) {
cout << "Please enter a valid number: "; getline(cin, input);
in c int value =0; printf(“please enter a number:\n”); fscanf(stdin,%d,&value);
c++ is a way to maintain your code through c lasses to make code more organized. in this class there is there is a public,private protected. these are the access for the class. what is in public can be accessed from anyone. thoses in private cannot be accessed at all from anyone unless there is a way to access it in protected like in the below example with get x.
#ifndef _GATE_H #define _GATE_H //sample code for classes dealing with inheritance //abstract base class.. //base class class gate{ public: gate(); // constructor bool getx(); void seta(bool); void setb(bool); protected: void setx(bool); bool a; bool b; private: bool x; }; #endif
When using same type of data for many declarations, you can customize its name and “re use it with out re writing the name again and again . In C++, the type def keyword allows you to create an alias for a data type. The formula to follow is: typedef [attributes] DataType AliasName; The typedef keyword is required. The attribute is not.
Enum short for enumerated data allow a user to define a fixed set of words that a variable of type enum can use as its value. The words are assigned integer values by the compiler so enum values can be compared.
A union is comprised of a collection of variables of different types, just like a structure. However, with unions, you can only store information in one field at a time. Once a new value is assigned to a field, any existing data is overwritten with new data. The use of unions can save memory if you have a grouping of data and only one of the types is used at a time. The size of a union is dependent on the size of it's largest data member.
struct person{ char *name;//or --char name[20]; unsigned char age; short int weight; float gpa; }; //struct differ from union bec struct allocate memory for each and dont share like union typedef struct person P; P p1,p2,p3,p4,p5; struct person p1; struct person p2; struct person p3,p4,p5; p1.age = 29;
stdio or standard input is defaulted to the the keyboard. standard output is defaulted to the screen. stderr is also defaulted to the screen for err msgs
is a thing that is inherited. example: B can inherit A and be a child
Demonstration of the chosen keyword.
gate :: gate() {
a=b=x=false;
} bool gate :: getx() {
return(x); //return x to have acces to x
}
void gate :: seta(bool a) {
this->a=a; //property of c++ refer to self
} void gate :: setb(bool b) {
this->b=b;//-> this is a pointer
} void gate :: setx(bool x) {
this->x=x;
}
Namespaces allow to group like classes, objects and functions under a name.
namespace myNamespace {
int a, b;
}
A function in the C programming language is code that has a name and property that are reusable. This means that a function can be called on from as many different points in the program as needed.
A Parameter in the C programming language is any data that is passed to a function. Demonstration
#include<stdio.h> #include<stdlib.h> int sum(int, int, int, int); //function and parameters expected float avg(int, int, int, int); //function and parameters expected int main(int n1)//main is accepting a integer value for parameter { return(0); }
establish a better understanding of c and c++
the objective entails learning about type defs classes and working projects
create a program that incorporates classes with code and type defs
upon Reflection of my results of the measurement to ascertain your achievement of the particular course objective.
■ $PATH….X
■ Job control…….x
■ wildcards……x
■ tab completion…..x
■ Cron/Crontab…….x
■ Pattern Matching………x
■ Regular Expressions…….x
■ Shell Scripting…..x
shell scripting
shell scripting is a small program essentialy that contains commands such as command line task such as grep, ls, mv, and cp. when you run the script it it excute these for you instead of typing all theses things.
ls ~ df who
is in script.sh
lab46:~$ ./script.sh Desktop archive2.zip count.c mail Documents archives data motd Downloads archivescombined.tar date multitask.lab.txt Maildir at dateyears output Music badname devel phenny Pictures badname.tgz file phenny.tar.bz2 Public bin forloop.sh script.sh Templates botscript.sh guess1.sh src Videos class_notes lab1 src.bak age.sh classlog.c lab2 the answer.txt archive1.tar.gz count loop.sh Filesystem 1K-blocks Used Available Use% Mounted on /dev/xvda1 4128448 2522072 1396664 65% / tmpfs 784300 0 784300 0% /lib/init/rw udev 755640 36 755604 1% /dev tmpfs 784300 4 784296 1% /dev/shm /dev/xvda2 253871 12859 227905 6% /tmp nfs:/home 2930056576 1434124544 1495932032 49% /home nfs:/lib/mail 2930056576 1434124544 1495932032 49% /var/mail skinney1 pts/8 2012-03-17 11:36 (cpe-24-94-52-91.stny.res.rr.com) rmatsch pts/16 2012-03-17 11:46 (user-10bj433.cable.mindspring.com) jjohns43 pts/24 2012-01-23 12:18 (cpe-74-65-82-173:S.0) smalik2 pts/29 2012-03-17 10:49 (cpe-69-205-204-88.stny.res.rr.com) skinney1 pts/35 2012-03-16 10:15 (65-124-85-125.dia.static.qwest.net) mfaucet2 pts/65 2012-03-09 17:09 (55:S.0) smalik2 pts/27 2012-01-25 14:53 (cpe-69-205-204-88:S.0) wedge pts/28 2012-03-17 10:02 (telstar.lair.lan) jdavis34 pts/22 2012-03-06 12:57 (cpe-69-205-141-69:S.0) jjohns43 pts/82 2012-02-27 11:03 (cpe-74-65-82-173:S.0) lab46:~$
PATH is an environmental variable that specifies a set of directories where executable programs are located.
lab46:~$export PATH=$PATH:/home/rmatsch/src/unix
Job control allow you to have the system work on a job in the background while you do something else . If you are simply trying to get logged out, but have encountered the “There are stopped jobs” message
Useful Commands control-z Stop (don't kill) the foreground job, and then return to the shell
Check the status of jobs in the current session ps -u username Check the status of processes, including those from other sessions. On BSD systems, use 'ps -gx'. kill -9 %1 Kill a job, by specifying its job number after the percent sign kill -9 123 Kill a process, by specifying its process id (PID) number bg Run the most recently stopped job in the background fg Bring most recently background job to the foreground fg %1 Bring a job to foreground by specifying its job number after the percent sign
A daemon is a computer program that runs in the background as a process, instead of running in the foreground. below is an example of a deamon running in back ground and a command to look at the root processes.
inetd or init
lab46:~$ ps -u root USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 8356 720 ? Ss Jan17 0:41 init [2] root 2 0.0 0.0 0 0 ? S Jan17 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S Jan17 0:05 [migration/0] root 4 0.0 0.0 0 0 ? S Jan17 0:08 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S Jan17 0:00 [watchdog/0] root 6 0.0 0.0 0 0 ? S Jan17 0:04 [migration/1] root 7 0.0 0.0 0 0 ? S Jan17 0:03 [ksoftirqd/1] root 8 0.0 0.0 0 0 ? S Jan17 0:00 [watchdog/1] root 9 0.0 0.0 0 0 ? S Jan17 5:40 [events/0] root 10 0.0 0.0 0 0 ? S Jan17 3:53 [events/1] root 11 0.0 0.0 0 0 ? S Jan17 0:00 [cpuset] root 12 0.0 0.0 0 0 ? S Jan17 0:00 [khelper] root 13 0.0 0.0 0 0 ? S Jan17 0:00 [netns] root 14 0.0 0.0 0 0 ? S Jan17 0:00 [async/mgr] root 15 0.0 0.0 0 0 ? S Jan17 0:00 [pm] root 16 0.0 0.0 0 0 ? S Jan17 0:00 [xenwatch] root 17 0.0 0.0 0 0 ? S Jan17 0:00 [xenbus] root 18 0.0 0.0 0 0 ? S Jan17 0:06 [sync_supers] root 19 0.0 0.0 0 0 ? S Jan17 0:07 [bdi-default] root 20 0.0 0.0 0 0 ? S Jan17 0:00 [kintegrityd/0] root 21 0.0 0.0 0 0 ? S Jan17 0:00 [kintegrityd/1] root 22 0.0 0.0 0 0 ? S Jan17 0:00 [kblockd/0] root 23 0.0 0.0 0 0 ? S Jan17 0:00 [kblockd/1] root 24 0.0 0.0 0 0 ? S Jan17 0:00 [kseriod] root 27 0.0 0.0 0 0 ? S Jan17 0:00 [kondemand/0] root 28 0.0 0.0 0 0 ? S Jan17 0:00 [kondemand/1] root 29 0.0 0.0 0 0 ? S Jan17 0:02 [khungtaskd] root 30 0.0 0.0 0 0 ? S Jan17 0:20 [kswapd0] root 31 0.0 0.0 0 0 ? SN Jan17 0:00 [ksmd] root 32 0.0 0.0 0 0 ? S Jan17 0:00 [aio/0] root 33 0.0 0.0 0 0 ? S Jan17 0:00 [aio/1] root 34 0.0 0.0 0 0 ? S Jan17 0:00 [crypto/0] root 35 0.0 0.0 0 0 ? S Jan17 0:00 [crypto/1] root 38 0.0 0.0 0 0 ? S Jan17 0:00 [khvcd] root 123 0.0 0.0 0 0 ? S Jan17 0:14 [kjournald] root 170 0.0 0.0 10408 4 ? S<s Jan17 0:00 udevd --daemon root 222 0.0 0.0 10404 4 ? S< Jan17 0:00 udevd --daemon root 223 0.0 0.0 10404 4 ? S< Jan17 0:00 udevd --daemon root 355 0.0 0.0 0 0 ? S Jan17 0:49 [rpciod/0] root 356 0.0 0.0 0 0 ? S Jan17 0:00 [rpciod/1] root 373 0.0 0.0 0 0 ? S< Jan17 0:00 [kslowd000] root 374 0.0 0.0 0 0 ? S< Jan17 0:00 [kslowd001] root 375 0.0 0.0 0 0 ? S Jan17 0:28 [nfsiod] root 395 0.0 0.0 0 0 ? S Jan17 0:03 [kjournald] root 495 0.0 0.0 6748 596 ? Ss Jan17 0:00 dhclient -v -pf root 788 0.0 0.0 43220 4 ? S Jan17 0:00 supervising sys root 789 0.0 0.1 51592 2912 ? Ss Jan17 0:39 /usr/sbin/syslo root 890 0.0 0.0 10208 104 ? Ss Jan17 0:00 /usr/sbin/inetd root 921 0.0 0.0 43112 344 ? Ss Jan17 0:05 /usr/sbin/sshd root 1014 0.0 0.0 0 0 ? S Jan17 0:00 [nfsv4.0-svc] root 1037 0.0 0.0 5928 8 hvc0 Ss+ Jan17 0:00 /sbin/getty 384 root 1780 0.0 0.1 74000 2296 ? SN Mar09 0:00 /USR/SBIN/CRON root 15461 0.0 0.1 59236 2076 ? Ss Jan19 0:12 /usr/sbin/cron root 21168 0.0 0.0 0 0 ? S Mar14 0:01 [flush-202:1] root 25915 0.0 0.2 89100 3932 ? SNs 02:23 0:00 sshd: csit2310 root 27443 0.0 0.2 89100 3964 ? SNs Mar16 0:00 sshd: skinney1 root 28768 0.0 0.0 0 0 ? S 08:35 0:00 [flush-0:17] root 29506 0.0 0.2 89100 3960 ? SNs 10:02 0:00 sshd: wedge [pr root 30082 0.0 0.2 89100 3988 ? SNs 10:48 0:00 sshd: smalik2 [ root 30157 0.0 0.1 58860 2076 ? Ss Mar14 0:02 /usr/sbin/rpc.i root 30213 0.0 0.1 167308 2236 ? Ssl Mar14 0:16 /usr/sbin/nscd root 30246 0.0 0.2 89100 4000 ? SNs 11:08 0:00 sshd: smalik2 [ root 30373 0.0 0.0 0 0 ? S 11:28 0:00 [flush-202:2] root 30418 0.0 0.2 89100 3984 ? SNs 11:35 0:00 sshd: jdavis34 root 30435 0.0 0.2 89100 4000 ? SNs 11:36 0:00 sshd: skinney1 root 30530 0.0 0.2 89100 3992 ? SNs 11:46 0:00 sshd: rmatsch [ root 31447 0.0 0.1 74000 2296 ? SN Mar09 0:00 /USR/SBIN/CRON root 31763 0.0 0.1 74004 1956 ? SN Mar14 0:00 /USR/SBIN/CRON root 32271 0.0 0.1 74000 2296 ? SN Mar09 0:00 /USR/SBIN/CRON root 32506 0.0 0.1 74000 2300 ? SN Mar13 0:00 /USR/SBIN/CRON lab46:~$
cron/crontab
cron tab is a task scheduler.It is a time based which runs periodically at certain times or dates, used to automate system processes.
lab46:~$ crontab -e # 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
characters that are very powerful and help a great deal when in UNIX. the special characters enable a user to control the output of commands without having to specify the exact name of a file.
* zero or more of “any” character
? used to represent one of “any” character
\ will ignore such things as space if the variable name isn't one string.
” ” (or ' ') quote the enclosed characters
[ ] character class - match any of the enclosed characters.
[^ ] inverted character class - do not match any of the enclosed characters.
Pattern matching a way to search in unix which enables the user to look for files.
Using ls(1), list files that match the following patterns: a. Only files that begin with a lowercase vowel. b. All files that end with a .s c. All files that do not start with a vowel, yet end with a .s d. Only 3 character filenames that don't end with a consonant. e. Explain your strategy and reasoning for constructing an effective pattern for each part of this question
a. Using ls in the given directory, show me how you'd list only files
that begin with a lowercase vowel:
ls a* e* i* o* u*
b. Using ls in the given directory, show me how you'd list only files
that end with a .s:
ls *.s
c. Using ls in the given directory, show me how you'd list only files
that do not start with a vowel, yet end with a .s:
ls [b-d,f-h,j-n,p-t,v-z]**.s
d. Using ls in the given directory, show me how you'd list only the
files consisting of just 3 character filenames that don't end with a consonant:
lab46:/var/public/unix/patterns$ ls a* e* i* o* u* a.b.c.d.e.f.s abd i3 a39487y abe i4 a6.c abf i5.s a7.d ac.s i6.s a8.e aca i7.s a9.f ad.s ive_got_a_beautiful_feeling aaa alab5.s o_what_a_beautiful_day aab alab6.s o_what_a_beautiful_morning.s aac e11 u_2 aad e8933 uey aae e9038 uey2 aaf e904385 ueya ab.s ee.s ueyai aba everythings_going_my_way.s ueyed abb i1 uint abc i2 lab46:/var/public/unix/patterns$
tab completion
tab completion is a command line feature that allows you to type some of a command and have the command line finish it when you hit the tab key. kinda like a auto complete
Demonstration of the chosen keyword.
lab46:/var/public/unix/patterns$ l (tab) last less lispmtopgm lrrdNode lastb lessecho listres ls lastlog lessfile ln lsattr latin2ascii.py lesskey lnstat lscpu lcf lesspipe loadkeys lsinitramfs ld let loadunimap lsmod ld.bfd lex local lsof ld.gold lexgrog locale lspci ldapadd lft localedef lspgpot ldapcompare lft.db lockfile lsusb ldapdelete lftp lockfile-check luit ldapexop lftpget lockfile-create lwp-download ldapmodify libnetcfg lockfile-remove lwp-dump ldapmodrdn libpng-config lockfile-touch lwp-mirror ldappasswd libpng12-config loggen lwp-request ldapsearch line logger lwp-rget ldapurl link login lxterm ldapwhoami links logname lynx ldd links2 logout lynx.cur ldrdf linux32 look lzmainfo leaftoppm linux64 lorder
regular expressions
Regular Expression Symbol . Match any character * Match 0 or more of the preceding
$ End of line or string [ ] Character class - match any of the enclosed characters [^ ] Negated character class - do not match any of the enclosed characters \< Beginning of word \> End of word
grep '^[b-d][aeiou]' /etc/passwd
be able to write a simple shell scipt that contains file manipulation, and irc bot configuration.
the objective entails making a script to do multiple task incoporatiing things which have already learned allong with new task.
have students given many task and allow students to write all of these task in a script to be performed in a single script.
tell students to creat a script to do thing they know how to do via command line and also do task they dont know.
Reflect upon your results of the measurement to ascertain my achievement i did alright but there is always room for inprovmemt.
What happends when you leave out a semi colin on a struct.
struct weki pages
Based on what i read i think the result of your experiment will be a compile erroor. i believe this because funtions do not need them after curly brace but a struct would have to
i will create a struct and compile it to see if it compiles with out errors.
like i thought the semi colin is very important. i recieved a error when compiling
Based on the data collected:
my hypothesis correct, and applicable for the data collected.
based on the experiment performed and data collected leaving a semi colin out of a struct will cause an error when compiling. Error exspected expression.
when defining a funtion can you put a return type on a void funtion()
class notes void main() and int main()
based on class notes i the void main cannot have a return valuenbecause void main mean nothing is being returned.
i will create a void sum funtion and then type retutn(0); at the end pf the funtion. i will then compile and see what happends if any/
lab46:~/src/cprog/project2$ gcc -o prog2f prog2f.c prog2f.c: In function 'sum': prog2f.c:56: warning: 'return' with a value, in function returning void lab46:~/src/cprog/project2$
Based on the data collected my hypothesis was not correct but it was applicable. there was no short commings ut just a little more going on then exspected
===Conclusions===
based on the experiment performed and data collected having a return type to a void funtion will give a warning but will still compile.
brobbins exsperiment 1
Evaluate their resources and commentary. Answer the following questions:
Based on what I have learned about the C programming language thus far, I believe that the use of the exit command within a function will only cause the function to exit and not the entire program due to the fact that the exit argument would only be in scope with the current function and not the rest of the program.
This is the original code
#include<stdio.h> #include<stdlib.h> #include<math.h> int iseven(int value) { int tmp; tmp=value % 2; return(tmp); } void add(int *list, int total, int value) { int i, s=0; for(i=0; i < total; i++) { if(*(list+i)==-1) { *(list+i)=value; s=i; break; } } } int *init(int total, int *status) { int i, *tmp; *status=0; if(total > 0) { tmp=(int*)malloc(sizeof(int)*total); for(i=0; i < total; i++) { *(tmp+i)=-1; } *status=1; } return(tmp); } int main(int argc, char **argv) { int *list, i, x=0; list=init(atoi(*(argv+1)),&x); if(x==0) { fprintf(stderr, "Error on initialization!"); exit(1); } for(i=0; i < atoi(*(argv+1)); i++) { add(list, atoi(*(argv+1)), (rand()%atoi(*(argv+2)))); } for(i=0; i < atoi(*(argv+1)); i++) { if(iseven(*(list+i))==0) { fprintf(stdout, "%d is even\n", *(list+i)); } else fprintf(stdout, "%d is odd\n", *(list+i)); } return(0); }
This is the output received from the unmodified code.
lab46:~/src/cprog$ ./iseven 5 30 13 is odd 16 is even 27 is odd 25 is odd 23 is odd lab46:~/src/cprog$
The following is the code that has been modified to reflect the question above. Note the change in the “add” function, the “break” statement has been changed to an “exit” statement with a return code of zero. Also note the inclusion if the new printf statements within each function. These are included so I am able to tell how far the program progresses.
#include<stdio.h> #include<stdlib.h> #include<math.h> int iseven(int value) { printf("Diag 1\n"); int tmp; tmp=value % 2; return(tmp); } void add(int *list, int total, int value) { printf("Diag 2\n"); int i, s=0; for(i=0; i < total; i++) { if(*(list+i)==-1) { *(list+i)=value; s=i; exit(0); } } } int *init(int total, int *status) { printf("Diag 3\n"); int i, *tmp; *status=0; if(total > 0) { tmp=(int*)malloc(sizeof(int)*total); for(i=0; i < total; i++) { *(tmp+i)=-1; } *status=1; } return(tmp); } int main(int argc, char **argv) { printf("Diag 4A\n"); int *list, i, x=0; printf("Diag 4B\n"); list=init(atoi(*(argv+1)),&x); printf("Diag 4C\n"); if(x==0) { fprintf(stderr, "Error on initialization!"); exit(1); } printf("Diag 4D\n"); for(i=0; i < atoi(*(argv+1)); i++) { printf("Diag 4Da\n"); add(list, atoi(*(argv+1)), (rand()%atoi(*(argv+2)))); printf("Diag 4Db\n"); } for(i=0; i < atoi(*(argv+1)); i++) { if(iseven(*(list+i))==0) { fprintf(stdout, "%d is even\n", *(list+i)); } else fprintf(stdout, "%d is odd\n", *(list+i)); } return(0); }
The following is the resulting output after the modifications.
lab46:~/src/cprog$ ./iseven 5 30 Diag 4A Diag 4B Diag 3 Diag 4C Diag 4D Diag 4Da Diag 2 lab46:~/src/cprog$