A command line program that does this is sox.
The general idea with the algorithm is to find the highest absolute value sample (audio should be centered, whatever the measurement of the sampled data).
You divide your maximum possible value by this number (which is guaranteed to be equal or smaller), and then you multiply that by your desired peak level (ie. do you want it to reach .95 of max? full 1.0?). If the result is not one, it becomes your scale value. Then you iterate through your file and multiply every sample by that number.
For example with CD quality audio your highest possible absolute value for a sample is 32767 (fudging this to make the example easier, the real range is -32768 to 32767, but treating 32767 as your max makes things much simpler here), so if you scanned through and the highest absolute value you found was 18000, than your amplification factor will be 1.8203888... , and if you want your max volume to be 0.9887997070223*the max availible, that gives you a new scale factor of 1.8. So you loop through the array holding the audio file, and replace the previous value for each sample with the value * 1.8.
This can be optimized by doing a click filter first, to eliminate spurious transients, and also by de-essing, which makes sure the waveform is evenly centered around the median value by removing low frequency components that cannot be produced by speakers or heard by the human ear. The click filter is a lowpass, and the de-esser is a highpass. Once these filters are run, there will be more room for amplifying the sound without introducing distortion.