first commit
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
##
|
||||
# Makefile automatically generated by genmake 1.0, May-03-00
|
||||
# genmake 1.0 by muquit@muquit.com, http://www.muquit.com/
|
||||
##
|
||||
CC= gcc
|
||||
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_YP_GET_DEFAULT_DOMAIN=1 -DHAVE_LIBNSL=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENSSL=1 -DUNIX
|
||||
PROGNAME= mailsend
|
||||
|
||||
MUTILS_INCLUDE= -I./libs/libmutils
|
||||
MSOCK_INCLUDE= -I./libs/libmsock
|
||||
SLL_INCLUDE= -I./libs/libsll
|
||||
|
||||
MUTILS_LIB= ./libs/libmutils/libmutils.a
|
||||
MSOCK_LIB=./libs/libmsock/libmsock.a
|
||||
SLL_LIB= ./libs/libsll/libsll.a
|
||||
|
||||
OPENSSL_DIR=/usr/
|
||||
OPENSSL_INC=-I/usr/include
|
||||
#OPENSSL_LIBS=-L/usr/lib -lssl -lcrypto -ldl
|
||||
|
||||
INCLUDES= -I. -I/usr/include/malloc $(MUTILS_INCLUDE) $(MSOCK_INCLUDE) $(SLL_INCLUDE) $(OPENSSL_INC)
|
||||
|
||||
DEFINES= $(INCLUDES) $(DEFS) -DHAVE_STRING_H=1 -DHAVE_STDLIB_H=1 \
|
||||
-DHAVE_MATH_H=1
|
||||
|
||||
CFLAGS= -g -O2 -Wall $(DEFINES)
|
||||
LIBS=$(MSOCK_LIB) $(SLL_LIB) $(MUTILS_LIB) -L/usr/lib -lssl -lcrypto -ldl
|
||||
|
||||
SRCS = main.c smtp.c utils.c setget.c
|
||||
OBJS = main.o smtp.o utils.o setget.o
|
||||
|
||||
.c.o:
|
||||
rm -f $@
|
||||
$(CC) $(CFLAGS) -c $*.c
|
||||
|
||||
all: mlibs $(PROGNAME)
|
||||
|
||||
$(PROGNAME) : $(OBJS)
|
||||
$(CC) $(CFLAGS) $(OBJS) -o $(PROGNAME) $(LIBS)
|
||||
cp -f $(PROGNAME) ../modules/
|
||||
|
||||
mlibs:
|
||||
(cd libs/libmsock && make)
|
||||
(cd libs/libmutils && make)
|
||||
(cd libs/libsll && make)
|
||||
|
||||
clean:
|
||||
(cd libs/libmsock && make clean)
|
||||
(cd libs/libmutils && make clean)
|
||||
(cd libs/libsll && make clean)
|
||||
rm -f *.o *~ core $(PROGNAME)
|
||||
@@ -0,0 +1,43 @@
|
||||
##
|
||||
# Makefile Generated by genmake 1.0, Nov-16-96
|
||||
# genmake 1.0 by ma_muquit@fccc.edu, RCS
|
||||
##
|
||||
CC= gcc
|
||||
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_YP_GET_DEFAULT_DOMAIN=1 -DHAVE_LIBNSL=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENSSL=1
|
||||
AR= ar cq
|
||||
RANLIB= ranlib
|
||||
LIBNAME= libmsock.a
|
||||
|
||||
OPENSSL_DIR=/usr/
|
||||
OPENSSL_INC=-I/usr//include
|
||||
OPENSSL_LIBS=-L/usr//lib -lssl -lcrypto
|
||||
|
||||
INCLUDES= -I. -I/usr/include/malloc $(OPENSSL_INC)
|
||||
|
||||
DEFINES= $(INCLUDES) $(DEFS) -DSYS_UNIX=1
|
||||
CFLAGS= -O $(DEFINES)
|
||||
|
||||
SRCS = msock.c
|
||||
|
||||
OBJS = msock.o
|
||||
|
||||
.c.o:
|
||||
rm -f $@
|
||||
$(CC) $(CFLAGS) -c $*.c
|
||||
|
||||
all: $(LIBNAME)
|
||||
|
||||
$(LIBNAME) : $(OBJS)
|
||||
rm -f $@
|
||||
$(AR) $@ $(OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(LIBNAME) core
|
||||
|
||||
clean_all:
|
||||
make clean
|
||||
(cd examples/htget; make clean)
|
||||
(cd examples/echod; make clean)
|
||||
(cd examples/server_type; make clean)
|
||||
@@ -0,0 +1,337 @@
|
||||
/* a quick port of my libmsock routine to MS NT */
|
||||
/* muquit@Aug-20-2005 Mar 01 Eastern Standard Time 2001 */
|
||||
|
||||
#include "msock.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
static SSL *s_ssl=NULL;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
static SOCKET s_sock;
|
||||
static int ssl_status=0;
|
||||
|
||||
void msock_set_socket(SOCKET sfd)
|
||||
{
|
||||
s_sock=sfd;
|
||||
}
|
||||
|
||||
SOCKET msock_get_socket(void)
|
||||
{
|
||||
return(s_sock);
|
||||
}
|
||||
|
||||
void msock_turn_ssl_on(void)
|
||||
{
|
||||
ssl_status=1;
|
||||
}
|
||||
void msock_turn_ssl_off(void)
|
||||
{
|
||||
ssl_status=0;
|
||||
}
|
||||
int msock_is_ssl_on(void)
|
||||
{
|
||||
return(ssl_status);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
void msock_set_ssl(SSL *ssl)
|
||||
{
|
||||
s_ssl=ssl;
|
||||
}
|
||||
SSL *msock_get_ssl(void)
|
||||
{
|
||||
return(s_ssl);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
struct in_addr *atoAddr(char *address)
|
||||
{
|
||||
struct hostent
|
||||
*host;
|
||||
|
||||
static struct in_addr
|
||||
saddr;
|
||||
|
||||
saddr.s_addr=inet_addr(address);
|
||||
if (saddr.s_addr != -1)
|
||||
return (&saddr);
|
||||
|
||||
host=gethostbyname(address);
|
||||
if (host != (struct hostent *) NULL)
|
||||
return ((struct in_addr *) *host->h_addr_list);
|
||||
|
||||
return ((struct in_addr *) NULL);
|
||||
}
|
||||
|
||||
#ifdef WINNT
|
||||
/* returns 0 on success -1 on failure */
|
||||
int initWinSock(void)
|
||||
{
|
||||
WORD
|
||||
version_requested;
|
||||
|
||||
WSADATA
|
||||
wsa_data;
|
||||
|
||||
int
|
||||
err;
|
||||
|
||||
version_requested=MAKEWORD(2,0);
|
||||
err=WSAStartup(version_requested,&wsa_data);
|
||||
if (err != 0)
|
||||
{
|
||||
(void) fprintf(stderr," Unable to initialize winsock (%d)\n",err);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
#endif /* WINNT */
|
||||
|
||||
/* returns SOCKET on success INVALID_SOCKET on failure */
|
||||
SOCKET clientSocket(char *address,int port)
|
||||
{
|
||||
SOCKET
|
||||
s;
|
||||
|
||||
struct sockaddr_in
|
||||
sa;
|
||||
|
||||
struct in_addr
|
||||
*addr;
|
||||
|
||||
int
|
||||
rc;
|
||||
|
||||
#ifdef WINNT
|
||||
rc=initWinSock();
|
||||
if (rc != 0)
|
||||
return(INVALID_SOCKET);
|
||||
#endif /* WINNT */
|
||||
|
||||
addr=atoAddr(address);
|
||||
if (addr == NULL)
|
||||
{
|
||||
(void) fprintf(stderr," Invalid address: %s\n",address);
|
||||
return(INVALID_SOCKET);
|
||||
}
|
||||
|
||||
memset((char *) &sa,0,sizeof(sa));
|
||||
sa.sin_family=AF_INET;
|
||||
sa.sin_port=htons(port);
|
||||
sa.sin_addr.s_addr=addr->s_addr;
|
||||
|
||||
/* open the socket */
|
||||
s=socket(AF_INET,SOCK_STREAM,PF_UNSPEC);
|
||||
if (s == INVALID_SOCKET)
|
||||
{
|
||||
(void) fprintf(stderr," Could not create socket\n");
|
||||
return(INVALID_SOCKET);
|
||||
}
|
||||
|
||||
/* connect */
|
||||
rc=connect(s,(struct sockaddr *) &sa,sizeof(sa));
|
||||
if (rc < 0)
|
||||
return(INVALID_SOCKET);
|
||||
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** this function writes a character string out to a socket.
|
||||
** it returns -1 if the connection is closed while it is trying to
|
||||
** write
|
||||
*/
|
||||
static int sockWrite(SOCKET sock,char *str,size_t count)
|
||||
{
|
||||
size_t
|
||||
bytesSent=0;
|
||||
|
||||
int
|
||||
thisWrite;
|
||||
|
||||
while (bytesSent < count)
|
||||
{
|
||||
thisWrite=send(sock,str,count-bytesSent,0);
|
||||
/*
|
||||
(void) fprintf(stderr,"str=%s\n",str);
|
||||
(void) fprintf(stderr,"count=%d\n",count);
|
||||
*/
|
||||
|
||||
if (thisWrite <= 0)
|
||||
return (thisWrite);
|
||||
|
||||
bytesSent += thisWrite;
|
||||
str += thisWrite;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
int sockWriteSSL(SSL *ssl,char *str,size_t count)
|
||||
{
|
||||
size_t
|
||||
bytesSent=0;
|
||||
|
||||
int
|
||||
thisWrite;
|
||||
|
||||
while (bytesSent < count)
|
||||
{
|
||||
thisWrite=SSL_write(ssl,str,count-bytesSent);
|
||||
if (thisWrite <= 0)
|
||||
return (thisWrite);
|
||||
|
||||
bytesSent += thisWrite;
|
||||
str += thisWrite;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
int sockPutsSSL(SSL *ssl,char *str)
|
||||
{
|
||||
return (sockWriteSSL(ssl,str,strlen(str)));
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
int sockPuts(SOCKET sock,char *str)
|
||||
{
|
||||
return (sockWrite(sock,str,strlen(str)));
|
||||
}
|
||||
|
||||
int sockGets(SOCKET sockfd,char *str,size_t count)
|
||||
{
|
||||
int
|
||||
bytesRead;
|
||||
|
||||
int
|
||||
totalCount=0;
|
||||
|
||||
char
|
||||
buf[1],
|
||||
*currentPosition;
|
||||
|
||||
char
|
||||
lastRead=0;
|
||||
|
||||
currentPosition=str;
|
||||
|
||||
while (lastRead != 10)
|
||||
{
|
||||
bytesRead=recv(sockfd,buf,1,0);
|
||||
if (bytesRead <= 0)
|
||||
{
|
||||
/*
|
||||
** the other side may have closed unexpectedly
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
lastRead=buf[0];
|
||||
|
||||
if ((totalCount < count) && (lastRead != 10)
|
||||
&& (lastRead != 13))
|
||||
{
|
||||
*currentPosition=lastRead;
|
||||
currentPosition++;
|
||||
totalCount++;
|
||||
}
|
||||
}
|
||||
if (count > 0)
|
||||
*currentPosition=0;
|
||||
|
||||
return (totalCount);
|
||||
}
|
||||
#ifdef HAVE_OPENSSL
|
||||
int sockGetsSSL(SSL *ssl,char *str,size_t count)
|
||||
{
|
||||
int
|
||||
bytesRead;
|
||||
|
||||
int
|
||||
totalCount=0;
|
||||
|
||||
char
|
||||
buf[1],
|
||||
*currentPosition;
|
||||
|
||||
char
|
||||
lastRead=0;
|
||||
|
||||
currentPosition=str;
|
||||
while (lastRead != 10)
|
||||
{
|
||||
bytesRead=SSL_read(ssl,buf,1);
|
||||
if (bytesRead <= 0)
|
||||
{
|
||||
/*
|
||||
** the other side may have closed unexpectedly
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
lastRead=buf[0];
|
||||
|
||||
if ((totalCount < count) && (lastRead != 10)
|
||||
&& (lastRead != 13))
|
||||
{
|
||||
*currentPosition=lastRead;
|
||||
currentPosition++;
|
||||
totalCount++;
|
||||
}
|
||||
}
|
||||
if (count > 0)
|
||||
*currentPosition=0;
|
||||
|
||||
return (totalCount);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
/* must be called after msock_set_socket() */
|
||||
/* must be called after msock_set_ssl() if SSL is on */
|
||||
int msock_gets(char *str,size_t count)
|
||||
{
|
||||
if (! msock_is_ssl_on())
|
||||
{
|
||||
return(sockGets(msock_get_socket(),str,count));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
return(sockGetsSSL(msock_get_ssl(),str,count));
|
||||
#endif /* HAVE_OPENSSL */
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* must be called after msock_set_socket() */
|
||||
/* must be called after msock_set_ssl() if SSL is on */
|
||||
int msock_puts(char *str)
|
||||
{
|
||||
if (! msock_is_ssl_on())
|
||||
{
|
||||
return(sockPuts(msock_get_socket(),str));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
return(sockPutsSSL(msock_get_ssl(),str));
|
||||
#endif /* HAVE_OPENSSL */
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
void msock_close_socket(SOCKET fd)
|
||||
{
|
||||
#ifdef WINNT
|
||||
closesocket(fd);
|
||||
#else
|
||||
close(fd);
|
||||
#endif /* MSOCK_WIN32 */
|
||||
|
||||
}
|
||||
|
||||
void msock_close(void)
|
||||
{
|
||||
msock_close_socket(msock_get_socket());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef MSOCK_H
|
||||
#define MSOCK_H
|
||||
|
||||
#ifdef WINNT
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h> /* ULTRIX didn't like stat with types*/
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h> /* for inet_ntoa */
|
||||
#include <time.h> /* for ctime */
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#undef SOCKET
|
||||
#define SOCKET int
|
||||
|
||||
#undef INVALID_SOCKET
|
||||
#define INVALID_SOCKET -1
|
||||
#define _fileno fileno
|
||||
#define _isatty isatty
|
||||
|
||||
#endif /* ! WINNT */
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
SOCKET clientSocket(char *,int);
|
||||
int sockGets(SOCKET,char *,size_t);
|
||||
int sockPuts(SOCKET sock,char *str);
|
||||
|
||||
void msock_set_socket(SOCKET sock);
|
||||
SOCKET msock_get_socket(void);
|
||||
void msock_turn_ssl_on(void);
|
||||
void msock_turn_ssl_off(void);
|
||||
int msock_is_ssl_on(void);
|
||||
int msock_gets(char *buf,size_t bufsiz);
|
||||
int msock_puts(char *str);
|
||||
void msock_close_socket(SOCKET fd);
|
||||
void msock_close(void);
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
int sockGetsSSL(SSL *ssl,char *buf,size_t count);
|
||||
int sockPutsSSL(SSL *ssl,char *str);
|
||||
SSL *msock_get_ssl(void);
|
||||
void msock_set_ssl(SSL *ssl);
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
#endif /* ! MSOCK_H */
|
||||
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# ma_muquit@fccc.edu
|
||||
# jul-29-199
|
||||
#
|
||||
|
||||
CC= gcc
|
||||
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_YP_GET_DEFAULT_DOMAIN=1 -DHAVE_LIBNSL=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENSSL=1
|
||||
AR= ar cq
|
||||
RANLIB= ranlib
|
||||
LIBNAME= libmutils.a
|
||||
|
||||
INCLUDES= -I. -I/usr/include/malloc
|
||||
|
||||
# replace -O with -g in order to debug
|
||||
|
||||
DEFINES= $(INCLUDES) $(DEFS) -DSYS_UNIX=1
|
||||
CFLAGS= -O $(DEFINES)
|
||||
|
||||
SRCS = string.c mutils.c mime.c
|
||||
OBJS = string.o mutils.o mime.o
|
||||
|
||||
.c.o:
|
||||
rm -f $@
|
||||
$(CC) $(CFLAGS) -c $*.c
|
||||
|
||||
all: $(LIBNAME)
|
||||
|
||||
$(LIBNAME): $(OBJS)
|
||||
rm -f $@
|
||||
$(AR) $@ $(OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(LIBNAME) core
|
||||
@@ -0,0 +1,9 @@
|
||||
A utility library. All the functions starts with mtutils, for example:
|
||||
mutilsSafeStrcpy(), mutilsMalloc() etc. The library can be compiled with
|
||||
an ANSI or non-ANSI C compiler.
|
||||
|
||||
/* ANSIfiled, muquit@muquit.com, Mar-27-2001 */
|
||||
|
||||
--
|
||||
Muhammad Muquit
|
||||
Jul-29-199
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "mutils.h"
|
||||
#include <string.h>
|
||||
|
||||
int main (int argc,char **argv)
|
||||
{
|
||||
char
|
||||
*s=NULL;
|
||||
int
|
||||
i;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
(void) fprintf(stderr,"usage: %s <string>\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
s=strdup(argv[1]);
|
||||
(void) fprintf(stderr,"MD5(%s) %s\n",s,getMD5Digest(s));
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "mutils.h"
|
||||
|
||||
static char base64_chars[64] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
|
||||
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
|
||||
't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '+', '/'
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** generateBoundary()
|
||||
** generate unuque string for boundary for MIME tag
|
||||
**
|
||||
** Parameters:
|
||||
** char *boundary - NULL terminated boundary string - returns
|
||||
** int len - size of boundary (malloc'd or static)
|
||||
**
|
||||
** Return Values:
|
||||
** none
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** boundary must have len bytes in it to store the boundary. the
|
||||
functio
|
||||
n
|
||||
** calls rand() for random number, so the caller should call srand()
|
||||
** before calling this function.
|
||||
**
|
||||
** This function is adapted from mutt code.
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** muquit@muquit.com Mar-06-2002 needs MIME support
|
||||
*/
|
||||
#define BOUNDARY_LEN 16
|
||||
void mutilsGenerateMIMEBoundary(char *boundary,int len)
|
||||
{
|
||||
char
|
||||
*p;
|
||||
int
|
||||
i;
|
||||
memset(boundary,0,len);
|
||||
p=boundary;
|
||||
for (i=0; i < BOUNDARY_LEN; i++)
|
||||
{
|
||||
if (i >= (len-1))
|
||||
break;
|
||||
*p++ = base64_chars[rand() % sizeof(base64_chars)];
|
||||
}
|
||||
*p='\0';
|
||||
}
|
||||
|
||||
static void output64Chunk(int c1,int c2,int c3,int pads, FILE *outfile)
|
||||
{
|
||||
putc(base64_chars[c1>>2], outfile);
|
||||
putc(base64_chars[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)], outfile);
|
||||
if (pads == 2)
|
||||
{
|
||||
putc('=', outfile);
|
||||
putc('=', outfile);
|
||||
}
|
||||
else if (pads)
|
||||
{
|
||||
putc(base64_chars[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)], outfile);
|
||||
putc('=', outfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
putc(base64_chars[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)], outfile);
|
||||
putc(base64_chars[c3 & 0x3F], outfile);
|
||||
}
|
||||
}
|
||||
|
||||
void mutilsBase64Encode(FILE *ifp,FILE *ofp)
|
||||
{
|
||||
int
|
||||
c1,
|
||||
c2,
|
||||
c3,
|
||||
c4,
|
||||
ct=0;
|
||||
|
||||
while ((c1=getc(ifp)) != EOF)
|
||||
{
|
||||
c2=getc(ifp);
|
||||
if (c2 == EOF)
|
||||
{
|
||||
output64Chunk(c1,0,0,2,ofp);
|
||||
}
|
||||
else
|
||||
{
|
||||
c3=getc(ifp);
|
||||
if (c3 == EOF)
|
||||
{
|
||||
output64Chunk(c1,c2,0,1,ofp);
|
||||
}
|
||||
else
|
||||
{
|
||||
output64Chunk(c1,c2,c3,0,ofp);
|
||||
}
|
||||
}
|
||||
ct += 4;
|
||||
if (ct > 71)
|
||||
{
|
||||
putc('\r',ofp); /* qmail fix 15.07.05 (movi) */
|
||||
putc('\n',ofp);
|
||||
ct=0;
|
||||
}
|
||||
}
|
||||
if (ct)
|
||||
{
|
||||
putc('\r',ofp); /* qmail fix 15.07.05 (movi) */
|
||||
putc('\n',ofp);
|
||||
}
|
||||
|
||||
(void) fflush(ofp);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,148 @@
|
||||
#ifndef MUTILS_H
|
||||
#define MUTILS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
#include <string.h> /* ANSI string.h and pre-ANSI memory.h might conflict*/
|
||||
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#else
|
||||
#if HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#if SYS_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef WINNT
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <io.h>
|
||||
#include <share.h>
|
||||
#define ftruncate chsize
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_FCNTL_H
|
||||
#ifndef O_RDONLY /* prevent multiple inclusion on lame systems (from
|
||||
vile)*/
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_SYS_FILE_H
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#if TIME_WITH_SYS_TIME
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#else
|
||||
#if HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MUTILS_CFL __FILE__,__LINE__
|
||||
|
||||
|
||||
#if __STDC__ || defined(sgi) || defined(_AIX)
|
||||
#undef _Declare
|
||||
#define _Declare(formal_parameters) formal_parameters
|
||||
#else
|
||||
#define _Declare(formal_parameters) ()
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#define MUTILS_MAX_TOKEN_LEN 1024
|
||||
|
||||
|
||||
#define MUTILS_CHECK_MALLOC(p) \
|
||||
do \
|
||||
{ \
|
||||
if (p == NULL) \
|
||||
{\
|
||||
(void) fprintf(stderr,"%s (%d) - memory allocation problem\n",__FILE__,__LINE__); \
|
||||
goto ExitProcessing; \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
|
||||
|
||||
/* function prototypes */
|
||||
void mutilsBase64Encode (FILE *ifp,FILE *ofp);
|
||||
void mutilsGenerateMIMEBoundary(char *boundary,int len);
|
||||
int mutilsParseURL (char *url,char *hostname,
|
||||
int hostname_len, int *port,
|
||||
char *page,int page_len);
|
||||
|
||||
void mutilsStripLeadingSpace (char *s);
|
||||
void mutilsStripTrailingSpace (char *s);
|
||||
char *mutilsReverseString (char *str);
|
||||
char *mutilsStrncat (char *dst,char *src,int n);
|
||||
char *mutilsStrncpy (char *dsr,char *src,int n);
|
||||
int mutilsStrncasecmp (char *s1,char *s2,int n);
|
||||
char *mutilsStrdup (char *str);
|
||||
int mutilsStrcasecmp (char *a,char *b);
|
||||
void mutilsSafeStrcpy (char *dst,char *src,int n);
|
||||
void mutilsSafeStrcat (char *dsr,char *src,int n,int ss,int sl);
|
||||
char *mutilsStrtok (char *s,char *delim);
|
||||
int mutilsHowmanyCommas (char *buf);
|
||||
void mutilsCommaize (char *buf);
|
||||
void mutilsCleanBuf (char *buf,int bufsize,int *length);
|
||||
char *mutilsRmallws (char *str);
|
||||
char *mutilsStristr (char *s,char *t);
|
||||
int mutilsIsinname (char *string,char *mask);
|
||||
char *mutilsGetTime (void);
|
||||
char mutilsChopNL (char *str);
|
||||
int mutilsTmpFilename (char *filename);
|
||||
char *mutilsBasename (char *path);
|
||||
int mutilsWhich (char *name);
|
||||
void mutilsSetLock (int fd);
|
||||
void mutilsDotLock (char *filepath,char *errbuf);
|
||||
void mutilsDotUnlock (int delete);
|
||||
char *mutilsStrUpper (char *str);
|
||||
char *mutilsStrLower (char *str);
|
||||
int mutilsEatComment (FILE *fp);
|
||||
int mutilsEatWhitespace (FILE *fp);
|
||||
char *mutilsGetDirname (char *file);
|
||||
char *mutilsSpacesToChar (char *str,int c);
|
||||
char **mutilsTokenize(char *str,int delim,int *ntokens);
|
||||
void mutilsFreeTokens(char **tokens,int ntokens);
|
||||
unsigned char *mutils_encode_base64(void *src,unsigned long srcl,unsigned long *len);
|
||||
void *mutils_decode_base64(unsigned char *src,unsigned long srcl,unsigned long *len);
|
||||
|
||||
|
||||
#endif /* MUTILS_H */
|
||||
@@ -0,0 +1,510 @@
|
||||
/* all interesting strngs related routines */
|
||||
|
||||
#include <mutils.h>
|
||||
|
||||
|
||||
/*
|
||||
** reverseString()
|
||||
** reverse a string
|
||||
**
|
||||
** Parameters:
|
||||
** char *str string to modify
|
||||
**
|
||||
** Return Values:
|
||||
** pointer to the modified string
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** str is modified
|
||||
** borrowed from c-snippets STRREV.C, public domain by Bob Stout
|
||||
** The name of the function was stttev() -- muquit, May-26-1999
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu may-26-1999 first cut
|
||||
*/
|
||||
|
||||
char *mutilsReverseString(char *str)
|
||||
{
|
||||
char
|
||||
*p1,
|
||||
*p2;
|
||||
|
||||
if (! str || ! *str)
|
||||
return str;
|
||||
|
||||
for (p1=str,p2 =str+strlen(str)-1; p2 > p1; ++p1, --p2)
|
||||
{
|
||||
*p1 ^= *p2;
|
||||
*p2 ^= *p1;
|
||||
*p1 ^= *p2;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** mutilsStrncat()
|
||||
** appends at most n characters of src string to dst string
|
||||
**
|
||||
** Parameters:
|
||||
** dst destination string
|
||||
** src source string
|
||||
** n number of character to take from src
|
||||
**
|
||||
**
|
||||
** Return Values:
|
||||
**
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** taken from Henry Spencer's public domain string library
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Jul-31-1999 first cut
|
||||
*/
|
||||
char *mutilsStrncat(char *dst,char *src,int n)
|
||||
{
|
||||
register char
|
||||
*dscan,
|
||||
*sscan;
|
||||
|
||||
register int
|
||||
count;
|
||||
|
||||
for (dscan=dst; *dscan != '\0'; dscan++)
|
||||
continue;
|
||||
|
||||
sscan=src;
|
||||
count=n;
|
||||
|
||||
while (*sscan != '\0' && --count >= 0)
|
||||
*dscan++ = *sscan++;
|
||||
|
||||
*dscan++ = '\0';
|
||||
|
||||
return (dst);
|
||||
}
|
||||
/*
|
||||
** mutilsStrncpy()
|
||||
** copy at most n characters of string src to dst
|
||||
**
|
||||
** Parameters:
|
||||
** char *dst
|
||||
** char *str
|
||||
** int n
|
||||
**
|
||||
** Return Values:
|
||||
** pinter to the destination string
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** adapted from henry's stringlib
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Jul-31-1999 first cut
|
||||
*/
|
||||
char *mutilsStrncpy(char *dst,char *src,int n)
|
||||
{
|
||||
register char
|
||||
*dscan;
|
||||
|
||||
register char
|
||||
*sscan;
|
||||
|
||||
register int
|
||||
count;
|
||||
|
||||
dscan=dst;
|
||||
sscan=src;
|
||||
count=n;
|
||||
|
||||
while (--count >= 0 && (*dscan++ = *sscan++) != '\0')
|
||||
continue;
|
||||
|
||||
while (--count >= 0)
|
||||
*dscan++ = '\0';
|
||||
return(dst);
|
||||
}
|
||||
|
||||
/*
|
||||
** mutilsStrdup()
|
||||
** duplicate a sting
|
||||
**
|
||||
** Parameters:
|
||||
** char *string string to duplicate
|
||||
**
|
||||
** Return Values:
|
||||
** pointer to the duplicated stirng. NULL if fails.
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** allocate memory, caller is responsible to free it.
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Jul-31-1999 first cut
|
||||
*/
|
||||
char *mutilsStrdup(char *string)
|
||||
{
|
||||
char
|
||||
*tmp;
|
||||
|
||||
if (string == NULL || *string == '\0')
|
||||
return ((char *) NULL);
|
||||
|
||||
tmp = (char *) malloc ((int) strlen(string)*sizeof(char)+1 );
|
||||
|
||||
if (tmp == (char *) NULL)
|
||||
{
|
||||
return ((char *) NULL);
|
||||
}
|
||||
/* it's safe to copy this way */
|
||||
(void) strcpy(tmp, string);
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** mutilsStrcasecmp()
|
||||
** case insensitive string comparison
|
||||
**
|
||||
** Parameters:
|
||||
** char *a
|
||||
** char *b
|
||||
**
|
||||
** Return Values:
|
||||
** < 0 if a < b
|
||||
** > 0 if a > b
|
||||
** 0 if a = b
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** found somewhere on the net. I didn't write it
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Jul-31-1999 first cut
|
||||
*/
|
||||
int mutilsStrcasecmp(char *a,char *b)
|
||||
{
|
||||
register char
|
||||
ac,
|
||||
bc;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ac = *a++;
|
||||
bc = *b++;
|
||||
|
||||
if(ac == 0)
|
||||
{
|
||||
if(bc == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bc == 0)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if(ac != bc)
|
||||
{
|
||||
if(islower(ac)) ac = toupper(ac);
|
||||
if(islower(bc)) bc = toupper(bc);
|
||||
if( ac != bc )
|
||||
return ac - bc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** mutilsStrncasecmp()
|
||||
** case in-sensitive comparison wth first n bytes of fist string
|
||||
**
|
||||
** Parameters:
|
||||
** char *s1
|
||||
* char *s2
|
||||
* int n
|
||||
**
|
||||
** Return Values:
|
||||
**
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** < 0 if first n bytes of a < b
|
||||
** > 0 if first n bytes of a a > b
|
||||
** 0 if first n bytes of a a = b
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Jul-31-1999 first cut
|
||||
*/
|
||||
int mutilsStrncasecmp(char *s1,char *s2,int n)
|
||||
{
|
||||
register char
|
||||
*scan1,
|
||||
*scan2;
|
||||
|
||||
int
|
||||
count;
|
||||
|
||||
scan1=s1;
|
||||
scan2=s2;
|
||||
count=n;
|
||||
|
||||
while (--count >= 0 && *scan1 != '\0' && tolower(*scan1) == tolower(*scan2))
|
||||
{
|
||||
scan1++;
|
||||
scan2++;
|
||||
}
|
||||
if (count < 0)
|
||||
return (0);
|
||||
|
||||
|
||||
return(tolower(*scan1) - tolower(*scan2));
|
||||
}
|
||||
|
||||
/*
|
||||
** mutilsSafeStrcpy()
|
||||
** copy a string to another safely without overflowing buffer
|
||||
**
|
||||
** RCS
|
||||
** $Revision: 1 $
|
||||
** $Date: 2/24/04 8:38p $
|
||||
** Return Values:
|
||||
** none
|
||||
**
|
||||
** Parameters:
|
||||
** dst destination buffer
|
||||
** src source buffer
|
||||
** n max allowable n of the src
|
||||
**
|
||||
** Side Effects:
|
||||
** if copying is safe, dst buffer is modified.
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** if the source string is longer than n, it's truncated to
|
||||
** n. dst must be static or dynamically allocated buffer, that
|
||||
** is it must be able to hold atleast lenth bytes buffer. The src
|
||||
** is checked if it is NULL or not. if NULL the routine will exit
|
||||
** after writing an error message image.
|
||||
**
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Oct-17-1997 first cut
|
||||
*/
|
||||
void mutilsSafeStrcpy(char *dst,char *src,int n)
|
||||
{
|
||||
/* now copy */
|
||||
/*
|
||||
(void) mutilsStrncpy(dst,src,n);
|
||||
*/
|
||||
(void) strncpy(dst,src,n);
|
||||
dst[n]='\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* mutilsSafeStrcat()
|
||||
* safely appends one string to another without overflowing the source
|
||||
* buffer.
|
||||
*
|
||||
* Parameters:
|
||||
* dst appends with this string
|
||||
* src string to append
|
||||
* length first this many character of src to append
|
||||
* ssc_size maximum size of destination string
|
||||
* ssc_length length of string in destination buffer
|
||||
*
|
||||
* Return Values:
|
||||
* none
|
||||
*
|
||||
* Limitations and Comments:
|
||||
* dst must have enough space staically or dynamically allocated
|
||||
* before calling. Need to provide a portable strncat() as matt
|
||||
* suggested that some versions of strncat (e.g. solaris 2.5.1) write
|
||||
* at most n+1 characters past the end of s1 and then replace the
|
||||
* n+1st character with a '\0';
|
||||
*
|
||||
*
|
||||
* Development History:
|
||||
* who when why
|
||||
* ma_muquit@fccc.edu Oct-1997 first cut
|
||||
* mhpower@mit.edu Nov-03-1997 fixed
|
||||
*/
|
||||
void mutilsSafeStrcat(char *dst,char *src,int length,int ssc_size,
|
||||
int ssc_length)
|
||||
{
|
||||
int copy_length;
|
||||
|
||||
if ( NULL == src )
|
||||
{
|
||||
/*
|
||||
StringImage("Source buffer is NULL in safeStrcat()!");
|
||||
*/
|
||||
(void) fprintf(stderr,"Source buffer is NULL in safeStrcat()!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (strlen(src) >= ssc_size - ssc_length)
|
||||
{
|
||||
/*
|
||||
StringImage("buffer overflow detected! aborting");
|
||||
*/
|
||||
(void) fprintf(stderr,"buffer overflow detected! aborting\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (length < ssc_size - ssc_length)
|
||||
{
|
||||
copy_length = length;
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_length = ssc_size - ssc_length;
|
||||
}
|
||||
|
||||
/* now copy */
|
||||
(void) mutilsStrncat(dst,src,copy_length);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
** I'm renaming it to mystrtok() in order to avoid conflict with the
|
||||
** system which might have it
|
||||
** I also formatted to my coding style
|
||||
** 10/08/95, muquit@semcor.com
|
||||
*/
|
||||
|
||||
char *mutilsStrtok(char *s,char *delim)
|
||||
{
|
||||
register char
|
||||
*spanp;
|
||||
|
||||
register int
|
||||
c,
|
||||
sc;
|
||||
|
||||
char
|
||||
*tok;
|
||||
|
||||
static char
|
||||
*last;
|
||||
|
||||
|
||||
if (s == (char *) NULL && (s = last) == (char *) NULL)
|
||||
return ((char *) NULL);
|
||||
|
||||
/*
|
||||
** Skip (span) leading delimiters (s += strspn(s, delim), sort of).
|
||||
*/
|
||||
cont:
|
||||
c = *s++;
|
||||
for (spanp = (char *)delim; (sc = *spanp++) != 0;)
|
||||
{
|
||||
if (c == sc)
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (c == 0)
|
||||
{ /* no non-delimiter characters */
|
||||
last = (char *) NULL;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
tok = s - 1;
|
||||
|
||||
/*
|
||||
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
|
||||
* Note that delim must have one NUL; we stop if we see that, too.
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
c = *s++;
|
||||
spanp = (char *)delim;
|
||||
do
|
||||
{
|
||||
if ((sc = *spanp++) == c)
|
||||
{
|
||||
if (c == 0)
|
||||
s = (char *) NULL;
|
||||
else
|
||||
s[-1] = '\0';
|
||||
last = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** convert a string to upper case
|
||||
** borrowed from C snippets library (strupr.c)
|
||||
*/
|
||||
char *mutilsStrUpper(char *str)
|
||||
{
|
||||
char
|
||||
*s;
|
||||
|
||||
if (str)
|
||||
{
|
||||
for (s=str; *s; ++s)
|
||||
*s=toupper(*s);
|
||||
}
|
||||
|
||||
return (str);
|
||||
}
|
||||
|
||||
/*
|
||||
** convert a string to lower case
|
||||
** borrowed from C snippets library (strupr.c)
|
||||
*/
|
||||
char *mutilsStrLower(char *str)
|
||||
{
|
||||
char
|
||||
*s;
|
||||
|
||||
if (str)
|
||||
{
|
||||
for (s=str; *s; ++s)
|
||||
*s=tolower(*s);
|
||||
}
|
||||
|
||||
return (s);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "mutils.h"
|
||||
|
||||
int main (int argc,char **argv)
|
||||
{
|
||||
int
|
||||
rc;
|
||||
if (argc != 3)
|
||||
{
|
||||
(void) fprintf(stderr," usage: %s <string> <mask>\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rc=mutilsIsinname(argv[1],argv[2]);
|
||||
if (rc)
|
||||
(void) fprintf(stderr,"%s %s fits\n",argv[1],argv[2]);
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "mutils.h"
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
char
|
||||
buf[BUFSIZ];
|
||||
|
||||
FILE
|
||||
*ifp,
|
||||
*ofp;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
(void) fprintf(stderr,"usage: %s file\n",argv[0]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
(void) sprintf(buf,"%s.b64",argv[1]);
|
||||
ifp=fopen(argv[1],"r");
|
||||
if (ifp == NULL)
|
||||
{
|
||||
(void) fprintf(stderr,"could not open for reading: %s\n",argv[1]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
ofp=fopen(buf,"w");
|
||||
if (ofp == NULL)
|
||||
{
|
||||
(void) fprintf(stderr,"could not open for writing: %s\n",buf);
|
||||
return (1);
|
||||
}
|
||||
|
||||
mutilsBase64Encode(ifp,ofp);
|
||||
|
||||
(void) fclose(ifp);
|
||||
(void) fclose(ofp);
|
||||
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# for Singly linked list package.
|
||||
# muhammad a muquit
|
||||
# Aug-07-1998
|
||||
#
|
||||
CC= gcc
|
||||
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_YP_GET_DEFAULT_DOMAIN=1 -DHAVE_LIBNSL=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENSSL=1
|
||||
AR= ar cq
|
||||
RANLIB= ranlib
|
||||
LIBNAME= libsll.a
|
||||
|
||||
INCLUDES= -I. -I/usr/include/malloc
|
||||
|
||||
# replace -O with -g in order to debug
|
||||
|
||||
DEFINES= $(INCLUDES) $(DEFS) -DSYS_UNIX=1
|
||||
CFLAGS= -O $(DEFINES)
|
||||
|
||||
SRCS = sll.c
|
||||
OBJS = sll.o
|
||||
|
||||
.c.o:
|
||||
rm -f $@
|
||||
$(CC) $(CFLAGS) -c $*.c
|
||||
|
||||
all: $(LIBNAME)
|
||||
|
||||
$(LIBNAME): $(OBJS)
|
||||
rm -f $@
|
||||
$(AR) $@ $(OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
sll.o: sll.h
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(LIBNAME) core a.out
|
||||
|
||||
realclean:
|
||||
rm -f $(OBJS) $(LIBNAME) core a.out config.cache config.log config.status
|
||||
(cd examples/append;make clean)
|
||||
(cd examples/append_sorted;make clean)
|
||||
(cd examples/delete;make clean)
|
||||
(cd examples/insert;make clean)
|
||||
@@ -0,0 +1,419 @@
|
||||
#include "sll.h"
|
||||
|
||||
/*
|
||||
** private protos
|
||||
static void freeList(Sll **list);
|
||||
*/
|
||||
|
||||
/*
|
||||
** initList()
|
||||
** initialize a list
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **list list to initialize
|
||||
**
|
||||
** Return Values:
|
||||
** none
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** none
|
||||
**
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-07-1998 first cut
|
||||
*/
|
||||
void initList(Sll **list)
|
||||
{
|
||||
(*list)=NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** allocateNode()
|
||||
** allocate a new node.
|
||||
**
|
||||
** Parameters:
|
||||
** void *data a generic pointer to object data
|
||||
**
|
||||
** Return Values:
|
||||
** pointer to Sll if succeeds
|
||||
** NULL otherwise
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** the caller must pass valid pointer to data.
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-07-1998 first cut
|
||||
*/
|
||||
|
||||
Sll *allocateNode(void *data)
|
||||
{
|
||||
char
|
||||
*func="allocateNode() in sll.c";
|
||||
|
||||
Sll
|
||||
*sll;
|
||||
|
||||
sll=(Sll *) malloc(sizeof(Sll));
|
||||
if (sll == (Sll *) NULL)
|
||||
{
|
||||
(void) fprintf(stderr,"malloc failed at: %s\n",func);
|
||||
return ((Sll *) NULL);
|
||||
}
|
||||
|
||||
sll->data=data;
|
||||
sll->next=NULL;
|
||||
|
||||
return (sll);
|
||||
}
|
||||
|
||||
/*
|
||||
** appendNode()
|
||||
** appends a node to the end of a list
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **head - modify the list
|
||||
** Sll **new - appends this node
|
||||
**
|
||||
** Return Values:
|
||||
** None
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** new node must be allocated and initialized before passing it here
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-07-1998 first cut
|
||||
*/
|
||||
|
||||
void appendNode(Sll **head,Sll **new)
|
||||
{
|
||||
Sll
|
||||
*tmp;
|
||||
|
||||
if (emptyList(*head) == TRUE)
|
||||
{
|
||||
(*head)=(*new);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (tmp=(*head); tmp->next != NULL; tmp=tmp->next)
|
||||
;
|
||||
tmp->next=(*new);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** appendNodeSorted()
|
||||
** appends a node to the end of a list sorting by a user defined function
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **head - append at the ends of this node
|
||||
** Sll **new - appends this node
|
||||
**
|
||||
** Return Values:
|
||||
** None
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** new node must be allocated and initialized before passing it here
|
||||
** the function takes two arguments, void * each
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-07-1998 first cut
|
||||
*/
|
||||
|
||||
void appendNodeSorted(Sll **head,Sll **new,Ifunc compFunc)
|
||||
{
|
||||
Sll
|
||||
*tmp;
|
||||
|
||||
if (emptyList(*head) == TRUE)
|
||||
{
|
||||
(*head)=(*new);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*compFunc)((*head)->data,(*new)->data) > 0)
|
||||
{
|
||||
(*new)->next=(*head);
|
||||
(*head)=(*new);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(tmp=(*head); tmp->next; tmp=tmp->next)
|
||||
{
|
||||
if ((*compFunc)(tmp->next->data,(*new)->data) > 0)
|
||||
break;
|
||||
}
|
||||
(*new)->next=tmp->next;
|
||||
tmp->next=(*new);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** insertNode()
|
||||
** insert a node at the beginning of a list
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **head - modify this list
|
||||
** Sll **new - appends this node
|
||||
**
|
||||
** Return Values:
|
||||
** None
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** new node must be allocated and initialized before passing it here
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-07-1998 first cut
|
||||
*/
|
||||
|
||||
void insertNode(Sll **head,Sll **new)
|
||||
{
|
||||
|
||||
(*new)->next=(*head);
|
||||
(*head)=(*new);
|
||||
}
|
||||
|
||||
/*
|
||||
** emptyList()
|
||||
** check if a list variable is NULL
|
||||
**
|
||||
** Parameters:
|
||||
** Sll *list list
|
||||
**
|
||||
** Return Values:
|
||||
** TRUE if empty
|
||||
** FALSE if not empty
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** list must be allocated/initialized or initialized before calling
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-07-1998 first cut
|
||||
*/
|
||||
|
||||
Bool emptyList(Sll *list)
|
||||
{
|
||||
return ((list == NULL) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
** delNode()
|
||||
** remove a node from a list
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **head - list to modify
|
||||
** Sll *node - node to remove
|
||||
**
|
||||
** Return Values:
|
||||
** none
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** list is modified
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-07-1998 first cut
|
||||
*/
|
||||
void delNode(Sll **head,Sll *node)
|
||||
{
|
||||
if (emptyList(*head) == TRUE)
|
||||
return;
|
||||
|
||||
if ((*head) == node)
|
||||
(*head)=(*head)->next;
|
||||
else
|
||||
{
|
||||
Sll
|
||||
*l;
|
||||
for (l=(*head); l != NULL && l->next != node; l=l->next);
|
||||
if (l == NULL)
|
||||
return;
|
||||
else
|
||||
l->next=node->next;
|
||||
}
|
||||
freeNode(&node);
|
||||
}
|
||||
|
||||
/*
|
||||
** freeNode()
|
||||
** frees a node
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **list node to free
|
||||
**
|
||||
** Return Values:
|
||||
** none
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** if list is not null, it wil be freed. so list better point to a valid
|
||||
** location
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-07-1998 first cut
|
||||
*/
|
||||
|
||||
void freeNode(Sll **list)
|
||||
{
|
||||
if (*list)
|
||||
{
|
||||
(void) free ((char *) (*list));
|
||||
(*list)=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** getNthNode()
|
||||
** get nth node in a list
|
||||
**
|
||||
** Parameters:
|
||||
** Sll *list - the head list
|
||||
** int n - return the node
|
||||
** Return Values:
|
||||
** a pointer to the list at position n
|
||||
** NULL if there's no such node at posion n
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** position starts at 1
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-08-1998 frist cut
|
||||
*/
|
||||
|
||||
Sll *getNthNode(Sll *list,int n)
|
||||
{
|
||||
Sll
|
||||
*lp=NULL;
|
||||
int
|
||||
j=0;
|
||||
|
||||
for (lp=list; lp; lp=lp->next)
|
||||
{
|
||||
j++;
|
||||
if (j == n)
|
||||
{
|
||||
return (lp);
|
||||
}
|
||||
}
|
||||
|
||||
return ((Sll *) NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
** destroyNode()
|
||||
** frees a node and the data associated with it
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **list - modify this list
|
||||
** SLl *node - remove the node
|
||||
** void (*freeFunc)() - pointer to function to free the data
|
||||
**
|
||||
** Return Values:
|
||||
** none
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** none
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-08-1998 first cut
|
||||
*/
|
||||
|
||||
/*
|
||||
void destroyNode(Sll **list,Sll *node,void (*freeFunc)(void **))
|
||||
*/
|
||||
void destroyNode(Sll **list,Sll *node,Vfunc freeFunc)
|
||||
{
|
||||
if (emptyList(node) == FALSE)
|
||||
{
|
||||
/*
|
||||
** destroy the data
|
||||
*/
|
||||
if (freeFunc != NULL)
|
||||
(*freeFunc) (&(node->data));
|
||||
|
||||
delNode(list,node);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** destroyNodes()
|
||||
** destroy the entire linked list and the data
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **head - head node of the list
|
||||
** freeFunc - function to free data
|
||||
**
|
||||
** Return Values:
|
||||
** none
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** whole list and the data associated are freed
|
||||
**
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-08-1998 first cut
|
||||
*/
|
||||
|
||||
/*
|
||||
void destroyNodes(Sll **head,void (*freeFunc)(void **))
|
||||
*/
|
||||
void destroyNodes(Sll **head,Vfunc freeFunc)
|
||||
{
|
||||
Sll
|
||||
*lp;
|
||||
while (*head)
|
||||
{
|
||||
lp=(*head);
|
||||
if (freeFunc != NULL)
|
||||
(*freeFunc) (&lp->data);
|
||||
(*head)=(*head)->next;
|
||||
(void) free((char *) lp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** numNodes()
|
||||
** returns number of nodes in the list
|
||||
**
|
||||
** Parameters:
|
||||
** Sll **head - the head node of the list
|
||||
**
|
||||
** Return Values:
|
||||
** number of node/s
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** traverse the whole list, so not efficient
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** ma_muquit@fccc.edu Aug-09-1998 first cut
|
||||
*/
|
||||
|
||||
int numNodes(Sll **head)
|
||||
{
|
||||
int
|
||||
n=0;
|
||||
|
||||
Sll
|
||||
*lp;
|
||||
|
||||
for (lp=(*head); lp; lp=lp->next)
|
||||
{
|
||||
n++;
|
||||
}
|
||||
|
||||
return (n);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#ifndef SLL_H
|
||||
#define SLL_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if TIME_WITH_SYS_TIME
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#else
|
||||
#if HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WINNT
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
#ifdef WINNT
|
||||
#include <io.h>
|
||||
#include <share.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define SLL_SUCCESS 0
|
||||
#define SLL_ERROR -1
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
typedef void (*Vfunc)(void **);
|
||||
typedef int (*Ifunc)(void *,void *);
|
||||
|
||||
|
||||
/*
|
||||
** the linked list structure
|
||||
*/
|
||||
|
||||
typedef struct _Sll
|
||||
{
|
||||
void
|
||||
*data; /* void pointer for user data */
|
||||
|
||||
struct _Sll
|
||||
*next; /* pointer to next node */
|
||||
} Sll;
|
||||
|
||||
/*
|
||||
** function prototypes
|
||||
*/
|
||||
Sll *allocateNode (void *data);
|
||||
void appendNodeSorted (Sll **head,Sll **new,Ifunc compFunc);
|
||||
void appendNode (Sll **list,Sll **new);
|
||||
void delNode (Sll **list,Sll *node);
|
||||
/*
|
||||
void destroyNode (Sll **list,Sll *node,
|
||||
void (*freeFunc)(void **));
|
||||
*/
|
||||
void destroyNode (Sll **list,Sll *node,Vfunc freeFunc);
|
||||
/*
|
||||
void destroyNodes (Sll **head,
|
||||
void (*freeFunc)(void **));
|
||||
*/
|
||||
void destroyNodes (Sll **head,Vfunc freeFunc);
|
||||
Bool emptyList (Sll *list);
|
||||
void freeNode (Sll **list);
|
||||
Sll *getNthNode (Sll *list,int n);
|
||||
void initList (Sll **list);
|
||||
void insertNode (Sll **list,Sll **new);
|
||||
int numNodes (Sll **head);
|
||||
|
||||
#endif /* SLL_H */
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,228 @@
|
||||
#ifndef MAILSEND_H
|
||||
#define MAILSEND_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "mutils.h"
|
||||
#include "msock.h"
|
||||
#include "sll.h"
|
||||
|
||||
#ifdef UNIX
|
||||
#include <signal.h>
|
||||
#endif /* UNIX */
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
/*
|
||||
** header for mailsend - a simple mail sender via SMTP
|
||||
** $Id: mailsend.h,v 1.3 2002/06/22 21:17:29 muquit Exp $
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** muquit@muquit.com Mar-23-2001 first cut
|
||||
*/
|
||||
|
||||
#define BUFSIZ 32768
|
||||
|
||||
#define MFL __FILE__,__LINE__
|
||||
|
||||
#define MAILSEND_VERSION "@(#) mailsend v1.15b5"
|
||||
#define MAILSEND_PROG "mailsend"
|
||||
#define MAILSEND_AUTHOR "muquit@muquit.com"
|
||||
#define MAILSEND_URL "http://www.muquit.com/"
|
||||
#define NO_SPAM_STATEMENT "GNU GPL. It is illegal to use this software for Spamming"
|
||||
|
||||
#define MAILSEND_SMTP_PORT 587 // 25
|
||||
#define MAILSEND_DEF_SUB ""
|
||||
|
||||
|
||||
#define A_SPACE ' '
|
||||
#define A_DASH '-'
|
||||
|
||||
#define EMPTY_OK 0x01
|
||||
#define EMPTY_NOT_OK 0x02
|
||||
#define ATTACHMENT_SEP ','
|
||||
|
||||
#define FILE_TYPE_DOS 0x00000001
|
||||
#define FILE_TYPE_UNIX 0x00000002
|
||||
#define FILE_TYPE_BINARY 0x00000004
|
||||
|
||||
|
||||
#ifdef EXTERN
|
||||
#undef EXTERN
|
||||
#endif /* EXTERN */
|
||||
|
||||
#ifndef __MAIN__
|
||||
#define EXTERN extern
|
||||
#else
|
||||
#define EXTERN
|
||||
#endif /* __MAIN__ */
|
||||
|
||||
#ifdef WINNT
|
||||
#define snprintf _snprintf
|
||||
#endif /* WINNT */
|
||||
|
||||
#define CFL __FILE__,__LINE__
|
||||
|
||||
#define CHECK_MALLOC(x) \
|
||||
do \
|
||||
{ \
|
||||
if (x == NULL) \
|
||||
{ \
|
||||
(void) fprintf(stderr,"%s (%d) - Memory allocation failed\n",CFL); \
|
||||
exit(0); \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define CHECK_USERNAME(mech) \
|
||||
do \
|
||||
{ \
|
||||
if (*g_username == '\0') \
|
||||
{ \
|
||||
(void) fprintf(stderr,"\nError: No user name specified for 'AUTH %s'\n",mech); \
|
||||
(void) fprintf(stderr," use the flag '-user username'\n\n");\
|
||||
rc=(-1);\
|
||||
goto cleanup; \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define CHECK_USERPASS(mech) \
|
||||
do \
|
||||
{ \
|
||||
if (*g_userpass == '\0') \
|
||||
{ \
|
||||
(void) fprintf(stderr,"\nError: No password specified for user %s for 'AUTH %s'\n",g_username,mech); \
|
||||
(void) fprintf(stderr," user '-pass password' or env var SMTP_USER_PASS\n\n");\
|
||||
rc=(-1);\
|
||||
goto cleanup; \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define ERR_STR strerror(errno)
|
||||
|
||||
EXTERN int g_verbose;
|
||||
EXTERN int g_wait_for_cr;
|
||||
EXTERN int g_do_starttls;
|
||||
EXTERN int g_quiet;
|
||||
EXTERN int g_do_auth;
|
||||
EXTERN int g_esmtp;
|
||||
EXTERN int g_auth_plain;
|
||||
EXTERN int g_auth_cram_md5;
|
||||
EXTERN int g_auth_login;
|
||||
EXTERN char g_charset[33];
|
||||
EXTERN char g_username[64];
|
||||
EXTERN char g_userpass[64];
|
||||
EXTERN char g_from_name[64];
|
||||
|
||||
typedef struct _Address
|
||||
{
|
||||
|
||||
/*
|
||||
** label holds strings like "To" "Cc" "Bcc".
|
||||
** The address is the email address.
|
||||
*/
|
||||
|
||||
char
|
||||
*label, /* To: Cc: Bcc: */
|
||||
*address; /* the email address */
|
||||
}Address;
|
||||
|
||||
typedef struct _Attachment
|
||||
{
|
||||
char
|
||||
*file_path,
|
||||
*file_name;
|
||||
char
|
||||
*mime_type;
|
||||
char
|
||||
*content_disposition;
|
||||
}Attachment;
|
||||
|
||||
/* the mail sturct */
|
||||
typedef struct _TheMail
|
||||
{
|
||||
SOCKET
|
||||
fd;
|
||||
|
||||
Address
|
||||
*address;
|
||||
|
||||
char
|
||||
*from,
|
||||
*subject,
|
||||
*x_mailer,
|
||||
*smtp_server,
|
||||
*helo_domain,
|
||||
*msg_file;
|
||||
} TheMail;
|
||||
|
||||
|
||||
/* struct for $HOME/.mailsendrc */
|
||||
typedef struct _Mailsendrc
|
||||
{
|
||||
char
|
||||
*domain,
|
||||
*from,
|
||||
*smtp_server;
|
||||
}Mailsendrc;
|
||||
|
||||
/* function prototypes */
|
||||
char *xStrdup(char *string);
|
||||
int addAddressToList(char *a,char *label);
|
||||
TheMail *initTheMail(void);
|
||||
Address *newAddress(void);
|
||||
Sll *getAddressList(void);
|
||||
void printAddressList(void);
|
||||
void print_server_caps(void);
|
||||
char *check_server_cap(char *what);
|
||||
int read_smtp_line();
|
||||
void show_smtp_info(char *smtp_server,int port,char *domain);
|
||||
int send_the_mail(char *from,char *to,char *cc,char *bcc,char *sub,
|
||||
char *smtp_server,int smtp_port,char *helo_domain,
|
||||
char *attach_file,char *txt_msg_file,char *the_msg,
|
||||
int is_mime,char *rrr,char *rt,int add_dateh);
|
||||
TheMail *newTheMail(void);
|
||||
void errorMsg(char *format,...);
|
||||
void showVerbose(char *format,...);
|
||||
void print_info(char *format,...);
|
||||
int addAddressesFromFileToList(char *adress_list_file);
|
||||
int validateMusts(char *from,char *to,char *smtp_server,
|
||||
char *helo_domain);
|
||||
char *askFor(char *buf,int buflen,char *label,int loop);
|
||||
int isInConsole(int fd);
|
||||
int add_attachment_to_list(char *file_path_mime);
|
||||
int add_server_cap_to_list(char *capability);
|
||||
Sll *get_attachment_list();
|
||||
Sll *get_server_caps_list();
|
||||
void print_attachemtn_list();
|
||||
char *fix_to(char *to);
|
||||
int isInteractive(void);
|
||||
int get_filepath_mimetype(char *str,char *filename,int fn_size,
|
||||
char *mype_type,int mt_size);
|
||||
int rfc822_date(time_t when,char *datebuf,int bufsiz);
|
||||
|
||||
void openssl_init_init_SSLLibrary(void);
|
||||
int do_tls(int sfd);
|
||||
void initialize_openssl(char *cipher);
|
||||
char *encode_cram_md5(char *challenge,char *user,char *pass);
|
||||
int guess_file_type(char *path,unsigned int *flag);
|
||||
#ifdef HAVE_OPENSSL
|
||||
void print_cert_info(SSL *ssl);
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
#endif /* ! MAIL_SEND_H */
|
||||
@@ -0,0 +1,948 @@
|
||||
/*
|
||||
** main for mailsend - a simple mail sender via SMTP protocol
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** I needed to send a alert mail from a bare-bone networked NT machine,
|
||||
** but could not find a simple mail sender to do this (not surprised!).
|
||||
** so I wrote this one!
|
||||
**
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** muquit@muquit.com Mar-23-2001 first cut
|
||||
*/
|
||||
|
||||
#define __MAIN__ 1
|
||||
|
||||
#include "mailsend.h"
|
||||
//#include "../cgi.h"
|
||||
|
||||
//extern C_Cfg *cfg;
|
||||
|
||||
/* exits after writing the usage */
|
||||
static void usage(void)
|
||||
{
|
||||
char
|
||||
**p;
|
||||
|
||||
static char
|
||||
*options[]=
|
||||
{
|
||||
" -smtp hostname/IP* - of the SMTP server",
|
||||
" -port SMTP port - SMTP port",
|
||||
" -d domain - domain name for SMTP HELO/EHLO",
|
||||
" -t to,to..* - email address/es of the reciepient/s",
|
||||
" -cc cc,cc.. - Carbon copy address/es",
|
||||
" +cc - don't ask for Carbon Copy",
|
||||
" -bc bcc,bcc.. - Blind carbon copy address/es",
|
||||
" +bc - don't ask for Blind carbon copy",
|
||||
" +D - don't add Date header",
|
||||
" -f address* - email address of the sender",
|
||||
" -sub subject - subject",
|
||||
" -l file - a file containing the email addresses",
|
||||
" -attach file,mime_type,[i/a] (i=inline,a=attachment)",
|
||||
" - attach this file as attachment or inline",
|
||||
" -cs character set - for text/plain attachments (default is us-ascii)",
|
||||
" -M \"one line msg\" - attach this one line text message",
|
||||
" -name \"Full Name\" - add name in the From header",
|
||||
" -v - verbose mode",
|
||||
" -V - show version info",
|
||||
" -w - wait for a CR after sending the mail",
|
||||
" -rt email_address - add Reply-To header",
|
||||
" -rrr email_address - request read receipts to this address",
|
||||
" -starttls - Check for STARTTLS and if server supports, do it",
|
||||
" -auth - Try CRAM-MD5,LOGIN,PLAIN in that order",
|
||||
" -auth-cram-md5 - use AUTH CRAM-MD5 authentication",
|
||||
" -auth-plain - use AUTH PLAIN authentication",
|
||||
" -auth-login - use AUTH LOGIN authentication",
|
||||
" -user username - username for ESMTP authentication",
|
||||
" -pass password - password for ESMTP authentication",
|
||||
" -example - show examples",
|
||||
" -ehlo - force EHLO",
|
||||
" -info - show SMTP server information",
|
||||
" -help - shows this help",
|
||||
" -q - quiet",
|
||||
(char *) NULL
|
||||
};
|
||||
(void) printf("\n");
|
||||
(void) printf("Version: %.1024s\n\n",MAILSEND_VERSION);
|
||||
(void) printf("Copyright: %.1024s\n\n",NO_SPAM_STATEMENT);
|
||||
#ifdef HAVE_OPENSSL
|
||||
(void) fprintf(stdout,"(Compiled with %s)\n",
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
#else
|
||||
(void) fprintf(stdout,"(Not compiled with OpenSSL)\n");
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
(void) printf("usage: mailsend [options]\n");
|
||||
(void) printf("Where the options are:\n");
|
||||
|
||||
for (p=options; *p != NULL; p++)
|
||||
(void) printf("%s\n",*p);
|
||||
|
||||
(void) fprintf(stdout,"\nThe options with * must the specified\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void show_examples(void)
|
||||
{
|
||||
(void) fprintf(stdout,"Example (Note: type without newline):\n");
|
||||
(void) fprintf(stderr,
|
||||
"Show server info:\n"
|
||||
" mailsend -info -smtp smtp.gmail.com\n\n");
|
||||
|
||||
(void) fprintf(stdout,
|
||||
" mailsend -f muquit@example.com -d example.com -smtp 10.100.30.1\n"
|
||||
" -t muquit@muquit.com -sub test -a \"file.txt,text/plain\"\n"
|
||||
" -a \"/usr/file.gif,image/gif\" -a \"file.jpeg,image/jpg\"\n\n");
|
||||
|
||||
(void) fprintf(stdout,
|
||||
" mailsend -f muquit@example.com -d example.com -smtp 192.168.0.2\n"
|
||||
" -t muquit@muquit.com -sub test +cc +bc\n"
|
||||
" -a \"c:\\file.gif,image/gif\" -M \"Sending a GIF file\"\n\n");
|
||||
|
||||
(void) fprintf(stdout,
|
||||
" mailsend -f muquit@example.com -d example.com -smtp 192.168.0.2\n"
|
||||
" -t muquit@muquit.com -sub test +cc +bc -cs \"ISO-8859-1\"\n"
|
||||
" -a \"file2.txt,text/plain\"\n\n");
|
||||
|
||||
(void) fprintf(stdout,"Change content disposition to inline:\n");
|
||||
(void) fprintf(stdout,
|
||||
" mailsend -f muquit@example.com -d example.com -smtp 10.100.30.1\n"
|
||||
" -t muquit@muquit.com -sub test -a \"nf.jpg,image/jpeg,i\"\n"
|
||||
" -M \"content disposition is inline\"\n\n");
|
||||
|
||||
(void) fprintf(stdout,"STARTTLS+AUTH PLAIN:\n");
|
||||
(void) fprintf(stdout,
|
||||
" mailsend -f muquit@example.com -d example.com -smtp smtp.gmail.com\n"
|
||||
" -sub test -from muquit@muquit.com +cc +bc -v -starttls -auth-plain\n"
|
||||
" -user you -pass 'secert'\n\n");
|
||||
|
||||
(void) fprintf(stdout,"STARTTLS+AUTH CRAM-MD5:\n");
|
||||
(void) fprintf(stdout,
|
||||
" mailsend -f muquit@example.com -d example.com -smtp 1.2.3.4\n"
|
||||
" -sub test -from muquit@muquit.com +cc +bc -v -starttls -auth-cram-md5\n"
|
||||
" -user you -pass 'secert'\n\n");
|
||||
|
||||
(void) fprintf(stdout,"STARTTLS+AUTH LOGIN:\n");
|
||||
(void) fprintf(stdout,
|
||||
" mailsend -f muquit@example.com -d example.com -smtp 1.2.3.4\n"
|
||||
" -sub test -from muquit@muquit.com +cc +bc -v -starttls -auth-login\n"
|
||||
" -user you -pass 'secert'\n");
|
||||
(void) fprintf(stdout,
|
||||
"(Password can be set by env var SMTP_USER_PASS instead of -pass)\n\n");
|
||||
(void) fprintf(stdout,
|
||||
"Note: I suggest you always use STARTTLS if your server supports it\n");
|
||||
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
char
|
||||
*x,
|
||||
buf[BUFSIZ],
|
||||
*cipher=NULL,
|
||||
*option;
|
||||
|
||||
int
|
||||
smtp_info=0,
|
||||
is_mime=0,
|
||||
add_dateh=1,
|
||||
port=(-1),
|
||||
rc,
|
||||
no_cc=0,
|
||||
no_bcc=0,
|
||||
i;
|
||||
|
||||
char
|
||||
*address_file=NULL,
|
||||
*helo_domain=NULL,
|
||||
*smtp_server=NULL,
|
||||
*attach_file=NULL,
|
||||
*msg_body_file=NULL,
|
||||
*the_msg=NULL,
|
||||
*to=NULL,
|
||||
*save_to=NULL,
|
||||
*save_cc=NULL,
|
||||
*save_bcc=NULL,
|
||||
*from=NULL,
|
||||
*sub=NULL,
|
||||
*cc=NULL,
|
||||
*bcc=NULL,
|
||||
*rt=NULL,
|
||||
*rrr=NULL;
|
||||
|
||||
g_verbose=0;
|
||||
g_quiet=0;
|
||||
g_wait_for_cr=0;
|
||||
g_do_auth=0;
|
||||
g_esmtp=0;
|
||||
g_auth_plain=0;
|
||||
g_auth_cram_md5=0;
|
||||
g_auth_login=0;
|
||||
g_do_starttls=0;
|
||||
memset(g_username,0,sizeof(g_username));
|
||||
memset(g_userpass,0,sizeof(g_userpass));
|
||||
memset(g_from_name,0,sizeof(g_from_name));
|
||||
|
||||
(void) strcpy(g_charset,"us-ascii");
|
||||
|
||||
for (i=1; i < argc; i++)
|
||||
{
|
||||
option=argv[i];
|
||||
switch (*(option+1))
|
||||
{
|
||||
|
||||
case 'a':
|
||||
{
|
||||
if (strncmp("attach",option+1,2) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing file to attach");
|
||||
return (1);
|
||||
}
|
||||
attach_file=argv[i];
|
||||
add_attachment_to_list(attach_file);
|
||||
}
|
||||
}
|
||||
else if (strncmp("auth-plain",option+1,
|
||||
strlen("auth-plain"))==0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
g_auth_plain=1;
|
||||
}
|
||||
}
|
||||
else if (strncmp("auth-cram-md5",option+1,
|
||||
strlen("auth-cram-md5"))==0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
g_auth_cram_md5=1;
|
||||
}
|
||||
}
|
||||
else if (strncmp("auth-login",option+1,
|
||||
strlen("auth-login"))==0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
g_auth_login=1;
|
||||
}
|
||||
}
|
||||
else if (strncmp("auth",option+1,
|
||||
strlen("auth"))==0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
g_auth_login=1;
|
||||
g_auth_cram_md5=1;
|
||||
g_auth_login=1;
|
||||
g_do_auth=1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'b':
|
||||
{
|
||||
if (strncmp("bcc",option+1,2) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing BCc address/es");
|
||||
return (1);
|
||||
}
|
||||
bcc=argv[i];
|
||||
save_bcc=mutilsStrdup(bcc);
|
||||
|
||||
/* collapse all spaces to a comma */
|
||||
mutilsSpacesToChar(bcc,',');
|
||||
addAddressToList(bcc,"Bcc");
|
||||
}
|
||||
else if (*option == '+')
|
||||
{
|
||||
no_bcc=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'c':
|
||||
{
|
||||
if (strncmp("cc",option+1,2) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing Cc address/es");
|
||||
return (1);
|
||||
}
|
||||
cc=argv[i];
|
||||
save_cc=mutilsStrdup(cc);
|
||||
|
||||
/* collapse all spaces to a comma */
|
||||
mutilsSpacesToChar(cc,',');
|
||||
addAddressToList(cc,"Cc");
|
||||
}
|
||||
else if (*option == '+')
|
||||
{
|
||||
no_cc=1;
|
||||
}
|
||||
}
|
||||
else if (strncmp("cs",option+1,2) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing character set");
|
||||
return (1);
|
||||
}
|
||||
mutilsSafeStrcpy(g_charset,argv[i],sizeof(g_charset)-1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'D':
|
||||
{
|
||||
if (strncmp("D",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '+')
|
||||
{
|
||||
add_dateh=0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'd':
|
||||
{
|
||||
if (strncmp("domain",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing domain name");
|
||||
return (1);
|
||||
}
|
||||
helo_domain=argv[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'e':
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
if (strncmp("example",option+1,3) == 0)
|
||||
{
|
||||
show_examples();
|
||||
return(1);
|
||||
}
|
||||
if (strncmp("ehlo",option+1,4) == 0)
|
||||
{
|
||||
g_esmtp=1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
{
|
||||
if (strncmp("from",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing From address/es");
|
||||
return (1);
|
||||
}
|
||||
from=argv[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
{
|
||||
if (strncmp("help",option+1,1) == 0)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
/* won't be here */
|
||||
break;
|
||||
}
|
||||
|
||||
case 'i':
|
||||
{
|
||||
if (strncmp("info",option+1,2) == 0)
|
||||
{
|
||||
smtp_info=1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'l':
|
||||
{
|
||||
if (strncmp("list_address",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing address list file");
|
||||
return (1);
|
||||
}
|
||||
address_file=argv[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'p':
|
||||
{
|
||||
if (strncmp("port",option+1,2) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing SMTP Port with -port");
|
||||
return (1);
|
||||
}
|
||||
port=atoi(argv[i]);
|
||||
}
|
||||
}
|
||||
else if (strncmp("pass",option+1,2) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing password with -pass");
|
||||
return (1);
|
||||
}
|
||||
(void) snprintf(g_userpass,sizeof(g_userpass)-1,
|
||||
"%s",argv[i]);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* -gone-
|
||||
case 'm':
|
||||
{
|
||||
if (strncmp("msgbody",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing message body file");
|
||||
return (1);
|
||||
}
|
||||
msg_body_file=argv[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case 'M':
|
||||
{
|
||||
if (strncmp("Message",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing text message");
|
||||
return (1);
|
||||
}
|
||||
the_msg=argv[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'n':
|
||||
{
|
||||
if (strncmp("name",option+1,3) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing Name with -n");
|
||||
return (1);
|
||||
}
|
||||
(void) snprintf(g_from_name,sizeof(g_from_name)-1,
|
||||
"%s",argv[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 's':
|
||||
{
|
||||
if (strncmp("smtp",option+1,3) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing smtp server");
|
||||
return (1);
|
||||
}
|
||||
smtp_server=argv[i];
|
||||
}
|
||||
}
|
||||
else if (strncmp("subject",option+1,3) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing subject with -sub");
|
||||
return (1);
|
||||
}
|
||||
sub=argv[i];
|
||||
}
|
||||
}
|
||||
else if (strncmp("starttls",option+1,3) == 0)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
g_do_starttls=1;
|
||||
#else
|
||||
(void) fprintf(stderr,"Warning: '-starttls' not available, only avaible if compiled with OpenSSL\n");
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'u':
|
||||
{
|
||||
if (strncmp("user",option+1,2) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
errorMsg("Missing smtp server");
|
||||
return (1);
|
||||
}
|
||||
(void) snprintf(g_username,sizeof(g_username)-1,
|
||||
"%s",argv[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
case 'v':
|
||||
{
|
||||
if (strncmp("verbose",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
g_verbose=1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
if (strncmp("quiet",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
g_quiet=1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'V':
|
||||
{
|
||||
(void) fprintf(stderr,"mailsend Version: %.1024s\n",MAILSEND_VERSION);
|
||||
#ifdef HAVE_OPENSSL
|
||||
(void) fprintf(stderr,"Compiled with %s\n",
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
#else
|
||||
(void) fprintf(stderr,"Not Compiled OpenSSL, some auth methods will be unavailable\n");
|
||||
#endif /* ! HAVE_OPENSSL */
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case 't':
|
||||
{
|
||||
if (strncmp("to",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
(void) fprintf(stderr,"Error: missing to addresses\n");
|
||||
return (1);
|
||||
}
|
||||
to=argv[i];
|
||||
save_to=mutilsStrdup(to);
|
||||
if (save_to == NULL)
|
||||
{
|
||||
errorMsg("memory allocation problem for -to");
|
||||
return(-1);
|
||||
}
|
||||
save_to=fix_to(save_to);
|
||||
to=fix_to(to);
|
||||
/* collapse all spaces to a comma */
|
||||
mutilsSpacesToChar(to,',');
|
||||
|
||||
/* add addresses to a singly linked list */
|
||||
addAddressToList(to,"To");
|
||||
/* Note: to is modifed now! */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'r':
|
||||
{
|
||||
if (strncmp("rrr",option+1,3) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
(void) fprintf(stderr,"Error: missing to addresses for -rrr\n");
|
||||
return (1);
|
||||
}
|
||||
rrr=mutilsStrdup(argv[i]);
|
||||
if (rrr == NULL)
|
||||
{
|
||||
errorMsg("memory allocation problem for -rrr");
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strncmp("rt",option+1,2) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
(void) fprintf(stderr,"Error: missing to addresses for -rt\n");
|
||||
return (1);
|
||||
}
|
||||
rt=mutilsStrdup(argv[i]);
|
||||
if (rt == NULL)
|
||||
{
|
||||
errorMsg("memory allocation problem for -rt");
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Unknown flag: %s\n",option);
|
||||
return(1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'w':
|
||||
{
|
||||
if (strncmp("wait",option+1,1) == 0)
|
||||
{
|
||||
if (*option == '-')
|
||||
{
|
||||
g_wait_for_cr=1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
(void) fprintf(stderr,"Error: Unrecognized option: %s\n",
|
||||
option);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
initialize_openssl(cipher);
|
||||
|
||||
if (port == -1)
|
||||
port=MAILSEND_SMTP_PORT;
|
||||
if (smtp_info)
|
||||
{
|
||||
if (smtp_server == NULL)
|
||||
smtp_server="localhost";
|
||||
}
|
||||
if (smtp_info && smtp_server)
|
||||
{
|
||||
if (helo_domain == NULL)
|
||||
helo_domain="localhost";
|
||||
show_smtp_info(smtp_server,port,helo_domain);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
print_attachemtn_list();
|
||||
|
||||
/*
|
||||
** attaching a file or a one line message will make the mail a
|
||||
** MIME mail
|
||||
*/
|
||||
if (attach_file || the_msg || msg_body_file)
|
||||
{
|
||||
is_mime=1;
|
||||
}
|
||||
|
||||
if (smtp_server == NULL)
|
||||
{
|
||||
memset(buf,0,sizeof(buf));
|
||||
x=askFor(buf,sizeof(buf)-1,"SMTP server address/IP: ",EMPTY_NOT_OK);
|
||||
if (x)
|
||||
smtp_server=xStrdup(x);
|
||||
}
|
||||
|
||||
if (helo_domain == NULL)
|
||||
{
|
||||
/*
|
||||
memset(buf,0,sizeof(buf));
|
||||
x=askFor(buf,sizeof(buf)-1,"Domain: ",EMPTY_NOT_OK);
|
||||
if (x)
|
||||
helo_domain=xStrdup(x);
|
||||
*/
|
||||
/* use localhost */
|
||||
helo_domain=xStrdup("localhost");
|
||||
}
|
||||
|
||||
if (from == NULL)
|
||||
{
|
||||
memset(buf,0,sizeof(buf));
|
||||
x=askFor(buf,sizeof(buf)-1,"From: ",EMPTY_NOT_OK);
|
||||
if (x)
|
||||
from=xStrdup(x);
|
||||
}
|
||||
|
||||
x=getenv("SMTP_USER_PASS");
|
||||
if (x)
|
||||
{
|
||||
if (*g_userpass == '\0')
|
||||
{
|
||||
(void) snprintf(g_userpass,sizeof(g_userpass)-1,"%s",x);
|
||||
}
|
||||
}
|
||||
|
||||
/* if address file specified, add the addresses to the list as well */
|
||||
if (address_file != NULL)
|
||||
{
|
||||
addAddressesFromFileToList(address_file);
|
||||
printAddressList();
|
||||
}
|
||||
|
||||
/*
|
||||
** The To address must be speicifed, even if the file with the list of
|
||||
** addresses is specified. The specified To will be shown in the
|
||||
** envelope. None of the To, Cc and Bcc from the address list file will
|
||||
** be shown anywhre.. that's how I like it. I hate long To, Cc or Bcc.
|
||||
** muquit@muquit.com, Thu Mar 29 11:56:45 EST 2001
|
||||
*/
|
||||
|
||||
if (save_to == NULL)
|
||||
{
|
||||
/* don't ask for To add addresses are specified with -l file */
|
||||
if (getAddressList() == NULL)
|
||||
{
|
||||
memset(buf,0,sizeof(buf));
|
||||
x=askFor(buf,sizeof(buf)-1,"To: ",EMPTY_NOT_OK);
|
||||
if (x)
|
||||
{
|
||||
save_to=xStrdup(x);
|
||||
addAddressToList(x,"To");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** if msg file specified, dont ask for unneeded things, as it could
|
||||
** be used from other programs, and it will wait for input
|
||||
** muquit@muquit.com Tue Apr 10 18:02:12 EST 2001
|
||||
*/
|
||||
|
||||
#ifdef WINNT
|
||||
if (attach_file == NULL && isInConsole(_fileno(stdin)))
|
||||
#else
|
||||
if (attach_file == NULL && isatty(fileno(stdin)))
|
||||
#endif /* WINNT */
|
||||
{
|
||||
if (save_cc == NULL && !no_cc)
|
||||
{
|
||||
memset(buf,0,sizeof(buf));
|
||||
x=askFor(buf,sizeof(buf)-1,"Carbon copy: ",EMPTY_OK);
|
||||
if (x)
|
||||
{
|
||||
save_cc=xStrdup(x);
|
||||
addAddressToList(x,"Cc");
|
||||
}
|
||||
}
|
||||
|
||||
if (save_bcc == NULL && ! no_bcc)
|
||||
{
|
||||
memset(buf,0,sizeof(buf));
|
||||
x=askFor(buf,sizeof(buf)-1,"Blind Carbon copy: ",EMPTY_OK);
|
||||
if (x)
|
||||
{
|
||||
save_bcc=xStrdup(x);
|
||||
addAddressToList(x,"BCc");
|
||||
}
|
||||
}
|
||||
|
||||
if (sub == NULL)
|
||||
{
|
||||
memset(buf,0,sizeof(buf));
|
||||
x=askFor(buf,sizeof(buf)-1,"Subject: ",EMPTY_OK);
|
||||
if (x)
|
||||
sub=xStrdup(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* TODO: read from default file or registry */
|
||||
rc=validateMusts(from,save_to,smtp_server,helo_domain);
|
||||
if (rc == -1)
|
||||
return (1); /* exit */
|
||||
|
||||
#ifdef UNIX
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
#endif /* UNIX */
|
||||
|
||||
rc=send_the_mail(from,save_to,save_cc,save_bcc,sub,smtp_server,port,
|
||||
helo_domain,attach_file,msg_body_file,the_msg,is_mime,rrr,rt,add_dateh);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
if (isInteractive())
|
||||
{
|
||||
(void) printf("Mail sent successfully\n");
|
||||
(void) fflush(stdout);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isInteractive())
|
||||
{
|
||||
(void) printf("Could not send mail\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (isInteractive())
|
||||
{
|
||||
if (g_wait_for_cr)
|
||||
{
|
||||
printf("\nPress Enter to Exit: ");
|
||||
fgets(buf,sizeof(buf)-1,stdin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (rc);
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
** setget routines for mailsend
|
||||
**
|
||||
** Limitations and Comments:
|
||||
** vars are static in this module.
|
||||
**
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** muquit@muquit.com Mar-27-2001 first cut
|
||||
*/
|
||||
|
||||
#include "mailsend.h"
|
||||
|
||||
static Sll
|
||||
*attachment_head=NULL,
|
||||
*server_caps=NULL,
|
||||
*addr_head=NULL;
|
||||
|
||||
static Address
|
||||
*address=NULL;
|
||||
|
||||
void print_server_caps(void)
|
||||
{
|
||||
Sll
|
||||
*l;
|
||||
for (l=server_caps; l; l=l->next)
|
||||
{
|
||||
(void) fprintf(stdout,"%s\n",(char *) l->data);
|
||||
(void) fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printAddressList2(Sll *list)
|
||||
{
|
||||
Sll
|
||||
*l;
|
||||
|
||||
Address
|
||||
*addr=NULL;
|
||||
|
||||
for (l=list; l; l=l->next)
|
||||
{
|
||||
addr=(Address *) l->data;
|
||||
}
|
||||
}
|
||||
|
||||
void print_attachemtn_list()
|
||||
{
|
||||
Sll
|
||||
*l;
|
||||
|
||||
Attachment
|
||||
*a;
|
||||
|
||||
for (l=attachment_head; l; l=l->next)
|
||||
{
|
||||
a=(Attachment *) l->data;
|
||||
/*
|
||||
(void) fprintf(stderr,"File path: %s\n",a->file_path);
|
||||
(void) fprintf(stderr,"File name: %s\n",a->file_name);
|
||||
(void) fprintf(stderr,"Mime type: %s\n",a->mime_type);
|
||||
(void) fprintf(stderr,"Disposition: %s\n",a->content_disposition);
|
||||
(void) fprintf(stderr,"\n");
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printAddressList(void)
|
||||
{
|
||||
Sll
|
||||
*l;
|
||||
|
||||
Address
|
||||
*addr=NULL;
|
||||
|
||||
if (g_verbose)
|
||||
{
|
||||
for (l=addr_head; l; l=l->next)
|
||||
{
|
||||
addr=(Address *) l->data;
|
||||
if (addr)
|
||||
{
|
||||
(void) fprintf(stdout,"%s: %s\n",
|
||||
addr->label,
|
||||
addr->address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* return pointer to capability if found, NULL otherwise */
|
||||
char *check_server_cap(char *what)
|
||||
{
|
||||
Sll
|
||||
*l;
|
||||
if (what == NULL || *what == '\0')
|
||||
return(NULL);
|
||||
|
||||
for (l=server_caps; l; l=l->next)
|
||||
{
|
||||
if (mutilsStristr((char *) l->data,what))
|
||||
{
|
||||
return((char *) l->data);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* add server capabilities to our list */
|
||||
int add_server_cap_to_list(char *cap)
|
||||
{
|
||||
Sll
|
||||
*na=NULL;
|
||||
|
||||
char
|
||||
*c;
|
||||
|
||||
if (cap == NULL || *cap == '\0')
|
||||
return(-1);
|
||||
|
||||
|
||||
c=strdup(cap);
|
||||
if (c == NULL)
|
||||
return(-1);
|
||||
|
||||
na=allocateNode((void *) c);
|
||||
CHECK_MALLOC(na);
|
||||
appendNode(&server_caps,&na);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* add the file to attachment_list
|
||||
*/
|
||||
int add_attachment_to_list(char *file_path_mime)
|
||||
{
|
||||
int
|
||||
ntokens;
|
||||
|
||||
Sll
|
||||
*na=NULL;
|
||||
|
||||
char
|
||||
**tokens=NULL,
|
||||
*file_path=NULL,
|
||||
*file_name=NULL,
|
||||
*mime_type=NULL,
|
||||
*content_disposition="attachment";
|
||||
|
||||
Attachment
|
||||
*a=NULL;
|
||||
|
||||
if (file_path_mime == NULL || *file_path_mime == '\0')
|
||||
return(-1);
|
||||
|
||||
/* Tokenize the string "file,mime_type,something" */
|
||||
tokens=mutilsTokenize(file_path_mime,',',&ntokens);
|
||||
if (tokens == NULL)
|
||||
{
|
||||
errorMsg("Could not parse attachment string: \"%s\"",file_path_mime);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get the file name out */
|
||||
file_path=tokens[0];
|
||||
if ((file_name=strrchr(file_path,'/')) ||
|
||||
(file_name=strrchr(file_path,'\\')))
|
||||
{
|
||||
file_name++;
|
||||
}
|
||||
else
|
||||
{
|
||||
file_name=file_path;
|
||||
}
|
||||
|
||||
a=(Attachment *) malloc(sizeof(Attachment));
|
||||
CHECK_MALLOC(a);
|
||||
|
||||
a->file_path=xStrdup(file_path);
|
||||
a->file_name=xStrdup(file_name);
|
||||
|
||||
switch (ntokens)
|
||||
{
|
||||
case 1: /* Only File_path/name given */
|
||||
{
|
||||
|
||||
mime_type="application/octet-stream";
|
||||
a->mime_type=xStrdup(mime_type);
|
||||
a->content_disposition=xStrdup("attachment");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: /* filepath/name, mime_type given */
|
||||
{
|
||||
mime_type=tokens[1];
|
||||
a->mime_type=xStrdup(mime_type);
|
||||
a->content_disposition=xStrdup("attachment");
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
mime_type=tokens[1];
|
||||
a->mime_type=xStrdup(mime_type);
|
||||
content_disposition=tokens[2];
|
||||
if (*content_disposition == 'a')
|
||||
a->content_disposition=xStrdup("attachment");
|
||||
else if (*content_disposition == 'i')
|
||||
a->content_disposition=xStrdup("inline");
|
||||
else
|
||||
a->content_disposition=xStrdup("attachment");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
errorMsg("Invalid string specified with -a \"%s\"",file_path_mime);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
na=allocateNode((void *) a);
|
||||
CHECK_MALLOC(na);
|
||||
|
||||
appendNode(&attachment_head,&na);
|
||||
|
||||
/*
|
||||
print_attachemtn_list();
|
||||
*/
|
||||
#if 0
|
||||
if ((mime_type=strchr(file_path_mime,ATTACHMENT_SEP)))
|
||||
{
|
||||
*mime_type++='\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
mime_type="application/octet-stream";
|
||||
}
|
||||
|
||||
|
||||
/* get the file name out */
|
||||
if ((file_name=strrchr(file_path_mime,'/')) || (file_name=strrchr(file_path_mime,'\\')))
|
||||
{
|
||||
file_name++;
|
||||
}
|
||||
else
|
||||
{
|
||||
file_name=file_path_mime;
|
||||
}
|
||||
|
||||
a=(Attachment *) malloc(sizeof(Attachment));
|
||||
CHECK_MALLOC(a);
|
||||
|
||||
a->file_path=xStrdup(file_path_mime);
|
||||
a->file_name=xStrdup(file_name);
|
||||
a->mime_type=xStrdup(mime_type);
|
||||
na=allocateNode((void *) a);
|
||||
CHECK_MALLOC(na);
|
||||
|
||||
appendNode(&attachment_head,&na);
|
||||
#endif /* 0 */
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int addAddressToList(char *a,char *label)
|
||||
{
|
||||
char
|
||||
*p;
|
||||
|
||||
Sll
|
||||
*new=(Sll *) NULL;
|
||||
|
||||
if (a == NULL || *a == '\0')
|
||||
return(-1);
|
||||
|
||||
if (label == NULL || *label == '\0')
|
||||
label="To";
|
||||
|
||||
/* if comma separated, tokenize them */
|
||||
p=mutilsStrtok(a,",");
|
||||
if (p != NULL)
|
||||
{
|
||||
address=newAddress();
|
||||
if (address == NULL)
|
||||
{
|
||||
errorMsg("addAddressToList: malloc problem for newAddress()");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
address->label=xStrdup(label);
|
||||
address->address=xStrdup(p);
|
||||
|
||||
new=allocateNode((void *) address);
|
||||
if (new == (Sll *) NULL)
|
||||
{
|
||||
errorMsg("addAddressToList: malloc problem with allocateNode()");
|
||||
(void) free ((char *) address);
|
||||
return (-1);
|
||||
}
|
||||
appendNode(&addr_head,&new);
|
||||
}
|
||||
while ((p=mutilsStrtok((char *) NULL,",")) != NULL)
|
||||
{
|
||||
if (p != NULL)
|
||||
{
|
||||
address=newAddress();
|
||||
if (address == NULL)
|
||||
{
|
||||
errorMsg("addAddressToList: x malloc problem for newAddress()");
|
||||
return (-1);
|
||||
}
|
||||
address->label=xStrdup(label);
|
||||
address->address=xStrdup(p);
|
||||
new=allocateNode((void *) address);
|
||||
if (new == (Sll *) NULL)
|
||||
{
|
||||
errorMsg("addAddressToList:malloc problem with allocateNode()");
|
||||
(void) free ((char *) address);
|
||||
return (-1);
|
||||
}
|
||||
appendNode(&addr_head,&new);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** add the address list from file to the "head" linked list.
|
||||
** return 0 on success, -1 on error
|
||||
*/
|
||||
int addAddressesFromFileToList(char *address_file)
|
||||
{
|
||||
char
|
||||
*label=NULL,
|
||||
*p=NULL,
|
||||
buf[BUFSIZ];
|
||||
|
||||
Sll
|
||||
*list=(Sll *) NULL;
|
||||
|
||||
Address
|
||||
*addr=(Address *) NULL;
|
||||
|
||||
FILE
|
||||
*fp=(FILE *) NULL;
|
||||
|
||||
/* open the file */
|
||||
fp=fopen(address_file,"r");
|
||||
if (fp == (FILE *) NULL)
|
||||
{
|
||||
errorMsg("Could not open address list file: %s",address_file);
|
||||
return (-1);
|
||||
}
|
||||
while (fgets(buf,sizeof(buf)-1,fp) && !feof(fp))
|
||||
{
|
||||
p=NULL;
|
||||
|
||||
/* remove all white spaces */
|
||||
mutilsRmallws(buf);
|
||||
|
||||
if (*buf == '\0')
|
||||
continue;
|
||||
/* If a line starts with # or ; consider it's a comment */
|
||||
if (*buf == '#' || *buf == ';')
|
||||
continue;
|
||||
|
||||
showVerbose("Address> %s\n",buf);
|
||||
if (mutilsStrncasecmp(buf,"To:",3) == 0)
|
||||
{
|
||||
label="To";
|
||||
if (strlen(buf) > 3)
|
||||
p=buf+3;
|
||||
else
|
||||
p=(char *) NULL;
|
||||
}
|
||||
else if (mutilsStrncasecmp(buf,"Cc:",3) == 0)
|
||||
{
|
||||
label="Cc";
|
||||
if (strlen(buf) > 3)
|
||||
p=buf+3;
|
||||
else
|
||||
p=(char *) NULL;
|
||||
}
|
||||
else if (mutilsStrncasecmp(buf,"BCc:",4) == 0)
|
||||
{
|
||||
label="BCc";
|
||||
if (strlen(buf) > 4)
|
||||
p=buf+4;
|
||||
else
|
||||
p=(char *) NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* just an email address */
|
||||
/* TODO: allow comma separared may be */
|
||||
label="To";
|
||||
p=buf;
|
||||
}
|
||||
|
||||
if (p == (char *) NULL) /* won't be */
|
||||
p=buf;
|
||||
|
||||
if (p == (char *) NULL)
|
||||
continue;
|
||||
|
||||
addr=newAddress();
|
||||
if (addr == NULL)
|
||||
{
|
||||
errorMsg("addAddressToList: malloc problem for newAddress()");
|
||||
return (-1);
|
||||
}
|
||||
/* fill with data */
|
||||
showVerbose("Label: %s\n",label);
|
||||
showVerbose("Address: %s\n",p);
|
||||
|
||||
addr->label=xStrdup(label);
|
||||
addr->address=xStrdup(p);
|
||||
list=allocateNode((void *) addr);
|
||||
if (list == (Sll *) NULL)
|
||||
{
|
||||
errorMsg("addAddressToList: malloc problem with allocateNode()");
|
||||
(void) free ((char *) addr);
|
||||
return (-1);
|
||||
}
|
||||
appendNode(&addr_head,&list);
|
||||
}
|
||||
|
||||
if (fp != (FILE *) NULL)
|
||||
(void) fclose(fp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
Sll *getAddressList(void)
|
||||
{
|
||||
return (addr_head);
|
||||
}
|
||||
|
||||
Sll *get_attachment_list(void)
|
||||
{
|
||||
return(attachment_head);
|
||||
}
|
||||
|
||||
Sll *get_server_cap_list(void)
|
||||
{
|
||||
return(server_caps);
|
||||
}
|
||||
|
||||
/* just a debug routine */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,646 @@
|
||||
/*
|
||||
** various utility routines for mailsend
|
||||
**
|
||||
**
|
||||
** Development History:
|
||||
** who when why
|
||||
** muquit@muquit.com Mar-26-2001 first cut
|
||||
*/
|
||||
|
||||
#include "mailsend.h"
|
||||
#define DAY_MIN (24 * HOUR_MIN) /* minutes in a day */
|
||||
#define HOUR_MIN 60 /* minutes in an hour */
|
||||
#define MIN_SEC 60 /* seconds in a minute */
|
||||
|
||||
|
||||
/*
|
||||
** returns a positive number if the file descriptor is connected to
|
||||
** console. 0 if not
|
||||
*/
|
||||
int isInConsole(int fd)
|
||||
{
|
||||
int
|
||||
rc;
|
||||
rc=_isatty(fd);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
int isInteractive(void)
|
||||
{
|
||||
#ifdef WINNT
|
||||
if (isInConsole(_fileno(stdout)))
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
#else
|
||||
if (isatty(fileno(stdout)))
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
#endif /* ! WINNT */
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
/*
|
||||
** duplicate a string. exits on failure
|
||||
*/
|
||||
char *xStrdup (char *string)
|
||||
{
|
||||
char
|
||||
*tmp;
|
||||
|
||||
if (string == (char *) NULL || *string == '\0')
|
||||
return ((char *) NULL);
|
||||
|
||||
/* malloc twice as much memory. */
|
||||
tmp = (char *) malloc ((int) strlen(string)+1);
|
||||
|
||||
if (tmp == (char *) NULL)
|
||||
{
|
||||
(void) fprintf(stderr,"Error: mystrdup(): memory allocation problem\n");
|
||||
exit(0);
|
||||
}
|
||||
/* it's safe to copy this way */
|
||||
(void) strcpy(tmp, string);
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
void errorMsg(char *format,...)
|
||||
{
|
||||
va_list
|
||||
args;
|
||||
|
||||
va_start(args,format);
|
||||
(void) fprintf (stderr,"Error: ");
|
||||
vfprintf(stderr,format,args);
|
||||
(void) fprintf(stderr,"\n");
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void showVerbose(char *format,...)
|
||||
{
|
||||
va_list
|
||||
args;
|
||||
if (g_quiet)
|
||||
return;
|
||||
|
||||
if (g_verbose == 1)
|
||||
{
|
||||
va_start(args,format);
|
||||
vfprintf(stdout,format,args);
|
||||
(void) fflush(stdout);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void print_info(char *format,...)
|
||||
{
|
||||
va_list
|
||||
args;
|
||||
if (g_quiet)
|
||||
return;
|
||||
|
||||
va_start(args,format);
|
||||
vfprintf(stdout,format,args);
|
||||
(void) fflush(stdout);
|
||||
va_end(args);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Initialize TheMail structure. returns pointer to the TheMail sturcture on
|
||||
** success, NULL on failure.
|
||||
*/
|
||||
TheMail *newTheMail(void)
|
||||
{
|
||||
TheMail
|
||||
*the_mail=(TheMail *) NULL;
|
||||
|
||||
the_mail=(TheMail *) malloc(sizeof(TheMail));
|
||||
if (the_mail == (TheMail *) NULL)
|
||||
{
|
||||
(void) fprintf(stderr,"initTheMail(): malloc failed\n");
|
||||
return ((TheMail *) NULL);
|
||||
}
|
||||
memset(the_mail,0,sizeof(TheMail));
|
||||
|
||||
return (the_mail);
|
||||
}
|
||||
|
||||
Address *newAddress(void)
|
||||
{
|
||||
Address
|
||||
*a;
|
||||
|
||||
a=(Address *) malloc(sizeof(Address));
|
||||
if (a == (Address *) NULL)
|
||||
{
|
||||
(void) fprintf(stderr," newAddress() malloc failed\n");
|
||||
}
|
||||
memset(a,0,sizeof(Address));
|
||||
|
||||
return (a);
|
||||
}
|
||||
|
||||
|
||||
int validateMusts(char *from,char *to,char *smtp_server,char *helo_domain)
|
||||
{
|
||||
int
|
||||
err=0;
|
||||
|
||||
if (getAddressList() == NULL)
|
||||
{
|
||||
if (to == (char *) NULL)
|
||||
{
|
||||
errorMsg("No To address/es specified. Speicfy with: -t to,to,..");
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
if (from == (char *) NULL)
|
||||
{
|
||||
errorMsg("No From address specified. Specify with: -f");
|
||||
err++;
|
||||
}
|
||||
|
||||
|
||||
if (smtp_server == (char *) NULL)
|
||||
{
|
||||
errorMsg("No SMTP server address or IP specified. Specify with -smtp");
|
||||
err++;
|
||||
}
|
||||
|
||||
|
||||
if (helo_domain == (char *) NULL)
|
||||
{
|
||||
errorMsg("No domain specified. Specify with: -d");
|
||||
err++;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *askFor(char *buf,int buflen,char *label,int ask)
|
||||
{
|
||||
|
||||
if (label == NULL || *label == '\0')
|
||||
return (NULL);
|
||||
|
||||
again:
|
||||
if (isInConsole(_fileno(stdin)))
|
||||
{
|
||||
(void) fprintf(stdout,label);
|
||||
(void) fflush(stdout);
|
||||
(void) fflush(stderr);
|
||||
}
|
||||
|
||||
(void) fgets(buf,buflen,stdin);
|
||||
if (*buf == '\0' || *buf == '\n')
|
||||
{
|
||||
if (ask == EMPTY_NOT_OK)
|
||||
goto again;
|
||||
}
|
||||
|
||||
mutilsChopNL(buf);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
** remote mailto from To
|
||||
** remote mailto: from the address
|
||||
** mailto:foo => foo
|
||||
** mailto: => mailto:
|
||||
** mailto:x => "x"
|
||||
** mailto: x => " x"
|
||||
*/
|
||||
char *fix_to(char *to)
|
||||
{
|
||||
char
|
||||
*p=to;
|
||||
|
||||
if (to == NULL || *to == '\0')
|
||||
return(p);
|
||||
|
||||
/* mailto:foo */
|
||||
if (strlen(to) > 7 && mutilsStrncasecmp(to,"mailto:",7) == 0)
|
||||
{
|
||||
p=to;
|
||||
p=p+7;
|
||||
return(p);
|
||||
}
|
||||
|
||||
return(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* return filepath and mime_type
|
||||
* @param str String of the form "file,mime_type"
|
||||
* example: "c:\usr\local\foo.txt,text/plain"
|
||||
* "/usr/local/foo.html,text/html"
|
||||
* @param filepath returns
|
||||
* @param fp_size size of the buffer filepath
|
||||
* @param mime_type returns
|
||||
* @param mt_size size of the buffer mime_type
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*
|
||||
* Note: it will not expand "~ $" etc in the filepath
|
||||
* This function is used when a body is attached with -m flag
|
||||
*
|
||||
*/
|
||||
int get_filepath_mimetype(char *str,char *filepath,int fp_size,char *mype_type,int mt_size)
|
||||
{
|
||||
|
||||
int
|
||||
rc=0;
|
||||
char
|
||||
*fp,
|
||||
*mt;
|
||||
if ((mt=strchr(str,ATTACHMENT_SEP)))
|
||||
{
|
||||
*mt++='\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg("Could not determine mime-type from input: %s\n",str);
|
||||
return(-1);
|
||||
}
|
||||
mutilsSafeStrcpy(mype_type,mt,mt_size);
|
||||
|
||||
/* get the filepath out */
|
||||
fp=str;
|
||||
mutilsSafeStrcpy(filepath,fp,fp_size);
|
||||
return(rc);
|
||||
}
|
||||
|
||||
void initialize_openssl(char *cipher)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
static const char rnd_seed[]="my huge entropy for rng.. blah";
|
||||
SSL_CTX *ssl_ctx=(SSL_CTX *) NULL;
|
||||
SSL *ssl=NULL;
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
RAND_seed(rnd_seed,sizeof(rnd_seed));
|
||||
ssl_ctx=SSL_CTX_new(SSLv23_client_method());
|
||||
if (ssl_ctx == NULL)
|
||||
{
|
||||
errorMsg("Could not create SSL context\n");
|
||||
return;
|
||||
}
|
||||
if (cipher)
|
||||
{
|
||||
if (!SSL_CTX_set_cipher_list(ssl_ctx,cipher))
|
||||
{
|
||||
errorMsg("Could not set cipher list %s\n",cipher);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ssl=SSL_new(ssl_ctx);
|
||||
if (ssl == NULL)
|
||||
{
|
||||
errorMsg("SSL_new() failed\n");
|
||||
return;
|
||||
}
|
||||
/* set ssl to msock's static */
|
||||
msock_set_ssl(ssl);
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Date for RFC822 Date: header
|
||||
*
|
||||
* @param when time since unix epoch
|
||||
* @param datebuf returns NULL terminated date string.
|
||||
* Example: Wed, 17 May 2006 13:55:35 -0400
|
||||
* @param bufsiz size of buffer dates. It's callers responsibily to make sure
|
||||
* datebuf contains enough space. It must be at least 64 bytes.
|
||||
* Usually it'll contain 31 bytes.
|
||||
*
|
||||
* returns 0 on success, -1 on failure
|
||||
*
|
||||
* The code is adapted from postfix.
|
||||
*
|
||||
* Changes I made:
|
||||
* - I use fixed size buffers instead of dynamic ones.
|
||||
* - I don't use %e to calcuate day of the week, instead I use %d. Windows strftime
|
||||
* does not have %e.
|
||||
* - I don't add timzone name.
|
||||
*
|
||||
* Reference: http://cr.yp.to/immhf/date.html
|
||||
*/
|
||||
int rfc822_date(time_t when,char *datebuf,int bufsiz)
|
||||
{
|
||||
char
|
||||
ts1[32],
|
||||
ts2[32];
|
||||
|
||||
struct tm
|
||||
*lt;
|
||||
|
||||
struct tm
|
||||
gmt;
|
||||
|
||||
int
|
||||
gmtoff;
|
||||
|
||||
if (bufsiz < 64)
|
||||
{
|
||||
(void) fprintf(stderr,"buffer size of date must be > 31, it is %d\n",bufsiz);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
memset(datebuf,0,bufsiz);
|
||||
memset(ts1,0,sizeof(ts1));
|
||||
memset(ts2,0,sizeof(ts2));
|
||||
|
||||
gmt=*gmtime(&when);
|
||||
lt=localtime(&when);
|
||||
|
||||
gmtoff = (lt->tm_hour - gmt.tm_hour) * HOUR_MIN + lt->tm_min - gmt.tm_min;
|
||||
if (lt->tm_year < gmt.tm_year)
|
||||
gmtoff -= DAY_MIN;
|
||||
else if (lt->tm_year > gmt.tm_year)
|
||||
gmtoff += DAY_MIN;
|
||||
else if (lt->tm_yday < gmt.tm_yday)
|
||||
gmtoff -= DAY_MIN;
|
||||
else if (lt->tm_yday > gmt.tm_yday)
|
||||
gmtoff += DAY_MIN;
|
||||
if (lt->tm_sec <= gmt.tm_sec - MIN_SEC)
|
||||
gmtoff -= 1;
|
||||
else if (lt->tm_sec >= gmt.tm_sec + MIN_SEC)
|
||||
gmtoff += 1;
|
||||
|
||||
/*
|
||||
** windows strftime does not have %e, so I'll use %d instead.
|
||||
** day 1 - 9 can be written as 01 - 09
|
||||
*/
|
||||
(void) strftime(ts1,sizeof(ts1)-1,"%a, %d %b %Y %H:%M:%S ",lt);
|
||||
if (gmtoff < -DAY_MIN || gmtoff > DAY_MIN)
|
||||
{
|
||||
(void) fprintf(stderr,"UTC time offset %d is larger than one day",gmtoff);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
(void) snprintf(ts2,sizeof(ts2)-1,"%+03d%02d",
|
||||
(int) (gmtoff / HOUR_MIN),(int) (abs(gmtoff) % HOUR_MIN));
|
||||
|
||||
/* put everything in the buffer. it's usually 31 bytes */
|
||||
(void) snprintf(datebuf,bufsiz,"%s%s",ts1,ts2);
|
||||
|
||||
/* I will not add timezone name, it's not required */
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
** return 0 on success, -1 on failure
|
||||
*/
|
||||
int guess_file_type(char *file,unsigned int *flag)
|
||||
{
|
||||
char
|
||||
buf[BUFSIZ];
|
||||
|
||||
int
|
||||
i,
|
||||
c,
|
||||
cr_found=0,
|
||||
nbytes,
|
||||
buflen;
|
||||
|
||||
FILE
|
||||
*fp=NULL;
|
||||
|
||||
*flag=0;
|
||||
|
||||
buflen=sizeof(buf)-1;
|
||||
fp=fopen(file,"rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
errorMsg("Could not open file %s for reading (%s)\n",
|
||||
file,ERR_STR);
|
||||
return(-1);
|
||||
}
|
||||
while(!feof(fp))
|
||||
{
|
||||
nbytes=fread(buf,1,buflen,fp);
|
||||
if ((nbytes != buflen) && ferror(fp))
|
||||
{
|
||||
errorMsg("Read error in guess_file_type\n");
|
||||
goto ExitProcessing;
|
||||
}
|
||||
for (i=0; i < nbytes; i++)
|
||||
{
|
||||
c=buf[i];
|
||||
if (cr_found)
|
||||
{
|
||||
cr_found=0;
|
||||
if (c == '\n')
|
||||
continue;
|
||||
}
|
||||
if (c == '\r')
|
||||
{
|
||||
cr_found=1;
|
||||
*flag |= FILE_TYPE_DOS;
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
*flag |= FILE_TYPE_UNIX;
|
||||
}
|
||||
else if ((c < 32 || c > 126) && c != '\t')
|
||||
{
|
||||
*flag |= FILE_TYPE_BINARY;
|
||||
(void) fclose(fp);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fp)
|
||||
(void) fclose(fp);
|
||||
return(0);
|
||||
ExitProcessing:
|
||||
if (fp)
|
||||
(void) fclose(fp);
|
||||
return(-1);
|
||||
|
||||
}
|
||||
|
||||
static int unix2dos(FILE *ifp,FILE *ofp)
|
||||
{
|
||||
int
|
||||
n,
|
||||
j,
|
||||
k,
|
||||
c,
|
||||
c2;
|
||||
char
|
||||
buf2[BUFSIZ+1],
|
||||
buf[BUFSIZ+1];
|
||||
if (ifp == NULL || ofp == NULL)
|
||||
return(-1);
|
||||
#ifdef WINNT
|
||||
_setmode(_fileno(ofp),_O_BINARY);
|
||||
#endif /* WINNT */
|
||||
while(!feof(ifp))
|
||||
{
|
||||
n=fread(buf,1,BUFSIZ,ifp);
|
||||
(void) fprintf(stderr,"n=\"%d\"\n",n);
|
||||
k=0;
|
||||
for (j=0; j < n; j++)
|
||||
{
|
||||
c=buf[j];
|
||||
if (c == '\n')
|
||||
{
|
||||
(void) fprintf(stderr,"j=%d\n",j);
|
||||
buf2[k++]='\r';
|
||||
}
|
||||
buf2[k++]=c;
|
||||
}
|
||||
c2=fwrite(buf2,sizeof(char),k,ofp);
|
||||
if (c2 != k)
|
||||
{
|
||||
perror("fwrite");
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
void print_cert_info(SSL *ssl)
|
||||
{
|
||||
X509
|
||||
*cert=NULL;
|
||||
X509_NAME
|
||||
*sub=NULL,
|
||||
*issuer=NULL;
|
||||
char
|
||||
buf[BUFSIZ];
|
||||
|
||||
if (!g_verbose)
|
||||
return;
|
||||
|
||||
print_info("Cipher: %s\n",SSL_get_cipher(ssl));
|
||||
(void) fprintf(stdout,"Certificate information:\n");
|
||||
cert=SSL_get_peer_certificate(ssl);
|
||||
if (cert == NULL)
|
||||
{
|
||||
errorMsg("No peer certificate found\n");
|
||||
return;
|
||||
}
|
||||
/* get subject name */
|
||||
sub=X509_get_subject_name(cert);
|
||||
if (sub == NULL)
|
||||
{
|
||||
errorMsg("Could not get subject name in certificate\n");
|
||||
}
|
||||
X509_NAME_oneline(sub,buf,sizeof(buf)-1);
|
||||
(void) fprintf(stdout,"Subject: %s\n",buf);
|
||||
|
||||
issuer=X509_get_issuer_name(cert);
|
||||
if (issuer == NULL)
|
||||
{
|
||||
errorMsg("Could not get issuer name in certificate\n");
|
||||
}
|
||||
X509_NAME_oneline(issuer,buf,sizeof(buf)-1);
|
||||
(void) fprintf(stdout,"Issuer: %s\n",buf);
|
||||
(void) fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
** params:
|
||||
** challenge: base64 encoded challenge
|
||||
** user username
|
||||
** seceret password
|
||||
**
|
||||
** Returns: NULL terminated base64 encoded CRAM-MD5 material on success,
|
||||
** NULL on failure
|
||||
*/
|
||||
char *encode_cram_md5(char *challenge,char *user,char *secret)
|
||||
{
|
||||
unsigned char
|
||||
*data;
|
||||
|
||||
unsigned long
|
||||
data_len;
|
||||
|
||||
unsigned char
|
||||
hmac_md5[16];
|
||||
|
||||
HMAC_CTX
|
||||
ctx;
|
||||
|
||||
const EVP_MD
|
||||
*md5=NULL;
|
||||
|
||||
unsigned int
|
||||
hmac_len;
|
||||
|
||||
int
|
||||
i;
|
||||
|
||||
char
|
||||
*b64;
|
||||
|
||||
unsigned long
|
||||
b64len=0;
|
||||
|
||||
char
|
||||
hex[33],
|
||||
buf[BUFSIZ];
|
||||
if (challenge == NULL || *challenge == '\0' ||
|
||||
user == NULL || *user == '\0' ||
|
||||
secret == NULL || *secret == '\0')
|
||||
return(NULL);
|
||||
|
||||
OpenSSL_add_all_digests();
|
||||
|
||||
/* decode the challenge */
|
||||
data=mutils_decode_base64(challenge,strlen(challenge),&data_len);
|
||||
if (data == NULL)
|
||||
{
|
||||
errorMsg("Could not base64 decode CRAM-MD5 challenge: %s",challenge);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* take HMAC-MD5 of the challenge*/
|
||||
md5=EVP_get_digestbyname("md5");
|
||||
HMAC_CTX_init(&ctx);
|
||||
HMAC_Init(&ctx,secret,strlen(secret),md5);
|
||||
HMAC_Update(&ctx,data,data_len);
|
||||
HMAC_Final(&ctx,hmac_md5,&hmac_len);
|
||||
|
||||
/* convert the digest to hex */
|
||||
memset(hex,0,sizeof(hex));
|
||||
for (i=0; i < 16; i++)
|
||||
{
|
||||
(void) sprintf(hex+2*i,"%02x",hmac_md5[i]);
|
||||
}
|
||||
|
||||
(void) snprintf(buf,sizeof(buf)-1,"%s %s",user,hex);
|
||||
/* base64 encode "user hex_digest" */
|
||||
b64=mutils_encode_base64(buf,strlen(buf),&b64len);
|
||||
if (b64len <= 0)
|
||||
return(NULL);
|
||||
/* mutils_encode_base64 adds CRLF */
|
||||
if (b64len > 2)
|
||||
b64[b64len-2]='\0';
|
||||
return(b64);
|
||||
}
|
||||
#else
|
||||
|
||||
char *encode_cram_md5(char *challenge,char *user,char *secret)
|
||||
{
|
||||
errorMsg("Must be compiled with OpenSSL in order to get CRAM-MD5 support\n");
|
||||
return(NULL);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
Reference in New Issue
Block a user