Archive

Archive for the ‘Programming’ Category

Reading logs with a Named Pipe

November 22, 2012 Leave a comment

Recently I had to write a piece of code that constantly would read a log file and if something wrong had happened a specific action should be taken.
For this reason I wrote this piece of code in Lua using Named Pipes.
If you are not familiar with Named Pipes check them out (from Wikepedia: A named pipe is system-persistent and exists beyond the life of the process and must be deleted once it is no longer being used.).

LOG_FILE = "/path/to/the/log/file"
LOG_PIPE = "/path/to/the/log_pipe"
LOG_STR  = "A word/phrase that we are searching for on the logs"

--- Create the logs pipe
function create_log_pipe()
    print("Creating the Logs' pipe...")

    local cmd_status = os.execute("rm -f " .. LOG_PIPE .. ";" ..
        "mkfifo " .. LOG_PIPE .. ";" ..
        "tail -n1 -f " .. LOG_FILE .." > " ..LOG_PIPE .. "&")

    if cmd_status == nil then
        print("[Error] Couldn't create the Logs' Pipe")
        exit
    else
        print("Logs' pipe was created")
    end
end

--- Open the logs' pipe
-- @return the logs' pipe descriptor
function open_log_pipe()
    print("Opening the Logs' pipe...")

    local logfd, _, _ = io.open(LOG_PIPE, "r")

    if not logfd then
        print("[Error] Couldn't open the Logs' pipe.")
        exit
    else
        print("Logs' pipe has opened successfully.")
    end

    return logfd
end

create_log_pipe()
log_pipe = open_log_pipe()

for line in log_pipe:lines() do
    repeat
        if string.find(line, LOG_STR) ~= nil then
            -- do something
        end
    until true
end

Credits on this thread.

Advertisements
Categories: Lua, Programming Tags: ,

Two 16bit integers that represent one 32bit float

April 24, 2012 3 comments

Recently I came across the following problem…

There was a function that could read from some device’s registers and return their values as uint16_t. The problem was that each two 16bit registers in sequence (reg[0] and reg[1], reg[2] and reg[3], etc) were storing a 32bit float number (in little endian).

The first thing that came into my mind was to concatenate the data

integer_32 = ((integer_16_2 & 0xFFFF) << 16) | (integer_16_1 & 0xFFFF)

and produce a 32bit integer. Then this 32bit integer would be casted to a float.

Nevertheless, this is not correct because the bits of the registers were representing a float and not an integer. So if we produced lets say the integer_32 “3” the float that would be generated would be “3.0” and not the float that is represented by the binary “11”.

The solution to this problem was the following:

#include <string.h>

/**
 * Reform two 16bit unsigned integers that store one 32bit
 * signed float (little endian).
 * @param u1 the first 16bit unsigned
 * @param u2 the second 16bit unsigned
 * return the 32bit float
 */
float reform_uint16_2_float32(uint16_t u1, uint16_t u2)
{
    long int num = ((u2 & 0xFFFF) << 16) | (u1 & 0xFFFF);
    float numf;
    memcpy(&numf, &num, 4);
    return numf;
}
Categories: Programming Tags:

Pexpect module for Python 2.5

May 23, 2010 Leave a comment

Today I was searching for a way to run a bash command, that needed superuser’s permissions, from a python program that I had made… The problem was that I had to find a way to interact with the bash and when I would be asked for the password, the python program would answer with it.

So after some googling I found that awesome module called Pexpect , tested in Python 2.5, that allows to your python program to control and automate other programs.

As mentioned in its official site, Pexpect is basically a pattern matching system. It runs programs and watches output. When output matches a given pattern Pexpect can respond as if a human were typing responses. So it is very useful to automate some procedures, and others like testing and screen scraping. Also Pexpect is pure Python so it works on any platform that supports the standard Python pty module.

But enough with that!
Here is the code that I was talking about:

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Author         : Aravanis Konstantinos
# Author's url   : http://AravanisKostas.com
# Author's email : kos.arav@gmail.com
#
# Tested in Python 2.5.5!

import pexpect
import getpass

class suError(Exception):
    """ A new exception. It is used from the su function, if there is a
        problem.
    """
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value)

def su(command, password = None, prompt = "Enter SuperUser Password: ",\
        attempts = None):
    """ Function that ran a command with superuser's permissions.

        @command  : the command that must be ran with superuser's permissions
        @password : the superuser's password.
        @prompt   : the message that will be printed to inform that will ask
                    for the password, if it wasn't set.
        @attempts : the number of attempts. If it is not set then the program
                    will attempt for ever to gain the superuser's permissions.
                    If the attempts were set to zero, the program will still
                    run for a time.
    """
    # decrease the number of the remaining attempts
    if attempts:
        attempts = attempts - 1

    # if the password hadn't been given then ask for it (from the
    # command line)
    if not password:
        password = getpass.getpass(prompt)

    # the command must be ran with superuser's permissions
    child = pexpect.spawn('su -c "' + command + '"')

    # when the password is asked, send it
    choice = child.expect(['Password:'])
    child.sendline(password)

    # check to see if there was an Authentication failure or else that
    # there was no problem
    choice = child.expect(['su: Authentication failure' ,pexpect.EOF])

    # if there was an Authentication failure, ask again for the password
    if choice == 0:
        # if the max number of attempts was reached
        if attempts < 1:
            raise suError("Too Many Attempts!")

        su(command, attempts = attempts)

    # return success
    return True

And if you want to test it:

############
# test it! #
############
try:
    su("echo su_test_text > su_test_file", attempts = 3)
except suError:
    print "No other attempts left!"