+ if (!arg || strcmp(arg, ".") == 0)
+ return score_loop(prepare_ls_row, NULL, opts);
+ if (!strncmp(arg, "m/", 2)) {
+ struct mood_instance *m;
+ ret = mood_load(arg + 2, &m, &msg);
+ if (ret < 0)
+ afs_error(aca, "%s", msg);
+ free(msg);
+ if (ret < 0)
+ return ret;
+ ret = mood_loop(m, prepare_ls_row, opts);
+ mood_unload(m);
+ return ret;
+ }
+ if (!strncmp(arg, "p/", 2)) {
+ struct playlist_instance *pi;
+ ret = playlist_load(arg + 2, &pi, &msg);
+ if (ret < 0)
+ afs_error(aca, "%s", msg);
+ free(msg);
+ if (ret < 0)
+ return ret;
+ ret = playlist_loop(pi, prepare_ls_row, opts);
+ playlist_unload(pi);
+ return ret;
+ }
+ afs_error(aca, "bad mood/playlist specifier: %s\n", arg);
+ return -ERRNO_TO_PARA_ERROR(EINVAL);
+}
+
+static int com_ls_callback(struct afs_callback_arg *aca)
+{
+ const struct lls_command *cmd = SERVER_CMD_CMD_PTR(LS);
+ struct ls_options *opts = aca->query.data;
+ int ret;
+ time_t current_time;
+ const struct lls_opt_result *r_r, *r_a;
+ uint32_t limit, k, n;
+
+ ret = lls_deserialize_parse_result(
+ (char *)aca->query.data + sizeof(*opts), cmd, &opts->lpr);
+ assert(ret >= 0);
+ r_r = SERVER_CMD_OPT_RESULT(LS, REVERSE, opts->lpr);
+ r_a = SERVER_CMD_OPT_RESULT(LS, ADMISSIBLE, opts->lpr);
+ aca->pbout.flags = (opts->mode == LS_MODE_PARSER)? PBF_SIZE_PREFIX : 0;
+ if (admissible_only(opts)) {
+ const char *arg = lls_string_val(0, r_a);
+ ret = mop_loop(arg, aca, opts);