Index: conf.c =================================================================== --- conf.c (revision 184) +++ conf.c (working copy) @@ -98,6 +98,7 @@ vidpipe: NULL, filepath: NULL, jpegpath: DEF_JPEGPATH, + last_jpeg_filename: NULL, mpegpath: DEF_MPEGPATH, snappath: DEF_SNAPPATH, timepath: DEF_TIMEPATH, @@ -741,6 +742,15 @@ copy_string, print_string }, + { + "last_jpeg_filename", + "# File name for the symlink to the last saved image. Example: lastimage\n" + "# The (.jpg|.ppm) extension will be added to the filename you specified.\n" + "# Default: undefined\n", + CONF_OFFSET(last_jpeg_filename), + copy_string, + print_string + }, #ifdef HAVE_FFMPEG { "movie_filename", Index: conf.h =================================================================== --- conf.h (revision 184) +++ conf.h (working copy) @@ -82,6 +82,7 @@ const char *vidpipe; const char *filepath; const char *jpegpath; + const char *last_jpeg_filename; const char *mpegpath; const char *snappath; const char *timepath; Index: event.c =================================================================== --- event.c (revision 184) +++ event.c (working copy) @@ -242,7 +242,7 @@ char filename[PATH_MAX]; char fullfilenamem[PATH_MAX]; char filenamem[PATH_MAX]; - + if (conf->motion_img || cnt->new_img==NEWIMG_ON || cnt->preview_shot) { const char *jpegpath; @@ -265,6 +265,23 @@ if (cnt->new_img==NEWIMG_ON || cnt->preview_shot) { put_picture(cnt, fullfilename, newimg, FTYPE_IMAGE); } + + if (cnt->conf.last_jpeg_filename != NULL){ + char tmplinkpath[PATH_MAX]; + char linkpath[PATH_MAX]; + char linktarget[PATH_MAX]; + + snprintf(linktarget, PATH_MAX, "%s.%s", filename, imageext(cnt)); + snprintf(linkpath, PATH_MAX, "%s/%s.%s", cnt->conf.filepath, cnt->conf.last_jpeg_filename, imageext(cnt)); + snprintf(tmplinkpath, PATH_MAX, "%s.tmp", linkpath); + if (symlink(linktarget, tmplinkpath)) { + motion_log(LOG_ERR, 1, "Could not create symbolic link [%s]", linktarget); + return; + } + if (rename(tmplinkpath, linkpath)) { + motion_log(LOG_ERR, 1, "Could overwrite old symbolic link [%s]", fullfilename); + } + } } static void event_image_snapshot(struct context *cnt, int type ATTRIBUTE_UNUSED, @@ -277,6 +294,7 @@ char filename[PATH_MAX]; char filepath[PATH_MAX]; char linkpath[PATH_MAX]; + char tmplinkpath[PATH_MAX]; const char *snappath; /* conf.snappath would normally be defined but if someone deleted it by control interface it is better to revert to the default than fail */ @@ -293,11 +311,14 @@ /* Update symbolic link *after* image has been written so that the link always points to a valid file. */ snprintf(linkpath, PATH_MAX, "%s/lastsnap.%s", cnt->conf.filepath, imageext(cnt)); - remove(linkpath); - if (symlink(filename, linkpath)) { + snprintf(tmplinkpath, PATH_MAX, "%s.tmp", linkpath); + if (symlink(filename, tmplinkpath)) { motion_log(LOG_ERR, 1, "Could not create symbolic link [%s]", filename); return; } + if (rename(tmplinkpath, linkpath)) { + motion_log(LOG_ERR, 1, "Could overwrite old symbolic link [%s]", filename); + } } else { snprintf(fullfilename, PATH_MAX, "%s/lastsnap.%s", cnt->conf.filepath, imageext(cnt)); remove(fullfilename);