~ubuntu-branches/debian/sid/picolisp/sid

« back to all changes in this revision

Viewing changes to .pc/picolisp_sync_to_tip.patch/src/ssl.c

  • Committer: Package Import Robot
  • Author(s): Kan-Ru Chen
  • Date: 2011-11-13 17:15:44 UTC
  • mfrom: (1.1.14)
  • Revision ID: package-import@ubuntu.com-20111113171544-04gkr7r0lzmngt0u
Tags: 3.0.8.7-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 20oct11abu
2
 
 * (c) Software Lab. Alexander Burger
3
 
 */
4
 
 
5
 
#include <stdio.h>
6
 
#include <stdlib.h>
7
 
#include <unistd.h>
8
 
#include <fcntl.h>
9
 
#include <dirent.h>
10
 
#include <errno.h>
11
 
#include <string.h>
12
 
#include <signal.h>
13
 
#include <sys/stat.h>
14
 
#include <netdb.h>
15
 
#include <arpa/inet.h>
16
 
 
17
 
#include <openssl/pem.h>
18
 
#include <openssl/ssl.h>
19
 
#include <openssl/err.h>
20
 
 
21
 
typedef enum {NO,YES} bool;
22
 
 
23
 
static char *File, *Dir, *Data;
24
 
static off_t Size;
25
 
 
26
 
static char Get[] =
27
 
   "GET /%s HTTP/1.0\r\n"
28
 
   "User-Agent: PicoLisp\r\n"
29
 
   "Host: %s:%s\r\n"
30
 
   "Accept-Charset: utf-8\r\n\r\n";
31
 
 
32
 
static void errmsg(char *msg) {
33
 
   fprintf(stderr, "ssl: %s\n", msg);
34
 
}
35
 
 
36
 
static void giveup(char *msg) {
37
 
   errmsg(msg);
38
 
   exit(1);
39
 
}
40
 
 
41
 
static void sslChk(int n) {
42
 
   if (n < 0) {
43
 
      ERR_print_errors_fp(stderr);
44
 
      exit(1);
45
 
   }
46
 
}
47
 
 
48
 
static int sslConnect(SSL *ssl, char *node, char *service) {
49
 
   struct addrinfo hints, *lst, *p;
50
 
   int sd;
51
 
 
52
 
   memset(&hints, 0, sizeof(hints));
53
 
   hints.ai_family = AF_UNSPEC;
54
 
   hints.ai_socktype = SOCK_STREAM;
55
 
   if (getaddrinfo(node, service, &hints, &lst) == 0) {
56
 
      for (p = lst; p; p = p->ai_next) {
57
 
         if ((sd = socket(p->ai_family, p->ai_socktype, 0)) >= 0) {
58
 
            if (connect(sd, p->ai_addr, p->ai_addrlen) == 0) {
59
 
               freeaddrinfo(lst);
60
 
               SSL_set_fd(ssl, sd);
61
 
               if (SSL_connect(ssl) >= 0)
62
 
                  return sd;
63
 
               close(sd);
64
 
               return -1;
65
 
            }
66
 
            close(sd);
67
 
         }
68
 
      }
69
 
      freeaddrinfo(lst);
70
 
   }
71
 
   return -1;
72
 
}
73
 
 
74
 
static void sslClose(SSL *ssl, int sd) {
75
 
   SSL_shutdown(ssl);
76
 
   close(sd);
77
 
}
78
 
 
79
 
static bool sslFile(SSL *ssl, char *file) {
80
 
   int fd, n;
81
 
   char buf[BUFSIZ];
82
 
 
83
 
   if (file[0] == '-')
84
 
      return SSL_write(ssl, file+1, strlen(file)-1) >= 0;
85
 
   if ((fd = open(file, O_RDONLY)) < 0)
86
 
      return NO;
87
 
   while ((n = read(fd, buf, sizeof(buf))) > 0)
88
 
      if (SSL_write(ssl, buf, n) < 0) {
89
 
         close(fd);
90
 
         return NO;
91
 
      }
92
 
   close(fd);
93
 
   return n == 0;
94
 
}
95
 
 
96
 
static void doSigTerm(int n __attribute__((unused))) {
97
 
   int fd1, fd2, cnt;
98
 
   char buf[BUFSIZ];
99
 
 
100
 
   if (Data  &&  (fd1 = open(File, O_RDWR)) >= 0) {
101
 
      if (unlink(File) < 0)
102
 
         giveup("Can't unlink back");
103
 
      if ((fd2 = open(File, O_CREAT|O_WRONLY|O_TRUNC, 0666)) < 0)
104
 
         giveup("Can't create back");
105
 
      if (write(fd2, Data, Size) != Size)
106
 
         giveup("Can't write back");
107
 
      while ((cnt = read(fd1, buf, sizeof(buf))) > 0)
108
 
         write(fd2, buf, cnt);
109
 
   }
110
 
   exit(0);
111
 
}
112
 
 
113
 
// ssl host port url
114
 
// ssl host port url file
115
 
// ssl host port url key file
116
 
// ssl host port url key file dir sec
117
 
int main(int ac, char *av[]) {
118
 
   SSL_CTX *ctx;
119
 
   SSL *ssl;
120
 
   bool bin;
121
 
   int n, sec, getLen, lenLen, fd, sd;
122
 
   DIR *dp;
123
 
   struct dirent *p;
124
 
   struct stat st;
125
 
   struct flock fl;
126
 
   char get[1024], buf[4096], nm[4096], len[64];
127
 
 
128
 
   if (!(ac >= 4 && ac <= 6  ||  ac == 8))
129
 
      giveup("host port url [[key] file] | host port url key file dir sec");
130
 
   if (strlen(Get)+strlen(av[1])+strlen(av[2])+strlen(av[3]) >= sizeof(get))
131
 
      giveup("Names too long");
132
 
   if (strchr(av[3],'/'))
133
 
      bin = NO,  getLen = sprintf(get, Get, av[3], av[1], av[2]);
134
 
   else
135
 
      bin = YES,  getLen = sprintf(get, "@%s ", av[3]);
136
 
 
137
 
   SSL_library_init();
138
 
   SSL_load_error_strings();
139
 
   if (!(ctx = SSL_CTX_new(SSLv23_client_method()))) {
140
 
      ERR_print_errors_fp(stderr);
141
 
      giveup("SSL init");
142
 
   }
143
 
   ssl = SSL_new(ctx);
144
 
 
145
 
   if (ac <= 6) {
146
 
      if (sslConnect(ssl, av[1], av[2]) < 0) {
147
 
         errmsg("Can't connect");
148
 
         return 1;
149
 
      }
150
 
      sslChk(SSL_write(ssl, get, getLen));
151
 
      if (ac > 4) {
152
 
         if (*av[4]  &&  !sslFile(ssl,av[4]))
153
 
            giveup(av[4]);
154
 
         if (ac > 5  &&  *av[5]  &&  !sslFile(ssl,av[5]))
155
 
            giveup(av[5]);
156
 
      }
157
 
      while ((n = SSL_read(ssl, buf, sizeof(buf))) > 0)
158
 
         write(STDOUT_FILENO, buf, n);
159
 
      return 0;
160
 
   }
161
 
 
162
 
   signal(SIGCHLD,SIG_IGN);  /* Prevent zombies */
163
 
   if ((n = fork()) < 0)
164
 
      giveup("detach");
165
 
   if (n)
166
 
      return 0;
167
 
   setsid();
168
 
 
169
 
   File = av[5];
170
 
   Dir = av[6];
171
 
   sec = atoi(av[7]);
172
 
   signal(SIGINT, doSigTerm);
173
 
   signal(SIGTERM, doSigTerm);
174
 
   signal(SIGPIPE, SIG_IGN);
175
 
   for (;;) {
176
 
      if (*File && (fd = open(File, O_RDWR)) >= 0) {
177
 
         if (fstat(fd,&st) < 0  ||  st.st_size == 0)
178
 
            close(fd);
179
 
         else {
180
 
            fl.l_type = F_WRLCK;
181
 
            fl.l_whence = SEEK_SET;
182
 
            fl.l_start = 0;
183
 
            fl.l_len = 0;
184
 
            if (fcntl(fd, F_SETLKW, &fl) < 0)
185
 
               giveup("Can't lock");
186
 
            if (fstat(fd,&st) < 0  ||  (Size = st.st_size) == 0)
187
 
               giveup("Can't access");
188
 
            lenLen = sprintf(len, "%lld\n", Size);
189
 
            if ((Data = malloc(Size)) == NULL)
190
 
               giveup("Can't alloc");
191
 
            if (read(fd, Data, Size) != Size)
192
 
               giveup("Can't read");
193
 
            if (ftruncate(fd,0) < 0)
194
 
               errmsg("Can't truncate");
195
 
            close(fd);
196
 
            for (;;) {
197
 
               if ((sd = sslConnect(ssl, av[1], av[2])) >= 0) {
198
 
                  if (SSL_write(ssl, get, getLen) == getLen  &&
199
 
                           (!*av[4] || sslFile(ssl,av[4]))  &&                   // key
200
 
                           (bin || SSL_write(ssl, len, lenLen) == lenLen)  &&    // length
201
 
                           SSL_write(ssl, Data, Size) == Size  &&                // data
202
 
                           SSL_write(ssl, bin? "\0" : "T", 1) == 1  &&           // ack
203
 
                           SSL_read(ssl, buf, 1) == 1  &&  buf[0] == 'T' ) {
204
 
                     sslClose(ssl,sd);
205
 
                     break;
206
 
                  }
207
 
                  sslClose(ssl,sd);
208
 
               }
209
 
               sleep(sec);
210
 
            }
211
 
            free(Data),  Data = NULL;
212
 
         }
213
 
      }
214
 
      if (*Dir && (dp = opendir(Dir))) {
215
 
         while (p = readdir(dp)) {
216
 
            if (p->d_name[0] != '.') {
217
 
               snprintf(nm, sizeof(nm), "%s%s", Dir, p->d_name);
218
 
               if ((n = readlink(nm, buf, sizeof(buf))) > 0  &&
219
 
                        (sd = sslConnect(ssl, av[1], av[2])) >= 0 ) {
220
 
                  if (SSL_write(ssl, get, getLen) == getLen  &&
221
 
                        (!*av[4] || sslFile(ssl,av[4]))  &&          // key
222
 
                        (bin || SSL_write(ssl, buf, n) == n)  &&     // path
223
 
                        (bin || SSL_write(ssl, "\n", 1) == 1)  &&    // nl
224
 
                        sslFile(ssl, nm) )                           // file
225
 
                     unlink(nm);
226
 
                  sslClose(ssl,sd);
227
 
               }
228
 
            }
229
 
         }
230
 
         closedir(dp);
231
 
      }
232
 
      sleep(sec);
233
 
   }
234
 
}