Saturday, November 29, 2008

My Favorites

Here is a list of my favorites:

Favorite Ancient Civilization : Maya
Favorite Animals : Cobra , Firefox & Panda
Favorite Astronomy:Eclipse & Sun
Favorite Drinks:Java
Favorite Flights:Apache & Tomcat
Favorite Fruits:Apple, Blackberry & Orange
Favorite Girl:Ruby
Favorite Heroine:Oracle
Favorite Legends / Mythology:
(Greek)Kerberos, Oracle of Delphi, Python & Trojan Horse
(Indian)Thunderbird
(misc)daemon
Favorite Painter:Michelangelo
Favorite Professionals:Ada & Pascal
Favorite Snacks:cookies & hot dog


Friday, November 28, 2008

Display the Length of the Filename in Windows

Sometimes if the file name is too long, some application will not work properly. So, it is better to make the name short. What is the length of the file name now ?

Instead of counting by fingers, I have written this JScript named filename_length.js :

// -------------------------------------------------------------
// Licence Information:
// --------------------
// This coding is offered at no charge for 
// NON-COMMERCIAL PERSONAL USE only.
// The coding is copyright.
// Reproduction of this coding in whole or in part 
// in any form without the express written permission 
// of the author is strictly prohibited. 
// -------------------------------------------------------------
// Disclaimer : 
// ------------
// This coding is distributed "as is" and is UNSUPPORTED.
// NO WARRANTY of any kind is expressed or implied.
// You use AT YOUR OWN RISK.
// The author will not be liable for any data loss,
// damages, and loss of profits or any other kind of
// tangible or intangible loss while using or 
// misusing this coding.
// -------------------------------------------------------------
// Purpose: Display the length of the filename(s)
//          as well as the length of the fullpath filename(s).
//          If there are multiple files,
//             the whole list of files will be displayed line by line
//             with the length of the fullpath filename inside brackets
//             And, at the end, the file(s) with the longest length
//             will be identified (except when all files are with same
//             length).
// Noted  : This script counts the number of characters in the name,
//          not the number of byte.  Double-byte character (e.g.
//          Chinese) is counted as 1 in the filename length.
//          For example, a filename with 4 Chinese characters will
//          give a length of 4 (even though the name occupies 8 bytes).
// Limitation: 1. The total number of files passed to this script
//                cannot be too large because this will trigger the 
//                error - arguments list is too long
//             2. When filename is with Unicode characters, some 
//                application cannot open it because the application
//                does not use Unicode-API.
//                This script also cannot display Unicode filename
//                correctly.  Instead, a Question Mark will be seen.
// Platform    : Windows XP
// Installation: 1. Put this script in the any folder you like
//               2. Go to the Send To folder
//               3. Create a shortcut to point to this script
// Usage     : Inside any folder,
//             1. Select one (or multiple) file
//             2. Right-Click
//             3. Select Send To
//             4. Select the shortcut of this script
//             The information will be dislayed in a pop up window.
//             After reading, click OK to quit.
// Author    : Alvin SIU
// Date      : 2007-11-28
//-------------------------------------------------------------

  var fso=  WScript.createObject("Scripting.FileSystemObject");
  var args= WScript.arguments;

//-------------------------------------------------------------
// Ensure at least 1 argument
//-------------------------------------------------------------
  if (args.length == 0) { 
    WScript.Echo('The script requires argument(s)'); 
    WScript.Quit()
  }

//-------------------------------------------------------------
// Main program
//-------------------------------------------------------------
  var dasFullpathFilename ;
  var dasFilename         ;
  var dasCount            ;
      dasCount= 0         ;
  var dasLongest          ;   
      dasLongest= 0       ;
  var dasLongestString    ;  // Store all filenames with longest length
      dasLongestString= '';
  var k                   ; 
  var dasString           ;
      dasString= ''       ;
  var dasString1          ;
  var shorter             ; // When all files are with same length,
      shorter= false      ; // both the longer and shorter flags
  var longer              ; // will be false.
      longer=  false      ;
  var dasCount            ;
      dasCount= 0         ;

  for ( k= 0 ; k < args.length ; k++) {
    dasFullpathFilename= args(k) ; 
    dasFilename= fso.GetFileName(dasFullpathFilename);

    dasCount++ ;
    dasString1= '[' + dasCount + '.]     '
              + dasFilename.length + ' ( ' 
              + dasFullpathFilename.length + ' ) ' 
              + dasFilename + '\n';

    dasString+= dasString1 ; 

    if     (dasFilename.length > dasLongest) {
              if (k > 0) longer= true ; 
              dasLongest=       dasFilename.length ;
              dasLongestString= dasString1 ;
    }
    else if (dasFilename.length == dasLongest) {
              dasLongestString+= dasString1 ;
         }
    else shorter= true;
  }

  if (k > 1) {
     if (shorter | longer) {
        WScript.Echo( dasString
                    + '\nThe Longest Filename is/are :\n'
                    + dasLongestString);
     }
     else {
            WScript.Echo( dasString );
          }
  }
  else {
         WScript.Echo( dasFilename.length + ' : ' 
                     + dasFilename+'\n'
                     + dasFullpathFilename.length + ' : ' 
                     + dasFullpathFilename);
       }

//-------------------------------------------------------------
// End Of Script
//-------------------------------------------------------------
The installation and usage instructions are at the beginning of the script flower comment.


Alternate Line Shading in Program Coding

It is very simple to use alternate line shading in program coding like this :

program Hello_World; begin; writeln('Hello World !'); writeln('This is a demo for alternate line shading.'); end.

The alternate line shading in the above example are simply implemented by repeating the image at the left.
Of course, you have to adjust the height of the image to the line-height of the text.

This demo shows alternate line shading for 5 different shadings :

All animals are equal, but some animals are more equal than others. They are ... Administrators. Better late than never. Better never be late. Curiosity killed the cat. Who kill the Cat Woman ? Do as I say, and not as I do. How about when you say 'I do' ? Early bird catches the worm. Early programmer catches the bug. Failure is the mother of success. Program failure is a shit. Garbage in, garbage out and garbage inside out. Hello World ! Halloween ! I am serious. It was a joke. I am just kidding. Java, cookies together with the Sun : this is my breakfast. Keep your mouth shut and your ear, eye, mind, source-code, ... open. Life is just a bowl of cherries, and ... honeys. Money($) is not everything, but no money makes you a nothing. Nothing is impossible. Impossible is nothing. Is nothing impossible ? Orz Practice makes perfect. Illegal practice makes money. Quality rather than quantity. But, man-day is a measure for quantity. Rome was not built in one day, so did computer systems. Simple is beautiful. Simple mind is brilliant. Simphson is ... There are 10 types of people in the world: Those who understand binary, and those who don't. Universe in a nutshell. C, C++, Java, Perl, SQL, Unix, ... also in a nutshell. Vision without action is merely a dream. Action without vision just passes time. Wonder is the beginning of wisdom. Wonder Woman is ... WoW ! XD :) XP (^o^) (^0^) (^O^) ... 囧囧 You jump, I jump ! Z notation is ...

The alternate line shading colors in the above example are implemented by repeating the image at the left.

Licence Information:
All coding in this article is offered at no charge for NON-COMMERCIAL PERSONAL USE only.
The coding is copyright.
Reproduction of this coding in whole or in part in any form without the express written permission of the author is strictly prohibited.

Disclaimer :
All coding in this article is distributed "as is" and is UNSUPPORTED.
NO WARRANTY of any kind is expressed or implied.
You use AT YOUR OWN RISK.
The author will not be liable for any data loss,damages, and loss of profits or any other kind of tangible or intangible loss while using or misusing this coding.


Thursday, November 27, 2008

Make Hong Kong Post as a Trusted CA in Firefox 3.0.4

Every time when I login the Renewal of Libarary Materials of Hong Kong Public Libraries and the eTax of Inland Revenue Department of Hong Kong to perform any taxation related activities, Firefox 3.0.4 will pop up to ask me to add the site as exception. So far I was asked 3 times because in each time I was re-directed to a different server , namely etax11, etax21 and etax22. This is quite troublesome.

So, the best way is to add the Hong Kong Post as a trusted CA in Firfox.

To do so, the first step is to get the certificate of Hong Kong Post.

Then, follows these steps

  1. Go to Firefox 3.0.4
  2. In the main menu, click Tools
  3. Click Options
  4. Click Advanced
  5. Click Encryption tab
  6. Click View Certificates button
  7. Click Authorities tab
  8. Click Import... button
  9. In the pop up window, locate the file Hongkong Post Root CA 1.cer
  10. Click Open button
  11. In the Downloading Certificate window, click View button to examine the certificate
  12. Make sure the Issued by is Hongkong Post Root CA 1
  13. Make sure the SHA1 Fingerprint is D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58
  14. Click Close button to close the view
  15. Tick the check box Trust this CA to identify web sites
  16. Click OK button
  17. When back to the Authorities tab, the Hongkong Post entry should be appear in the Certificate Name column.
  18. Click many OK buttons to end and save the setting

Now the Hongkong Post is one of the trusted CA in your Firefox. When going to the sites having certificates issued by Hongkong Post, it will be trust and will not prompt for add exception in Firefox.

For example, when you go to Hong Kong Public Libraries for books renewal, the site will be trusted. At the bottom right corner of the status bar, there is a site name libcat.hkpl.gov.hk with a lock button. Double-click the lock button and then the View Certificate button will see the certificate.

BTW, as at 2008-11-28, the eTax of Inland Revenue Departement of Hong Kong still cannot support the browser Firefox 3. However, as at 2009-02-05, Firefox 3 can be used to login the eTax.


Wednesday, November 26, 2008

Search Operators in Google

Although we use Google everyday, do you really know about some advanced technique.

This URL www.googleguide.com - Special Characters: Summary show some useful search operators (e.g. + - ~ OR | .. *) in Google search.

The URL also contains some other userful information of Google search.


Tuesday, November 25, 2008

Remove Square Brackets in Filename

When you drag a file (e.g. index.htm) from the Temporary Internet Folder to a standard folder, the file is renamed with square brackets with a number inside (e.g. index[1].htm or index[2].htm).

The URL SCRIPTING REMOVE BRACKETS REVISITED has a JScript to remove this square brackets. The steps are :

  1. Put the JScript in the SendTo directory
  2. Over the file (e.g. index[1].htm), right click
  3. Select Send To
  4. Select the JScript

Then, the file will be renamed with square brackets removed.


Monday, November 24, 2008

Run the BlackBerry Localization Demo

After numerous trials and errors and searching the net, I finally can partially run the Localization Demo of BlackBerry in Eclipse 3.4.1.

By default, the simulator's language is English. So, the followings are the steps to call the application in English :

  1. Go to the Simulator
  2. Press Menu key
  3. Choose Downloads
  4. Choose Localization Demo
  5. In Choose a Country:, the default is United States. Just let it be.
  6. Press the Menu key
  7. Choose View. The information of USA is displayed on the screen.
  8. Press Escape key to back to the Choose a Country:
  9. Click the United States to call the pop up menu
  10. Press down arrow in the keyboard to go to China
  11. Press Enter key in the keyboard. Now, the China information is display.
  12. Press Escape key to back to the Choose a Country:
  13. Click the China to call the pop up menu
  14. Press down arrow in the keyboard to go to Germany
  15. Press Enter key in the keyboard. Now, the information of Germany is displayed.
  16. Press Escape key to back to the Choose a Country:
  17. Press Escape key to quit the application

To test the Demo in German, one have to add the German language into the simulator. For example, when using the simulator 9530, edit the 9530.xml to locate the line:

<application>net.rim.blackberry.lang.en_GB</application>
Then, add the following line under it :
<application>net.rim.blackberry.lang.de</application>
Afterwards, use the followings to test the application in German :
  1. Go to the Simulator
  2. Press Menu key
  3. Choose Options
  4. Choose Language
  5. In the Language:, choose Deutsche
  6. Press Menu key
  7. Choose Save. Now everything is in German. Hope that you know German :)
  8. Press Escape key
  9. Choose Downloads
  10. Choose Sparchopti...
  11. In the screen, the default is United States. Just let it be.
  12. Press the Menu key
  13. Choose Anzeigen to view the information of USA in German language
  14. Press Escape key to go back
  15. Click the United States to call the pop up menu
  16. Press down arrow in the keyboard to go to China
  17. Press Enter key in the keyboard. Now, the China information is display in German
  18. Press Escape key to go back
  19. Click the China to call the pop up menu
  20. Press down arrow in the keyboard to go to Deutschland
  21. Press Enter key in the keyboard. Now, the information of Germany is display in German
  22. Press Escape key to go back
  23. Press Escape key to quit the application
  24. Now reset the phone to English.   Choose Optionen
  25. Choose Sprache
  26. In Sprache:, click the Deutsch to show the pop up menu
  27. Choose English
  28. Press the Menu key
  29. Choose Speichem to save the setting. Now, everything will resume to English

For France, in the 9530.xml add the following lines under it :

<application>net.rim.blackberry.lang.fr</application>
Then, follow the similar steps as German to test the application.

BTW, I have tried the followings language but seems that 9530 simulator does not support them :

  • Netherland (net.rim.blackberry.lang.en_NL)
  • Traditional Chinese (net.rim.blackberry.lang.zh_TW)
  • Simplied Chinese (net.rim.blackberry.lang.zh_CN)


Saturday, November 22, 2008

Set Gmail as the default mail sending application in Firefox 3

There are many web sites having the standard emailto: protocol for you to directly email to the web site owner. For example, you can click this hyperlink to email to me. Traditionally, once you click this emailto link, it will call a pre-installed email software in your PC to open a email compose window for you to write and send email. But nowadays, with Firefox 3 we can use webware instead of software to handle this email matter. Firefox can use Gmail and Yahoo email to handle this mailto: protocol.

Here are the steps :

1. Make sure the mailto handler is turn on

  1. Open Firefox 3
  2. In the address bar, input about:config (If there is a friendly warning, simply accept it.)
  3. In the filter box, input network.protocol-handler.external.mailto
  4. Make sure the value is true. If it is false, double click it to toggle it to true. After setting it to true, the settings will be saved in the file %ProgramFiles%\Mozilla Firefox\defaults\pref\filrefox.js

2. Set Gmail as the default email application

  1. In the Firefox main menu, click Tools
  2. Click Options
  3. Click the Applications tab
  4. In the Search box, input mailto
  5. In the Action drop down box, choose Use Gmail
  6. Tick the check-box Remember my choice for mailto links

Now, Firefox will call gmail to handle the mailto: link.

As a reminder, sometimes, the mailto: link may be inside a frame of the web page. In this case, Firefox will switch to Gmail inside that frame. If that frame is too small, you have to :

  1. Right click the mouse button
  2. Click This frame
  3. Click Open Frame in New Tab
Then, the frame will be opened in a new tab for you to use Gmail to write and send email.


Friday, November 21, 2008

Gmail Themes

Today when I open gmail, there is a highlight conerning gmail theme. After reading my mails, I go to [ Settings > Themes ] to have a look. When I try it out, it is great.

After trying some themes, finally I choose the Phantasea. Its background is green and the theme is cool !

Together with color labels, this give a new look to my gmail.

For details of themes, please visit the official Gmail blog.


The volume of junk mail dropped drastically in 2008-11

After un-plug the servers of McColo Corp, the volume of junk email dropped drastically.

For details, please visit these URLs:

  1. Host of Internet Spam Groups Is Cut Off
  2. Unplugging The World's Biggest Spam Host-- Temporarily


How do you know an internal web server is up or down ?

Nowadays, setting up a web server for internal use in a company intranet is very common. But, sometimes when your browser reports that you cannot connect to the main page of your web server, what can you do ?

Here is some simple diagnostic steps (assuming that the web server IP is 10.20.30.40) :

1. Ensure that your PC can reach the web server machine

Try to ping the machine using :
ping 10.20.30.40
If you cannot ping the machine, maybe the machine is not up or may be there is a firewall to block the access to the machine.

If you can ping the machine, the machine is proved to be up and running and is connected to the network.

2. telnet using port 80

If you can ping the machine, the next step is to check whether you can visit the port 80 of the server machine. Type this command :
telnet 10.20.30.40 80
(Port-80 is the default web server listening port. If your server uses another port number, just replace 80 with that port number.)

If the telnet command reports any connection error like :
Connecting To 10.20.30.40... Could not open connection to the host, on port 80 Connect failed
, most probably the web server software is not up or there is a firewall blocking the port 80.

If you see the screen black out :
, congratulation, the web server is probably up and running !

To double confirm, just type this command :
get
If you see something like
<html> ..... .... ..... ...... ..... ............. .... .... Connection to host lost.
and then quit back to the command prompt, the web server is actually up and running. She try to send you a HTML pages.


3. Check your own PC

Steps 1 and 2 confirm that the web server is up and running. If your browser still cannot display the HTML page, the problem must be in the client side, i.e. your own PC.

Here are some suggested actions:

  • Check the personal firewall
  • Check the browser setting / options (e.g. check pop-up blocking)
  • If possible, try another browser
  • When Java related, look at Java console

Disclaimer :
All coding/commands in this article is distributed "as is" and is UNSUPPORTED.
NO WARRANTY of any kind is expressed or implied.
You use AT YOUR OWN RISK.
The author will not be liable for any data loss,damages, and loss of profits or any other kind of tangible or intangible loss while using or misusing this coding/commands.


Describe a SAS view

For SAS version 6.12 in unix, files with extension ssv01 are SAS views. For SAS version 8 and 9, the file extension is changed to sas7bvew (this also apply for Windows).
In my previous company, there are at least 2 types of SAS views. I will called one type as data step views, because the view is generated by a data step statement. Another type is referred as SQL-view which is actually a SAS view on DB2 table generated using a [ proc sql ] statement.
Both types of SAS view will have the same file extension. Therefore, by just looking at the file extension, you cannot know which type of view one is using.
Starting from SAS version 8 in AIX, the view generation source code is also included inside the sas7bvew file. Therefore, you can [ describe ] the sas7bvew file to find out how the view is generated.
But, you have to use different programming statements to [ describe ] the 2 types of views.
For data step views, the coding is :
data view=myLib.myView ; describe ; run;
For SQL-view, the coding is :
proc sql ; describe view myLib.myView ; quit;
On looking at the myView.sas7bvew file, how do you know which one of the two codings to be used ? This depends on whether there is some pre-defined file name naming standard in your company. If there is such a standard, you can tell by the file name. If not, simply use trial and error.

Alvin SIU
2018-11-21
Last Updated: 2020-04-04

Copyright/Licence Information:
All information and coding in this article is offered at no charge for NON-COMMERCIAL PERSONAL USE only.

This blog and the coding is copyright.
Reproduction of this blog and its coding in whole or in part in any form without the explicit written permission of the author is strictly prohibited.

Disclaimer:
All information in this article is distributed "as is" and is UNSUPPORTED.
NO WARRANTY of any kind is expressed or implied.
You use AT YOUR OWN RISK.
The author will not be liable for any data loss, damages, and loss of profits or any other kind of tangible or intangible loss while using or misusing wholly or partly of the information.

Wednesday, November 19, 2008

Convert Seconds to Hour-Minute-Second in Excel

Sometimes when doing time related calculation, the final values are in second.

For example, downloading a 369,300 byte file with a speed of 100 byte/second, the time required is 3693 seconds. Then, what is the hour-minute-second of 3693 seconds ?

Using Excel, there is a formula called time(). Put this formula into a cell :

=time(0,0,3693)

Then, format the cell with :

hh:mm:ss

The cell will display 01:01:33 (i.e. 1 hour 1 minute and 33 seconds).


Tuesday, November 18, 2008

Smooth Font Look Better in Windows XP

The font appearance in Windows XP for some LCD monitor under some resolution setting can be looked better by choosing the ClearType method to smooth the edge of fonts.

Here is the steps:

  1. Click Start
  2. Click Settings
  3. Click Control Panel
  4. Double-click the Display icon
  5. Click the Appearance tab
  6. Click the Effects button
  7. Check the box : Use the below method to smooth edges of screen fonts
  8. Choose the ClearType method


Saturday, November 15, 2008

Duplicate Tab in Firefox

I have used Firefox for a long time. Just wonder why there is no such thing as duplicating a tab. This action is similar to Ctrl-N to duplicate a window.

With Firefox 3 (actually I am using 3.0.4 today), when you right-click on a tab, there is still no such feature. However, there is really a duplicate tab functionality in Firefox 3. All you have to do is to :

  1. Hold the Ctrl key
  2. Drag the tab left or right. While moving around, an arrow will appear when crossing the border of the tabs.
  3. Then, when you release the mouse button, the tab will be duplicated and inserted in that border.
  4. Now, the last thing to do is to un-hold the Ctrl key.

If you make the above steps in another sequence :

  1. Hold Ctrl key
  2. Drag around
  3. Un-hold Ctrl key
  4. release mouse button
, this will move the tab in Firfox 3.0.4.
(Noted that in Firefox 3.0.6, you can simply drag-and-drop the tab in order to move it.)

Now, my wonder is : why don't just make the whole thing more simple ? Maybe just right-click on the tab to pop-up a menu to choose [ duplicate tab ]. Then, simply duplicate the tab at the rightmost. This is far most user friendly than the existing Ctrl-key-drag method.


Friday, November 14, 2008

Some Firefox Plugins

Today, I have to install the Firefox 3.0.3. Therefore, I have also to re-install those useful plugins. Here are them:

1. DowmThemAll 1.0.3

This plugin will add a menu in the Tool menu.

For first use, please remember to input the default file saving location.

Then, for any web page, simply choose [ dTa One Click! ] menu item from the [ Tools > DownThemAll Tools ] menu, all the images, etc will be saved to the default file saving location.

2. Linkification 1.3.5

Sometimes, some web page will display this string, e.g. http://www.orbis.org , as normal text, not a hyper link. You have to open a new tab, and then cut and paste the string into the address box.

This plug-in is very helpful. You simply highlight the text, and then right-click. A pop-up menu will be displayed and you can choose [ open selected link ] to open it.

I like to config this plug-in to open in a new tab.

3. PlainOldFavorites 1.0.1

This plug-in allows you directly use the IE Favorites inside Firefox. No need to do any import or export activities. After installing this plug-in, you will see the [ Favorites ] menu item just next to the [ Bookmarks ] item in the menu bar.

4. Dictionary Tooltip 1.3

This plug-in will search some predefined dictionary after you highlight a word. So far, all are English-English dictionary. You cannot config to use your prefer English-Chinese dictionary.

After installation, simply double-click a word will see a small icon (look like a book). Put the mouse over the icon will pop-up a dictionary content.

5. FastDic 0.2.7

This plug-in is helpful for using your own prefer dictionary. For my case, I have try the Yahoo and sina dictionary. They can give the meanings in Chinese.

This version 0.2.7 cannot be installed in Firefox 3.0.4 To make it happen, you have to follow this procedure (by outyarder on July 21, 2008 documented in the review comment section)

  1. Go on the 'See All Versions' page
  2. Right click on the latest version, then 'Save Link As...'
  3. on your computer, open the saved .xpi file with WinRar or something similar
  4. extract the 'install.rdf' file from the archive and open it in Notepad
  5. change em:maxVersion 2.bla bla to 3.*
  6. replace the 'install.rdf' file in the archive with this modified version
  7. drag the modified .xpi on Firefox and install it

After installation, config the option to use Alt - Click.

In the URL box, input the URL for calling the dictionary. For yahoo dictionary, input the following :

http://hk.dictionary.yahoo.com/search.html?s=$
For sina dictionary, input the following :
http://dictionary.sina.com.hk/p/word/$

At last, click OK to save.

Then, in any web page, you can press the Alt key and then click on any English word. Then, a new window will be pop-up by the sina dictionary with the meaning.

The shortcoming is that you cannot work on words inside a hyperlink string because by default Alt-Click a hyperlink will auto-download the URL. (BTW, Ctrl-Click will auto open hyperlink in new tab and Shift-Click will open in new window.)

6. OpenBook 2.0.1.1.

This add-on can allow you to resize the box when you bookmark this page. Also, it can show the bookmark tree immediately when you bookmark this page.


Thursday, November 13, 2008

Run my utility CLIST in SYSPROC library

In unix, I would like to put my helpful utilities inside a directory [ util ] under my $HOME. Then, I will put this directory as the first directory in the searching path like this:

export PATH=/home/alvin/util:$PATH

Putting this statement at in the .profile file, I can use my utilities every time when I login my korn shell.

In mainframe MVS, there is something similar.

Actually, every time when you logon the TSO ISPF session, there is a SYSPROC library allocated to your session. This SYSPROC is similar to the PATH variable in unix. This SYSPROC contains a list of partition datasets. Members inside these partition datasets are those command, CLIST or REXX which you can execute in the TSO session.

Usually, I will put my useful REXX or CLIST (e.g. QDEL as mentioned in my other post) inside a partition dataset named, e.g. ALVIN.MISC.CLISTLIB.

Some sites allow you to customize your login procedure. Then, I can allocate this ALVIN.MISC.CLISTLIB as the first dataset in SYSPROC.

However, some sites do not provide this customization. In this case, once you have successfully login the ISPF panel, you can run the following command :

CONCAT SYSPROC 'ALVIN.MISC.CLISTLIB' FIRST

This command will make ALVIN.MISC.CLISTLIB to be the first dataset in the SYSPROC library, just like putting /home/alvin/util as the first directory in the PATH in unix.

Noted that, if you omit the word [ FIRST ], the dataset ALVIN.MISC.CLISTLIB will be concat at the end of the datasets list in SYSPROC.

Comparing the two scenarios, SYSPROC corresponds to the PATH variable. Each allocated PDS datasets corresponds to the directories in the PATH. The PDS dataset members correspond to the files in the directories.


Tuesday, November 11, 2008

Display code snippets on the blog

Today when I display the CLIST on my blog, I find out that all the formatting are gone.

Searching the internet, the following article is found to be useful for displaying code snippets on the blog.
http://bguide.blogspot.com/2008/02/howto-add-custom-css-class-to-blogger.html

Following the method documented in the article, I setup a CSS class named mycode. Then, the CLIST code snippets can be displayed in good format.


Use CLIST to submit JCL to batch delete dataset

In mainframe MVS ISPF option 3.4 panel, one can easily delete a dataset. However, if the dataset is already migrated to tape, such a deletion will hold up your session until the dataset is recovered from taped.

To avoid this, I have written a CLIST (called QDEL) to submit batch job JCL to do the deletion. Using batch job, there is no need to wait for those migrated dataaset.

Also, tranditonally, one cannot delete tape dataset in the foreground ISPF 3.4. But, since QDEL will submit a JCL, it can delete tape dataset.

But looking at the coding, it can also delete alias. Sorry that I cannot remember what exactly it is because the CLIST is written more than 10 years ago and I am now no longer working in mainframe platform.

As far as I remember, using this QDEL, I can delete many datasets in the background using batch JCL. I do not need to care whether the dataset is a tape or not, or whether it is migrated, ... etc.

QDEL is one of my favorite utilities. I usually put it as a member of a CLISTLIB which is usually the first allocated dataset of SYSPROC.

Here is the CLIST QDEL :

PROC 1 INDD DEBUG DELETE GDG(N) GEN() CLASS(H) USER()
CONTROL NOFLUSH NOMSG
IF &DEBUG = DEBUG THEN CONTROL MSG LIST NOFLUSH CONLIST SYMLIST
/* ******************************************************************
/* Licence Information:
/* --------------------
/* This coding is offered at no charge for 
/* NON-COMMERCIAL PERSONAL USE only.
/* The coding is copyright.
/* Reproduction of this coding in whole or in part 
/* in any form without the express written permission 
/* of the author is strictly prohibited. 
/* ******************************************************************
/* Disclaimer : 
/* ------------
/* This coding is distributed "as is" and is UNSUPPORTED.
/* NO WARRANTY of any kind is expressed or implied.
/* You use AT YOUR OWN RISK.
/* The author will not be liable for any data loss,
/* damages, and loss of profits or any other kind of
/* tangible or intangible loss while using or 
/* misusing this coding.
/* ******************************************************************
/* NAME   : QDEL
/* PURPOSE: BATCH DELETE DSN
/* AUTHOR : ALVIN SIU
/* *******************************************************************
/* MDIFICATIONS:
/* -------------
/* 1. ADD FUNCTION TO DELETE ALIAS
/* 2. ADD DOUBLE CONFIRMATION "DELETE"
/* 3. FIX SMALL BUG ON ALIAS CHECKING
/* 4. ADD ENVIRONMENT SAVE/RESTORE AND QUITING
/*    IN ORDER TO HANDLE THOSE PROFILE-PREFIX
/* 5. DO NOT DELETE A MEMBER OF PDS
/*    BECAUSE DELETE DDNAME(MEMBER) WILL
/*    ACTUALLY DELETE THE WHOLE "DDNAME" DATASET
/* *******************************************************************
NGLOBAL PARM0
NGLOBAL OPREFIX
SET PARM0 = QDEL
SET MYDD = &STR(&INDD)

/* ---------------- */
/* SAVE ENVIRONMENT */
/* ---------------- */
SET OPREFIX = &SYSPREF
PROFILE NOPREFIX

/* ------------ */
/* DISPLAY HELP */
/* ------------ */
IF &STR(&MYDD) = &STR(?) OR &STR(&MYDD) = &STR(HELP) THEN +
DO
  CLEAR
  SYSCALL USAGE
  SYSCALL QUITING 0
END

/* ------------------------------- */
/* ENSURE CANNOT DELETE PDS MEMBER */
/* ------------------------------- */
SET LP = &STR((
SET RP = &STR())
IF &SYSINDEX(&STR(&LP),&INDD) GT 0 +
OR &SYSINDEX(&STR(&RP),&INDD) GT 0 THEN +
DO
  WRITE QDEL &INDD
  WRITE
  WRITE ERROR: CANNOT DELETE A MEMBER IN A PARTITION DATASET
  SYSCALL QUITING 20
END

/* ------------------- */
/* DOUBLE CONFIRMATION */
/* ------------------- */
IF &DELETE = DELETE THEN SET TMP = 0
ELSE DO
       WRITE QDEL
       WRITE ERROR: PLEASE ADD THE WORD "DELETE" AS A DOUBLE
       WRITE CONFIRMATION.
       SYSCALL QUITING 21
     END

/* ------------- */
/* REMOVE QUOTES */
/* ------------- */
SET QUOTED = NO
SET L = &LENGTH(&STR(&MYDD))
SET L1 = &L - 1
IF &STR(&SUBSTR(&L:&L,&STR(&MYDD))) = &STR(') THEN +
DO
  SET MYDD = &SUBSTR(1:&L1,&STR(&MYDD))
  SET QUOTED = YES
END
SET L = &LENGTH(&STR(&MYDD))
IF &STR(&SUBSTR(1:1,&STR(&MYDD))) = &STR(') THEN +
DO
  SET MYDD = &SUBSTR(2:&L,&STR(&MYDD))
  SET QUOTED = YES
END
IF &QUOTED = NO AND &OPREFIX ¬= THEN +
   SET MYDD = &OPREFIX..&MYDD
SET L = &LENGTH(&STR(&MYDD))

/* ------------------- */
/* FIND OUT THE SUFFIX */
/* ------------------- */
SET TMP = &STR(&MYDD)
SET I = 1
SET S = 1
SET J = -1
DO WHILE &I > 0
   SET I = &SYSINDEX(&STR(.),&STR(&TMP),&S)
   IF &I > 0 THEN SET J = &I
   SET S = &J + 1
END
IF &J = -1 THEN SET SUF = &STR(&MYDD)
           ELSE SET SUF = &SUBSTR(&S:&L,&STR(&MYDD))

/* -------------- */
/* CHECK IF ALIAS */
/* -------------- */
SET &SYSOUTTRAP = 1000
LISTCAT ENTRY(&MYDD) ALL
SET LINE001 = &&SYSOUTLINE1
SET &SYSOUTTRAP = 0
IF &STR(&SUBSTR(1:5,&STR(&LINE001 ))) = &STR(ALIAS) THEN +
     SET ISALIAS = Y
ELSE SET ISALIAS = N

/* ------------ */
/* CHECK IF GDG */
/* ------------ */
IF &STR(&GEN) = &STR() THEN SET J = 0
ELSE DO
       IF &GEN > 0 THEN +
       DO
         WRITE ERROR: INVALID OPTIONAL PARAMETER - GEN
         WRITE GEN SHOULD BE A NUMERIC GENERATION FOR GDG DATASET
         WRITE CURRENT VALUE IS <&GEN>
         WRITE BUT ITS VALUE SHOULD BE 0 OR NEGATIVE
         SYSCALL QUITING 22
       END
       SET MYDD = &STR(&MYDD(&GEN))
     END

/* ---------- */
/* SUBMIT JCL */
/* ---------- */
SET TMP1 =
IF      &ISALIAS = Y THEN SET TMP1 = ALIAS
ELSE IF &GDG = Y     THEN SET TMP1 = GDG
WRITE &PARM0 - DELETE &TMP1 DATASET &MYDD
SET XXX = &STR(//**)
SUBMIT * END($$)
//&SYSUID.D JOB (AAAAAA,BBBBBB),
//       '&SUBSTR(1:20,&STR(DELETE &SUF ))',
//       NOTIFY=&SYSUID,
//       CLASS=&CLASS,
//       MSGCLASS=X,MSGLEVEL=(1,1),
IF &USER ¬= THEN +
//       USER=&USER,
//       REGION=1M
&XXX
&XXX*******************************************************************
&XXX PURPOSE : BATCH DELETE DATASET
&XXX &STR(&MYDD)
&XXX JOB OWNER: &SYSUID
&XXX DATE : &SYSSDATE - &SYSTIME
&XXX*******************************************************************
&XXX
IF &ISALIAS = Y THEN DO
//DEL#ALIA EXEC PGM=IDCAMS
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
&STR( DELETE &STR(&MYDD) - )
&STR( ALIAS )
&STR(/* )
END
ELSE +
IF &GDG = Y THEN DO
//DEL#GDG EXEC PGM=IDCAMS
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
&STR( DELETE &STR(&MYDD) - )
&STR( GDG FORCE PURGE )
&STR(/* )
END
ELSE DO
//DEL#DD EXEC PGM=IEFBR14
//DD1 DD DISP=(OLD,DELETE,DELETE),
// DSN=&STR(&MYDD)
END
//
//
$$
WRITE JOB SUBMITTED
SYSCALL QUITING 0
END /* OF CLIST */


USAGE: PROC 0
/* ***************************************************************** */
/* PURPOSE: DISPLAY USAGE HELP
/* ***************************************************************** */
IF &OPREFIX = THEN SET PP =
          ELSE SET PP = &STR(&OPREFIX..)

WRITE &PARM0 - SUBMIT JCL TO DELETE A QSAM, A GDG BASE OR A GDG +
GENERATION
WRITE
WRITE EXAMPLE:
WRITE - &PARM0 MY.PROJECT.QSAM
WRITE DELETE THE QSAM DATASET '&STR(&PP)MY.PROJECT.QSAM'
WRITE - &PARM0 'MY.PROJECT.QSAM1'
WRITE DELETE THE QSAM DATASET 'MY.PROJECT.QSAM1'
WRITE - &PARM0 MY.PROJECT.GDGBASE GEN(0)
WRITE DELETE A GDG GENERATION '&STR(&PP)MY.PROJECT.GDGBASE(0)'
WRITE - &PARM0 MY.PROJECT.GDGBASE GEN(-1)
WRITE DELETE A GDG GENERATION '&STR(&PP)MY.PROJECT.GDGBASE(-1)'
WRITE - &PARM0 MY.PROJECT.GDGBASE GDG(Y)
WRITE DELETE A GDG BASE '&STR(&PP)MY.PROJECT.GDGBASE'
END /* OF PROC USAGE*/


QUITING: PROC 1 XCODE
/* ******************************************************************
/* PURPOSE: EXIT CLIST WITH ENVIRONMENT RESTORED
/* ******************************************************************
/* ------------------- */
/* RESTORE ENVIRONMENT */
/* ------------------- */
IF &OPREFIX ¬= THEN PROFILE PREFIX(&OPREFIX)

/* ---- */
/* EXIT */
/* ---- */
EXIT CODE(&XCODE)
END /* OF PROC QUITING */

With this CLIST, in the ISPF option 3.4 panel like this:

        ALVIN.PROJECT1.QSAM1                       DD1233
        ALVIN.PROJECT1.QSAM2                       DD1234
        ALVIN.PROJECT1.QSAM3                       DD1235
        ALVIN.PROJECT1.QSAM4                       MIGRAT
        ALVIN.PROJECT1.QSAM5                       MIGRAT
        ALVIN.PROJECT1.TAPE1                       T12345
        ALVIN.PROJECT1.TAPE2                       T12346
        ALVIN.PROJECT1.TAPE3                       T12347
I can do the following:
        ALVIN.PROJECT1.QSAM1                       DD1233
        ALVIN.PROJECT1.QSAM2                       DD1234
        ALVIN.PROJECT1.QSAM3                       DD1235
        ALVIN.PROJECT1.QSAM4                       MIGRAT
        ALVIN.PROJECT1.QSAM5                       MIGRAT
qdel / delete PROJECT1.TAPE1                       T12345
        ALVIN.PROJECT1.TAPE2                       T12346
        ALVIN.PROJECT1.TAPE3                       T12347
This will call QDEL to submit JCL to delete the tape dataset ALVIN.PROJECT1.TAPE1.



Alvin SIU
2008-11-11

Copyright/Licence Information:
All information and coding in this article is offered at no charge for NON-COMMERCIAL PERSONAL USE only.
This blog and the coding is copyright.
Reproduction of this blog and its coding in whole or in part in paper or digitally or in any other forms without the explicit written permission of the author is strictly prohibited.

Disclaimer:
All information in this article is distributed "as is" and is UNSUPPORTED.
NO WARRANTY of any kind is expressed or implied.
You use AT YOUR OWN RISK.
The author will not be liable for any data loss, damages, and loss of profits or any other kind of tangible or intangible loss while using or misusing wholly or partly of the information.

Friday, November 7, 2008

The Max Download Session Problem

Think about this story : there is a big data warehouse department in a company. The DW department unix machine has to download numerous files from various other departments in order to collect data to build the warehouse.

There is a situation that : for example, job script-1 will download file-A, file-B, file-C, file-D & file-E from department-1 of the company, Job script-2 will download file-F, file-G, file-H, file-I & file-J from department-2 of the company, similarly for job script-3, script-4, script-5, script-6 and so so. All jobs are inside the job database and are kick-out by the job scheduler in a monthly, weekly and daily basis respectively.

How to do the download ? Actually, the script will call a third party file transfer software.

For this situation, there are many outstanding questions :

Due to license issue, the third party file transfer software only allows a max download session of 4. If there are 6 scripts kick-out by the job scheduler, what will happen ? Can the third party file transfer software put the requests queuing ? Or, will it just turn down the all upcoming requests ?

How about, for example, job script-1 & job script-2 are monthly jobs, script-3 & script-4 are weekly jobs and script-5 & script-6 are daily jobs. The files in monthly job scripts (e.g. script-1 and script-2) are very large. They take a long time for transfer. The files in daily job scripts (e.g. script-5 and script-6) are relatively smaller, just a few hours or minutes are required. But, the daily job scripts have a batch running window of approx 24 hour only. They must finish the file downloading within one day. On the next day, there is a new daily batch. Can the third party file transfer software prioritize the transfer requests ? What happen when all the 4 downloading sessions are occupied by the files of the monthly job scripts ? Can the third party file transfer software let the daily job scripts to jump queue to do the downloading once a monthly file finishes its downloading ? If the transfer software only serves the request in a first-come-first-serve basis and the monthly job scripts appear first, all the monthly file transfer will be answered first. Then, the daily job scripts may face starvation.

What happen when the third party software is hang up ? Will the job scripts get notified ? Or, will the job script simply wait infinitely ? Will the human being production system support get alerted ?

When that third party file transfer software is down, what happens to all the downloading job scripts ? Can all the job scripts automatically switch to use another file transfer software ?

If the DW department wants to upgrade the third party file transfer software or to replace it by another software, will the job script affected ?

To tackle all these questions, one solution is to build a centralized file transfer request manager as an agent or a middle-man between the job scripts and the third party file transfer software.

First of all, the DW job scripts should not call the third party file transfer software directly. Instead, they will submit the file transfer requests to the file transfer request manager and then go sleeping. For example, job script-1 will submit the request of file-A, file-B, file-C, file-D & file-E to the manager and then go sleeping for 2 days. After 2 days, if all the 5 files are not received, the job script-1 should raise a non-zero return-code to the job scheduler to signal the production system support personnel, similarly for script-2. For script-3 and script-4, since they are weekly jobs, sleeping hour is only 1 day. For daily job script-5 & script-6, they can only sleep for a few hours. Each job script can control its own sleeping hours, depending on the average file transfer time of the job script.

On receiving the file transfer requests, the manager can then call the third party file transfer software to perform the actual file downloading.

Normally, the request is done in a first-come-file-serve basis. However, the manager can also allow daily jobs to jump queue. Daily jobs should have a higher priority always.

Also, the manager can control over the max file transfer session. If there are already 4 files performing transfer, the manager simply put all upcoming request queuing. Also, the manager can further control that each job can only occupy at most 2 file transfer sessions in order to avoid one single job to use up all the 4 sessions.

The manager should totally take care about the third party file transfer software. If the third party software is down, the manager should alert the human being production system support (i.e. PSS). After investigation, if the bug cannot be fixed shortly, this PSS can instruct the manger to switch to use another file transfer software. This is transparent to the DW job scripts.

For the handshaking between the manager and the job scripts, the manager to send signal to the job script to report whether the file transfer is successful or fail. When receiving a successful signal, the DW job script can do some post processing.

For example, when all the file-A, file-B, file-C, file-D & file-E are downloaded successfully, the manger can alert the job script-1. Another method is to let the job script-1 to count whether all the 5 files are downloaded, the manager does not perform the counting. When all the 5 files are downloaded successfully, job script-1 should wake up from sleeping (job script-1 sleeps at most 2 days). Then, job script-1 should give a zero return-code to the job scheduler to indicate job successfully complete so that the scheduler can kick-out job(s) in the downstream.

When there is a software upgrade, only the manger is affected. The DW job scripts are totally transparent.

Furthermore, the manager can be enhanced to classify and distribute requests to different multiple queues. The requests of some VIP DW job scripts can go to high priority queues which is always served first. Those requests from some can-be-wait job scripts should go to lower priority queues. Also, maybe different queues are using different third party file transfer software. Maybe some queues are using software for secured channel to provide higher security level with maybe slower performance.

By the way, although this article is talking about file downloading, everything can also be applied to uploading as well. In other words, this situation and the file request manager can actually handle both file downloading / receiving / pulling as well as file uploading / sending / pushing. There can be out-queues and in-queues in the manger.


Wednesday, November 5, 2008

Go to your Application Data folder

In Windows XP, there is a quick way to go to the application data folder of the current user.

  1. Click Start
  2. Click Run
  3. Then, in the box, type :
    %APPDATA%

Then, the a new explorer window will be opened to take you to

C:\Documents and Settings\XXXXXX\Application Data


Duplicate Open Current Folder in a New Window

Sometimes after I opened a folder in Win7, I would like to duplicate open the same folder again in another explorer window. Then, I can ope...