Subversion Repositories SvarDOS

Rev

Rev 1964 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1959 mateusz.vi 1
/*
2
 * This file is part of the pkg (SvarDOS) project.
3
 * Copyright (C) Mateusz Viste 2012-2024
4
 */
5
 
1961 mateusz.vi 6
#include <direct.h> /* opendir() and friends */
1959 mateusz.vi 7
#include <stdio.h>
8
#include <string.h>    /* strlen() */
9
#include <stdlib.h>    /* free() */
10
 
11
#include "crc32.h"
12
#include "helpers.h"
13
#include "svarlang.lib\svarlang.h"
14
 
15
#include "healthck.h"
16
 
17
 
1961 mateusz.vi 18
static void clrcurline(unsigned short screenwidth);
19
#pragma aux clrcurline = \
20
"mov ah, 0x02" \
21
"mov dl, 0x0D" \
22
"int 0x21" \
23
"mov ax, 0x0A20" /* int 10h "write char to screen" */ \
24
"xor bx, bx"     /* video page and attribute (attr on PCjr) */ \
25
"int 0x10" \
26
parm [cx] \
27
modify [ax bx dx]
28
 
29
 
1959 mateusz.vi 30
/* checks the health of a package (or all packages).
31
 * Returns 0 on success, non-zero otherwise */
1964 mateusz.vi 32
int healthcheck(unsigned char *buff4k, const char *pkgname, const char *dosdir, unsigned char extendedcheck) {
1959 mateusz.vi 33
  char *crc, *ext;
34
  FILE *flist, *fd;
35
  unsigned long goodcrc, realcrc;
36
  unsigned short errcount = 0;
1961 mateusz.vi 37
  DIR *dp = NULL;
38
  struct dirent *ep;
1959 mateusz.vi 39
 
40
  if (pkgname == NULL) {
1964 mateusz.vi 41
    sprintf(buff4k, "%s\\appinfo", dosdir);
42
    dp = opendir(buff4k);
1961 mateusz.vi 43
    if (dp == NULL) {
1965 mateusz.vi 44
      output(svarlang_str(9, 0)); /* "ERROR: Could not access directory:" */
45
      outputnl(buff4k);
1961 mateusz.vi 46
      return(-1);
47
    }
48
 
49
    AGAIN:
50
 
51
    /* if check is system-wide then fetch next package */
52
    while ((ep = readdir(dp)) != NULL) { /* readdir() result must never be freed (static allocation) */
53
      int tlen = strlen(ep->d_name);
54
      if (ep->d_name[0] == '.') continue; /* ignore '.', '..', and hidden directories */
55
      if (tlen < 4) continue; /* files must be at least 5 bytes long ("x.lst") */
56
      if (strcasecmp(ep->d_name + tlen - 4, ".lsm") != 0) continue;  /* if not an .lsm file, skip it silently */
57
      ep->d_name[tlen - 4] = 0; /* trim out the ".lsm" suffix */
58
      break;
59
    }
60
    if (ep == NULL) {
61
      closedir(dp);
62
      goto DONE;
63
    }
64
    pkgname = ep->d_name;
1959 mateusz.vi 65
  }
66
 
1961 mateusz.vi 67
 
68
  /************************************************************
69
   * pkgname is valid now so let's proceed with serious stuff *
70
   ************************************************************/
71
 
1959 mateusz.vi 72
  /* open the (legacy) listing file at %DOSDIR%\packages\pkgname.lst
73
   * if not exists then fall back to appinfo\pkgname.lsm */
1964 mateusz.vi 74
  sprintf(buff4k, "%s\\appinfo\\%s.lsm", dosdir, pkgname);
75
  flist = fopen(buff4k, "rb");
1959 mateusz.vi 76
  if (flist == NULL) {
1965 mateusz.vi 77
    sprintf(buff4k, svarlang_str(4,0), pkgname); /* "Package %s is not installed, so not removed." */
78
    outputnl(buff4k);
1959 mateusz.vi 79
    return(-1);
80
  }
81
 
82
  /* iterate over all files listed in pkgname.lsm */
1964 mateusz.vi 83
  while (freadtokval(flist, buff4k, 4096, NULL, 0) == 0) {
1959 mateusz.vi 84
 
85
    /* skip empty lines */
1964 mateusz.vi 86
    if (buff4k[0] == 0) continue;
1959 mateusz.vi 87
 
88
    /* change all slash to backslash */
1964 mateusz.vi 89
    slash2backslash(buff4k);
1959 mateusz.vi 90
 
91
    /* skip garbage */
1964 mateusz.vi 92
    if ((buff4k[1] != ':') || (buff4k[2] != '\\')) continue;
1959 mateusz.vi 93
 
94
    /* trim out CRC information and get the ptr to it (if present) */
1964 mateusz.vi 95
    crc = trimfnamecrc(buff4k);
1959 mateusz.vi 96
    if (crc == NULL) continue;
97
 
98
    goodcrc = strtoul(crc, NULL, 16);
1964 mateusz.vi 99
    ext = getfext(buff4k);
1959 mateusz.vi 100
    strlwr(ext);
101
 
1961 mateusz.vi 102
    /* skip non-executable files (unless healthcheck+) */
103
    if ((extendedcheck == 0) &&
104
        (strcmp(ext, "bat") != 0) &&
105
        (strcmp(ext, "bin") != 0) &&
106
        (strcmp(ext, "com") != 0) &&
107
        (strcmp(ext, "dll") != 0) &&
108
        (strcmp(ext, "drv") != 0) &&
109
        (strcmp(ext, "exe") != 0) &&
110
        (strcmp(ext, "ovl") != 0) &&
111
        (strcmp(ext, "sys") != 0)) continue;
1959 mateusz.vi 112
 
113
    output("[");
114
    output(pkgname);
115
    output("] ");
1964 mateusz.vi 116
    output(buff4k);
1959 mateusz.vi 117
 
118
    realcrc = CRC32_INITVAL;
1964 mateusz.vi 119
    fd = fopen(buff4k, "rb");
1959 mateusz.vi 120
    if (fd == NULL) {
121
      outputnl(": NOT FOUND");
122
      continue;
123
    }
124
    for (;;) {
125
      unsigned short bufflen;
1964 mateusz.vi 126
      bufflen = fread(buff4k, 1, 4096, fd);
1959 mateusz.vi 127
      if (bufflen == 0) break;
1964 mateusz.vi 128
      crc32_feed(&realcrc, buff4k, bufflen);
1959 mateusz.vi 129
    }
130
    fclose(fd);
131
 
132
    crc32_finish(&realcrc);
133
 
134
    if (goodcrc != realcrc) {
1964 mateusz.vi 135
      sprintf(buff4k, ": %s", "BAD CRC");
136
      outputnl(buff4k);
1959 mateusz.vi 137
      errcount++;
138
      continue;
139
    }
140
 
1961 mateusz.vi 141
    clrcurline(80);
1959 mateusz.vi 142
 
143
  }
144
 
145
  /* close the lsm file */
146
  fclose(flist);
147
 
1961 mateusz.vi 148
  if (dp != NULL) goto AGAIN;
149
 
150
  DONE:
151
 
1959 mateusz.vi 152
  if (errcount == 0) {
153
    outputnl(svarlang_strid(0x0A00));
154
  } else {
1964 mateusz.vi 155
    sprintf(buff4k, "%u errors.", errcount);
156
    outputnl(buff4k);
1959 mateusz.vi 157
  }
158
  return(0);
159
}