Subversion Repositories SvarDOS

Rev

Rev 2163 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
562 mateuszvis 1
<?php /*
2
 
3
  SvarDOS repo index builder
1697 mateusz.vi 4
  Copyright (C) Mateusz Viste 2012-2024
562 mateuszvis 5
 
734 bttr 6
  buildidx computes an index json file for the SvarDOS repository.
673 mateusz.vi 7
  it must be executed pointing to a directory that stores packages (*.svp)
562 mateuszvis 8
  files. buildidx will generate the index file and save it into the package
9
  repository.
10
 
11
  requires php-zip
12
 
2163 mateusz.vi 13
  14 oct 2024: tolerate single-file documentation of CORE pkgs in DOC/PKGNAME.TXT
1811 bernd.boec 14
  20 may 2024: directory for alternative kernels changed to "KERNEL"
1801 mateusz.vi 15
  10 mar 2024: support for "url" in LSM files
1697 mateusz.vi 16
  01 feb 2024: computes the "latest" collection of symlinks
1608 mateusz.vi 17
  24 nov 2023: SVED included in the MS-DOS compat list instead of EDIT + support for "release xyz" versions
1522 mateusz.vi 18
  25 aug 2023: validation of the hwreq section in LSM files
1509 mateusz.vi 19
  24 aug 2023: load hwreq data from LSM and store them in the json index + skip the '.svn' dir
1267 mateusz.vi 20
  30 jun 2023: adapted for new CORE packages location (../packages-core)
999 mateusz.vi 21
  28 feb 2022: svarcom allowed to have a COMMAND.COM file without subdirectory
951 mateusz.vi 22
  24 feb 2022: added hardcoded hack to translate version 'x.xx' to '0.44' (NESticle)
941 mateusz.vi 23
  23 feb 2022: basic validation of source archives (not empty + matches an existing svp file)
912 mateusz.vi 24
  21 feb 2022: buildidx collects categories looking at the dir layout of each package + improved version string parsing (replaced version_compare call by dos_version_compare)
775 mateusz.vi 25
  17 feb 2022: checking for non-8+3 filenames in packages and duplicates + devload no longer part of CORE
736 mateusz.vi 26
  16 feb 2022: added warning about overlong version strings and wild files location
719 mateusz.vi 27
  15 feb 2022: index is generated as json, contains all filenames and alt versions
673 mateusz.vi 28
  14 feb 2022: packages are expected to have the *.svp extension
650 mateusz.vi 29
  12 feb 2022: skip source packages from being processed (*.src.zip)
562 mateuszvis 30
  20 jan 2022: rewritten the code from ANSI C to PHP for easier maintenance
31
  13 feb 2021: 'title' LSM field is no longer looked after
32
  11 feb 2021: lsm headers are no longer checked, so it is compatible with the simpler lsm format used by SvarDOS
33
  13 jan 2021: removed the identification line, changed CRC32 to bsum, not creating the listing.txt file and stopped compressing index
34
  23 apr 2017: uncompressed index is no longer created, added CRC32 of zib (bin only) files, if present
35
  28 aug 2016: listing.txt is always written inside the repo dir (instead of inside current dir)
36
  27 aug 2016: accepting full paths to repos (starting with /...)
37
  07 dec 2013: rewritten buildidx in ANSI C89
38
  19 aug 2013: add a compressed version of the index file to repos (index.gz)
39
  22 jul 2013: creating a listing.txt file with list of packages
40
  18 jul 2013: writing the number of packaged into the first line of the lst file
41
  11 jul 2013: added a switch to 7za to make it case insensitive when extracting lsm files
42
  10 jul 2013: changed unzip calls to 7za (to handle cases when appinfo is compressed with lzma)
43
  04 feb 2013: added CRC32 support
44
  22 sep 2012: forked 1st version from FDUPDATE builder
45
*/
46
 
2163 mateusz.vi 47
$PVER = "20241014";
562 mateuszvis 48
 
49
 
50
// computes the BSD sum of a file and returns it
51
function file2bsum($fname) {
52
  $result = 0;
53
 
54
  $fd = fopen($fname, 'rb');
55
  if ($fd === false) return(0);
56
 
57
  while (!feof($fd)) {
58
 
59
    $buff = fread($fd, 1024 * 1024);
60
 
563 mateuszvis 61
    $slen = strlen($buff);
62
    for ($i = 0; $i < $slen; $i++) {
562 mateuszvis 63
      // rotr
64
      $result = ($result >> 1) | ($result << 15);
65
      // add and truncate to 16 bits
563 mateuszvis 66
      $result += ord($buff[$i]);
562 mateuszvis 67
      $result &= 0xffff;
68
    }
69
  }
70
 
71
  fclose($fd);
72
  return($result);
73
}
74
 
75
 
912 mateusz.vi 76
// translates a version string into a array of integer values.
77
// Accepted formats follow:
78
//    300.12.1
79
//    1
80
//    12.2.34.2-4.5
81
//    1.2c
82
//    1.01 beta+3
83
//    2013-12-31
84
//    20220222 alpha
85
function vertoarr($verstr) {
86
  $subver = array(0,0,0,0);
87
 
88
  // switch string to lcase for easier processing and trim any leading or trailing white spaces
89
  $verstr = strtolower(trim($verstr));
90
 
1608 mateusz.vi 91
  // Special hack for E. C. Masloch's lDebug. lDebug's versions are identifying as "releases" and wish to be recognized as such. If the version string starts with "release " I remove this word and continue.
92
  if (preg_match('/^release /', $verstr)) $verstr = substr($verstr, 8);
93
 
912 mateusz.vi 94
  // replace all '-' and '/' characters to '.' (uniformization of sub-version parts delimiters)
95
  $verstr = strtr($verstr, '-/', '..');
96
 
97
  // is there a subversion value? (for example "+4" in "1.05+4")
98
  $i = strrpos($verstr, '+', 1);
99
  if ($i !== false) {
100
    // validate the svar-version is a proper integer
101
    $svarver = substr($verstr, $i + 1);
102
    if (! preg_match('/[1-9][0-9]*/', $svarver)) {
103
      return(false);
104
    }
105
    $subver[3] = intval($svarver); // set the +rev as a very minor item
106
    $verstr = substr($verstr, 0, $i);
107
  }
108
 
951 mateusz.vi 109
  // NESticls hack: version "x.xx" is translated to "0.44"... that sucks but that's how it is.
110
  // ref: https://web.archive.org/web/20070205074631/http://www.zophar.net/NESticle/
111
  if ($verstr == 'x.xx') $verstr = '0.44';
112
 
936 mateusz.vi 113
  // beta reordering: convert "beta 0.95" to "0.95 beta"
114
  if (preg_match('/^beta /', $verstr)) $verstr = substr($verstr, 5) . ' beta';
115
 
927 mateusz.vi 116
  // any occurence of alpha,beta,gamma,delta etc preceded by a digit should have a space separator added
117
  // example: "2.6.0pre9" becomes "2.6.0 pre9"
118
  $verstr = preg_replace('/([0-9])(alpha|beta|gamma|delta|pre|rc|patch)/', '$1 $2', $verstr);
119
 
120
  // same as above, but this time adding a trailing space separator
121
  // example: "2.6.0 pre9" becomes "2.6.0 pre 9"
122
  $verstr = preg_replace('/(alpha|beta|gamma|delta|pre|rc|patch)([0-9])/', '$1 $2', $verstr);
123
 
921 mateusz.vi 124
  // is the version ending with ' alpha', 'beta', etc?
922 mateusz.vi 125
  if (preg_match('/ (alpha|beta|gamma|delta|pre|rc|patch)( [0-9]{1,4}){0,1}$/', $verstr)) {
921 mateusz.vi 126
    // if there is a trailing beta-number, process it first
127
    if (preg_match('/ [0-9]{1,4}$/', $verstr)) {
128
      $i = strrpos($verstr, ' ');
129
      $subver[2] = intval(substr($verstr, $i + 1));
130
      $verstr = trim(substr($verstr, 0, $i));
131
    }
912 mateusz.vi 132
    $i = strrpos($verstr, ' ');
133
    $greek = substr($verstr, $i + 1);
134
    $verstr = trim(substr($verstr, 0, $i));
135
    if ($greek == 'alpha') {
921 mateusz.vi 136
      $subver[1] = 1;
912 mateusz.vi 137
    } else if ($greek == 'beta') {
921 mateusz.vi 138
      $subver[1] = 2;
920 mateusz.vi 139
    } else if ($greek == 'gamma') {
921 mateusz.vi 140
      $subver[1] = 3;
920 mateusz.vi 141
    } else if ($greek == 'delta') {
921 mateusz.vi 142
      $subver[1] = 4;
143
    } else if ($greek == 'pre') {
144
      $subver[1] = 5;
914 mateusz.vi 145
    } else if ($greek == 'rc') {
921 mateusz.vi 146
      $subver[1] = 6;
922 mateusz.vi 147
    } else if ($greek == 'patch') { // this is a POST-release version, as opposed to all above that are PRE-release versions
148
      $subver[1] = 99;
912 mateusz.vi 149
    } else {
150
      return(false);
151
    }
914 mateusz.vi 152
  } else {
922 mateusz.vi 153
    $subver[1] = 98; // one less than the 'patch' level
912 mateusz.vi 154
  }
155
 
156
  // does the version string have a single-letter subversion? (1.0c)
157
  if (preg_match('/[a-z]$/', $verstr)) {
921 mateusz.vi 158
    $subver[0] = ord(substr($verstr, -1));
912 mateusz.vi 159
    $verstr = substr_replace($verstr, '', -1); // remove last character from string
160
  }
161
 
926 mateusz.vi 162
  // convert "30-jan-99", "1999-jan-30" and "30-jan-1999" versions to "30jan99" or "30jan1999"
163
  // note that dashes have already been replaced by dots
164
  if (preg_match('/^([0-9][0-9]){1,2}\.(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\.([0-9][0-9]){1,2}$/', $verstr)) {
165
    $verstr = str_replace('.', '', $verstr);
166
  }
167
 
168
  // convert "2009mar17" versions to "17mar2009"
169
  if (preg_match('/^[0-9]{4}(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[0-9]{2}$/', $verstr)) {
170
    $dy = substr($verstr, 7);
171
    $mo = substr($verstr, 4, 3);
172
    $ye = substr($verstr, 0, 4);
925 mateusz.vi 173
    $verstr = "{$dy}{$mo}{$ye}";
923 mateusz.vi 174
  }
175
 
176
  // convert "30jan99" versions to 99.1.30 and "30jan1999" to 1999.1.30
925 mateusz.vi 177
  if (preg_match('/^[0-3][0-9](jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)([0-9][0-9]){1,2}$/', $verstr)) {
923 mateusz.vi 178
    $months = array('jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8, 'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' => 12);
179
    $dy = substr($verstr, 0, 2);
180
    $mo = $months[substr($verstr, 2, 3)];
181
    $ye = substr($verstr, 5);
182
    $verstr = "{$ye}.{$mo}.{$dy}";
183
  }
184
 
912 mateusz.vi 185
  // validate the format is supported, should be something no more complex than 1.05.3.33
919 mateusz.vi 186
  if (! preg_match('/^[0-9][0-9.]{0,20}$/', $verstr)) {
912 mateusz.vi 187
    return(false);
188
  }
189
 
190
  // NOTE: a zero right after a separator and trailed with a digit (as in 1.01)
191
  //       has a special meaning
192
  $exploded = explode('.', $verstr);
193
  if (count($exploded) > 16) {
194
    return(false);
195
  }
921 mateusz.vi 196
  $exploded[16] = $subver[0]; // a-z (1.0c)
197
  $exploded[17] = $subver[1]; // alpha/beta/gamma/delta/rc/pre
198
  $exploded[18] = $subver[2]; // alpha-beta-gamma subversion (eg. "beta 9")
912 mateusz.vi 199
  $exploded[19] = $subver[3]; // svar-ver (1.0+5)
200
  for ($i = 0; $i < 20; $i++) if (empty($exploded[$i])) $exploded[$i] = '0';
201
 
202
  ksort($exploded);
203
 
204
  return($exploded);
205
}
206
 
207
 
208
function dos_version_compare($v1, $v2) {
209
  $v1arr = vertoarr($v1);
210
  $v2arr = vertoarr($v2);
211
  for ($i = 0; $i < count($v1arr); $i++) {
921 mateusz.vi 212
    if ($v1arr[$i] > $v2arr[$i]) return(1);
213
    if ($v1arr[$i] < $v2arr[$i]) return(-1);
912 mateusz.vi 214
  }
215
  return(0);
216
}
217
 
218
 
562 mateuszvis 219
// reads file fil from zip archive z and returns its content, or false on error
220
function read_file_from_zip($z, $fil) {
221
  $zip = new ZipArchive;
222
  if ($zip->open($z, ZipArchive::RDONLY) !== true) {
223
    echo "ERROR: failed to open zip file '{$z}'\n";
224
    return(false);
225
  }
226
 
227
  // load the appinfo/pkgname.lsm file
228
  $res = $zip->getFromName($fil, 8192, ZipArchive::FL_NOCASE);
229
 
230
  $zip->close();
231
  return($res);
232
}
233
 
234
 
731 mateusz.vi 235
function read_list_of_files_in_zip($z) {
236
  $zip = new ZipArchive;
237
  if ($zip->open($z, ZipArchive::RDONLY) !== true) {
238
    echo "ERROR: failed to open zip file '{$z}'\n";
239
    return(false);
240
  }
241
 
242
  $res = array();
243
  for ($i = 0; $i < $zip->numFiles; $i++) $res[] = $zip->getNameIndex($i);
244
 
245
  $zip->close();
246
  return($res);
247
}
248
 
249
 
562 mateuszvis 250
// reads a LSM string and returns it in the form of an array
251
function parse_lsm($s) {
252
  $res = array();
253
  for ($l = strtok($s, "\n"); $l !== false; $l = strtok("\n")) {
254
    // the line is "token: value", let's find the colon
255
    $colpos = strpos($l, ':');
256
    if (($colpos === false) || ($colpos === 0)) continue;
257
    $tok = strtolower(trim(substr($l, 0, $colpos)));
258
    $val = trim(substr($l, $colpos + 1));
259
    $res[$tok] = $val;
260
  }
261
  return($res);
262
}
263
 
264
 
731 mateusz.vi 265
// on PHP 8+ there is str_starts_with(), but not on PHP 7 so I use this
266
function str_head_is($haystack, $needle) {
267
  return strpos($haystack, $needle) === 0;
268
}
269
 
270
 
791 mateusz.vi 271
// returns an array that contains CORE packages (populated from the core subdirectory in pkgdir)
1267 mateusz.vi 272
function load_core_list($repodir_core) {
791 mateusz.vi 273
  $res = array();
274
 
1267 mateusz.vi 275
  foreach (scandir($repodir_core) as $f) {
791 mateusz.vi 276
    if (!preg_match('/\.svp$/', $f)) continue;
277
    $res[] = explode('.', $f)[0];
278
  }
279
  return($res);
280
}
281
 
282
 
562 mateuszvis 283
// ***************** MAIN ROUTINE *********************************************
284
 
719 mateusz.vi 285
//echo "SvarDOS repository index generator ver {$PVER}\n";
562 mateuszvis 286
 
287
if (($_SERVER['argc'] != 2) || ($_SERVER['argv'][1][0] == '-')) {
288
  echo "usage: php buildidx.php repodir\n";
289
  exit(1);
290
}
291
 
292
$repodir = $_SERVER['argv'][1];
293
 
294
$pkgfiles = scandir($repodir);
295
$pkgcount = 0;
296
 
738 mateusz.vi 297
 
795 mateusz.vi 298
// load the list of CORE and MSDOS_COMPAT packages
738 mateusz.vi 299
 
1267 mateusz.vi 300
$core_packages_list = load_core_list($repodir . '/../packages-core/');
2164 mateusz.vi 301
$msdos_compat_list = explode(' ', 'append assign attrib callver chkdsk choice comp cpidos debug defrag deltree diskcomp diskcopy display edlin exe2bin fc fdapm fdisk find format freecom help himemx kernledr kernlfd keyb label localcfg mem mirror mode more move nlsfunc print replace share shsucdx sort svarcom sved swsubst tree undelete unformat xcopy');
738 mateusz.vi 302
 
719 mateusz.vi 303
// do a list of all svp packages with their available versions and descriptions
562 mateuszvis 304
 
719 mateusz.vi 305
$pkgdb = array();
306
foreach ($pkgfiles as $fname) {
562 mateuszvis 307
 
941 mateusz.vi 308
  // zip files (ie. source archives)
309
  if (preg_match('/\.zip$/', $fname)) {
310
    // the zip archive should contain at least one file
311
    if (count(read_list_of_files_in_zip($repodir . '/' . $fname)) < 1) echo "WARNING: source archive {$fname} contains no files (either empty or corrupted)\n";
312
    // check that the file relates to an existing svp package
313
    $svpfname = preg_replace('/zip$/', 'svp', $fname);
314
    if (!file_exists($repodir . '/' . $svpfname)) echo "ERROR: orphaned source archive '{$fname}' (no matching svp file, expecting a package named '{$svpfname}')\n";
315
    // that is for zip files
316
    continue;
317
  }
318
 
1509 mateusz.vi 319
  // silently skip the hidden .svn directory
320
  if ($fname === '.svn') continue;
321
 
941 mateusz.vi 322
  // skip (and warn about) non-svp
323
  if (!preg_match('/\.svp$/', $fname)) {
1267 mateusz.vi 324
    $okfiles = array('.', '..', '_cats.json', '_index.json', '_buildidx.log');
941 mateusz.vi 325
    if (array_search($fname, $okfiles) !== false) continue;
1509 mateusz.vi 326
    echo "WARNING: wild file '{$fname}' (this is either an useless file that should be removed, or a misnamed package or source archive)'\n";
941 mateusz.vi 327
    continue;
328
  }
329
 
801 mateusz.vi 330
  if (!preg_match('/^[a-zA-Z0-9+. _-]*\.svp$/', $fname)) {
331
    echo "ERROR: {$fname} has a very weird name\n";
332
    continue;
333
  }
334
 
719 mateusz.vi 335
  $path_parts = pathinfo($fname);
336
  $pkgnam = explode('-', $path_parts['filename'])[0];
337
  $pkgfullpath = realpath($repodir . '/' . $fname);
562 mateuszvis 338
 
719 mateusz.vi 339
  $lsm = read_file_from_zip($pkgfullpath, "appinfo/{$pkgnam}.lsm");
562 mateuszvis 340
  if ($lsm == false) {
802 mateusz.vi 341
    echo "ERROR: {$fname} does not contain an LSM file at the expected location\n";
719 mateusz.vi 342
    continue;
562 mateuszvis 343
  }
344
  $lsmarray = parse_lsm($lsm);
345
  if (empty($lsmarray['version'])) {
719 mateusz.vi 346
    echo "ERROR: lsm file in {$fname} does not contain a version\n";
347
    continue;
562 mateuszvis 348
  }
730 mateusz.vi 349
  if (strlen($lsmarray['version']) > 16) {
737 mateusz.vi 350
    echo "ERROR: version string in lsm file of {$fname} is too long (16 chars max)\n";
730 mateusz.vi 351
    continue;
352
  }
562 mateuszvis 353
  if (empty($lsmarray['description'])) {
719 mateusz.vi 354
    echo "ERROR: lsm file in {$fname} does not contain a description\n";
355
    continue;
562 mateuszvis 356
  }
357
 
731 mateusz.vi 358
  // validate the files present in the archive
359
  $listoffiles = read_list_of_files_in_zip($pkgfullpath);
739 mateusz.vi 360
  $pkgdir = $pkgnam;
361
 
768 mateusz.vi 362
  // special rule for "parent and children" packages
363
  if (str_head_is($pkgnam, 'djgpp_')) $pkgdir = 'djgpp'; // djgpp_* packages put their files in djgpp
754 mateusz.vi 364
  if ($pkgnam == 'fbc_help') $pkgdir = 'fbc'; // FreeBASIC help goes to the FreeBASIC dir
802 mateusz.vi 365
  if ($pkgnam == 'clamdb') $pkgdir = 'clamav'; // data patterns for clamav
739 mateusz.vi 366
 
768 mateusz.vi 367
  // array used to detect duplicated entries after lower-case conversion
368
  $duparr = array();
369
 
909 mateusz.vi 370
  // will hold the list of categories that this package belongs to
371
  $catlist = array();
372
 
731 mateusz.vi 373
  foreach ($listoffiles as $f) {
374
    $f = strtolower($f);
768 mateusz.vi 375
    $path_array = explode('/', $f);
376
    // emit a warning when non-8+3 filenames are spotted and find duplicates
377
    foreach ($path_array as $item) {
378
      if (empty($item)) continue; // skip empty items at end of paths (eg. appinfo/)
379
      if (!preg_match("/[a-z0-9!#$%&'()@^_`{}~-]{1,8}(\.[a-z0-9!#$%&'()@^_`{}~-]{1,3}){0,1}/", $item)) {
380
        echo "WARNING: {$fname} contains a non-8+3 path (or weird char): {$item} (in $f)\n";
381
      }
382
    }
383
    // look for dups
384
    if (array_search($f, $duparr) !== false) {
385
      echo "WARNING: {$fname} contains a duplicated entry: '{$f}'\n";
386
    } else {
387
      $duparr[] = $f;
388
    }
731 mateusz.vi 389
    // LSM file is ok
390
    if ($f === "appinfo/{$pkgnam}.lsm") continue;
391
    if ($f === "appinfo/") continue;
795 mateusz.vi 392
    // CORE and MSDOS_COMPAT packages are premium citizens and can do a little more
909 mateusz.vi 393
    $core_or_msdoscompat = 0;
394
    if (array_search($pkgnam, $core_packages_list) !== false) {
395
      $catlist[] = 'core';
396
      $core_or_msdoscompat = 1;
397
    }
398
    if (array_search($pkgnam, $msdos_compat_list) !== false) {
399
      $catlist[] = 'msdos_compat';
400
      $core_or_msdoscompat = 1;
401
    }
402
    if ($core_or_msdoscompat == 1) {
736 mateusz.vi 403
      if (str_head_is($f, 'bin/')) continue;
779 mateusz.vi 404
      if (str_head_is($f, 'cpi/')) continue;
749 mateusz.vi 405
      if (str_head_is($f, "doc/{$pkgdir}/")) continue;
2163 mateusz.vi 406
      if ($f === "doc/{$pkgnam}.txt") continue;
749 mateusz.vi 407
      if ($f === 'doc/') continue;
408
      if (str_head_is($f, "nls/{$pkgdir}.")) continue;
409
      if ($f === 'nls/') continue;
736 mateusz.vi 410
    }
2163 mateusz.vi 411
    // SVARCOM and FREECOM are allowed to have a root-based COMMAND.COM file
412
    if (($pkgnam === 'svarcom') || ($pkgnam === 'freecom')) {
999 mateusz.vi 413
      if ($f === 'command.com') continue;
414
    }
2164 mateusz.vi 415
    // KERNL* packages are allowed to have a root-based KERNEL.SYS file and BIN/COUNTRY.SYS
416
    if (str_head_is($pkgnam, "kernl")) {
417
      if ($f === 'kernel.sys') continue;
418
      if ($f === 'bin/country.sys') continue;
419
    }
798 mateusz.vi 420
    // the help package is allowed to put files in... help
421
    if (($pkgnam == 'help') && (str_head_is($f, 'help/'))) continue;
909 mateusz.vi 422
    // must be category-prefixed file, add it to the list of categories for this package
423
    $catlist[] = explode('/', $f)[0];
749 mateusz.vi 424
    // well-known "category" dirs are okay
739 mateusz.vi 425
    if (str_head_is($f, "progs/{$pkgdir}/")) continue;
731 mateusz.vi 426
    if ($f === 'progs/') continue;
739 mateusz.vi 427
    if (str_head_is($f, "devel/{$pkgdir}/")) continue;
731 mateusz.vi 428
    if ($f === 'devel/') continue;
739 mateusz.vi 429
    if (str_head_is($f, "games/{$pkgdir}/")) continue;
731 mateusz.vi 430
    if ($f === 'games/') continue;
739 mateusz.vi 431
    if (str_head_is($f, "drivers/{$pkgdir}/")) continue;
731 mateusz.vi 432
    if ($f === 'drivers/') continue;
1810 bernd.boec 433
    if (str_head_is($f, "kernel/{$pkgdir}/")) continue;
768 mateusz.vi 434
    echo "WARNING: {$fname} contains a file in an illegal location: {$f}\n";
731 mateusz.vi 435
  }
436
 
912 mateusz.vi 437
  // do I understand the version string?
438
  if (vertoarr($lsmarray['version']) === false) echo "WARNING: {$fname} parsing of version string failed ('{$lsmarray['version']}')\n";
439
 
1511 mateusz.vi 440
  $meta = array();
719 mateusz.vi 441
  $meta['fname'] = $fname;
442
  $meta['desc'] = $lsmarray['description'];
909 mateusz.vi 443
  $meta['cats'] = array_unique($catlist);
1801 mateusz.vi 444
  $meta['url'] = $lsmarray['url'];
719 mateusz.vi 445
 
1522 mateusz.vi 446
  if (!empty($lsmarray['hwreq'])) {
447
    $meta['hwreq'] = explode(' ', strtolower($lsmarray['hwreq']));
1524 mateusz.vi 448
    sort($meta['hwreq']);
1522 mateusz.vi 449
 
450
    // validate list of valid hwreq tokens
451
    $validtokens = array('8086', '186', '286', '386', '486', '586', 'fpu', 'mda', 'cga', 'ega', 'vga', 'mcga', 'svga');
452
    foreach (array_diff($meta['hwreq'], $validtokens) as $tok) echo "WARNING: {$fname} contains an LSM hwreq section with invalid token: {$tok}\n";
453
  }
454
 
719 mateusz.vi 455
  $pkgdb[$pkgnam][$lsmarray['version']] = $meta;
456
}
457
 
801 mateusz.vi 458
 
719 mateusz.vi 459
$db = array();
909 mateusz.vi 460
$cats = array();
719 mateusz.vi 461
 
909 mateusz.vi 462
// ******** compute the version-sorted list of packages with a single *********
463
// ******** description and category list for each package ********************
464
 
719 mateusz.vi 465
// iterate over each svp package
466
foreach ($pkgdb as $pkg => $versions) {
467
 
468
  // sort filenames by version, highest first
912 mateusz.vi 469
  uksort($versions, "dos_version_compare");
719 mateusz.vi 470
  $versions = array_reverse($versions, true);
471
 
472
  foreach ($versions as $ver => $meta) {
473
    $fname = $meta['fname'];
474
    $desc = $meta['desc'];
1802 mateusz.vi 475
    $url = $meta['url'];
719 mateusz.vi 476
 
477
    $bsum = file2bsum(realpath($repodir . '/' . $fname));
478
 
1511 mateusz.vi 479
    $meta2 = array();
719 mateusz.vi 480
    $meta2['ver'] = strval($ver);
481
    $meta2['bsum'] = $bsum;
1522 mateusz.vi 482
    if (!empty($meta['hwreq'])) $meta2['hwreq'] = $meta['hwreq'];
719 mateusz.vi 483
 
484
    if (empty($db[$pkg]['desc'])) $db[$pkg]['desc'] = $desc;
1802 mateusz.vi 485
    if (empty($db[$pkg]['url'])) $db[$pkg]['url'] = $url;
909 mateusz.vi 486
    if (empty($db[$pkg]['cats'])) {
487
      $db[$pkg]['cats'] = $meta['cats'];
488
      $cats = array_unique(array_merge($cats, $meta['cats']));
489
    }
719 mateusz.vi 490
    $db[$pkg]['versions'][$fname] = $meta2;
491
  }
492
 
562 mateuszvis 493
  $pkgcount++;
494
 
495
}
496
 
719 mateusz.vi 497
if ($pkgcount < 100) echo "WARNING: an unexpectedly low number of packages has been found in the repo ({$pkgcount})\n";
562 mateuszvis 498
 
801 mateusz.vi 499
$json_blob = json_encode($db);
500
if ($json_blob === false) {
501
  echo "ERROR: JSON convertion failed! -> ";
502
  switch (json_last_error()) {
503
    case JSON_ERROR_DEPTH:
504
      echo 'maximum stack depth exceeded';
505
      break;
506
    case JSON_ERROR_STATE_MISMATCH:
507
      echo 'underflow of the modes mismatch';
508
      break;
509
    case JSON_ERROR_CTRL_CHAR:
510
      echo 'unexpected control character found';
511
      break;
512
    case JSON_ERROR_UTF8:
513
      echo 'malformed utf-8 characters';
514
      break;
515
    default:
516
      echo "unknown error";
517
      break;
518
  }
519
  echo "\n";
520
}
521
 
909 mateusz.vi 522
file_put_contents($repodir . '/_index.json', $json_blob);
562 mateuszvis 523
 
909 mateusz.vi 524
$cats_json = json_encode($cats);
525
file_put_contents($repodir . '/_cats.json', $cats_json);
526
 
1697 mateusz.vi 527
 
528
// populate the 'latest' dir with symlinks to latest version of every svp
529
mkdir($repodir . '/latest');
530
foreach ($db as $pkg => $props) {
531
  $fname = array_key_first($props['versions']);
532
  $cat = array_values($props['cats'])[0];
533
  //echo "pkg = '{$pkg}' ; fname = '{$fname}' ; cat = '{$cat}'\n";
534
  if (!file_exists($repodir . '/latest/' . $cat)) mkdir($repodir . '/latest/' . $cat);
535
  symlink('../../' . $fname, $repodir . '/latest/' . $cat . '/' . $pkg . '.svp');
536
}
537
 
538
 
562 mateuszvis 539
exit(0);
540
 
541
?>