Warning: I'm not going to answer the question itself, as usage of CGI.pm will fix that almost automagically.
- You use only global variables. For example, the @pairs you use in your parsing routine, is visibile everywhere. This might not be a problem in small scripts, but when you code larger programs, it will definitely bite you. Try using strict and declaring variables with my. When you do so, variables will cease to exist when the surrounding scope (block) ends.
- Your parsing routine can't handle multiple values. This may not be a problem now, but will be when you use multiple form elements that have the same name. With a query string of foo=bar&foo=xyzzy, the bar value is lost, and overwritten by the xyzzy one. You might think it's not likely to have multiple form elements with the same name, but think about <select multiple> for example, or a greater number of form fields, which can be handy if you use JavaScript to generate more elements if required.
- A value containing multiple = characters will not be parsed right: foo=bar=baz will not set $FORM{foo} to bar=baz but to bar.
- Your indenting in the last else block is terrible. You seem to understand why indenting is important and how it works, but you don't pay attention to it over where, leaving a whitespace mess.
- CONTENT_LENGTH is not what you want to check for POST requests, as POST requests can be empty - try using REQUEST_METHOD.
- Have you been reading a Perl 4 book? The & character when without parens and used to call a sub distributes the current @_, which isn't useful in this case, and will bite you in more complex code if you continue to use it when you don't need @_ to be passed around.
Yes, I reinvent wheels.