Friday, December 19, 2008

Raw Printing in Linux

Raw printing in Linux is achieved by issuing the command and piping the result to /dev/lp0. For example:

# ls -l > /dev/lp0

Raw printing is useful if you want to take advantage of fast printing using the default fonts of the printer. More often, this is useful if you will be printing under a dot matrix printer.

Furthermore, you can also issue printer codes to the printer to make condensed printing as follows:

# echo -ne '\033\017' >> /dev/lp0

The printer code "\033\017" is an octal equivalent for condensed printing under an Epson-like dot matrix printers. Commonly, the following codes may also be used:

\033\115 for elite and \033\120 for pica

If you are using a different dot matrix printer, the printer codes are found in your printer manual.

Solution to PostgreSQL Serial Limitations

In PostgreSQL, an automatic incrementing column is called "serial". This is often used as a primary key of a table. The default serial column is of type INT4 which has a maximum value of 2,147,483,647. To increase this maximum number, create an INT8 data type for your serial column, as follows:

>CREATE SEQUENCE person_id_seq;
>CREATE TABLE person( id INT8 NOT NULL DEFAULT nextval('person_id_seq'), name TEXT);
>CREATE UNIQUE INDEX person_id_key on person(id);

This will increase the capacity of the column to 9,223,372,036,854,775,807. I don't know if there is an INT16 column type. If there is, theoretically we can increase further the capacity of the column by a factor of 2 since PostgreSQL does not support unsigned integers as far as I know.

Solution to MySQL auto_increment Limitations

By default, MySQL's auto_increment column has a maximum number of 2,147,483,647. In practice, this number may even be less since the next NULL insert to the table will use the next value of the highest insert number. Consequently, once you have reached the maximum number, the next null insert will cause an error because of the occurrence of a duplicate key.

The solution to MySQL's auto_increment limitations is to create a primary key as an UNSIGNED BIGINT(20) type. As an example for the table "mytest", issue the following MySQL command:

>CREATE TABLE mytest(p_id BIGINT(20) UNSIGNED PRIMARY KEY AUTO_INCREMENT, name CHAR(10) );

The UNSIGNED BIGINT(20) type has a maximum number of 18,446,744,073,709,551,616. A SIGNED BIGINT(20) type has a maximum number of 9,223,372,036,854,775,807. Since you will be using this as a non-duplicating primary key in your table, most likely you will be using the UNSIGNED BIGINT(20) type since there is no need for storing negative values.

Firewall Script

The following is a sample firewall script on Linux. It also acts as a network address translation (NAT) script that masquerades the IP addresses of the local area network. The script assumes that the local area network is in the 192.168.0.0 network class. Here it is:
# Load Modules
modprobe ip_conntrack
modprobe ip_conntrack_ftp

echo 1 > /proc/sys/net/ipv4/ip_forward

# Flush rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

# Default Deny Policy
iptables -P INPUT DENY
iptables -P OUTPUT DENY
iptables -P FORWARD DENY

# Perform NAT
iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.255.0 -d 0.0.0.0/0.0.0.0 -j MASQUERADE

Thursday, December 18, 2008

Removing Comment Lines and Spaces in a File

How to remove comment lines and spaces on a configuration file in Linux?

To remove comment lines under Linux, issue the following command:

# sed -e '/^#/d' -e '/^$/d' < squid.conf > newsquid.conf

Then, go can backup the original squid.conf file by copying it to say squidconf.bak:

# cp squid.conf squidconf.bak

And finally copying the new squid file to replace the original file as:

# cp newsquid.conf squid.conf

DHCP 3.x Server Configuration

The following is the DHCP 3.x configuration file "dhcpd.conf" on a Linux server:

-- Start of Configuration File --

ddns-update-style interim;
ignore client-updates;

subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.100 192.168.0.200;
option routers 192.168.0.254;
option subnet-mask 255.255.255.0;
option domain-name "portal.ph";
option domain-name-servers 192.168.0.1;
option netbios-name-servers 192.168.0.1;
default-lease-time 21600;
max-lease-time 43200;
}

-- End of Configuration File --

Recovering Lost MySQL Password

The following are the steps on how to recover lost passwords in MySQL.

Steps:

1. Kill the MySQL daemon.

(the command on a RedHat-based system)
# /etc/rc.d/init.d/mysqld stop

2. Run the command:

# safe_mysqld --skip-grant-tables&
(on Fedora Core 5, the command is "mysqld_safe" instead of "safe_mysqld")

3. Go to the CLI.

#mysql
> use mysql
> update user set password=password('test123') where user='root' and host='localhost';
>\quit

4. Stop the MySQL

#mysqladmin -u root -p shutdown

5. Rerun MySQL

# /etc/rc.d/init.d/mysqld start

You can now access your database using the new password 'test123' as follows:

#mysql -u root -ptest123

Tuesday, December 16, 2008

HTTP Proxy Script in Python


The following is an HTTP proxy script written by Suzuki Hisao using the Python programming language. I lifted this post from the original posting at http://mail.python.org/pipermail/python-list/2003-June/210343.html since I may have need for this script in the future. I have tested this script and it works great. Its even better than the one I wrote using the Ruby programming language. Thanks Mr. Suzuki Hisao for sharing this with us.





----------------------------------------------------------------
#!/bin/sh -
"exec" "python" "-O" "$0" "$@"

__doc__ = """Tiny HTTP Proxy.

This module implements GET, HEAD, POST, PUT and DELETE methods
on BaseHTTPServer, and behaves as an HTTP proxy. The CONNECT
method is also implemented experimentally, but has not been
tested yet.

Any help will be greatly appreciated. SUZUKI Hisao
"""

__version__ = "0.2.1"

import BaseHTTPServer, select, socket, SocketServer, urlparse

class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler):
__base = BaseHTTPServer.BaseHTTPRequestHandler
__base_handle = __base.handle

server_version = "TinyHTTPProxy/" + __version__
rbufsize = 0 # self.rfile Be unbuffered

def handle(self):
(ip, port) = self.client_address
if hasattr(self, 'allowed_clients') and ip not in self.allowed_clients:
self.raw_requestline = self.rfile.readline()
if self.parse_request(): self.send_error(403)
else:
self.__base_handle()

def _connect_to(self, netloc, soc):
i = netloc.find(':')
if i >= 0:
host_port = netloc[:i], int(netloc[i+1:])
else:
host_port = netloc, 80
print "\t" "connect to %s:%d" % host_port
try: soc.connect(host_port)
except socket.error, arg:
try: msg = arg[1]
except: msg = arg
self.send_error(404, msg)
return 0
return 1

def do_CONNECT(self):
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
if self._connect_to(self.path, soc):
self.log_request(200)
self.wfile.write(self.protocol_version +
" 200 Connection established\r\n")
self.wfile.write("Proxy-agent: %s\r\n" % self.version_string())
self.wfile.write("\r\n")
self._read_write(soc, 300)
finally:
print "\t" "bye"
soc.close()
self.connection.close()

def do_GET(self):
(scm, netloc, path, params, query, fragment) = urlparse.urlparse(
self.path, 'http')
if scm != 'http' or fragment or not netloc:
self.send_error(400, "bad url %s" % self.path)
return
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
if self._connect_to(netloc, soc):
self.log_request()
soc.send("%s %s %s\r\n" % (
self.command,
urlparse.urlunparse(('', '', path, params, query, '')),
self.request_version))
self.headers['Connection'] = 'close'
del self.headers['Proxy-Connection']
for key_val in self.headers.items():
soc.send("%s: %s\r\n" % key_val)
soc.send("\r\n")
self._read_write(soc)
finally:
print "\t" "bye"
soc.close()
self.connection.close()

def _read_write(self, soc, max_idling=20):
iw = [self.connection, soc]
ow = []
count = 0
while 1:
count += 1
(ins, _, exs) = select.select(iw, ow, iw, 3)
if exs: break
if ins:
for i in ins:
if i is soc:
out = self.connection
else:
out = soc
data = i.recv(8192)
if data:
out.send(data)
count = 0
else:
print "\t" "idle", count
if count == max_idling: break

do_HEAD = do_GET
do_POST = do_GET
do_PUT = do_GET
do_DELETE=do_GET

class ThreadingHTTPServer (SocketServer.ThreadingMixIn,
BaseHTTPServer.HTTPServer): pass

if __name__ == '__main__':
from sys import argv
if argv[1:] and argv[1] in ('-h', '--help'):
print argv[0], "[port [allowed_client_name ...]]"
else:
if argv[2:]:
allowed = []
for name in argv[2:]:
client = socket.gethostbyname(name)
allowed.append(client)
print "Accept: %s (%s)" % (client, name)
ProxyHandler.allowed_clients = allowed
del argv[2:]
else:
print "Any clients will be served..."
BaseHTTPServer.test(ProxyHandler, ThreadingHTTPServer)
----------------------------------------------------------------

Thursday, October 16, 2008

Comparing Costs with Different Time Periods

How do you compare costs with different time periods?

To answer the above question, people who have no background in Economics or Finance will just ignore the difference in the time periods of costs. So the analysis becomes simple, it is a matter of comparing the cost items. The resulting comparison while theoretically is wrong is practical especially under three (3) conditions:

1. The time period involved is too short, say 2 years;
2. The amount is too small, say a few hundred pesos; and
3. The interest rate is too low, say less than 1%.

Whoa! interest rate? What has interest rate got to do with comparing costs? Well, interest rate is the cost differences between the two periods. Say if you got P1.00 now and you place it in a bank for 2 years and your deposit registered P1.20, the P1.00 now can be said to be equal to P1.20 after two years. The differences between now and the future value is the interest rate earned or foregone. Economists refer to this as the "opportunity cost of capital".

In most investments situations, you will be faced with decisions involving costs at difference time periods. So it is best that you know how much is the interest rate. In the above example, the interest rate is 10% per year.

So when comparing costs at different time periods, know the interest rate. Use it as a gauge in deciding which costs are higher or lower. In investment decision-making, if the yield from an investment is say 20% and the interest rate is 10%, then you gain by 10% if you decide to invest. Assuming all other things to be equal.

If however the investment yield is only 5%, and the interest rate is 10%, then the investment is not attractive since you will actually be losing 5% have you decided to put your money in the bank that yields 10%.

In short, faced with an investment decision problem, don't just compare costs without regard to its time period. You may lose money in the process. But if it does not involve much money, then perhaps, it is just practical to compare costs without regard to its time period.

Thursday, October 2, 2008

Page Numbering in OpenOffice

Of late, I have to write a long report. So being an open source enthusiast, I decided to use OpenOffice instead of Microsoft Office. Guess what? Page numbering under OpenOffice is a bit cumbersome. In fact, I have to search the web for answer and it would seem that I am not the only one experiencing the problem. So after some playing around with OpenOffice, I finally was able to do the things I need for a long report. Here it is...

(1) Page Numbering

The procedure is to go "Insert->Footer->Default", then "Insert->Fields->Page Number". If you want your page number to appear in the header, use "Insert->Header->Default", then "Insert->Fields->Page Number".

Quite cumbersome, but still if you are an old hand in using computers, you may eventually figure that out. Here is the more difficult part. How do you insert a page number that does not start with page 1? It took me hours to figure it out. But since, I cannot find a solution also online, I had vowed to post the procedure online. Here it is...

(2) Starting a page number not from the default page 1, say page 20 ...

The procedure is to locate your cursor on the first paragraph where you want the page to start. Then, go "Format->Paragraph" then select the "Text Flow" tab. Under the "Breaks" line, check the "Insert", and check the "With Page Style", then indicate your desired page number under "Page Number".

Very cumbersome. I think, the creators of OpenOffice can make this more intuitive since regularly writers will need this feature. Sigh!

Monday, September 8, 2008

About Me

Hello! My name is Clement Rasul. I am an information and communication technology (ICT) and project management (PM) specialist. My professional interests are: (i) Statistics, (ii) Economics, (iii) Information and Communication Technology, (iv) Project Management, and (v) Management Consultancy.