4556435 [rkeene@sledge /home/rkeene/devel/dact]$ cat -n net.c
  1 /*
  2  * Copyright (C) 2001, 2002, and 2003  Roy Keene
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU General Public License
  6  * as published by the Free Software Foundation; either version 2
  7  * of the License, or (at your option) any later version.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  * GNU General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU General Public License
 15  * along with this program; if not, write to the Free Software
 16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 17  *
 18  *      email: dact@rkeene.org
 19  */
 20 
 21 
 22 /*
 23  *  Network related functions
 24  */
 25 #include "dact.h"
 26 #include "net.h"
 27 #ifdef HAVE_SYS_TYPES_H
 28 #include <sys/types.h>
 29 #endif
 30 #ifdef HAVE_SYS_STAT_H
 31 #include <sys/stat.h>
 32 #endif
 33 #include <stdarg.h>
 34 #ifdef HAVE_UNISTD_H
 35 #include <unistd.h>
 36 #endif
 37 #include <fcntl.h>
 38 
 39 #ifndef NO_NETWORK
 40 #ifdef HAVE_SYS_SOCKET_H
 41 #include <sys/socket.h>
 42 #endif
 43 #ifdef HAVE_NETINET_IN_H
 44 #include <netinet/in.h>
 45 #endif
 46 #ifdef HAVE_ARPA_INET_H
 47 #include <arpa/inet.h>
 48 #endif
 49 #ifdef HAVE_STDLIB_H
 50 #include <stdlib.h>
 51 #endif
 52 #ifdef HAVE_STRING_H
 53 #include <string.h>
 54 #endif
 55 #ifdef HAVE_NETDB_H
 56 #include <netdb.h>
 57 #endif
 58 #ifdef HAVE_ERRNO_H
 59 #include <errno.h>
 60 #endif
 61 #ifdef HAVE_STDIO_H
 62 #include <stdio.h>
 63 #endif
 64 #ifdef HAVE_WINSOCK2_H
 65 #include <winsock2.h>
 66 #endif
 67 #include "parse.h"
 68 #include "crc.h"
 69 
 70 #ifndef O_BINARY
 71 #define O_BINARY 0x0
 72 #endif
 73 #ifndef S_IFSOCK
 74 #define S_IFSOCK 0140000
 75 #endif
 76 
 77 
 78 struct dact_url_info {
 79     char *url;
 80     int flags;
 81     mode_t mode;
 82 };
 83 struct dact_url_info dact_urls[256];
 84 
 85 /*
 86  *  Create a listening port on tcp port PORT
 87  */
 88 int createlisten(int port)
 89 {
 90     struct sockaddr_in localname;
 91     int sockFd;
 92     sockFd=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
 93     localname.sin_family=AF_INET;
 94     localname.sin_port=htons(port);
 95     localname.sin_addr.s_addr=INADDR_ANY;
 96     if (bind(sockFd,(struct sockaddr *) & localname,sizeof(localname))==-1) { perror("bind");return(-1); }
 97     if (listen(sockFd,1024)==-1) { perror("listen"); return(-1); }
 98     return(sockFd);
 99 }
100 
101 
102 /*
103  *  Close that socket, yeah.
104  */
105 void closeconnection(int sockfd) {
106     shutdown(sockfd, 1);
107     close(sockfd);
108 }
109 
110 int createconnection_tcp(char *host, int port) {
111     int sockid;
112     struct hostent *hostinfo;
113     struct sockaddr_in sock;
114 
115     if (dact_nonetwork) return(-EPERM);
116 
117 #ifdef HAVE_INET_ATON
118     if (!inet_aton(host,&sock.sin_addr)) {
119 #elif HAVE_INET_ADDR
120     if ( (sock.sin_addr.s_addr=inet_addr(host) )==-1) {
121 #else
122     {
123 #endif
124         if ((hostinfo=gethostbyname(host))==NULL) return(-EPERM);
125         memcpy(&sock.sin_addr.s_addr,hostinfo->h_addr_list[0],hostinfo->h_length);
126     }
127 
128     sock.sin_family=AF_INET;
129     sock.sin_port=htons(port);
130     if ((sockid=socket(AF_INET, SOCK_STREAM, 0))<0) {
131         CHECKPOINT;
132         return(-EIO);
133     }
134     if (connect(sockid, (struct sockaddr *) &sock, sizeof(sock))<0) {
135         PERROR("connect");
136         CHECKPOINT;
137         close(sockid);
138         return(-EIO);
139     }
140     CHECKPOINT;
141     return(sockid);
142 }
143 
144 int open_net(const char *pathname, int flags, mode_t mode) {
145     char scheme[5], host[512], file[1024];
146     char username[128], password[128];
147     char *read_buf, *read_buf_s=NULL;
148     char *smallbuf, *tmpbuf;
149     int port, fd, x, ftpfd=-1, retrmode=0;
150 
151     if (!parse_url(pathname,scheme,username,password,host,&port,file)) {
152         if ((fd=createconnection_tcp(host,port))<0) return(-1);
153 
154         switch (ELFCRC(0, scheme, strlen(scheme))) {
155             case 457648: /* http */
156                 if ((flags&O_WRONLY)==O_WRONLY || (flags&O_RDWR)==O_RDWR) {
157                     close(fd);
158                     return(-1);
159                 }
160                 read_buf_s=read_buf=malloc(50);
161                 write(fd, "GET ", 4);
162                 write(fd, file, strlen(file));
163                 write(fd, " HTTP/1.0\nHost: ",16);
164                 write(fd, host, strlen(host));
165                 write(fd, "\n", 1);
166                 if (strcmp(username, "")) {
167                     smallbuf=malloc(strlen(password)+strlen(username)+3);
168                     smallbuf[0]=0;
169                     strcat(smallbuf,username);
170                     strcat(smallbuf,":");
171                     strcat(smallbuf,password);
172                     tmpbuf=mime64(smallbuf);
173                     write(fd, "Authorization: Basic ", 21);
174                     write(fd, tmpbuf, strlen(tmpbuf));
175                     free(tmpbuf);
176                     free(smallbuf);
177                     write(fd, "\n", 1);
178                 }
179                 write(fd, "\n", 1);
180                 x=read(fd, read_buf, 50);
181                 strsep(&read_buf," ");
182                 if (strncmp("200 ",read_buf,4) && strncmp("302 ",read_buf,4)) {
183                     free(read_buf_s);
184                     close(fd);
185                     return(-ENOENT);
186                 }
187                 retrmode=read_buf[0];
188                 read_buf=read_buf_s;
189                 read_buf[4]=0;
190                 while (1) {
191                     read(fd, read_buf, 1);
192                     if (read_buf[0]==read_buf[2]&&read_buf[0]=='\n') break;
193                     if (!strncmp(":noi", read_buf, 4) && retrmode=='3') {
194                         tmpbuf=smallbuf=malloc(512);
195                         read(fd, read_buf, 1);
196                         read(fd, smallbuf, 510);
197                         close(fd);
198                         return(open_net(strsep(&smallbuf,"\r\n"),flags,mode));
199                         free(tmpbuf);
200                     }
201                     read_buf[3]=read_buf[2];
202                     read_buf[2]=read_buf[1];
203                     read_buf[1]=read_buf[0];
204                 }
205 
206                 free(read_buf_s);
207 
208                 if (dact_urls[fd].url!=NULL) free(dact_urls[fd].url);
209                 dact_urls[fd].url=strdup(pathname);
210                 dact_urls[fd].flags=flags;
211                 dact_urls[fd].mode=mode;
212                 return(fd);
213                 break;
214             case 28080: /* ftp */
215                 if ((flags&O_RDWR)==O_RDWR) {
216                     close(fd);
217                     return(-1);
218                 }
219 
220                 read_buf_s=read_buf=malloc(1024);
221                 read_buf[0]=0;
222 
223                 while (1) {
224                     if ((x=read(fd, read_buf, 1024))<1024) {
225                         if (x<0) {
226                             free(read_buf_s);
227                             return(-EIO);
228                         }
229                         /* It's waiting for input... */
230                     }
231                     read_buf[x]=0;
232 
233                     while ((smallbuf=strsep(&read_buf,"\n"))!=NULL) {
234                         switch (ELFCRC(0, smallbuf, 4)) {
235                             case 231456: /* 550 */
236                                 if (ftpfd!=-1) close(ftpfd);
237                                 close(fd);
238                                 free(read_buf_s);
239                                 return(-ENOENT);
240                                 break;
241                             case 230944: /* 530 */
242                                 if (ftpfd!=-1) close(ftpfd);
243                                 close(fd);
244                                 free(read_buf_s);
245                                 return(-EIO);
246                                 break;
247                             case 231504: /* 553 */
248                                 if (ftpfd!=-1) close(ftpfd);
249                                 close(fd);
250                                 free(read_buf_s);
251                                 return(-EPERM);
252                                 break;
253                             case 218400: /* 220 */
254                                 write(fd, "USER ", 5);
255                                 if (strcmp(username,"")) {
256                                     write(fd, username, strlen(username));
257                                 } else {
258                                     write(fd, "anonymous", 9);
259                                 }
260                                 write(fd, "\n", 1);
261                                 break;
262                             case 222768: /* 331 */
263                                 write(fd, "PASS ", 5);
264                                 if (strcmp(password,"")) {
265                                     write(fd, password, strlen(password));
266                                 } else {
267                                     write(fd, "user@host.com", 13);
268                                 }
269                                 write(fd, "\n", 1);
270                                 break;
271                             case 218512: /* 227 */
272                                 strsep(&smallbuf,"(");
273                                 host[0]=0;
274                                 for (x=0;x<4;x++) {
275                                     strncat(host,strsep(&smallbuf,","),5);
276                                     strcat(host,".");
277                                 }
278                                 host[strlen(host)-1]=0;
279                                 port=(atoi(strsep(&smallbuf,","))<<8)+atoi(strsep(&smallbuf,")\n\r "));
280                                 write(fd, "TYPE I\n", 7);
281                                 break;
282                             case 217888:
283                                 if ((flags&O_RDONLY)==O_RDONLY) write(fd,"RETR ",5);
284                                 if ((flags&O_WRONLY)==O_WRONLY) write(fd,"STOR ",5);
285                                 write(fd, file, strlen(file));
286                                 write(fd, "\n", 1);
287                                 if ((ftpfd=createconnection_tcp(host,port))<0) {
288                                     close(fd);
289                                     return(-ENOENT);
290                                 }
291                                 break;
292                             case 215072: /* 150 */ 
293                                 if (dact_urls[ftpfd].url!=NULL) free(dact_urls[ftpfd].url);
294                                 dact_urls[ftpfd].url=strdup(pathname);
295                                 dact_urls[ftpfd].flags=flags;
296                                 dact_urls[ftpfd].mode=mode;
297                                 return(ftpfd);
298                                 break;
299                             case 218656: /* 230 */
300                                 write(fd, "PASV\n", 5);
301                                 break;
302                             default:
303 #ifdef DEBUG_FTP
304                                 PRINT_LINE; fprintf(stderr, "dact: Unknown cmd %i
	(%s)\n",ELFCRC(0,smallbuf,4),smallbuf);
305 #endif
306                                 break;
307                         }
308                     }
309                     read_buf=read_buf_s;
310                 }
311 
312                 
313                 break;
314         }
315 
316         free(read_buf_s);
317         close(fd);
318     } else {
319         fd=open(pathname,flags|O_BINARY,mode);
320         if (dact_urls[fd].url!=NULL) free(dact_urls[fd].url);
321         dact_urls[fd].url=strdup(pathname);
322         dact_urls[fd].flags=flags;
323         dact_urls[fd].mode=mode;
324         return(fd);
325     }
326 
327     return(-1);
328 }
329 
330 off_t lseek_net(int filedes, off_t offset, int whence) {
331     struct stat file_status;
332     int newfd;
333 
334     fstat(filedes, &file_status);
335     if ((file_status.st_mode&S_IFSOCK)==S_IFSOCK) {
336         if (whence==SEEK_END) return(-1);
337         if (offset!=0 || whence!=SEEK_SET) return(-1); /* For now ... */
338         if (dact_urls[filedes].url==NULL) return(-1);
339         if ((newfd=open_net(dact_urls[filedes].url,dact_urls[filedes].flags,dact_urls[filedes].mode))<0) return(-1);
340         close(filedes);
341         dup2(newfd,filedes);
342         return(0);
343     }
344     return(lseek(filedes,offset,whence));
345 }
346 
347 #else
348 #ifndef O_BINARY
349 #define O_BINARY 0x0
350 #endif
351 
352 int createlisten(int port) { return(-1); }
353 void closeconnection(int sockfd) { return; }
354 int createconnection_tcp(char *host, int port) { return(-1); }
355 int open_net(const char *pathname, int flags, mode_t mode) {
356     return(open(pathname,flags|O_BINARY,mode));
357 }
358 off_t lseek_net(int filedes, off_t offset, int whence) {
359     return(lseek(filedes,offset,whence));
360 }
361 #endif
4556436 [rkeene@sledge /home/rkeene/devel/dact]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-04-04 07:01:53