PHP script to fetch Domain Name Server information for .uk domain

What Is a Domain Name Server (DNS)?

DNS is a technology to map the names of sites with the server’s IP address. DNS is used to point domain name to server IP address.

WHOIS lookup is an internet utility that helps us to find information about a particular domain or IP address. Typically a record will contain the name and the contact information of the Registrant and the Registrar.

Let us discuss the method to get information about .uk domains:

Step 1. Assign SLD (Second Level Domain) & TLD (Top Level Domain) of domain to the php variables.

$tld = “nic.uk”;
$sld = “whois”;
$end = substr ($tld, 0 – 2); // to get last two characters of domain tld

      Step 2. Connect to the whois server using socket connection.

$whois_server = ‘whois.nic.uk’; // who is server
$fp = fsockopen ($whois_server, 43, &$err_no, &$err_str, 10); // open socket fputs ($fp, $sld.’.’.$tld); // put sld & tld data

        Step 3. Read socket data.

while (!feof ($fp)) // read up to last line of file { $buf = fgets ($fp, 128);// read line by line }

          Step 4. Find name server information.

if (ereg (‘Name servers’, $buf))
{
$dns = fgets ($fp, 128); // read data
$dns = str_replace (‘Name Server:’, ”,
$dns); // replace ‘Name Server:’ text with empty string $dns = str_replace (‘Server:’, ”, $dns); // replace ‘Server:’ text with empty string
}

            Step 5. The entire code is as follows:

if (ereg (‘Name servers’, $buf))
{
$dns = fgets ($fp, 128); // read data
$dns = str_replace (‘Name Server:’, ”, $dns); // replace ‘Name Server:’ text with empty string
$dns = str_replace (‘Server:’, ”, $dns); // replace ‘Server:’ text with empty string
}Step 5. The entire code is as follows:$tld = “nic.uk”;
$sld = “whois”;
$str_search = substr ($tld, 0 – 2);
if ($str_search == ‘uk’)
{
$whois_server = ‘whois.nic.uk’;
$fp = fsockopen ($whois_server, 43, &$err_no, &$err_str, 10);
fputs ($fp, $sld.’.’.$tld);
while (!feof ($fp))
{
$buf = fgets ($fp, 128);
if (ereg (‘Name servers’, $buf))
{
$dns = fgets ($fp, 128);
$dns = str_replace (‘Name Server:’, ”, $dns);
$dns = str_replace (‘Server:’, ”, $dns);
$domain_info['ns1'] = trim ($dns); // primary ns$dns = fgets ($fp, 128);
$dns = str_replace (‘Name Server:’, ”, $dns);
$dns = str_replace (‘Server:’, ”, $dns);
$domain_info['ns2'] = trim ($dns);// secondary ns

$dns = fgets ($fp, 128);
$dns = str_replace (‘Name Server:’, ”, $dns);
$dns = str_replace (‘Server:’, ”, $dns);
$domain_info['ns3'] = trim ($dns); // tertiary ns

$dns = fgets ($fp, 128);
$dns = str_replace (‘Name Server:’, ”, $dns);
$dns = str_replace (‘Server:’, ”, $dns);
$domain_info['ns4'] = trim ($dns); // quaternary ns
}
}
}
print_r($domain_info);

Originally posted 2011-11-07 10:39:05.

Posted in PHP | Tagged , , , , | Leave a comment

Creating SEO friendly URL in PHP

Nowadays, without SEO (Search Engine Optimization), there is chance that a website may not get indexed by search spiders or crawlers. Thus, if website is not ranked high enough it will result in poor conversion rate.

Two main advantages of rewriting URLs are:

1. Search Engine Optimization:

Search engines are much more at ease with URLs that don’t contain long query strings. It becomes easy for the search engine to rank the page URL higher this way.

Consider the Dynamic URl below:

http://www.abc.com/cgi-bin/gen.pl?id=4&view=basic

This type of link can cause the search engine to miss the main contents in the URL in terms of SEO  and thus prevent the page from getting the desired rankings. After rewriting, the URL becomes easier to understand and there are many chances of it to get ranked.

The URL is rewritten as:

http://www.abc.com/4/basic.html

With optimized URLs, it becomes easy for the search engines to distinguish folder names and to establish real links to keywords. These can be indexed easily.

2. Increase in usability for web users and in maintainability for webmasters:

A web surfer will find it tough to remember a URL full of parameters, also he would be discouraged by the idea of typing each parameter at a time. Also, there is a possibility of mistyping which would lead to an undesired page. In case of webmaster it is easier for him to maintain records of the clean or optimized URL than that of dynamic URL.

Some Steps to be considered while Rewriting URLs :

  1. 1. Keep the URL short and tidy

Make the site directories and file names short but meaningful. For example /products is better than /p. Find the shortest identifiers that include a general description of the page contents or function.

  1. 2. Avoid punctuation marks in file names

Often designers use names like product_spec_sheet.html or product-spec-sheet.html. The use of underscore is sign of a carelessly designed site structure.

Note: The usage of underscore in the file naming structures is not user friendly. We recommend separation of file names using hyphens (-).

  1. 3. Use lower cases

Use of upper and lower case in URL is troublesome because depending on the web server’s operating system, file names and directories may or may not be case sensitive. For example, http://ww.xyz.com/Products.html and http://www.xyz.com/products.html are two different files on a UNIX system but the same file on a Windows system.

  1. 4. Add easy to guess entry points in URL

Since users guess domain names, it is easy for users – particularly power users – to guess directory paths in URLs.

For example, a user trying to find information about Microsoft Word might type ‘http://www.microsoft.com/word ’ .

Many sites have already begun to create a variety of synonym URLs for sections. For example, to access the careers section of the site, the canonical URL might be http://www.xyz.com/careers. However, adding in URLs like http://www.xyz.com/career, http://www.xyz.com/jobs, or http://www.xyz.com/hr is easy and vastly improves the chances that the user will hit the target.

  1. 5. Avoid exposing technology via directory names

Uses of names associated with server side technology disclose implementation details and discourage permanent URLs. Generalized paths should be used in case of this scenario. For example, instead of /cgi-bin, use a /scripts directory.

Tutorial for rewriting the URLs with the help of PHP, mod rewrite and .htaccess in Apache:

To turn on the module use mod_rewrite in first line in htaccess using the code below:

RewriteEngine On
RewriteRule ^page/([0-9]).html$ /page.php?id=$1

For example: page/([0-9]).html$  will be redirected to /page.php?id=$1

([0-9]).html$ call the number value which is ID in URL.

We can call multiple numbers on this rule as mentioned below:

RewriteRule ^page/([0-9])/([0-9]).html$ /page.php?id=$1&pagenum=$2

We get the two variables:

1. id
2. pagenum

We can call these variables and show the actual page results.

Originally posted 2011-06-30 11:01:50.

Posted in PHP, Programming | Tagged , , , , | Leave a comment

Introduction to Cloud Computing and Service Models

What is cloud computing?

Cloud Computing is a very comprehensive topic to understand and still in its infancy. It can be termed as the next evolution of computing. Cloud computing offers number of benefits to its users.

Depending upon the usage and advantages, there are several definitions of cloud computing. We can define cloud computing in a number of ways some of them are as follows:

1.  Cloud Computing is the use of multiple server computers via a digital network.

2.  Cloud Computing is an internet based computing environment where you pay only for resources that you use.

3.  Cloud computing is a technology which provides “Resource Optimization” where one can adjust the resource allocation by adding and removing resources dynamically to fit the need.

4.  National Institute of Standards and Technology (NIST) defined Cloud Computing as  a model for enabling convenient, on-demand network access to a shared pool of configurable computing resources (e.g., networks, servers, storage, applications, and services) that can be rapidly provisioned and released with minimal management effort or service provider interaction.


cloud computing Introduction to Cloud Computing and Service Models

Key Cloud Characteristics:

• On-demand self-service

• Ubiquitous network access

• Location independent resource pooling

• Rapid elasticity

• Pay per use

There are three service models of Cloud Computing:

1.  Infrastructure as a Service (IaaS)

2.  Platform as a Service (PaaS)

3.  Software as a Service (SaaS)

cloud service models Introduction to Cloud Computing and Service Models

These service models are not new to the IT world, the difference is only that cloud computing combines and integrate these approaches.

Infrastructure as a Service : Primary objective of an organization is to reduce time & money required to  procure, provision, and install new hardware systems. IaaS fulfills this primary objective i.e. equipment is outsourced to support operations. This is a provision model in which service provider is responsible for the housing, running and maintenance of the equipment.

Platform as a Service : PaaS provides computational resources through the platform such as Operating System. PaaS is built upon the principals of Infrastructure as a Service by providing an environment where applications can be built and deployed in a secure, rapid and high quality manner. The business needs Information Technology to rapidly develop, deploy, and maintain new applications to remain competitive and PaaS helps organizations in the same. PaaS eliminates the hardware dependency and capacity concerns. It also provides a simplified deployment model.

Software as a Service : SaaS is the most basic form of cloud computing. It includes implementation of specific business functions, customized business applications, etc. The major benefit of SaaS is that there is no licensing risk involved and neither there is any version compatibility issue. It reduces the hardware cost as well.  You pay for the software and the underlying infrastructure and does not require technical know-how. Typical examples of SaaS application software are ERP, CRM, Google Docs, etc. SaaS ensures lower capital, better cash flow and reduced IT support cost.

Originally posted 2011-10-20 13:45:21.

Posted in Cloud Computing | Tagged , , , , , , , | Leave a comment

Graphical User Interface Testing

GUI testing means testing how the application and user interact with system.

GUI Testing includes how the application handles/responds to keyboard and mouse inputs and how it displays screen text, images, links, buttons, menus, dialog boxes, icons, toolbox,etc.

Consider the following factors while GUI testing:

1. Consistency:
Users expect that if they perform something in a certain way in a program, another will do the same function the same way.
E.g. In notepad Find is accessed by going through search menu or F3.In WordPad it accessed through the edit menu or by CTRL+ F. Such inconsistency frustrate users.

2. Flexibility:
Flexible application provides more options and more ways to accomplish the same task.
Flexibility includes escape from any place or state and facility to skip & go to initial state.

3. Comfortability:
Appropriateness- Application should look and feel proper for what  it’s doing and for whom it is for.
E.g. Financial business application should probably not go crazy with loud and dark colors and sound effects.

4. Error Handling:
Application should warn user before critical operation.

5. Compatibility:
There are different screen sizes and resolutions available. So GUI element’s location may get changed according to screen size hence needs to be tested. We can use emulators or simulators for that.

Check List for GUI testing:

- Closing application should result in confirmation message box.

- All the screens in application should have a help button.

- Tabbing should highlight or focus on the current area.

- Does the general screen background have proper color?

- Does the text have a readable font?

- Is the screen resizable and minimizable?

- All the windows & dialog boxes should have consistent look & feel.

Lastly I would like to conclude that an impressive user interface design is the design that  provides maximum usability to the users of application.

Originally posted 2011-11-04 12:25:46.

Posted in Quality Assurance & Testing | Tagged , , | Leave a comment

How to prevent your application from SQL Injection?

Avoiding auto generated queries is best method to protect your application from SQL injection or you can use parametrized queries or stored procedures.
For example, a login form has two basic form elements, a text box for accepting a user name and a password box for the password.

< form action="test.aspx">
< input type="textbox" name="user_name">
< input type="password" name="password">
< input type="submit">
< /form>

 

Then if we go by the traditional way of coding,

Dim SQLquery As String = "SELECT Count(*) FROM Users WHERE user_name = '" & user_name.text & "' AND Password = '"& password.text &"'"Dim txtCommand As SQLCommand = New SQLCommand(SQLquery, ConnectionString)

Dim thisCount As Integer = txtCommand.ExecuteScalar()

Above code executes the query which is auto generated. After execution it returns count, if it is greater than zero it means information entered by user is present in database else it is an invalid login.

Considering the above code, suppose someone entered the following string into your password text box:

' or '1'='1

Then the new query would be:

Dim SQLquery As String = "SELECT Count(*) FROM Users WHERE user_name = '" & user_name.text & "' AND Password = '' or '1'='1'"

Dim txtCommand As SQLCommand = New SQLCommand(SQLquery, ConnectionString)

Dim thisCount As Integer = txtCommand.ExecuteScalar()
' or '1'='1

Execution of above query will always give positive login and attacker can easily get into your system and may steal the data or change it.

To avoid this kind of attack we will use parametrized query instead of auto generated query, which is demonstrated in the following example:

Dim txtCommand As SQLCommand = New SQLCommand("SELECT Count(*) FROM Users WHERE user_name = @username AND password = @password", ConnectionString)txtCommand.Parameters.Add ("@username", SqlDbType.VarChar).Value = user_name

txtCommand.Parameters.Add (“@password”, SqlDbType.VarChar).Value = password

Dim thisCount As Integer = txtCommand.ExecuteScalar()

By passing parameters you can avoid many types of SQL injection attacks. You can also use stored procedures to protect your application from SQL injection. Stored procedures secure your database by specific account logins, only these accounts are permitted to execute stored procedures. So, hacker gets restricted access to enter SQL queries to execute against your database. Any transaction to your database would have to be done using a stored procedure which you wrote and is in the database itself, which is usually inaccessible to a perimeter network or DMZ.

Following is an example of stored procedure with authentication:

Dim txtCommand As SQLCommand = New SqlCommand ("proc_CheckLogon", ConnectionString)

txtCommand.CommandType = CommandType.StoredProcedure

txtCommand.Parameters.Add (“@use_rname”, SqlDbType.VarChar).Value = user_name

txtCommand.Parameters.Add (“@password”, SqlDbType.VarChar).Value = password

txtCommand.Parameters.Add (“@return”, SqlDbType.Int).Direction = ParameterDirection.ReturnValue

Dim thisCount As Integer = txtCommand.ExecuteScalar()

Finally, ensure you provide very little information to the user when an error does occur. If there is any database error, don’t give the entire error message. Only provide the necessary information to the users.

Originally posted 2012-01-09 13:07:56.

Posted in Database, Security | Tagged , | Leave a comment

Resize linux /tmp partition

We can increase the “/tmp” partition on Linux without reformatting the file system.

Use following steps to re-size tmp partition:

  • Change “count=2” field as per your requirement.
  • Create “/home/tmp-dir” directory in the partition with sufficient available space.
  • Change “/tmp” in last command to original path give in /etc/fstab

dd if=/dev/zero of=/home/tmpDir bs=1024M count=2
mke2fs -j /home/tmpDir
mount -t ext3 -o loop /home/tmpDir /tmp
/home/tmpDir /tmp ext3 defaults,loop 0 0

  • Set permission to 1777 for “/tmp” once it’s created.

Hope this will make your job easy for resizing /tmp partition.

Originally posted 2011-09-12 13:33:42.

Posted in Linux | Tagged , , | Leave a comment

System variables used in Perl

Perl is a powerful, adaptable and dynamic programming language which is compiled each time before running. It was first developed by Larry Wall in late 1980s. Today we will discuss briefly the system variables used in Perl.

The following are system variables used in Perl:

1. $$
This variable returns the process ID of the process that is running the current Perl script. It is very handy where the operations are to be performed using the script’s process ID.

2. $<
This variable returns the user ID of the current process.

3. $>
This variable returns the effective user ID of the current process.

Note: The difference between current and effective user is that effective user is running with the privileges of that user id. Basically the real is the user id of the user and current is the process that started you.

4. $(
This variable holds the real group ID of the current process.

5. $)
This variable holds the effective group ID of the current process.

6. $0(zero)
This variable holds the name of the file the current Perl process is executing.

7. $^X
This variable stores the interpreter path or the binary of Perl that got executed.

8.  $]
This variable is very helpful to get the version number of the perl interpreter. This helps to trace the version compatibility issues that occur with various modules.

9.  $^O
The name of the operating system the Perl code was built on. This is similar to $Config{‘osname’}.

10.  $^T
This variable returns the time at which the script was executed. This time is in seconds since the beginning of 1970.

11.  $^W
Returns the value of the warning switch. It is either TRUE or FALSE. Warnings is a Perl program to control additional Perl warnings. The syntax to enable a warning is to “use warnings” and to disable them is “no warnings”.

12.  %ENV
This special hash variable maintains all the environment variables. Basically environment variables are used to store the information that is used to run the system/computer. One can change the values of these variables but these changes are available within the program. Once the program exits, these changes loose their respective scope. Every Perl process is provided with a copy of these environmental variables.
One can print out all these environment variables using:

foreach (keys(%ENV)) {
print “Key:$_ and its value: $ENV{$_}\n”;
}

13.  %SIG
This is also a special hash variable that can be used to set signal handlers of various signals. This makes signal handling quite easy as one can set a signal handler to a certain value and again reset its value to default.

Similar to %ENV, %SIG can also be printed using:

foreach (keys(%SIG)) {
print “$_”;
}

My system provides the following list of signals:

NUM63,TRAP,NUM42,URG,STOP,NUM39,NUM62,NUM43,USR2,NUM57,NUM56,RTMAX,NUM59,VTALRM,CONT,NUM45,
NUM61,TERM,NUM44,NUM36,NUM32,BUS,NUM40,NUM51,
IOT,STKFLT,NUM41,KILL,QUIT,NUM37,NUM50,
ABRT,NUM48,CLD,NUM35,NUM38,TTOU,IO,TSTP,
PROF,NUM53,NUM58,SEGV,RTMIN,POLL,PIPE,SYS,
NUM46,PWR,CHLD,HUP,FPE,NUM54,XCPU,TTIN,NUM52,
NUM55,XFSZ,NUM33,INT,NUM49,UNUSED,WINCH,USR1,ILL,ALRM,NUM47,NUM60

14.  @INC

This special array is similar to shell’s PATH variable. Although, PATH contains a list of directories that are to be searched for executables, @INC contains a list of directories from which Perl modules and libraries can be loaded.

When we code use()” or require() or do(), Perl searches the list of directories from @INC and searches the requested file in this array. If the file is not present then one has to define it separately.

15.  %INC
This is special hash that is used to store the names of the files and modules that were successfully loaded and compiled for a given Perl script. Before loading and compiling any file or module Perl initially checks for its availability in this special hash and thus if not found loads and compiles it accordingly.

Originally posted 2011-08-25 13:59:59.

Posted in Perl | Tagged , , , | Leave a comment

File-handle or format variables

These are the special variables that are used for file or related operations. These need not be mentioned explicitly as they are initialized on successful file opening. Moreover each file-handle holds its own set of values.

Some File handle or format variables are listed below:

1. $|
2. $%
3. $=
4. $-
5. $~
6. $^
7. $:
8. $^L

1. $|
This variable is basically used for output buffering. This flag determines whether buffering should be performed on programs input/output and on file read/write operations. If value is set to 1 ($| = 1), then buffering is enabled.

2. $%
This variable holds the current page number of the output channel that is being selected.

3. $=
This variable holds the current page length. The default being set to 60. This is measured in number of printable lines. This variable is useful in page formatting operations. If the page length increases than the current size then page formatting is applied.

4. $-
This holds the number of lines left on a given page to be printed. It basically gives the number of blank lines. For every line print its value is internally decremented. One can continuously check its value for a page break.

5. $~
It holds the name of the current report format name. The default is the file-handle name.

6. $^
This variable holds the name at the top of the page format.

7. $:
Holds the set of characters by which a string may be broken to fill continuation fields in a format. The defaults is ‘\n-’ to break on white spaces or hyphens.

8. $^L
Holds a character that is used by a format’s output to request a form feed. Defaults is \f.

Originally posted 2011-10-31 14:16:34.

Posted in Perl | Leave a comment

MySQL storage engines

MySQL supports the following the table types or storage engines:
1. ISAM
2. MyISAM
3. InnoDB
4. BerkeleyDB(BDB)
5. MERGE
6. HEAP

While considering the table types you have to mainly focus on the following factors:
1. Transaction safe
2. Full text and search features

The default table type of MYSQL in MyISAM. This means that if you have created the table without mentioning the table type, then the type of that table will be MyISAM.

ISAM:
This is not a portable storage engine and is removed from MySQL version 5.x. Its functionality is now replaced by the MyISAM. It supports only 4GB size for storage.

MyISAM:
This is the default storage engine for the MYSQL. This is a fast storage engine but this storage engine is not transaction safe. The size of the MyISAM table varies with different operating systems and the data file too varies from system to system. With the table of this type you can allocate the 64 keys and the length of the key is 1024 bytes.

InnoDB:
Apart from MyISAM, the table of the Innodb type is transaction safe and offers row-level locking. Referential integrity is also supported by the InnoDB storage engine. Unlike  MYISAM, the size of the table is depends on the disk space. Drawback of the InnoDB is that it takes more disk space.

BDB:
This storage engine is transaction safe . It supports page level locking but the data file used in this storage engine is not portable.

Merge:
This storage engine is a collection of multiple MyISAM tables in a single table in order to remove the size limitation from the MyISAM storage engine.

Heap:
This is the fastest storage engine as the table of the HEAP storage engine is stored in memory rather than the disk space. Though this can cause data loss in case of power failure or out of memory error. Also the HEAP storage engine does not support the columns that have AUTO-INCREMENT, BLOB and TEXT as data types.

MyISAM:
This is the default storage engine for the MYSQL. This is the fast storage engine but this storage engine is not transaction safe. The size of the MyISAM table varies from operating system to operating system and the data file varies from system to system. With the table of this type you can allocate the 64 keys and the length of the key is 1024 bytes.

InnoDB:
Apart from MyISAM , the table of the Innodb type is transaction safe and offers row-level locking. Referential integrity is also supported by the InnoDB storage engine. Also diferent from the MYISAM the size of the table is depends on the disk space. Similar to MyISAM InnoDB varies from system to system. Drawback of the InnoDB is that it takes more disk space.

BDB:
This storage engine is transaction safe . It supports the page level locking but the data file used in this storage engine are not portable.
Merge:
This storage engine is nothing but the collection of the multiple MyISAM table in single table in order to remove the size limitation from the MyISAM storage engine.

Heap:
This is the fastest storage engine . The reason behind this is that the table of the HEAP storage engine is stored in memory rather than disk space. But this cause the data loss in case of power failure , out of memory error . Also the HEAP storage engine is not supporting the columns haiving AUTO-INCREMENT , BLOB and TEXT as data types.

Originally posted 2011-09-05 16:01:26.

Posted in MySQL | Tagged , , , , | Leave a comment

How to Monitor Resource Utilization of any Network Device

It is very essential to monitor resources like  RAM, CPU Load, Bandwidth etc. to ensure that they are efficiently utilized. To monitor the the resource utilization of any network device such as sever, router, switch, UPS, etc. you can follow the steps mentioned below:

1 : Create a RRD File :
First create a rrd file by using the following rrd command:
rrdtool create $fname  -s 60 DS:total:GAUGE:600:U:U     DS:used:GAUGE:600:U:U RRA:AVERAGE:0.5:1:259200
where,

  • $fname  is the name you want to give to the rrd file.
  • DS:total:GAUGE:600:U:U:GAUGE:600:U:U is for variable declaration, where ‘total’ is the name of the variable and GAUGE is its data-type.
  • RRA:AVERAGE:0.5:1:259200 is the Round Robin Archive.

2 : Update RRD File:  Once RRD file is created you need to update it at the same interval you have specified while file creation.
For example: In our case it is 60 seconds (-s 60). Here -s is for steps,the step of 60 means that database expects new values every 60 seconds. You can define your own step value.

To update  RRD file the command is:
rrdtool update $ram_rrdfile N:$total:$used“.
where $total and $used are the values you get for the variable names total and used we have specified
in file create command respectively.

The RRD File is to be updated at the same interval as defined in the create command.  So the best way to update the file is to set a Cron Job for the same which runs exactly at the same interval you have specified.  Every data get stored with its time stamp so you can easily get the data of any time span.

3 : Create the Graph or Show the data in tabular report as per your requirement:

Now the final step is to make report from the data you have stored in the RRD database. There are
many ways to get the data from RRD database  depending on your need, I have mentioned two ways below:

a ) Create a graph : You can directly create a graph from the data you have stored in RRD File . To plot a graph the command is :

$rrdcommand = “/usr/bin/rrdtool graph – ” .
“–imgformat PNG “.
“–font DEFAULT:7: “.
“–lazy –height=$graph_height –width=$graph_width “.
“–alt-autoscale-max “.
“–color CANVAS#FFFFFF “.
“–lower-limit=0  –slope-mode –vertical-label=’Total’ “.
“–no-legend “.
” DEF:TOTAL=$filename:total:AVERAGE”.
” DEF:USED =$filename:used:AVERAGE”.
” AREA:TOTAL#FF33FF:’Total Resource’ “.
” LINE1:USAGE#0033FF:’Utilized
‘ “;

b ) Get data in XML Format : To show the report in other format you can fetch the RRD database value in XML file by using rrd fetch or rrd dump command and then get the data from that file.
Use 
SNMP, MIB, OID’s to get the resources data.

Originally posted 2012-01-07 13:27:28.

Posted in Knowledgebase | Tagged , , | Leave a comment