123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /**
- * saop: smtp authentication over pop3
- * Copyright (C) 2007 Juan José Gutiérrez de Quevedo <juanjo@iteisa.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * @author Juan José Gutiérrez de Quevedo <juanjo@iteisa.com>
- */
- #include "utils.h"
- #ifdef DEBUG
- extern FILE *fsaopdebug;
- #endif /* DEBUG */
- /**
- * reads a string as safely as possible.
- *
- * it will read one byte at a time until a '\\n' is read.
- * we store one char at a time in a static buffer, and when
- * we find a '\\n', we do an strndup of the buffer.
- * it might be possible in this special case to just use
- * a static buffer, return a pointer to it and never assign
- * any memory with strndup or in any other way.
- *
- * @param fd fd to read from
- *
- * @return a pointer to the read string
- */
- char *read_string(int fd)
- {
- char chr;
- char *buffer=NULL,*tmpbuf=NULL;
- unsigned long strsize=0;
- unsigned long allocsize=0;
- debug("Reading from socket");
- assert(fd>=0);
- /* read one byte at a time */
- while(1)
- {
- if(1!=recv(fd,&chr,1,MSG_NOSIGNAL))
- break;
- if(0==allocsize||allocsize<strsize+2)
- {
- allocsize=MAX(allocsize+512,strsize+2);
- if(NULL==(tmpbuf=realloc(buffer,allocsize)))
- {
- printf(_("Error reserving memory\n"));
- condfree(buffer);
- break;
- }
- else
- buffer=tmpbuf;
- }
- if(10==chr) break;
- if(13!=chr)
- buffer[strsize++]=chr;
- }
- if(NULL==buffer) return NULL;
- /* finalize string */
- buffer[strsize]='\0';
- debug(buffer);
- /* return a new string with new mem */
- return buffer;
- }
- /**
- * create a new listening socket.
- *
- * with following options:
- * - SO_REUSEADDR
- * - INADDR_ANY
- *
- * @param port the port to listen on
- *
- * @return the new socket fd
- */
- int create_listening_socket(unsigned int port)
- {
- int fd_server;
- struct sockaddr_in address;
- int i;
- /* create socket */
- if(-1==(fd_server=socket(PF_INET,SOCK_STREAM,0))) { perror("Error creating socket"); return -1; }
- debug("Socket created successfully");
- /* set option for the socket: SO_REUSEADDR (will reuse address between invocations of the same program) */
- i=1;
- if(-1==setsockopt(fd_server,SOL_SOCKET,SO_REUSEADDR,(void *)&i,sizeof(i))) { perror("Error configuring socket reuse"); closeskt(fd_server); return -1; }
- /* bind to address :ANY */
- address.sin_family=AF_INET;
- address.sin_addr.s_addr=INADDR_ANY;
- address.sin_port=htons(port);
- if(-1==bind(fd_server,(struct sockaddr *)&address,sizeof(address))) { perror("Error binding to address"); closeskt(fd_server); return -1; }
- debug("bind() successful");
- /* listen on socket */
- if(-1==listen(fd_server,10)) { perror("Error listening on socket"); closeskt(fd_server); return -1; }
- debug("listen() successful");
- return fd_server;
- }
- /**
- * create a socket that is connected to an address.
- *
- * @param address address to connect to
- * @param port port to connect to
- *
- * @return fd of the opened connection
- */
- int create_connected_socket(char *address,unsigned int port)
- {
- int fd;
- struct sockaddr_in addr;
- /* create socket */
- if(-1==(fd=socket(PF_INET,SOCK_STREAM,0))) { perror("Error creating socket"); return -1; }
- debug("Connecting to..");
- debug(address);
- /* fill address structure */
- addr.sin_family=AF_INET;
- addr.sin_addr.s_addr=resolve(address);
- addr.sin_port=htons(port);
- /* connect to remote host */
- if(-1==connect(fd,(struct sockaddr *)&addr,sizeof(addr))) { perror("Error connecting to host"); return -1; }
- debug("Connection successful");
- return fd;
- }
- unsigned long resolve(char *address)
- {
- struct hostent *resolved;
- struct in_addr addr;
- if(NULL==(resolved=gethostbyname(address))) { perror("Error resolving"); return 0; }
- memcpy(&addr,resolved->h_addr,sizeof(addr));
- debug("Address resolved");
- debug(address);
- debug(inet_ntoa(addr));
- return addr.s_addr;
- }
- /**
- * whether a fd does have data waiting or not.
- *
- * @param fd fd to ask
- * @param time time to wait for data
- *
- * @return 1 on data waiting to be read, else return 0
- */
- unsigned char can_read(int fd,float time)
- {
- fd_set rfd;
- struct timeval timeout;
- assert(fd>=0);
- /* configure timeout */
- timeout.tv_sec=(int)time;
- timeout.tv_usec=(time-(int)time)*1000000;
- /* configure rfd */
- FD_ZERO(&rfd);
- FD_SET(fd,&rfd);
- return (select(fd+1,&rfd,NULL,NULL,&timeout)>0)?1:0;
- }
|