int volume_left, volume_right; /* last known volume */
+/** @brief Accept all well-formed login attempts
+ *
+ * Used in debugging.
+ */
+int wideopen;
+
struct listener {
const char *name;
int pf;
sink_writes(ev_writer_sink(c->w), "530 authentication failure\n");
return 1;
}
- }
+ } else
+ strcpy(host, "local");
/* find the user */
for(n = 0; n < config->allow.n
&& strcmp(config->allow.s[n].s[0], vec[0]); ++n)
;
/* if it's a real user check whether the response is right */
- if(n < config->allow.n) {
- res = authhash(c->nonce, sizeof c->nonce, config->allow.s[n].s[1]);
- if(res && !strcmp(res, vec[1])) {
- c->who = vec[0];
- /* currently we only bother logging remote connections */
- if(c->l->pf != PF_UNIX)
- info("S%x %s connected from %s", c->tag, vec[0], host);
- sink_writes(ev_writer_sink(c->w), "230 OK\n");
- return 1;
- }
+ if(n >= config->allow.n) {
+ info("S%x unknown user '%s' from %s", c->tag, vec[0], host);
+ sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
+ return 1;
+ }
+ res = authhash(c->nonce, sizeof c->nonce, config->allow.s[n].s[1],
+ config->authorization_algorithm);
+ if(wideopen || (res && !strcmp(res, vec[1]))) {
+ c->who = vec[0];
+ /* currently we only bother logging remote connections */
+ if(c->l->pf != PF_UNIX)
+ info("S%x %s connected from %s", c->tag, vec[0], host);
+ sink_writes(ev_writer_sink(c->w), "230 OK\n");
+ return 1;
}
/* oops, response was wrong */
- if(c->l->pf != PF_UNIX)
- info("S%x authentication failure for %s from %s", c->tag, vec[0], host);
- else
- info("S%x authentication failure for %s", c->tag, vec[0]);
+ info("S%x authentication failure for %s from %s", c->tag, vec[0], host);
sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
return 1;
}
sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state %s\n",
(uintmax_t)now,
paused ? "pause" : "resume");
+ if(playing)
+ sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state playing\n",
+ (uintmax_t)now);
+ /* Initial volume */
+ sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" volume %d %d\n",
+ (uintmax_t)now, volume_left, volume_right);
c->lo = xmalloc(sizeof *c->lo);
c->lo->fn = logclient;
c->lo->user = c;
return 1;
}
+static int c_nop(struct conn *c,
+ char attribute((unused)) **vec,
+ int attribute((unused)) nvec) {
+ sink_printf(ev_writer_sink(c->w), "250 Quack\n");
+ return 1;
+}
+
+static int c_new(struct conn *c,
+ char **vec,
+ int nvec) {
+ char **tracks = trackdb_new(0, nvec > 0 ? atoi(vec[0]) : INT_MAX);
+
+ sink_printf(ev_writer_sink(c->w), "253 New track list follows\n");
+ while(*tracks) {
+ sink_printf(ev_writer_sink(c->w), "%s%s\n",
+ **tracks == '.' ? "." : "", *tracks);
+ ++tracks;
+ }
+ sink_writes(ev_writer_sink(c->w), ".\n");
+ return 1; /* completed */
+
+}
+
#define C_AUTH 0001 /* must be authenticated */
#define C_TRUSTED 0002 /* must be trusted user */
{ "log", 0, 0, c_log, C_AUTH },
{ "move", 2, 2, c_move, C_AUTH },
{ "moveafter", 1, INT_MAX, c_moveafter, C_AUTH },
+ { "new", 0, 1, c_new, C_AUTH },
+ { "nop", 0, 0, c_nop, C_AUTH },
{ "part", 3, 3, c_part, C_AUTH },
{ "pause", 0, 0, c_pause, C_AUTH },
{ "play", 1, 1, c_play, C_AUTH },
c->reader = reader_callback;
c->l = l;
gcry_randomize(c->nonce, sizeof c->nonce, GCRY_STRONG_RANDOM);
- sink_printf(ev_writer_sink(c->w), "231 %s\n", hex(c->nonce, sizeof c->nonce));
+ if(!strcmp(config->authorization_algorithm, "sha1")
+ || !strcmp(config->authorization_algorithm, "SHA1")) {
+ sink_printf(ev_writer_sink(c->w), "231 %s\n",
+ hex(c->nonce, sizeof c->nonce));
+ } else {
+ sink_printf(ev_writer_sink(c->w), "231 %s %s\n",
+ config->authorization_algorithm,
+ hex(c->nonce, sizeof c->nonce));
+ }
return 0;
}
fill-column:79
End:
*/
-/* arch-tag:eb9b30c87008880f3f53535101356ab5 */