xaizek / rocketgit (License: AGPLv3+) (since 2018-12-09)
Light and fast Git hosting solution suitable to serve both as a hub or as a personal code storage with its tickets, pull requests, API and much more.
Commit 3c6df6f5a6053d322f93814b3a8ccc8555951d9f

Another round of fixes.
Author: Catalin(ux) M. BOIE
Author date (UTC): 2011-05-04 03:22
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2011-05-04 03:22
Parent(s): 0d841811babba24b643404169b645379377a92f9
Signing key:
Tree: e86017a74df43e6e7628ee3b4f5d94adfbcd7978
File Lines added Lines deleted
TODO 4 7
inc/keys.inc.php 15 5
inc/repo.inc.php 3 9
inc/repo/repo_page.php 3 2
inc/state.inc.php 20 16
inc/user.inc.php 3 0
inc/util.inc.php 0 8
samples/config.php 3 0
scripts/cron.php 19 19
scripts/ssh.php 6 3
tests/Makefile 4 1
tests/keys.php 38 10
tests/state.php 57 0
File TODO changed (mode: 100644) (index 61e6efc..9cb8273)
1 1 == BEFORE FIRST RELEASE! == == BEFORE FIRST RELEASE! ==
2 2 [ ] Validate e-mails. [ ] Validate e-mails.
3 [ ] Validate repo names.
4 [ ] Validate user names.
5 [ ] XSS protection for every cell.
6 3 [ ] You cannot admin rights of a repository if is not yours. [ ] You cannot admin rights of a repository if is not yours.
7 [ ] In Admin section we must check if the user has access!
4 [ ] Check XSRF attacks and other types.
8 5 [ ] [ ]
9 6
10 7 == Low priority == == Low priority ==
 
40 37 [ ] Limit number of simultaneously connection per repo and per user. Maybe also the time! [ ] Limit number of simultaneously connection per repo and per user. Maybe also the time!
41 38 [ ] Add /var/run/rg to spec file, to be created at instalation. [ ] Add /var/run/rg to spec file, to be created at instalation.
42 39 [ ] We should add a dependency on php-process? [ ] We should add a dependency on php-process?
43 [ ] Make everywhere present a "Make a surgestion" area.
40 [ ] Make everywhere present a "Make a sugestion" area.
44 41 [ ] On rocketgit website, add "Feedback" area. [ ] On rocketgit website, add "Feedback" area.
45 42 [ ] Do not forget to pack /etc/httpd/conf.d/rg.conf. [ ] Do not forget to pack /etc/httpd/conf.d/rg.conf.
46 [ ] Allow multipl virtual hosts, with different configurations.
47 [ ]
43 [ ] Allow multiple virtual hosts, with different configurations.
44 [ ]
File inc/keys.inc.php changed (mode: 100644) (index ddb0b09..b75c3af)
... ... function rg_keys_fingerprint($key)
62 62 function rg_keys_remove($db, $rg_ui, $key_id) function rg_keys_remove($db, $rg_ui, $key_id)
63 63 { {
64 64 // mark dirty // mark dirty
65 rg_state_set($db, "authorized_keys", 1);
65 if (rg_state_set($db, "authorized_keys", 1) === FALSE) {
66 rg_keys_set_error("Cannot make state dirty!");
67 return FALSE;
68 }
66 69
67 70 // TODO: move this to caller? // TODO: move this to caller?
68 71 $e_key_id = sprintf("%u", $key_id); $e_key_id = sprintf("%u", $key_id);
 
... ... function rg_keys_add($db, $rg_ui, $key)
93 96 return FALSE; return FALSE;
94 97
95 98 // set dirty // set dirty
96 if (rg_state_set($db, "authorized_keys", 1) === FALSE)
99 if (rg_state_set($db, "authorized_keys", 1) === FALSE) {
100 rg_keys_set_error("Cannot make state dirty!");
97 101 return FALSE; return FALSE;
102 }
98 103
99 104 $sql = "INSERT INTO keys (itime, uid, key)" $sql = "INSERT INTO keys (itime, uid, key)"
100 105 . " VALUES ($itime, " . $rg_ui['uid'] . ", '$e_key')"; . " VALUES ($itime, " . $rg_ui['uid'] . ", '$e_key')";
 
... ... function rg_keys_regen($db)
115 120 { {
116 121 global $rg_keys_file; global $rg_keys_file;
117 122 global $rg_scripts; global $rg_scripts;
123 global $rg_ssh_paras;
118 124
119 125 $dirty = rg_state_get($db, "authorized_keys"); $dirty = rg_state_get($db, "authorized_keys");
120 if ($dirty == 0)
126 if ($dirty == 0) {
127 rg_log("Skip generation because is not dirty!");
121 128 return TRUE; return TRUE;
129 }
122 130
123 131 $tmp = $rg_keys_file . ".tmp"; $tmp = $rg_keys_file . ".tmp";
124 132 $f = @fopen($tmp, "w"); $f = @fopen($tmp, "w");
 
... ... function rg_keys_regen($db)
139 147 return FALSE; return FALSE;
140 148 } }
141 149 while (($row = rg_sql_fetch_array($res))) { while (($row = rg_sql_fetch_array($res))) {
142 $buf = "command=\"/usr/bin/php " . $rg_scripts . "/ssh.php " . $row['uid'] . "\""
143 . ",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty"
150 rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']);
151 $buf = "command=\"/usr/bin/php " . $rg_scripts . "/ssh.php"
152 . " " . $row['uid'] . "\""
153 . "," . $rg_ssh_paras
144 154 . " " . $row['key'] . "\n"; . " " . $row['key'] . "\n";
145 155 if (@fwrite($f, $buf) === FALSE) { if (@fwrite($f, $buf) === FALSE) {
146 156 rg_keys_set_error("Cannot write. Disk space problems? ($php_errormsg)"); rg_keys_set_error("Cannot write. Disk space problems? ($php_errormsg)");
File inc/repo.inc.php changed (mode: 100644) (index c641892..92959fc)
... ... function rg_repo_allow($db, $ri, $rg_ui, $needed_rights)
113 113 rg_log("repo_allow: rg_uid=" . $rg_ui['uid'] rg_log("repo_allow: rg_uid=" . $rg_ui['uid']
114 114 . ", needed_rights=$needed_rights..."); . ", needed_rights=$needed_rights...");
115 115
116 if ($rg_ui['is_admin'] == 1)
116 if ($rg_ui['is_admin'] == 1) {
117 rg_log("\tUser is admin, allow!");
117 118 return TRUE; return TRUE;
119 }
118 120
119 121 if (empty($needed_rights)) { if (empty($needed_rights)) {
120 122 rg_log("\tNo perms passed!"); rg_log("\tNo perms passed!");
 
... ... function rg_repo_create($db, $master, $rg_ui, $name, $max_commit_size, $desc,
167 169 return FALSE; return FALSE;
168 170 } }
169 171
170 // XSS protection - TODO: be more specific
171 $name = rg_xss($name);
172 $desc = rg_xss($desc);
173
174 172 $e_name = rg_sql_escape($db, $name); $e_name = rg_sql_escape($db, $name);
175 173 $e_desc = rg_sql_escape($db, $desc); $e_desc = rg_sql_escape($db, $desc);
176 174
 
... ... function rg_repo_update($db, &$new)
247 245 return FALSE; return FALSE;
248 246 } }
249 247
250 // XSS protection - TODO: move this to the caller!
251 $new['name'] = rg_xss($new['name']);
252 $new['desc'] = rg_xss($new['desc']);
253
254 248 $e_name = rg_sql_escape($db, $new['name']); $e_name = rg_sql_escape($db, $new['name']);
255 249 $e_desc = rg_sql_escape($db, $new['desc']); $e_desc = rg_sql_escape($db, $new['desc']);
256 250
File inc/repo/repo_page.php changed (mode: 100644) (index 9fb21c7..10df380)
... ... $name = rg_var_str("name");
7 7 $max_commit_size = rg_var_uint("max_commit_size"); $max_commit_size = rg_var_uint("max_commit_size");
8 8 $desc = rg_var_str("desc"); $desc = rg_var_str("desc");
9 9 $rights = @rg_repo_rights_a2s($_REQUEST['rights']); $rights = @rg_repo_rights_a2s($_REQUEST['rights']);
10 $user = rg_user_fix(rg_var_str("user"));
10 $user = rg_var_str("user");
11 11 $master_repo_id = 0; $master_repo_id = 0;
12 12
13 13 // menu // menu
 
... ... if ($show_repo_info == 1) {
156 156 $_dr = rg_repo_rights_text($ri['default_rights']); $_dr = rg_repo_rights_text($ri['default_rights']);
157 157 $_rt .= "Default rights: " . implode(", ", $_dr) . "<br />\n"; $_rt .= "Default rights: " . implode(", ", $_dr) . "<br />\n";
158 158 $_rt .= "Maxim commit size: " . rg_1024($ri['max_commit_size']) . "<br />\n"; $_rt .= "Maxim commit size: " . rg_1024($ri['max_commit_size']) . "<br />\n";
159 $_rt .= "Git URL: git://" . $_SERVER['HTTP_HOST'] . "/" . $ri['name'] . ".git<br />\n";
159 $_url = "git://" . $_SERVER['HTTP_HOST'] . "/" . $ri['name'] . ".git";
160 $_rt .= "Git URL: <a href=\"$_url\">$_url</a><br />\n";
160 161 $_rt .= "<br />\n"; $_rt .= "<br />\n";
161 162 } }
162 163
File inc/state.inc.php changed (mode: 100644) (index 6ab5899..ec90371)
2 2 require_once($INC . "/db.inc.php"); require_once($INC . "/db.inc.php");
3 3
4 4 /* /*
5 * Set state
5 * Get state
6 6 */ */
7 function rg_state_set($db, $var, $value)
7 function rg_state_get($db, $var)
8 8 { {
9 9 $e_var = rg_sql_escape($db, $var); $e_var = rg_sql_escape($db, $var);
10 $e_value = rg_sql_escape($db, $value);
11 10
12 $sql = "UPDATE state SET value = '$e_value'"
13 . " WHERE var = '$e_var'";
11 $sql = "SELECT value FROM state WHERE var = '$e_var'";
14 12 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
15 13 if ($res === FALSE) if ($res === FALSE)
16 14 return FALSE; return FALSE;
15
16 $row = rg_sql_fetch_array($res);
17 if (!isset($row['value']))
18 return FALSE;
19
17 20 rg_sql_free_result($res); rg_sql_free_result($res);
18 21
19 return TRUE;
22 return $row['value'];
20 23 } }
21 24
22 25 /* /*
23 * Get state
26 * Set state
24 27 */ */
25 function rg_state_get($db, $var)
28 function rg_state_set($db, $var, $value)
26 29 { {
27 30 $e_var = rg_sql_escape($db, $var); $e_var = rg_sql_escape($db, $var);
31 $e_value = rg_sql_escape($db, $value);
28 32
29 $sql = "SELECT value FROM state WHERE var = '$e_var'";
33 if (rg_state_get($db, $var) === FALSE) {
34 $sql = "INSERT INTO state (var, value)"
35 . " VALUES('$e_var', '$e_value')";
36 } else {
37 $sql = "UPDATE state SET value = '$e_value'"
38 . " WHERE var = '$e_var'";
39 }
30 40 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
31 41 if ($res === FALSE) if ($res === FALSE)
32 42 return FALSE; return FALSE;
33
34 $row = rg_sql_fetch_array($res);
35 if (!isset($row['value']))
36 return FALSE;
37
38 43 rg_sql_free_result($res); rg_sql_free_result($res);
39 44
40 return $row['value'];
45 return TRUE;
41 46 } }
42
43 47 ?> ?>
File inc/user.inc.php changed (mode: 100644) (index eea1ece..c6d7b94)
... ... function rg_user_info($db, $uid, $user, $email)
103 103 $ret['uid'] = 0; $ret['uid'] = 0;
104 104 $ret['is_admin'] = 0; $ret['is_admin'] = 0;
105 105
106 if (rg_user_ok($user) === FALSE)
107 return FALSE;
108
106 109 if ($uid > 0) { if ($uid > 0) {
107 110 $add = " AND uid = " . sprintf("%u", $uid); $add = " AND uid = " . sprintf("%u", $uid);
108 111 } else if (!empty($user)) { } else if (!empty($user)) {
File inc/util.inc.php changed (mode: 100644) (index bcb394b..1aeece6)
... ... function rg_id($len)
42 42 return substr($id, 0, $len); return substr($id, 0, $len);
43 43 } }
44 44
45 /*
46 * XSS protection
47 */
48 function rg_xss($v)
49 {
50 return htmlspecialchars($v, ENT_QUOTES);
51 }
52
53 45 $_lock = FALSE; $_lock = FALSE;
54 46 function rg_lock_or_exit($file) function rg_lock_or_exit($file)
55 47 { {
File samples/config.php changed (mode: 100644) (index ca0dee9..722b2d2)
... ... $rg_user_allow = '/^[^A-Za-z0-9_.-]$/';
30 30 // Allowed user name length // Allowed user name length
31 31 $rg_user_max_len = 16; $rg_user_max_len = 16;
32 32
33 // SSH parameters for authorized_keys
34 $rg_ssh_paras = "no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty";
35
33 36 ?> ?>
File scripts/cron.php changed (mode: 100644) (index f98d4cc..87dc90d)
... ... rg_log_set_file("/tmp/rg_cron.log");
19 19 $lock = "/var/run/rg/cron.lock"; $lock = "/var/run/rg/cron.lock";
20 20 rg_lock_or_exit($lock); rg_lock_or_exit($lock);
21 21
22 $sql_debug = $rg_db_debug;
22 $rg_sql_debug = $rg_db_debug;
23 23
24 24 rg_log("Start: euid=" . posix_geteuid() . "..."); rg_log("Start: euid=" . posix_geteuid() . "...");
25 25
26 $db = sql_open($rg_db);
26 $db = rg_sql_open($rg_db);
27 27 if ($db === FALSE) { if ($db === FALSE) {
28 rg_log("Cannot connect to database!");
28 rg_log("Cannot connect to database (" . rg_sql_error() . ")!");
29 29 // TODO: inform admin - already by e-mail? // TODO: inform admin - already by e-mail?
30 30 exit(1); exit(1);
31 31 } }
 
... ... if (date("H") == 0) {
34 34 rg_log("Compute repository sizes if dirty..."); rg_log("Compute repository sizes if dirty...");
35 35 // delete 'dirty' files // delete 'dirty' files
36 36 $sql = "SELECT * FROM repos"; $sql = "SELECT * FROM repos";
37 $res = sql_query($db, $sql);
37 $res = rg_sql_query($db, $sql);
38 38 if ($res === FALSE) { if ($res === FALSE) {
39 39 rg_log("Cannot run query (" . rg_sql_error() . ")!"); rg_log("Cannot run query (" . rg_sql_error() . ")!");
40 40 } else { } else {
41 while (($row = sql_fetch_array($res))) {
41 while (($row = rg_sql_fetch_array($res))) {
42 42 rg_log("Processing repository [" . $row['name'] . "]..."); rg_log("Processing repository [" . $row['name'] . "]...");
43 $repo_path = repo_id2base($row['repo_id']) . $row['name'] . ".git";
44 $disk_mb = repo_disk_mb($repo_path);
43 $repo_path = rg_repo_id2base($row['repo_id']) . $row['name'] . ".git";
44 $disk_mb = rg_repo_disk_mb($repo_path);
45 45 $sql = "UPDATE repos SET disk_mb = $disk_mb" $sql = "UPDATE repos SET disk_mb = $disk_mb"
46 46 . " WHERE repo_id = " . $row['repo_id']; . " WHERE repo_id = " . $row['repo_id'];
47 $res2 = sql_query($db, $sql);
47 $res2 = rg_sql_query($db, $sql);
48 48 if ($res2 === FALSE) { if ($res2 === FALSE) {
49 49 rg_log("Cannot run query!"); rg_log("Cannot run query!");
50 50 } else { } else {
51 51 @unlink($repo_path . "/rg/dirty"); @unlink($repo_path . "/rg/dirty");
52 sql_free_result($res2);
52 rg_sql_free_result($res2);
53 53 } }
54 54 } }
55 sql_free_result($res);
55 rg_sql_free_result($res);
56 56 } }
57 57 } }
58 58
 
... ... if (date("H") == 0) {
65 65 if (date("H") == 0) { if (date("H") == 0) {
66 66 rg_log("Clean old forget_pass entries..."); rg_log("Clean old forget_pass entries...");
67 67 $sql = "DELETE FROM forgot_pass WHERE expire < $now"; $sql = "DELETE FROM forgot_pass WHERE expire < $now";
68 $res = sql_query($db, $sql);
69 sql_free_result($res);
68 $res = rg_sql_query($db, $sql);
69 rg_sql_free_result($res);
70 70 } }
71 71
72 72 if (date("H") == 1) { if (date("H") == 1) {
73 73 rg_log("Clean old sess entries..."); rg_log("Clean old sess entries...");
74 74 $sql = "DELETE FROM sess WHERE expire < $now"; $sql = "DELETE FROM sess WHERE expire < $now";
75 $res = sql_query($db, $sql);
76 sql_free_result($res);
75 $res = rg_sql_query($db, $sql);
76 rg_sql_free_result($res);
77 77 } }
78 78
79 79 rg_log("Regenerate keys..."); rg_log("Regenerate keys...");
80 keys_regen($db);
80 rg_keys_regen($db);
81 81
82 82 // Arhive deleted repositories // Arhive deleted repositories
83 83 if (date("H") == 23) { if (date("H") == 23) {
 
... ... if (date("H") == 23) {
88 88 if (date("H") == 0) { if (date("H") == 0) {
89 89 rg_log("Run VACUUM on database..."); rg_log("Run VACUUM on database...");
90 90 $sql = "VACUUM"; $sql = "VACUUM";
91 $res = sql_query($db, $sql);
92 sql_free_result($res);
91 $res = rg_sql_query($db, $sql);
92 rg_sql_free_result($res);
93 93
94 94 rg_log("Run ANALYZE on database..."); rg_log("Run ANALYZE on database...");
95 95 $sql = "ANALYZE"; $sql = "ANALYZE";
96 $res = sql_query($db, $sql);
97 sql_free_result($res);
96 $res = rg_sql_query($db, $sql);
97 rg_sql_free_result($res);
98 98 } }
99 99
100 100 rg_log("Done!"); rg_log("Done!");
File scripts/ssh.php changed (mode: 100644) (index 06ee476..74a4810)
... ... require_once($INC . "/log.inc.php");
13 13 require_once($INC . "/db.inc.php"); require_once($INC . "/db.inc.php");
14 14 require_once($INC . "/repo.inc.php"); require_once($INC . "/repo.inc.php");
15 15
16 rg_log_set_file("/tmp/rg_ssh.log");
17
16 18 $rg_sql_debug = $rg_db_debug; $rg_sql_debug = $rg_db_debug;
17 19
18 20 function fatal($str) function fatal($str)
 
... ... if (isset($_SERVER['SSH_CONNECTION'])) {
85 87 // extract command and compute permissions // extract command and compute permissions
86 88 if (strncmp($cmd_repo, "git-upload-pack", 15) == 0) { if (strncmp($cmd_repo, "git-upload-pack", 15) == 0) {
87 89 $cmd = "git-upload-pack"; $cmd = "git-upload-pack";
88 $perms = "R";
90 $perms = "F";
89 91 } else if (strncmp($cmd_repo, "git-receive-pack", 16) == 0) { } else if (strncmp($cmd_repo, "git-receive-pack", 16) == 0) {
90 92 $cmd = "git-receive-pack"; $cmd = "git-receive-pack";
91 $perms = "W";
93 $perms = "P";
92 94 } else { } else {
93 95 fatal("Unknown command!"); fatal("Unknown command!");
94 96 } }
 
... ... if ($ri['exists'] != 1)
122 124 if ($ri['deleted'] == 1) if ($ri['deleted'] == 1)
123 125 fatal("Repo was deleted!"); fatal("Repo was deleted!");
124 126
125 if (!rg_repo_allow($db, $ri, $uid, $perms))
127 $rg_ui = array("uid" => $uid, "is_admin" => 0);
128 if (!rg_repo_allow($db, $ri, $rg_ui, $perms))
126 129 fatal("You do not have this type of access to this repository!"); fatal("You do not have this type of access to this repository!");
127 130
128 131 // TODO: limit per connection // TODO: limit per connection
File tests/Makefile changed (mode: 100644) (index bd9be3b..a30ccb6)
1 tests := util db keys repo
1 tests := util db keys repo state
2 2 .PHONY: $(tests) .PHONY: $(tests)
3 3
4 4 all: $(tests) all: $(tests)
 
... ... keys:
14 14
15 15 repo: repo:
16 16 php repo.php php repo.php
17
18 state:
19 php state.php
File tests/keys.php changed (mode: 100644) (index ec7d3db..204c664)
... ... $INC = "../inc";
5 5 require_once($INC . "/keys.inc.php"); require_once($INC . "/keys.inc.php");
6 6 require_once($INC . "/db/struct.inc.php"); require_once($INC . "/db/struct.inc.php");
7 7
8 rg_log_set_file("keys.log");
9
8 10 @unlink("keys.sqlite"); @unlink("keys.sqlite");
9 11
10 12 $db = rg_sql_open("sqlite:keys.sqlite"); $db = rg_sql_open("sqlite:keys.sqlite");
 
... ... if ($r === FALSE) {
20 22 exit(1); exit(1);
21 23 } }
22 24
23 // insert a key
25 // insert a key 1
24 26 $rg_ui = array("uid" => 1, "is_admin" => 0); $rg_ui = array("uid" => 1, "is_admin" => 0);
25 $key = "aaa 'bbb' ccc";
26 $key_id = rg_keys_add($db, $rg_ui, $key);
27 if ($key_id === FALSE) {
27 $key = "aaa 'bbb' first_key";
28 $key_id1 = rg_keys_add($db, $rg_ui, $key);
29 if ($key_id1 === FALSE) {
28 30 echo "Cannot add key (" . rg_keys_error() . ")!\n"; echo "Cannot add key (" . rg_keys_error() . ")!\n";
29 31 exit(1); exit(1);
30 32 } }
31 33
32 // delete a key
33 $rg_ui = array("uid" => 1, "is_admin" => 0);
34 $r = rg_keys_remove($db, $rg_ui, $key_id);
35 if ($r === FALSE) {
36 echo "Cannot remove key (" . keys_error() . ")!";
34 // insert a key 2
35 $rg_ui = array("uid" => 2, "is_admin" => 0);
36 $key = "aaa 'bbb' second_key";
37 $key_id2 = rg_keys_add($db, $rg_ui, $key);
38 if ($key_id2 === FALSE) {
39 echo "Cannot add key (" . rg_keys_error() . ")!\n";
37 40 exit(1); exit(1);
38 41 } }
39 42
43
40 44 // test key file generation // test key file generation
45 $rg_scripts = "/a";
41 46 $rg_keys_file = "afile.txt"; $rg_keys_file = "afile.txt";
47 $rg_ssh_paras = "ssh1,ssh2,ssh3";
42 48 $r = rg_keys_regen($db); $r = rg_keys_regen($db);
43 49 if ($r === FALSE) { if ($r === FALSE) {
44 echo "Cannot regenerate keys (" . keys_error() . ")!";
50 echo "Cannot regenerate keys (" . rg_keys_error() . ")!";
51 exit(1);
52 }
53 $c = file_get_contents("afile.txt");
54 if ($c === FALSE) {
55 echo "Cannot regenerate file: " . rg_keys_error() . "!\n";
56 exit(1);
57 }
58 $e = "command=\"/usr/bin/php " . $rg_scripts . "/ssh.php 1\"," . $rg_ssh_paras . " aaa 'bbb' first_key\n"
59 . "command=\"/usr/bin/php " . $rg_scripts . "/ssh.php 2\"," . $rg_ssh_paras . " aaa 'bbb' second_key\n";
60 if (strcmp($c, $e) != 0) {
61 echo "Generated file does not seems OK\n";
45 62 exit(1); exit(1);
46 63 } }
64
47 65 @unlink("afile.txt"); @unlink("afile.txt");
48 66
67
68 // delete a key
69 $rg_ui = array("uid" => 1, "is_admin" => 0);
70 $r = rg_keys_remove($db, $rg_ui, $key_id1);
71 if ($r === FALSE) {
72 echo "Cannot remove key (" . rg_keys_error() . ")!";
73 exit(1);
74 }
75
76
49 77 rg_sql_close($db); rg_sql_close($db);
50 78
51 79 @unlink("keys.sqlite"); @unlink("keys.sqlite");
File tests/state.php added (mode: 100644) (index 0000000..e84f877)
1 <?php
2 error_reporting(E_ALL | E_STRICT);
3
4 $INC = "../inc";
5 require_once($INC . "/log.inc.php");
6 require_once($INC . "/db.inc.php");
7 require_once($INC . "/state.inc.php");
8 require_once($INC . "/db/struct.inc.php");
9
10 rg_log_set_file("state.log");
11
12 @unlink("state.sqlite");
13
14 $db = rg_sql_open("sqlite:state.sqlite");
15 if ($db === FALSE) {
16 echo "Cannot create a database (" . rg_sql_error() . ")!";
17 exit(1);
18 }
19
20 // state table
21 $r = rg_db_struct_run($db, FALSE);
22 if ($r === FALSE) {
23 echo "Cannot create tables!";
24 exit(1);
25 }
26
27 // check return for an invalid state
28 $r = rg_state_get($db, "asdsdsdf");
29 if ($r !== FALSE) {
30 echo "Cannot get FALSE for an unknown key!\n";
31 exit(1);
32 }
33
34 $r = rg_state_set($db, "a", "bau");
35 if ($r !== TRUE) {
36 echo "Cannot get a TRUE for setting a key1 ($r)!\n";
37 exit(1);
38 }
39
40 $r = rg_state_set($db, "a", "cucu");
41 if ($r !== TRUE) {
42 echo "Cannot get a TRUE for setting a key2 ($r)!\n";
43 exit(1);
44 }
45
46 $r = rg_state_get($db, "a");
47 if (strcmp($r, "cucu") != 0) {
48 echo "Cannot get correct state ($r != cucu)!\n";
49 exit(1);
50 }
51
52 rg_sql_close($db);
53
54 @unlink("state.sqlite");
55
56 echo "OK\n";
57 ?>
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master