cvs: pear /PECL/smtp CREDITS EXPERIMENTAL Makefile.in TODO config.m4 package.xml php_smtp.h smtp.c smtp.php

From: Date: Fri, 30 Nov 2001 17:21:51 +0000
Subject: cvs: pear /PECL/smtp CREDITS EXPERIMENTAL Makefile.in TODO config.m4 package.xml php_smtp.h smtp.c smtp.php
Groups: php.pear.cvs 
Request: Send a blank email to pear-cvs+get-1439@lists.php.net to get a copy of this message
heyesr Fri Nov 30 12:21:51 2001 EDT Added files: /pear/PECL/smtp config.m4 CREDITS EXPERIMENTAL Makefile.in package.xml php_smtp.h smtp.c smtp.php TODO Log: Initial commit of smtp extension

Index: pear/PECL/smtp/config.m4 +++ pear/PECL/smtp/config.m4 dnl $Id: config.m4,v 1.1 2001/11/30 17:21:51 heyesr Exp $ dnl config.m4 for extension smtp dnl Comments in this file start with the string 'dnl'. dnl Remove where necessary. This file will not work dnl without editing. dnl If your extension references something external, use with: dnl PHP_ARG_WITH(smtp, for smtp support, dnl Make sure that the comment is aligned: dnl [ --with-smtp Include smtp support]) dnl Otherwise use enable: PHP_ARG_ENABLE(smtp, whether to enable smtp support, dnl Make sure that the comment is aligned: [ --enable-smtp Enable smtp support]) if test "$PHP_SMTP" != "no"; then dnl Write more examples of tests here... dnl # --with-smtp -> check with-path dnl SEARCH_PATH="/usr/local /usr" # you might want to change this dnl SEARCH_FOR="/include/smtp.h" # you most likely want to change this dnl if test -r $PHP_SMTP/; then # path given as parameter dnl SMTP_DIR=$PHP_SMTP dnl else # search default path list dnl AC_MSG_CHECKING(for smtp files in default path) dnl for i in $SEARCH_PATH ; do dnl if test -r $i/$SEARCH_FOR; then dnl SMTP_DIR=$i dnl AC_MSG_RESULT(found in $i) dnl fi dnl done dnl fi dnl dnl if test -z "$SMTP_DIR"; then dnl AC_MSG_RESULT(not found) dnl AC_MSG_ERROR(Please reinstall the smtp distribution) dnl fi dnl # --with-smtp -> add include path dnl PHP_ADD_INCLUDE($SMTP_DIR/include) dnl # --with-smtp -> chech for lib and symbol presence dnl LIBNAME=smtp # you may want to change this dnl LIBSYMBOL=smtp # you most likely want to change this dnl old_LIBS=$LIBS dnl LIBS="$LIBS -L$SMTP_DIR/lib -lm -ldl" dnl AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_SMTPLIB,1,[ ])], dnl [AC_MSG_ERROR(wrong smtp lib version or lib not found)]) dnl LIBS=$old_LIBS dnl dnl PHP_SUBST(SMTP_SHARED_LIBADD) dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $SMTP_DIR/lib, SMTP_SHARED_LIBADD) AC_DEFINE(HAVE_SMTP,1,[ ]) PHP_EXTENSION(smtp, $ext_shared) PHP_SUBST(SMTP_SHARED_LIBADD) fi Index: pear/PECL/smtp/Makefile.in +++ pear/PECL/smtp/Makefile.in # $Id: Makefile.in,v 1.1 2001/11/30 17:21:51 heyesr Exp $ LTLIBRARY_NAME = libsmtp.la LTLIBRARY_SOURCES = smtp.c LTLIBRARY_SHARED_NAME = smtp.la LTLIBRARY_SHARED_LIBADD = $(SMTP_SHARED_LIBADD) include $(top_srcdir)/build/dynlib.mk Index: pear/PECL/smtp/package.xml +++ pear/PECL/smtp/package.xml <?xml version="1.0" encoding="ISO-8859-1" ?> <!-- do not use the "Type" attribute here, that one is only for generated package.xml files --> <package> <name>pecl_smtp</name> <summary>Provides functions to send mail via smtp</summary> <status>alpha</status> <maintainer> <user>heyesr</user> <name>Richard Heyes</name> <email>heyesr@php.net</email> </maintainer> <release> <version>0.1</version> <date>2001-11-30</date> <notes> - First offical PEAR/PECL release - Probably very buggy </notes> </release> <filelist> <dir role="source" name="/" baseinstalldir="smtp"> <file>CREDITS</file> <file>EXPERIMENTAL</file> <file>TODO</file> <file>Makefile.in</file> <file>config.m4</file> <file>smtp.c</file> <file>smtp.php</file> <file>php_smtp.h</file> </dir> </filelist> </package> Index: pear/PECL/smtp/php_smtp.h +++ pear/PECL/smtp/php_smtp.h /* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: | | | +----------------------------------------------------------------------+ */ #ifndef PHP_SMTP_H #define PHP_SMTP_H extern zend_module_entry smtp_module_entry; #define phpext_smtp_ptr &smtp_module_entry #ifdef PHP_WIN32 #define PHP_SMTP_API __declspec(dllexport) #else #define PHP_SMTP_API #endif #ifdef ZTS #include "TSRM.h" #endif PHP_MINIT_FUNCTION(smtp); PHP_MSHUTDOWN_FUNCTION(smtp); PHP_RINIT_FUNCTION(smtp); PHP_RSHUTDOWN_FUNCTION(smtp); PHP_MINFO_FUNCTION(smtp); PHP_FUNCTION(smtp_connect); PHP_FUNCTION(smtp_close); PHP_FUNCTION(smtp_cmd_mail); PHP_FUNCTION(smtp_cmd_rcpt); PHP_FUNCTION(smtp_cmd_data); /* Declare any global variables you may need between the BEGIN and END macros here: ZEND_BEGIN_MODULE_GLOBALS(smtp) int global_value; char *global_string; ZEND_END_MODULE_GLOBALS(smtp) */ /* In every utility function you add that needs to use variables in php_smtp_globals, call TSRM_FETCH(); after declaring other variables used by that function, or better yet, pass in TSRMG_CC after the last function argument and declare your utility function with TSRMG_DC after the last declared argument. Always refer to the globals in your function as SMTP_G(variable). You are encouraged to rename these macros something shorter, see examples in any other php module directory. */ #ifdef ZTS #define SMTP_G(v) TSRMG(smtp_globals_id, zend_smtp_globals *, v) #else #define SMTP_G(v) (smtp_globals.v) #endif #endif /* PHP_SMTP_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode: t * End: */ Index: pear/PECL/smtp/smtp.c +++ pear/PECL/smtp/smtp.c /* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Richard Heyes <richard@phpguru.org> | | And all the people on EFnets' #php.bugs | +----------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_smtp.h" #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <netdb.h> #include <string.h> /******************** ** DEFINITIONS ********************/ #define TRUE 1 #define FALSE 0 #define SMTP_READ_BUFFER_SIZE 4096 #define SMTP_DEFAULT_PORT 25 #define SMTP_STATE_DISCONNECTED 0 #define SMTP_STATE_CONNECTED 1 #define SMTP_STATE_SEND_MAIL 2 #define SMTP_STATE_SEND_RCPT 3 #define SMTP_STATE_SEND_DATA 4 #define SMTP_STATE_EMAIL_SENT 5 typedef struct { int socket_descriptor; int state; } smtp_resource; void smtp_resource_destructor(smtp_resource *handle); int _php_smtp_validate_response(char *buffer, const char *code); int _php_smtp_send_data(smtp_resource *smtp, const char *data); int _php_smtp_get_data(smtp_resource *smtp, char *buffer); char* _php_smtp_escape(char *data); /* True global resources - no need for thread safety here */ static int le_smtp; /* {{{ smtp_functions[] * * Every user visible function must have an entry in smtp_functions[]. */ function_entry smtp_functions[] = { PHP_FE(smtp_connect, NULL) PHP_FE(smtp_close, NULL) PHP_FE(smtp_cmd_mail, NULL) PHP_FE(smtp_cmd_rcpt, NULL) PHP_FE(smtp_cmd_data, NULL) {NULL, NULL, NULL} }; /* }}} */ /* {{{ smtp_module_entry */ zend_module_entry smtp_module_entry = { STANDARD_MODULE_HEADER, "smtp", smtp_functions, PHP_MINIT(smtp), PHP_MSHUTDOWN(smtp), PHP_RINIT(smtp), PHP_RSHUTDOWN(smtp), PHP_MINFO(smtp), "0.2", STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_SMTP ZEND_GET_MODULE(smtp) #endif /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(smtp) { le_smtp = register_list_destructors(smtp_resource_destructor, NULL); return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(smtp) { return SUCCESS; } /* }}} */ /* Remove if there's nothing to do at request start */ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(smtp) { return SUCCESS; } /* }}} */ /* Remove if there's nothing to do at request end */ /* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(smtp) { return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(smtp) { php_info_print_table_start(); php_info_print_table_header(2, "SMTP Support", "Enabled"); php_info_print_table_end(); } /* }}} */ /* {{{ Resource destructor function */ void smtp_resource_destructor(smtp_resource *handle) { close(handle->socket_descriptor); efree(handle); } /* }}} */ /* {{{ proto resource smtp_connect(string server ip/host [, int server port]) Connects to the supplied SMTP server */ PHP_FUNCTION(smtp_connect) { smtp_resource *smtp; struct hostent *server_addr_resolved; struct sockaddr_in server; zval **server_addr; zval **port; int argc; unsigned short int server_port; char *buffer = (char *)emalloc(SMTP_READ_BUFFER_SIZE); char *hostname = (char *)emalloc(256); char *helo_string; /* ** Get the arguments */ argc = ZEND_NUM_ARGS(); switch(argc){ case 1: zend_get_parameters_ex(1, &server_addr); convert_to_string_ex(server_addr); server_port = SMTP_DEFAULT_PORT; break; case 2: zend_get_parameters_ex(2, &server_addr, &port); convert_to_string_ex(server_addr); convert_to_long_ex(port); server_port = (unsigned short int)Z_LVAL_PP(port); break; default: WRONG_PARAM_COUNT; } /* ** Get ip of server to connect to */ if ((server_addr_resolved = gethostbyname(Z_STRVAL_PP(server_addr))) == NULL){ /* ** Do something useful here? */ } /* ** Setup the server struct */ server.sin_family = AF_INET; server.sin_port = htons((unsigned short int)server_port); server.sin_addr.s_addr = inet_addr((char *)inet_ntoa(*((struct in_addr *)server_addr_resolved->h_addr))); memset(&(server.sin_zero), '\0', 8); /* ** Create the socket descriptor */ smtp = (smtp_resource *)emalloc(sizeof(smtp_resource)); memset(smtp, 0, sizeof(smtp_resource)); smtp->socket_descriptor = socket(AF_INET, SOCK_STREAM, 0); /* ** Connect to server */ if(connect(smtp->socket_descriptor, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1){ close(smtp->socket_descriptor); efree(smtp); RETURN_FALSE; } /* ** Get server greeting */ if(_php_smtp_get_data(smtp, buffer) == TRUE && _php_smtp_validate_response(buffer, "220") != TRUE){ close(smtp->socket_descriptor); efree(smtp); RETURN_FALSE; } /* ** Get my hostname */ if(gethostname(hostname, 256) == -1){ RETURN_FALSE; } /* ** Format the HELO ... string */ helo_string = (char *)ecalloc(1, 5 + strlen(hostname) + 1); sprintf(helo_string, "HELO %s", hostname); efree(hostname); /* ** Send the HELO string */ _php_smtp_send_data(smtp, helo_string); _php_smtp_get_data(smtp, buffer); efree(helo_string); if(_php_smtp_validate_response(buffer, "250") != TRUE){ efree(buffer); RETURN_FALSE; } efree(buffer); smtp->state = SMTP_STATE_SEND_MAIL; ZEND_REGISTER_RESOURCE(return_value, smtp, le_smtp); } /* }}} */ /* {{{ proto bool smtp_close(resource smtp_resource) Close connection to server*/ PHP_FUNCTION(smtp_close) { smtp_resource *smtp; zval **resource_id; char *quit_string; /* ** Get the argument */ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &resource_id) == FAILURE){ WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(smtp, smtp_resource *, resource_id, -1, "SMTP Connection ID", le_smtp); /* ** Send the quit command */ quit_string = estrdup("QUIT"); _php_smtp_send_data(smtp, quit_string); efree(quit_string); zend_list_delete(Z_LVAL_PP(resource_id)); RETURN_TRUE; } /* }}} */ /* {{{ proto bool smtp_cmd_mail(resource smtp_resource, string return_address) Sends MAIL FROM:<email> command*/ PHP_FUNCTION(smtp_cmd_mail) { smtp_resource *smtp; char *mail_string; char *buffer = (char *)emalloc(SMTP_READ_BUFFER_SIZE); zval **resource_id; zval **address; /* ** Get the arguments */ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &resource_id, &address) == FAILURE) { convert_to_string_ex(address); WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(smtp, smtp_resource *, resource_id, -1, "SMTP Connection ID", le_smtp); /* ** Check the state */ if(smtp->state != SMTP_STATE_SEND_MAIL) RETURN_FALSE; /* ** Format the MAIL FROM:<...> string */ mail_string = (char *)ecalloc(1, 12 + Z_STRLEN_PP(address) + 1); sprintf(mail_string, "MAIL FROM:<%s>", Z_STRVAL_PP(address)); /* ** Send the MAIL string */ _php_smtp_send_data(smtp, mail_string); _php_smtp_get_data(smtp, buffer); efree(mail_string); if(_php_smtp_validate_response(buffer, "250") == TRUE){ efree(buffer); smtp->state = SMTP_STATE_SEND_RCPT; RETURN_TRUE; } RETURN_FALSE; } /* }}} */ /* {{{ proto bool smtp_cmd_rcpt(resource smtp_resource, string recipient_address) Sends RCPT TO:<email> command*/ PHP_FUNCTION(smtp_cmd_rcpt) { smtp_resource *smtp; char *rcpt_string; char *buffer = (char *)emalloc(SMTP_READ_BUFFER_SIZE); zval **resource_id; zval **address; /* ** Get the arguments */ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &resource_id, &address) == FAILURE) { convert_to_string_ex(address); WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(smtp, smtp_resource *, resource_id, -1, "SMTP Connection ID", le_smtp); /* ** Check the state */ if(smtp->state != SMTP_STATE_SEND_RCPT && smtp->state != SMTP_STATE_SEND_DATA) RETURN_FALSE; /* ** Format the RCPT TO:<...> string */ rcpt_string = (char *)ecalloc(1, 10 + Z_STRLEN_PP(address) + 1); sprintf(rcpt_string, "RCPT TO:<%s>", Z_STRVAL_PP(address)); /* ** Send the RCPT string */ _php_smtp_send_data(smtp, rcpt_string); _php_smtp_get_data(smtp, buffer); efree(rcpt_string); if(_php_smtp_validate_response(buffer, "250") == TRUE){ efree(buffer); smtp->state = SMTP_STATE_SEND_DATA; RETURN_TRUE; } RETURN_FALSE; } /* }}} */ /* {{{ proto bool smtp_cmd_data(resource smtp_resource, string email) Sends DATA command and then the email itself*/ PHP_FUNCTION(smtp_cmd_data) { smtp_resource *smtp; char *data_string; char *buffer = (char *)emalloc(SMTP_READ_BUFFER_SIZE); char *email; char *email_final; zval **resource_id; zval **arg_email; /* ** Get the arguments */ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &resource_id, &arg_email) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(arg_email); ZEND_FETCH_RESOURCE(smtp, smtp_resource *, resource_id, -1, "SMTP Connection ID", le_smtp); /* ** Check the state */ if(smtp->state != SMTP_STATE_SEND_DATA) RETURN_FALSE; /* ** Send the DATA string */ data_string = estrdup("DATA"); _php_smtp_send_data(smtp, data_string); _php_smtp_get_data(smtp, buffer); if(_php_smtp_validate_response(buffer, "354") == TRUE){ /* ** Send the email itself */ email = estrdup(Z_STRVAL_PP(arg_email)); email = _php_smtp_escape(email); email_final = (char *)ecalloc(1, strlen(email) + 4); sprintf(email_final, "%s\r\n.", email); _php_smtp_send_data(smtp, email_final); _php_smtp_get_data(smtp, buffer); if(_php_smtp_validate_response(buffer, "250") == TRUE){ efree(email); efree(buffer); efree(data_string); smtp->state = SMTP_STATE_EMAIL_SENT; RETURN_TRUE; } } efree(email); efree(buffer); efree(data_string); RETURN_FALSE; } /* }}} */ /* {{{ proto int smtp_validate_repsonse(char *buffer, const char *code) Checks the server reponse corresonds to supplied reponse code*/ int _php_smtp_validate_response(char *buffer, const char *code){ if(strncmp(buffer, code, 3) == 0){ return TRUE; }else{ return FALSE; } } /* }}} */ /* {{{ proto int smtp_send_data(smtp_resource *smtp, const char *data) Sends a commend to the server after appending a \r\n*/ int _php_smtp_send_data(smtp_resource *smtp, const char *data){ int len_data_sent; int len_data; char *p; p = (char *)ecalloc(1, strlen(data)+3); sprintf(p, "%s\r\n", data); len_data = strlen(p); while(1){ if((len_data_sent = send(smtp->socket_descriptor, p, len_data, 0)) < len_data){ p += len_data_sent; len_data -= len_data_sent; continue; } break; } return TRUE; } /* }}} */ /* {{{ proto int smtp_get_data(smtp_resource *smtp, char *buffer) Gets server reponse*/ int _php_smtp_get_data(smtp_resource *smtp, char *buffer){ int bytes_read; memset(buffer, 0, 4096); // Ensure buffer is emtpy bytes_read = recv(smtp->socket_descriptor, buffer, 4096, 0); if(bytes_read == 0){ return FALSE; } if(bytes_read == -1){ return FALSE; } return TRUE; } /* }}} */ /* {{{ proto char *smtp_escape(char *data) Replaces \n. with \n.. in the email body*/ char *_php_smtp_escape(char *data){ char *buffer = (char *)ecalloc(1, 2 * strlen(data)); char *p = buffer; while(*data != '\0'){ if(*data == '\n' && *(data+1) == '.'){ memcpy (p, "\n.", 2); p += 2; }else{ memcpy (p, data, 1); p++; } data++; } *p = '\0'; buffer = (char *)erealloc(buffer, strlen(buffer)+1); return buffer; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 tw=78 fdm=marker * vim<600: sw=4 ts=4 tw=78 */ Index: pear/PECL/smtp/smtp.php +++ pear/PECL/smtp/smtp.php <? /* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Richard Heyes <richard@phpguru.org> | +----------------------------------------------------------------------+ */ if(!extension_loaded('smtp')) { dl('smtp.so'); } $smtp = smtp_connect('10.1.1.2', 25); if($smtp){ smtp_cmd_mail($smtp, 'return-path@example.com'); smtp_cmd_rcpt($smtp, 'recipient@example.com'); smtp_cmd_data($smtp, "To: recipient@example.com\r\nSubject: Test mail\r\n\r\nHello world!"); smtp_close($smtp); } ?>
« previous php.pear.cvs (#1439) next »