Subversion Repositories SvarDOS

Rev

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