Tag Archive : unix

/ unix

Remote Access Raspberry Pi Using Only X Client

December 9, 2015 | Article | No Comments

There are some ways for accessing Raspberry Pi: access Pi directly or indirectly. You might at least try one of thus method for connecting your Pi to your PC.

The direct access involving access without any medium. You connect screen (LCD screen, for example), keyboards, mice, etc to your Pi. This way, your Raspberry Pi act as normal computer. You operate it like you operate your PC. This method has a drawback, whenever you want to use Pi you must provide appropriate input and output device (keyboard, mouse, screen).

Another way to access Pi is using indirect access. This method involving other medium to access Pi, technically a network. In this term, your Pi is connect to a network and you can access the Pi over the network. SSH and VNC are the good example of this. This method demand us to provide good network connection if you want a good connection.

Accessing Pi over network is good, you don’t need other peripheral / device such as keyboard, mouse, or LCD screen. If you want to do thing graphically you can use VNC (Virtual Network Computing). However, using VNC is somehow slow because the application and desktop environment are rendered both on your Pi and your desktop. VNC also require better network as it sends picture / screen image over time.

There is a better solution for this problem. Instead of rendering the graphic on Pi, why don’t we render it on our local computer? This way, Pi only send us minimal packet. Using this method, we can also use keyboard and mouse on our local computer, just like indirect access do.

In this article we will discuss about other way to remote accessing your desktop without VNC. We will use X.org which is used for Linux & Unix OS for GUI. For this article I use:

  1. Slackware64 14.0 on PC
  2. Raspbian Wheezy on Raspberry Pi

This article is written for Linux. If you use Windows, go here.

X Window System – Server & Client Architecture

X Window is originated at the Massachussetts Institute of Technology (MIT) In 1984. X11 is the system-level software infrastructure for the windowing GUI on Linux, *BSD, and other UNIX-like Operating System. It is designed to handle both local display, as well as across the network displays. X Window is a computer software system and network protocol that provides a basis for graphical user interfaces (GUIs) and rich input device capability for networked computers. It creates a hardware abstraction layer where software is written to use a generalized set of commands, allowing for device independence and reuse of programs on any computer that implements X.

X was designed from the beginning to be network-centric. It adopts a “client-server” model.

In the X model, the “X server” runs on the computer that has the keyboard, monitor, and mouse attached. The server’s responsibility includes tasks such as managing the display, handling input from the keyboard and mouse, and other input or output devices (i.e., a “tablet” can be used as an input device, and a video projector may be an alternative output device). Each X application (such as XTerm or Firefox) is a “client”. A client sends messages to the server such as “Please draw a window at these coordinates”, and the server sends back messages such as “The user just clicked on the OK button”.

In a home or small office environment, the X server and the X clients commonly run on the same computer. However, it is perfectly possible to run the X server on a less powerful desktop computer, and run X applications (the clients) on, say, the powerful and expensive machine that serves the office. In this scenario the communication between the X client and server takes place over the network.

This confuses some people, because the X terminology is exactly backward to what they expect. They expect the “X server” to be the big powerful machine down the hall, and the “X client” to be the machine on their desk.

It is important to remember that the X server is the machine with the monitor and keyboard, and the X clients are the programs that display the windows.

Preparations

As stated before, the X window is using client/server model. Our communication would be on top of secure connection. Specifically, SSH (Secure SHell) connection are chosen to transport data (as a tunneling). Therefore, we should configure SSH server properly.

Now on your Raspberry Pi, configure SSH server. Obviously, you MUST install your SSH server program. Edit following file /etc/ssh/ssh_config, make sure these lines are not commented.

ForwardAgent yes
ForwardX11 yes
ForwardX11Trusted yes

Now open /etc/ssh/sshd_config and edit the file so it has following line:

X11Forwarding yes

Restart the SSH Server.

Remote Display

Running X on your local machine, you should have more than 1 tty (teletype). Go to tty 1 (or any from 2 to 6) and you would see a black screen with login message there. Login with your account.

Next we need to make an X server. This server is another X server running on our local machine. This X server will manage our local screen output. We use this server to display anything from our X client, which is raspberry pi.

export DISPLAY=:1

Now, the easiest way is to do is running X on display :1.

X :1 &; xterm

You should be brought to new tty with a blank screen and a “window” there.

Now connect to Raspberry Pi using SSH.

ssh -X [email protected]_ip_address

user is the username we will use and the raspberry_ip_address is the Pi’s IP address. Make sure you can access and you can login to Pi.

Once you are logged in, execute this to start the X.

lxsession &
lxpanel &

Now, your tty should be drawn to your Raspbian’s LXDE.

When you want to back to your original desktop, press CTRL+ALT+F7. When you want to back to Pi’s desktop, press CTRL+ALT+F8.

Drawbacks

This method require more resource on local computer as your local computer run 2 X Server at same time.

You should also note that you can only do swap display to change between these two display. Using VNC, you can display the content of Pi display as a window.

Installation of CMake

December 9, 2015 | Article | 2 Comments

CMake is a cross platform, open-source build system consists of tools designed to build, test, and packaging software. It used to control the software compilation process using simple platform and compiler independent configuration files.

In general, CMake generates native makefiles and workspaces that can be used in the chosen compiler environment.

In this article, we will discuss about how to install CMake, either binary or from sources. The method we use here is generic way, which means, it can be applied to any Operating System. However, for demonstration I will use following machine:

  1. Slackware64 14.0 Linux
  2. GCC (Compiler)

Preparation

At least you have privileges for installing the files later.

Obtain the Materials

A binary and source code can be obtained here. The latest version per June 29th, 2013 is 2.8.11. Both binaries and source codes can be downloaded from here.

As I use Linux I would download source code (http://www.cmake.org/files/v2.8/cmake-2.8.11.1.tar.gz) and unfortunately no binary for Linux x64 so we download this binary (http://www.cmake.org/files/v2.8/cmake-2.8.11.1-Linux-i386.sh). If you want to download for Windows version, go grab source code (http://www.cmake.org/files/v2.8/cmake-2.8.11.1.zip) and binary (http://www.cmake.org/files/v2.8/cmake-2.8.11.1-win32-x86.exe)

Binary Installation

Assuming we download shell archive cmake-2.8.11.1-Linux-i386.sh.

Make sure the file is executable (having +x permission). Do following if you want to set the permission:

chmod +x cmake-2.8.11.1-Linux-i386.sh

Then execute it from terminal

./cmake-2.8.11.1-Linux-i386.sh

Make sure you have privileges to do installation.

Binary installation for Windows system is similar. Just execute the application to initiated installation.

Source Code Compilation & Installation

There are two case for compilation, whether you have CMake or not installed in your system. If you have CMake, we can use CMake to build CMake. However, we can also build it from scratch. Either way we should extract the sourcecode from. A simple way is using command:

tar -xf cmake-2.8.11.1-Linux-i386.tar.gz
cd cmake-2.8.11.1

From Scratch

This case will describe compilation from scratch and suitable for us who either don’t have CMake installed before or just want to compile it from scratch.

We need a compiler and a make utility and running UNIX/Mac OSX/MinGW/MSYS/Cygwin.

Run the bootstrap script in the source directory of CMake. If CMake is going to be installed on particular path, use –prefix. For this example I use /usr/local as my base path.

./bootstrap --prefix=/usr/local
make
make install

Unfortunately for Windows user who didn’t use Cygwin, you can’t do this method. Instead, you should download the binary version of CMake.

Build With CMake

Building CMake with CMake is like building any CMake-based project. Run CMake to the root of cmake directory (e.x: ~/cmake-2.8.11.1).

cd ~/cmake-2.8.11.1
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local .
make
make install

Notice the “.” (dot) in the trail, that’s part of command.

At this point, we have successfully install CMake

Using Extended Filesystem Access Control List

December 9, 2015 | Article | No Comments

Access Control List, or ACL, is a simple security mechanism but most likely implemented on any system. Not to mention, it is also implemented on various filesystem, including ext2, ext3, ext4 and also XFS.

In earlier article, we have discussed about simple permission on UNIX Operating System. In this article we will discuss about using Extended Access Control List on Filesystem for permission. In this article I use:

  1. Slackware64 14.0
  2. XFS

ACL and POSIX

As seen on this article, traditional POSIX file system object permission model defines three classes of users: owner, group, and other. Each of these classes is associated with a set of permission.

The owner class permissions define access privileges to the object (file/folder) owner. The group refers to the owning groups and thus the group permissions defines action can be done by owning group of file. When a user is not either owner or group owner of file, s/he simply referred as other and having other permissions on the file.

The permissions are defined as read, write, and execute an object and denote as r, w, x.

An Extended-ACL consists of a set of entries. The permissions of each file system object have an ACL representation, even in the minimal. On traditional ACL, there are owner, group, and other permissions. One for each class. In Extended ACL, every class might has one or more entries defined. In ACL, default permission entries are calle minimal ACL.

Extended-ACL also contain a mask entry and may contain any number of named. user and named group entries.

So what makes Extended-ACL good?

Extended-ACL can control permission in detail. Using Extended-ACL we can specify what user can do, or what group can do.

Let take an example of this. Let say there are three user: xathrya, marina, and elisa. All of them are on group developer. A file “secret.txt” is created and owned by xathrya. Xathrya want to restrict marina from reading the file, while elisa is restricted to writing the file. Then there is no restriction for marina to write file and elisa to read the file. Using file permission, xathrya can set the permission to 760 so only him can alter the file. But as a fellow group member, marina and elisa can also alter the file. If xathrya alter the file permission to 740, elisa is restricted from writing the file but marina is not restricted to reading. If xathrya use 720, the other condition applies.

Using Extended-ACL, xathrya can precisely set restriction on marina and elise. On account marina, xathrya can put ban for her to read while he can also put ban for elise to write. So that we can have permission -w- specific to marina and r– for elisa. This is the power of Extended-ACL.

The Classes

Generally, Extended-ACL defines six classes of entry, instead of well-known three class as in traditional permission system. They are:

Entry type Text Form
Owner user::rwx
Named user user:name:rwx
Owning group group::rwx
Named group group:name:rwx
Mask mask::rwx
Others other::rwx

As seen there, what is mask? Before we discuss that, let’s get deeper into new class named user and named group.

Named group and named user entries are assigned to the group class, which already contains the owning group entry. Different from the traditional permission model, the group class may now contain ACL entries with different permission sets, so the group class permissions alone are no longer sufficient to represent all the detailed permissions of all ACL entries it contains.

Well, let say that on earlier model, all group user are bound together using group permission. So one permission will be applied to all of group member. However in Extended-ACL, user is not bounded in that manner.

Therefore, the meaning of the group class permissions is redefined: under their new semantics, they represent an upper bound of the permissions that any entry in the group class will grant.

This upper bound property ensures that POSIX.1 applications that are unaware of ACLs will not suddenly and unexpectedly start to grant additional permissions once ACLs are supported.

In minimal ACLs (traditional), the group class permissions are identical to the owning group permissions. In Extended-ACLs, the group class may contain entries for additional users or groups. This results in a problem: some of these additional entries may contain permissions that are not contained in the owning group entry, so the owning group entry permissions may differ from the group class permissions.

This problem is solved by the virtue of the mask entry. With minimal ACLs, the group class permissions map to the owning group entry permissions. With Extended-ACLs, the group class permissions map to the mask entry permissions, whereas the owning group entry still defines the owning group permissions. The mapping of the group class permissions is no longer constant.

Dive into Extended-ACL

On default, for every file creation a standard traditional permission model is used to “stamp” files. We can set Extended-ACL later.

Now, let’s start by cerating a directory and checking its permission. The umask determines which permissions will be masked off then the directory is created. A umask 027 disables write access for the owning group; and read,write,execute access for others.

$ umask 027
$ mkdir dir
$ ls -dl dir
drwxr-x--- ... xathrya users ... dir

The string “rwxr-x--” represents the resulting permissions for the new directory: read, write, and execute access for the owner and read and execute access for the owning group. The dots in the output of ls stand for text that is not relevant here and has been removed.

These base permissions have an equivalent representation as an ACL. ACLs are displayed using the getfacl command.

$ getfacl dir
# file: dir
# owner: xathrya
# group: users
user::rwx
group::r-x
other::---

The first three lines of output contain the file name, owner, and owning group of the file as comments. Each of the following lines contains an ACL entry for one of the three classes of users: owner, group, and other. And that is a traditional permission model.

Now we will grants read, write access to user Marina in addition to the existing permissions. For that, the -m (modify) argument of setfacl is used. The resulting ACL is again shown using the getfacl command. The -omit-header option to getfacl suppresses the three-line comment header containing the file name, owner, and owning group to shorten the examples shown.

$ setfacl -m user:marina:rw dir
$ getfacl --omit-header dir
user::rwx
user:marina:rw
group::r-x
mask::rwx
other::---

Two additional entries have been added to the ACL: one is for user Marina and the other is the mask entry. The mask entry is automatically created when needed but not provided. Its permissions are set to the union of the permissions of all entries that are in the group class, so the mask entry does not mask any permissions.

Now, to grant only read permission to Elisa, we can also do:

$ setfacl -m user:elisa:r-- dir
$ getfacl --omit-header dir
user::rwx
user:marina:rwx
user:elisa:r--
group::r-x
mask::rwx
other::---

Now, let see what these commands (one line per command) will do:

setfacl -d -m group:developer:r-x tools
setfacl -m user:root:--- supersecret.txt
setfacl -m user:marina:r-- file.txt

Now, how to remove an ACL entry from a file? There is a simple command to do so. For example, we want to lift ban from Marina on file.txt then we invoke following:

setfacl -x user:marina file.txt

Yes, as simple as that 😀

File Transfer using Rsync

December 9, 2015 | Article | No Comments

Rsync, old but still powerful tools for moving files between hosts. The main use is to keep file trees synchronized. Rsync have been used for long time since its inception. And it seems Rsync is still used this day.

Rsync is available in many platform, especially UNIX-like system. As the title said, we will discuss about Rsync and not nailed to specific Operating System. In this article we are not discussing about how to install rsync so I assume we already have rsync installed on local machine.

We also not covering about how to prepare rsync server. It will be discussed in another article.

Rsync Overview

Rsync syntax in general would be:

rsync [OPTION] SRC DST

Where SRC is the source address and DST is the destination.

In general, we can use rsync for some purposes:

    1. Copying local files.
    2. Copying from local machine to remote machine.
    3. Copying from remote machine to local machine.

Synchronize local directory and remote rsync server.

On next sections, we will discuss each way described above. But our topic will be focused to point (2) to (4). Well, why would we use rsync to copying local files instead of using cp command?

It is also recommended to used rsync over ssh. Rsync does not provide any security while transferring data therefore we need to tunnel it with secure remote connection.

Now, some arguments or command options we will used in this article:

  • –delete: delete files that don’t exists on sender (system)
  • -v: verbose, use -vv for more detailed information
  • -e “ssh options”: specify ssh as remote shell. The “options” will then passed to ssh when creating a connection
  • -a: archive mode
  • -r: recurse into directories
  • -z: compress file data. Might consume memory and cpu resource but helpful for low bandwidth.

Copying from Local Machine to Remote Machine

Also known as push / upload file(s) into remote machine. Suppose we want to copy /var/www/backup.tgz to a remote server called backup.celestial-links.net on home directory, we could use:

rsync -v -e ssh /var/www/backup.tgz [email protected]:~

You will then be prompted by a password authentication message.

Copying from Remote Machine to Local Machine

Also known as pull / download file(s) from remote machine. Suppose we want to copy /usr/bin/secretbackdoor from remote server machine.celestial-being.net to local storage /tmp:

rsync -v -e ssh [email protected]:/usr/bin/secretbackdoor /tmp/

Synchronizing Local Directory and Remote RSync Server

Well, this is the main purpose of rsync (guess where rsync name comes from). Here the methods are two way connection, it means both machine will synchronizing their content.

rsync -r -a -v --delete rsync://rsync.celestial-links.net/somedir/ /local/somedir/

Or you can swap the src and destination, its same

rsync -r -a -v /local/somedir rsync://rsync.celestial-links.net/somedir

Note that this method use pure rsync which means we are not using it on top of ssh protoocl.

If you want to only synchronize a local directory according to remote directory:

rsync -r -a -v -e "ssh -l xathrya" --delete /local/somedir backup.celestial-links.net:/somedir

Or you want to only synchronize a remote directory according to our local directory:

rsync -r -a -v -e "ssh -l xathrya" --delete backup.celestial-links.net:/somedir /local/somedir

Transfer from One Remote Machine to Other Remote Machine

Suppose we have two remote servers: A and B. In this section we will use rsync to move a file from A to B without transit to our machine. It means file on A is directly copied to B.

rsync -zavrR --delete --links usernameA:[email protected]:/path/to/resource \
usernameB:[email protected]:/path/to/resource

Mounting and Unmounting ISO file

December 5, 2015 | Article | No Comments

ISO files, is a CD/DVD image file. This means, on that single CD/DVD stored files and use structure like real CD/DVD does. Well, it sounds complicated but you could say that you have copy all CD/DVD contents and pack it into a single file.

In Linux, mounting and unmounting an ISO file is so easy and doesn’t need any 3rd party tools.

In this article we will discuss about how to mounting ISO file and unmounting it. For this article I use Slackware64 14.0, but we can do the trick here for any linux distribution.

Preparation

To do mounting and unmounting, you should have superuser or root privileges. You can either login to root account, or either use sudo tool. I assume you have root privileges.

Now create a directory. This directory will be a directory where we will mount our ISO file. Simply we say, we can access the content of ISO file by accessing this directory.

mkdir /mnt/cd-dvd

On this article I assume we want to mount simple.iso. The simple.iso is located on /home/xathrya/

Mounting

To mount / attach an ISO file to /mnt/cd-dvd we use mount tool and specifying some arguments:

mount -o loop -t iso9660 /home/xathrya/simple.iso /mnt/cd-dvd

Unmounting

To unmount / deattach ISO file from /mnt/cd-dvd we use umount tool.

umount /mnt/cd-dvd

In computer science especially in Unix world, a shell is a software that provides an interface for users to access kernel services. The name shell originates from shells being an outer layer of interface between user and the internals of operating system (kernel). Some shell we might know are: bash, csh, tcsh, sh, etc.

In this article, I will show you how to build a simple shell. Our shell can execute command which is inputted by user. But before that, we will cover some basic knowledge about how things going on.

How can our shell execute a command? The answer lies on the capability of exec() function family. Exec will execute command given by them and passing arguments if any. As I said exec() family functions, the actual function we can use are: execl(), execlp(), execle(), execv(), execvp().

How to distinguish between these function?

The suffix ‘l’ (el) means exec commands expect a null-terminated list (hence the “l” for list) of arguments, so to execute “/bin/ls/ -l /” we will call

execl("/bin/ls", "-l" , "/" , (char*) 0);

The suffix ‘v’ (vi) means exec commands expect an array or vector (hence the “v” for vector) of arguments. Here is the snippet for doing same thing as previous:

char *vec[4];

vec[0]="ls";
vec[1]="-l";
vec[2]="/";
vec[3]=(char *)0;
execv("/bin/ls", vec);

The suffix ‘e’ take an additional argument which is an array of char containing the environment (hence the ‘e’ for environment) to be passed to the exec-ed command. Both le and and ve expect an array.

The suffix ‘p’ search the PATH for the command named in their first argument. The one without p don’t.

To use them we should include <unistd.h> header.

In this article we will use execvp() to execute our command.

Now to do exec() thing, we will need help from fork(). What is fork? In computer science, a process do fork will creates a copy of itself. Under Unix OS, the parent and the child process can tell each other apart by examining the return value of the fork() system call. In the child process, the return value of fork() is 0 while the parent side has PID of newly created child process as return value.

Why we should create a fork? First, when exec has finish executing command, it would be exited by default. Our shell must remain running even after the command finished unless we are ordered to exit. Second, having ability to “background”-ing a process executed. You would noticed that when we enter a command in shell like bash and end it with &, our newly executed command would run independently while the shell itself is ready to receive new command.

Here is the complete source code for our shell:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

const int BUFFER_SIZE = 1<<16;
const int ARR_SIZE = 1 << 16;
/* parse arguments and creating a vector of argument */
void parse_args(char* buffer, char** args, size_t args_size, size_t *nargs);

/* SIGNAL HANDLER */
/* handler for SIGCHLD */
void child_handler(int);

/* handler for SIGINT */
void interrupt_handler(int);

int child_count = 0;

int main(int argc, char* argv[]) {
   char buffer[BUFFER_SIZE];
   char* args[ARR_SIZE];
   int ret_status;
   size_t nargs;
   pid_t pid;
   int background;
   signal(SIGCHLD, &child_handler);
   signal(SIGINT, &interrupt_handler);
   while(1) {
      background = 0;
      printf("$> ");
      fgets(buffer, BUFFER_SIZE, stdin);
      parse_args(buffer, args, ARR_SIZE, &nargs);
      if(nargs==0) continue;
      if(!strcmp(args[0],"exit")) {
         printf("Session terminated\n");
         exit(0);
      }
      if( !strcmp(args[nargs-1], "&") ) {
         background = 1;
         args[nargs-1] = NULL;
         nargs--;
      }
      child_count += 1;
      pid = fork();
      if(pid > 0) {
      /* PARENT */
      if( !background ) {
         pid = wait(&ret_status);
         printf("Child (%d) finished\n", pid);
      } else {
         printf("[ ] %d\n", pid);
      }
   } else if(pid == 0) {
      /* CHILD */
      if( execvp(args[0], args) ) {
         puts(strerror(errno));
         exit(127);
      }
   } else {
      printf("Error: Can not fork\n");
      exit(1);
      }
   }
   return 0;
}

void parse_args(char* buffer, char** args, size_t args_size, size_t *nargs) {
   if( strlen(buffer) > 0 ) {
      char *buf_args[args_size];
      char **cp;
      char *wbuf;
      size_t i,j;
      wbuf=buffer;
      buf_args[0] = buffer;
      args[0] = buffer;
      for(cp=buf_args; (*cp=strsep(&wbuf," \n\t")) != NULL;) {
         if((*cp != '\0') && (++cp >= &buf_args[args_size]))
         break;
      }
      for(j=i=0; buf_args[i] != NULL; i++) {
         if(strlen(buf_args[i]) > 0)
         args[j++]=buf_args[i];
      }
      *nargs=j;
      args[j]=NULL;
   } else {
      *nargs = 0;
   }
}

/* handler for SIGCHLD */
void child_handler(int sig_type) {
   int child_status;
   pid_t child;
   /* Getting exit status from child */
   child = waitpid(0, &child_status, 0);
}

/* handler for SIGINT */
void interrupt_handler(int sig_type) {
   printf("\n%d child(s) has been spawned successfully. Session terminated\n", child_count);
   exit(0);
}

Any comment or question is welcomed.

Social media & sharing icons powered by UltimatelySocial