2 * Copyright (c) 2018, De Rais <derais@cock.li>
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
23 #include <libwebsockets.h>
29 const char *program_name
= "cycon";
32 static void usage(void)
34 int len
= strlen(program_name
) + 7;
36 fprintf(stderr
, "usage: %s [ -s SERVER ] # like \"cytu.be\"\n",
38 fprintf(stderr
, "%*s [ -h ] # if website is http (not https)\n",
40 fprintf(stderr
, "%*s -c CHANNEL\n", len
, "");
43 /* LWS handling thread */
45 cytube_lws_handler(struct lws
*wsi
, enum lws_callback_reasons reason
,
46 void *user
, void *in
, size_t len
);
47 void * lws_spin(void *arg
)
51 struct state
volatile *s
= (struct state
volatile *) arg
;
52 char *ripped_host
= 0;
53 const struct lws_protocols p
[] = {
58 .callback
= cytube_lws_handler
, /* */
59 .per_session_data_size
= sizeof(struct state
), /* */
60 .rx_buffer_size
= 0, /* */
62 .user
= (void *) s
, /* */
63 .tx_packet_size
= 0, /* */
66 struct lws_context_creation_info info
= {
68 .options
= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT
, /* */
69 .port
= CONTEXT_PORT_NO_LISTEN
, /* */
72 struct lws_context
*context
= 0;
74 int sslf
= s
->https
? LCCSCF_USE_SSL
| LCCSCF_ALLOW_SELFSIGNED
: 0;
75 struct lws_client_connect_info cci
= {
78 .ssl_connection
= sslf
, /* */
79 .address
= s
->address
, /* */
80 .origin
= s
->address
, /* */
81 .protocol
= "sync", /* */
82 .userdata
= (void *) &s
, /* */
86 /* First, HTTP stuff in preparation for LWS */
87 if (cytube_get_session_cookie(cci
.address
, (s
->https
? "https" :
88 "http"), s
->channel_name
,
90 ERROR_MESSAGE("cannot extract ip-session cookie");
91 ERROR_MESSAGE("perhaps \"%s\" is not a channel?",
97 /* See cb_get_real_server */
99 ripped_host
= strdup(s
->socket_host
+ 8);
101 ripped_host
= strdup(s
->socket_host
+ 7);
104 if (!(ripped_host
)) {
108 for (char *p
= ripped_host
; *p
; ++p
) {
111 cci
.port
= strtoll(p
+ 1, 0, 0);
116 cci
.host
= ripped_host
;
117 cci
.address
= ripped_host
;
119 /* Start up LWS XXX: change log_level to 0 */
120 lws_set_log_level(0, 0);
121 cytube_set_cci_and_s(&cci
, s
);
123 if (!(context
= lws_create_context(&info
))) {
124 ERROR_MESSAGE("lws_create_context failed");
129 cci
.context
= context
;
130 s
->last_playlist_req
= time(0) + 120;
132 while (!s
->please_die
) {
133 if ((lret
= lws_service(context
, 1000)) < 0) {
137 /* Do we need to ping? */
140 if (s
->established
) {
141 if (s
->last_ping
+ (s
->ping_interval
/ 1000) <= now
) {
142 s
->must_write_ping
= 1;
146 if (s
->last_playlist_req
+ 120 <= now
) {
147 s
->must_ask_for_playlist
= 1;
148 s
->last_playlist_req
= now
;
152 /* Tell LWS we want to write */
153 if (s
->must_write_upgrade
||
154 s
->must_write_ping
||
155 s
->must_join_channel
||
156 s
->must_ask_for_playlist
) {
157 lws_callback_on_writable(wsi
);
161 lws_context_destroy(context
);
169 int main(int argc
, char **argv
)
174 .address
= "cytu.be", .https
= 1,
176 char *server_arg
= 0;
177 char *channel_arg
= 0;
179 pthread_t lws_thread
= { 0 };
181 setlocale(LC_ALL
, "");
183 /* Parse arguments */
184 while ((opt
= getopt(argc
, argv
, "s:c:h")) != -1) {
190 channel_arg
= optarg
;
203 s
.address
= server_arg
;
211 s
.channel_name
= channel_arg
;
212 s
.playlist
.current_playing_uid
= -1;
214 if (ui_init(&s
) < 0) {
215 PERROR_MESSAGE("ui initialization error");
219 if (pthread_create(&lws_thread
, 0, lws_spin
, (void *) &s
)) {
220 PERROR_MESSAGE("pthread_create");
227 pthread_join(lws_thread
, 0);