Subversion Repositories SvarDOS

Rev

Rev 1508 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1508 Rev 1791
1
<?php
1
<?php
2
 
2
 
3
/*
3
/*
4
  pkgnet interface
4
  pkgnet interface
5
  Copyright (C) 2021-2022 Mateusz Viste
5
  Copyright (C) 2021-2024 Mateusz Viste
6
 
6
 
7
 === API ===
7
 === API ===
8
  ?a=pull&p=PACKAGE[-VER]     downloads the svp archive of PACKAGE (possibly of VER version)
8
  ?a=pull&p=PACKAGE[-VER]     downloads the svp archive of PACKAGE (possibly of VER version)
9
  ?a=pullsrc&p=PACKAGE[-VER]  downloads the source zip of PACKAGE (possibly of VER version)
9
  ?a=pullsrc&p=PACKAGE[-VER]  downloads the source zip of PACKAGE (possibly of VER version)
10
  ?a=search&p=PHRASE[::cat]   list packages that match PHRASE (possibly filtered by cat category)
10
  ?a=search&p=PHRASE[::cat]   list packages that match PHRASE (possibly filtered by cat category)
11
  ?a=checkup                  list of packages+versions in $_POST
11
  ?a=checkup                  list of packages+versions in $_POST
12
*/
12
*/
13
 
13
 
14
 
14
 
15
// messages in different languages (and necessary mappings for codepage conversions)
15
// messages in different languages (and necessary mappings for codepage conversions)
16
include 'lang.php';
16
include 'lang.php';
17
 
17
 
18
 
18
 
19
// convert a utf-8 string into codepage related to lang
19
// convert a utf-8 string into codepage related to lang
20
function cp_conv($s, $lang) {
20
function cp_conv($s, $lang) {
21
  global $CP_UTF, $CP_ENC;
21
  global $CP_UTF, $CP_ENC;
22
  $res = str_replace($CP_UTF[$lang], $CP_ENC[$lang], $s);
22
  $res = str_replace($CP_UTF[$lang], $CP_ENC[$lang], $s);
23
  return($res);
23
  return($res);
24
}
24
}
25
 
25
 
26
 
26
 
27
function get_msg($id, $lang) {
27
function get_msg($id, $lang) {
28
  global $MSG;
28
  global $MSG;
29
  if (!empty($MSG[$id][$lang])) {
29
  if (!empty($MSG[$id][$lang])) {
30
    return cp_conv($MSG[$id][$lang], $lang);
30
    return cp_conv($MSG[$id][$lang], $lang);
31
  } else {
31
  } else {
32
    return $MSG[$id]['en'];
32
    return $MSG[$id]['en'];
33
  }
33
  }
34
}
34
}
35
 
35
 
36
 
36
 
37
function nicesize($bytes) {
37
function nicesize($bytes) {
38
  if ($bytes < 1024) return(round($bytes / 1024, 1) . "K");
38
  if ($bytes < 1024) return(round($bytes / 1024, 1) . "K");
39
  if ($bytes < 1024 * 1024) return(round($bytes / 1024) . "K");
39
  if ($bytes < 1024 * 1024) return(round($bytes / 1024) . "K");
40
  return(round($bytes / 1024 / 1024, 1) . "M");
40
  return(round($bytes / 1024 / 1024, 1) . "M");
41
}
41
}
42
 
42
 
43
 
43
 
44
function csv_to_array($filename = '', $delimiter = "\t") {
44
function csv_to_array($filename = '', $delimiter = "\t") {
45
  //if (! file_exists($filename) || ! is_readable($filename)) return FALSE;
45
  //if (! file_exists($filename) || ! is_readable($filename)) return FALSE;
46
  $handle = fopen($filename, 'r');
46
  $handle = fopen($filename, 'r');
47
  if ($handle === false) return(false);
47
  if ($handle === false) return(false);
48
 
48
 
49
  $rez = array();
49
  $rez = array();
50
 
50
 
51
  while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
51
  while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
52
    $rez[] = $row;
52
    $rez[] = $row;
53
  }
53
  }
54
  fclose($handle);
54
  fclose($handle);
55
 
55
 
56
  return $rez;
56
  return $rez;
57
}
57
}
58
 
58
 
59
 
59
 
60
function tabulprint($ar_data, $ar_width, $margin = true) {
60
function tabulprint($ar_data, $ar_width, $margin = true) {
61
  $count = 0;
61
  $count = 0;
62
  foreach ($ar_data as $item) {
62
  foreach ($ar_data as $item) {
63
    if ($count == 0) {
63
    if ($count == 0) {
64
      echo '|';
64
      echo '|';
65
      if ($margin) echo ' ';
65
      if ($margin) echo ' ';
66
    }
66
    }
67
    echo substr(str_pad($item, $ar_width[$count]), 0, $ar_width[$count]);
67
    echo substr(str_pad($item, $ar_width[$count]), 0, $ar_width[$count]);
68
    if ($margin) {
68
    if ($margin) {
69
      echo ' | ';
69
      echo ' | ';
70
    } else {
70
    } else {
71
      echo '|';
71
      echo '|';
72
    }
72
    }
73
    $count++;
73
    $count++;
74
  }
74
  }
75
  echo "\r\n";
75
  echo "\r\n";
76
}
76
}
77
 
77
 
78
 
78
 
79
// *** MAIN START ************************************************************
79
// *** MAIN START ************************************************************
80
 
80
 
81
 
81
 
82
if (empty($_GET['a'])) {
82
if (empty($_GET['a'])) {
83
  http_response_code(404);
83
  http_response_code(404);
84
  echo "ERROR: no action specified\r\n";
84
  echo "ERROR: no action specified\r\n";
85
  exit(0);
85
  exit(0);
86
}
86
}
87
 
87
 
88
$lang = 'en';
88
$lang = 'en';
89
if ((!empty($_GET['lang'])) && (preg_match('/[a-zA-Z][a-zA-Z]/', $_GET['lang']))) $lang = strtolower($_GET['lang']);
89
if ((!empty($_GET['lang'])) && (preg_match('/[a-zA-Z][a-zA-Z]/', $_GET['lang']))) $lang = strtolower($_GET['lang']);
90
 
90
 
91
// load pkg desc translations
91
// load pkg desc translations
92
$descdb = json_decode(file_get_contents("pkg_desc_{$lang}.json"), true);
92
$descdb = json_decode(file_get_contents("pkg_desc_{$lang}.json"), true);
93
 
93
 
94
// switch to the packages directory
94
// switch to the packages directory
95
if (chdir('../../packages') === false) {
95
if (chdir('../../packages') === false) {
96
  http_response_code(404);
96
  http_response_code(404);
97
  echo "ERROR: server-side error, cannot access packages\r\n";
97
  echo "ERROR: server-side error, cannot access packages\r\n";
98
  exit(0);
98
  exit(0);
99
}
99
}
100
 
100
 
101
$a = strtolower($_GET['a']);
101
$a = strtolower($_GET['a']);
102
 
102
 
103
$p = '';
103
$p = '';
104
$v = '';
104
$v = '';
105
if ($a != 'checkup') {
105
if ($a != 'checkup') {
106
  if (empty($_GET['p'])) {
106
  if (empty($_GET['p'])) {
107
    http_response_code(404);
107
    http_response_code(404);
108
    echo "ERROR: no package specified\r\n";
108
    echo "ERROR: no package specified\r\n";
109
    exit(0);
109
    exit(0);
110
  }
110
  }
111
  // pull and pullsrc actions accept pkg-ver strings
111
  // pull and pullsrc actions accept pkg-ver strings
112
  if ($a == 'pull' || $a == 'pullsrc') {
112
  if ($a == 'pull' || $a == 'pullsrc') {
113
    $pv = explode('-', strtolower($_GET['p']));
113
    $pv = explode('-', strtolower($_GET['p']));
114
    $p = $pv[0];
114
    $p = $pv[0];
115
    if (!empty($pv[1])) $v = $pv[1];
115
    if (!empty($pv[1])) {
-
 
116
      // space is not a valid character in a version string, if there is any then it must have been a plus sign (as in "1.0+1") but it got changed to a space by the www server because pkgnet does not perform url percent-encoding. So I'm changing it back to a plus here.
-
 
117
      $v = strtr($pv[1], ' ', '+');
-
 
118
    }
116
  } else {
119
  } else {
117
    $p = strtolower($_GET['p']);
120
    $p = strtolower($_GET['p']);
118
  }
121
  }
119
}
122
}
120
 
123
 
121
 
124
 
122
// is action valid?
125
// is action valid?
123
 
126
 
124
if (($a !== 'search') && ($a !== 'checkup') && ($a !== 'pull') && ($a !== 'pullsrc')) {
127
if (($a !== 'search') && ($a !== 'checkup') && ($a !== 'pull') && ($a !== 'pullsrc')) {
125
  http_response_code(404);
128
  http_response_code(404);
126
  echo "ERROR: invalid action\r\n";
129
  echo "ERROR: invalid action\r\n";
127
  exit(0);
130
  exit(0);
128
}
131
}
129
 
132
 
130
 
133
 
131
// load pkg db
134
// load pkg db
132
 
135
 
133
$db = json_decode(file_get_contents('_index.json'), true);
136
$db = json_decode(file_get_contents('_index.json'), true);
134
if (empty($db)) {
137
if (empty($db)) {
135
  http_response_code(404);
138
  http_response_code(404);
136
  echo "ERROR: server error, database not found\n";
139
  echo "ERROR: server error, database not found\n";
137
  exit(0);
140
  exit(0);
138
}
141
}
139
 
142
 
140
 
143
 
141
// pull or pullsrc action (svp / zip)
144
// pull or pullsrc action (svp / zip)
142
 
145
 
143
if (($a === 'pull') || ($a === 'pullsrc')) {
146
if (($a === 'pull') || ($a === 'pullsrc')) {
144
  $fname = false;
147
  $fname = false;
145
  if (empty($v)) { // take first version (that's the preferred one)
148
  if (empty($v)) { // take first version (that's the preferred one)
146
    $fname = array_key_first($db[$p]['versions']);
149
    $fname = array_key_first($db[$p]['versions']);
147
  } else {
150
  } else {
148
    // look for a specific version string
151
    // look for a specific version string
149
    foreach ($db[$p]['versions'] as $f => $e) {
152
    foreach ($db[$p]['versions'] as $f => $e) {
150
      if (strcasecmp($e['ver'], $v) == 0) {
153
      if (strcasecmp($e['ver'], $v) == 0) {
151
        $fname = $f;
154
        $fname = $f;
152
        break;
155
        break;
153
      }
156
      }
154
    }
157
    }
155
  }
158
  }
156
  if (file_exists($fname)) {
159
  if (file_exists($fname)) {
157
    if ($a === 'pullsrc') { // is it about source?
160
    if ($a === 'pullsrc') { // is it about source?
158
      $fname = preg_replace('/svp$/', 'zip', $fname); // replace *.svp by *.zip
161
      $fname = preg_replace('/svp$/', 'zip', $fname); // replace *.svp by *.zip
159
      if (file_exists($fname)) {
162
      if (file_exists($fname)) {
160
        header('Content-Disposition: attachment; filename="' . $fname);
163
        header('Content-Disposition: attachment; filename="' . $fname);
161
        header('Content-Type: application/octet-stream');
164
        header('Content-Type: application/octet-stream');
162
        readfile($fname);
165
        readfile($fname);
163
      } else {
166
      } else {
164
        http_response_code(404);
167
        http_response_code(404);
165
        echo get_msg('PKG_NO_SRC', $lang) . "\r\n";
168
        echo get_msg('PKG_NO_SRC', $lang) . "\r\n";
166
      }
169
      }
167
    } else {
170
    } else {
168
      header('Content-Disposition: attachment; filename="' . $p . '.svp');
171
      header('Content-Disposition: attachment; filename="' . $p . '.svp');
169
      header('Content-Type: application/octet-stream');
172
      header('Content-Type: application/octet-stream');
170
      readfile($fname);
173
      readfile($fname);
171
    }
174
    }
172
  } else {
175
  } else {
173
    http_response_code(404);
176
    http_response_code(404);
174
    echo get_msg('PKG_NOT_FOUND', $lang) . "\r\n";
177
    echo get_msg('PKG_NOT_FOUND', $lang) . "\r\n";
175
  }
178
  }
176
  exit(0);
179
  exit(0);
177
}
180
}
178
 
181
 
179
 
182
 
180
// search action
183
// search action
181
 
184
 
182
if ($a === 'search') {
185
if ($a === 'search') {
183
  $matches = 0;
186
  $matches = 0;
184
  header('Content-Type: text/plain');
187
  header('Content-Type: text/plain');
185
 
188
 
186
  // if catfilter present, trim it out of the search term
189
  // if catfilter present, trim it out of the search term
187
  $exp_cat = explode('::', $p);
190
  $exp_cat = explode('::', $p);
188
  $p = $exp_cat[0];
191
  $p = $exp_cat[0];
189
  $catfilter = '';
192
  $catfilter = '';
190
  if (!empty($exp_cat[1])) $catfilter = strtolower($exp_cat[1]);
193
  if (!empty($exp_cat[1])) $catfilter = strtolower($exp_cat[1]);
191
 
194
 
192
  foreach ($db as $pkg => $meta) {
195
  foreach ($db as $pkg => $meta) {
193
    // apply the category filter, if any
196
    // apply the category filter, if any
194
    if (! empty($catfilter)) {
197
    if (! empty($catfilter)) {
195
      if (array_search($catfilter, $meta['cats']) === false) continue;
198
      if (array_search($catfilter, $meta['cats']) === false) continue;
196
    }
199
    }
197
    // look for term
200
    // look for term
198
    if ((empty($p)) || (stristr($pkg, $p)) || (stristr($meta['desc'], $p))) {
201
    if ((empty($p)) || (stristr($pkg, $p)) || (stristr($meta['desc'], $p))) {
199
      // fetch first (preferred) version
202
      // fetch first (preferred) version
200
      $prefver_fname = array_key_first($meta['versions']);
203
      $prefver_fname = array_key_first($meta['versions']);
201
      $prefver = array_shift($meta['versions']);
204
      $prefver = array_shift($meta['versions']);
202
      echo str_pad(strtoupper($pkg), 12);
205
      echo str_pad(strtoupper($pkg), 12);
203
      echo str_pad(get_msg('VER', $lang) . " {$prefver['ver']} ", 16);
206
      echo str_pad(get_msg('VER', $lang) . " {$prefver['ver']} ", 16);
204
      echo str_pad(get_msg('SIZE', $lang) . ' ' . nicesize(filesize($prefver_fname)), 16) . "BSUM: " . sprintf("%04X", $prefver['bsum']) . "\r\n";
207
      echo str_pad(get_msg('SIZE', $lang) . ' ' . nicesize(filesize($prefver_fname)), 16) . "BSUM: " . sprintf("%04X", $prefver['bsum']) . "\r\n";
205
 
208
 
206
      // do I have a localized version of the description?
209
      // do I have a localized version of the description?
207
      if (!empty($descdb[$pkg])) {
210
      if (!empty($descdb[$pkg])) {
208
        echo wordwrap(cp_conv($descdb[$pkg], $lang), 79, "\r\n", true);
211
        echo wordwrap(cp_conv($descdb[$pkg], $lang), 79, "\r\n", true);
209
      } else {
212
      } else {
210
        echo wordwrap($meta['desc'], 79, "\r\n", true);
213
        echo wordwrap($meta['desc'], 79, "\r\n", true);
211
      }
214
      }
212
 
215
 
213
      echo "\r\n";
216
      echo "\r\n";
214
      // do I have any alt versions?
217
      // do I have any alt versions?
215
      $altlist = array();
218
      $altlist = array();
216
      foreach ($meta['versions'] as $altver) {
219
      foreach ($meta['versions'] as $altver) {
217
        $altlist[] = $pkg . '-' . $altver['ver'];
220
        $altlist[] = $pkg . '-' . $altver['ver'];
218
      }
221
      }
219
      if (!empty($altlist)) {
222
      if (!empty($altlist)) {
220
        echo wordwrap('[' . get_msg('ALT_VERS', $lang) . ' ' . implode(', ', $altlist), 79, "\r\n", true) . "]\r\n";
223
        echo wordwrap('[' . get_msg('ALT_VERS', $lang) . ' ' . implode(', ', $altlist), 79, "\r\n", true) . "]\r\n";
221
      }
224
      }
222
      echo "\r\n";
225
      echo "\r\n";
223
      $matches++;
226
      $matches++;
224
    }
227
    }
225
  }
228
  }
226
  if ($matches == 0) echo get_msg('NO_MATCHING_PKG', $lang) . "\r\n";
229
  if ($matches == 0) echo get_msg('NO_MATCHING_PKG', $lang) . "\r\n";
227
}
230
}
228
 
231
 
229
 
232
 
230
// checkup action
233
// checkup action
231
 
234
 
232
if ($a === 'checkup') {
235
if ($a === 'checkup') {
233
  $found = 0;
236
  $found = 0;
234
  $remote_pkgs = csv_to_array("php://input", "\t"); // [0] = pkgname ; [1] = version
237
  $remote_pkgs = csv_to_array("php://input", "\t"); // [0] = pkgname ; [1] = version
235
 
238
 
236
  foreach ($remote_pkgs as $rpkg) {
239
  foreach ($remote_pkgs as $rpkg) {
237
    $rpkg[0] = strtolower($rpkg[0]);
240
    $rpkg[0] = strtolower($rpkg[0]);
238
    if (empty($db[$rpkg[0]])) continue;
241
    if (empty($db[$rpkg[0]])) continue;
239
 
242
 
240
    $dbpkg = $db[$rpkg[0]];
243
    $dbpkg = $db[$rpkg[0]];
241
    // compare user's version with preferred version in repo
244
    // compare user's version with preferred version in repo
242
    $prefver = array_shift($dbpkg['versions']);
245
    $prefver = array_shift($dbpkg['versions']);
243
    if (strcasecmp($prefver['ver'], $rpkg[1]) == 0) continue;
246
    if (strcasecmp($prefver['ver'], $rpkg[1]) == 0) continue;
244
    // found version mismatch
247
    // found version mismatch
245
    if ($found == 0) {
248
    if ($found == 0) {
246
      echo str_pad('', 78, '-') . "\r\n";
249
      echo str_pad('', 78, '-') . "\r\n";
247
      tabulprint(array(get_msg('PACKAGE', $lang), get_msg('INSTALLED', $lang), get_msg('AVAILABLE', $lang)), array(8, 30, 30));
250
      tabulprint(array(get_msg('PACKAGE', $lang), get_msg('INSTALLED', $lang), get_msg('AVAILABLE', $lang)), array(8, 30, 30));
248
      tabulprint(array('----------', '--------------------------------', '--------------------------------'), array(10, 32, 32), false);
251
      tabulprint(array('----------', '--------------------------------', '--------------------------------'), array(10, 32, 32), false);
249
    }
252
    }
250
    $found++;
253
    $found++;
251
    tabulprint(array('' . $rpkg[0], $rpkg[1], $prefver['ver']), array(8, 30, 30));
254
    tabulprint(array('' . $rpkg[0], $rpkg[1], $prefver['ver']), array(8, 30, 30));
252
  }
255
  }
253
  if ($found == 0) {
256
  if ($found == 0) {
254
    echo get_msg('NO_UPDATES', $lang) . "\r\n";
257
    echo get_msg('NO_UPDATES', $lang) . "\r\n";
255
  } else {
258
  } else {
256
    echo str_pad('', 78, '-') . "\r\n";
259
    echo str_pad('', 78, '-') . "\r\n";
257
    echo get_msg('FOUND_DIFFER', $lang) . ' ' . $found . "\r\n";
260
    echo get_msg('FOUND_DIFFER', $lang) . ' ' . $found . "\r\n";
258
  }
261
  }
259
}
262
}
260
 
263
 
261
?>
264
?>
262
 
265