Add type information into scripts/protocol
[disorder] / scripts / protocol
CommitLineData
200adb00
RK
1#! /usr/bin/perl -w
2#
3# This file is part of DisOrder.
4# Copyright (C) 2010 Richard Kettlewell
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19use strict;
20
21# Variables and utilities -----------------------------------------------------
22
23our @h = ();
24our @c = ();
25
26sub Write {
27 my $path = shift;
28 my $lines = shift;
29
30 (open(F, ">$path")
31 and print F @$lines
32 and close F)
7788b7c7 33 or die "$0: $path: $!\n";
200adb00
RK
34}
35
36# Command classes -------------------------------------------------------------
37
50d905eb
RK
38sub c_in_decl {
39 my $arg = shift;
40
41 my $type = $arg->[0];
42 my $name = $arg->[1];
43 if($type eq 'string') {
44 return "const char *$name";
45 } elsif($type eq 'integer') {
46 return "long $name";
47 } else {
48 die "$0: unknown type '$type'\n";
49 }
50}
51
52sub c_out_decl {
53 my $arg = shift;
54
55 my $type = $arg->[0];
56 my $name = $arg->[1];
57 if($type eq 'string') {
58 return "char **${name}p";
59 } elsif($type eq 'integer') {
60 return "long *${name}p";
61 } else {
62 die "$0: unknown type '$type'\n";
63 }
64}
65
66sub c_param_docs {
67 my $args = shift;
68 return map(" * \@param $_->[1] $_->[2]\n", @$args);
69}
70
71# simple(CMD, SUMMARY, DETAIL, [[TYPE,NAME,DESCR], [TYPE,NAME,DESCR], ...],)
200adb00
RK
72#
73# Response is simply success/failure
96b1cf08 74sub simple {
200adb00
RK
75 my $cmd = shift;
76 my $summary = shift;
77 my $detail = shift;
78 my $args = shift;
79
80 my $cmdc = $cmd;
81 $cmdc =~ s/-/_/g;
82 # Synchronous C API
83 push(@h, "/** \@brief $summary\n",
7788b7c7
RK
84 " *\n",
85 " * $detail\n",
86 " *\n",
50d905eb 87 c_param_docs($args),
7788b7c7
RK
88 " * \@return 0 on success, non-0 on error\n",
89 " */\n",
50d905eb
RK
90 "int disorder_$cmdc(",
91 join(", ", "disorder_client *c",
92 map(c_in_decl($_), @$args)),
93 ");\n\n");
94 push(@c, "int disorder_$cmdc(",
95 join(", ", "disorder_client *c",
96 map(c_in_decl($_), @$args)),
97 ") {\n",
7788b7c7 98 " return disorder_simple(c, 0, \"$cmd\"",
50d905eb 99 map(", $_->[1]", @$args),
7788b7c7
RK
100 ", (char *)0);\n",
101 "}\n\n");
102
103 # Asynchronous C API
104 # TODO
105
106 # Python API
107 # TODO
108
109 # Java API
110 # TODO
111}
112
50d905eb 113# string(CMD, SUMMARY, DETAIL, [[TYPE,NAME,DESCR], [TYPE,NAME,DESCR], ...], [RETURN, DESCR])
7788b7c7 114#
3680ef53 115# Response is a string, or failure, or 555 for "none".
7788b7c7
RK
116sub string {
117 my $cmd = shift;
118 my $summary = shift;
119 my $detail = shift;
120 my $args = shift;
121 my $return = shift;
122
123 my $cmdc = $cmd;
124 $cmdc =~ s/-/_/g;
125 # Synchronous C API
126 push(@h, "/** \@brief $summary\n",
127 " *\n",
128 " * $detail\n",
129 " *\n",
50d905eb 130 c_param_docs($args),
7788b7c7
RK
131 " * \@param $return->[0]p $return->[1]\n",
132 " * \@return 0 on success, non-0 on error\n",
133 " */\n",
50d905eb
RK
134 "int disorder_$cmdc(",
135 join(", ", "disorder_client *c",
136 map(c_in_decl($_), @$args),
137 "char **$return->[0]p"),
138 ");\n\n");
139 push(@c, "int disorder_$cmdc(",
140 join(", ", "disorder_client *c",
141 map(c_in_decl($_), @$args),
142 "char **$return->[0]p"),
143 ") {\n",
7788b7c7 144 " return dequote(disorder_simple(c, $return->[0]p, \"$cmd\"",
50d905eb 145 map(", $_->[1]", @$args),
7788b7c7
RK
146 ", (char *)0), $return->[0]p);\n",
147 "}\n\n");
148
149 # Asynchronous C API
150 # TODO
151
152 # Python API
153 # TODO
154
155 # Java API
156 # TODO
157}
158
50d905eb 159# string_login(CMD, SUMMARY, DETAIL, [[TYPE,NAME,DESCR], [TYPE,NAME,DESCR], ...])
7788b7c7 160#
3680ef53
RK
161# Like string(), but the server returns a username, which we squirrel
162# away rather than returning to the caller.
7788b7c7
RK
163sub string_login {
164 my $cmd = shift;
165 my $summary = shift;
166 my $detail = shift;
167 my $args = shift;
168 my $return = shift;
169
170 my $cmdc = $cmd;
171 $cmdc =~ s/-/_/g;
172 # Synchronous C API
173 push(@h, "/** \@brief $summary\n",
174 " *\n",
175 " * $detail\n",
176 " *\n",
50d905eb 177 c_param_docs($args),
7788b7c7
RK
178 " * \@return 0 on success, non-0 on error\n",
179 " */\n",
50d905eb
RK
180 "int disorder_$cmdc(",
181 join(", ", "disorder_client *c",
182 map(c_in_decl($_), @$args)),
7788b7c7 183 ");\n");
50d905eb
RK
184 push(@c, "int disorder_$cmdc(",
185 join(", ", "disorder_client *c",
186 map(c_in_decl($_), @$args)),
7788b7c7
RK
187 ") {\n",
188 " char *u;\n",
189 " int rc;\n",
190 " if((rc = disorder_simple(c, &u, \"$cmd\"",
50d905eb 191 map(", $_->[1]", @$args),
7788b7c7
RK
192 " )))\n",
193 " return rc;\n",
194 " c->user = u;\n",
195 " return 0;\n",
196 "}\n\n");
200adb00
RK
197
198 # Asynchronous C API
199 # TODO
200
201 # Python API
202 # TODO
203
204 # Java API
205 # TODO
206}
207
50d905eb 208# boolean(CMD, SUMMARY, DETAIL, [[TYPE,NAME,DESCR], [TYPE,NAME,DESCR], ...], [RETURN, DESCR])
96b1cf08
RK
209#
210# Response is yes/no or failure
211sub boolean {
212 my $cmd = shift;
213 my $summary = shift;
214 my $detail = shift;
215 my $args = shift;
216 my $return = shift;
217
218 my $cmdc = $cmd;
219 $cmdc =~ s/-/_/g;
220 # Synchronous C API
221 push(@h, "/** \@brief $summary\n",
7788b7c7
RK
222 " *\n",
223 " * $detail\n",
224 " *\n",
50d905eb 225 c_param_docs($args),
7788b7c7
RK
226 " * \@param $return->[0]p $return->[1]\n",
227 " * \@return 0 on success, non-0 on error\n",
228 " */\n",
50d905eb
RK
229 "int disorder_$cmdc(",
230 join(", ", "disorder_client *c",
231 map(c_in_decl($_), @$args),
232 "int *$return->[0]p"),
233 ");\n\n");
234 push(@c, "int disorder_$cmdc(",
235 join(", ", "disorder_client *c",
236 map(c_in_decl($_), @$args),
237 "int *$return->[0]p"),
238 ") {\n",
7788b7c7
RK
239 " char *v;\n",
240 " int rc;\n",
241 " if((rc = disorder_simple(c, &v, \"$cmd\"",
50d905eb 242 map(", $_->[1]", @$args),
7788b7c7
RK
243 ", (char *)0)))\n",
244 " return rc;\n",
245 " return boolean(\"$cmd\", v, $return->[0]p);\n",
246 "}\n\n");
96b1cf08
RK
247
248 # Asynchronous C API
249 # TODO
250
251 # Python API
252 # TODO
253
254 # Java API
255 # TODO
256}
257
50d905eb 258# integer(CMD, SUMMARY, DETAIL, [[TYPE,NAME,DESCR], [TYPE,NAME,DESCR], ...], [RETURN, DESCR])
711a4497
RK
259#
260# Response is an integer, or failure
261sub integer {
262 my $cmd = shift;
263 my $summary = shift;
264 my $detail = shift;
265 my $args = shift;
266 my $return = shift;
267
268 my $cmdc = $cmd;
269 $cmdc =~ s/-/_/g;
270 # Synchronous C API
271 push(@h, "/** \@brief $summary\n",
272 " *\n",
273 " * $detail\n",
274 " *\n",
50d905eb 275 c_param_docs($args),
711a4497
RK
276 " * \@param $return->[0]p $return->[1]\n",
277 " * \@return 0 on success, non-0 on error\n",
278 " */\n",
50d905eb
RK
279 "int disorder_$cmdc(",
280 join(", ", "disorder_client *c",
281 map(c_in_decl($_), @$args),
282 "long *$return->[0]p"),
283 ");\n\n");
284 push(@c, "int disorder_$cmdc(",
285 join(", ", "disorder_client *c",
286 map(c_in_decl($_), @$args),
287 "long *$return->[0]p"),
288 ") {\n",
711a4497
RK
289 " char *v;\n",
290 " int rc;\n",
291 "\n",
292 " if((rc = disorder_simple(c, &v, \"$cmd\"",
50d905eb 293 map(", $_->[1]", @$args),
711a4497
RK
294 ", (char *)0)))\n",
295 " return rc;\n",
296 " *$return->[0]p = atol(v);\n",
297 " xfree(v);\n",
298 " return 0;\n",
299 "}\n\n");
300
301 # Asynchronous C API
302 # TODO
303
304 # Python API
305 # TODO
306
307 # Java API
308 # TODO
309}
310
50d905eb 311# list(CMD, SUMMARY, DETAIL, [[TYPE,NAME,DESCR], [TYPE,NAME,DESCR], ...], [RETURN, DESCR])
3680ef53
RK
312#
313# Response is a a list of strings in a dot-stuffed body
314sub list {
315 my $cmd = shift;
316 my $summary = shift;
317 my $detail = shift;
318 my $args = shift;
319 my $return = shift;
320
321 my $cmdc = $cmd;
322 $cmdc =~ s/-/_/g;
323 # Synchronous C API
324 push(@h, "/** \@brief $summary\n",
325 " *\n",
326 " * $detail\n",
327 " *\n",
50d905eb 328 c_param_docs($args),
3680ef53
RK
329 " * \@param $return->[0]p $return->[1]\n",
330 " * \@param n$return->[0]p Number of elements in $return->[0]p\n",
331 " * \@return 0 on success, non-0 on error\n",
332 " */\n",
50d905eb
RK
333 "int disorder_$cmdc(",
334 join(", ", "disorder_client *c",
335 map(c_in_decl($_), @$args),
336 "char ***$return->[0]p",
337 "int *n$return->[0]p"),
338 ");\n\n");
339 push(@c, "int disorder_$cmdc(",
340 join(", ", "disorder_client *c",
341 map(c_in_decl($_), @$args),
342 "char ***$return->[0]p",
343 "int *n$return->[0]p"),
344 ") {\n",
3680ef53 345 " return disorder_simple_list(c, $return->[0]p, n$return->[0]p, \"$cmd\"",
50d905eb 346 map(", $_->[1]", @$args),
3680ef53
RK
347 ", (char *)0);\n",
348 "}\n\n");
349
350 # Asynchronous C API
351 # TODO
352
353 # Python API
354 # TODO
355
356 # Java API
357 # TODO
358}
359
200adb00
RK
360# TODO other command classes
361
362# Front matter ----------------------------------------------------------------
363
364our @gpl = ("/*\n",
7788b7c7
RK
365 " * This file is part of DisOrder.\n",
366 " * Copyright (C) 2010 Richard Kettlewell\n",
367 " *\n",
368 " * This program is free software: you can redistribute it and/or modify\n",
369 " * it under the terms of the GNU General Public License as published by\n",
370 " * the Free Software Foundation, either version 3 of the License, or\n",
371 " * (at your option) any later version.\n",
372 " *\n",
373 " * This program is distributed in the hope that it will be useful,\n",
374 " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n",
375 " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n",
376 " * GNU General Public License for more details.\n",
377 " *\n",
378 " * You should have received a copy of the GNU General Public License\n",
379 " * along with this program. If not, see <http://www.gnu.org/licenses/>.\n",
380 " */\n");
200adb00
RK
381
382
383push(@h, @gpl,
384 "#ifndef CLIENT_STUBS_H\n",
385 "#define CLIENT_STUBS_H\n",
386 "\n");
387
388push(@c, @gpl,
389 "\n");
390
391# The protocol ----------------------------------------------------------------
392
96b1cf08
RK
393simple("adopt",
394 "Adopt a track",
395 "Makes the calling user owner of a randomly picked track.",
50d905eb 396 [["string", "id", "Track ID"]]);
200adb00 397
96b1cf08
RK
398simple("adduser",
399 "Create a user",
400 "Create a new user. Requires the 'admin' right. Email addresses etc must be filled in in separate commands.",
50d905eb
RK
401 [["string", "user", "New username"],
402 ["string", "password", "Initial password"],
403 ["string", "rights", "Initial rights (optional)"]]);
200adb00 404
3680ef53
RK
405list("allfiles",
406 "List files and directories in a directory",
407 "See 'files' and 'dirs' for more specific lists.",
50d905eb
RK
408 [["string", "dir", "Directory to list (optional)"],
409 ["string", "re", "Regexp that results must match (optional)"]],
3680ef53 410 ["files", "List of matching files and directories"]);
200adb00 411
7788b7c7
RK
412string_login("confirm",
413 "Confirm registration",
414 "The confirmation string must have been created with 'register'. The username is returned so the caller knows who they are.",
50d905eb 415 [["string", "confirmation", "Confirmation string"]]);
200adb00 416
7788b7c7
RK
417string_login("cookie",
418 "Log in with a cookie",
419 "The cookie must have been created with 'make-cookie'. The username is returned so the caller knows who they are.",
50d905eb 420 [["string", "cookie", "Cookie string"]]);
200adb00 421
96b1cf08
RK
422simple("deluser",
423 "Delete user",
424 "Requires the 'admin' right.",
50d905eb 425 [["string", "user", "User to delete"]]);
200adb00 426
3680ef53
RK
427list("dirs",
428 "List directories in a directory",
429 "",
50d905eb
RK
430 [["string", "dir", "Directory to list (optional)"],
431 ["string", "re", "Regexp that results must match (optional)"]],
3680ef53 432 ["files", "List of matching directories"]);
200adb00 433
96b1cf08
RK
434simple("disable",
435 "Disable play",
436 "Play will stop at the end of the current track, if one is playing. Requires the 'global prefs' right.",
437 []);
438
439simple("edituser",
440 "Set a user property",
441 "With the 'admin' right you can do anything. Otherwise you need the 'userinfo' right and can only set 'email' and 'password'.",
50d905eb
RK
442 [["string", "username", "User to modify"],
443 ["string", "property", "Property name"],
444 ["string", "value", "New property value"]]);
96b1cf08
RK
445
446simple("enable",
447 "Enable play",
448 "Requires the 'global prefs' right.",
449 []);
450
451boolean("enabled",
7788b7c7
RK
452 "Detect whether play is enabled",
453 "",
454 [],
455 ["enabled", "1 if play is enabled and 0 otherwise"]);
96b1cf08
RK
456
457boolean("exists",
7788b7c7
RK
458 "Test whether a track exists",
459 "",
50d905eb 460 [["string", "track", "Track name"]],
7788b7c7 461 ["exists", "1 if the track exists and 0 otherwise"]);
200adb00 462
3680ef53
RK
463list("files",
464 "List files in a directory",
465 "",
50d905eb
RK
466 [["string", "dir", "Directory to list (optional)"],
467 ["string", "re", "Regexp that results must match (optional)"]],
3680ef53 468 ["files", "List of matching files"]);
200adb00 469
7788b7c7
RK
470string("get",
471 "Get a track preference",
472 "If the track does not exist that is an error. If the track exists but the preference does not then a null value is returned.",
50d905eb
RK
473 [["string", "track", "Track name"],
474 ["string", "pref", "Preference name"]],
7788b7c7 475 ["value", "Preference value"]);
200adb00 476
7788b7c7
RK
477string("get-global",
478 "Get a global preference",
479 "If the preference does exist not then a null value is returned.",
50d905eb 480 [["string", "pref", "Global preference name"]],
7788b7c7 481 ["value", "Preference value"]);
200adb00 482
711a4497
RK
483integer("length",
484 "Get a track's length",
485 "If the track does not exist an error is returned.",
50d905eb 486 [["string", "track", "Track name"]],
711a4497 487 ["length", "Track length in seconds"]);
200adb00
RK
488
489# TODO log
490
7788b7c7
RK
491string("make-cookie",
492 "Create a login cookie for this user",
493 "The cookie may be redeemed via the 'cookie' command",
494 [],
495 ["cookie", "Newly created cookie"]);
200adb00
RK
496
497# TODO move
498
499# TODO moveafter
500
501# TODO new
502
96b1cf08
RK
503simple("nop",
504 "Do nothing",
505 "Used as a keepalive. No authentication required.",
506 []);
200adb00 507
7788b7c7
RK
508string("part",
509 "Get a track name part",
510 "If the name part cannot be constructed an empty string is returned.",
50d905eb
RK
511 [["string", "track", "Track name"],
512 ["string", "context", "Context (\"sort\" or \"display\")"],
513 ["string", "part", "Name part (\"artist\", \"album\" or \"title\")"]],
7788b7c7 514 ["part", "Value of name part"]);
200adb00 515
96b1cf08
RK
516simple("pause",
517 "Pause the currently playing track",
518 "Requires the 'pause' right.",
519 []);
200adb00 520
00861dcb
RK
521string("play",
522 "Play a track",
523 "Requires the 'play' right.",
50d905eb 524 [["string", "track", "Track to play"]],
00861dcb
RK
525 ["id", "Queue ID of new track"]);
526
200adb00
RK
527# TODO playafter
528
529# TODO playing
530
96b1cf08
RK
531simple("playlist-delete",
532 "Delete a playlist",
533 "Requires the 'play' right and permission to modify the playlist.",
50d905eb 534 [["string", "playlist", "Playlist to delete"]]);
200adb00 535
3680ef53
RK
536list("playlist-get",
537 "List the contents of a playlist",
538 "Requires the 'read' right and oermission to read the playlist.",
50d905eb 539 [["string", "playlist", "Playlist name"]],
3680ef53 540 ["tracks", "List of tracks in playlist"]);
200adb00 541
7788b7c7
RK
542string("playlist-get-share",
543 "Get a playlist's sharing status",
544 "Requires the 'read' right and permission to read the playlist.",
50d905eb 545 [["string", "playlist", "Playlist to read"]],
7788b7c7 546 ["share", "Sharing status (\"public\", \"private\" or \"shared\")"]);
200adb00 547
3680ef53
RK
548simple("playlist-lock",
549 "Lock a playlist",
550 "Requires the 'play' right and permission to modify the playlist. A given connection may lock at most one playlist.",
50d905eb 551 [["string", "playlist", "Playlist to delete"]]);
3680ef53 552
96b1cf08
RK
553simple("playlist-set-share",
554 "Set a playlist's sharing status",
7788b7c7 555 "Requires the 'play' right and permission to modify the playlist.",
50d905eb
RK
556 [["string", "playlist", "Playlist to modify"],
557 ["string", "share", "New sharing status (\"public\", \"private\" or \"shared\")"]]);
200adb00 558
96b1cf08
RK
559simple("playlist-unlock",
560 "Unlock the locked playlist playlist",
561 "The playlist to unlock is implicit in the connection.",
562 []);
200adb00 563
3680ef53
RK
564list("playlists",
565 "List playlists",
566 "Requires the 'read' right. Only playlists that you have permission to read are returned.",
567 [],
568 ["playlists", "Playlist names"]);
200adb00
RK
569
570# TODO prefs
571
572# TODO queue
573
96b1cf08
RK
574simple("random-disable",
575 "Disable random play",
576 "Requires the 'global prefs' right.",
577 []);
578
579simple("random-enable",
580 "Enable random play",
581 "Requires the 'global prefs' right.",
582 []);
200adb00 583
96b1cf08 584boolean("random-enabled",
7788b7c7
RK
585 "Detect whether random play is enabled",
586 "Random play counts as enabled even if play is disabled.",
587 [],
588 ["enabled", "1 if random play is enabled and 0 otherwise"]);
200adb00
RK
589
590# TODO recent
591
96b1cf08
RK
592simple("reconfigure",
593 "Re-read configuraiton file.",
594 "Requires the 'admin' right.",
595 []);
200adb00 596
7788b7c7
RK
597string("register",
598 "Register a new user",
599 "Requires the 'register' right which is usually only available to the 'guest' user. Redeem the confirmation string via 'confirm' to complete registration.",
50d905eb
RK
600 [["string", "username", "Requested new username"],
601 ["string", "password", "Requested initial password"],
602 ["string", "email", "New user's email address"]],
7788b7c7 603 ["confirmation", "Confirmation string"]);
200adb00 604
96b1cf08
RK
605simple("reminder",
606 "Send a password reminder.",
607 "If the user has no valid email address, or no password, or a reminder has been sent too recently, then no reminder will be sent.",
50d905eb 608 [["string", "username", "User to remind"]]);
200adb00 609
96b1cf08
RK
610simple("remove",
611 "Remove a track form the queue.",
612 "Requires one of the 'remove mine', 'remove random' or 'remove any' rights depending on how the track came to be added to the queue.",
50d905eb 613 [["string", "id", "Track ID"]]);
200adb00 614
96b1cf08
RK
615simple("rescan",
616 "Rescan all collections for new or obsolete tracks.",
617 "Requires the 'rescan' right.",
7788b7c7 618 []); # TODO wait/fresh flags
200adb00 619
7788b7c7
RK
620string("resolve",
621 "Resolve a track name",
622 "Converts aliases to non-alias track names",
50d905eb 623 [["string", "track", "Track name (might be an alias)"]],
7788b7c7 624 ["resolved", "Resolve track name (definitely not an alias)"]);
200adb00 625
96b1cf08
RK
626simple("resume",
627 "Resume the currently playing track",
628 "Requires the 'pause' right.",
629 []);
200adb00 630
96b1cf08
RK
631simple("revoke",
632 "Revoke a cookie.",
633 "It will not subsequently be possible to log in with the cookie.",
7788b7c7 634 []); # TODO fix docs!
200adb00
RK
635
636# TODO rtp-address
637
96b1cf08
RK
638simple("scratch",
639 "Terminate the playing track.",
640 "Requires one of the 'scratch mine', 'scratch random' or 'scratch any' rights depending on how the track came to be added to the queue.",
50d905eb 641 [["string", "id", "Track ID (optional)"]]);
200adb00
RK
642
643# TODO schedule-add
644
96b1cf08
RK
645simple("schedule-del",
646 "Delete a scheduled event.",
647 "Users can always delete their own scheduled events; with the admin right you can delete any event.",
50d905eb 648 [["string", "event", "ID of event to delete"]]);
200adb00
RK
649
650# TODO schedule-get
651
3680ef53
RK
652list("schedule-list",
653 "List scheduled events",
654 "This just lists IDs. Use 'schedule-get' to retrieve more detail",
655 [],
656 ["ids", "List of event IDs"]);
200adb00 657
3680ef53
RK
658list("search",
659 "Search for tracks",
660 "Terms are either keywords or tags formatted as 'tag:TAG-NAME'.",
50d905eb 661 [["string", "terms", "List of search terms"]],
3680ef53 662 ["tracks", "List of matching tracks"]);
200adb00 663
96b1cf08
RK
664simple("set",
665 "Set a track preference",
666 "Requires the 'prefs' right.",
50d905eb
RK
667 [["string", "track", "Track name"],
668 ["string", "pref", "Preference name"],
669 ["string", "value", "New value"]]);
200adb00 670
96b1cf08
RK
671simple("set-global",
672 "Set a global preference",
673 "Requires the 'global prefs' right.",
50d905eb
RK
674 [["string", "pref", "Preference name"],
675 ["string", "value", "New value"]]);
200adb00 676
eea34c08
RK
677simple("shutdown",
678 "Request server shutdown",
679 "Requires the 'admin' right.",
680 []);
7788b7c7 681
3680ef53
RK
682list("stats",
683 "Get server statistics",
684 "The details of what the server reports are not really defined. The returned strings are intended to be printed out one to a line..",
685 [],
686 ["stats", "List of server information strings."]);
200adb00 687
3680ef53
RK
688list("tags",
689 "Get a list of known tags",
690 "Only tags which apply to at least one track are returned.",
691 [],
692 ["tags", "List of tags"]);
200adb00 693
96b1cf08
RK
694simple("unset",
695 "Unset a track preference",
696 "Requires the 'prefs' right.",
50d905eb
RK
697 [["string", "track", "Track name"],
698 ["string", "pref", "Preference name"]]);
200adb00 699
96b1cf08
RK
700simple("unset-global",
701 "Set a global preference",
702 "Requires the 'global prefs' right.",
50d905eb 703 [["string", "pref", "Preference name"]]);
200adb00 704
50d905eb 705# 'user' only used for authentication
200adb00 706
7788b7c7
RK
707string("userinfo",
708 "Get a user property.",
709 "If the user does not exist an error is returned, if the user exists but the property does not then a null value is returned.",
50d905eb
RK
710 [["string", "username", "User to read"],
711 ["string", "property", "Property to read"]],
7788b7c7 712 ["value", "Value of property"]);
200adb00 713
3680ef53
RK
714list("users",
715 "Get a list of users",
716 "",
717 [],
718 ["users", "List of users"]);
200adb00 719
7788b7c7
RK
720string("version",
721 "Get the server version",
722 "",
723 [],
724 ["version", "Server version string"]);
200adb00
RK
725
726# TODO volume
727
728# End matter ------------------------------------------------------------------
729
730push(@h, "#endif\n");
731
732# Write it all out ------------------------------------------------------------
733
7788b7c7
RK
734Write("lib/client-stubs.h", \@h);
735Write("lib/client-stubs.c", \@c);