Changeset 4703:be4d84be6f04 in roaraudio


Ignore:
Timestamp:
01/06/11 00:30:53 (11 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

added basic gopher support

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r4696 r4703  
    33        * Fixed small win32 bugs 
    44        * Fixed Typos (Closes: #100) 
     5        * Added basic gopher server to roard. 
    56 
    67v. 0.4beta2 - Sun Dec 12 2010 10:28 CET 
  • plugins/roard/protocol-gopher.c

    r4699 r4703  
    2929#include <roaraudio/proto_gopher.h> 
    3030 
     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 
     36static 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 
     41static 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 
     60static 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 
     73static 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 
     107static 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 
     122int 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 
     215int emul_gopher_flushed_client(int client, struct roar_vio_calls * vio) { 
     216 return clients_delete(client); 
     217} 
     218 
    31219#endif 
    32220 
  • roard/clients.c

    r4688 r4703  
    3535 {ROAR_PROTO_RPLAY, NULL, emul_rplay_check_client, NULL, NULL}, 
    3636#endif 
     37#ifndef ROAR_WITHOUT_DCOMP_EMUL_GOPHER 
     38 {ROAR_PROTO_GOPHER, NULL, emul_gopher_check_client, NULL, emul_gopher_flushed_client}, 
     39#endif 
    3740 {-1, NULL} 
    3841}; 
  • roard/include/emul_gopher.h.OLD

    r4699 r4703  
    2929#include <roaraudio.h> 
    3030 
     31int emul_gopher_check_client(int client, struct roar_vio_calls * vio); 
     32int emul_gopher_flushed_client(int client, struct roar_vio_calls * vio); 
     33 
    3134#endif 
    3235 
  • roard/roard.c

    r4690 r4703  
    354354 printf("  rplay         W      - RPlay emulation\n"); 
    355355#endif 
     356#ifndef ROAR_WITHOUT_DCOMP_EMUL_GOPHER 
     357 printf("  gopher               - The Internet Gopher Protocol\n"); 
     358#endif 
    356359} 
    357360 
Note: See TracChangeset for help on using the changeset viewer.