Tuesday, September 23, 2008

Here are some promotions from Brokerage Firm.

Bonus for first time deposit of up to $200, bonus $75 for being refered by friend, bonus $50 for referring friends. contact us to claim your $75 Bonus after you have signed up to avafx
Broker AvaFx
Site http://www.avafx.com
Leverage 1:200
Minimum Lot size $5,000 (0.5 Lot), lot increment is 0.5 lot
Minimum Deposit $100
Currency Accepted Visa, Web Money, Paypal
Platform ICTS - Win Dealer
Trust Geotrust, Verisign, Paypal verified, Web Money certificate, BVI

Free $25 for 100 posts on the forum and many other promotions, see their promotions

page. Get your 0.8 Pip cash back/rebates if you sign up through us
Broker FXEgypt
Site - Click here to open your CENTS Account at http://fxopen.com
- Click here to open your REAL Account http://fxopen.com
Leverage 1:500
Minimum Lot Size $100 (0.001 Lot) : **on a cents account
Minimum Deposit $1 (Cents account), and $25(Regular account)
Currency Accepted Web Money, Liberty Reserve, CASHU, c-gold, altergold
Platform Meta Trader 4.0
Trust BVI

First deposit bonus (10%) up to $200; $10,000 Forex Contest; Great Affiliation commision, FREE FOREX DEMO-Account CONTEST
contact us, and we will send you the special invitation to claim your free $100 deposit addition bonus!
Broker RetailFX
Site http://www.etoro.com
Leverage 1:400
Minimum Deposit $50
Currency Accepted Credit Cards, Paypal, Wire Transfer.
Platform Custom etoro platform
Trust Verisign verified

Deposit bonus (5%) for deposit using Webmoney (WMZ) with a sum of larger than $500. Get your 1.3 Pip cash back/rebates if you sign up through here!
Broker Masterforex
Site http://masterforex.org
Leverage 1:500
Minimum Lot Size $100 (0.001 Lot) **on their cents account
Minimum Deposit $1
Currency Accepted Wire transfer, webmoney, liberty reserve
Platform MetaTrader platform 4.0
Trust The owner of MasterForex trademark is the company Beaverhead Financial Inc., registered in the Repupblic of Seychelles on the basis of the International Business Companies Act, 1994 (Act 24 of 1994). The company registration number is 028996. Legal address: 306 Victoria House, Victoria, Mahe, Seychells

The Masterforex trade mark is registered in the U.S. Patent and Trademark Office with number 78/886380

Deposit bonus of up to $2,500 if using wire transfer. Get your 0.7 Pip cash back/rebates if you sign up through here!
Broker Lite Forex
Site http://liteforex.org
Leverage 1:500
Minimum Lot Size $100 (0.001 Lot) **on their cents account
Minimum Deposit $1
Currency Accepted Wire transfer, webmoney, liberty reserve, MONEYBOOKER
Platform MetaTrader platform 4.0
Trust LiteForex service mark and www.LiteForex.org web-site are governed by Straighthold Investment Group Inc., registered resident of Seychelles, according to the terms of the International Business Companies Act, 1994 (Act 24 of 1994). The Office : 306 Victoria House Victoria, Mahe, Seychelles; Headquarter : Straighthold Headquarters 95 Griva Dighenis Street, Office 51
3101 Limassol, Cyprus

LiteForex service mark is registered in the United States Patent and Trademark Office under the serial number 78863864 and registration number 3255556

Recieve 10% Addition on your deposit if using LIBERTY RESERVE. a Regulated Broker
Site http://www.finexo.com
Leverage 1:100
Minimum Lot Size $1000 (0.01 Lot)
Minimum Deposit $25
Currency Accepted Wire transfer, Credit Card VISA, Liberty Reserve, MONEYBOOKER, E-Bullion
Platform Web Platform "FOREXTRADER"
Trust Finexo is a whitelabel partner of SaxoBank, a well know brooker firm established in1992. Headquarters in Copenhagen, Denmark. This central office is backed up by operating offices in London, Geneva, Zurich, Singapore, Tokyo and Marbella and a representative office in Beijing. And a A fully licensed and regulated European investment bank.

Saxo Bank A/S
Smakkedalen 2
DK-2820 Gentofte
Phone: (+45) 39 77 40 00
Fax: (+45) 39 77 42 00
Email: info@saxobank.com

Monday, September 22, 2008

Meningkatkan Performa Database MySQL

Langkah berikut bisa digunakan untuk meningkatkan kecepatan akses terhadap database MySQL, terutama jika akses dilakukan dari komputer dengan sistem non Linux.
1. Memperbaiki DNS setting dan memasukkan ip address / nama host client yang mengakses mysql kedalam file /etc/hosts di server mysql.
Proses edit file /etc/hosts ini bisa dilakukan menggunakan webmin ataupun diedit langsung. Berdasarkan ujicoba langsung, tips ini meningkatkan kecepatan koneksi hingga 10X
2. Memperbaiki / meningkatkan setting konfigurasi MySQL pada file my.cnf.
Secara default, setting mysql menggunakan setting normal dengan memori kecil.

# This is for a system with little memory (32M - 64M) where MySQL plays
# an important part, or systems up to 128M where MySQL is used together with
# other programs (such as a web server)
Dengan memori yang ada pada server (misalnya sebesar 1 GB), kemampuan MySQL dapat lebih ditingkatkan dengan menaikkan key_buffer_Size (untuk model tabel MYISAM) dan innodb_buffer_pool_size (untuk tipe table Inno-db) dan table_cache. Jangan lupa, angka yang diisikan adalah angka dalam bentuk umum memory (kelipatan dari 2n), misalnya 128 MB, 256 MB, 512 MB dll.
Dalam beberapa proses instalasi, biasanya ada juga file konfigurasi untuk mysql yang dijalankan pada komputer dengan memori besar. Nama file konfigurasinya : my-large.cnf. Pelajari file konfigurasi tersebut agar bisa diujicoba pada file konfigurasi my.cnf.
Sebelum melakukan perubahan setting, backup terlebih dahulu konfigurasi yang lama, untuk berjaga-jaga jika setting yang baru justru memunculkan masalah. Berdasarkan pengalaman, setting yang tidak tepat-terlalu tinggi misalnya-membuat MySQL tidak bisa dijalankan.
Jangan lupa, perubahan konfigurasi MySQL sebaiknya dilakukan dalam posisi MySQL off sehingga setelah selesai dire-konfigurasi bisa langsung ditest.
3. Meningkatkan kapasitas memori server
Memori yang lebih tinggi akan membuat server leluasa dalam melayani trafik yang tinggi. Jika memori mencukupi, server tidak akan menggunakan memori cadangan dari swap file yang biasanya berimplikasi pada kecepatan akses data.
4. Pada aplikasi, hindari query SELECT yang tidak spesifik seperti SELECT * …
Pastikan memilih kolom yang akan diambil dan sedapat mungkin hindari model Select *
5. Gunakan indeks pada key table yang sering digunakan. Misalnya pada tabel karyawan yang menggunakan NIK (Nomor Induk Karyawan) sebagai primary key, indeks table menggunakan key ini. Jika ada proses query yang sering menggunakan nama field lainnya, buat indeks juga untuk field tersebut.
Referensi :
MySQL Amazing Tips to Improve, Tuning and Increase MySQL Performance

Tuning MySQL Performance

I just stumbled across this interesting mysql tuning script called MySQLTuner. Don’t see this (or any other similar script) as the magical tool that will optimize your mysel server… There is no such thing, because there are so many different applications and each will require its specific database tunings.
Still, mysqltuner can be very useful tool in many cases, like for ex:

it gives a quick overview on your running mysql configuration and some common sense recommendations.
i really liked how it computes the total amount of memory needed for the current configuration (assuming all global buffers will be used and the maximum number of threads being connected).
very simple usage: you just have to download and run it.

wget http://mysqltuner.com/mysqltuner.pl
perl mysqltuner.pl
The output for a server that has most of the parameters on default might look like:

# ./mysqltuner.pl
MySQL High-Performance Tuner - Major Hayden
Bug reports, feature requests, and downloads at mysqltuner.com
Run with ‘–help’ for additional options and output filtering
[OK] Currently running supported MySQL version 5.0.44-log
——– General Statistics ————————————————–
[–] Up for: 15s (15 q [1.000 qps], 8 conn, TX: 20K, RX: 894)
[OK] Maximum possible memory usage: 318.7M (63% of installed RAM)
[OK] Slow queries: 0%
[OK] Highest usage of available connections: 2%
[!!] Key buffer size / total MyISAM indexes: 8.0M/64.8M
[!!] Query cache is disabled
[OK] Temporary tables created on disk: 19%
[!!] Thread cache hit rate: 12%
[OK] Table cache hit rate: 80%
[OK] Open file limit used: 4%
[OK] Table locks acquired immediately: 100%
——– Recommendations —————————————————–
General recommendations:
MySQL started within last 24 hours - recommendations may be inaccurate
Variables to increase:
key_buffer_size (> 64.8M)
query_cache_size (>= 8M)
Variables to decrease:
long_query_time (<= 5)
max_seeks_for_key (<= 100)From its documentation:

Memory Usage: Calculates MySQL memory usage at max load and makes recommendations for increasing or decreasing the MySQL memory footprint. Per-thread and server-wide buffer data is calculated separately for an accurate snapshot of the server’s configuration.
Slow Queries: Reviews the amount of slow queries relative to the total queries. Slow query time limits are also analyzed and recommendations are made.
Connections: Current and historical connection counts are reviewed.
Key Buffer: Takes configuration data and compares it to the actual indexes found in MyISAM tables. Key cache hit rates are calculated and variable adjustments are suggested.
Query Cache: Query cache hit rates and usage percentages are used to make recommendations for the query cache configuration variables.
Sorting & Joins: Per-thread buffers that affect sorts and joins are reviewed along with the statistics from the queries run against the server.
Temporary Tables: Variable recommendations are made to reduce temporary tables that are written to the disk.
Table Cache: Compares total tables opened to the currently open tables. Calculates the table cache hit rate in order to make suggestions.
Open Files: Determines if the server will approach or run into the open file limit set by the operating system or the MySQL server itself.
Table Locks: Finds table locking that forces queries to wait and makes suggestions for reducing locks that require a wait.
Thread Cache: Calculates how many times MySQL must create a new thread to respond to a query.
Aborted Connections: Finds applications that are not closing connections to MySQL properly.
Read/Write Ratios: Calculates the percentage of read and write operations on your MySQL installation.
Check it out as it is definitely an interesting script that will give you a quick look at the configuration of your mysql server and start your journey to optimize your mysql server.

Friday, September 19, 2008

Tutorial for Decode and Encode Base64 or Decode MD5
this link
Decode and Encode Base64

Sunday, September 7, 2008

SIRCAM/Recycled Virus to Clean ?

This is bad, when I check my PC in this morning, my Windows XP invected by SIRCAM/Recycled Virurs, I try to find how clean this dam problem. After I googling, I found some tutorial. And this is the results.

First Tutorial
1. Go to command prompt.
2. Type CD\ in drive C to go the root directory
3. Type DIR /AH and press ENTER key. This will display all hidden files in your drive C
4. If you see a file AUTORUN.INF and a folder Recycled, then your system is infected.
5. Try doing this to your USB drive and check if your USB stick contains the same folder and AUTORUN.INF, if it does then your system is really infected.

To remove it download and install a trial version of Trendmicro and scan your system.

To manually remove it follow the following steps (This is the step I take when i repair my computer without an internet connection. Note you should understand what you’re about to do, you try it at your own risk!)

1. Boot your system in Safemode
2. Go to command prompt, in Drive C do the following commands.
3. Type -> ATTRIB -H -R -S AUTORUN.INF then press enter
4. Type -> DEL AUTORUN.INF then press enter
5. Type -> ATTRIB -H -R -S Recycled then press enter
6. In Windows Explorer in Safemode, remove the folder Recycled in drive C use Shift-Delete to delete the folder.
7. Repeat Step 3 to 6 for all drives of your system including the USB drive.
8. Search for CTFMON.EXE in your system using the Search of Windows found in Start Menu. If you find a file that is not located in C:\WINDOWS\SYSTEM32, delete it immediately. Dont forget to empty the recycle bin afterwards (Usually the virus will copy itself in the Startup folder of the Startmenu. Check if the file is present there and delete it then.)

To disable autorun of drives (i.e. everytime you double-click a drive or cd or usb, it is auto open) follow the following step:

1. Click Start->Run->type REGEDIT.EXE
2. Go to this key from the register HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer
3. Look for the entry NoDriveTypeAutoRun, double click the entry
4. Type a new value : 03ffffff for the NoDriveTypeAutoRun and press ENTER
5. Reboot the system.

Second Tutorial
You can download and run the automatic cleaning tool for SIRCAM or Follow the directions below to manually remove it.

1. First, rename REGEDIT.EXE to REGEDIT.COM. If you want to use the fix tool, there is no need to rename the file
2. Click Start, Run, type REGEDIT and then press Enter.
3. In the left panel, click the (+) left of each of the below:
4. In the right panel, look for and then delete the registry value called Driver32.
5. In the left panel, click the (+) left of each of the below:
6. Click SirCam and then press the Delete key.
7. In the left panel, click the (+) left of each of the below:
8. In the right panel, right-click the (Default) value, then choose Modify.
9. Change “C:\Recycled\SirC32.exe””%1”%* to “%1” %*. In other words, remove “C:\Recycled\SirC32.exe”.

Remove the dropped files:

1. Open an MS-DOS box or Command Prompt
2. Go to the System directory (C:\Windows\System or C:\Winnt\System32).
3. Type ATTRIB -S -H -R SCAM32.EXE to unhide the Trojan file.
4. Type DEL SCAM32.EXE to delete the Trojan file.
5. Go to the Recycled folder (C:\Recycled folder)

Note: Emptying the recycle bin does not effectively delete the dropped Trojan files in the folder. It is suggested that the command prompt be used when deleting the dropped files.

1. Type ATTRIB -S -H -R SIRC32.EXE.
2. Type DEL SIRC32.EXE to delete the Trojan file.

Remove the Worm reference from AUTOEXEC.BAT:

1. Look for the AUTOEXEC.BAT file.
2. Search and remove the string “@win \recycled\Sirc32.exe”

Restore your RUNDLL32.EXE:

1. Search for RUN32.EXE in your WINDOWS folder. If not found, then the worm did not overwrite your RUNDLL32.EXE.
2. If found, delete RUNDLL32.EXE and rename RUN32.EXE to RUNDLL32.EXE.
3. Restart your system

Note: If you found the worm entry in the AUTOEXEC.BAT file or if you found the RUN32.EXE file in the Windows directory, this means that other computers in your network are also infected. For protection, minimize giving full access to your drives and as much as possible DO NOT share your Windows and System folder.

Tuesday, July 8, 2008


This detection is for a worm which spreads by copying itself to network shared drives. It also has the ability to terminate security applications.
When the worm is executed, it creates a copy of itself using the following filenames:
C:\BootEx.exe C:\Log.exe C:\WINDOWS\ErrorReport.exe C:\WINDOWS\MonitorMission.run C:\WINDOWS\MonitorSetup.exe C:\WINDOWS\regedif.exe C:\WINDOWS\SystemMonitor.exe C:\WINDOWS\Win System.exe C:\WINDOWS\windows.exe C:\WINDOWS\WinSystem C:\WINDOWS\WinSystem.exe C:\WINDOWS\WinSystem32.exe C:\WINDOWS\SYSTEM\mscomfig.exe C:\WINDOWS\SYSTEM\msiexece.exe C:\WINDOWS\SYSTEM\rundlI.exe C:\WINDOWS\SYSTEM\WindowsUpadate.exe C:\WINDOWS\SYSTEM\msidlI.exe C:\WINDOWS\SYSTEM\msiexee.exe C:\WINDOWS\SYSTEM\regedif32.exe C:\WINDOWS\SYSTEM\SCCONFIG.exe C:\WINDOWS\SYSTEM\WindowsProtection.exe C:\WINDOWS\SYSTEM\winlocon.exe C:\WINDOWS\SYSTEM\wpa.bdlx D:\BootEx.exe D:\help.exe D:\materi.exe D:\SwapDrive.exe
The following files are also created:
C:\WINDOWS\SYSTEM\oemlogo.bmp C:\WINDOWS\SYSTEM\oeminfo.ini

It also drops a log.txt on the desktop which contains the strings 'no error found'.
The following registry keys are created :
HKEY_CURRENT_USER\Software\KyrentSoft HKEY_CLASSES_ROOT\*\shell\Scan for Virus\Command HKEY_CLASSES_ROOT\.bin "Default" = cfgFile HKEY_CLASSES_ROOT\.cfg "(Default)" = cfgFile HKEY_CLASSES_ROOT\.cvd "(Default)" = cfgFile HKEY_CLASSES_ROOT\.dat "(Default)" = cfgFile HKEY_CLASSES_ROOT\.exed "(Default)" = exedfile HKEY_CLASSES_ROOT\.run "(Default)" = exefile HKEY_CLASSES_ROOT\cfgfile "NeverShowExt" HKEY_CLASSES_ROOT\cfgfile\shell\Open\command "(Default)" = c:\windows\windows.exe HKEY_CLASSES_ROOT\excfile "NeverShowExt" HKEY_CLASSES_ROOT\excfile\DefaultIcon "(Default)" = %SystemRoot%\System32\shell32.dll,3 m 3 2 \ s h e l l 3 2 . d l l , 3 HKEY_CLASSES_ROOT\exedfile\DefaultIcon "(Default)" = C:\windows\windows.exe i n d o w s . e x e HKEY_CLASSES_ROOT\Folder\shell\Scan for Virus\Command "(Default)" = C:\windows\MonitorMission.run HKEY_CLASSES_ROOT\htmlfile "NeverShowExt" HKEY_CLASSES_ROOT\Folder\shell\Search\Command "(Default)" = C:\windows\MonitorMission.run HKEY_CLASSES_ROOT\Word.Document.8 "NeverShowExt" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run " SysMonitor" = C:\windows\WinSystem.exe HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run "explores" = C:\BootEx.exe HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced "Hidden" = 0 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced "HideFileExt" = 1 HKEY_CLASSES_ROOT\Access.Application.9 "(Default)" = %SystemRoot%\System32\shell32.dll,3 m 3 2 \ s h e l l 3 2 . d l l , 3 HKEY_CLASSES_ROOT\dbfile "(Default)" = %SystemRoot%\System32\shell32.dll,3 m 3 2 \ s h e l l 3 2 . d l l , 3 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Hidden\SHOWALL "RegPath" = Software\Microsoft\Windows\CurrentVersions\Explorer\Advanced HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\HideFileExt "RegPath" = Software\Microsoft\Windows\CurrentVersions\Explorer\Advanced
The worm minimises applications which contain the following window titles:
Updatex Updatingx Upgradex p.c.m.a.v system restore kill process Task Manager Warning Confirm Value Delete Confirm Key Delete Edit String process xp Process View Process Control Process Explorer process Patrol hijack raypc
Symptoms -
Presence of the mentioned files. Presence of the mentioned registry entries.
Method of Infection
Method of Infection -
The worm spreads by trying to copy itself to local & mapped drives.
Removal -

Tuesday, June 10, 2008


Before you begin this tutorial, please make sure that your prompt is C:\> If it is not, please do the following:
1. Type: c:
2. Type: cd..
This should place you into the C:\> working directory.
NOTE: DOS is not case sensitive; therefore, a command can be entered in with CAPITAL LETTERS, lower-case letters, or a MiXtuRe of the two.
Hardware and Software Differences
There are two parts to a computer system, the hardware and the software. Hardware refers to the physical components of a computer. An example of hardware components would be the monitor, keyboard and mouse. Software represents the programs which contain a set of instructions written to perform a certain task on the computer.
What is DOS?

DOS stands for Disk Operating System. DOS controls the computer’s hardware and provides an environment for programs to run. This system program must always be present when working with your computer.
Why You Need DOS
There are a variety of reasons why you need DOS. A few of them are listed below to satisfy your curiosity.
1. DOS controls the flow of information between you and the computer (translator).
2. DOS allows you to store information on your computer.
3. DOS allows you to retrieve information stored on your computer.
4. DOS interprets and translates the software you have on your computer.
5. DOS gives you access to all its function (i.e. saving, copying, and printing files).
Set the Date and Time
Most computers on campus have an internal clock that will automatically set the date and time for you when you turn the computer on. However, if your computer does not have this feature or your computer has two floppy drives, you will need to do the following steps to set the date and time.
1. Type the date like this: 1-15-97
2. Press the return key (enter key).
3. Type the time like this: 8:46
4. Press return.
5. Notice that the C:\> prompt will appear.
DOS marks the date and time on everything you do. It is important to periodically check the date and time if you have an internal clock to see if it is correct. If you have a two floppy system, it is important to enter the correct date and time when you turn the computer on.
NOTE: Baynan sets the date and time for you automatically when you Login.
Check the Date and Time
DOS will let you check or change the date and time once it has been set. The procedure to do this is as follows:
1. Type: date and press return.
2. If the correct date is displayed, simply press return. If the date is incorrect, type the correct date and press return.
3. Type: time and press return.
4. If the correct time is displayed, simply press return. If the time is incorrect, type the correct time and press return.
Directory Command
The DIRECTORY command is like a table of contents in a book. This directory will list the following information:
* Filenames
* File extensions
* Size of each file
* Date and time the file was last updated.
1. At the C:\> type: dir and press return.
2. The list of files will scroll up and off the screen.
NOTE: At the end of the listing, there is a line that shows the number of bytes free on the hard drive.
Scroll Through the Directory Listing
When you type the DIR command and press return, the files begin to scroll vertically on your screen. If you have a lot of files it is difficult to read each one. By holding down the Control Key (CTRL) and the letter S at the same time, you are able to freeze the listing to view your files. When you are finished, press the spacebar for the list to continue.
NOTE: You must return to the C:\> before entering your next command.
Pause a Directory Listing
You can add a PAUSE command to your directory command which will allow you to view your directory one screen at a time.
1. Type: dir/p and press return.
2. The screen freezes after it fills the screen with the files that are listed first in the directory.
3. Press the spacebar to continue listing you files.
4. Continue to press the spacebar until you return back to the C:\> prompt.
View a Wide Listing of Files
When you need to quickly view your files, you can add a /W to the directory command. This will display your files into five columns on the screen.
1. Type: dir/w and press return.
2. DOS will list only the name of you file and the file extension on the screen.
NOTE: Use this command when you are not concerned with looking at the file size or the date it was created.
Recall a DOS Command
The F3 function key can be used to recall the last DOS command you typed in. If you would like to retrieve a previously entered command, you can also press the up arrow key continuously until you reach the desired command you were looking for.
NOTE: You can also type out each letter in your last command by using the right arrow key or the right cursor key. After you use the F3 key to recall a command, you can use the backspace key to edit any part of the command or add to your command.
Print a Directory Listing
You can print a list of your files in your directory by instructing DOS to send the information to your printer.
1. Type: dir>prn and press return.
2. The > symbol stands for output. The PRN stands for printer.
NOTE: You can print a wide listing of your files by typing dir/w>prn
Laserjet printers and other sheetfeeder printers will not eject the page after the dir>prn command. You must take the printer off-line and press the form feed button. Remember to press the on-line button when you are done in order to continue using the printer.
Check for a Single File
Instead of using the directory command to look for one particular file, you can type the name of the file after the DIR command at the C:\> prompt.
1. Make sure that you are at your C:\> prompt.
2. Type: dir format.com (filename.extension) and press return.
3. The screen will display a listing of the file or a file not found message.
Check for a Group of Files
The * symbol is referred to as a wildcard and stands for any character or group of characters. This is helpful when you want to list files that start with a particular letter or group.
1. Type: dir c* and press return.
2. All filenames that begin with the letter C will be listed.
3. Press the F3 key.
4. Backspace twice and replace C* with A* and press return.
5. All filenames that begin with the letter A are listed.
List Files with the Same Extensions
You can also use the wildcard character * to look for a group of files with the same extension.
1. Type: dir *.bat and press return.
2. All files with the .bat extension are listed.
3. Press the F3 key.
4. Backspace three times and replace the .bat extension with the .sys extension and press return.
5. All files with the .sys extension should now be listed.
Clear the Screen
When the screen get full of information, you may want to clear it. To do this, type CLS at the C:\> prompt and press return.
Create a File with DOS
1. Type: copy con Quick.ltr and press return.
2. Type this message in the following format:
Sales are up 15%.
Good Job!
3. Press the F6 function key (^Z) and press return.
4. DOS gives you a message that 1 File(s) has been copied.
5. Type: dir q* and press return.
6. Now you can see the list of files beginning with the letter Q.
NOTE: You can also use the COPY command to print a file by typing: copy quick.ltr prn and press return.
Copy a File
You can use the COPY command to copy one file to another.
1. Type: copy quick.ltr quick2.ltr and press return.
2. DOS will tell you one file has been copied.
3. Type: dir q* and press return.
4. You should have two files listed with different names.
NOTE: Filenames cannot be more than eight characters in length. File extensions cannot be more than three characters in length.
Copy a File with a New Extension
You can also use the COPY command to copy the file with a different filename extension.
1. Type: copy quick.ltr quick.bac and press return.
2. Type: dir q* and press return.
3. Three files should be listed.
Type a File with DOS
If you need to check the contents of a particular file or any DOS file, you will need to use the TYPE command.
1. Type: type quick2.ltr and press return.
2. DOS prints the contents of the file.
NOTE: Never use the TYPE command with files that have the .com, .exe, .sys, and .bas extensions. These are program files and will only display junk on the screen.
Rename a File
The RENAME command lets you rename a previous file with a new name.
1. Type: ren quick2.ltr sales.ltr and press return.
2. Type: dir *.ltr and press return.
3. DOS lists only two files that have the .ltr extension: quick.ltr and sales.ltr.
Rename a Group of Files
With the wildcard character *, you can also use the RENAME command to change a group of files.
1. Type: ren *.ltr *.bob and press return.
2. Type: dir *.bob and press return.
3. You should have two files listed with a .bob extension.
4. Type: dir *.ltr and press return.
5. There should be no files found with .ltr extensions.
NOTE: You can also rename a group of files that have the same name but different extensions. Type the RENAME command then the filename followed by the dot and the wildcard, space and then type the new filename followed by a dot and the wildcard character. It will look like this: filename.* newfilename.*
Create a Subdirectory
To create a subdirectory, you will need to use the MAKE DIRECTORY command, a.k.a. MD. The MD command is useful for organizing files on your hard drive. With subdirectories, you can create and store related files together. For example, one subdirectory could be used to store all word processing files and another for all spreadsheet files.
1. Type: md \info and press return.
2. Type: dir *. and press return.
3. Notice the *. will list only the subdirectories.
Move to a Subdirectory
Once you have created a subdirectory, to move to that directory, you will use the CHANGE DIRECTORY command, a.k.a. CD.
1. Type: cd \info and press return.
2. Type: cd and press return.
3. The name of the directory is listed.
Set the DOS Prompt
You can set or change the standard system prompt to display the name of the directory or subdirectory you are currently working in.
1. Type: prompt $p $g and press return.
2. The DOS prompt tells you that you are working in the C directory (drive) and in the Info subdirectory.
3. Type: dir and press return.
4. The single dot stands for the current directory. The double dots stand for the parent directory (root). The dots are often referred to as place markers.
Move to the Parent Directory
DOS has a quick way to move from the current directory back to the parent directory.
1. Type: cd.. and press return.
2. You will return back to the C:\> prompt.
Copy a File into a Subdirectory
The COPY command lets you copy files from one directory to another.
1. Type: copy sales.bob \info and press return.
2. Type: dir \info and press return.
3. Notice that a copy of Sales.bob is copied into the subdirectory Info. The original file is also in the root directory.
Copy a Group of Files into a Subdirectory
When copying a group of files from the root directory into a subdirectory, it is necessary to use the wildcard character * along with the COPY command.
1. Type: copy quick.* \info and press return.
2. DOS will list the files being copied.
3. Type: dir \info and press return.
4. Three files should be listed in the Info subdirectory.
List Files in a Subdirectory
The CHANGE DIRECTORY, a.k.a. CD, command will let you list files in your subdirectory from your hard drive.
1. Type: cd \info and press return.
2. Type: dir and press return.
3. All files in the Info subdirectory are listed.
List Files in the Root from a Subdirectory
The DIRECTORY command is also used to get a listing of all the files in the root directory while in a subdirectory. The backslash character \ represents the root directory.
1. Type: dir \ and press return.
2. All the files in the root directory are listed.
Select the Directory List
To look for a specific filename extension, you can use the SELECTED DIRECTORY command.
1. Type: dir \*.bat and press return.
2. Only the files with the .bat extensions are listed.
3. Press the F3 key.
4. Backspace three times.
5. Type: sys and press return.
6. Now only the files with the .sys extensions are listed.
List Subdirectories
1. Type: dir \*. and press return.
2. All the subdirectories are listed.
NOTE: The backslash character \ directs DOS to read from the root directory. The *. requests the listing of the subdirectories.
Delete a Single File
Periodically it is a good idea to delete files from the hard disk which are no longer needed or used. DOS makes it easy to remove these files with the DELETE command, a.k.a. DEL.
1. Type: cd.. and press return.
2. The prompt shows you that you are back in the root directory.
3. Type: del sales.bob and press return.
4. Type: dir Sales.bob and press return.
5. Sales.bob is no longer listed because it has been deleted.
Delete a Group of Files
By using the wildcard character * you can delete a group of files from you hard Drive.
1. Type: del quick.* and press return.
2. Type: dir quick.* and press return.
3. All Quick files have been deleted.
Delete all Files in a Subdirectory
There are two rules you will need to follow before removing a subdirectory.
RULE 1: All files in the subdirectory must be deleted.
NOTE: Never type DEL *.* when you are in the root directory. It will destroy all DOS files that are necessary to boot and operate the computer.
1. Type: cd \info and press return.
2. Type: dir and press return.
3. Three files should be listed.
4. Type: del *.* and press return.
5. DOS will ask you if you are sure? (Y/N)
6. Type: Y and press enter.
Now that your subdirectory is empty, you can delete the subdirectory (see rule 2 below).
Remove a Subdirectory
RULE 2: You cannot be in the subdirectory that you wish to remove. You will need to return to the root directory (C:\> prompt).
1. Type: cd.. and press return.
2. You should be back in the root directory.
3. Type: rd \info and press return.
4. Type: dir *. and press return.
5. Notice that the Info subdirectory is no longer listed.
Format a Floppy Disk
Before you can use a disk, you must format it.
1. At the C:\> prompt type: format a:
2. The A drive will be the drive that you insert your disk into; hence, the a: after the Format command and press return.
3. You will be prompted with the message: "Insert new diskette for drive A: and press enter when ready."
4. Now insert the disk you wish to format and press return.
5. Once this formatting process is done, the following message will appear: "Format Completed." Then you will be prompted for a volume label. Simply press return again.
6. Now you will be asked if you would like to format another disk (Y/N)? Press N.
NOTE: If you receive a message like: "Track 0 bad" or "Disk unusable," your disk may be the wrong capacity. You can get help with this error message by typing:
Help Format.
Change the Default Drive
To change from your hard drive to a floppy drive, you will need to indicate this change as follows:
1. Put a floppy disk into drive A.
2. Type: a: and press return.
3. Your prompt should change to A:\>
4. Type: dir and press return.
5. You are now able to see all the files on the floppy.
6. To change back to your hard drive, you will need to reverse this procedure.
7. Type: c: and press return. Now your prompt should be C:\>
Diskcopy Command
Sometimes there is a need to copy all the files on one floppy diskette to another floppy. First you will need a blank formatted disk (refer to section on formatting disks.)
1. Type: diskcopy a: a: and press return.
2. When asked to put in the source disk, put in the diskette that has the information you want to copy into drive A and press return.
3. Wait a few seconds. When asked to insert a target disk, take out the diskette from drive A and insert the blank floppy disk and press return.
4. Once this process is complete, you will be prompted to write to another duplicate diskette (Y/N). Press N.
5. Then you will be prompted to copy another disk (Y/N)? Press N.
NOTE: If your machine has two floppy disk drives, insert the original (source) disk into drive A and the blank (target) disk into drive B. Then type: DISKCOPY A: B:
Copying a File from the Hard Drive to a Floppy Disk
Sometimes there is a need to copy a file from the hard drive onto a floppy disk. This is helpful if you would like to have an extra copy of a certain file as a backup or to transport the copied file to another computer.
1. Type: copy a: and press return.
2. Wait for a few seconds, notice the red light on the floppy drive. Never attempt to remove a disk from the disk drive while this red light is on.
3. To check to see if the file was copied, type a: at the C:\> prompt and press return.
4. Type: dir and press return.

Friday, June 6, 2008


Repair Install Printable version
Because of Service Packs, virus, malware, spyware, etc. changes
and warnings will be added.
Read entire article before proceeding with the Repair Install.
It is extremely important that you backup important data that
is not available from other media sources. This backup should be
located on a separate hard drive, CD, DVD, network storage,
etc. that will not be affected by the repair install.

Please check out the warning links before attempting the Repair
It is to your advantage you follow the suggestions to prevent data
loss and especially if you also have the capability to boot into XP,
perform the steps listed in the Warning #1 , before proceeding with
the repair install.
If the capability to boot into Windows XP is still available and the
steps listed in the warning did not help the situation, you can use
an OEM XP Pro or Home, "retail" full version or upgrade CD of the
same version Home or Pro to perform a Repair Install. OEM Restore
disks or folders will not work for the Repair Install.
A Repair Install will replace the system files with the files on the
XP CD used for the Repair Install. It will leave your applications
and settings intact, but Windows updates will need to be reapplied.
A Repair Install will replace files altered by ad ware and malware,
but will not fix an ad ware, malware problem.
You can use the In place upgrade option to change a Product Key in
the event you entered a key that was already activated.
An option I highly recommend is creating a Slipstreamed XP CD with
SP1, SP2, etc..
Slipstreaming Windows XP with Service Pack 2 (SP2) Good
Another Slipstream step by step Better
AutoStreamer mirror link for AutoStreamer Best!!
Step by Step on AutoStreamer
1. Boot the computer using the XP CD. You may need to change the
boot order in the system BIOS. Check your system documentation
for steps to access the BIOS and change the boot order.
2. When you see the "Welcome To Setup" screen, you will see the
options below This portion of the Setup program prepares Microsoft
Windows XP to run on your computer:

To setup Windows XP now, press ENTER.

To repair a Windows XP installation using Recovery Console, press R.

To quit Setup without installing Windows XP, press F3.

3. Press Enter to start the Windows Setup.
do not choose "To repair a Windows XP installation using the
Recovery Console, press R", (you do not want to load Recovery
Console). I repeat, do not choose "To repair a Windows XP
installation using the Recovery Console, press R".
4. Accept the License Agreement and Windows will search for existing
Windows installations.
5. Select the XP installation you want to repair from the list and
press R to start the repair. If Repair is not one of the options,
read Warning #2 below!!
6. Setup will copy the necessary files to the hard drive and reboot.
Do not press any key to boot from CD when the message appears.
Setup will continue as if it were doing a clean install, but your
applications and settings will remain intact.

Blaster worm warning: Do not immediately activate over the internet
when asked, enable the XP firewall
[ http://support.microsoft.com/?kbid=283673 ]
before connecting to the internet. You can activate after the
firewall is enabled. Control Panel - Network Connections. Right click
the connection you use, Properties, and there is a check box on the
Advanced [ http://michaelstevenstech.com/xpfirewall1.jpg ] page.

7. Reapply updates or service packs applied since initial Windows XP
installation. Please note that a Repair Install using an Original
pre service pack 1 or 2 XP CD used as the install media will remove
SP1/SP2 respectively and service packs plus updates isssued after the
service packs will need to be reapplied.

Service Pack 2 link. Copy and paste link into your browser.

An option I highly recommend; is creating a Slipstreamed XP CD with
SP1, SP2, etc. .

Slipstreaming Windows XP with Service Pack 2 (SP2) Good

Another Slipstream step by step Better

AutoStreamer mirror link for AutoStreamer Best!!

Step by Step on AutoStreamer

Warning! #1
Should you do a repair install; and is it the best choice?

A Repair Install is not foolproof, and should not be considered
the cure-all fix for non-boot situations.
To prevent loss of data or program settings, perform the
following before the Repair Install.

Manually delete the Undo_guimode.txt file from the
Windows\System32 folder before you perform any of the actions
that are listed in the "Symptoms" section of this article.
To do this in Windows XP, type the following command at a
command prompt: del /a /f %windir%\system32\undo_guimode.txt

From the Start menu, click Run.
Screenshot Image

In the Run dialog box, in the Open text box, type: cmd. Click OK.
Delete the undo_guimode.txt file. In the C:\Windows\System32\cmd.exe
dialog box, type: del /a /f c:\windows\system32\undo_guimode.txt.
Press the ENTER key.
Screenshot Image
KB Q312369

Check the link below for an option for recovering from a
non-boot event.
Windows XP Crashed? Here's Help
A salvage mission into the depths of Windows XP, explained by a non-geek
by Charlie White

Also as a precaution the windows\system32\WPA.DBL and WPA.BAK
should be copied to a floppy before doing a repair install. For more
information see Alex Nichol's article on XP activation.

More articles to help prevent data loss.


Additional tips to perform before initiating the Repair Install.
You should complete the basic requirements of backing up all files
and folders that cannot be restored from other media. This includes
passwords, applications purchased and downloaded from the internet
without CD support, financial records and folders, digital images
that cannot be replaced...............

Backup copies of your registry files (in the %systemroot%\Repair
folder) are also replaced after the in-place upgrade is complete.
Copy these registry backups to another location before you perform
an in-place upgrade/Repair Install. You may need to use them after
the in-place upgrade is complete.

It would also be a good idea to run the Files And Settings Transfer
wizard F.A.S.T located on the XP CD.

If you made unorthodox registry changes with third party software,
there is the potential of data loss from a Repair Install. Another
consideration of concern would be a power failure during the repair
install could render your system unbootable and result in loss of data.

The likelihood of you losing the files and folders is probably of
minimal risk, but you have to expect the worst and make sure you are
prepared for recovery.

If you are sure you have explored all other troubleshooting avenues,
then proceed with the repair install.

Warning #2!! If the Repair Option is not Available
What should I do? Most important do not ignore the information below!

If the option to Repair Install is NOT available and you continue
with the install; you will delete your Windows folder, Documents and
Settings folders. All Applications that place keys in the registry
will need to be re-installed.

You should exit setup if the repair option is not available and
consider other options. I have found if the Repair option is not
available, XP is usually not repairable and will require a Clean
If you still have the ability to access the Windows XP installation,
backup all important files not restorable from other sources before
attempting any recovery console trouble shooting attempts.

Possible Fix by reconfiguring boot.ini using Recovery Console.
1.Boot with XP CD or 6 floppy boot disk set.
2. Press R to load the Recovery Console.
3. Type bootcfg.
4. This should fix any boot.ini errors causing setup not to see the
XP OS install.
5. Try the repair install.

One more suggestion from MVP Alex Nichol

"Reboot, this time taking the immediate R option, and if the CD
letter is say K: give these commands

COPY K:\i386\ntldr C:\
COPY K:\i386\ntdetect.com C:\

(two other files needed - just in case)

1. Type: ATTRIB -H -R -S C:\boot.ini DEL C:\boot.ini

2. Type: BootCfg /Rebuild

which will get rid of any damaged boot.ini, search the disk for
systems and make a new one. This might even result in a damaged
windows reappearing; but gives another chance of getting at the

Feedback on success or failure of the above fixes would be greatly

Feedback on success or failure of the above fix would be greatly

Warning!! #3
Updates must be applied before connecting to the internet after a
repair install.
Reapply updates or service packs applied since initial Windows XP
installation. Please note that a Repair Install using an Original
pre service pack 1 or 2 XP CD used as the install media will remove
SP1/SP2 respectively and service packs plus updates issued after
the service packs will need to be reapplied.

Windows XP Service Pack 1

Service Pack 2

An option I highly recommend; is creating a Slipstreamed XP CD with SP1, SP2, etc. .

Slipstreaming Windows XP with Service Pack 2 (SP2) Good

Another Slipstream step by step Better

AutoStreamer mirror link for AutoStreamer Best!!

Step by Step on AutoStreamer


Related Microsoft KB Articles

You May Lose Data or Program Settings After Reinstalling, Repairing or Upgrading Windows XP (Q312369)

System Restore "Restore Points" Are Missing or Deleted (Q301224)

How to Perform an In-Place Upgrade (Reinstallation) of Windows XP (Q315341)

Michael Stevens MS-MVP XP

Friday, May 23, 2008

Top 84 MySQL Performance Tips

MySQL is a widely used and fast SQL database server. It is a client/server implementation that consists of a server daemon (mysqld) and many different client programs/libraries.
You can check the same tips from here.Here is very useful tips for all mysql DBA's,Developers these tips are noted from MySQL Camp 2006 suggested by mysql community experts.
Kaj (Most Excellent Obvious Facilitator) Index stuff.
Ronald Don't Index Everything Use benchmarking
Minimize traffic by fetching only what you need.
Paging/chunked data retrieval to limit
Don't use SELECT *
Be wary of lots of small quick queries if a longer query can be more efficient
Use EXPLAIN to profile the query execution plan Use Slow Query Log (always have it on!)
Don't use DISTINCT when you have or could use GROUP BY Use proper data partitions
For Cluster. Start thinking about Cluster *before* you need them Insert performance

Use LOAD DATA instead of INSERT
LIMIT m,n may not be as fast as it sounds
Don't use ORDER BY RAND() if you have > ~2K records
Use SQL_NO_CACHE when you are SELECTing frequently updated data or large sets of data
avoid wildcards at the start of LIKE queries
avoid correlated subqueries and in select and where clause (try to avoid in)
config params --
no calculated comparisons -- isolate indexed columns
innodb_flush_commit=0 can help slave lag
ORDER BY and LIMIT work best with equalities and covered indexes
isolate workloads don't let administrative work interfere with customer performance. (ie backups)
use optimistic locking, not pessimistic locking. try to use shared lock, not exclusive lock. share mode vs. FOR UPDATE
use row-level instead of table-level locking for OLTP workloads
Know your storage engines and what performs best for your needs, know that different ones exist.
use MERGE tables ARCHIVE tables for logs
Optimize for data types, use consistent data types. Use PROCEDURE ANALYSE() to help determine if you need less
separate text/blobs from metadata, don't put text/blobs in results if you don't need them
if you can, compress text/blobs
compress static data
don't back up static data as often
derived tables (subqueries in the FROM clause) can be useful for retrieving BLOBs w/out sorting them. (self-join can speed up a query if 1st part finds the IDs and use it to fetch the rest)
enable and increase the query and buffer caches if appropriate
ALTER TABLE...ORDER BY can take chronological data and re-order it by a different field
InnoDB ALWAYS keeps the primary key as part of each index, so do not make the primary key very large, be careful of redundant columns in an index, and this can make the query faster
Do not duplicate indexes
Utilize different storage engines on master/slave ie, if you need fulltext indexing on a table.
BLACKHOLE engine and replication is much faster than FEDERATED tables for things like logs.
Design sane query schemas. don't be afraid of table joins, often they are faster than denormalization
Don't use boolean flags
Use a clever key and ORDER BY instead of MAX
Keep the database host as clean as possible. Do you really need a windowing system on that server?
Utilize the strengths of the OS
Hire a MySQL (tm) Certified DBA
Know that there are many consulting companies out there that can help, as well as MySQL's Professional Services.
Config variables & tips:
use one of the supplied config files
key_buffer, unix cache (leave some RAM free), per-connection variables, innodb memory variables
be aware of global vs. per-connection variables
be aware of swapping esp. with Linux, "swappiness" (bypass OS filecache for innodb data files, innodb_flush_method=O_DIRECT if possible (this is also OS specific))
defragment tables, rebuild indexes, do table maintenance
If you use innodb_flush_txn_commit=1, use a battery-backed hardware cache write controller
more RAM is good so faster disk speed
use 64-bit architectures
Know when to split a complex query and join smaller ones
Debugging sucks, testing rocks!
Delete small amounts at a time if you can
Archive old data -- don't be a pack-rat! 2 common engines for this are ARCHIVE tables and MERGE tables
use INET_ATON and INET_NTOA for IP addresses, not char or varchar
make it a habit to REVERSE() email addresses, so you can easily search domains
increase myisam_sort_buffer_size to optimize large inserts (this is a per-connection variable)
look up memory tuning parameter for on-insert caching
increase temp table size in a data warehousing environment (default is 32Mb) so it doesn't write to disk (also constrained by max_heap_table_size, default 16Mb)
Normalize first, and denormalize where appropriate.
Databases are not spreadsheets, even though Access really really looks like one. Then again, Access isn't a real database
In 5.1 BOOL/BIT NOT NULL type is 1 bit, in previous versions it's 1 byte.
A NULL data type can take more room to store than NOT NULL
Choose appropriate character sets & collations -- UTF16 will store each character in 2 bytes, whether it needs it or not, latin1 is faster than UTF8.
make similar queries consistent so cache is used
Have good SQL query standards
Don't use deprecated features
Use Triggers wisely
Run in SQL_MODE=STRICT to help identify warnings
Turning OR on multiple index fields (<5.0) into UNION may speed things up (with LIMIT), after 5.0 the index_merge should pick stuff up.
/tmp dir on battery-backed write cache
consider battery-backed RAM for innodb logfiles
use min_rows and max_rows to specify approximate data size so space can be pre-allocated and reference points can be calculated.
as your data grows, indexing may change (cardinality and selectivity change). Structuring may want to change. Make your schema as modular as your code. Make your code able to scale. Plan and embrace change, and get developers to do the same.
pare down cron scripts
create a test environment
try out a few schemas and storage engines in your test environment before picking one.
Use HASH indexing for indexing across columns with similar data prefixes
Use myisam_pack_keys for int data
Don't use COUNT * on Innodb tables for every search, do it a few times and/or summary tables, or if you need it for the total # of rows, use SQL_CALC_FOUND_ROWS and SELECT FOUND_ROWS()
use --safe-updates for client
Redundant data is redundant
Use INSERT ... ON DUPLICATE KEY update (INSERT IGNORE) to avoid having to SELECT
use groupwise maximum instead of subqueries
be able to change your schema without ruining functionality of your code
source control schema and config files
for LVM innodb backups, restore to a different instance of MySQL so Innodb can roll forward
use multi_query if appropriate to reduce round-trips
partition appropriately
partition your database when you have real data
segregate tables/databases that benefit from

Wednesday, May 14, 2008

Calibrate the notebook PC battery

Short discharges and recharges do not fully synchronize the battery's fuel gauge with the battery's state-of-charge. This can result in the amount of power available in one cycle being less than expected or the battery meter being inaccurate.
Under normal usage, batteries should be calibrated a minimum of once every 3 months. Your battery can be calibrated by following these steps:
Step 1 - Disable the Windows Power Management

In Windows, right-click the Desktop and select Properties in the menu list.
Click the Screen Saver tab and then click the Power button.
Under Power schemes, select Always On in the drop down menu.
Under Settings for Always On power scheme, select Never in each of the drop down menus.
Click OK on the Power Options Properties window and then click OK on the Display Properties window.
Step 2 - Fully charge the battery
Connect the AC adapter to the notebook.
Charge the battery until the Windows battery meter is at 100%.
Step 3 - Fully discharge the battery
Remove the AC adapter.
Keep the notebook on until the battery has completely drained and the notebook automatically turns off.
Connect the AC adapter to the notebook.
Keep the AC adapter connected to the notebook until the battery has completely charged.
Step 4 - Enable the Windows Power Management
In Windows, right-click the Desktop and select Properties in the menu list.
Click the Screen Saver tab and then click the Power button.
Under Power schemes, select Portable/Laptop in the drop down menu.
Click OK on the Power Options Properties window and then click OK on the Display Properties window.
Note: After completing the steps above, your notebook PC battery will be calibrated.

Monday, May 12, 2008

Solution to MySQL Replication Problems: Master DB crashed

It is commons that replication will hang after master database crashed. And the error message you will get when you show slave status is:
Client requested master to start replication from impossible position (server_errno=1236)
This happened because MySQL write to bin-log in batch basis. If every bit of your data is mission critical and any inconsistent between master and salve is not accectable, then you should redo you replication all over again.
So far I do not found any way to prevent this replication failure. However, you may add the follwing line into you my.cnf to reduce the chances it happen:
This means that MySQL will write to bin-log after each update instead of write in batch. As you may expect, this will reduce the performance of the database.
Else, there is another way to resume the replication. The solution is illustrate in this article: Client asks master to start replication from impossible position

I get this question a lot. Why does a slave report that it's trying to replicate from an impossible position? 9 times out of 10 it's because the master crashed and when it came back online a new binlog file was made.
mySQL caches binlog events in the binlog cache, basically events are stored in memory and flushed to disk when the dirty buffer fills up. I believe the variable is called binlog_cache_size.
Here are some steps to recover from this:
Go onto the master execute
Look at the output and find the log that the slave is pointing to. Look at the File size field.
Next look at the slave output from the slave reporting the issue. Look at Exec_Master_Log_Pos, is that value greater then the File Size on the master if so issue
slave start;
Now if your super sensitive of lost events because a row or two could of been lost from this replication event, do some spot testing for tables written to often. Look for anything that has changed within the outage window, if the data doesn't match the slave then you're master and slave are out of sync, and will require a full clone to get the data back in sync.

Saturday, May 10, 2008

Perl Basic Program PART II

String matching
One of the most useful features of Perl (if not the most useful feature) is its powerful string manipulation facilities. At the heart of this is the regular expression (RE) which is shared by many other UNIX utilities.
Regular expressions
A regular expression is contained in slashes, and matching occurs with the =~ operator. The following expression is true if the string the appears in variable $sentence.
$sentence =~ /the/
The RE is case sensitive, so if
$sentence = "The quick brown fox";
then the above match will be false. The operator !~ is used for spotting a non-match. In the above example

$sentence !~ /the/
is true because the string the does not appear in $sentence.
The $_ special variable
We could use a conditional as
if ($sentence =~ /under/)
print "We're talking about rugby\n";
which would print out a message if we had either of the following
$sentence = "Up and under";
$sentence = "Best winkles in Sunderland";
But it's often much easier if we assign the sentence to the special variable $_ which is of course a scalar. If we do this then we can avoid using the match and non-match operators and the above can be written simply as
if (/under/)
print "We're talking about rugby\n";
The $_ variable is the default for many Perl operations and tends to be used very heavily.
More on REs
In an RE there are plenty of special characters, and it is these that both give them their power and make them appear very complicated. It's best to build up your use of REs slowly; their creation can be something of an art form.
Here are some special RE characters and their meaning

. # Any single character except a newline
^ # The beginning of the line or string
$ # The end of the line or string
* # Zero or more of the last character
+ # One or more of the last character
? # Zero or one of the last character

and here are some example matches. Remember that should be enclosed in /.../ slashes to be used.
t.e # t followed by anthing followed by e
# This will match the
# tre
# tle
# but not te
# tale
^f # f at the beginning of a line
^ftp # ftp at the beginning of a line
e$ # e at the end of a line
tle$ # tle at the end of a line
und* # un followed by zero or more d characters
# This will match un
# und
# undd
# unddd (etc)
.* # Any string without a newline. This is because
# the . matches anything except a newline and
# the * means zero or more of these.
^$ # A line with nothing in it.

There are even more options. Square brackets are used to match any one of the characters inside them. Inside square brackets a - indicates "between" and a ^ at the beginning means "not":

[qjk] # Either q or j or k
[^qjk] # Neither q nor j nor k
[a-z] # Anything from a to z inclusive
[^a-z] # No lower case letters
[a-zA-Z] # Any letter
[a-z]+ # Any non-zero sequence of lower case letters

At this point you can probably skip to the end and do at least most of the exercise. The rest is mostly just for reference.
A vertical bar | represents an "or" and parentheses (...) can be used to group things together:

jelly|cream # Either jelly or cream
(eg|le)gs # Either eggs or legs
(da)+ # Either da or dada or dadada or...

Here are some more special characters:

\n # A newline
\t # A tab
\w # Any alphanumeric (word) character.
# The same as [a-zA-Z0-9_]
\W # Any non-word character.
# The same as [^a-zA-Z0-9_]
\d # Any digit. The same as [0-9]
\D # Any non-digit. The same as [^0-9]
\s # Any whitespace character: space,
# tab, newline, etc
\S # Any non-whitespace character
\b # A word boundary, outside [] only
\B # No word boundary

Clearly characters like $, |, [, ), \, / and so on are peculiar cases in regular expressions. If you want to match for one of those then you have to preceed it by a backslash. So:

\| # Vertical bar
\[ # An open square bracket
\) # A closing parenthesis
\* # An asterisk
\^ # A carat symbol
\/ # A slash
\\ # A backslash

and so on.
Some example REs
As was mentioned earlier, it's probably best to build up your use of regular expressions slowly. Here are a few examples. Remember that to use them for matching they should be put in /.../ slashes
[01] # Either "0" or "1"
\/0 # A division by zero: "/0"
\/ 0 # A division by zero with a space: "/ 0"
\/\s0 # A division by zero with a whitespace:
# "/ 0" where the space may be a tab etc.
\/ *0 # A division by zero with possibly some
# spaces: "/0" or "/ 0" or "/ 0" etc.
\/\s*0 # A division by zero with possibly some
# whitespace.
\/\s*0\.0* # As the previous one, but with decimal
# point and maybe some 0s after it. Accepts
# "/0." and "/0.0" and "/0.00" etc and
# "/ 0." and "/ 0.0" and "/ 0.00" etc.
Previously your program counted non-empty lines. Alter it so that instead of counting non-empty lines it counts only lines with
the letter x
the string the
the string the which may or may not have a capital t
the word the with or without a capital. Use \b to detect word boundaries.
In each case the program should print out every line, but it should only number those specified. Try to use the $_ variable to avoid using the =~ match operator explicitly.
Substitution and translation
As well as identifying regular expressions Perl can make substitutions based on those matches. The way to do this is to use the s function which is designed to mimic the way substitution is done in the vi text editor. Once again the match operator is used, and once again if it is omitted then the substitution is assumed to take place with the $_ variable.
To replace an occurrence of london by London in the string $sentence we use the expression
$sentence =~ s/london/London/
and to do the same thing with the $_ variable just
Notice that the two regular expressions (london and London) are surrounded by a total of three slashes. The result of this expression is the number of substitutions made, so it is either 0 (false) or 1 (true) in this case.
This example only replaces the first occurrence of the string, and it may be that there will be more than one such string we want to replace. To make a global substitution the last slash is followed by a g as follows:
which of course works on the $_ variable. Again the expression returns the number of substitutions made, which is 0 (false) or something greater than 0 (true).
If we want to also replace occurrences of lOndon, lonDON, LoNDoN and so on then we could use
but an easier way is to use the i option (for "ignore case"). The expression
will make a global substitution ignoring case. The i option is also used in the basic /.../ regular expression match.
Remembering patterns
It's often useful to remember patterns that have been matched so that they can be used again. It just so happens that anything matched in parentheses gets remembered in the variables $1,...,$9. These strings can also be used in the same regular expression (or substitution) by using the special RE codes \1,...,\9. For example
$_ = "Lord Whopper of Fibbing";
print "$_\n";
will replace each upper case letter by that letter surrounded by colons. It will print :L:ord :W:hopper of :F:ibbing. The variables $1,...,$9 are read-only variables; you cannot alter them yourself.
As another example, the test

if (/(\b.+\b) \1/)
print "Found $1 repeated\n";
will identify any words repeated. Each \b represents a word boundary and the .+ matches any non-empty string, so \b.+\b matches anything between two word boundaries. This is then remembered by the parentheses and stored as \1 for regular expressions and as $1 for the rest of the program.
The following swaps the first and last characters of a line in the $_ variable:
The ^ and $ match the beginning and end of the line. The \1 code stores the first character; the \2 code stores everything else up the last character which is stored in the \3 code. Then that whole line is replaced with \1 and \3 swapped round.
After a match, you can use the special read-only variables $` and $& and $' to find what was matched before, during and after the seach. So after
$_ = "Lord Whopper of Fibbing";
all of the following are true. (Remember that eq is the string-equality test.)
$` eq "Lord Wo";
$& eq "pp";
$' eq "er of Fibbing";
Finally on the subject of remembering patterns it's worth knowing that inside of the slashes of a match or a substitution variables are interpolated. So
$search = "the";
will replace every occurrence of the with xxx. If you want to replace every occurence of there then you cannot do s/$searchre/xxx/ because this will be interpolated as the variable $searchre. Instead you should put the variable name in curly braces so that the code becomes
$search = "the";
The tr function allows character-by-character translation. The following expression replaces each a with e, each b with d, and each c with f in the variable $sentence. The expression returns the number of substitutions made.
$sentence =~ tr/abc/edf/
Most of the special RE codes do not apply in the tr function. For example, the statement here counts the number of asterisks in the $sentence variable and stores that in the $count variable.
$count = ($sentence =~ tr/*/*/);
However, the dash is still used to mean "between". This statement converts $_ to upper case.
Your current program should count lines of a file which contain a certain string. Modify it so that it counts lines with double letters (or any other double character). Modify it again so that these double letters appear also in parentheses. For example your program would produce a line like this among others:
023 Amp, James Wa(tt), Bob Transformer, etc. These pion(ee)rs conducted many
Try to get it so that all pairs of letters are in parentheses, not just the first pair on each line.
For a slightly more interesting program you might like to try the following. Suppose your program is called countlines. Then you would call it with
However, if you call it with several arguments, as in
./countlines first second etc
then those arguments are stored in the array @ARGV. In the above example we have $ARGV[0] is first and $ARGV[1] is second and $ARGV[2] is etc. Modify your program so that it accepts one argument and counts only those lines with that string. It should also put occurrences of this string in paretheses. So
./countlines the
will output something like this line among others:
019 But (the) greatest Electrical Pioneer of (the)m all was Thomas Edison, who
A very useful function in Perl is split, which splits up a string and places it into an array. The function uses a regular expression and as usual works on the $_ variable unless otherwise specified.
The split function is used like this:
$info = "Caine:Michael:Actor:14, Leafy Drive";
@personal = split(/:/, $info);
which has the same overall effect as
@personal = ("Caine", "Michael", "Actor", "14, Leafy Drive");
If we have the information stored in the $_ variable then we can just use this instead
@personal = split(/:/);
If the fields are divided by any number of colons then we can use the RE codes to get round this. The code
$_ = "Capes:Geoff::Shot putter:::Big Avenue";
@personal = split(/:+/);

is the same as
@personal = ("Capes", "Geoff",
"Shot putter", "Big Avenue");
But this:
$_ = "Capes:Geoff::Shot putter:::Big Avenue";
@personal = split(/:/);
would be like
@personal = ("Capes", "Geoff", "",
"Shot putter", "", "", "Big Avenue");
A word can be split into characters, a sentence split into words and a paragraph split into sentences:
@chars = split(//, $word);
@words = split(/ /, $sentence);
@sentences = split(/\./, $paragraph);
In the first case the null string is matched between each character, and that is why the @chars array is an array of characters - ie an array of strings of length 1.
A useful tool in natural language processing is concordance. This allows a specific string to be displayed in its immediate context whereever it appears in a text. For example, a concordance program identifying the target string the might produce some of the following output. Notice how the occurrences of the target string line up vertically.
discovered (this is the truth) that when he
t kinds of metal to the leg of a frog, an e
rrent developed and the frog's leg kicked,
longer attached to the frog, which was dea
normous advances in the field of amphibian
ch it hop back into the pond -- almost. Bu
ond -- almost. But the greatest Electrical
ectrical Pioneer of them all was Thomas Edi
This exercise is to write such a program. Here are some tips:
Read the entire file into array (this obviously isn't useful in general because the file may be extremely large, but we won't worry about that here). Each item in the array will be a line of the file.
When the chop function is used on an array it chops off the last character of every item in the array.
Recall that you can join the whole array together with a statement like $text = "@lines";
Use the target string as delimiter for splitting the text. (Ie, use the target string in place of the colon in our previous examples.) You should then have an array of all the strings between the target strings.
For each array element in turn, print it out, print the target string, and then print the next array element.
Recall that the last element of an array @food has index $#food.
As it stands this would be a pretty good program, but the target strings won't line up vertically. To tidy up the strings you'll need the substr function. Here are three examples of its use.
substr("Once upon a time", 3, 4); # returns "e up"
substr("Once upon a time", 7); # returns "on a time"
substr("Once upon a time", -6, 5); # returns "a tim"
The first example returns a substring of length 4 starting at position 3. Remember that the first character of a string has index 0. The second example shows that missing out the length gives the substring right to the end of the string The third example shows that you can also index from the end using a negative index. It returns the substring that starts at the 6th character from the end and has length 5.
If you use a negative index that extends beyond the beginning of the string then Perl will return nothing or give a warning. To avoid this happening you can pad out the string by using the x operator mentioned earlier. The expression (" "x30) produces 30 spaces, for example.
Associative arrays
Ordinary list arrays allow us to access their element by number. The first element of array @food is $food[0]. The second element is $food[1], and so on. But Perl also allows us to create arrays which are accessed by string. These are called associative arrays.
To define an associative array we use the usual parenthesis notation, but the array itself is prefixed by a % sign. Suppose we want to create an array of people and their ages. It would look like this:
%ages = ("Michael Caine", 39,
"Dirty Den", 34,
"Angie", 27,
"Willy", "21 in dog years",
"The Queen Mother", 108);
Now we can find the age of people with the following expressions
$ages{"Michael Caine"}; # Returns 39
$ages{"Dirty Den"}; # Returns 34
$ages{"Angie"}; # Returns 27
$ages{"Willy"}; # Returns "21 in dog years"
$ages{"The Queen Mother"}; # Returns 108
Notice that like list arrays each % sign has changed to a $ to access an individual element because that element is a scalar. Unlike list arrays the index (in this case the person's name) is enclosed in curly braces, the idea being that associative arrays are fancier than list arrays.
An associative array can be converted back into a list array just by assigning it to a list array variable. A list array can be converted into an associative array by assigning it to an associative array variable. Ideally the list array will have an even number of elements:

@info = %ages; # @info is a list array. It
# now has 10 elements
$info[5]; # Returns the value 27 from
# the list array @info
%moreages = @info; # %moreages is an associative
# array. It is the same as %ages
Associative arrays do not have any order to their elements (they are just like hash tables) but is it possible to access all the elements in turn using the keys function and the values function:
foreach $person (keys %ages)
print "I know the age of $person\n";
foreach $age (values %ages)
print "Somebody is $age\n";
When keys is called it returns a list of the keys (indices) of the associative array. When values is called it returns a list of the values of the array. These functions return their lists in the same order, but this order has nothing to do with the order in which the elements have been entered.
When keys and values are called in a scalar context they return the number of key/value pairs in the associative array.

There is also a function each which returns a two element list of a key and its value. Every time each is called it returns another key/value pair:

while (($person, $age) = each(%ages))
print "$person is $age\n";
Environment variables
When you run a perl program, or any script in UNIX, there will be certain environment variables set. These will be things like USER which contains your username and DISPLAY which specifies which screen your graphics will go to. When you run a perl CGI script on the World Wide Web there are environment variables which hold other useful information. All these variables and their values are stored in the associative %ENV array in which the keys are the variable names. Try the following in a perl program:
print "You are called $ENV{'USER'} and you are ";
print "using display $ENV{'DISPLAY'}\n";
Like any good programming langauge Perl allows the user to define their own functions, called subroutines. They may be placed anywhere in your program but it's probably best to put them all at the beginning or all at the end. A subroutine has the form
sub mysubroutine
print "Not a very interesting routine\n";
print "This does the same thing every time\n";
regardless of any parameters that we may want to pass to it. All of the following will work to call this subroutine. Notice that a subroutine is called with an & character in front of the name:
&mysubroutine; # Call the subroutine
&mysubroutine($_); # Call it with a parameter
&mysubroutine(1+2, $_); # Call it with two parameters
In the above case the parameters are acceptable but ignored. When the subroutine is called any parameters are passed as a list in the special @_ list array variable. This variable has absolutely nothing to do with the $_ scalar variable. The following subroutine merely prints out the list that it was called with. It is followed by a couple of examples of its use.
sub printargs
print "@_\n";
&printargs("perly", "king"); # Example prints "perly king"
&printargs("frog", "and", "toad"); # Prints "frog and toad"
Just like any other list array the individual elements of @_ can be accessed with the square bracket notation:
sub printfirsttwo
print "Your first argument was $_[0]\n";
print "and $_[1] was your second\n";

Again it should be stressed that the indexed scalars $_[0] and $_[1] and so on have nothing to with the scalar $_ which can also be used without fear of a clash.


Returning values
Result of a subroutine is always the last thing evaluated. This subroutine returns the maximum of two input parameters. An example of its use follows.
sub maximum
if ($_[0] > $_[1])
$biggest = &maximum(37, 24); # Now $biggest is 37
The &printfirsttwo subroutine above also returns a value, in this case 1. This is because the last thing that subroutine did was a print statement and the result of a successful print statement is always 1.
Local variables
The @_ variable is local to the current subroutine, and so of course are $_[0], $_[1], $_[2], and so on. Other variables can be made local too, and this is useful if we want to start altering the input parameters. The following subroutine tests to see if one string is inside another, spaces not withstanding. An example follows.
sub inside
local($a, $b); # Make local variables
($a, $b) = ($_[0], $_[1]); # Assign values
$a =~ s/ //g; # Strip spaces from
$b =~ s/ //g; # local variables
($a =~ /$b/ || $b =~ /$a/); # Is $b inside $a
# or $a inside $b?
&inside("lemon", "dole money"); # true
In fact, it can even be tidied up by replacing the first two lines with
local($a, $b) = ($_[0], $_[1]);

Perl Basic Program PART I

Here is the basic perl program that we'll use to get started.
# Program to do the obvious
print 'Hello world.'; # Print a message
Each of the parts will be discussed in turn.
The first line
Every perl program starts off with this as its very first line:

although this may vary from system to system. This line tells the machine what to do with the file when it is executed (ie it tells it to run the file through Perl).
Comments and statements
Comments can be inserted into a program with the # symbol, and anything from the # to the end of the line is ignored (with the exception of the first line). The only way to stretch comments over several lines is to use a # on each line.
Everything else is a Perl statement which must end with a semicolon, like the last line above.

Simple printing
The print function outputs some information. In the above case it prints out the the literal string Hello world. and of course the statement ends with a semicolon.
You may find the above program produces an slightly unexpected result. So the next thing to do is to run it.
Running the program
Type in the example program using a text editor, and save it. Emacs is a good editor to use for this because it has its own Perl mode which formats lines nicely when you hit tab (use `M-x perl-mode'). But as ever, use whichever you're most comfortable with.
After you've entered and saved the program make sure the file is executable by using the command
chmod u+x progname
at the UNIX prompt, where progname is the filename of the program. Now to run the program just type any of the following at the prompt.
perl progname
If something goes wrong then you may get error messages, or you may get nothing. You can always run the program with warnings using the command
perl -w progname
at the prompt. This will display warnings and other (hopefully) helpful messages before it tries to execute the program. To run the program with a debugger use the command
perl -d progname
When the file is executed Perl first compiles it and then executes that compiled version. So after a short pause for compilation the program should run quite quickly. This also explains why you can get compilation errors when you execute a Perl file which consists only of text.
Make sure your program works before proceeding. The program's output may be slightly unexpected - at least it isn't very pretty. We'll look next at variables and then tie this in with prettier printing.
Scalar variables
The most basic kind of variable in Perl is the scalar variable. Scalar variables hold both strings and numbers, and are remarkable in that strings and numbers are completely interchangable. For example, the statement
$priority = 9;
sets the scalar variable $priority to 9, but you can also assign a string to exactly the same variable:
$priority = 'high';
Perl also accepts numbers as strings, like this:
$priority = '9';
$default = '0009';
and can still cope with arithmetic and other operations quite happily.
In general variable names consists of numbers, letters and underscores, but they should not start with a number and the variable $_ is special, as we'll see later. Also, Perl is case sensitive, so $a and $A are different.
Operations and Assignment
Perl uses all the usual C arithmetic operators:
$a = 1 + 2; # Add 1 and 2 and store in $a
$a = 3 - 4; # Subtract 4 from 3 and store in $a
$a = 5 * 6; # Multiply 5 and 6
$a = 7 / 8; # Divide 7 by 8 to give 0.875
$a = 9 ** 10; # Nine to the power of 10
$a = 5 % 2; # Remainder of 5 divided by 2
++$a; # Increment $a and then return it
$a++; # Return $a and then increment it
--$a; # Decrement $a and then return it
$a--; # Return $a and then decrement it
and for strings Perl has the following among others:
$a = $b . $c; # Concatenate $b and $c
$a = $b x $c; # $b repeated $c times
To assign values Perl includes
$a = $b; # Assign $b to $a
$a += $b; # Add $b to $a
$a -= $b; # Subtract $b from $a
$a .= $b; # Append $b onto $a
Note that when Perl assigns a value with $a = $b it makes a copy of $b and then assigns that to $a. Therefore the next time you change $b it will not alter $a.
Other operators can be found on the perlop manual page. Type man perlop at the prompt.
The following code prints apples and pears using concatenation:
$a = 'apples';
$b = 'pears';
print $a.' and '.$b;
It would be nicer to include only one string in the final print statement, but the line
print '$a and $b';
prints literally $a and $b which isn't very helpful. Instead we can use the double quotes in place of the single quotes:
print "$a and $b";
The double quotes force interpolation of any codes, including interpreting variables. This is a much nicer than our original statement. Other codes that are interpolated include special characters such as newline and tab. The code \n is a newline and \t is a tab.
This exercise is to rewrite the Hello world program so that (a) the string is assigned to a variable and (b) this variable is then printed with a newline character. Use the double quotes and don't use the concatenation operator. Make sure you can get this to work before proceeding.
Array variables
A slightly more interesting kind of variable is the array variable which is a list of scalars (ie numbers and strings). Array variables have the same format as scalar variables except that they are prefixed by an @ symbol. The statement
@food = ("apples", "pears", "eels");
@music = ("whistle", "flute");
assigns a three element list to the array variable @food and a two element list to the array variable @music.
The array is accessed by using indices starting from 0, and square brackets are used to specify the index. The expression
returns eels. Notice that the @ has changed to a $ because eels is a scalar.
Array assignments
As in all of Perl, the same expression in a different context can produce a different result. The first assignment below explodes the @music variable so that it is equivalent to the second assignment.
@moremusic = ("organ", @music, "harp");
@moremusic = ("organ", "whistle", "flute", "harp");
This should suggest a way of adding elements to an array. A neater way of adding elements is to use the statement
push(@food, "eggs");
which pushes eggs onto the end of the array @food. To push two or more items onto the array use one of the following forms:
push(@food, "eggs", "lard");
push(@food, ("eggs", "lard"));
push(@food, @morefood);
The push function returns the length of the new list.
To remove the last item from a list and return it use the pop function. From our original list the pop function returns eels and @food now has two elements:
$grub = pop(@food); # Now $grub = "eels"
It is also possible to assign an array to a scalar variable. As usual context is important. The line
$f = @food;
assigns the length of @food, but
$f = "@food";
turns the list into a string with a space between each element. This space can be replaced by any other string by changing the value of the special $" variable. This variable is just one of Perl's many special variables, most of which have odd names.
Arrays can also be used to make multiple assignments to scalar variables:

($a, $b) = ($c, $d); # Same as $a=$c; $b=$d;
($a, $b) = @food; # $a and $b are the first two
# items of @food.
($a, @somefood) = @food; # $a is the first item of @food
# @somefood is a list of the
# others.
(@somefood, $a) = @food; # @somefood is @food and
# $a is undefined.
The last assignment occurs because arrays are greedy, and @somefood will swallow up as much of @food as it can. Therefore that form is best avoided.
Finally, you may want to find the index of the last element of a list. To do this for the @food array use the expression
Displaying arrays
Since context is important, it shouldn't be too surprising that the following all produce different results:
print @food; # By itself
print "@food"; # Embedded in double quotes
print @food.""; # In a scalar context
Try out each of the above three print statements to see what they do.
File handling
Here is the basic perl program which does the same as the UNIX cat command on a certain file.
# Program to open the password file, read it in,
# print it, and close it again.
$file = '/etc/passwd'; # Name the file
open(INFO, $file); # Open the file
@lines = ; # Read it into an array
close(INFO); # Close the file
print @lines; # Print the array
The open function opens a file for input (i.e. for reading). The first parameter is the filehandle which allows Perl to refer to the file in future. The second parameter is an expression denoting the filename. If the filename was given in quotes then it is taken literally without shell expansion. So the expression '~/notes/todolist' will not be interpreted successfully. If you want to force shell expansion then use angled brackets: that is, use <~/notes/todolist> instead.
The close function tells Perl to finish with that file.
There are a few useful points to add to this discussion on filehandling. First, the open statement can also specify a file for output and for appending as well as for input. To do this, prefix the filename with a > for output and a >> for appending:
open(INFO, $file); # Open for input
open(INFO, ">$file"); # Open for output
open(INFO, ">>$file"); # Open for appending
open(INFO, "<$file"); # Also open for input
Second, if you want to print something to a file you've already opened for output then you can use the print statement with an extra parameter. To print a string to the file with the INFO filehandle use
print INFO "This line goes to the file.\n";
Third, you can use the following to open the standard input (usually the keyboard) and standard output (usually the screen) respectively:
open(INFO, '-'); # Open standard input
open(INFO, '>-'); # Open standard output
In the above program the information is read from a file. The file is the INFO file and to read from it Perl uses angled brackets. So the statement
@lines = ;
reads the file denoted by the filehandle into the array @lines. Note that the expression reads in the file entirely in one go. This because the reading takes place in the context of an array variable. If @lines is replaced by the scalar $lines then only the next one line would be read in. In either case each line is stored complete with its newline character at the end.
Modify the above program so that the entire file is printed with a # symbol at the beginning of each line. You should only have to add one line and modify another. Use the $" variable. Unexpected things can happen with files, so you may find it helpful to use the -w option as mentioned in the section on running Perl programs.
Control structures
More interesting possiblities arise when we introduce control structures and looping. Perl supports lots of different kinds of control structures which tend to be like those in C, but are very similar to Pascal, too. Here we discuss a few of them.
To go through each line of an array or other list-like structure (such as lines in a file) Perl uses the foreach structure. This has the form
foreach $morsel (@food) # Visit each item in turn
# and call it $morsel
print "$morsel\n"; # Print the item
print "Yum yum\n"; # That was nice
The actions to be performed each time are enclosed in a block of curly braces. The first time through the block $morsel is assigned the value of the first item in the array @food. Next time it is assigned the value of the second item, and so until the end. If @food is empty to start with then the block of statements is never executed.
The next few structures rely on a test being true or false. In Perl any non-zero number and non-empty string is counted as true. The number zero, zero by itself in a string, and the empty string are counted as false. Here are some tests on numbers and strings.
$a == $b # Is $a numerically equal to $b?
# Beware: Don't use the = operator.
$a != $b # Is $a numerically unequal to $b?
$a eq $b # Is $a string-equal to $b?
$a ne $b # Is $a string-unequal to $b?
You can also use logical and, or and not:
($a && $b) # Is $a and $b true?
($a || $b) # Is either $a or $b true?
!($a) # is $a false?
Perl has a for structure that mimics that of C. It has the form
for (initialise; test; inc)
First of all the statement initialise is executed. Then while test is true the block of actions is executed. After each time the block is executed inc takes place. Here is an example for loop to print out the numbers 0 to 9.
for ($i = 0; $i < 10; ++$i) # Start with $i = 1
# Do it while $i < 10
# Increment $i before repeating
print "$i\n";
while and until
Here is a program that reads some input from the keyboard and won't continue until it is the correct password
print "Password? "; # Ask for input
$a = ; # Get input
chop $a; # Remove the newline at end
while ($a ne "fred") # While input is wrong...
print "sorry. Again? "; # Ask again
$a = ; # Get input again
chop $a; # Chop off newline again
The curly-braced block of code is executed while the input does not equal the password. The while structure should be fairly clear, but this is the opportunity to notice several things. First, we can we read from the standard input (the keyboard) without opening the file first. Second, when the password is entered $a is given that value including the newline character at the end. The chop function removes the last character of a string which in this case is the newline.
To test the opposite thing we can use the until statement in just the same way. This executes the block repeatedly until the expression is true, not while it is true.
Another useful technique is putting the while or until check at the end of the statement block rather than at the beginning. This will require the presence of the do operator to mark the beginning of the block and the test at the end. If we forgo the sorry. Again message in the above password program then it could be written like this.
"Password? "; # Ask for input
$a = ; # Get input
chop $a; # Chop off newline
while ($a ne "fred") # Redo while wrong input
Modify the program from the previous exercise so that each line of the file is read in one by one and is output with a line number at the beginning. You should get something like:
1 root:oYpYXm/qRO6N2:0:0:Super-User:/:/bin/csh
2 sysadm:*:0:0:System V Administration:/usr/admin:/bin/sh
3 diag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/csh
You may find it useful to use the structure
while ($line = )
When you have done this see if you can alter it so that line numbers are printed as 001, 002, ..., 009, 010, 011, 012, etc. To do this you should only need to change one line by inserting an extra four characters. Perl's clever like that.
Of course Perl also allows if/then/else statements. These are of the following form:
if ($a)
print "The string is not empty\n";
print "The string is empty\n";
For this, remember that an empty string is considered to be false. It will also give an "empty" result if $a is the string 0.
It is also possible to include more alternatives in a conditional statement:
if (!$a) # The ! is the not operator
print "The string is empty\n";
elsif (length($a) == 1) # If above fails, try this
print "The string has one character\n";
elsif (length($a) == 2) # If that fails, try this
print "The string has two characters\n";
else # Now, everything has failed
print "The string has lots of characters\n";
In this, it is important to notice that the elsif statement really does have an "e" missing.
Find a fairly large file that contains some text and some blank lines. The file ~webk/WWW/Perl/Misc/electricity.txt is pretty good because it's funny apart from anything else. It was originally posted to our local news system by David O'Brien.
From the previous exercise you should have a program which prints out the password file with line numbers. Change it so that works with the text file. Now alter the program so that line numbers aren't printed or counted with blank lines, but every line is still printed, including the blank ones. Remember that when a line of the file is read in it will still include its newline character at the end.