Changeset 4703:be4d84be6f04 in roaraudio
- Timestamp:
- 01/06/11 00:30:53 (13 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
ChangeLog
r4696 r4703 3 3 * Fixed small win32 bugs 4 4 * Fixed Typos (Closes: #100) 5 * Added basic gopher server to roard. 5 6 6 7 v. 0.4beta2 - Sun Dec 12 2010 10:28 CET -
plugins/roard/protocol-gopher.c
r4699 r4703 29 29 #include <roaraudio/proto_gopher.h> 30 30 31 #define _INFO ROAR_GOPHER_TYPE_INFO 32 #define _DIR ROAR_GOPHER_TYPE_DIR 33 #define _FILE ROAR_GOPHER_TYPE_FILE 34 #define _SOUND ROAR_GOPHER_TYPE_SOUND 35 36 static struct roar_gopher_menu_item g_gopher_root_menu[] = { 37 {.type = _INFO, .name = "roard Root Menu"}, 38 {.type = _FILE, .name = "Server Info", .selector = "/info.txt", .host = NULL, .port = 0} 39 }; 40 41 static struct item { 42 const char * selector; 43 char type; 44 struct roar_gopher_menu menu; 45 struct roar_audio_info info; 46 int dir; 47 const char * text; 48 } g_gopher_items[] = { 49 {.selector = "", .type = _DIR, 50 .menu = {.items = g_gopher_root_menu, .items_len = sizeof(g_gopher_root_menu)/sizeof(*g_gopher_root_menu)} 51 }, 52 // and again as selector '/' as some clients seems to require it: 53 {.selector = "/", .type = _DIR, 54 .menu = {.items = g_gopher_root_menu, .items_len = sizeof(g_gopher_root_menu)/sizeof(*g_gopher_root_menu)} 55 }, 56 {.selector = "/info.txt", .type = _FILE, .text = "Some\nText."} 57 }; 58 59 60 static int strip_nl (char * str) { 61 register char c; 62 63 for (; (c = *str) != 0; str++) { 64 if ( c == '\r' || c == '\n' ) { 65 *str = 0; 66 return 1; 67 } 68 } 69 70 return 0; 71 } 72 73 static int send_menu (int client, struct roar_gopher_menu * menu) { 74 struct roar_buffer * buf; 75 struct roar_gopher_menu_item * item; 76 const size_t len = 80; 77 size_t i; 78 void * data; 79 char * chardata; 80 81 for (i = 0; i < menu->items_len; i++) { 82 item = &(menu->items[i]); 83 if ( roar_buffer_new_data(&buf, len, &data) == -1 ) 84 return -1; 85 86 chardata = data; 87 88 switch (item->type) { 89 case _INFO: 90 snprintf(data, len-1, "i%s\tfake\t(NULL)\t0\r\n", item->name); 91 break; 92 default: 93 snprintf(data, len-1, "%c%s\t%s\t%s\t%u\r\n", item->type, item->name, item->selector, item->host, item->port); 94 break; 95 } 96 97 chardata[len-1] = 0; 98 99 roar_buffer_set_len(buf, strlen(data)); 100 101 clients_add_output(client, buf); 102 } 103 104 return 0; 105 } 106 107 static int send_text (int client, const char * text) { 108 struct roar_buffer * buf; 109 void * data; 110 size_t len = strlen(text); 111 112 if ( roar_buffer_new_data(&buf, len+6, &data) == -1 ) 113 return -1; 114 115 memcpy(data, text, len); 116 memcpy(data+len, "\r\n.\r\n\0", 6); 117 clients_add_output(client, buf); 118 119 return 0; 120 } 121 122 int emul_gopher_check_client(int client, struct roar_vio_calls * vio) { 123 struct roar_client_server * cs; 124 struct roar_vio_calls rvio; 125 struct item * c = NULL; 126 char inbuf[1024]; 127 ssize_t ret; 128 size_t i; 129 int funcret = -1; 130 size_t len = 0; 131 void * data; 132 133 if ( clients_get_server(client, &cs) == -1 ) { 134 clients_delete(client); 135 return -1; 136 } 137 138 if ( vio == NULL ) { 139 vio = &rvio; 140 roar_vio_open_fh_socket(vio, clients_get_fh(client)); 141 } 142 143 if ( cs->inbuf != NULL ) { 144 len = sizeof(inbuf)-1; 145 if ( roar_buffer_shift_out(&(cs->inbuf), inbuf, &len) == -1 ) { 146 clients_delete(client); 147 return -1; 148 } 149 150 if ( cs->inbuf != NULL ) { 151 roar_buffer_free(cs->inbuf); 152 clients_delete(client); 153 return -1; 154 } 155 156 // test if we have still buffer space left. 157 if ( len == (sizeof(inbuf)-1) ) { 158 clients_delete(client); 159 return -1; 160 } 161 } 162 163 ret = roar_vio_read(vio, inbuf+len, sizeof(inbuf)-len-1); 164 if ( ret < 1 ) { 165 clients_delete(client); 166 return -1; 167 } 168 169 ret += len; 170 171 inbuf[ret] = 0; 172 173 if ( !strip_nl(inbuf) ) { 174 if ( roar_buffer_new_data(&(cs->inbuf), ret, &data) == -1 ) { 175 clients_delete(client); 176 return -1; 177 } 178 179 memcpy(data, inbuf, ret); 180 return 0; 181 } 182 183 for (i = 0; i < sizeof(g_gopher_items)/sizeof(*g_gopher_items); i++) { 184 if ( !strcmp(g_gopher_items[i].selector, inbuf) ) { 185 c = &(g_gopher_items[i]); 186 break; 187 } 188 } 189 190 if ( c == NULL ) { 191 clients_delete(client); 192 return -1; 193 } 194 195 switch (c->type) { 196 case _DIR: 197 funcret = send_menu(client, &(c->menu)); 198 break; 199 case _FILE: 200 funcret = send_text(client, c->text); 201 break; 202 default: 203 funcret = -1; 204 break; 205 } 206 207 if ( funcret == -1 ) { 208 clients_delete(client); 209 return -1; 210 } 211 212 return 0; 213 } 214 215 int emul_gopher_flushed_client(int client, struct roar_vio_calls * vio) { 216 return clients_delete(client); 217 } 218 31 219 #endif 32 220 -
roard/clients.c
r4688 r4703 35 35 {ROAR_PROTO_RPLAY, NULL, emul_rplay_check_client, NULL, NULL}, 36 36 #endif 37 #ifndef ROAR_WITHOUT_DCOMP_EMUL_GOPHER 38 {ROAR_PROTO_GOPHER, NULL, emul_gopher_check_client, NULL, emul_gopher_flushed_client}, 39 #endif 37 40 {-1, NULL} 38 41 }; -
roard/include/emul_gopher.h.OLD
r4699 r4703 29 29 #include <roaraudio.h> 30 30 31 int emul_gopher_check_client(int client, struct roar_vio_calls * vio); 32 int emul_gopher_flushed_client(int client, struct roar_vio_calls * vio); 33 31 34 #endif 32 35 -
roard/roard.c
r4690 r4703 354 354 printf(" rplay W - RPlay emulation\n"); 355 355 #endif 356 #ifndef ROAR_WITHOUT_DCOMP_EMUL_GOPHER 357 printf(" gopher - The Internet Gopher Protocol\n"); 358 #endif 356 359 } 357 360
Note: See TracChangeset
for help on using the changeset viewer.