⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 event.c

📁 motion motion
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	event.c	Generalised event handling for motion	Copyright Jeroen Vreeken, 2002	This software is distributed under the GNU Public License Version 2	see also the file 'COPYING'.*/#include "ffmpeg.h"	/* must be first to avoid 'shadow' warning *///#include "motion.h"#include "picture.h"	/* already includes motion.h */#include "event.h"#if (!defined(BSD)) #include "video.h"#endif/* *	Various functions (most doing the actual action) *//* 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);		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(LOG_ERR, 1, "Unable to start external command '%s'", stamp);		exit(1);	}	else if (cnt->conf.setup_mode)		motion_log(-1, 0, "Executing external command '%s'", stamp);}/*  *	Event handlers */static void event_newfile(struct context *cnt ATTRIBUTE_UNUSED,            int type ATTRIBUTE_UNUSED, unsigned char *dummy ATTRIBUTE_UNUSED,            char *filename, void *ftype, struct tm *tm ATTRIBUTE_UNUSED){	motion_log(-1, 0, "File of type %ld saved to: %s", (unsigned long)ftype, filename);}static void event_beep(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *dummy ATTRIBUTE_UNUSED,            char *filename ATTRIBUTE_UNUSED,            void *ftype ATTRIBUTE_UNUSED,            struct tm *tm ATTRIBUTE_UNUSED){	if (!cnt->conf.quiet)		printf("\a");}/* on_picture_save_command handles both on_picture_save and on_movie_start * If arg = FTYPE_IMAGE_ANY on_picture_save script is executed * If arg = FTYPE_MPEG_ANY on_movie_start script is executed * The scripts are executed with the filename of picture or movie appended * to the config parameter. */static void on_picture_save_command(struct context *cnt,            int type ATTRIBUTE_UNUSED, unsigned char *dummy ATTRIBUTE_UNUSED,            char *filename, void *arg, struct tm *tm ATTRIBUTE_UNUSED){	int filetype = (unsigned long)arg;		if ((filetype & FTYPE_IMAGE_ANY) != 0 && cnt->conf.on_picture_save)		exec_command(cnt, cnt->conf.on_picture_save, filename, filetype);	if ((filetype & FTYPE_MPEG_ANY) != 0 && cnt->conf.on_movie_start)		exec_command(cnt, cnt->conf.on_movie_start, filename, filetype);}static void on_motion_detected_command(struct context *cnt,            int type ATTRIBUTE_UNUSED, unsigned char *dummy1 ATTRIBUTE_UNUSED,            char *dummy2 ATTRIBUTE_UNUSED, void *dummy3 ATTRIBUTE_UNUSED,            struct tm *tm ATTRIBUTE_UNUSED){	if (cnt->conf.on_motion_detected)		exec_command(cnt, cnt->conf.on_motion_detected, NULL, 0);}#if defined(HAVE_MYSQL) || defined(HAVE_PGSQL)static void event_sqlnewfile(struct context *cnt, int type  ATTRIBUTE_UNUSED,            unsigned char *dummy ATTRIBUTE_UNUSED,            char *filename, void *arg, struct tm *tm ATTRIBUTE_UNUSED){	int sqltype = (unsigned long)arg;	/* Only log the file types we want */	if (!(cnt->conf.mysql_db || cnt->conf.pgsql_db) || (sqltype & cnt->sql_mask) == 0) 		return;	/* We place the code in a block so we only spend time making space in memory	 * for the sqlquery and timestr when we actually need it.	 */	{		char sqlquery[PATH_MAX];		int ret;			mystrftime(cnt, sqlquery, sizeof(sqlquery), cnt->conf.sql_query, &cnt->current_image->timestamp_tm, filename, sqltype);		#ifdef HAVE_MYSQL		if (cnt->conf.mysql_db) {			ret = mysql_query(cnt->database, sqlquery);			if (ret != 0){				int error_code = mysql_errno(cnt->database);								motion_log(LOG_ERR, 1, "Mysql query failed %s error code %d",						mysql_error(cnt->database), error_code);				/* Try to reconnect ONCE if fails continue and discard this sql query */				if (error_code >= 2000){					cnt->database = (MYSQL *) mymalloc(sizeof(MYSQL));					mysql_init(cnt->database);					if (!mysql_real_connect(cnt->database, cnt->conf.mysql_host, 								cnt->conf.mysql_user, cnt->conf.mysql_password, 								cnt->conf.mysql_db, 0, NULL, 0)) {						motion_log(LOG_ERR, 0, "Cannot reconnect to MySQL database %s on host %s with user %s", cnt->conf.mysql_db, cnt->conf.mysql_host, cnt->conf.mysql_user);						motion_log(LOG_ERR, 0, "MySQL error was %s", mysql_error(cnt->database));					}else mysql_query(cnt->database, sqlquery);				}								}			}#endif /* HAVE_MYSQL */#ifdef HAVE_PGSQL		if (cnt->conf.pgsql_db) {			PGresult *res;			res = PQexec(cnt->database_pg, sqlquery);			if (PQresultStatus(res) != PGRES_COMMAND_OK) {				motion_log(LOG_ERR, 1, "PGSQL query failed");				PQclear(res);			}		}#endif /* HAVE_PGSQL */	}}#endif /* defined HAVE_MYSQL || defined HAVE_PGSQL */static void on_area_command(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *dummy1 ATTRIBUTE_UNUSED,            char *dummy2 ATTRIBUTE_UNUSED, void *dummy3 ATTRIBUTE_UNUSED,            struct tm *tm ATTRIBUTE_UNUSED){	if (cnt->conf.on_area_detected)		exec_command(cnt, cnt->conf.on_area_detected, NULL, 0);}static void on_event_start_command(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *dummy1 ATTRIBUTE_UNUSED,            char *dummy2 ATTRIBUTE_UNUSED, void *dummy3 ATTRIBUTE_UNUSED,            struct tm *tm ATTRIBUTE_UNUSED){	if (cnt->conf.on_event_start)		exec_command(cnt, cnt->conf.on_event_start, NULL, 0);}static void on_event_end_command(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *dummy1 ATTRIBUTE_UNUSED,            char *dummy2 ATTRIBUTE_UNUSED, void *dummy3 ATTRIBUTE_UNUSED,            struct tm *tm ATTRIBUTE_UNUSED){	if (cnt->conf.on_event_end)		exec_command(cnt, cnt->conf.on_event_end, NULL, 0);}static void event_stop_webcam(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *dummy1 ATTRIBUTE_UNUSED,            char *dummy2 ATTRIBUTE_UNUSED, void *dummy3 ATTRIBUTE_UNUSED,            struct tm *tm ATTRIBUTE_UNUSED){	if ((cnt->conf.webcam_port) && (cnt->webcam.socket != -1)){		webcam_stop(cnt);	}}static void event_webcam_put(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *img, char *dummy1 ATTRIBUTE_UNUSED,            void *dummy2 ATTRIBUTE_UNUSED, struct tm *tm ATTRIBUTE_UNUSED){	if (cnt->conf.webcam_port)		webcam_put(cnt, img);}#ifndef WITHOUT_V4L#if (!defined(BSD))static void event_vid_putpipe(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *img, char *dummy ATTRIBUTE_UNUSED, void *devpipe,            struct tm *tm ATTRIBUTE_UNUSED){	if (*(int *)devpipe >= 0) {		if (vid_putpipe(*(int *)devpipe, img, cnt->imgs.size) == -1)			motion_log(LOG_ERR, 1, "Failed to put image into video pipe");	}}#endif /* BSD */#endif /* WITHOUT_V4L */const char *imageext(struct context *cnt){	if (cnt->conf.ppm)		return "ppm";	return "jpg";}static void event_image_detect(struct context *cnt, int type ATTRIBUTE_UNUSED,	    unsigned char *newimg, char *dummy1 ATTRIBUTE_UNUSED,	    void *dummy2 ATTRIBUTE_UNUSED, struct tm *currenttime_tm){	char fullfilename[PATH_MAX];	char filename[PATH_MAX];	if (cnt->new_img & NEWIMG_ON) {		const char *jpegpath;		/* 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 = DEF_JPEGPATH;					mystrftime(cnt, filename, sizeof(filename), jpegpath, currenttime_tm, NULL, 0);		snprintf(fullfilename, PATH_MAX, "%s/%s.%s", cnt->conf.filepath, filename, imageext(cnt));		put_picture(cnt, fullfilename, newimg, FTYPE_IMAGE);	}}static void event_imagem_detect(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *newimg ATTRIBUTE_UNUSED, char *dummy1 ATTRIBUTE_UNUSED,            void *dummy2 ATTRIBUTE_UNUSED, struct tm *currenttime_tm){	struct config *conf=&cnt->conf;	char fullfilenamem[PATH_MAX];	char filename[PATH_MAX];	char filenamem[PATH_MAX];	if (conf->motion_img) {		const char *jpegpath;		/* 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 = DEF_JPEGPATH;					mystrftime(cnt, filename, sizeof(filename), jpegpath, currenttime_tm, NULL, 0);		/* motion images gets same name as normal images plus an appended 'm' */		snprintf(filenamem, PATH_MAX, "%sm", filename);		snprintf(fullfilenamem, PATH_MAX, "%s/%s.%s", cnt->conf.filepath, filenamem, imageext(cnt));		put_picture(cnt, fullfilenamem, cnt->imgs.out, FTYPE_IMAGE_MOTION);	}}static void event_image_snapshot(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *img, char *dummy1 ATTRIBUTE_UNUSED,            void *dummy2 ATTRIBUTE_UNUSED, struct tm *currenttime_tm){	char fullfilename[PATH_MAX];	if ( strcmp(cnt->conf.snappath, "lastsnap") ) {		char filename[PATH_MAX];		char filepath[PATH_MAX];		char linkpath[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 */		if (cnt->conf.snappath)			snappath = cnt->conf.snappath;		else			snappath = DEF_SNAPPATH;					mystrftime(cnt, filepath, sizeof(filepath), snappath, currenttime_tm, NULL, 0);		snprintf(filename, PATH_MAX, "%s.%s", filepath, imageext(cnt));		snprintf(fullfilename, PATH_MAX, "%s/%s", cnt->conf.filepath, filename);		put_picture(cnt, fullfilename, img, FTYPE_IMAGE_SNAPSHOT);		/* 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)) {			motion_log(LOG_ERR, 1, "Could not create symbolic link [%s]", filename);			return;		}	} else {		snprintf(fullfilename, PATH_MAX, "%s/lastsnap.%s", cnt->conf.filepath, imageext(cnt));		remove(fullfilename);		put_picture(cnt, fullfilename, img, FTYPE_IMAGE_SNAPSHOT);	}	cnt->snapshot = 0;}static void event_camera_lost(struct context *cnt, int type ATTRIBUTE_UNUSED,            unsigned char *img ATTRIBUTE_UNUSED, char *dummy1 ATTRIBUTE_UNUSED,            void *dummy2 ATTRIBUTE_UNUSED, struct tm *currenttime_tm ATTRIBUTE_UNUSED){	if (cnt->conf.on_camera_lost)		exec_command(cnt, cnt->conf.on_camera_lost, NULL, 0);}#ifdef HAVE_FFMPEGstatic void grey2yuv420p(unsigned char *u, unsigned char *v, int width, int height){	memset(u, 128, width*height/4);	memset(v, 128, width*height/4);}static void on_movie_end_command(struct context *cnt, int type ATTRIBUTE_UNUSED,                                 unsigned char *dummy ATTRIBUTE_UNUSED, char *filename,                                 void *arg, struct tm *tm ATTRIBUTE_UNUSED){	int filetype = (unsigned long) arg;	if ((filetype & FTYPE_MPEG_ANY) && cnt->conf.on_movie_end)		exec_command(cnt, cnt->conf.on_movie_end, filename, filetype);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -