Monday, April 28, 2025

C Tutorial - 2 - Line by Line - Detailed Explanations

#include <stdio.h>

int main() {
    printf("Hack The Planet");
    printf("\n");
    printf("Hack The Planet 2");
    return 0;
}

Here's a line-by-line explanation of the C source code you provided:

#include <stdio.h>

This line includes the standard input/output library, which provides functions for handling input and output operations.

int main() {

This line defines the main() function, which serves as the entry point for the program. The int at the beginning of the line specifies that the function should return an integer value. Since there are no parameters between the parentheses, this function takes no arguments.

printf("Hack The Planet");

This line uses the printf() function to output the string "Hack The Planet" to the console. The printf() function is part of the standard input/output library and is used to print formatted output to the console. In this case, the string is enclosed in double quotes, which is how string literals are represented in C.

printf("\n");

This line uses the printf() function again to output a newline character to the console. The \n character is an escape sequence that represents a newline character in C.

printf("Hack The Planet 2");

This line uses the printf() function once again to output the string "Hack The Planet 2" to the console.

return 0;

This line returns the integer value 0 from the main() function. This value is typically used to indicate to the operating system whether the program executed successfully (a return value of 0 means success, while a non-zero value indicates an error). In this case, since the program simply prints some output to the console and then exits, a return value of 0 is appropriate.

Why do we need to use quotes in C programming 

Quotes are used in C programming to delimit string literals, which are sequences of characters enclosed in double quotes. String literals are used to represent text in a C program.

For example, in the following line of code:

printf("Hello, world!");

The string literal "Hello, world!" is enclosed in double quotes. This tells the C compiler that the characters between the quotes should be treated as a single string.

In addition to string literals, quotes are also used to delimit character literals, which are single characters enclosed in single quotes. For example:

char c = 'A';

In this line of code, the character literal 'A' is enclosed in single quotes. This tells the C compiler that the value of the variable c should be set to the ASCII value of the character 'A', which is 65.

Quotes are an important part of C programming because they allow programmers to represent text and characters in their programs. Without quotes, it would be difficult to work with strings and characters in a C program.

What are strings 

In programming, a string is a sequence of characters. Strings are commonly used to represent text in computer programs, and are often used for tasks such as input/output operations, text manipulation, and data storage.

In C programming, strings are represented as arrays of characters. For example, the following line of code declares a string named message:

char message[] = "Hello, world!";

In this example, the string "Hello, world!" is stored in an array of characters named message. The array is automatically sized to accommodate the length of the string.

C provides a number of functions for working with strings, including functions for copying, concatenating, and comparing strings. For example, the strcpy() function is used to copy one string to another, the strcat() function is used to concatenate two strings, and the strcmp() function is used to compare two strings.

Strings are an important part of programming, and are used in a wide variety of applications. In addition to representing text, strings can be used to store and manipulate binary data, such as images and audio files.

Why do we need to compile C source code ?

C is a compiled programming language, which means that source code must be compiled into executable code before it can be run on a computer. The compilation process translates the human-readable source code into machine-readable instructions that can be executed by the computer's processor.

There are several reasons why we need to compile C source code:

  1. To catch errors: The compilation process checks the source code for syntax errors, type errors, and other potential issues that can cause the program to fail at runtime. By catching these errors during compilation, we can fix them before the program is ever run, saving time and reducing the risk of errors in the final product.

  2. To optimize performance: The compiler can optimize the code generated from the source code to improve its performance. This includes optimizing the use of memory, improving the efficiency of loops and other constructs, and generating code that takes advantage of features of the target hardware.

  3. To create portable code: Compiled code is generally platform-independent, which means that it can be run on any computer that has the necessary libraries and runtime environment. This makes it easier to distribute and deploy software to different platforms and operating systems.

  4. To protect intellectual property: Compiled code is more difficult to reverse engineer than source code, which can help protect the intellectual property of software developers and prevent others from stealing or copying their code.

The compilation process is an essential step in the development of C programs, as it ensures that the code is correct, optimized, and portable.

Are C compilers free ? 

Yes, there are several free and open-source C compilers available for download, such as GCC (GNU Compiler Collection) and Clang. These compilers can be used to compile C source code into executable files on a wide range of platforms, including Linux, Windows, and macOS.

In addition to open-source compilers, there are also commercial C compilers available for purchase, such as Microsoft Visual C++, Intel C++ Compiler, and CodeWarrior. These compilers typically offer additional features and optimizations that may be useful for certain applications, but they come at a cost.

Regardless of whether you choose to use a free or commercial C compiler, it is important to choose a compiler that is reliable, well-supported, and compatible with the platform and tools you are using for development.

Is it hard to reverse program writen in C ?

Reversing a program written in C can be difficult, but it is not impossible. The difficulty of reversing a program depends on various factors, such as the complexity of the program, the level of obfuscation or anti-reverse engineering techniques used in the code, and the reverse engineer's skill and experience.

C is a compiled language, which means that the source code is translated into machine code before it can be executed. This machine code is not human-readable and can be difficult to understand or modify without reverse engineering tools and techniques. However, reverse engineers can use tools such as disassemblers, debuggers, and decompilers to analyze the machine code and reverse engineer the original source code.

Additionally, C programs can be obfuscated or protected using various anti-reverse engineering techniques, such as code obfuscation, encryption, and tamper detection. These techniques are designed to make the program harder to reverse engineer by making the code more difficult to read, analyze, or modify.

Reversing a C program can be a challenging task, but it is possible with the right tools and expertise. However, it is important to note that reverse engineering software without permission is often illegal and unethical, and can lead to serious consequences.

C Tutorial - 1 - Setup and First Compilation

#include <stdio.h>

int main() {
    printf("Hack The Planet");
    printf("\n");
    printf("Hack The Planet 2");
    return 0;
}

Result:

Hack The Planet
Hack The Planet 2
Process returned 0 (0x0)   execution time : 0.030 s
Press any key to continue.

This is a simple C program that prints the text "Hack The Planet" and "Hack The Planet 2" on separate lines, followed by a newline character to ensure that the output is properly formatted.

Here's a breakdown of the code:

  • The first line includes the standard input/output library, which provides functions for inputting and outputting data.
  • The main function is the starting point of the program. It is where the program execution begins.
  • The printf function is used to print output to the console. In this case, it prints the text "Hack The Planet" followed by a newline character (\n), which moves the cursor to the beginning of the next line. Then, it prints "Hack The Planet 2" on the following line, and finally returns the value 0 to indicate successful program completion.

This program is a simple example of how to use the printf function in C to output text to the console.

What is standard input/output library

The standard input/output library, also known as the "stdio" library, is a standard library of C programming language that provides a set of functions for handling input and output operations. The library is defined in the header file "stdio.h", and it includes functions for reading from and writing to files, as well as functions for reading from and writing to the console (also known as standard input and standard output, respectively).

Some of the most commonly used functions in the stdio library include printf, scanf, fgets, fopen, fclose, fread, and fwrite, among others. These functions provide a flexible and efficient way to interact with input and output streams, and they are widely used in C programming for a variety of purposes, such as printing messages to the console, reading user input, reading and writing files, and more.

What are functions in programming

In programming, a function is a self-contained block of code that performs a specific task or set of tasks. Functions are a fundamental building block of most programming languages, and they allow programmers to write reusable and modular code.

A function usually takes one or more input parameters as arguments, and may or may not return a value as output. When a function is called, the program passes the input values to the function, which performs the specified operations and optionally returns a result. This result can then be used in other parts of the program, or passed as an argument to other functions.

Functions can be defined by the programmer, or they can be part of a library or framework that is included in the programming language. Some examples of functions in programming include mathematical functions (such as sqrt or sin), string manipulation functions (such as strlen or strcmp), and file I/O functions (such as fopen or fwrite).

By breaking down a program into smaller, more modular functions, programmers can write more maintainable and scalable code, and avoid duplicating code in multiple places. Functions also make it easier to debug and test code, since individual functions can be isolated and tested independently of the rest of the program.

What is main() function and why we need it in C programming

In C programming, main() is a special function that serves as the entry point for the program. When a C program is executed, the operating system loads the program into memory and starts execution at the beginning of the main() function.

The main() function is required in all C programs, and it must have a specific signature: it should return an integer value, and it should either take no arguments, or take two arguments: an integer representing the number of command-line arguments, and an array of strings representing the command-line arguments themselves.

The purpose of the main() function is to specify the behavior of the program. It typically contains a sequence of statements that define the program's logic and control flow, such as variable declarations, function calls, conditional statements, loops, and input/output operations.

In short, the main() function is essential in C programming because it provides a starting point for the program's execution and defines its behavior. Without a main() function, a C program would not be able to run or do anything useful.

Why do we need to include external files in programming

In programming, it's common to need to use external files or libraries that are not part of the main program. Including these external files in a program provides a way to reuse code and avoid duplicating efforts.

There are several reasons why including external files is important in programming:

  1. Reusability: By including external files, programmers can reuse code that has already been written instead of writing it again from scratch. This saves time and effort and helps to ensure consistency in the code.

  2. Modularity: Including external files can help to organize the code into smaller, more manageable modules. This makes the code easier to read, understand, and maintain.

  3. Scalability: As a program grows in size and complexity, including external files can help to manage its complexity. Breaking down the code into smaller modules makes it easier to scale and maintain.

  4. Libraries: External files often contain libraries of pre-written functions that can be used by the main program. This allows programmers to take advantage of existing code and libraries, which can save time and effort.

  5. Separation of concerns: Including external files can help to separate the concerns of the program. For example, one file may contain the user interface code, while another file may contain the business logic. This separation can make it easier to understand and modify the code.

Including external files is an important technique in programming that helps to promote code reuse, modularity, scalability, and separation of concerns.

Version of UNIX/BSD I am using - uname tutorial

To find out which version of OS we are using, we will use UNIX uname command, alone, or with additional options:

This is result on my system:

#uname
OpenBSD

More info about system you will get with "uname -a":

#uname -a OpenBSD swordfish 4.8 GENERIC#136 i386

Machine type,  "uname -m":

#uname -m i386

Machine nodename (network name),  "uname -n":

#uname -n swordfish

Some details on processor, "uname -p":

#uname -p Intel(R) Pentium(R) 4 Mobile CPU 1.70 GHz ("GenuineIntel" 686-class)

Release with "uname -r":

#uname -r 4.8

System version, "uname -v":

#uname -v GENERIC#136

All in all, except "uname -p" for info on CPU, all you need is "uname -a".

Check your man uname page.

Software Installed on OpenBSD System , pkg-info tutorial

To find out what we have on our OpenBSD system, we will use pkg_info:

#pkg_info

BitTorrent-4.4.0p6  cooperative file distribution system implemented in Python
BitTorrent-gui-4.4.0p6 graphical interface components for BitTorrent
ImageMagick-6.4.5.6p0 image processing tools
ORBit2-2.14.18      high-performance CORBA Object Request Broker
OpenEXR-1.6.1p1     high dynamic range image format
agg-2.5p1           anti-grain geometry graphics library
amarok-1.4.10p4     music player for KDE
arts-1.5.10p3       K Desktop Environment, aRTs
aspell-0.60.6p4     spell checker designed to eventually replace Ispell
atk-1.30.0p0        accessibility toolkit used by gtk+
august-0.63bp0      html editor designed for the experienced web designer
avahi-0.6.27        framework for Multicast DNS Service Discovery
blas-1.0p3          Basic Linear Algebra Subprograms
boost-1.42.0p2      free peer-reviewed portable C++ source libraries
bzip2-1.0.5         block-sorting file compressor, unencumbered
cairo-1.8.10p0      vector graphics library
cdparanoia-3.a9.8p0 CDDA reading utility with extra data verification features
curl-7.20.0         get files from FTP, Gopher, HTTP or HTTPS servers
cyrus-sasl-2.1.23p0 RFC 2222 SASL (Simple Authentication and Security Layer)
dbus-1.2.24p4       message bus system
dbus-glib-0.86p1v0  glib bindings for dbus message system
desktop-file-utils-0.16p0 utilities for 'desktop' entries
epdfview-0.1.7p5    lightweight PDF document viewer
faac-1.26           MPEG-2 and MPEG-4 AAC encoder
faad-2.6.1p1        MPEG-2 and MPEG-4 AAC decoder
ffmpeg-20100512p0   audio/video converter and streamer with bktr(4) support
flac-1.2.1p0        free lossless audio codec
fribidi-0.10.4p0    library implementing the Unicode Bidirectional Algorithm
gconf2-2.28.1p2     configuration database system for GNOME
gdbm-1.8.3p0        GNU dbm
gettext-0.18.1      GNU gettext
ghostscript-8.63p13 GNU PostScript interpreter
ghostscript-fonts-8.11p2 35 standard PostScript fonts with Adobe name aliases
glib2-2.24.1p2      general-purpose utility library
glitz-0.5.6p2       OpenGL image compositing library
gnash-0.8.3p4       flash player with firefox browser plugin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
 Cut here because of readability
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
x264-20100511       free H264/AVC encoder
xine-lib-1.1.18.1p1 multimedia decoding library
xvidcore-1.2.2p1    ISO MPEG-4 compliant video codec
yt-15               fetch youtube and google videos 

You can use some options with pkg_info, example for package  yt-15:

#pkg_info -c yt-15,  for comment about program/package at one line

Information for inst:yt-15

Comment:
fetch youtube and google videos

#pkg_info -d yt-15,  for detailed comments on installed program/package

 Information for inst:yt-15

Description:
yt is an extensible Lua script to fetch videos from YouTube.com. You can
(and probably should) customize it to use your preferred encoding tool.
By default it uses graphics/ffmpeg.

Maintainer: Martynas Venckus <martynas@openbsd.org>

OpenBSD pkg_info do have some more options, and it is used on other BSD system, so you need to check man pkg_info page for your OS version.

In any case, it is important to know (if you get your hands on OpenBSD) that report on installed software is available with pkg_info.

Multiple IP Addresses on Single Network Card - OpenBSD IP Alias tutorial

Situation: 

1. Do you have a router (a separate device) through which several computers in a company goes to the Internet (via a hub). In this case that is a wireless router.  
2. Router must have a static IP address (eg 192.168.1.1), so that in the event of a server crash some of the clients on the LAN at the company could fix him. 
3. Some computers on the LAN do not need to have a static local address, but some do. 
4. ISP assigns you a dynamic IP address for the router and computers behind them, if you set them so.
5. Some of computer on LAN need to have, for various reasons, bouth static and dynamic IP. Of course, server is among them.

Why OpenBSD server need to have a dynamic address? 

Because in this case server must have indipendent connection to outside world. 

You should not be dependent (in office) on just one line to the Internet - must be able for fast switch to another Internet line, with second router, dial up modem or  other device (radio, satelite link, etc). 

Why server must have a static IP address, other than those provided by the dynamic ISP via DHCP? 

To access computer in the local network and reverse, regardless of whether it has or does not have access to the internet. 

Why does the router to your ISP has a static IP address?
 
 In case of cancellation of the server, which has a static IP address (alias) and dynamic address given by the ISP, computers that are behind a router on the local network (typically workstations) can access the router and configure router if needed.

 If router loses a dynamic address, computers that were behind him will also lose their IP adresses. In order to set up the router, it must be reset to factory setings. 

And that can be done just with static adressing. 

So, we don't wan't to waste company time, right ?

Note, it is possible for you to have multiple accounts with one (wireless) ISP over just one router. It is important to note that the OpenBSD machines do have just one network card, in this case, and no more. But we need multiple IPs for our OpenBSD server.

 How to set up one or more IP addresses on one card ?:

 ifconfig fxp0 alias 192.168.1.49 255 255 255 255

Explanation:

ifconfig - this command adjusts the network parameters of the OpenBSD and similar systems
fxp0 - this is the network card on the system
192.168.1.49 - this is the IP address that we want to add 255 255 255 255 - this is the "netmask". Use this IP address when you make IP alias, after "real" IP (192.168.1.49)

For example, let's add one more IP address to NIC:

ifconfig fxp0 alias 192.168.1.23 255.255.255.255
# Ifconfig fxp0
fxp0: flags = 8843 mtu 1500
        lladdr 00:00: xx: xx: xx: xx
        priority: 0
        media AutoSelect Ethernet (100BaseTX full-duplex)
        Status: Active
        inet6 xxx% fxp0 prefixlen 64 scopeid 0x1
        iNet 10x.x01.111.16 netmask 0xffffff00 broadcast 10x.x01.111.255
        inet 192.168.1.49 netmask 0xffffff00 broadcast 255,255,255,255
        inet 192.168.1.23 netmask 0xffffff00 broadcast 255,255,255,255

Can we ping router now ?

# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1): 56 data bytes
64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=0.751 ms
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.970 ms
--- 192.168.1.1 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.751/0.860/0.970/0.113 ms
#

As soon as we can ping something, we can manage that thing, right ?
Do we have an exit to the Internet?

# ping google.com
PING google.com (173.194.39.69): 56 data bytes
64 bytes from 173.194.39.69: icmp_seq=1 ttl=52 time=38.831 ms
64 bytes from 173.194.39.69: icmp_seq=2 ttl=52 time=23.956 ms
64 bytes from 173.194.39.69: icmp_seq=3 ttl=52 time=10.524 ms
64 bytes from 173.194.39.69: icmp_seq=4 ttl=52 time=12.198 ms
--- google.com ping statistics ---
5 packets transmitted, 4 packets received, 20.0% packet loss
round-trip min/avg/max/std-dev = 10.524/21.377/38.831/11.328 ms
#

Ok, the system is up.

If you want to assign a permanent IP alias to a network card ?

It is necessary to add this line to  /etc/hostname.fxp0 :

inet alias xxx.xxx.xxx.xxx 255.255.255.0

Of course, instead of Xs insert the desired IP address you need.

To delete an alias IP's use the command

# Ifconfig fxp0 delete 192.168.1.23 
# Ifconfig fxp0 delete 192.168.1.49

Now you can have a lot of "NICs" at your disposal.

How to take screenshot - OpenBSD - Scroot

We can take a screenshot in UNIX/BSD/Linux systems with "scrot" program.

First, I will install it on my OpenBSD system. Let's define location where packages are, with PKG_PATH:

# export PKG_PATH=http://ftp.vim.org/OpenBSD/4.8/packages/i386 
Checking program description and location with "pkg_info scrot": 
# pkg_info scrot    
Information for http://ftp.vim.org/OpenBSD/4.8/packages/i386/scrot-0.8p1.tgz

Comment:
commandline screen capture util

Description:
scrot is a commandline screen capture util like "import", but using
imlib2. It has lots of options for autogenerating filenames, and can
do fun stuff like taking screenshots of multiple displays and glueing
them together.

Maintainer: Victor Sahlstedt 

WWW: http://www.linuxbrit.co.uk/scrot/ 
Ok. Now we will instal scrot with pkg_add: 
# pkg_add -v scrot-0.8p1.tgz

scrot-0.8p1:imlib2-1.4.2p1: ok                                                 
scrot-0.8p1:giblib-1.2.4p4: ok                                                 
scrot-0.8p1: ok                                                                
# 

That's fine. Please note that saved shots will be in working directory. In this case "/home/scrot":

#pwd
/home 
# mkdir scrot
# cd scrot
# pwd
/home/scrot

So far, so good. Take note about naming convention : 

# man scrot man: Formatting manual page...

scrot(1)                                                 scrot(1)

NAME
       scrot - Screen capture using imlib2

SYNOPSIS
       scrot [options] [file]

DESCRIPTION
       scrot  is  a  screen capture utility using the imlib2 library to aquire
       and save images.  scrot has a  few  options,  detailed  below.  Specify
       [file]  as  the  filename  to save the screenshot to.  If [file] is not
       specified, a date-stamped file will be dropped in  the  current  direc-
       tory.

Last check, are we in right directory ?

# pwd
/home/scrot
# ls
# 

To get a screenshot of whole screen, we need just "scrot", without additional options. Default filetype is .png. Take note about timestamp.

# scrot
# ls
2013-01-04-152547_1024x768_scrot.png
# 

If we need countdown option:  

# scrot -d 5 -c 

Taking shot in 5.. 4.. 3.. 2.. 1.. 0.
# ls
2013-01-04-152547_1024x768_scrot.png    2013-01-04-152940_1024x768_scrot.png
#    

In case above, "-d" is for countdown, "5" is number of seconds, and "-c" is for showing countdown on screen.

You can define quality of screenshot in range scale up to 100. Default quality is 75. We will use "scrot -q 10", just to test it:

# scrot -q 10 
# ls -lh 

total 548
-rw-r--r--  1 root  wheel  94.2K Jan  4 15:25 2013-01-04-152547_1024x768_scrot.png
-rw-r--r--  1 root  wheel  95.5K Jan  4 15:29 2013-01-04-152940_1024x768_scrot.png
-rw-r--r--  1 root  wheel  81.1K Jan  4 15:32 2013-01-04-153221_1024x768_scrot.png
# 

Pay attention to size of shot on 153221, it's smaller than 152940, of course.

How to change file type for screenshot ? For example, use "$t filename.jpg" :

# scrot $t desktop.jpg
# ls -lh
total 792
-rw-r--r--  1 root  wheel  94.2K Jan  4 15:25 2013-01-04-152547_1024x768_scrot.png
-rw-r--r--  1 root  wheel  95.5K Jan  4 15:29 2013-01-04-152940_1024x768_scrot.png
-rw-r--r--  1 root  wheel  81.1K Jan  4 15:32 2013-01-04-153221_1024x768_scrot.png
-rw-r--r--  1 root  wheel   120K Jan  4 15:38 desktop.jpg

Now we have screenshot in .jpg format.

How to take screenshot of window, or region ?

Use "scrot -s" command, pres ENTER, left mouse clickdefine region, release click, wait for prompt:

# scrot -s $t windows.jpg  
# ls -hl
total 876
-rw-r--r--  1 root  wheel  94.2K Jan  4 15:25 2013-01-04-152547_1024x768_scrot.png
-rw-r--r--  1 root  wheel  95.5K Jan  4 15:29 2013-01-04-152940_1024x768_scrot.png
-rw-r--r--  1 root  wheel  81.1K Jan  4 15:32 2013-01-04-153221_1024x768_scrot.png
-rw-r--r--  1 root  wheel   120K Jan  4 15:38 desktop.jpg
-rw-r--r--  1 root  wheel  41.8K Jan  4 15:42 windows.jpg 

New file is windows.jpg, and that file is smaller, because region for shot is smaller than whole screen.

Scrot program have option to define shot width, height, to execute additional command after taking shot (copy to another dir), etc.

Check man page for your version of scrot.

How to Mount Android phone as Flash Drive in OpenBSD

If you need to transfer some files to OpenBSD box from cell phone/flash/card.

But before everything:

Please, be sure that your mem.card/flash/external disk is properly pluged in USB/sock/whatever.

First I will make "htc" directory in /mnt:

#pwd
/mnt
#mkdir htc

Is directory there ?

#ls
htc

Ok. Let plug device into USB port. Here is report from console:

umass0: using SCSI over Bulk-Only
scsibus1 at umass0: 2targets, inititor 0
sd0 at scsibus1 targ 1 lun0: <HTC, Android Phone, 0100> SCSI2 0/direct removable
sd0: drive offline

So far, so good. Now, run disklabel sd0:

#disklabel sd0

# /dev/rsd0c:
type: SCSI
disk: SCSI disk
label: Android Phone   
uid: 0000000000000000
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 255
sectors/cylinder: 16065
cylinders: 240
total sectors: 3862528
boundstart: 0
boundend: 3862528
drivedata: 0 

16 partitions:
#                size           offset  fstype [fsize bsize  cpg]
  c:          3862528                0  unused                   
  i:          3862399              129   MSDOS                   

What we have ? fstype is MSDOS :) , and sd0 goes sd0i ( i = partition, see above).

Mounting:

#mount -t msdos /dev/sd0i /mnt/htc

Check:

#mount:

/dev/wd0a on / type ffs (local)
/dev/wd0k on /home type ffs (local, nodev, nosuid)
/dev/wd0d on /tmp type ffs (local, nodev, nosuid)
/dev/wd0f on /usr type ffs (local, nodev)
/dev/wd0g on /usr/X11R6 type ffs (local, nodev)
/dev/wd0h on /usr/local type ffs (local, nodev)
/dev/wd0j on /usr/obj type ffs (local, nodev, nosuid)
/dev/wd0i on /usr/src type ffs (local, nodev, nosuid)
/dev/wd0e on /var type ffs (local, nodev, nosuid)
/dev/sd0i on /mnt/htc type msdos (local)

That's it.  Now, do what you need to do with your data in /mnt/htc or some other dir...

For sure, check your local man mount/umount page.

How to make files from a list in Perl

Some time ago I was in need to create a lot of html files, thousands of them in some 20 dirs. So, no manual work here, of course.

Here is simple Perl script to automate this process. There is some file, list-to-make.txt, in this case, where on every line you have name of future file. Program will read that list, and for every line make empty file using system touch UNIX command.

Please note, if you need file with some extension, than state that extension in list-to-make.txt, example:

  • 1file
  • 2file.txt
  • 3file.html
  • 4file.htm

Source code in Perl:

#!usr/bin/perl

print "****************************************************************\n";
print "Program: massmake.pl, ver:0.1, 11/Dec/2012\n";
print "Autor : Milan Smudja";
print "****************************************************************\n";
#This program will make files listed in list-to-make.txt in same dir 
#where program is stored. 

open SOURCEFILE, "list-to-make.txt" || die "Damn, can\'t read from file$!";
@lines = <SOURCEFILE>;
foreach $line (@lines) {
   system "touch $line" || die "Can\'t use sustem touch... $!";
}

 

List files in UNIX directory - ls command

UNIX ls command is something you will need every day if you decide to move to or work on UNIX systems. UNIX ls command is used for listing files and directories on all operating systems similar to UNIX.

Depending on the directory where you are, you will get a list of files and directories, in order to check your parent dir, use UNIX pwd command.

UNIX ls command has many options, for example, if you type just ls, you will get a simple report.

If you type ls -1 (number one), you have a report format "line by line". The command ls-A produce report without the "." and "..", while the command ls -a produce report with "."

You need the directories? - You will use ls-F and at the end of each directory there will be slash ("/"), asterisk ("*") for an executable file ("@") sign to the symbolic link (or "=") for the socket.

UNIX ls command with the -g, gives a detailed report on current directory without the information about the owner:

#ls -g

total 47376
-rw-r--r--   1 wheel      578 Aug 16  2010 .cshrc
-rw-r--r--   1 wheel      411 Aug 16  2010 .profile
drwxr-xr-x   2 wheel      512 Aug 16  2010 altroot
drwxr-xr-x   2 wheel     1024 Aug 16  2010 bin
-rw-r--r--   1 wheel    47320 Sep  7  2011 boot
-rw-r--r--   1 wheel  8854601 Sep  7  2011 bsd
-rw-r--r--   1 wheel  8878433 Sep  7  2011 bsd.mp
-rw-r--r--   1 wheel  6327987 Sep  7  2011 bsd.rd
drwxr-xr-x   3 wheel    23552 Dec 21 05:15 dev
drwxr-xr-x  33 wheel     2560 Dec 21 05:21 etc
drwxr-xr-x  14 wheel    22016 Dec 21 06:34 home
drwxr-xr-x   6 wheel      512 Sep 26  2011 mnt
drwx------  20 wheel     1536 Dec 21 05:16 root
drwxr-xr-x   2 wheel     1536 Aug 16  2010 sbin
drwxr-xr-x   2 wheel      512 Aug 16  2010 stand
lrwxr-xr-x   1 wheel       11 Sep  7  2011 sys -> usr/src/sys
drwxrwxrwt   5 wheel      512 Dec 21 06:32 tmp
drwxr-xr-x  17 wheel      512 Aug  8  2010 usr
drwxr-xr-x  25 wheel      512 Sep 14  2011 var

Most useful combination? For shure that is  ls -l. This combination is similar to ls -g, but you will get report with owner info:

#ls -l

total 47376
-rw-r--r--   1 root  wheel      578 Aug 16  2010 .cshrc
-rw-r--r--   1 root  wheel      411 Aug 16  2010 .profile
drwxr-xr-x   2 root  wheel      512 Aug 16  2010 altroot
drwxr-xr-x   2 root  wheel     1024 Aug 16  2010 bin
-rw-r--r--   1 root  wheel    47320 Sep  7  2011 boot
-rw-r--r--   1 root  wheel  8854601 Sep  7  2011 bsd
-rw-r--r--   1 root  wheel  8878433 Sep  7  2011 bsd.mp
-rw-r--r--   1 root  wheel  6327987 Sep  7  2011 bsd.rd
drwxr-xr-x   3 root  wheel    23552 Dec 21 05:15 dev
drwxr-xr-x  33 root  wheel     2560 Dec 21 05:21 etc
drwxr-xr-x  14 root  wheel    22016 Dec 21 06:34 home
drwxr-xr-x   6 root  wheel      512 Sep 26  2011 mnt
drwx------  20 root  wheel     1536 Dec 21 05:16 root
drwxr-xr-x   2 root  wheel     1536 Aug 16  2010 sbin
drwxr-xr-x   2 root  wheel      512 Aug 16  2010 stand
lrwxr-xr-x   1 root  wheel       11 Sep  7  2011 sys -> usr/src/sys
drwxrwxrwt   5 root  wheel      512 Dec 21 06:32 tmp
drwxr-xr-x  17 root  wheel      512 Aug  8  2010 usr
drwxr-xr-x  25 root  wheel      512 Sep 14  2011 var

If you need info on last change you will use ls - lt:

#ls -lt

total 47376
drwxr-xr-x  14 root  wheel    22016 Dec 21 06:34 home
drwxrwxrwt   5 root  wheel      512 Dec 21 06:32 tmp
drwxr-xr-x  33 root  wheel     2560 Dec 21 05:21 etc
drwx------  20 root  wheel     1536 Dec 21 05:16 root
drwxr-xr-x   3 root  wheel    23552 Dec 21 05:15 dev
drwxr-xr-x   6 root  wheel      512 Sep 26  2011 mnt
drwxr-xr-x  25 root  wheel      512 Sep 14  2011 var
-rw-r--r--   1 root  wheel    47320 Sep  7  2011 boot
lrwxr-xr-x   1 root  wheel       11 Sep  7  2011 sys -> usr/src/sys
-rw-r--r--   1 root  wheel  8878433 Sep  7  2011 bsd.mp
-rw-r--r--   1 root  wheel  6327987 Sep  7  2011 bsd.rd
-rw-r--r--   1 root  wheel  8854601 Sep  7  2011 bsd
drwxr-xr-x   2 root  wheel     1536 Aug 16  2010 sbin
drwxr-xr-x   2 root  wheel     1024 Aug 16  2010 bin
-rw-r--r--   1 root  wheel      578 Aug 16  2010 .cshrc
-rw-r--r--   1 root  wheel      411 Aug 16  2010 .profile
drwxr-xr-x   2 root  wheel      512 Aug 16  2010 altroot
drwxr-xr-x   2 root  wheel      512 Aug 16  2010 stand
drwxr-xr-x  17 root  wheel      512 Aug  8  2010 usr

Last access time is available with  ls -lu:

#ls -lu

total 47376
-rw-r--r--   1 root  wheel      578 Jan 29  2012 .cshrc
-rw-r--r--   1 root  wheel      411 Jan 29  2012 .profile
drwxr-xr-x   2 root  wheel      512 Dec 21 07:09 altroot
drwxr-xr-x   2 root  wheel     1024 Dec 21 07:20 bin
-rw-r--r--   1 root  wheel    47320 Jan 29  2012 boot
-rw-r--r--   1 root  wheel  8854601 Jan 29  2012 bsd
-rw-r--r--   1 root  wheel  8878433 Jan 29  2012 bsd.mp
-rw-r--r--   1 root  wheel  6327987 Jan 29  2012 bsd.rd
drwxr-xr-x   3 root  wheel    23552 Dec 21 07:17 dev
drwxr-xr-x  33 root  wheel     2560 Dec 21 07:09 etc
drwxr-xr-x  14 root  wheel    22016 Dec 21 07:09 home
drwxr-xr-x   6 root  wheel      512 Dec 21 07:17 mnt
drwx------  20 root  wheel     1536 Dec 21 07:13 root
drwxr-xr-x   2 root  wheel     1536 Dec 21 07:17 sbin
drwxr-xr-x   2 root  wheel      512 Dec 21 07:10 stand
lrwxr-xr-x   1 root  wheel       11 Sep  7  2011 sys -> usr/src/sys
drwxrwxrwt   5 root  wheel      512 Dec 21 07:18 tmp
drwxr-xr-x  17 root  wheel      512 Dec 21 07:16 usr
drwxr-xr-x  25 root  wheel      512 Dec 21 07:07 var 

Always check your man ls page.

Check who is logged into UNIX server

The answer to the question: "Who is logged on to the system?" is simple. Just use UNIX "who" command:

# who   
root     ttyC0    Dec 30 13:45 
root     ttyp1    Dec 30 14:43   (:0.0)
root     ttyp3    Dec 30 13:47   (:0.0)
root     ttyp4    Dec 30 14:00   (:0.0)
root     ttyp6    Dec 30 14:02   (:0.0)
root     ttypc    Dec 30 14:35   (:0.0)

If this report is not clear, use the "who" command with the addition of -H, to get report Header:

# who -H
USER     LINE     WHEN           FROM 
root     ttyC0    Dec 30 13:45 
root     ttyp1    Dec 30 14:43   (:0.0)
root     ttyp3    Dec 30 13:47   (:0.0)
root     ttyp4    Dec 30 14:00   (:0.0)
root     ttyp6    Dec 30 14:02   (:0.0)
root     ttypc    Dec 30 14:35   (:0.0)

Well, this report is not so interesting at all. Just me. It's ok, there is no any of paratroopers:

With "who -m", or "who am i" or "who i am" you can get info on current terminal:

# who -m 
root     ttyp1    Dec 30 14:43   (:0.0)
# who i am
root     ttyp1    Dec 30 14:43   (:0.0)
# who am i
root     ttyp1    Dec 30 14:43   (:0.0)
# 

Fast report is available with "who -q":

# who -q 
root     root     root     root     root     root     
# users=6
# 

You can get terminal status with "who -T". There is 3 options, writable (+), not writable (-), i some problem (?):

# who -T
root     - ttyC0    Dec 30 13:45 
root     + ttyp1    Dec 30 14:43   (:0.0)
root     + ttyp3    Dec 30 13:47   (:0.0)
root     + ttyp4    Dec 30 14:00   (:0.0)
root     + ttyp6    Dec 30 14:02   (:0.0)
root     + ttypc    Dec 30 14:35   (:0.0) 

Do you want to kick somesone from system ?  No problem, just check idle time with "who -u":

# who -u 
root     ttyC0    Dec 30 13:45 01:09 
root     ttyp1    Dec 30 14:43   .     (:0.0)
root     ttyp2    Dec 30 15:06   .     (:0.0)
root     ttyp3    Dec 30 13:47 00:28   (:0.0)
root     ttyp4    Dec 30 14:00 00:09   (:0.0)
hacker   ttyp5    Dec 30 15:08   .     (localhost)
root     ttyp6    Dec 30 14:02 00:59   (:0.0)
root     ttypc    Dec 30 14:35 00:09   (:0.0)
# 

Well, that was just simple root and some hacker ssh-ing inside.

As always, check your local  man who page.

Check free space in UNIX - df command tutorial

To check free disk space on our UNIX system we will use UNIX df command.

Standard report after df command will be simmilar to this (note, this is my old IBM R32 laptop with OpenBSD on it):

#df 

Filesystem  512-blocks      Used     Avail Capacity  Mounted on
/dev/wd0a      1389148    296708   1022984    22%    /
/dev/wd0k     13470908   3247728   9549636    25%    /home
/dev/wd0d      2202748       616   2091996     0%    /tmp
/dev/wd0f      3038428    703640   2182868    24%    /usr
/dev/wd0g      1764380    325380   1350784    19%    /usr/X11R6
/dev/wd0h      6578268   1820580   4428776    29%    /usr/local
/dev/wd0j      2799836         4   2659844     0%    /usr/obj
/dev/wd0i      2799836         4   2659844     0%    /usr/src
/dev/wd0e      3348924    102312   3079168     3%    /var 

If you need more readable report, use df with -h option (Human Readable Output):

#df -h

Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/wd0a      678M    146M    499M    23%    /
/dev/wd0k      6.4G    1.5G    4.6G    25%    /home
/dev/wd0d      1.0G    308K   1022M     0%    /tmp
/dev/wd0f      1.4G    344M    1.0G    24%    /usr
/dev/wd0g      862M    159M    660M    19%    /usr/X11R6
/dev/wd0h      3.1G    889M    2.1G    29%    /usr/local
/dev/wd0j      1.3G    2.0K    1.3G     0%    /usr/obj
/dev/wd0i      1.3G    2.0K    1.3G     0%    /usr/src
/dev/wd0e      1.6G   50.0M    1.5G     3%    /var 

If, for some reason, you need report where blocks are not 512 bytes, but one kilobyte, use df with -k option:

#df -k

Filesystem  1K-blocks      Used     Avail Capacity  Mounted on
/dev/wd0a      694574    149968    509878    23%    /
/dev/wd0k     6735454   1623868   4774814    25%    /home
/dev/wd0d     1101374       308   1045998     0%    /tmp
/dev/wd0f     1519214    351820   1091434    24%    /usr
/dev/wd0g      882190    162690    675392    19%    /usr/X11R6
/dev/wd0h     3289134    910290   2214388    29%    /usr/local
/dev/wd0j     1399918         2   1329922     0%    /usr/obj
/dev/wd0i     1399918         2   1329922     0%    /usr/src
/dev/wd0e     1674462     51156   1539584     3%    /var

How to limit report to just one partition ? It's easy, just use df with, say, /home. Also, we will use -h option again:

#df -h /home

Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/wd0k      6.4G    1.5G    4.6G    25%    /home

You can check inode by #df -i:

Filesystem  512-blocks      Used     Avail Capacity iused   ifree  %iused  Mounted on
/dev/wd0a      1389148    249532   1070160    19%    2936   85638     3%   /
/dev/wd0k     13470908   3247744   9549620    25%   17535  865919     2%   /home
/dev/wd0d      2202748       100   2092512     0%      10  155892     0%   /tmp
/dev/wd0f      3038428    703640   2182868    24%   13683  194187     7%   /usr
/dev/wd0g      1764380    325380   1350784    19%    9017  120901     7%   /usr/X11R6
/dev/wd0h      6578268   1820580   4428776    29%   53722  388004    12%   /usr/local
/dev/wd0j      2799836         4   2659844     0%       1  181885     0%   /usr/obj
/dev/wd0i      2799836         4   2659844     0%       1  181885     0%   /usr/src
/dev/wd0e      3348924    102336   3079144     3%    3671  230183     2%   /var 

 

IRC Bot in Python - Passive IRC Client

This Python script will connect to IRC server and lurk in background. 

 

We are doing network related programming, so first thing is to import socket module. 

We need it to prepare IPv4 connection (socket.AF_INET) with TCP (socket.SOCK_STREAM).

HOST will hold IRC server domain, PORT 6667 will almost always work, and set NICK to something you desire. 

After that we will use s.connect((HOST, PORT)) to prepare for data sending.

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = 'irc.libera.chat' #irc server
PORT = 6667 #port
NICK = 'YourNick'

s.connect((HOST, PORT))

First we will send NICK data finishing with '\r\n'. Sure, we will encode commands with .encode() method.

Same stuff with USER command. IRC is weird one, yes you need 3 "usernames" and one "real name". 

Read more about why at SO excellent link.

After that, we will JOIN #programming channel in this case. Don't forget encoding.

nick_data = ('NICK ' + NICK + '\r\n')
s.send(nick_data.encode())

usernam_data= ('USER YourNick1 YourNick2 YourNick3 :YourNick4 \r\n')
s.send(usernam_data.encode())

s.send('JOIN #programming \r\n'.encode()) #channel

With "while True" we will constantly check for incoming traffic to catch IRC server PING request. Because it's a must to respond with PONG.

Decode incoming stuff as UTF-8, and print results (chat). If PING is at the start of the stream, send same string with PONG. Encode it.

while True:
    result = s.recv(1024).decode('utf-8')
    print(result)

Just use 4 characters after PING (result[0:4) to grab what we need to return back.

 if result[0:4] == "PING":
        s.send(("PONG" + result[4:] + "\r\n").encode())

If length of the received message from IRC server is 0, than probably theres problem with connection so we will just break from script.

 if len(result) == 0:
        break        

Full script:  

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = 'irc.libera.chat' #irc server
PORT = 6667 #port
NICK = 'YourNick'

s.connect((HOST, PORT))

nick_data = ('NICK ' + NICK + '\r\n')
s.send(nick_data.encode())

usernam_data= ('USER YourNick1 YourNick2 YourNick3 :YourNick4 \r\n')
s.send(usernam_data.encode())

s.send('JOIN #programming \r\n'.encode()) #channel
while True:
    result = s.recv(1024).decode('utf-8')
    print(result)

    if result[0:4] == "PING":
        s.send(("PONG" + result[4:] + "\r\n").encode())

    if len(result) == 0:
        break        
        

Learn More:

Free Python Programming Course
Python Examples
Python How To
Python Modules 

YouTube WebDevPro Tutorials

Ping Multiple IP Addresses - Scan Network with Ping - Python

To use ping, we will import os module. To have a little bit of pause between pings, time module is needed.

Variable ip will hold left part of IP address, as a base for full IP. 

import os, time

ip = "192.168.0."

To go through all range of IPs for loop is needed (1, 255)Pause is set to 5 seconds between pings.

Results of pinging for every individual ip address will end up in - result. We will send just one packet, no need for 4 of them. It will be too slow.

Secondary for loop is needed to check for "TTL" string in system return. You can see that with normal pinging in terminal or command prompt if you are on Windows.

for x in range(1, 255):
    time.sleep(5)
    result = os.popen("ping -n 1 " + ip + str(x))

    for linija in result.readlines():
        if "TTL" in linija:
            print("DETECTED: ", linija)

If we are unable to ping IP, that networking device is probably off, so we will just print that.

else:
        print("OFF !", ip + str(x))

 Full Script:

import os, time

ip = "192.168.0."

for x in range(1, 255):
    time.sleep(5)
    result = os.popen("ping -n 1 " + ip + str(x))

    for linija in result.readlines():
        if "TTL" in linija:
            print("DETECTED: ", linija)
    else:
        print("OFF !", ip + str(x))
    

Learn More:

Free Python Programming Course
Python Examples
Python How To
Python Modules 

YouTube WebDevPro Tutorials

Number Stations as Screensaver - Random Number Generator - Python

This Python script will emulate number station stream. You can use it as screensaver or just for experiments. 

Random module is for, well, randomness, and time module is for pause between generations.

import random, time

While True is needed so this random number generator will work constantly.


Variables rn from 1 to 4 will hold random number from 1000 to 9999. 

    rn_1 = random.randint(1000, 9999)
    rn_2 = random.randint(1000, 9999)
    rn_3 = random.randint(1000, 9999)
    rn_4 = random.randint(1000, 9999)

After that, you can just print variables, or, of you need more numbers just multiply existing variables with some constant as 0.8 or something.

    print(rn_1, '\t', int(rn_1*0.8), '\t',
          int(rn_2), '\t',int(rn_2*0.8), '\t',
          int(rn_3), '\t',int(rn_3*0.8), '\t',
          int(rn_4), '\t',int(rn_4*0.8), '\t')
    time.sleep(1)

You can have as menu random numbers as you like :)

Full Script: 

import random, time

while True:
    rn_1 = random.randint(1000, 9999)
    rn_2 = random.randint(1000, 9999)
    rn_3 = random.randint(1000, 9999)
    rn_4 = random.randint(1000, 9999)
    
    print(rn_1, '\t', int(rn_1*0.8), '\t',
          int(rn_2), '\t',int(rn_2*0.8), '\t',
          int(rn_3), '\t',int(rn_3*0.8), '\t',
          int(rn_4), '\t',int(rn_4*0.8), '\t')
    time.sleep(1)

Learn More:

Free Python Programming Course
Python Examples
Python How To
Python Modules 

YouTube WebDevPro Tutorials

Detect Key Presses with Python

 With this simple Python script we will detect keypresses.

If you don't have pynput module, just type this in cmd: "pip install pynput".

We need two custom functions, press_on() will be activated when you press buttons, and press_off() will be activated on release.

If we press Escape, script will terminate.

This is just simple printing on screen, but you can upgrade your functions to do many other things.

from pynput.keyboard import *

def press_on(key):
    print('Press ON {}'.format(key))

def press_off(key):
    print('Press OFF: {}'.format(key))
    if key == Key.esc:
        return False

with Listener(on_press = press_on, on_release = press_off) as listener:
    listener.join()

Learn More:

Free Python Programming Course
Python Examples
Python How To
Python Modules 

YouTube WebDevPro Tutorials

Tkinter Introduction - Top Widget, Method, Button

First, let's make shure that our tkinter module is working ok with simple  for loop that will spawn 5 instances of blank Tk window .  ...