All Things Techie With Huge, Unstructured, Intuitive Leaps

Facebook Privacy Slip-up - Randi Zuckerberg Family Photo



Now isn't this rich with irony.  Randi Zuckerberg posts a private family photo to Facebook and the privacy policy doesn't protect it.  They were poking each other with the new Facebook Picture Poke.  The picture goes public and Randi is not pleased.  Randi is the former marketing chief of Facebook and should know better.

Inquiring minds want to know though -- where is the lovely Mrs. Mark Zuckerberg in this photo?  Maybe she and Mark are not into poking any more?  Just saying ..

Merry Christmas

Merry Christmas.  May all of your hardware and software dreams come true.

Looking to develop an Interest Engine

I exchanged emails with the founder of a startup, and we touched on the topic of linking internet content to personal interests.  This is one of the last frontiers of searches and delivering content.  A hell of a lot of money could be made if someone made a content delivery system from the web that was say, 80-90 percent right all of the time.  I suppose that the Semantic Web with it Resource Description Framework and Web Ontology Language might help, but that is a bit of pie in the sky, because there are millions if not billions of html pages already out there that will never be reworked.

So the work will have to come from the server side.  The search engines will have to get a hell of a lot better at context recognition.  However, my specific concern is matching your interests to web content. For example, suppose you listed your interest as cats.  There is the cat breeder who is interested in breeds of cats.  There is the charity who rescues cats.  Veterinarians need information on cat diseases and pharmacology.  Just putting in the word cats will create a lot of junk to sift through for each specific case.  This example is trivial because you could add another search term like "rescue" or "veterinary" etc.  But what if my interest is "neat stuff".  How would I create a machine language to search and deliver neat stuff content.

My research continues, but if you have any ideas, leave a comment.  Thanks.

Strange MySQL Error

Had a strange MySQL error:

ERROR 1033 (HY000): Incorrect information in file (table_name)

We couldn't log into our app.  It looked like the database connection wasn't happening.  The logs were useless.  All they said was that there was a null pointer exception for getting the data back from the database.

We have a Linux server, so I typed in the /etc/init.d/mysqld stop  and then issued the start command:

/etc/init.d/mysqld start .  It failed.  I did it again (stop and start) and it said OK.  I could log into the database.  I could show tables.  But when I went to select from the tables, I got the above error.

Nothing worked.  Finally I rebooted the server and it was fixed.  If anyone has an idea of what caused this, please leave a comment.

Data source rejected establishment of connection

It was frustrating. I set up a Java JDBC connection pool to MySQL, and the app ran for awhile, then it would not connect. Obviously I had leaking connections somewhere.

The message in the transcript log was:
Data source rejected establishment of connection, message from server: "Too many connections"

  I went and tried closing all of the connections, but the app is a fairly large one. What to do? I Googled around and there was no obvious way of seeing where the connection leak was, so I opted for brute force. The pseudo code for establishing a connection with at connection pool looks like this:

 DataSource ds=getDataSource();
 Connection conn=ds.getConnection();

and to close the connection, it was:

conn.close();

 So the way that I solved it and found the connection leak, was that I added a couple of lines to the above code.

In the open connection method, I added

System.out.println("Open Connection " + conn.toString();

and in the close method, before the close statement, I added:

System.out.println("Close Connection " + conn.toString();

It prints out stuff in the console like this:


Open  Connection ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@e78c1b]]
Close Connection ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@e78c1b]]

I then match up the open and closes as I do stuff, and find my unclosed connections leaks.

Hope this helps.


Javascript -- Round Number to nearest 100 -- Validate

I have this web page that is created by a jsp.  The user has to input an amount of money to make a bid, but I don't want the users entering silly amounts like $1098.66.  I want the amount to be in exact increments of $100.  So I have an input tag "<input tabindex='1' type='text' name='amt' id='amt' value='00.00'  size='10' />" and I want to validate and make sure that the number is an increment of $100.  When the user presses the submit button, I call onclick="javascript:validateAndSubmit()".

My validate and submit function is something like this:


var bestPrice = document.(insert Form Name).amt.value;
                //get rid of the dollar sign
var match= bestPrice.match(/[0-9,.]*/);
if (match!==null) {
                    //Make the number into a float
   var amount= parseFloat( match[0].replace(/,/g, '') ); 
                 //find out if the number is not in multiples of 100 using modulus
   var rem = amount % 100;
   if ( rem > 0)
    {
    alert("Your offer must be in multiples of $100.")
    }

Hope that this helps.

The Fastest And Slowest Emails among the big free providers

I use all of the big free email account providers like Gmail, Yahoo, GXM, Mail.com, hotmail, etc etc.  Regular readers know that I am a data privacy freak, so every time that I have to open an account and need an email address, I do not give out my gmail because it has my real name.  I have a whole stable of free accounts.  AND, when I am asked to give another account for password recovery (or mobile phone number for that matter), I never do.

So I conducted some latency tests to see who has the fastest and slowest email.  I sent all of the tests from a linux server using the sendmail facility.  The winner by far was Gmail.  The sent messages arrived the fastest by gmail.  The loser and slowest email account was Yahoo.  I am not surprised.

The only discordant note about the speed of gmail, is that I bet Google reads my email   The ads on my gmail folder prove it.

Setting Up JNDI JDBC MySQL Connection Pool in Tomcat

So it was time to set up a connection pool for our high concurrency application.  It seemed like an easy thing to do.  I went to avajava.com followed one of their instruction tutorials, and burned a whole afternoon debugging.  Tomcat 7 has connection pooling built in, so I figured it would be a walk in the park.  Man, I got the following list of errors:



  • org.apache.tomcat.dbcp.dbcp.BasicDataSource cannot be cast to org.apache.tomcat.jdbc.pool.DataSource
  • name is not bound in this context. unable to find 
  • java.lang.ClassNotFoundException: org.apache.tomcat.jdbc.pool DataSourceFactor
  • java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.BasicDataSource cannot be cast to org.apache.tomcat.jdbc.pool.DataSource
  • java.lang.ClassNotFoundException: org.apache.tomcat.jdbc.pool DataSourceFactory
After wasting a whole bunch of time, I finally got it to bind to the database resource, but I had an error with the login stored procedure.  It was this one:

  • mysql - java.sql.SQLException: Parameter number 3 is not an OUT parameter

I knew that I was getting some sort of binding but not a good connection.  Not knowing what I didn't know, I decided to do a debug on my connection called conn:

                       System.out.println(conn.toString());
System.out.println(conn.getCatalog());
System.out.println(conn.getAutoCommit());
System.out.println(conn.getMetaData().allTablesAreSelectable());
System.out.println(conn.getMetaData().getDriverName());
System.out.println(conn.getMetaData().getMaxConnections());
System.out.println(conn.getMetaData().supportsStoredFunctionsUsingCallSyntax());
System.out.println(conn.getMetaData().supportsStoredProcedures());
System.out.println(conn.getMetaData().allProceduresAreCallable());


It was quite an interesting transcript.  It told me that getMaxConnections() was zero, that allTablesAreSelectable was false, and allProceduresAreCallable() was false.  I spent a lot of time chasing down this dead end rabbit hole.

Finally I went to the expert:

http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency

I followed the instructions implicitly and voila -- every thing works:

Simple Connection Pool for MySQL

<Resource type="javax.sql.DataSource"
            name="jdbc/TestDB"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/mysql"
            username="mysql_user"
            password="mypassword123"
/>
The first thing we notice is the factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" attribute.
When Tomcat reads the type="javax.sql.DataSource" it will automatically configure its repackaged DBCP, unless you specify a different factory. The factory object is what creates and configures the connection pool itself.
There are two ways to configure Resource elements in Apache Tomcat.
Configure a global connection pool
File: conf/server.xml
<GlobalNamingResources>
  <Resource type="javax.sql.DataSource"
            name="jdbc/TestDB"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/mysql"
            username="mysql_user"
            password="mypassword123"
/>
 </GlobalNamingResources>
You then create a ResourceLink element to make the pool available to the web applications. If you want the pool available to all applications under the same name, the easiest way is to edit the File: conf/context.xml
<Context>
  <ResourceLink type="javax.sql.DataSource"
                name="jdbc/LocalTestDB"
                global="jdbc/TestDB"
/>
 <Context>
Note, that if you don't want a global pool, move the Resource element from server.xml into your context.xml file for the web application.
And to retrieve a connection from this configuration, the simple Java code looks like
Context initContext = new
 InitialContext();
   Context envContext  = (Context)initContext.lookup("java:/comp/env");
   DataSource datasource = (DataSource)envContext.lookup("jdbc/LocalTestDB");
   Connection con = datasource.getConnection();

Mister TomcatExpert is really an expert.



MySQL Connection Pooling with Java & Tomcat Tip

It is time we got serious with a webapp of my to quit setting up and tearing down connections to the mysql database.  I decided to implement a connection pool.  There are examples all over the web on how to do this.  Luckily, I am using Apache Tomcat 7 and it has the connection pooling built in.

So I was implementing the java code:


 import java.sql.Connection;
  import java.sql.ResultSet;
  import java.sql.Statement;

  import org.apache.tomcat.jdbc.pool.DataSource;
  import org.apache.tomcat.jdbc.pool.PoolProperties;

and the import was throwing the class not found error.  I thought "WTH -- I am using Apache 7".  As it turns out, I had to go to the properties, and add the Apache Tomcat Library (not the jars but the libraries) in the Project Build Path.  Problem solved.  Hope this helps someone.

Giving a user an anonymous ID programatically

We have a web application written in Java whereby when the users sign in, we want them to be anonymous to each other.  So what we do, is give them a number.  I needed an algorithm to generate the number from their database user id, and I wanted the algorithm to vary such that it wasn't that easy to figure out.

So what I do, is on even days of the month, the user id is added to the day of the month, and on odd month days, I take the absolute value of the day of month - the user id.


//get day of month

int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
//cast it to a double so that I can get a modulus 2 which indicates whether it is even or odd
double amem = (double) dayOfMonth;
if ((amem % 2) == 0) {       // it's an even day with no remainder
dayOfMonth = dayOfMonth + userId;
} else {
//its an odd day
dayOfMonth = Math.abs(dayOfMonth - userId);
}


Hope this helps someone.

Toshiba Laptop Mouse Won't Work

I was logged in via Remote Desktop to one of my Caribbean servers.  The browser window was being blocked by the Remote Desktop banner or task bar on top of the screen.  I couldn't close it.  So I Googled how to close an application window.  It said to press Alt + F4.

Well on this stupid Toshiba laptop with the weird keyboard, F4 also needs a function key press as well.  The normal key for F4 is to switch display modes when you are connected to a projector.

So I pressed Fn + Alt + F4 and my browser closed.  But I must have let go of the Fn key.  The cursor froze.  The mouse wouldn't work.   I am talking about the mouse on the finger pad.  It is a Synaptic pointing device.  So I shut down the computer and re-started it.  No dice.  I restarted in Safe Mode.  Still had a frozen cursor.  Took out the battery, and re-started it with the last good configuration.  Nada.

I figured that I had blown the drivers.  I went to another machine and did some googling.  It said that Toshiba had a mouse lock. It said to press Fn + F9.  I did.  Nothing happened.  I tried Fn + F4.  My cursor unlocked.

Hope this helps someone.  It sure wasted a bit of my time.

Virus Free For 5 Years -- Thanks Free Avira



Someone on a forum asked about trojans and viruses.  I posted the following:

My 5 cents on anti-virus:

We needed a computer to act as a server in Nassau. We went to the Radio Shack. It was a Radio Shack in name only. The guy paid the franchise fee and sold whatever he wanted. He was selling a brand new Pentium knock-off complete with Microsoft Office, Adobe Photoshop, Macromedia Director -- everything, The machine was just over $300, and with those software packages, it should have been over $2000.

I brought it back to the office, plugged it in, and every single machine on the network alarmed about spyware, trojans and viruses trying to get in. It turns out the software was crack software from China, embedded with viruses.

The machine was so virus laden, that the browser was hijacked. You couldn't physically go to many anti-virus sites. I download a virus killer onto a USB stick, and ran it from there. That gave me my browser back. But every single machine in the network was still alarming. I used a router to create a subnet to isolate the machine, and I went to work.

We had a bought copy of Norton and MacAfee. That didn't do the trick. We downloaded everything, and still couldn't get a clean machine. I removed all of the software -- Microsoft Office, Adobe Photoshop, everything. Finally there was one free on that worked. It was the free version of Avira out of Germany. I have that on all of my machines today, and it performs wonderfully. It blocks even the most sophisticated attempts to get in.

And then on top of that, I started using Google Chrome exclusively. The infection rate went to zero. 

Since I am a data privacy advocate (I quit Linked In and Facebook), I went to the free Google Chrome store and downloaded tracking cookie blockers. Some of them don't let me buy on Expedia, but when I have to use online shopping and it doesn't work, I temporarily turn them off from icons in the tool bar.

Since I have the free version of Avira, every day I get a huge pop-up with an ad from Avira. I can live with that because it lets me sleep nights. I earn my living with my computer, and I have to protect my digital assets. Speaking of which, you should go to the store, buy a cheap USB key and put your digital books on it. Then put the key in a safety deposit box or in another location other than your house.


I have been trojan and virus free for five years.  Thanks Avira.

Linux Sendmail Not Working

It's real easy to send email using a linux server.  We have an app where we need to send notification details to our users so we send it via the linux server that is already running Apache Tomcat.

Since the details and notifications go beyond the simple, we use java to write the details to a temp file, get the email address from the database, invoke a bash shell to send the mail and then delete the temp file.

Here is how its done.



String messbody = (new StringBuilder(String.valueOf(messbody)))
.append("Please log into www.mydomain.com to see the latest things on your account.").toString();

Then I generate a random file name by assembling a bunch of random characters:

int rancharacter = 65 + (int) (Math.random() * 90);

char ck = (char) rancharacter; 
String fnum = String.valueOf(ck); 

I did the rancharacter many times to generate a random string.  I created a linux directory where this would be written to.  It is in /home/messages.



String longfileName = "/home/messages/" + fnum; 
 File f = new File(longfileName); 
 try {
 BufferedWriter bout = new BufferedWriter( new FileWriter(longfileName)); 
 bout.write(messbody);
 bout.close(); 
 } catch (IOException e)
 { System.out
 .println("Writing email file exception");
 System.out.println("Exception " + e.getMessage()); }

Now that I have a file, I wrote a very little bash script called mailer, put it in the /bin directory and did a chmod so that it could be executed.  The bash script looks like this:


#!/bin/bash
IFS=":-;"
#FILE= "/home/messages/$3"
#echo $(basename "$2")
mail -s $(basename "$2") $(basename "$1") < /home/messages/$(basename "$3")


The only thing life to do, is to create a subject, get the email, get the runtime so that one can execute a linux command, and send the email.

Here's some code:

String emailAddress = email;   //previous declared variable that went to the database
 String subject = "Account_Notification";  //I had to put the underscore to eliminate space problems
 String messBody = fileName; 
 String cmd = "mailer" + " " + emailAddress
 + "  " + subject + " " + longfileName; 
  // get the linux runtime to execute the command
 try { Runtime run
 = Runtime.getRuntime(); Process pr = run.exec(cmd);
 pr.waitFor(); BufferedReader buf = new
 BufferedReader( new InputStreamReader(
 pr.getInputStream()));
 
 } catch (Exception fu) {
 
 System.out.print(fu.getMessage()); } 
 boolean success = f.delete();

OK - all of this was working.  Then I changed the message body and it stopped working.  What caused it to stop working.  In the body of the message, I put java.util.Date.toString();

That would stop Centos linux from mailing.  Weird.  I hope that this helps someone.



A Whole Bunch of MySQL Stuff

Had a major event today on our server.  MySQL took the server down.  It was the daemon mysqld.  It started to spike the memory, which started the system to page furiously and then we had a kernel dump.  Went to /var/log/messages and grepped for “memory” and saw that UID27 reported out of memory as part of the crash output.  The message was

 [ERROR] /usr/share/mysqld: Out of memory (Needed xxx bytes)

So what to do?  Obviously we didn't have enough RAM allocation.  I use entirely an innodb engine with mysql.  So I had to find where mysql was getting its configs from.

From the server console, I typed in:

mysql --help

and among all of the stuff that was returned, it told me where to look for the config file.  It said:


Default options are read from the following files in the given order:
/etc/my.cnf ~/.my.cnf

So I went to /etc/my.cnf and used the vi editor.  I added

innodb_buffer_pool_size = 1000M

I added it under [mysqld].  We have 4 Gigs of RAM and the allowable value is up to 80% of the RAM.  Previous to this it was 16M.

Then I stopped the database by issuing the following command:

/etc/init.d/mysqld stop

No issues.

To start it, I issued

/etc/init.d/mysqld start

and it failed.  This is what it said:


[root@ap1 etc]# /etc/init.d/mysqld start
Timeout error occurred trying to start MySQL Daemon.
Starting MySQL:                                            [FAILED]

Well, went back to /etc/my.cnf and I noticed that I had forgotten the "i" in the innodb_buffer_pool_size.  I added that, and it started.

I gotta tell you, the application now screams!!  I should have done a RAM allocation earlier.




Making Effective Online Ads



Everybody sells at one time or another. We sell ourselves to our dates. We sell ourselves to our prospective employers. We sell stuff on the internet. There is a lot of clutter out there, and when we have something to sell, we must get ourselves to stand out above the clutter.

If you have to create an ad, or a webpage or any online presence, then this eBook is for you. It is the Top Secrets of the Admasters. It teaches you how to make the most effective online ads and web pages. It tells how to make ads that people cannot resist clicking on.

The psychology and layout of an online presence is important. This book show you how to use color, subject matter, trusted colors, the 9 elements that your ad must have and other helpful tips to rise above the noise and get noticed on the web.

Buy it here on Amazon Kindle:  http://www.amazon.com/dp/B009XHPIYE

Major UIX Tip -- It's Black and White

If you ware a regular reader of this blog, you know that I have several blogs, and I am constantly experimenting with them as to optimal design to generate the most hits, the greatest user experience and the best UIX or user interface experience.

I decided to experiment with stickability -- how long visitors to the site would stick around for content other than that what brought them there in the first place.  I took two relatively popular blogs, and had one with a black background and one with a white background.

The white background blog continuously outperformed the black one.  After a month, I switched it.  The one that was previously black and now white, suddenly became popular again with more hits.

No one needs more black and white evidence than this.  I had previously opined that a black background on a mobile device acts like a mirror, and that a white background was better.  That was a subjective feeling before.  It appears that it is also an empirical observation now.

New Revenue Stream for Photoshop Gurus

Self publishing on Amazon with eBooks is now a big thing.

I was reading an online forum for that topic and the author of the above book idly wondered online as to whether Brits hated her because she wasn't getting sales in the UK.  Her book had a cover of the heroine in a bar scene that was drawn for the cover.

I opined that perhaps the UK reader had cultural anomalies that made them hard to identify with the American bar scene.  The author replied that she was considering changing the cover.

It occurred to me that a photoshop person could make some serious cash by doing covers for authors.  Then I discovered that they were.  There was some guy selling stock photos for $20 with the title and author added with the photoshop text tools.  Others were selling covers for up to $299 per cover.  Photoshop gurus, here is another revenue stream for you.

A real graphics designer with a creative flair could probably make more money doing covers than the authors were making writing the books.

Just as an exercise tonight, I idly wondered how I would re-design the cover of Ms. Alroc's book called "Strangely Sober".  Knowing that sex sells, I photoshopped the above cover just as an exercise.  Ms. Alroc didn't ask for this and is unaware that I am doing this.  I just did it to see how my design effort would turn out.  I will certainly notify her that I have done this, and I will remove it if she requests it.

And if you are a Kindle reader, please buy her book:  http://www.amazon.com/Strangely-Sober-Essa-Alroc/dp/1478341467/ref=la_B008QN3FX2_1_1?ie=UTF8&qid=1350875121&sr=1-1

Thanks.

How to split a .war file or a .zip file


I had a problem.  I remotely manage some coders 800 miles away.  I am getting them up to speed with j2ee, jsps, java, pojos and such.  I needed to get a .war file to them to deploy on a test server.

I used Eclipse to make my war, and when I went to send it to them, the size of the file was 34 megabytes.  I am only allowed 25 megabytes with my email program as an attachment.

What makes a war file big, are the jars in the lib directory.  I could have pulled them out and sent them separately, but my programmers are junior programmers and I wanted a no-muss, no fuss solution.  I needed a free file splitter.

So I went to http://www.filesplitter.org/ and downloaded FreeFileSplitter.  I broke my war file into 18 mb chunks, and sent my guys two emails each with a chunk attached.

They downloaded FreeFileSplitter on their end.  It doesn't even have an installer.  It is just a very small binary that sits on the desktop.  They joined the two chunks together and deployed the war.

Thanks very much to FreeFileSplitter.  It works like a charm.  It will split and reassemble any kind of file including zip and media files.

How To Prevent Hack Attacks and Cyber Attacks From Iran

I just read that American Banks and other companies are under cyber attack sponsored by the government of Iran.

If I were the CIO, CTO or the IT management type responsible for American banks, financial institutions, energy companies, or major (and not-so-major) corporations, I would call in my network administrators and system administrators and have them write firewall rules blocking everything from Iran. If there is an economic embargo, there should be an internet embargo as well.

As a public service, here is a list of IP addresses to write the firewall wall rules preventing any access at all from Iran.

 Major IP Address Blocks For Iran


From IPTo IPTotal IPsAssign DateOwner
62.60.128.062.60.255.2553276813/06/2001Iranian Research Organization for Science & Technology
62.193.0.062.193.31.255819217/07/2000DP IRAN
62.220.96.062.220.127.255819225/10/2001Soroush Audio Visual Company
77.36.128.077.36.255.2553276812/03/2007IRIB (Islamic Republic of Iran Broadcasting)
77.77.64.077.77.127.2551638421/02/2007Rayaneh Danesh Golestan
77.104.64.077.104.127.2551638407/10/2008Respina Networks & Beyond
77.237.64.077.237.95.255819201/02/2007Respina Networks & Beyond
77.237.160.077.237.191.255819206/02/2007Parsun Network Solutions
77.245.224.077.245.239.255409607/05/2007Research Institute Of Petroleum Industry
78.38.0.078.39.255.25513107219/03/2007Information Technology Company (ITC)
78.109.192.078.109.207.255409617/07/2007Afranet
78.110.112.078.110.127.255409609/08/2007TSTonline co.
78.111.0.078.111.15.255409627/08/2007Neda Rayaneh
78.154.32.078.154.63.255819217/07/2007Arya Sepehr Ettelarasan Tehran
78.157.32.078.157.63.255819228/08/2007Fanava Group
78.158.160.078.158.191.255819206/09/2007Arya Sepehr Ettelarasan Tehran
79.127.0.079.127.127.2553276817/09/2007AsiaTech Inc.
79.132.192.079.132.223.255819202/10/2007Morva System Company
79.175.128.079.175.191.2551638412/11/2007Afranet
80.66.176.080.66.191.255409609/06/2004University of Tehran Informatic Center
80.69.240.080.69.255.255409603/04/2009ir.pasargad
80.71.112.080.71.127.255409618/01/2005Neda Rayaneh
80.75.0.080.75.15.255409619/06/2001Afranet
80.191.0.080.191.255.2556553623/07/2002Information Technology Company (ITC)
80.242.0.080.242.15.255409627/04/2009AFROOZ Etela Resan Company Ltd
80.253.128.080.253.143.255409613/12/2001Azadnet Resaneh
80.253.144.080.253.159.255409628/05/2002Azadnet Resaneh
81.12.0.081.12.127.2553276827/05/2002Soroush Audio Visual Company
81.28.32.081.28.47.255409617/04/2002IsIran
81.28.48.081.28.63.255409622/12/2004IsIran
81.29.240.081.29.255.255409617/06/2009Pardis Ettela Resaan Sepehr
81.31.160.081.31.175.255409603/06/2002Sharif University Of Technology
81.31.176.081.31.191.255409608/12/2003Sharif University Of Technology
81.90.144.081.90.159.255409604/01/2006Afranet
81.91.128.081.91.143.255409618/07/2002DATAK Internet Engineering, Inc
81.91.144.081.91.159.255409626/09/2002DATAK Internet Engineering, Inc
82.99.192.082.99.255.2551638412/12/2003Pars Online
82.115.0.082.115.31.255819206/01/2004Parsun Network Solutions
83.147.192.083.147.255.2551638414/06/2007Oracle Investment Group.
84.47.192.084.47.255.2551638418/10/2004Parscyberian Consultants
84.241.0.084.241.63.2551638410/06/2004Aria Rasana Tadbir
85.9.64.085.9.127.2551638411/02/2005Pishgaman Kavir Yazd Cooperative
85.15.0.085.15.63.2551638419/04/2005Aria Rasana Tadbir
85.133.128.085.133.255.2553276806/12/2005Sepanta Communication Development Co. Ltd
85.185.0.085.185.255.2556553625/11/2004Information Technology Company (ITC)
85.198.0.085.198.63.2551638431/01/2005TSTonline co.
86.109.32.086.109.63.255819205/07/2005Azadnet Resaneh
87.107.0.087.107.255.2556553622/08/2005Soroush Audio Visual Company
87.247.160.087.247.191.255819223/11/2005Neda Rayaneh
87.248.128.087.248.159.255819226/08/2008CallWithMe
89.144.128.089.144.191.2551638427/01/2006ANDISHE SABZ KHAZAR CO. P.J.S.
89.165.0.089.165.127.2553276801/03/2006Neda Gostar Saba Data Transfer Company Private Joint Stock
89.221.80.089.221.95.255409629/09/2006Fanava Group
89.235.64.089.235.127.2551638430/05/2006Azadnet Resaneh
91.98.0.091.99.255.25513107211/09/2006Pars Online
91.184.64.091.184.95.255819211/10/2006DATAK Internet Engineering, Inc
91.186.192.091.186.223.255819210/11/2006Oracle Investment Group.
92.50.0.092.50.63.2551638417/12/2007Shahrad Net Company Ltd.
92.61.176.092.61.191.255409602/01/2008Arian Rasaneh Pars
92.62.176.092.62.191.255409625/01/2008ir.pasargad
92.242.192.092.242.223.255819208/01/2008Respina Networks & Beyond
93.110.0.093.110.255.2556553624/04/2008Laser Company Ltd
94.74.128.094.74.191.2551638414/07/2008Farahoosh Dena
94.101.128.094.101.143.255409615/08/2008AFROOZ Etela Resan Company Ltd
94.101.176.094.101.191.255409621/08/2008Jahan Negar Parsian
94.101.240.094.101.255.255409626/08/2008AFROOZ Etela Resan Company Ltd
94.139.160.094.139.191.255819226/11/2008DATAK Internet Engineering, Inc
94.182.0.094.183.255.25513107217/09/2008Aria Rasana Tadbir
94.184.0.094.184.127.2553276811/08/2008I.P.M
94.184.128.094.184.255.2553276815/07/2009I.P.M
94.241.128.094.241.191.2551638430/09/2008Oracle Investment Group.
95.38.0.095.38.255.2556553611/12/2008Fanava Group
95.80.128.095.80.191.2551638425/11/2008Bozorg Net-e Aria
95.81.64.095.81.127.2551638404/06/2009Hamara System Tabriz Engineering Company
95.82.0.095.82.63.2551638408/12/2008Shahrad Net Company Ltd.
95.82.64.095.82.127.2551638411/12/2008kara amin ertebat
95.142.224.095.142.239.255409611/08/2009Armaghan Rahe Talaie
188.34.0.0188.34.255.2556553619/03/2009Asre Enteghal Dadeha
188.75.64.0188.75.127.2551638424/08/2009homatelecom
188.118.64.0188.118.127.2551638422/06/2009University of Tehran Informatic Center
188.121.96.0188.121.127.255819211/05/2009Jahan Negar Parsian
188.121.128.0188.121.159.255819211/05/2009TSTonline co.
188.126.128.0188.126.159.255819223/07/2009Arian Rasaneh Pars
188.136.128.0188.136.255.2553276815/05/2009Ariana Gostar Spadana
188.158.0.0188.159.255.25513107209/06/2009Neda Gostar Saba Data Transfer Company Private Joint Stock
194.225.0.0194.225.255.2556553629/12/1995I.P.M
195.146.32.0195.146.63.255819222/07/1997Information Technology Company (ITC)
212.16.64.0212.16.95.255819229/05/2008Farhang Azma Company Ltd
212.33.192.0212.33.223.255819215/07/2008Fanavaran Ettelaaat Dibagaran Karaj Co. Ltd.
212.50.224.0212.50.255.255819223/05/2008Rasaneh Esfahan Net
212.80.0.0212.80.31.255819227/05/2009Farhang Azma Company Ltd
212.95.128.0212.95.159.255819227/04/2009Parsun Network Solutions
212.120.192.0212.120.223.255819227/05/2008Hamara System Tabriz Engineering Company
213.176.0.0213.176.31.255819208/12/1999Iranian Research Organization for Science & Technology
213.176.32.0213.176.63.255819225/07/2000Iranian Research Organization for Science & Technology
213.176.64.0213.176.127.2551638401/02/2000Iranian Research Organization for Science & Technology
213.195.0.0213.195.63.2551638421/04/2009Arya Sepehr Ettelarasan Tehran
213.207.192.0213.207.255.2551638407/11/2002DATAK Internet Engineering, Inc
213.217.32.0213.217.63.255819219/02/2001Pars Online
213.233.160.0213.233.191.255819204/04/2003Sharif University Of Technology
217.11.16.0217.11.31.255409621/11/2002Afranet
217.24.144.0217.24.159.255409620/03/2003Parscyberian Consultants
217.25.48.0217.25.63.255409624/03/2003IRNA
217.64.144.0217.64.159.255409601/04/2009Aka Networks
217.66.192.0217.66.207.255409607/11/2000Neda Rayaneh
217.66.208.0217.66.223.255409602/02/2001Neda Rayaneh
217.146.208.0217.146.223.255409626/04/2004Neda Rayaneh
217.172.96.0217.172.127.255819211/02/2004Parscyberian Consultants
217.174.16.0217.174.31.255409626/03/2004National Iranian Oil Company
217.218.0.0217.219.255.25513107203/04/2001Information Technology Company (ITC)
Source:  http://www.nirsoft.net/countryip/ir.html

Come to think of it, I should do this with China too.  It is ironic that the minute that I deploy a new server, I start getting clever scripted hack attacks from institutions in China, like the meteorological institute.  I think that firewall blocking from unfriendlies, should be the first step in protecting your digital assets.


 

Buddha of the Binaries ~ Zen of Software Development~ Noble Truth #3


Oh Buddhist of the Binaries, I desire more lessons, what is the third noble truth?

Well my little code monkey with the red ass,  the third noble truth is that bugs in software  can be overcome and apps become killer and happiness can be attained; that true happiness and contentment are possible. lf we give up useless kiddie scripting and learn to code Java classes and jsps each day at a time (not dwelling in the past or the imagined future) then we can become happy and free. We then have more time and energy to help take our company viral. This is Nirvana.

One must learn to write elegant, simple profound code that supplies a desired need among the software addicts of the world.  Your code must become the crack cocaine of the mobile device.

For the other lessons, click HERE (and send money!)


How To Resize and Rename Photos

I had a problem.  I had to send a kajillion pictures to a person.  They were taken with a high resolution setting on the camera.  All of the photos were too large to be sent by email.

Usually when I have just a few, I open them in GIMP and resize the image.  This was a whole folder full of photos.

I searched the web for a free resizer and PhotoResize400.exe came up.  I gave it the college try.  I downloaded it from here:  http://www.rw-designer.com/picture-resize  and to my surprise, it wasn't zipped or anything.  The binary executable loaded directly onto the desktop.

I then separated out the pics that I wanted into a new folder on the desktop.  Then I closed the folder, grabbed it by selecting it, and drag and dropped it on the PhotoResize400.exe icon.  As quick as you could say "Gee I wonder if this works|, it was done.  I took a peek inside the folder, and sure enough it was done.

It preserved the original pics, and next to it, made a newer smaller version labeled -400.jpg.  (If the original pic was name 100234.jpg, it renamed it to 100234-400.jpg).  So now, it was a pain in the rear to separate them.  I decided to use DOS to do it.

I opened a RUN command shell and changed directory (cd command) to my desktop.  Then I did a directory listing (dir).  All of the photos were name September12-00x.jpg and the smaller ones were named September12-00x-400.jpg.

To separate them out so that the listing would group the smaller ones together, I had to do a DOS rename. It was easy as pie.  I typed in rename September12*-400.jpg  resized*.jpg in the cmd window.

What this did was rename the September12-00x-400.jpg to resized-00x-400.jpg.  The 00x was an incremental number (01, 02,03) so the numbering was preserved, it just took out the September12 prefix, because even the big ones (unresized) started with that prefix and they were a pain to separate.  Now all of the unresized ones started with September12 and all of the small ones started with resized.  When you did a directory listing or explored the folder, they were all neatly grouped into large and small by name.

As a product review, I fully recommend PhotoResize400.exe.  The photos are a little small for my liking, but it let me send a whole pile through the email.

Anonymous Email? What is the Best?

I was idly wondering about sending an anonymous email, so I plugged the term into good old Google.  The first site that came up was:

www.sendanonymousemail.net


I have a couple of throwaway email accounts (everyone should have a couple of them that cannot be tied to you) and send two from that page.  That was 5 hours ago.  No email has arrived at any of my email boxes from them.  Things that make you go hmmmmm.

Then I ended up at:

send-email.org

Well, within 20 minutes the test email arrived.  So I would say that send-email.org is the best out of the two.

When the email arrived, it said that it was from Free Email Service and the return address was: info@send-email.org

That works for me.

Then I got to thinking ...........  ..............

suppose that I was an intelligence agency, FBI, law enforcement, private investigator, criminal, blackmailer or a news organization.  I would set up one of these things to collect information and see what comes in.

That thought was enough to scare the crap out of me.  Its now back to sending emails from a Linux command line for me.

Update:  It is now 16 hours and the emails from sendanonymousemail.net still have not yet arrived.  This service is definitely not to be relied on.

Update II - I think that sendanonymousemail.net is a scam.  My test emails still haven't arrived a full day and a half later, and they probably never will.

java.sql.SQLException: After end of result set





I had to google this exception thrown because I had never encountered it before:

java.sql.SQLException: After end of result set


It turns out that I had called ResultSet rs.next() twice.  The second time it was after the end of it.  It was a careless dumb coding error.

Simple yet dumb error.   Hope this helps.

Thread: java.net.SocketException: Too many open files

Running my tomcat app on a Centos machine.  I looked at the logs and saw this error:

Thread: java.net.SocketException: Too many open files

Bummer.  I opened up a putty ssh to the server and did an su to superuser.  I wanted to see what the hard limit was for open file handles

I typed in at the bash#    ulimit -Hn and the return value was 1024,  Not good.

I issued the command to up the hard limit to 10000.  The command was ulimit -Hn 10000.

The soft limit was 1024 as well.  I upped the soft limit to 5000 with the command:  ulimit -Sn 5000

From what I could gather, this problem started happening when I initiated a log4j logger and we started getting decent traffic.

Hope this helps.

Java - How to make an arraylist of arraylists

I had to make an arraylist of arraylists.  The reason that I was doing this, was that I had to eliminate duplicates from a resultset.  The easiest way to do this was to put the resultset into an arraylist so that I could operate on it, because you can't iterate or use a resultset twice in Java.

Here are a few examples of the constructors to make an arraylist of arraylists:

   ArrayList<ArrayList<Object>> allData = new ArrayList<ArrayList<Object>>();

 ArrayList<ArrayList<String>> allString = new ArrayList<ArrayList<String>>();

 ArrayList<ArrayList<int>> allInts = new ArrayList<ArrayList<int>>();


Easy once you know how.

CNN Website Error

(click for larger image)

This has all happened to us at one time or another.  We have deployed a website and have forgotten to validate the tags.  When we visit the website live, we find the above junk printed.  It is actually the tag code that wasn't interpreted but rather rendered as text due to a missing element.

One of the easiest ways to avoid website validation errors is to go to the following URL:

http://validator.w3.org/

and enter the URL.  It will identify any tag errors.

I am just amazed that a large organization like CNN who lives and dies by their online presence would make such newbie mistakes.

Java String MySQL Error

I just spent an hour banging my head against a wall.  I constructed a mysql query string from variables.  So my string construct would look like this:
String quality = "Very Good";

String queryString = "Select  * from products where consumer_rating=" + quality;

The thing kept bombing.  It said that I had an sql error near where consumer_rating=Very Good.

It all looked kosher.  I had forgotten that a string value needs single quotes.

In other words, I should have declared quality =" 'Very Good' ";

Notice the single quotes after the double quotes.  Necessary for an sql statement for string injection.

Hope this helps someone save some time.

Adding A New Development Dimension ~ Mac

After visiting clients in the tropics (did I mention that I have developed software for high net worth individuals), I have come to the conclusion that being a straight Windows developer is a path to oblivion.  I have to take the plunge and develop for iPad and Mac.

If you try and download the Mac SDK on a Windoze machine, the downloader detects it.  So you really need a Mac.  Because I split my time between North America and the tropics, I had to get a laptop for uninterruptability.  So MacBook Pro it is.  I always try to develop for one generation behind the curve, so you see that the iPad is a slightly older iPad.

Here is a usage tip -- it turns out that geezers with money are now travelling with iPads.  They can read their email, they can review documents and they can get their entertainment, news and stock quotes.  They do not travel with laptops any more.  I have to cater to that market.

So in upcoming posts, I will start relaying tips on my Mac development experience.  Stay tuned.

(And for the meta-data collectors -- add one more developer converted to Mac.  Microsoft is truly dead man walking, as is Facebook.)

invalid server's version String Tamirsharpssh


I was using the Tamirsharp or SharpSSH library in a demo that I was doing.  I was in a hotel lobby business area and I kept getting an connection error:  "invalid server's version String".  Google wasn't that helpful.  I was defecating bricks trying to resolve this.

I couldn't possibly imagine what was wrong.  I got a valid connection a few hours earlier from a different location.  We remoted desktopped to the server, and everything was running fine.  Our ssh daemon was cygwin d and we rebooted that for good measure.

Couldn't understand what the problem was, until it dawned on us.  The hotel IT network was blocking the ssh/ssl ports.  Moved away from the hotel network and everything worked fine.  It did cause a few anxious moments though.

Search Engine Use As an Intelligence Indicator

Can your choice of search engine show your intelligence levels? Judging by my overnight blog statistics, I'd say yes. First of all, look at the chart for the dummies:

Dummy Usage of Search Engine:

(click for larger image)

Did you notice the top search engine by far? It was Microsoft's Bing. And do know that the search term was. It was "Kate Middleton Topless". And Bing is the dummy winner by far.

Now lets examine smart folks usage of search engines:

Intelligent person's usage of a search engine:

(Click for larger image)

The search engine results are for this software and concepts blog that 85% of the world doesn't understand. The intelligent people coming to this blog, by far use Google.

So, let's just say that Bing has a higher usage among those looking for less intelligent subject matter. The numbers don't lie, and the difference is dramatic.

So take a look at your blog statistics. If a majority of your search traffic comes from Bing, well the term "lowest common denominator" comes to mind.

Update of Browser Types and Operating Systems on the Internet

What is the most popular Browser? Easy -- Chrome. I have a popular blog, and today I have a crapload of hits. Here is what Google is telling me about my blog traffic browsers:

Chrome
  • 1,511 (27%)
Internet Explorer
  • 1,438 (26%)
Firefox
  • 1,424 (25%)
Safari
  • 693 (12%)
Mobile Safari
  • 161 (2%)
Apple-PubSub
  • 143 (2%)
Opera
  • 89 (1%)
BingPreview
  • 25 (<1%)
Mobile
  • 24 (<1%)

And as for operating systems, here are todays stats:



Windows
  • 3,843 (71%)
Macintosh
  • 658 (12%)
Linux
  • 355 (6%)
iPhone
  • 150 (2%)
iPad
  • 134 (2%)
Android
  • 131 (2%)
BlackBerry
  • 47 (<1%)
Other Unix
  • 17 (<1%)
Windows NT 6.1
  • 15 (<1%)
iPod
  • 22 (<1%)
chromeframe
  • 10 (<1%)

I have no idea what chromeframe is. The biggest surprise is that there is still Windows NT6.1 out there.

So if you want a snapshot of what people are using to surf and crawl the web today -- there you have it!

Facebook Inc. (NASDAQ:FB) Accounts Illegaly Used to Gather Secret Information, Report | News Today Digest


Fake Facebook Inc. (FB) accounts are being illegally used to gather secret information, it is revealed by an Australian government review of social media and defense.
The review of social media and defense by Australian government completed in March disclosed that Taliban is using fake Facebook profiles with girls to obtain intelligence from military personnel. (Read more)


Facebook Inc. (NASDAQ:FB) Accounts Illegaly Used to Gather Secret Information, Report | News Today Digest

The Problem With Python ~ Perils of Python

Python freaks adhere to their favorite programming language like zombies to a cult. This is going to tick off some Python freaks.

You need some third party apps to make a standalone app out of Python. Plus it has many many add-ins built with C, C++ and whatever your programming weapon of choice. It can be a mashup of binary vomitus that can have some serious consequences. I saw one today.

This particular Python app was built by some troglodyte who's previous arena of expertise was DBase and FoxPro and thought that relational databases were a passing fad. So this app that he built fed itself data using .dbf files. Let me tell you, finding a .dbf file converter for free is like trying to find someone with a full set of teeth in a small southern town. Excel stopped outputting .dbf with 2007. Why would you need a dbf converter when you could use something more in the 19th century like a csv file? (Twentieth century is xml and 21rst century is JSON).

Well, it all has to do with the Perils of Python. The importer in this case was written in Python, and theoretically, it could import both csv and dbf files. CSV files always failed. But they didn't fail consistently. Sometimes the python input parser would correctly import a CSV and then on another like file, it would create extra fields, columns or whatever dinosaurs called table columns. It was a huge WTF? moment.

Then it came to me in a flash while I was emptying my colon. It was the colon in the date field. In some random cases, it correctly surmised that it was just another character in the field, and when another file was read in, it immediately said "AHA! Reserved character separator!. So why the inconsistent behavior? Da Python!

The input parser would make a decision on which import method to pass the input to. Depending on file size, it went to a method that was a layer of abstraction over the Python engine, or virtual machine, or Model T or whatever they call Python binaries. This would cause a choke. With just a few changes in the file characteristics, it would get imported natively and happily work. Unfortunately, you couldn't predict when and where it would work.

SO .... people beware of hiring the guy next door who will do the job for cheap ... these guys who still program with tools from the middle ages are doing you more harm than good. And your program is only good when it is operating on their development machine. Put it out in the real world and it fails quicker than the zipper coming down on Pee Wee Herman's and Fred Willard's pants in a darkened theater. Caveat emptor. The price you pay for using Python is huge if you want real inter-connectivity.

Chrome Blocking Extensions Part II



In a previous blog entry, I described how I added Chrome Browser extensions to prevent tracking cookies. Sites like CNN and New York Times and such sell tracking cookie information to all comers, and since I am a privacy advocate, it was starting to tick me off. So, I added DisconnectMe, Ghostery, and Do Not TrackPlus to my Chrome browser, and life was good.

I added the Adblocker, and that threw me my first curve ball. I couldn't access my Google account to see how much money my online ads were making. That made me take off AdBlocker.

Last week I discovered another fly in the ointment: Expedia.

The reason that I use Expedia is simple. I wanted in overnight hotel room in city that was 5 hours away. I just wanted a quick stopover, a place to lay my head and to get up and continue my journey. I knew of just the hotel that I wanted to stay at and where it was. I went to their site, and got what I thought was a reasonable price. To double check, I went to Expedia.

That same hotel room was 30 per cent cheaper on Expedia for the same night. I immediately booked it. I couldn't complete the online transaction. It kept telling me to wait a second and try again. After 15 minutes of this, a Eureka moment struck me. I turned off the Chrome Extension blockers and all worked well. I was able to book my hotel online.

Luckily most of these blockers have a little icon in the corner of the browser where you can turn them off and on. However, I wasted a quarter of an hour figuring this out.

500 Error UnsupportedClassVersionError


(click for larger image)

Had a troublesome error. I moved my development environment in Eclipse to my laptop. Imported the project. Everything went smoothly. Started the server. All fine. The minute that I had to go to the database, it blew up with an error that looked like this:

javax.servlet.ServletException: java.lang.UnsupportedClassVersionError Unsupported major.minor version 51.0

I realized that my new Eclipse Juno was set to compile for the 1.7 Java environment and Tomcat was running 1.6 Java JRE.

I went into the project properties, and selected Java Compiler option. On the upper right corner there is a link where you can click to Configure workspace settings. The JDK compliance is set to 1.7. (which is version 51). Use the combo box to set it to 1.6 which is version 50 and it should work.

I Won a Copyright Right Dispute with Google's Youtube

(click for larger image)

Google owns Youtube. When I wanted to make some of my pictures of Provence into a Youtube video, I deliberately did not want to run afoul of copyright laws. So I googled royalty free music and came to a site with free, unencumbered music. I downloaded a track and used it as background information.

When it came time to upload, I identified the track and artist and the fact that it was royalty free music. Youtube said that I couldn't monetize the video, because I didn't own the copyright. Interestingly enough, they didn't make me take it down.

I left it that way for months. Then I get a notice saying that some entity called CD Baby was disputing my right to use the music. I did an online appeal by filling in the forms, and using drop down menus to say that it was free, and royalty free music.

A couple of days later, I get the following email:


CD Baby has reviewed your dispute and released its copyright claim on your video, "A Peek At Provence". For more information, please visit your Copyright Notice page

Sincerely,
- The YouTube Team

Cool. So I figured that I would go ahead and monetize the video. Not so fast. I opened up video manager, and it said that there was copyright information that said I couldn't monetize it. I cut and pasted the email into the explanation box.

So I won a copyright dispute with the Google-owned YouTube, now lets see if they will let me monetize it. Here is the video in question:





Twitter Follow-Backs

(click for larger image)

I have officially stopped. I have stopped playing the stupid tit-for-tat followers games. I got the above this morning in my email saying that I was being followed, and that we would have a pact, and if I followed they would keep the follow and if I unfollowed them on Twitter, they would unfollow as well.

Bully for them. I am tired of playing this game. I will return to my true self. I will not follow ghetto rap artists. I will not follow girls more intent on showing their breasts rather than reading my content. I will not follow fundamentalist, racist Republicans.

I will just follow people and accounts that I am interested in, and will not follow you just because you follow me. Inflated follower numbers mean nothing. I have conducted experiments on how to convert followers to web hits, and the only way to do it, is to emulate the religion model. Anyone who is a true follower, will check out your website. Anyone paying lip service and just playing the tit-for-tat following game cannot be converted to web hits and is uninterested in what you have to say.

So most of my followers are real now. If you want to follow me for real, I can be followed @ArtOfWarm. If you are interesting, have decent content, and are not trying to sell me something, I will follow you back,

Javascript - How To Format a Telephone Number

This is quite a common problem. You have an user input table on your html or jsp page and you want to make sure that it is numbers only, has the area code, and is in a consistent format when you put it into the database. I downloaded some javascript to do just that and it worked fine for numbers that you typed in using the numbers on the keyboard. But when you used the numeric keypad on the keyboard, or a USB external keypad, it failed. The keypad, instead of putting numbers, put junk into it.

So this is how I solved it. I created a javascript file called phone.js. This is the contents:

function formatPnum(phonenum, textbox) {
var regexObj = /^(?:\+?1[-. ]?)?(?:\(?([0-9]{3})\)?[-. ]?)?([0-9]{3})[-. ]?([0-9]{4})$/;
if (regexObj.test(phonenum)) {
var parts = phonenum.match(regexObj);
var phone = "";
if (parts[1]) {
phone += "(" + parts[1] + ") "; }
phone += parts[2] + "-" + parts[3];
textbox.value = phone;
}
else {
//invalid phone number
alert('Please enter a proper phone number');
textbox.value = '';
}
return false;
}

Then at the top of the html page, I added the following script tag:

(script type="text/javascript" src="phone.js" /)

Note: I used "(" and ")" instead of "<" and ">" because this blog actually parses it as real HTML. Then, everywhere I needed a phone number, I added this to the tag (in this case for a fax number):


Fax (Area Code + #)
(input type="text" name="fax" onfocus="this.value='';" onmouseout="javascript:return formatPNum(this.value, this);")


Note: I used "(" and ")" instead of "<" and ">" because this blog actually parses it as real HTML.
You will note, that I have an onfocus event. When the user clicks on it, the previous number or whatever is in the input box goes away. Then the user enters the number. If any part of it fails (like he adds a letter), it fails and the alert shows that there is an error. There is no input displayed. However, if the user enters a three digit area code and a seven digit number, the phone number is automagically formatted into (123) 456-7890.

Piece of cake. Hope this helps.