Subversion Repositories SvarDOS

Rev

Rev 675 | Rev 725 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 675 Rev 712
Line 21... Line 21...
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
 * DEALINGS IN THE SOFTWARE.
24
 * DEALINGS IN THE SOFTWARE.
25
 *
25
 *
26
 * http://svardos.osdn.io
26
 * http://svardos.org
27
 */
27
 */
28
 
28
 
29
#include <direct.h> /* opendir() and friends */
29
#include <direct.h> /* opendir() and friends */
30
#include <stdio.h>
30
#include <stdio.h>
31
#include <stdlib.h>
31
#include <stdlib.h>
Line 33... Line 33...
33
#include <time.h>
33
#include <time.h>
34
 
34
 
35
#include "net.h"
35
#include "net.h"
36
#include "unchunk.h"
36
#include "unchunk.h"
37
 
37
 
-
 
38
#include "svarlang.lib\svarlang.h"
-
 
39
 
38
#include "../../pkg/trunk/lsm.h"
40
#include "../../pkg/trunk/lsm.h"
39
 
41
 
40
 
42
 
41
#define PVER "20220214"
43
#define PVER "20220215"
42
#define PDATE "2021-2022"
44
#define PDATE "2021-2022"
43
 
45
 
44
#define HOSTADDR "svardos.org"
46
#define HOSTADDR "svardos.org"
45
 
47
 
46
 
48
 
-
 
49
/* convenience define that outputs nls strings to screen (followed by CR/LF) */
-
 
50
#define putsnls(x,y) puts(svarlang_strid((x << 8) | y))
-
 
51
 
-
 
52
 
47
/* returns length of all http headers, or 0 if uncomplete yet */
53
/* returns length of all http headers, or 0 if uncomplete yet */
48
static unsigned short detecthttpheadersend(const unsigned char *buff) {
54
static unsigned short detecthttpheadersend(const unsigned char *buff) {
49
  char lastbyteislf = 0;
55
  char lastbyteislf = 0;
50
  unsigned short i;
56
  unsigned short i;
51
  for (i = 0; buff[i] != 0; i++) {
57
  for (i = 0; buff[i] != 0; i++) {
Line 67... Line 73...
67
 
73
 
68
 
74
 
69
static void help(void) {
75
static void help(void) {
70
  puts("pkgnet ver " PVER " -- Copyright (C) " PDATE " Mateusz Viste");
76
  puts("pkgnet ver " PVER " -- Copyright (C) " PDATE " Mateusz Viste");
71
  puts("");
77
  puts("");
72
  puts("pkgnet is the SvarDOS package downloader.");
78
  putsnls(1, 0);  /* "pkgnet is the SvarDOS package downloader" */
73
  puts("");
79
  puts("");
74
  puts("usage:  pkgnet search <term>");
80
  putsnls(1, 1);  /* "usage:  pkgnet search <term>" */
75
  puts("        pkgnet pull <package>");
81
  putsnls(1, 2);  /* "        pkgnet pull <package>" */
76
  puts("        pkgnet pull <package>-<version>");
82
  putsnls(1, 3);  /* "        pkgnet pull <package>-<version>" */
77
  puts("        pkgnet checkup");
83
  putsnls(1, 6);  /* "        pkgnet checkup" */
78
  puts("");
84
  puts("");
79
  puts("actions:");
85
  putsnls(1, 7);  /* "actions:" */
80
  puts(" search   - asks remote repository for the list of matching packages");
-
 
81
  puts(" pull     - downloads package into current directory");
-
 
82
  puts(" checkup  - lists updates available for your system");
-
 
83
  puts("");
86
  puts("");
-
 
87
  putsnls(1, 8);  /* "search   - asks remote repository for the list of matching packages" */
84
  printf("Watt32 kernel: %s", net_engine());
88
  putsnls(1, 9);  /* "pull     - downloads package into current directory" */
-
 
89
  putsnls(1, 10); /* "checkup  - lists updates available for your system" */
85
  puts("");
90
  puts("");
-
 
91
  printf("Watt32 kernel: %s", net_engine());
86
  puts("");
92
  puts("");
87
}
93
}
88
 
94
 
89
 
95
 
90
/* parses command line arguments and fills outfname and url accordingly
96
/* parses command line arguments and fills outfname and url accordingly
Line 184... Line 190...
184
 
190
 
185
  /* make sure I know %DOSDIR% */
191
  /* make sure I know %DOSDIR% */
186
  if (dosdir == NULL) {
192
  if (dosdir == NULL) {
187
    dosdir = getenv("DOSDIR");
193
    dosdir = getenv("DOSDIR");
188
    if ((dosdir == NULL) || (dosdir[0] == 0)) {
194
    if ((dosdir == NULL) || (dosdir[0] == 0)) {
189
      puts("ERROR: %DOSDIR% not set");
195
      putsnls(9, 0); /* "ERROR: %DOSDIR% not set" */
190
      return(0);
196
      return(0);
191
    }
197
    }
192
  }
198
  }
193
 
199
 
194
  /* if first call, open the package directory */
200
  /* if first call, open the package directory */
195
  if (dp == NULL) {
201
  if (dp == NULL) {
196
    sprintf(buff, "%s\\packages", dosdir);
202
    sprintf(buff, "%s\\packages", dosdir);
197
    dp = opendir(buff);
203
    dp = opendir(buff);
198
    if (dp == NULL) {
204
    if (dp == NULL) {
199
      puts("ERROR: Could not access %DOSDIR%\\packages directory");
205
      putsnls(9, 1); /* "ERROR: Could not access %DOSDIR%\\packages directory" */
200
      return(0);
206
      return(0);
201
    }
207
    }
202
  }
208
  }
203
 
209
 
204
  for (;;) {
210
  for (;;) {
Line 244... Line 250...
244
  buffersz -= sizeof(*unchstate);
250
  buffersz -= sizeof(*unchstate);
245
  memset(unchstate, 0, sizeof(*unchstate));
251
  memset(unchstate, 0, sizeof(*unchstate));
246
 
252
 
247
  sock = net_connect(ipaddr, 80);
253
  sock = net_connect(ipaddr, 80);
248
  if (sock == NULL) {
254
  if (sock == NULL) {
249
    puts("ERROR: failed to connect to " HOSTADDR);
255
    printf(svarlang_strid(0x0902), HOSTADDR); /* "ERROR: failed to connect to " HOSTADDR */
-
 
256
    puts("");
250
    goto SHITQUIT;
257
    goto SHITQUIT;
251
  }
258
  }
252
 
259
 
253
  /* wait for net_connect() to actually connect */
260
  /* wait for net_connect() to actually connect */
254
  for (;;) {
261
  for (;;) {
255
    int connstate = net_isconnected(sock);
262
    int connstate = net_isconnected(sock);
256
    if (connstate > 0) break;
263
    if (connstate > 0) break;
257
    if (connstate < 0) {
264
    if (connstate < 0) {
-
 
265
      printf(svarlang_strid(0x0902), HOSTADDR); /* "ERROR: failed to connect to " HOSTADDR */
258
      puts("ERROR: connection error");
266
      puts("");
259
      goto SHITQUIT;
267
      goto SHITQUIT;
260
    }
268
    }
261
    _asm int 28h;  /* DOS idle */
269
    _asm int 28h;  /* DOS idle */
262
  }
270
  }
263
 
271
 
Line 267... Line 275...
267
  } else {
275
  } else {
268
    snprintf((char *)buffer, buffersz, "GET %s HTTP/1.1\r\nHOST: " HOSTADDR "\r\nUSER-AGENT: pkgnet/" PVER "\r\nConnection: close\r\n\r\n", url);
276
    snprintf((char *)buffer, buffersz, "GET %s HTTP/1.1\r\nHOST: " HOSTADDR "\r\nUSER-AGENT: pkgnet/" PVER "\r\nConnection: close\r\n\r\n", url);
269
  }
277
  }
270
 
278
 
271
  if (net_send(sock, buffer, strlen((char *)buffer)) != (int)strlen((char *)buffer)) {
279
  if (net_send(sock, buffer, strlen((char *)buffer)) != (int)strlen((char *)buffer)) {
272
    puts("ERROR: failed to send HTTP query to remote server");
280
    putsnls(9, 3); /* "ERROR: failed to send a HTTP query to remote server" */
273
    goto SHITQUIT;
281
    goto SHITQUIT;
274
  }
282
  }
275
 
283
 
276
  /* send chunked data for POST queries */
284
  /* send chunked data for POST queries */
277
  if (ispost) {
285
  if (ispost) {
Line 284... Line 292...
284
        hlen = sprintf(hbuf, "0\r\n");
292
        hlen = sprintf(hbuf, "0\r\n");
285
      } else {
293
      } else {
286
        hlen = sprintf(hbuf, "%X\r\n", blen);
294
        hlen = sprintf(hbuf, "%X\r\n", blen);
287
      }
295
      }
288
      if (net_send(sock, hbuf, hlen) != hlen) {
296
      if (net_send(sock, hbuf, hlen) != hlen) {
289
        puts("ERROR: failed to send POST data to remote server");
297
        putsnls(9, 4); /* "ERROR: failed to send POST data to remote server" */
290
        goto SHITQUIT;
298
        goto SHITQUIT;
291
      }
299
      }
292
      /* add trailing CR/LF to buffer as required by chunked mode */
300
      /* add trailing CR/LF to buffer as required by chunked mode */
293
      buffer[blen++] = '\r';
301
      buffer[blen++] = '\r';
294
      buffer[blen++] = '\n';
302
      buffer[blen++] = '\n';
295
      if (net_send(sock, buffer, blen) != blen) {
303
      if (net_send(sock, buffer, blen) != blen) {
296
        puts("ERROR: failed to send POST data to remote server");
304
        putsnls(9, 4); /* "ERROR: failed to send POST data to remote server" */
297
        goto SHITQUIT;
305
        goto SHITQUIT;
298
      }
306
      }
299
    } while (blen != 2);
307
    } while (blen != 2);
300
  }
308
  }
301
 
309
 
302
  /* receive and process HTTP headers */
310
  /* receive and process HTTP headers */
303
  byteread = htget_headers(buffer, buffersz, sock, &httpcode, &ischunked);
311
  byteread = htget_headers(buffer, buffersz, sock, &httpcode, &ischunked);
304
 
312
 
305
  /* transmission error? */
313
  /* transmission error? */
306
  if (byteread < 0) {
314
  if (byteread < 0) {
307
    printf("ERROR: communication error (%d)", byteread);
315
    printf(svarlang_strid(0x0905), byteread); /* "ERROR: TCP communication error #%d" */
308
    puts("");
316
    puts("");
309
    goto SHITQUIT;
317
    goto SHITQUIT;
310
  }
318
  }
311
 
319
 
312
  /* open destination file if required and if no server-side error occured */
320
  /* open destination file if required and if no server-side error occured */
313
  if ((httpcode >= 200) && (httpcode <= 299) && (*outfname != 0)) {
321
  if ((httpcode >= 200) && (httpcode <= 299) && (*outfname != 0)) {
314
    fd = fopen(outfname, "wb");
322
    fd = fopen(outfname, "wb");
315
    if (fd == NULL) {
323
    if (fd == NULL) {
316
      printf("ERROR: failed to create file %s", outfname);
324
      printf(svarlang_strid(0x0906), outfname); /* "ERROR: failed to create file %s" */
317
      puts("");
325
      puts("");
318
      goto SHITQUIT;
326
      goto SHITQUIT;
319
    }
327
    }
320
  }
328
  }
321
 
329
 
Line 331... Line 339...
331
 
339
 
332
      /* if downloading to file, write stuff to disk */
340
      /* if downloading to file, write stuff to disk */
333
      if (fd != NULL) {
341
      if (fd != NULL) {
334
        int i;
342
        int i;
335
        if (fwrite(buffer, 1, byteread, fd) != byteread) {
343
        if (fwrite(buffer, 1, byteread, fd) != byteread) {
336
          printf("ERROR: failed to write data to file %s after %ld bytes", outfname, flen);
344
          printf(svarlang_strid(0x0907), outfname, flen); /* "ERROR: failed to write data to file %s after %ld bytes" */
337
          puts("");
345
          puts("");
338
          break;
346
          break;
339
        }
347
        }
340
        flen += byteread;
348
        flen += byteread;
341
        /* update progress once a sec */
349
        /* update progress once a sec */
Line 361... Line 369...
361
    } else if (byteread < 0) { /* end of connection */
369
    } else if (byteread < 0) { /* end of connection */
362
      break;
370
      break;
363
 
371
 
364
    } else { /* check for timeout (byteread == 0) */
372
    } else { /* check for timeout (byteread == 0) */
365
      if (time(NULL) - lastactivity > 20) { /* TIMEOUT! */
373
      if (time(NULL) - lastactivity > 20) { /* TIMEOUT! */
366
        puts("ERROR: Timeout while waiting for data");
374
        putsnls(9, 8); /* "ERROR: Timeout while waiting for data" */
367
        goto SHITQUIT;
375
        goto SHITQUIT;
368
      }
376
      }
369
      /* waiting for packets - release a CPU cycle in the meantime */
377
      /* waiting for packets - release a CPU cycle in the meantime */
370
      _asm int 28h;
378
      _asm int 28h;
371
    }
379
    }
Line 402... Line 410...
402
    char ipaddr[64];
410
    char ipaddr[64];
403
    char url[64];
411
    char url[64];
404
    char outfname[16];
412
    char outfname[16];
405
  } *mem;
413
  } *mem;
406
 
414
 
-
 
415
  svarlang_autoload("PKGNET");
-
 
416
 
407
  /* allocate memory */
417
  /* allocate memory */
408
  mem = malloc(sizeof(*mem));
418
  mem = malloc(sizeof(*mem));
409
  if (mem == NULL) {
419
  if (mem == NULL) {
410
    puts("ERROR: out of memory");
420
    putsnls(9, 9); /* "ERROR: out of memory" */
411
    return(1);
421
    return(1);
412
  }
422
  }
413
 
423
 
414
  /* parse command line arguments */
424
  /* parse command line arguments */
415
  if (parseargv(argc, argv, mem->outfname, mem->url, &ispost) != 0) return(1);
425
  if (parseargv(argc, argv, mem->outfname, mem->url, &ispost) != 0) return(1);
416
 
426
 
417
  /* if outfname requested, make sure that file does not exist yet */
427
  /* if outfname requested, make sure that file does not exist yet */
418
  if ((mem->outfname[0] != 0) && (fexists(mem->outfname))) {
428
  if ((mem->outfname[0] != 0) && (fexists(mem->outfname))) {
419
    printf("ERROR: file %s already exists", mem->outfname);
429
    printf(svarlang_strid(0x090A), mem->outfname); /* "ERROR: file %s already exists" */
420
    puts("");
430
    puts("");
421
    return(1);
431
    return(1);
422
  }
432
  }
423
 
433
 
424
  /* init network stack */
434
  /* init network stack */
425
  if (net_init() != 0) {
435
  if (net_init() != 0) {
426
    puts("ERROR: Network subsystem initialization failed");
436
    putsnls(9, 11); /* "ERROR: Network subsystem initialization failed" */
427
    return(1);
437
    return(1);
428
  }
438
  }
429
 
439
 
430
  puts(""); /* required because watt-32 likes to print out garbage sometimes ("configuring through DHCP...") */
440
  puts(""); /* required because watt-32 likes to print out garbage sometimes ("configuring through DHCP...") */
431
 
441
 
432
  if (net_dnsresolve(mem->ipaddr, HOSTADDR) != 0) {
442
  if (net_dnsresolve(mem->ipaddr, HOSTADDR) != 0) {
433
    puts("ERROR: DNS resolution failed");
443
    putsnls(9, 12); /* "ERROR: DNS resolution failed" */
434
    return(1);
444
    return(1);
435
  }
445
  }
436
 
446
 
437
  flen = htget(mem->ipaddr, mem->url, mem->outfname, &bsum, ispost, mem->buffer, sizeof(mem->buffer));
447
  flen = htget(mem->ipaddr, mem->url, mem->outfname, &bsum, ispost, mem->buffer, sizeof(mem->buffer));
438
  if (flen < 1) return(1);
448
  if (flen < 1) return(1);
439
 
449
 
440
  if (mem->outfname[0] != 0) {
450
  if (mem->outfname[0] != 0) {
441
    /* print bsum, size, filename */
451
    /* print bsum, size, filename */
442
    printf("Downloaded %ld KiB into %s (BSUM: %04X)", flen >> 10, mem->outfname, bsum);
452
    printf(svarlang_strid(0x0200), flen >> 10, mem->outfname, bsum); /* Downloaded %ld KiB into %s (BSUM: %04X) */
443
    puts("");
453
    puts("");
444
  }
454
  }
445
 
455
 
446
  return(0);
456
  return(0);
447
}
457
}