Monday, February 7, 2011

Where does CGI.pm normally create temporary files?

On all my Windows servers, except for one machine, when I execute the following code to allocate a temporary files folder:

use CGI;
my $tmpfile = new CGITempFile(1);
print "tmpfile='", $tmpfile->as_string(), "'\n";

The variable $tmpfile is assigned the value '.\CGItemp1' and this is what I want. But on one of my servers it's incorrectly set to C:\temp\CGItemp1.

All the servers are running Windows 2003 Standard Edition, IIS6 and ActivePerl 5.8.8.822 (upgrading to later version of Perl not an option). The result is always the same when running a script from the command line or in IIS as a CGI script (where scriptmap .pl = c:\perl\bin\perl.exe "%s" %s).

How I can fix this Perl installation and force it to return '.\CGItemp1' by default?

I've even copied the whole Perl folder from one of the working servers to this machine but no joy.

@Hometoast:

I checked the 'TMP' and 'TEMP' environment variables and also $ENV{TMP} and $ENV{TEMP} and they're identical.

From command line they point to the user profile directory, for example:

C:\DOCUME~1\[USERNAME]\LOCALS~1\Temp\1

When run under IIS as a CGI script they both point to:

c:\windows\temp

In registry key HKEY_USERS/.DEFAULT/Environment, both servers have:

%USERPROFILE%\Local Settings\Temp

The ActiveState implementation of CGITempFile() is clearly using an alternative mechanism to determine how it should generate the temporary folder.

@Ranguard:

The real problem is with the CGI.pm module and attachment handling. Whenever a file is uploaded to the site CGI.pm needs to store it somewhere temporary. To do this CGITempFile() is called within CGI.pm to allocate a temporary folder. So unfortunately I can't use File::Temp. Thanks anyway.

@Chris:

That helped a bunch. I did have a quick scan through the CGI.pm source earlier but your suggestion made me go back and look at it more studiously to understand the underlying algorithm. I got things working, but the oddest thing is that there was originally no c:\temp folder on the server.

To obtain a temporary fix I created a c:\temp folder and set the relevant permissions for the website's anonymous user account. But because this is a shared box I couldn't leave things that way, even though the temp files were being deleted. To cut a long story short, I renamed the c:\temp folder to something different and magically the correct '.\' folder path was being returned. I also noticed that the customer had enabled FrontPage extensions on the site, which removes write access for the anonymous user account on the website folders, so this permission needed re-applying. I'm still at a loss as to why at the start of this issue CGITempFile() was returning c:\temp, even though that folder didn't exist, and why it magically started working again.

Thanks in advance
Kevin

  • If you're running this script as you, check the %TEMP% environment variable to see if if it differs.

    If IIS is executing, check the values in registry for TMP and TEMP under HKEY_USERS/.DEFAULT/Environment

    From hometoast
  • The name of the temporary directory is held in $CGITempFile::TMPDIRECTORY and initialised in the find_tempdir function in CGI.pm. The algorithm for choosing the temporary directory is described in the CGI.pm documentation (search for -private_tempfiles). IIUC, if a C:\Temp folder exists on the server, CGI.pm will use it. If none of the directories checked in find_tempdir exist, then the current directory "." is used.

    I hope this helps.

    From ChrisN
  • Not the direct answer to your question, but have you tried using File::Temp?

    It is specifically designed to work on any OS.

    From Ranguard

How to best implement simple crash / error reporting?

What would be the best way to implement a simple crash / error reporting mechanism?

Details: my app is cross-platform (mac/windows/linux) and written in Python, so I just need something that will send me a small amount of text, e.g. just a timestamp and a traceback (which I already generate and show in my error dialog).

It would be fine if it could simply email it, but I can't think of a way to do this without including a username and password for the smtp server in the application... Should I implement a simple web service on the server side and have my app send it an HTTP request with the info? Any better ideas?

Thanks!

  • The web hit is the way to go, but make sure you pick a good URL - your app will be hitting it for years to come.

    From pjz
  • PyCrash?

    From Allan Wind
  • Whether you use SMTP or HTTP to send the data, you need to have a username/password in the application to prevent just anyone from sending random data to you.

    With that in mind, I suspect it would be easier to use SMTP rather than HTTP to send the data.

    From Branan
  • The web service is the best way, but there are some caveats:

    1. You should always ask the user if it is ok to send error feedback information.
    2. You should be prepared to fail gracefully if there are network errors. Don't let a failure to report a crash impede recovery!
    3. You should avoid including user identifying or sensitive information unless the user knows (see #1) and you should either use SSL or otherwise protect it. Some jurisdictions impose burdens on you that you might not want to deal with, so it's best to simply not save such information.
    4. Like any web service, make sure your service is not exploitable by miscreants.
    From nsayer
  • Some kind of simple web service would suffice. You would have to consider security so not just anyone could make requests to your service..

    On a larger scale we considered a JMS messaging system. Put a serialized object of data containing the traceback/error message into a queue and consume it every x minutes generating reports/alerts from that data.

  • I can't think of a way to do this without including a username and password for the smtp server in the application...

    You only need a username and password for authenticating yourself to a smarthost. You don't need it to send mail directly, you need it to send mail through a relay, e.g. your ISP's mail server. It's perfectly possible to send email without authentication - that's why spam is so hard to stop.

    Having said that, some ISPs block outbound traffic on port 25, so the most robust alternative is an HTTP POST, which is unlikely to be blocked by anything. Be sure to pick a URL that you won't feel restricted by later on, or better yet, have the application periodically check for updates, so if you decide to change domains or something, you can push an update in advance.

    Security isn't really an issue. You can fairly easily discard junk data, so all that really concerns you is whether or not somebody would go to the trouble of constructing fake tracebacks to mess with you, and that's a very unlikely situation.

    As for the payload, PyCrash can help you with that.

    From Jim

FollowSymLinks - how to setup

I am trying to have Apache follow a symlink to a raid array server that will contain some large data files. I have tried modifying httpd.conf to have an entry like this

Options FollowSymLinks AllowOverride all Order allow,deny Allow from all

to have Apache follow any sym link in the Sites folder.

I keep getting an error return that seems to indicate I don't have any permissions to access the files. The error is: Forbidden

You don't have permission to access /~imagine/imageLibraryTest/videoClips/imageLibraryVideos/imageLibraryVideos/Data13/0002RT-1.mov on this server.

the sys link file is the last "imageLibraryVideos" in the line with the Data13 being the sub dir on the server containing the file.

The 0002RT-1.mov file hase these permissions: -rwxrwxrwx 1 imagine staff 1138757 Sep 15 17:01 0002RT-1.mov and is in this path: cd /Volumes/ImagineProducts-1/Users/imagine/Sites/imageLibraryVideos/Data13

the link points to: lrwxr-xr-x 1 imagine staff 65 Sep 15 16:40 imageLibraryVideos -> /Volumes/ImagineProducts-1/Users/imagine/Sites/imageLibraryVideos

  • Look in the enclosing directories. They need to be at least mode 711. (drwx--x--x)

    Also, look in /var/log/apache2/error_log (Or whatever the concatenation of ServerRoot and ErrorLog is from the httpd.conf) for a possibly more-detailed error message.

    Finally, ensure you restart apache after messing with httpd.conf.

    From Pi
  • This is a permissions problem where the user that your web server is running under does not have read and/or execute permissions to the necessary directories in the symbolic link path. The quick and easy way to check is to su - web-user (where web-user is the user account that the web server is running under) and then try to cd into the path and view the file. When you come across a directory that you don't have permission to enter, you'll have to change the permissions and/or ownership to make it accessible by the web server user account.

  • Thanks,

    I've set the permissions to all the enclosing directories to 755
    but Apache cstill cannot access the file.

  • You should also look at bind mounts rather than symlinks - that would allow you to remount a given path at a new point. The following is an example:

    mount --rbind /path/to/current/location/somewhere/else /new/mount/point
    

    You can also edit your fstab to do this at boot:

    /path/to/original /new/path bind defaults,bind 0 0
    
    From warren

Best binary XML format for JavaME

Can anyone recommend a good binary XML format? It's for a JavaME application, so it needs to be a) Easy to implement on the server, and b) Easy to write a low-footprint parser for on a low-end JavaME client device.

And it goes without saying that it needs to be smaller than XML, and faster to parse.

  • What kind of data are you planning to use? I would say, that if the server is also done in Java, easiest way for small footprint is to send/receive binary data in predefined format. Just write everything in known order into DataOutputStream.

    But it would really depend, what what kind of data are you working on and can you define the format.

    Actually you should evaluate, if this kind of optimization is even needed. Maybe you target devices are not so limited :)

    /JaanusSiim

    From JaanusSiim
  • You might want to take a look at wbxml (Wireless Binary XML) it is optimized for size, and often used on mobile phones, but it is not optimized for parsing speed.

    From Pat
  • The data would be something akin to SVG.

    From izb
  • Check out the following: SAXProject, XMLPull and kXML. kXML I have found to be pretty good. Regards philip.ie

    From Philip.ie
  • It very much depends on the target device. If you have JSR172 available, then you are done with the parsing, the runtime does it for you. And XML is mainly about making your own format. As was alredy stated if your goal is performance, than XML is probably not the best way to go and you will end up doing some binary stuff.

    From Honza
  • Hessian might be an alternative worth looking at. It is a small protocol, well-suited for Java ME applications.

    "Hessian is a binary web service protocol that makes web services usable without requiring a large framework, and without learning a new set of protocols. Because it is a binary protocol, it is well-suited to sending binary data without any need to extend the protocol with attachments."

    More links:

    http://hessian.caucho.com/

    http://www.nubius.be/info-software/hessian4j.html

    Wilfred Springer : We used that at TomTom as well. There's one gotcha though: the ME implementation of Hessian is not the same as the SE/EE implementation of Hessian. There are quite a few things missing, so don't expect binary compatibility in all cases.
    From darius

How do I enable more than 8-bit colors in Terminal.app?

In the Vim and Emacs terminal apps, the color schemes look horrid. How do I enable the colors to be as vibrant as the GUI version (or more than 8 colors for that matter)?

Should I just give up, and move over to their respective GUI applications? And if so, which?

  • You can't have more colors in the terminal, because there are only ANSI codes for 8 colors (16 if you count bold/light). If you want to customize the colors, you can use the TerminalColours plugin from http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal

    Personally, I prefer to use the so-called Carbon Emacs on my Mac. There are several builds available; Google is your friend. I get mine from http://www.porkrind.org/emacs/

    From masto
  • You are possibly being inhibited by the fact you are running in a VT100/WhateverItsCalled compatible terminal and it just doesn't have more than about 16 foreground and 16 background colours. If it did, the lovely library "CaCa" ( ColourAsciiColourArt ) would be much more pleasing to watch than it is.

    If you want more colours, you simply have to use more modern technology, and this generally means using X ( unless your loving pain and want to use directfb/framebuffer/svgalib ).

    For vim, there is GVim ( GTK+Vim ). Emacs GUI version however displeases me much, but I'm not an emacs user.

  • Aquamacs and MacVim

    From Hank Gay
  • Sounds like you want MacVim

    From camflan

How do I disable a button cell in a WinForms DataGrid?

I have a WinForms application with a DataGridView control and a column of DataGridViewButtonCell cells within that. When I click on one of these buttons, it starts a background task, and I'd like to disable the buttons until that task completes.

I can disable the DataGridView control, but it gives no visual indication that the buttons are disabled. I want the user to see that the buttons are disabled, and to notice that the task has finished when the buttons are enabled again.

Bonus points for a method that allows me to disable the buttons individually, so I can leave one of the buttons enabled while the task runs. (Note that I can't actually give out bonus points.)

  • Here's the best solution I've found so far. This MSDN article gives the source code for a cell class that adds an Enabled property.

    It works reasonably well, but there are two gotchas:

    1. You have to invalidate the grid after setting the Enabled property on any cells. It shows that in the sample code, but I missed it.
    2. It's only a visual change, setting the Enabled property doesn't actually enable or disable the button. The user can still click on it. I could check the enabled property before executing the click event, but it also seemed to be messing up the appearance when the user clicked on it. Instead, I just disabled the entire grid. That works alright for me, but I'd prefer a method that allows me to disable some buttons without disabling the entire grid.
    From Don Kirkby
  • Another example using the same concept as the MSDN article linked by Don.

    From hometoast
  • You could give this a try:

    When you click on the cell...

    1. Check to see if the process with the current row identifier is running from a class-level list; if so, exit the cell click event.
    2. Store the row identifier in the class-level list of running processes.
    3. Change the button text to "Running..." or something appropriate.
    4. Attach a basic RunWorkerCompleted event handler to your process (explained shortly).
    5. Call backgroundWorker.RunWorkerAsync(rowIdentifier).

    In the DoWork event handler...

    1. Set e.Result = e.Argument (or create an object that will return both the argument and your desired result)

    In the RunWorkerCompleted event hanlder...

    1. Remove the row identifier from the running processes list (e.Result is the identifier).
    2. Change the button text from "Running..." to "Ready"
    Don Kirkby : Thanks for an interesting alternative, but I'd rather stick with the standard visual cue of graying out the buttons.

Strange characters in PHP

This is driving me crazy.

I have this one php file on a test server at work which does not work.. I kept deleting stuff from it till it became

<?
print 'Hello';
?>

it outputs

Hello

if I create a new file and copy / paste the same script to it it works! Why does this one file give me the strange characters all the time?

  • That's the BOM (Byte Order Mark) you are seeing.

    In your editor, there should be a way to force saving without BOM which will remove the problem.

    From Pat
  • Is the document saved in an encoding such as UTF-8/16? What encoding does the html-page specify?

    From Patrik
  • Wow that was fast guys !

    Thanks I will check it out.

  • We had the same thing happen once upon a time it drove the dev crazy for a while too :-)

    Someone had opened the file and accidentally saved it with BOM and from there on the editor would preserve the BOM while saving the file.

    In your editor, there should be a way to force saving without BOM which will remove the problem.

    From Pat
  • Found it, file -> encoding -> UTF8 with BOM , changed to to UTF :-)

    I should ahve asked before wasing time trying to figure it out :-)

  • Just in case, here is a list of bytes for BOM

    Encoding    Representation (hexadecimal)
    UTF-8   EF BB BF
    UTF-16 (BE) FE FF
    UTF-16 (LE) FF FE
    UTF-32 (BE) 00 00 FE FF
    UTF-32 (LE) FF FE 00 00
    UTF-7   2B 2F 76, and one of the following bytes: [ 38 | 39 | 2B | 2F ]†
    UTF-1   F7 64 4C
    UTF-EBCDIC  DD 73 66 73
    SCSU    0E FE FF
    BOCU-1  FB EE 28 optionally followed by FF†