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