The Dev Pages

A knowledge base for simple (and beyond) web applications development

Archive for April, 2010




I had done a git rm of some swp files (I had forgotten to put *.swp in my .gitignore for this project) and after committing, I pushed to the remote origin and was suprised to see:

error: unable to create temporary sha1 filename ./objects/19: File exists

If you get this error (Where 19 is a number unique to your situation), then it is probably a permissions issue. On the remote server, make sure the remote bare repos, and ALL subfolders and files are owned by the appropriate (usually git) user. What is annoying is that somehow in the course of pretty normal git tasks, a non-git user was assigned ownership, or the git user was denied rights somehow. I forgot to check what the bad permissions were before I chowned and chgrped the files.

Once I logged in as an admin, changed to the git user’s home directory where all the remote bare repos exist, and issued ’sudo chown -R git ./’ and ’sudo chgrp -R git ./’ all was well.

I think the way to avoid this error is to make sure you are using the git user if you are pushing changes on the same server as the remote git repos.

See a more in depth discussion at http://kerneltrap.org/mailarchive/git/2008/11/28/4258264/thread




Note: If you have a one-off php script that just needs to shoot out emails, consider using the PEAR Mail class, or something similar. You can just pass it an SMTP server (e.g. that of your gmail account) with credentials (e.g. your gmail login) and it will work swell. See http://email.about.com/od/emailprogrammingtips/qt/PHP_Email_SMTP_Authentication.htm

Note 2: This was done on an ubuntu server using postfix. This assumes you have postfix or sendmail installed on your server. On ubuntu you just do a ’sudo apt-get install postfix’ (or sendmail). To configure your MTA (Mail Transfer Agent e.g. Postfix, sendmail, etc.) to be secure, you’ll need to take additional steps, beyond the scope of this article. If you’re not concerned about the contents of you’re email being sniffed out, you’re probably ok if you’re just using outbound mail (a null client) with no smtp server listening for incoming traffic on port 25. I personally don’t care if a comment from someone using my website is emailed to me in plaintext (but maybe they would). See http://www.n8williams.com/devblog/linux/using-postfix-on-linux-for-sending-only-outgoing-messages for postfix null client setup for just outgoing mail. You can do the same with sendmail, and even kill the sendmail daemons.

Open your php.ini file (ubuntu: /etc/php5/apache2/php.ini) and find the line that says:

; For Unix only. You may supply arguments as well (default: “sendmail -t -i”).
;sendmail_path =

Change this, by uncommenting out the second line, to:

; For Unix only. You may supply arguments as well (default: “sendmail -t -i”).
sendmail_path = /usr/sbin/sendmail -t -i

Where /usr/sbin/sendmail may be a different path for your linux distro. To find it you can issue ’sudo find / -name sendmail’ (note this does a recursive find starting at the root dir so it may take a little while, 7 seconds for me. Ctrl-C to cancel out of it when it finds it). the -t -i options have something to do with using email headers to determine who the email is from, and ignoring weird lines with a period. All I know is it has worked better with these flags. You can research them if you want.

Now here’s the crazy thing that I failed to get at first. If we’re using postfix, then why the hell are we dealing with sendmail_path? Well it turns out that sendmail_path is a common php.ini option, and the sendmail binary is commonly used by all sorts of things. So postfix, when installed, makes a sendmail binary called /usr/sbin/sendmail to be a sort-of backwards compatible sendmail interface for things that expect sendmail (which has been around for a while). So even though your calling upon a binary called sendmail, this is a postfix file. This confused me to no avail when I had installed sendmail first, than uninstalled it with the package m anager, and installed postfix. I was failing to understand why the uninstall didn’t remove the sendmail binary until I realized it was actually a postfix file after reading http://www.postfix.org/sendmail.1.html.

Now restart apache/php and the mail function should work. Let’s hope. There’s a million cluttered google results about all the various reasons why mail() runs, and may hang, but no email gets sent. One key is reading your logs. Get familiar with the mail log. On ubuntu this is /var/log/mail.err, etc.




Summary: What you want is to set up a null client. http://www.postfix.org/faq.html#null_client See my notes below for what constitutes an ’smtp server entry’.

So for my local dev environments I’ve been in the habit of setting up php’s mail function to work by doing a ’sudo apt-get install sendmail’ and editing the php.ini to point the sendmail_path to /usr/sbin/sendmail. (I’d recommend this procedure only if you’re working locally and don’t plan on opening port 25 to anything public, won’t want to mess with domain names, and won’t be dealing with mx records, etc.).

Well when I actually had to setup a server with a public domain, and needed emails to work efficiently from php with a qualified domain while worrying about port 25 being secure, I was in for some fun. For starters I’d recommend postfix over sendmail. Much easier to configure. Sendmail has many more config files, and you have to re-compile some of them after edits, etc. So once you have postfix installed, if you just want to send outgoing emails, then you can increase security and reduce overhead by making postfix not listen on the SMTP port. I wanted postfix as an smtp client only. With sendmail you can do this, and even kill all the daemons. With postfix you still need the daemon going, but when we’re done, nothing will be listening on port 25, smtp.

So what we are setting up is called a ‘null client’. You just have to modify /etc/postfix/main.cf and master/cf according to the instructions at http://www.postfix.org/faq.html#null_client.

The main thing that was unclear to me is what line(s) constitute a ‘SMTP server entry’ in master.cf. After commenting out the line close to the top with ’service’ as ’smtp’ and ‘type’ as ‘inet’, I figured this was enough, as ’sudo lsof -i’ indicated nothing was listening on port 25, or as smtp. I would leave the other smtp service entries alone, the ones with ‘type’ as ‘unix’.

Then do ’sudo postfix reload’ and for good measure we may as well do ’sudo /etc/init.d/postfix restart’, or the equivalent on your linux distro.