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

📄 netcam_ftp.c

📁 motion motion
💻 C
📖 第 1 页 / 共 2 页
字号:
		break;		case 1:		case 4:		case 5:		case -1:		default:		close(ctxt->control_file_desc);		ctxt->control_file_desc = -1;		return(-1);	}	res = ftp_send_passwd(ctxt);	if (res < 0) {		close(ctxt->control_file_desc);		ctxt->control_file_desc = -1;		return(-1);	}	res = ftp_get_response(ctxt);	switch (res) {		case 2:		break;		case 3:		motion_log(LOG_ERR, 0, "FTP server asking for ACCT on anonymous");		case 1:		case 4:		case 5:		case -1:		default:		close(ctxt->control_file_desc); ctxt->control_file_desc = -1;		ctxt->control_file_desc = -1;		return(-1);	}	return(0);}/*** ftp_get_connection**      Try to open a data connection to the server.** Parameters:**      ctxt    pointer to an FTP context** Returns -1 in case of error, 0 otherwise*/static int ftp_get_connection(ftp_context_pointer ctxt) {	char buf[200], *cur;	int len, i;	int res;	int on;	unsigned char ad[6], *adp, *portp;	unsigned int temp[6];	struct sockaddr_in data_address;	unsigned int data_address_length;	if (ctxt == NULL)	return(-1);	/* set up a socket for our data address */	if (ctxt->data_file_desc != -1)	close(ctxt->data_file_desc);	memset (&data_address, 0, sizeof(data_address));	ctxt->data_file_desc = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);	if (ctxt->data_file_desc < 0) {		motion_log(LOG_ERR, 1, "socket failed");		return (-1);	}	on = 1;	if (setsockopt(ctxt->data_file_desc, SOL_SOCKET, SO_REUSEADDR,	(char *)&on, sizeof(on)) < 0) {		motion_log(LOG_ERR, 1, "setting socket option SO_REUSEADDR");		return -1;	}	((struct sockaddr_in *)&data_address)->sin_family = AF_INET;	data_address_length = sizeof (struct sockaddr_in);	if (ctxt->passive) {		/* send PASV command over control channel */		snprintf (buf, sizeof(buf), "PASV\r\n");		len = strlen (buf);		res = send(ctxt->control_file_desc, buf, len, 0);		if (res < 0) {			motion_log(LOG_ERR, 1, "send failed in ftp_get_connection");			close(ctxt->data_file_desc);			ctxt->data_file_desc = -1;			return(res);		}		/* check server's answer */		res = ftp_get_response(ctxt);		if (res != 2) {			if (res == 5) {				close(ctxt->data_file_desc);				ctxt->data_file_desc = -1;				return(-1);			} else {				/*				* retry with an active connection				*/				close(ctxt->data_file_desc);				ctxt->data_file_desc = -1;				ctxt->passive = 0;			}		}		/* parse the IP address and port supplied by the server */		cur = &ctxt->control_buffer[ctxt->control_buffer_answer];		while (((*cur < '0') || (*cur > '9')) && *cur != '\0')		cur++;		if (sscanf (cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],		&temp[3], &temp[4], &temp[5]) != 6) {			motion_log(LOG_ERR, 0, "Invalid answer to PASV");			if (ctxt->data_file_desc != -1) {				close (ctxt->data_file_desc);				ctxt->data_file_desc = -1;			}			return (-1);		}		for (i=0; i<6; i++)		ad[i] = (unsigned char) (temp[i] & 0xff) ;		memcpy (&((struct sockaddr_in *)&data_address)->sin_addr, &ad[0], 4);		memcpy (&((struct sockaddr_in *)&data_address)->sin_port, &ad[4], 2);		/* Now try to connect to the data port */		if (connect(ctxt->data_file_desc, (struct sockaddr *) &data_address,		    data_address_length) < 0) {			motion_log(LOG_ERR, 1, "Failed to create a data connection");			close(ctxt->data_file_desc);			ctxt->data_file_desc = -1;			return (-1);		}	} else {		/*		* We want to bind to a port to receive the data.  To do this,		* we need the address of our host.  One easy way to get it is		* to get the info from the control connection that we have		* with the remote server		*/		getsockname(ctxt->control_file_desc, (struct sockaddr *)&data_address,		            &data_address_length);		((struct sockaddr_in *)&data_address)->sin_port = 0;		/* bind to the socket - should give us a unique port */		if (bind(ctxt->data_file_desc, (struct sockaddr *) &data_address,		    data_address_length) < 0) {			motion_log(LOG_ERR, 1, "bind failed");			close(ctxt->data_file_desc);			ctxt->data_file_desc = -1;			return (-1);		}		/* we get the port number by reading back in the sockaddr */		getsockname(ctxt->data_file_desc, (struct sockaddr *)&data_address,		            &data_address_length);		/* set up a 'listen' on the port to get the server's connection */		if (listen(ctxt->data_file_desc, 1) < 0) {			motion_log(LOG_ERR, 1, "listen failed");			close(ctxt->data_file_desc);			ctxt->data_file_desc = -1;			return (-1);		}		/* now generate the PORT command */		adp = (unsigned char *) &((struct sockaddr_in *)&data_address)->sin_addr;		portp = (unsigned char *) &((struct sockaddr_in *)&data_address)->sin_port;		snprintf (buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",		adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,		portp[0] & 0xff, portp[1] & 0xff);		buf[sizeof(buf) - 1] = 0;		len = strlen(buf);		/* send the PORT command to the server */		res = send(ctxt->control_file_desc, buf, len, 0);		if (res < 0) {			motion_log(LOG_ERR, 1, "send failed in ftp_get_connection");			close(ctxt->data_file_desc);			ctxt->data_file_desc = -1;			return(res);		}		res = ftp_get_response(ctxt);		if (res != 2) {			close(ctxt->data_file_desc);			ctxt->data_file_desc = -1;			return(-1);		}	}	return(ctxt->data_file_desc);}/*** ftp_close_connection**      Close the data connection from the server** Parameters:**      ctxt    Pointer to an FTP context** Returns -1 in case of error, 0 otherwise*/static int ftp_close_connection(ftp_context_pointer ctxt) {	int res;	fd_set rfd, efd;	struct timeval tv;	if ((ctxt == NULL) || (ctxt->control_file_desc < 0))		return(-1);	close(ctxt->data_file_desc);	ctxt->data_file_desc = -1;	/* Check for data on the control channel */	tv.tv_sec = 15;	tv.tv_usec = 0;	FD_ZERO(&rfd);	FD_SET(ctxt->control_file_desc, &rfd);	FD_ZERO(&efd);	FD_SET(ctxt->control_file_desc, &efd);	res = select(ctxt->control_file_desc + 1, &rfd, NULL, &efd, &tv);	if (res < 0) {		close(ctxt->control_file_desc);		ctxt->control_file_desc = -1;		return(-1);	}	if (res == 0) {             /* timeout */		close(ctxt->control_file_desc);		ctxt->control_file_desc = -1;	} else {                    /* read the response */		res = ftp_get_response(ctxt);		if (res != 2) {            /* should be positive completion (2) */			close(ctxt->control_file_desc);			ctxt->control_file_desc = -1;			return(-1);		}	}	return(0);}/*** ftp_get_socket**      Initiate fetch of the given file from the server.** Parameters:**      ctxt            an FTP context** Returns the socket for the data connection, or <0 in case of error*/int ftp_get_socket(ftp_context_pointer ctxt) {	char buf[300];	int res, len;	int acfd;	if ((ctxt == NULL) || (ctxt->path == NULL))		return(-1);	/* Set up the data connection */	ctxt->data_file_desc = ftp_get_connection(ctxt);	if (ctxt->data_file_desc == -1)		return(-1);	/* generate a "retrieve" command for the file */	snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);	buf[sizeof(buf) - 1] = 0;	len = strlen(buf);	/* send it to the server */	res = send(ctxt->control_file_desc, buf, len, 0);	if (res < 0) {		motion_log(LOG_ERR, 1, "send failed in ftp_get_socket");		close(ctxt->data_file_desc);		ctxt->data_file_desc = -1;		return(res);	}	/* check the answer */	res = ftp_get_response(ctxt);	if (res != 1) {		close(ctxt->data_file_desc);		ctxt->data_file_desc = -1;		return(-res);	}	/*	* if not a passive connection, need to do an accept to get the	* connection from the server	*/	if (!ctxt->passive) {		struct sockaddr_in data_address;		unsigned int data_address_length = sizeof(struct sockaddr_in);		if ((acfd = accept(ctxt->data_file_desc, (struct sockaddr *)&data_address,		    &data_address_length)) < 0) {			motion_log(LOG_ERR, 1, "accept in ftp_get_socket");			close(ctxt->data_file_desc);			ctxt->data_file_desc = -1;			return -1;		}		close(ctxt->data_file_desc);		ctxt->data_file_desc = acfd;	}	return(ctxt->data_file_desc);}/*** ftp_send_type** 	Send a TYPE (either 'I' or 'A') command to the server** Parameters**      ctxt    pointer to the ftp_context*      type    ascii character ('I' or 'A')** Returns      0 for success, negative error code for failure**/int ftp_send_type(ftp_context_pointer ctxt, char type) {	char buf[100], utype;	int len, res;	utype = toupper(type);	/* Assure transfer will be in "image" mode */	snprintf(buf, sizeof(buf), "TYPE I\r\n");	len = strlen(buf);	res = send(ctxt->control_file_desc, buf, len, 0);	if (res < 0) {		motion_log(LOG_ERR, 1, "send failed in ftp_get_socket");		close(ctxt->data_file_desc);		ctxt->data_file_desc = -1;		return(res);	}	res = ftp_get_response(ctxt);	if (res != 2) {		close(ctxt->data_file_desc);		ctxt->data_file_desc = -1;		return(-res);	}	return 0;}/*** ftp_read**      This function tries to read len bytes from the existing FTP*      connection and saves them in dest. This is a blocking call.** Parameters:*      ctxt    the FTP context*      dest    a buffer*      len     the buffer length** Returns:     the number of bytes read.*              0 is an indication of an end of connection.*              -1 indicates a parameter error.*/int ftp_read(ftp_context_pointer ctxt, void *dest, int len) {	if (ctxt == NULL)		return(-1);	if (ctxt->data_file_desc < 0)		return(0);	if (dest == NULL)		return(-1);	if (len <= 0)		return(0);	len = recv(ctxt->data_file_desc, dest, len, 0);	if (len <= 0) {		if (len < 0)			motion_log(LOG_ERR, 1, "recv failed in ftp_read");		ftp_close_connection(ctxt);	}	return(len);}/*** ftp_close**      Close the connection and both control and transport** Parameters:**      ctxt    Pointer to an FTP context** Returns -1 in case of error, 0 otherwise*/int ftp_close(ftp_context_pointer ctxt) {	if (ctxt == NULL)		return(-1);	if (ctxt->data_file_desc >= 0) {		close(ctxt->data_file_desc);		ctxt->data_file_desc = -1;	}	if (ctxt->control_file_desc >= 0) {		ftp_quit(ctxt);		close(ctxt->control_file_desc);		ctxt->control_file_desc = -1;	}	ftp_free_context(ctxt);	return(0);}

⌨️ 快捷键说明

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