/** * exec_command * Execute 'command' with 'arg' as its argument. * if !arg command is started with no arguments * Before we call execl we need to close all the file handles * that the fork inherited from the parent in order not to pass * the open handles on to the shell */ static void exec_command(struct context *cnt, char *command, char *filename, int filetype) { char stamp[PATH_MAX]; mystrftime(cnt, stamp, sizeof(stamp), command, &cnt->current_image->timestamp_tm, filename, filetype, 0); if (!fork()) { int i; /* Detach from parent */ setsid(); /* * Close any file descriptor except console because we will * like to see error messages */ for (i = getdtablesize(); i > 2; --i) close(i); execl("/bin/sh", "sh", "-c", stamp, " &", NULL); /* if above function succeeds the program never reach here */ MOTION_LOG(ALR, TYPE_EVENTS, SHOW_ERRNO, "%s: Unable to start external command '%s'", stamp); exit(1); } MOTION_LOG(DBG, TYPE_EVENTS, NO_ERRNO, "%s: Executing external command '%s'", stamp); }
/* save preview_shot */ void preview_save(struct context *cnt) { #ifdef HAVE_FFMPEG int use_jpegpath; int basename_len; #endif /* HAVE_FFMPEG */ const char *jpegpath; char previewname[PATH_MAX]; char filename[PATH_MAX]; struct image_data *saved_current_image; if (cnt->imgs.preview_image.diffs) { /* Save current global context */ saved_current_image = cnt->current_image; /* Set global context to the image we are processing */ cnt->current_image = &cnt->imgs.preview_image; #ifdef HAVE_FFMPEG /* Use filename of movie i.o. jpeg_filename when set to 'preview' */ use_jpegpath = strcmp(cnt->conf.jpegpath, "preview"); if (cnt->ffmpeg_new && !use_jpegpath) { /* Replace avi/mpg with jpg/ppm and keep the rest of the filename */ basename_len = strlen(cnt->newfilename) - 3; strncpy(previewname, cnt->newfilename, basename_len); previewname[basename_len] = '\0'; strcat(previewname, imageext(cnt)); put_picture(cnt, previewname, cnt->imgs.preview_image.image , FTYPE_IMAGE); } else #endif /* HAVE_FFMPEG */ { /* Save best preview-shot also when no movies are recorded or jpegpath * is used. Filename has to be generated - nothing available to reuse! */ //printf("preview_shot: different filename or picture only!\n"); /* conf.jpegpath would normally be defined but if someone deleted it by control interface * it is better to revert to the default than fail */ if (cnt->conf.jpegpath) jpegpath = cnt->conf.jpegpath; else jpegpath = (char *)DEF_JPEGPATH; mystrftime(cnt, filename, sizeof(filename), jpegpath, &cnt->imgs.preview_image.timestamp_tm, NULL, 0); snprintf(previewname, PATH_MAX, "%s/%s.%s", cnt->conf.filepath, filename, imageext(cnt)); put_picture(cnt, previewname, cnt->imgs.preview_image.image, FTYPE_IMAGE); } /* restore global context values */ cnt->current_image = saved_current_image; } }