Subversion Repositories SvarDOS

Rev

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