Subversion Repositories SvarDOS

Rev

Rev 804 | Rev 912 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 804 Rev 909
1
<?php /*
1
<?php /*
2
 
2
 
3
  SvarDOS repo index builder
3
  SvarDOS repo index builder
4
  Copyright (C) Mateusz Viste 2012-2022
4
  Copyright (C) Mateusz Viste 2012-2022
5
 
5
 
6
  buildidx computes an index json file for the SvarDOS repository.
6
  buildidx computes an index json file for the SvarDOS repository.
7
  it must be executed pointing to a directory that stores packages (*.svp)
7
  it must be executed pointing to a directory that stores packages (*.svp)
8
  files. buildidx will generate the index file and save it into the package
8
  files. buildidx will generate the index file and save it into the package
9
  repository.
9
  repository.
10
 
10
 
11
  requires php-zip
11
  requires php-zip
12
 
12
 
-
 
13
  21 feb 2022: buildidx collects categories looking at the dir layout of each package
13
  17 feb 2022: checking for non-8+3 filenames in packages and duplicates + devload no longer part of CORE
14
  17 feb 2022: checking for non-8+3 filenames in packages and duplicates + devload no longer part of CORE
14
  16 feb 2022: added warning about overlong version strings and wild files location
15
  16 feb 2022: added warning about overlong version strings and wild files location
15
  15 feb 2022: index is generated as json, contains all filenames and alt versions
16
  15 feb 2022: index is generated as json, contains all filenames and alt versions
16
  14 feb 2022: packages are expected to have the *.svp extension
17
  14 feb 2022: packages are expected to have the *.svp extension
17
  12 feb 2022: skip source packages from being processed (*.src.zip)
18
  12 feb 2022: skip source packages from being processed (*.src.zip)
18
  20 jan 2022: rewritten the code from ANSI C to PHP for easier maintenance
19
  20 jan 2022: rewritten the code from ANSI C to PHP for easier maintenance
19
  13 feb 2021: 'title' LSM field is no longer looked after
20
  13 feb 2021: 'title' LSM field is no longer looked after
20
  11 feb 2021: lsm headers are no longer checked, so it is compatible with the simpler lsm format used by SvarDOS
21
  11 feb 2021: lsm headers are no longer checked, so it is compatible with the simpler lsm format used by SvarDOS
21
  13 jan 2021: removed the identification line, changed CRC32 to bsum, not creating the listing.txt file and stopped compressing index
22
  13 jan 2021: removed the identification line, changed CRC32 to bsum, not creating the listing.txt file and stopped compressing index
22
  23 apr 2017: uncompressed index is no longer created, added CRC32 of zib (bin only) files, if present
23
  23 apr 2017: uncompressed index is no longer created, added CRC32 of zib (bin only) files, if present
23
  28 aug 2016: listing.txt is always written inside the repo dir (instead of inside current dir)
24
  28 aug 2016: listing.txt is always written inside the repo dir (instead of inside current dir)
24
  27 aug 2016: accepting full paths to repos (starting with /...)
25
  27 aug 2016: accepting full paths to repos (starting with /...)
25
  07 dec 2013: rewritten buildidx in ANSI C89
26
  07 dec 2013: rewritten buildidx in ANSI C89
26
  19 aug 2013: add a compressed version of the index file to repos (index.gz)
27
  19 aug 2013: add a compressed version of the index file to repos (index.gz)
27
  22 jul 2013: creating a listing.txt file with list of packages
28
  22 jul 2013: creating a listing.txt file with list of packages
28
  18 jul 2013: writing the number of packaged into the first line of the lst file
29
  18 jul 2013: writing the number of packaged into the first line of the lst file
29
  11 jul 2013: added a switch to 7za to make it case insensitive when extracting lsm files
30
  11 jul 2013: added a switch to 7za to make it case insensitive when extracting lsm files
30
  10 jul 2013: changed unzip calls to 7za (to handle cases when appinfo is compressed with lzma)
31
  10 jul 2013: changed unzip calls to 7za (to handle cases when appinfo is compressed with lzma)
31
  04 feb 2013: added CRC32 support
32
  04 feb 2013: added CRC32 support
32
  22 sep 2012: forked 1st version from FDUPDATE builder
33
  22 sep 2012: forked 1st version from FDUPDATE builder
33
*/
34
*/
34
 
35
 
35
$PVER = "20220217";
36
$PVER = "20220221";
36
 
37
 
37
 
38
 
38
// computes the BSD sum of a file and returns it
39
// computes the BSD sum of a file and returns it
39
function file2bsum($fname) {
40
function file2bsum($fname) {
40
  $result = 0;
41
  $result = 0;
41
 
42
 
42
  $fd = fopen($fname, 'rb');
43
  $fd = fopen($fname, 'rb');
43
  if ($fd === false) return(0);
44
  if ($fd === false) return(0);
44
 
45
 
45
  while (!feof($fd)) {
46
  while (!feof($fd)) {
46
 
47
 
47
    $buff = fread($fd, 1024 * 1024);
48
    $buff = fread($fd, 1024 * 1024);
48
 
49
 
49
    $slen = strlen($buff);
50
    $slen = strlen($buff);
50
    for ($i = 0; $i < $slen; $i++) {
51
    for ($i = 0; $i < $slen; $i++) {
51
      // rotr
52
      // rotr
52
      $result = ($result >> 1) | ($result << 15);
53
      $result = ($result >> 1) | ($result << 15);
53
      // add and truncate to 16 bits
54
      // add and truncate to 16 bits
54
      $result += ord($buff[$i]);
55
      $result += ord($buff[$i]);
55
      $result &= 0xffff;
56
      $result &= 0xffff;
56
    }
57
    }
57
  }
58
  }
58
 
59
 
59
  fclose($fd);
60
  fclose($fd);
60
  return($result);
61
  return($result);
61
}
62
}
62
 
63
 
63
 
64
 
64
// reads file fil from zip archive z and returns its content, or false on error
65
// reads file fil from zip archive z and returns its content, or false on error
65
function read_file_from_zip($z, $fil) {
66
function read_file_from_zip($z, $fil) {
66
  $zip = new ZipArchive;
67
  $zip = new ZipArchive;
67
  if ($zip->open($z, ZipArchive::RDONLY) !== true) {
68
  if ($zip->open($z, ZipArchive::RDONLY) !== true) {
68
    echo "ERROR: failed to open zip file '{$z}'\n";
69
    echo "ERROR: failed to open zip file '{$z}'\n";
69
    return(false);
70
    return(false);
70
  }
71
  }
71
 
72
 
72
  // load the appinfo/pkgname.lsm file
73
  // load the appinfo/pkgname.lsm file
73
  $res = $zip->getFromName($fil, 8192, ZipArchive::FL_NOCASE);
74
  $res = $zip->getFromName($fil, 8192, ZipArchive::FL_NOCASE);
74
 
75
 
75
  $zip->close();
76
  $zip->close();
76
  return($res);
77
  return($res);
77
}
78
}
78
 
79
 
79
 
80
 
80
function read_list_of_files_in_zip($z) {
81
function read_list_of_files_in_zip($z) {
81
  $zip = new ZipArchive;
82
  $zip = new ZipArchive;
82
  if ($zip->open($z, ZipArchive::RDONLY) !== true) {
83
  if ($zip->open($z, ZipArchive::RDONLY) !== true) {
83
    echo "ERROR: failed to open zip file '{$z}'\n";
84
    echo "ERROR: failed to open zip file '{$z}'\n";
84
    return(false);
85
    return(false);
85
  }
86
  }
86
 
87
 
87
  $res = array();
88
  $res = array();
88
  for ($i = 0; $i < $zip->numFiles; $i++) $res[] = $zip->getNameIndex($i);
89
  for ($i = 0; $i < $zip->numFiles; $i++) $res[] = $zip->getNameIndex($i);
89
 
90
 
90
  $zip->close();
91
  $zip->close();
91
  return($res);
92
  return($res);
92
}
93
}
93
 
94
 
94
 
95
 
95
// reads a LSM string and returns it in the form of an array
96
// reads a LSM string and returns it in the form of an array
96
function parse_lsm($s) {
97
function parse_lsm($s) {
97
  $res = array();
98
  $res = array();
98
  for ($l = strtok($s, "\n"); $l !== false; $l = strtok("\n")) {
99
  for ($l = strtok($s, "\n"); $l !== false; $l = strtok("\n")) {
99
    // the line is "token: value", let's find the colon
100
    // the line is "token: value", let's find the colon
100
    $colpos = strpos($l, ':');
101
    $colpos = strpos($l, ':');
101
    if (($colpos === false) || ($colpos === 0)) continue;
102
    if (($colpos === false) || ($colpos === 0)) continue;
102
    $tok = strtolower(trim(substr($l, 0, $colpos)));
103
    $tok = strtolower(trim(substr($l, 0, $colpos)));
103
    $val = trim(substr($l, $colpos + 1));
104
    $val = trim(substr($l, $colpos + 1));
104
    $res[$tok] = $val;
105
    $res[$tok] = $val;
105
  }
106
  }
106
  return($res);
107
  return($res);
107
}
108
}
108
 
109
 
109
 
110
 
110
// on PHP 8+ there is str_starts_with(), but not on PHP 7 so I use this
111
// on PHP 8+ there is str_starts_with(), but not on PHP 7 so I use this
111
function str_head_is($haystack, $needle) {
112
function str_head_is($haystack, $needle) {
112
  return strpos($haystack, $needle) === 0;
113
  return strpos($haystack, $needle) === 0;
113
}
114
}
114
 
115
 
115
 
116
 
116
// returns an array that contains CORE packages (populated from the core subdirectory in pkgdir)
117
// returns an array that contains CORE packages (populated from the core subdirectory in pkgdir)
117
function load_core_list($repodir) {
118
function load_core_list($repodir) {
118
  $res = array();
119
  $res = array();
119
 
120
 
120
  foreach (scandir($repodir . '/core/') as $f) {
121
  foreach (scandir($repodir . '/core/') as $f) {
121
    if (!preg_match('/\.svp$/', $f)) continue;
122
    if (!preg_match('/\.svp$/', $f)) continue;
122
    $res[] = explode('.', $f)[0];
123
    $res[] = explode('.', $f)[0];
123
  }
124
  }
124
  return($res);
125
  return($res);
125
}
126
}
126
 
127
 
127
 
128
 
128
// ***************** MAIN ROUTINE *********************************************
129
// ***************** MAIN ROUTINE *********************************************
129
 
130
 
130
//echo "SvarDOS repository index generator ver {$PVER}\n";
131
//echo "SvarDOS repository index generator ver {$PVER}\n";
131
 
132
 
132
if (($_SERVER['argc'] != 2) || ($_SERVER['argv'][1][0] == '-')) {
133
if (($_SERVER['argc'] != 2) || ($_SERVER['argv'][1][0] == '-')) {
133
  echo "usage: php buildidx.php repodir\n";
134
  echo "usage: php buildidx.php repodir\n";
134
  exit(1);
135
  exit(1);
135
}
136
}
136
 
137
 
137
$repodir = $_SERVER['argv'][1];
138
$repodir = $_SERVER['argv'][1];
138
 
139
 
139
$pkgfiles = scandir($repodir);
140
$pkgfiles = scandir($repodir);
140
$pkgcount = 0;
141
$pkgcount = 0;
141
 
142
 
142
 
143
 
143
// load the list of CORE and MSDOS_COMPAT packages
144
// load the list of CORE and MSDOS_COMPAT packages
144
 
145
 
145
$core_packages_list = load_core_list($repodir);
146
$core_packages_list = load_core_list($repodir);
146
$msdos_compat_list = explode(' ', 'append assign attrib chkdsk choice command 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 swsubst tree undelete unformat xcopy');
147
$msdos_compat_list = explode(' ', 'append assign attrib chkdsk choice command 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 swsubst tree undelete unformat xcopy');
147
 
148
 
148
// do a list of all svp packages with their available versions and descriptions
149
// do a list of all svp packages with their available versions and descriptions
149
 
150
 
150
$pkgdb = array();
151
$pkgdb = array();
151
foreach ($pkgfiles as $fname) {
152
foreach ($pkgfiles as $fname) {
152
  if (!preg_match('/\.svp$/i', $fname)) continue; // skip non-svp files
153
  if (!preg_match('/\.svp$/i', $fname)) continue; // skip non-svp files
153
 
154
 
154
  if (!preg_match('/^[a-zA-Z0-9+. _-]*\.svp$/', $fname)) {
155
  if (!preg_match('/^[a-zA-Z0-9+. _-]*\.svp$/', $fname)) {
155
    echo "ERROR: {$fname} has a very weird name\n";
156
    echo "ERROR: {$fname} has a very weird name\n";
156
    continue;
157
    continue;
157
  }
158
  }
158
 
159
 
159
  $path_parts = pathinfo($fname);
160
  $path_parts = pathinfo($fname);
160
  $pkgnam = explode('-', $path_parts['filename'])[0];
161
  $pkgnam = explode('-', $path_parts['filename'])[0];
161
  $pkgfullpath = realpath($repodir . '/' . $fname);
162
  $pkgfullpath = realpath($repodir . '/' . $fname);
162
 
163
 
163
  $lsm = read_file_from_zip($pkgfullpath, "appinfo/{$pkgnam}.lsm");
164
  $lsm = read_file_from_zip($pkgfullpath, "appinfo/{$pkgnam}.lsm");
164
  if ($lsm == false) {
165
  if ($lsm == false) {
165
    echo "ERROR: {$fname} does not contain an LSM file at the expected location\n";
166
    echo "ERROR: {$fname} does not contain an LSM file at the expected location\n";
166
    continue;
167
    continue;
167
  }
168
  }
168
  $lsmarray = parse_lsm($lsm);
169
  $lsmarray = parse_lsm($lsm);
169
  if (empty($lsmarray['version'])) {
170
  if (empty($lsmarray['version'])) {
170
    echo "ERROR: lsm file in {$fname} does not contain a version\n";
171
    echo "ERROR: lsm file in {$fname} does not contain a version\n";
171
    continue;
172
    continue;
172
  }
173
  }
173
  if (strlen($lsmarray['version']) > 16) {
174
  if (strlen($lsmarray['version']) > 16) {
174
    echo "ERROR: version string in lsm file of {$fname} is too long (16 chars max)\n";
175
    echo "ERROR: version string in lsm file of {$fname} is too long (16 chars max)\n";
175
    continue;
176
    continue;
176
  }
177
  }
177
  if (empty($lsmarray['description'])) {
178
  if (empty($lsmarray['description'])) {
178
    echo "ERROR: lsm file in {$fname} does not contain a description\n";
179
    echo "ERROR: lsm file in {$fname} does not contain a description\n";
179
    continue;
180
    continue;
180
  }
181
  }
181
 
182
 
182
  // validate the files present in the archive
183
  // validate the files present in the archive
183
  $listoffiles = read_list_of_files_in_zip($pkgfullpath);
184
  $listoffiles = read_list_of_files_in_zip($pkgfullpath);
184
  $pkgdir = $pkgnam;
185
  $pkgdir = $pkgnam;
185
 
186
 
186
  // special rule for "parent and children" packages
187
  // special rule for "parent and children" packages
187
  if (str_head_is($pkgnam, 'djgpp_')) $pkgdir = 'djgpp'; // djgpp_* packages put their files in djgpp
188
  if (str_head_is($pkgnam, 'djgpp_')) $pkgdir = 'djgpp'; // djgpp_* packages put their files in djgpp
188
  if ($pkgnam == 'fbc_help') $pkgdir = 'fbc'; // FreeBASIC help goes to the FreeBASIC dir
189
  if ($pkgnam == 'fbc_help') $pkgdir = 'fbc'; // FreeBASIC help goes to the FreeBASIC dir
189
  if ($pkgnam == 'clamdb') $pkgdir = 'clamav'; // data patterns for clamav
190
  if ($pkgnam == 'clamdb') $pkgdir = 'clamav'; // data patterns for clamav
190
 
191
 
191
  // array used to detect duplicated entries after lower-case conversion
192
  // array used to detect duplicated entries after lower-case conversion
192
  $duparr = array();
193
  $duparr = array();
193
 
194
 
-
 
195
  // will hold the list of categories that this package belongs to
-
 
196
  $catlist = array();
-
 
197
 
194
  foreach ($listoffiles as $f) {
198
  foreach ($listoffiles as $f) {
195
    $f = strtolower($f);
199
    $f = strtolower($f);
196
    $path_array = explode('/', $f);
200
    $path_array = explode('/', $f);
197
    // emit a warning when non-8+3 filenames are spotted and find duplicates
201
    // emit a warning when non-8+3 filenames are spotted and find duplicates
198
    foreach ($path_array as $item) {
202
    foreach ($path_array as $item) {
199
      if (empty($item)) continue; // skip empty items at end of paths (eg. appinfo/)
203
      if (empty($item)) continue; // skip empty items at end of paths (eg. appinfo/)
200
      if (!preg_match("/[a-z0-9!#$%&'()@^_`{}~-]{1,8}(\.[a-z0-9!#$%&'()@^_`{}~-]{1,3}){0,1}/", $item)) {
204
      if (!preg_match("/[a-z0-9!#$%&'()@^_`{}~-]{1,8}(\.[a-z0-9!#$%&'()@^_`{}~-]{1,3}){0,1}/", $item)) {
201
        echo "WARNING: {$fname} contains a non-8+3 path (or weird char): {$item} (in $f)\n";
205
        echo "WARNING: {$fname} contains a non-8+3 path (or weird char): {$item} (in $f)\n";
202
      }
206
      }
203
    }
207
    }
204
    // look for dups
208
    // look for dups
205
    if (array_search($f, $duparr) !== false) {
209
    if (array_search($f, $duparr) !== false) {
206
      echo "WARNING: {$fname} contains a duplicated entry: '{$f}'\n";
210
      echo "WARNING: {$fname} contains a duplicated entry: '{$f}'\n";
207
    } else {
211
    } else {
208
      $duparr[] = $f;
212
      $duparr[] = $f;
209
    }
213
    }
210
    // LSM file is ok
214
    // LSM file is ok
211
    if ($f === "appinfo/{$pkgnam}.lsm") continue;
215
    if ($f === "appinfo/{$pkgnam}.lsm") continue;
212
    if ($f === "appinfo/") continue;
216
    if ($f === "appinfo/") continue;
213
    // CORE and MSDOS_COMPAT packages are premium citizens and can do a little more
217
    // CORE and MSDOS_COMPAT packages are premium citizens and can do a little more
-
 
218
    $core_or_msdoscompat = 0;
214
    if ((array_search($pkgnam, $core_packages_list) !== false)
219
    if (array_search($pkgnam, $core_packages_list) !== false) {
-
 
220
      $catlist[] = 'core';
-
 
221
      $core_or_msdoscompat = 1;
-
 
222
    }
215
       || (array_search($pkgnam, $msdos_compat_list) !== false)) {
223
    if (array_search($pkgnam, $msdos_compat_list) !== false) {
-
 
224
      $catlist[] = 'msdos_compat';
-
 
225
      $core_or_msdoscompat = 1;
-
 
226
    }
-
 
227
    if ($core_or_msdoscompat == 1) {
216
      if (str_head_is($f, 'bin/')) continue;
228
      if (str_head_is($f, 'bin/')) continue;
217
      if (str_head_is($f, 'cpi/')) continue;
229
      if (str_head_is($f, 'cpi/')) continue;
218
      if (str_head_is($f, "doc/{$pkgdir}/")) continue;
230
      if (str_head_is($f, "doc/{$pkgdir}/")) continue;
219
      if ($f === 'doc/') continue;
231
      if ($f === 'doc/') continue;
220
      if (str_head_is($f, "nls/{$pkgdir}.")) continue;
232
      if (str_head_is($f, "nls/{$pkgdir}.")) continue;
221
      if ($f === 'nls/') continue;
233
      if ($f === 'nls/') continue;
222
    }
234
    }
223
    // the help package is allowed to put files in... help
235
    // the help package is allowed to put files in... help
224
    if (($pkgnam == 'help') && (str_head_is($f, 'help/'))) continue;
236
    if (($pkgnam == 'help') && (str_head_is($f, 'help/'))) continue;
-
 
237
    // must be category-prefixed file, add it to the list of categories for this package
-
 
238
    $catlist[] = explode('/', $f)[0];
225
    // well-known "category" dirs are okay
239
    // well-known "category" dirs are okay
226
    if (str_head_is($f, "progs/{$pkgdir}/")) continue;
240
    if (str_head_is($f, "progs/{$pkgdir}/")) continue;
227
    if ($f === 'progs/') continue;
241
    if ($f === 'progs/') continue;
228
    if (str_head_is($f, "devel/{$pkgdir}/")) continue;
242
    if (str_head_is($f, "devel/{$pkgdir}/")) continue;
229
    if ($f === 'devel/') continue;
243
    if ($f === 'devel/') continue;
230
    if (str_head_is($f, "games/{$pkgdir}/")) continue;
244
    if (str_head_is($f, "games/{$pkgdir}/")) continue;
231
    if ($f === 'games/') continue;
245
    if ($f === 'games/') continue;
232
    if (str_head_is($f, "drivers/{$pkgdir}/")) continue;
246
    if (str_head_is($f, "drivers/{$pkgdir}/")) continue;
233
    if ($f === 'drivers/') continue;
247
    if ($f === 'drivers/') continue;
234
    echo "WARNING: {$fname} contains a file in an illegal location: {$f}\n";
248
    echo "WARNING: {$fname} contains a file in an illegal location: {$f}\n";
235
  }
249
  }
236
 
250
 
237
  $meta['fname'] = $fname;
251
  $meta['fname'] = $fname;
238
  $meta['desc'] = $lsmarray['description'];
252
  $meta['desc'] = $lsmarray['description'];
-
 
253
  $meta['cats'] = array_unique($catlist);
239
 
254
 
240
  $pkgdb[$pkgnam][$lsmarray['version']] = $meta;
255
  $pkgdb[$pkgnam][$lsmarray['version']] = $meta;
241
}
256
}
242
 
257
 
243
 
258
 
244
$db = array();
259
$db = array();
-
 
260
$cats = array();
-
 
261
 
-
 
262
// ******** compute the version-sorted list of packages with a single *********
-
 
263
// ******** description and category list for each package ********************
245
 
264
 
246
// iterate over each svp package
265
// iterate over each svp package
247
foreach ($pkgdb as $pkg => $versions) {
266
foreach ($pkgdb as $pkg => $versions) {
248
 
267
 
249
  // sort filenames by version, highest first
268
  // sort filenames by version, highest first
250
  uksort($versions, "version_compare");
269
  uksort($versions, "version_compare");
251
  $versions = array_reverse($versions, true);
270
  $versions = array_reverse($versions, true);
252
 
271
 
253
  foreach ($versions as $ver => $meta) {
272
  foreach ($versions as $ver => $meta) {
254
    $fname = $meta['fname'];
273
    $fname = $meta['fname'];
255
    $desc = $meta['desc'];
274
    $desc = $meta['desc'];
256
 
275
 
257
    $bsum = file2bsum(realpath($repodir . '/' . $fname));
276
    $bsum = file2bsum(realpath($repodir . '/' . $fname));
258
 
277
 
259
    $meta2['ver'] = strval($ver);
278
    $meta2['ver'] = strval($ver);
260
    $meta2['bsum'] = $bsum;
279
    $meta2['bsum'] = $bsum;
261
 
280
 
262
    if (empty($db[$pkg]['desc'])) $db[$pkg]['desc'] = $desc;
281
    if (empty($db[$pkg]['desc'])) $db[$pkg]['desc'] = $desc;
-
 
282
    if (empty($db[$pkg]['cats'])) {
-
 
283
      $db[$pkg]['cats'] = $meta['cats'];
-
 
284
      $cats = array_unique(array_merge($cats, $meta['cats']));
-
 
285
    }
263
    $db[$pkg]['versions'][$fname] = $meta2;
286
    $db[$pkg]['versions'][$fname] = $meta2;
264
  }
287
  }
265
 
288
 
266
  $pkgcount++;
289
  $pkgcount++;
267
 
290
 
268
}
291
}
269
 
292
 
270
if ($pkgcount < 100) echo "WARNING: an unexpectedly low number of packages has been found in the repo ({$pkgcount})\n";
293
if ($pkgcount < 100) echo "WARNING: an unexpectedly low number of packages has been found in the repo ({$pkgcount})\n";
271
 
294
 
272
$json_blob = json_encode($db);
295
$json_blob = json_encode($db);
273
if ($json_blob === false) {
296
if ($json_blob === false) {
274
  echo "ERROR: JSON convertion failed! -> ";
297
  echo "ERROR: JSON convertion failed! -> ";
275
  switch (json_last_error()) {
298
  switch (json_last_error()) {
276
    case JSON_ERROR_DEPTH:
299
    case JSON_ERROR_DEPTH:
277
      echo 'maximum stack depth exceeded';
300
      echo 'maximum stack depth exceeded';
278
      break;
301
      break;
279
    case JSON_ERROR_STATE_MISMATCH:
302
    case JSON_ERROR_STATE_MISMATCH:
280
      echo 'underflow of the modes mismatch';
303
      echo 'underflow of the modes mismatch';
281
      break;
304
      break;
282
    case JSON_ERROR_CTRL_CHAR:
305
    case JSON_ERROR_CTRL_CHAR:
283
      echo 'unexpected control character found';
306
      echo 'unexpected control character found';
284
      break;
307
      break;
285
    case JSON_ERROR_UTF8:
308
    case JSON_ERROR_UTF8:
286
      echo 'malformed utf-8 characters';
309
      echo 'malformed utf-8 characters';
287
      break;
310
      break;
288
    default:
311
    default:
289
      echo "unknown error";
312
      echo "unknown error";
290
      break;
313
      break;
291
  }
314
  }
292
  echo "\n";
315
  echo "\n";
293
}
316
}
294
 
317
 
295
file_put_contents($repodir . '/_index.json', json_encode($db));
318
file_put_contents($repodir . '/_index.json', $json_blob);
-
 
319
 
-
 
320
$cats_json = json_encode($cats);
-
 
321
file_put_contents($repodir . '/_cats.json', $cats_json);
296
 
322
 
297
exit(0);
323
exit(0);
298
 
324
 
299
?>
325
?>
300
 
326