1 /*
2  * MOC - music on console
3  * Copyright (C) 2003 - 2005 Damian Pietras <daper@daper.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  */
11 
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15 
16 #include <string.h>
17 #include <stdlib.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <time.h>
22 #include <assert.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 
26 #include "common.h"
27 #include "log.h"
28 #include "protocol.h"
29 #include "playlist.h"
30 #include "files.h"
31 
32 /* Maximal socket name. */
33 #define UNIX_PATH_MAX	108
34 #define SOCKET_NAME	"socket2"
35 
36 /* Buffer used to send data in one bigger chunk instead of sending sigle
37  * integer, string etc. values. */
38 struct packet_buf
39 {
40 	char *buf;
41 	size_t allocated;
42 	size_t len;
43 };
44 
45 /* Create a socket name, return NULL if the name could not be created. */
socket_name()46 char *socket_name ()
47 {
48 	char *socket_name = create_file_name (SOCKET_NAME);
49 
50 	if (strlen(socket_name) > UNIX_PATH_MAX)
51 		fatal ("Can't create socket name!");
52 
53 	return socket_name;
54 }
55 
56 /* Get an integer value from the socket, return == 0 on error. */
get_int(int sock,int * i)57 int get_int (int sock, int *i)
58 {
59 	int res;
60 
61 	res = recv (sock, i, sizeof(int), 0);
62 	if (res == -1)
63 		logit ("recv() failed when getting int: %s", strerror(errno));
64 
65 	return res == sizeof(int) ? 1 : 0;
66 }
67 
68 /* Get an integer value from the socket without blocking. */
get_int_noblock(int sock,int * i)69 enum noblock_io_status get_int_noblock (int sock, int *i)
70 {
71 	int res;
72 	long flags;
73 
74 	if ((flags = fcntl(sock, F_GETFL)) == -1)
75 		fatal ("fcntl(sock, F_GETFL) failed: %s", strerror(errno));
76 	flags |= O_NONBLOCK;
77 	if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
78 		fatal ("Setting O_NONBLOCK for the socket failed: %s",
79 				strerror(errno));
80 	res = recv (sock, i, sizeof(int), 0);
81 	flags &= ~O_NONBLOCK;
82 	if (fcntl(sock, F_SETFL, flags) == -1)
83 		fatal ("Restoring flags for socket failed: %s", strerror(errno));
84 
85 	if (res == sizeof(int))
86 		return NB_IO_OK;
87 	if (res < 0 && errno == EAGAIN)
88 		return NB_IO_BLOCK;
89 
90 	logit ("recv() failed when getting int (res %d): %s", res,
91 			strerror(errno));
92 	return NB_IO_ERR;
93 }
94 
95 /* Send an integer value to the socket, return == 0 on error */
send_int(int sock,int i)96 int send_int (int sock, int i)
97 {
98 	int res;
99 
100 	res = send (sock, &i, sizeof(int), 0);
101 	if (res == -1)
102 		logit ("send() failed: %s", strerror(errno));
103 
104 	return res == sizeof(int) ? 1 : 0;
105 }
106 
107 #if 0
108 /* Get a long value from the socket, return == 0 on error. */
109 static int get_long (int sock, long *i)
110 {
111 	int res;
112 
113 	res = recv (sock, i, sizeof(long), 0);
114 	if (res == -1)
115 		logit ("recv() failed when getting int: %s", strerror(errno));
116 
117 	return res == sizeof(long) ? 1 : 0;
118 }
119 #endif
120 
121 #if 0
122 /* Send a long value to the socket, return == 0 on error */
123 static int send_long (int sock, long i)
124 {
125 	int res;
126 
127 	res = send (sock, &i, sizeof(long), 0);
128 	if (res == -1)
129 		logit ("send() failed: %s", strerror(errno));
130 
131 	return res == sizeof(long) ? 1 : 0;
132 }
133 #endif
134 
135 /* Get the string from socket, return NULL on error. The memory is malloced. */
get_str(int sock)136 char *get_str (int sock)
137 {
138 	int len;
139 	int res, nread = 0;
140 	char *str;
141 
142 	if (!get_int(sock, &len))
143 		return NULL;
144 
145 	if (!RANGE(0, len, MAX_SEND_STRING)) {
146 		logit ("Bad string length.");
147 		return NULL;
148 	}
149 
150 	str = (char *)xmalloc (sizeof(char) * (len + 1));
151 	while (nread < len) {
152 		res = recv (sock, str + nread, len - nread, 0);
153 		if (res == -1) {
154 			logit ("recv() failed when getting string: %s",
155 					strerror(errno));
156 			free (str);
157 			return NULL;
158 		}
159 		if (res == 0) {
160 			logit ("Unexpected EOF when getting string");
161 			free (str);
162 			return NULL;
163 		}
164 		nread += res;
165 	}
166 	str[len] = 0;
167 
168 	return str;
169 }
170 
send_str(int sock,const char * str)171 int send_str (int sock, const char *str)
172 {
173 	int len;
174 
175 	len = strlen (str);
176 	if (!send_int (sock, len))
177 		return 0;
178 
179 	if (send (sock, str, len, 0) != len)
180 		return 0;
181 
182 	return 1;
183 }
184 
185 /* Get a time_t value from the socket, return == 0 on error. */
get_time(int sock,time_t * i)186 int get_time (int sock, time_t *i)
187 {
188 	int res;
189 
190 	res = recv (sock, i, sizeof(time_t), 0);
191 	if (res == -1)
192 		logit ("recv() failed when getting time_t: %s", strerror(errno));
193 
194 	return res == sizeof(time_t) ? 1 : 0;
195 }
196 
197 /* Send a time_t value to the socket, return == 0 on error */
send_time(int sock,time_t i)198 int send_time (int sock, time_t i)
199 {
200 	int res;
201 
202 	res = send (sock, &i, sizeof(time_t), 0);
203 	if (res == -1)
204 		logit ("send() failed: %s", strerror(errno));
205 
206 	return res == sizeof(time_t) ? 1 : 0;
207 }
208 
packet_buf_new()209 static struct packet_buf *packet_buf_new ()
210 {
211 	struct packet_buf *b;
212 
213 	b = (struct packet_buf *)xmalloc (sizeof(struct packet_buf));
214 	b->buf = (char *)xmalloc (1024);
215 	b->allocated = 1024;
216 	b->len = 0;
217 
218 	return b;
219 }
220 
packet_buf_free(struct packet_buf * b)221 static void packet_buf_free (struct packet_buf *b)
222 {
223 	assert (b != NULL);
224 
225 	free (b->buf);
226 	free (b);
227 }
228 
229 /* Make sure that there is at least len bytes free. */
packet_buf_add_space(struct packet_buf * b,const size_t len)230 static void packet_buf_add_space (struct packet_buf *b, const size_t len)
231 {
232 	assert (b != NULL);
233 
234 	if (b->allocated < b->len + len) {
235 		b->allocated += len + 256; /* put some more space */
236 		b->buf = (char *)xrealloc (b->buf, b->allocated);
237 	}
238 }
239 
240 /* Add an integer value to the buffer */
packet_buf_add_int(struct packet_buf * b,const int n)241 static void packet_buf_add_int (struct packet_buf *b, const int n)
242 {
243 	assert (b != NULL);
244 
245 	packet_buf_add_space (b, sizeof(n));
246 	memcpy (b->buf + b->len, &n, sizeof(n));
247 	b->len += sizeof(n);
248 }
249 
250 /* Add a string value to the buffer. */
packet_buf_add_str(struct packet_buf * b,const char * str)251 static void packet_buf_add_str (struct packet_buf *b, const char *str)
252 {
253 	int str_len;
254 
255 	assert (b != NULL);
256 	assert (str != NULL);
257 
258 	str_len = strlen (str);
259 
260 	packet_buf_add_int (b, str_len);
261 	packet_buf_add_space (b, str_len * sizeof(char));
262 	memcpy (b->buf + b->len, str, str_len * sizeof(char));
263 	b->len += str_len * sizeof(char);
264 }
265 
266 /* Add a time_t value to the buffer. */
packet_buf_add_time(struct packet_buf * b,const time_t n)267 static void packet_buf_add_time (struct packet_buf *b, const time_t n)
268 {
269 	assert (b != NULL);
270 
271 	packet_buf_add_space (b, sizeof(n));
272 	memcpy (b->buf + b->len, &n, sizeof(n));
273 	b->len += sizeof(n);
274 }
275 
276 /* Add tags to the buffer. If tags == NULL, add empty tags. */
packet_buf_add_tags(struct packet_buf * b,const struct file_tags * tags)277 void packet_buf_add_tags (struct packet_buf *b, const struct file_tags *tags)
278 {
279 	assert (b != NULL);
280 
281 	if (tags) {
282 		packet_buf_add_str (b, tags->title ? tags->title : "");
283 		packet_buf_add_str (b, tags->artist ? tags->artist : "");
284 		packet_buf_add_str (b, tags->album ? tags->album : "");
285 		packet_buf_add_int (b, tags->track);
286 		packet_buf_add_int (b, tags->filled & TAGS_TIME ? tags->time : -1);
287 		packet_buf_add_int (b, tags->filled);
288 	}
289 	else {
290 
291 		/* empty tags: */
292 		packet_buf_add_str (b, ""); /* title */
293 		packet_buf_add_str (b, ""); /* artist */
294 		packet_buf_add_str (b, ""); /* album */
295 		packet_buf_add_int (b, -1); /* track */
296 		packet_buf_add_int (b, -1); /* time */
297 		packet_buf_add_int (b, 0); /* filled */
298 	}
299 }
300 
301 /* Add an item to the buffer. */
packet_buf_add_item(struct packet_buf * b,const struct plist_item * item)302 void packet_buf_add_item (struct packet_buf *b, const struct plist_item *item)
303 {
304 	packet_buf_add_str (b, item->file);
305 	packet_buf_add_str (b, item->title_tags ? item->title_tags : "");
306 	packet_buf_add_tags (b, item->tags);
307 	packet_buf_add_time (b, item->mtime);
308 }
309 
310 /* Send data to the socket. Return 0 on error. */
send_all(int sock,const char * buf,const size_t size)311 static int send_all (int sock, const char *buf, const size_t size)
312 {
313 	ssize_t sent;
314 	size_t send_pos = 0;
315 
316 	while (send_pos < size) {
317 		sent = send (sock, buf + send_pos, size - send_pos, 0);
318 		if (sent < 0) {
319 			logit ("Error while sending data: %s", strerror(errno));
320 			return 0;
321 		}
322 		send_pos += sent;
323 	}
324 
325 	return 1;
326 }
327 
328 /* Send a playlist item to the socket. If item == NULL, send empty item mark
329  * (end of playlist). Return 0 on error. */
send_item(int sock,const struct plist_item * item)330 int send_item (int sock, const struct plist_item *item)
331 {
332 	int res = 1;
333 	struct packet_buf *b;
334 
335 	if (!item) {
336 		if (!send_str(sock, "")) {
337 			logit ("Error while sending empty item");
338 			return 0;
339 		}
340 		return 1;
341 	}
342 
343 	b = packet_buf_new ();
344 	packet_buf_add_item (b, item);
345 	if (!send_all(sock, b->buf, b->len)) {
346 		logit ("Error when sending item");
347 		res = 0;
348 	}
349 
350 	packet_buf_free (b);
351 	return res;
352 }
353 
recv_tags(int sock)354 struct file_tags *recv_tags (int sock)
355 {
356 	struct file_tags *tags = tags_new ();
357 
358 	if (!(tags->title = get_str(sock))) {
359 		logit ("Error while receiving title");
360 		tags_free (tags);
361 		return NULL;
362 	}
363 
364 	if (!(tags->artist = get_str(sock))) {
365 		logit ("Error while receiving artist");
366 		tags_free (tags);
367 		return NULL;
368 	}
369 
370 	if (!(tags->album = get_str(sock))) {
371 		logit ("Error while receiving album");
372 		tags_free (tags);
373 		return NULL;
374 	}
375 
376 	if (!get_int(sock, &tags->track)) {
377 		logit ("Error while receiving track");
378 		tags_free (tags);
379 		return NULL;
380 	}
381 
382 	if (!get_int(sock, &tags->time)) {
383 		logit ("Error while receiving time");
384 		tags_free (tags);
385 		return NULL;
386 	}
387 
388 	if (!get_int(sock, &tags->filled)) {
389 		logit ("Error while receiving 'filled'");
390 		tags_free (tags);
391 		return NULL;
392 	}
393 
394 	/* Set NULL instead of empty tags. */
395 	if (!tags->title[0]) {
396 		free (tags->title);
397 		tags->title = NULL;
398 	}
399 	if (!tags->artist[0]) {
400 		free (tags->artist);
401 		tags->artist = NULL;
402 	}
403 	if (!tags->album[0]) {
404 		free (tags->album);
405 		tags->album = NULL;
406 	}
407 
408 	return tags;
409 }
410 
411 /* Send tags. If tags == NULL, send empty tags. Return 0 on error. */
send_tags(int sock,const struct file_tags * tags)412 int send_tags (int sock, const struct file_tags *tags)
413 {
414 	int res = 1;
415 	struct packet_buf *b;
416 
417 	b = packet_buf_new ();
418 	packet_buf_add_tags (b, tags);
419 
420 	if (!send_all(sock, b->buf, b->len))
421 		res = 0;
422 
423 	packet_buf_free (b);
424 	return res;
425 }
426 
427 /* Get a playlist item from the server.
428  * The end of the playlist is indicated by item->file being an empty string.
429  * The memory is malloc()ed.  Returns NULL on error. */
recv_item(int sock)430 struct plist_item *recv_item (int sock)
431 {
432 	struct plist_item *item = plist_new_item ();
433 
434 	/* get the file name */
435 	if (!(item->file = get_str(sock))) {
436 		logit ("Error while receiving file name");
437 		free (item);
438 		return NULL;
439 	}
440 
441 	if (item->file[0]) {
442 		if (!(item->title_tags = get_str(sock))) {
443 			logit ("Error while receiving tags title");
444 			free (item->file);
445 			free (item);
446 			return NULL;
447 		}
448 
449 		item->type = file_type (item->file);
450 
451 		if (!item->title_tags[0]) {
452 			free (item->title_tags);
453 			item->title_tags = NULL;
454 		}
455 
456 		if (!(item->tags = recv_tags(sock))) {
457 			logit ("Error while receiving tags");
458 			free (item->file);
459 			if (item->title_tags)
460 				free (item->title_tags);
461 			free (item);
462 			return NULL;
463 		}
464 
465 		if (!get_time(sock, &item->mtime)) {
466 			logit ("Error while receiving mtime");
467 			if (item->title_tags)
468 				free (item->title_tags);
469 			free (item->file);
470 			tags_free (item->tags);
471 			free (item);
472 			return NULL;
473 		}
474 	}
475 
476 	return item;
477 }
478 
recv_move_ev_data(int sock)479 struct move_ev_data *recv_move_ev_data (int sock)
480 {
481 	struct move_ev_data *d;
482 
483 	d = (struct move_ev_data *)xmalloc (sizeof(struct move_ev_data));
484 
485 	if (!(d->from = get_str(sock))) {
486 		logit ("Error while receiving 'from' data");
487 		free (d);
488 		return NULL;
489 	}
490 
491 	if (!(d->to = get_str(sock))) {
492 		logit ("Error while receiving 'to' data");
493 		free (d->from);
494 		free (d);
495 		return NULL;
496 	}
497 
498 	return d;
499 }
500 
501 /* Push an event on the queue if it's not already there. */
event_push(struct event_queue * q,const int event,void * data)502 void event_push (struct event_queue *q, const int event, void *data)
503 {
504 	assert (q != NULL);
505 
506 	if (!q->head) {
507 		q->head = (struct event *)xmalloc (sizeof(struct event));
508 		q->head->next = NULL;
509 		q->head->type = event;
510 		q->head->data = data;
511 		q->tail = q->head;
512 	}
513 	else {
514 		assert (q->head != NULL);
515 		assert (q->tail != NULL);
516 		assert (q->tail->next == NULL);
517 
518 		q->tail->next = (struct event *)xmalloc (
519 				sizeof(struct event));
520 		q->tail = q->tail->next;
521 		q->tail->next = NULL;
522 		q->tail->type = event;
523 		q->tail->data = data;
524 	}
525 }
526 
527 /* Remove the first event from the queue (don't free the data field). */
event_pop(struct event_queue * q)528 void event_pop (struct event_queue *q)
529 {
530 	struct event *e;
531 
532 	assert (q != NULL);
533 	assert (q->head != NULL);
534 	assert (q->tail != NULL);
535 
536 	e = q->head;
537 	q->head = e->next;
538 	free (e);
539 
540 	if (q->tail == e)
541 		q->tail = NULL; /* the queue is empty */
542 }
543 
544 /* Get the pointer to the first item in the queue or NULL if the queue is
545  * empty. */
event_get_first(struct event_queue * q)546 struct event *event_get_first (struct event_queue *q)
547 {
548 	assert (q != NULL);
549 
550 	return q->head;
551 }
552 
free_tag_ev_data(struct tag_ev_response * d)553 void free_tag_ev_data (struct tag_ev_response *d)
554 {
555 	assert (d != NULL);
556 
557 	free (d->file);
558 	tags_free (d->tags);
559 	free (d);
560 }
561 
free_move_ev_data(struct move_ev_data * m)562 void free_move_ev_data (struct move_ev_data *m)
563 {
564 	assert (m != NULL);
565 	assert (m->from != NULL);
566 	assert (m->to != NULL);
567 
568 	free (m->to);
569 	free (m->from);
570 	free (m);
571 }
572 
move_ev_data_dup(const struct move_ev_data * m)573 struct move_ev_data *move_ev_data_dup (const struct move_ev_data *m)
574 {
575 	struct move_ev_data *new;
576 
577 	assert (m != NULL);
578 	assert (m->from != NULL);
579 	assert (m->to != NULL);
580 
581 	new = (struct move_ev_data *)xmalloc (sizeof(struct move_ev_data));
582 	new->from = xstrdup (m->from);
583 	new->to = xstrdup (m->to);
584 
585 	return new;
586 }
587 
588 /* Free data associated with the event if any. */
free_event_data(const int type,void * data)589 void free_event_data (const int type, void *data)
590 {
591 	if (type == EV_PLIST_ADD || type == EV_QUEUE_ADD) {
592 		plist_free_item_fields ((struct plist_item *)data);
593 		free (data);
594 	}
595 	else if (type == EV_FILE_TAGS)
596 		free_tag_ev_data ((struct tag_ev_response *)data);
597 	else if (type == EV_PLIST_DEL || type == EV_STATUS_MSG
598 			|| type == EV_SRV_ERROR || type == EV_QUEUE_DEL)
599 		free (data);
600 	else if (type == EV_PLIST_MOVE || type == EV_QUEUE_MOVE)
601 		free_move_ev_data ((struct move_ev_data *)data);
602 	else if (data)
603 		abort (); /* BUG */
604 }
605 
606 /* Free event queue content without the queue structure. */
event_queue_free(struct event_queue * q)607 void event_queue_free (struct event_queue *q)
608 {
609 	struct event *e;
610 
611 	assert (q != NULL);
612 
613 	while ((e = event_get_first(q))) {
614 		free_event_data (e->type, e->data);
615 		event_pop (q);
616 	}
617 }
618 
event_queue_init(struct event_queue * q)619 void event_queue_init (struct event_queue *q)
620 {
621 	assert (q != NULL);
622 
623 	q->head = NULL;
624 	q->tail = NULL;
625 }
626 
627 #if 0
628 /* Search for an event of this type and return pointer to it or NULL if there
629  * was no such event. */
630 struct event *event_search (struct event_queue *q, const int event)
631 {
632 	struct event *e;
633 
634 	assert (q != NULL);
635 
636 	while ((e = q->head)) {
637 		if (e->type == event)
638 			return e;
639 		e = e->next;
640 	}
641 
642 	return NULL;
643 }
644 #endif
645 
646 /* Return != 0 if the queue is empty. */
event_queue_empty(const struct event_queue * q)647 int event_queue_empty (const struct event_queue *q)
648 {
649 	assert (q != NULL);
650 
651 	return q->head == NULL ? 1 : 0;
652 }
653 
654 /* Make a packet buffer filled with the event (with data). */
make_event_packet(const struct event * e)655 static struct packet_buf *make_event_packet (const struct event *e)
656 {
657 	struct packet_buf *b;
658 
659 	assert (e != NULL);
660 
661 	b = packet_buf_new ();
662 
663 	packet_buf_add_int (b, e->type);
664 
665 	if (e->type == EV_PLIST_DEL
666 			|| e->type == EV_QUEUE_DEL
667 			|| e->type == EV_SRV_ERROR
668 			|| e->type == EV_STATUS_MSG) {
669 		assert (e->data != NULL);
670 		packet_buf_add_str (b, e->data);
671 	}
672 	else if (e->type == EV_PLIST_ADD || e->type == EV_QUEUE_ADD) {
673 		assert (e->data != NULL);
674 		packet_buf_add_item (b, e->data);
675 	}
676 	else if (e->type == EV_FILE_TAGS) {
677 		struct tag_ev_response *r;
678 
679 		assert (e->data != NULL);
680 		r = e->data;
681 
682 		packet_buf_add_str (b, r->file);
683 		packet_buf_add_tags (b, r->tags);
684 	}
685 	else if (e->type == EV_PLIST_MOVE || e->type == EV_QUEUE_MOVE) {
686 		struct move_ev_data *m;
687 
688 		assert (e->data != NULL);
689 
690 		m = (struct move_ev_data *)e->data;
691 		packet_buf_add_str (b, m->from);
692 		packet_buf_add_str (b, m->to);
693 	}
694 	else if (e->data)
695 		abort (); /* BUG */
696 
697 	return b;
698 }
699 
700 /* Send the first event from the queue an remove it on success.  If the
701  * operation would block return NB_IO_BLOCK.  Return NB_IO_ERR on error
702  * or NB_IO_OK on success. */
event_send_noblock(int sock,struct event_queue * q)703 enum noblock_io_status event_send_noblock (int sock, struct event_queue *q)
704 {
705 	ssize_t res;
706 	struct packet_buf *b;
707 
708 	assert (q != NULL);
709 	assert (!event_queue_empty(q));
710 
711 	/* We must do it in one send() call to be able to handle blocking. */
712 	b = make_event_packet (event_get_first(q));
713 	res = send (sock, b->buf, b->len, MSG_DONTWAIT);
714 	packet_buf_free (b);
715 
716 	if (res > 0) {
717 		struct event *e;
718 
719 		e = event_get_first (q);
720 		free_event_data (e->type, e->data);
721 		event_pop (q);
722 
723 		return NB_IO_OK;
724 	}
725 	else if (errno == EAGAIN) {
726 		logit ("Sending event would block");
727 		return NB_IO_BLOCK;
728 	}
729 
730 	/* Error */
731 	logit ("Error when sending event: %s", strerror(errno));
732 	return NB_IO_ERR;
733 }
734