home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Archived / MP3 / Riscster / riscsrc / c / proto < prev   
Text File  |  2000-05-26  |  20KB  |  871 lines

  1. /*
  2.        _             __
  3.   ____(_)__ _______ / /____ ____
  4.  / __/ (_-</ __(_-</ __/ -_) __/
  5. /_/ /_/___/\__/___/\__/\__/_/
  6.  
  7. Napster client for RISC OS
  8. Copyright (C) 2000 Robert Dimond
  9.  
  10. Portions are based on gnap by Ryan Dahl.
  11.  
  12. This program is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation; either version 2 of the License, or
  15. (at your option) any later version.
  16.  
  17. This program is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. GNU General Public License for more details.
  21.  
  22. You should have received a copy of the GNU General Public License
  23. along with this program; if not, write to the Free Software
  24. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  25.  
  26. Bransley Cottage, Cleobury Mortimer, Kidderminster, WORCS. DY14 0BZ
  27. England. robdimond@cwcom.net
  28.  
  29. */
  30.  
  31. #include "runimage.h"
  32.  
  33.  
  34. socket_s server;
  35. socket_s listen;
  36.  
  37. char buffer[0xffff];
  38.  
  39. extern char email[];
  40. extern char username[];
  41. extern char password[];
  42. extern int connection;
  43. extern int new_user;
  44. extern connect_level connected;
  45. extern search_result * search_resblock;
  46. extern int search_currentres;
  47. extern int listening_port;
  48. extern transfer downloads[];
  49. extern incoming incon[];
  50.  
  51.  
  52. char ip_bestserver[34];
  53. char debugmsg[200];
  54.  
  55.  
  56. int on=1;
  57.  
  58.  
  59. message_status mess_stat=get_head;
  60. int mess_recvd=0, mess_len=0, mess_command=0;
  61. char mess_header[4];
  62.  
  63. int napster_connect(void)
  64. {
  65.  int b;
  66.  socket_sockaddr serveraddress;
  67.  connected=notc;
  68.  
  69.  if(error(xsocket_creat(socket_AF_INET,
  70.                   socket_SOCK_STREAM,
  71.                   socket_IPPROTO_IP, &server))) return(-1);
  72.  
  73.  
  74.  if(error(xsocket_ioctl(server, socket_FIONBIO, (byte *) &on)))
  75.  {
  76.   xsocket_close(server);
  77.   return(-2);
  78.  }
  79.  /* connect socket to remote server */
  80.  serveraddress.sockaddr_in.af=socket_AF_INET;
  81.  serveraddress.sockaddr_in.port=portconv(HOSTPORT);
  82.  serveraddress.sockaddr_in.addr=ipconv(HOSTIP);
  83.  for(b=0; b<8; b++) serveraddress.sockaddr_in.data[b]=0;
  84.  connectedchange(tc_redir);
  85.  motd_addline("Connecting to redirect server...");
  86.  strcpy(ip_bestserver, "");
  87.  if(nerror(xsocket_connect(server, &serveraddress, sizeof(serveraddress))))
  88.  {
  89.   napster_close();
  90.   return(-3);
  91.  }
  92.  return(0);
  93. }
  94.  
  95. int nerror(os_error * err)
  96. {
  97.  int e;
  98.  e=err->errnum;
  99.  if ((e==socket_EAGAIN)||(e==socket_EWOULDBLOCK)||
  100.      (e==socket_EINPROGRESS)) return (0);
  101.     else return(error(err));
  102. }
  103.  
  104. void napster_handle_bestserver()
  105. {
  106.  char c;
  107.  int cc=0, pos, b;
  108.  int newip, newport;
  109.  socket_sockaddr serveraddress;
  110.  if (nerror(xsocket_recv(server, (byte *) &c, 1, 0, &cc))) return;
  111.  pos=strlen(ip_bestserver);
  112.  if (cc)
  113.  {
  114.   ip_bestserver[pos]=c;
  115.   ip_bestserver[pos+1]='\0';
  116.  }
  117.  if (strlen(ip_bestserver)>=20)
  118.  {
  119.   error(xsocket_close(server));
  120.   sprintf(debugmsg, "Redirecting to: %s", ip_bestserver);
  121.   napster_get_best_host(&newip, &newport, ip_bestserver);
  122.   if(error(xsocket_creat(socket_AF_INET,
  123.                 socket_SOCK_STREAM,
  124.                 socket_IPPROTO_IP, &server)))
  125.   {
  126.    napster_close();
  127.    return;
  128.   }
  129.   serveraddress.sockaddr_in.af=socket_AF_INET;
  130.   serveraddress.sockaddr_in.port=newport;
  131.   serveraddress.sockaddr_in.addr=newip;
  132.   for(b=0; b<8; b++) serveraddress.sockaddr_in.data[b]=0;
  133.   error(xsocket_ioctl(server, socket_FIONBIO, (byte *) &on));
  134.   if(nerror(xsocket_connect(server, &serveraddress, sizeof(serveraddress))))
  135.   {
  136.    napster_close();
  137.    return;
  138.   }
  139.   connectedchange(tc_server);
  140.  
  141.   motd_addline(debugmsg);
  142.  }
  143. }
  144.  
  145. void napster_close()
  146. {
  147.  if (connected!=notc) error(xsocket_close(server));
  148.  connectedchange(notc);
  149. }
  150.  
  151. int napster_mo_userlogin(char * username, char * password, int port, int connection, int new_user)
  152. {
  153.  char connect_string[200]="";
  154.  if (!new_user)
  155.  {
  156.   sprintf(connect_string,"%s %s %i \"%s\" %i",username,password,port,VERSION_STRING,connection);
  157.  
  158.   napster_send(connect_string, 2, strlen(connect_string));
  159.  
  160.  
  161.  }
  162.  else
  163.  {
  164.   sprintf(connect_string,"%s %s %i \"%s\" %i %s",username,password,port,VERSION_STRING,connection, email);
  165.   napster_send(connect_string, 6, strlen(connect_string));
  166.  }
  167.  return(0);
  168. }
  169.  
  170. int napster_mo_newuser(char * username)
  171. {
  172.  napster_send(username, 7, strlen(username));
  173.  return(0);
  174. }
  175.  
  176.  
  177. int napster_mo_dlrequest(search_result * toget)
  178. {
  179.  char get_string[300];
  180.  sprintf(get_string, "%s \"%s\"", toget->user, toget->filename);
  181.  napster_send(get_string, 203, strlen(get_string));
  182.  return(0);
  183. }
  184.  
  185. void napster_get_best_host(int * ipo, int * porto, char * string)
  186. {
  187.  char * ip, * port, * c;
  188.  ip=string;
  189.  port=strchr(string, ':');
  190.  port[0]='\0';
  191.  port+=sizeof(char);
  192.  c=strchr(port, '\0');
  193.  c[0]='\0';
  194.  *porto=portconv(atoi(port));
  195.  *ipo=ipconv(ip);
  196. }
  197.  
  198. int portconv(int port)
  199. {
  200.  char *b, *c;
  201.  b=(char *)&port;
  202.  c=b+1;
  203.  return(*c|(*b<<8));
  204. }
  205.  
  206. int ipconv(char * ipin)
  207. {
  208.  char c[]=".";
  209.  char ip[]="000.000.000.000";
  210.  char * t;
  211.  int out=0, n=0;
  212.  strcpy(ip, ipin);
  213.  t=strtok(ip, c);
  214.  while ((t!=NULL)&&(n<4))
  215.  {
  216.   out+=atoi(t)<<(n*8);
  217.   t=strtok(NULL, c);
  218.   n++;
  219.  }
  220.  /*os_writec('\4');
  221.  printf("%s %d\n", ip, out);*/
  222.  return(out);
  223. }
  224.  
  225. /*int main(void)
  226. {
  227.  napster_connect();
  228.  napster_mo_userlogin("ribby", "jelly", 6699, 3, 0);
  229.  while(napster_poll()==0);
  230. }*/
  231.  
  232. /*int napster_poll(void)
  233. {
  234.  int cc, length, type;
  235.  if(error(xsocket_recv(server, (byte *) buffer, 4, 0, &cc))) return(-1);
  236.  if (cc==4)
  237.  {
  238.   length=buffer[0]|(buffer[1]<<8);
  239.   type=buffer[2]|(buffer[3]<<8);
  240.   printf("%d %d\n", length, type);
  241.   if(error(xsocket_recv(server, (byte *) buffer, length, 0, &cc))) return(-1);
  242.   buffer[cc]='\0';
  243.   printf("%s\n", buffer);
  244.   switch(type)
  245.   {
  246.    case 0:
  247.    napster_mess_error(buffer); break;
  248.    case 1: break;
  249.  
  250.   }
  251.   return(0);
  252.  }
  253. }*/
  254.  
  255. int napster_poll(void)
  256. {
  257.  int i;
  258.  socket_s newsocket;
  259.  socket_timeval timeout;
  260.  long readfd=0, writefd=0;
  261.  int nfound=0;
  262.  readfd=readfd|(long)1<<(int)listen;
  263.  switch(connected)
  264.  {
  265.   case notc:
  266.   break;
  267.   case tc_redir:
  268.   writefd=writefd|(long)1<<(int)server;
  269.   break;
  270.   case get_redir:
  271.   readfd=readfd|(long)1<<(int)server;
  272.   break;
  273.   case tc_server:
  274.   writefd=writefd|(long)1<<(int)server;
  275.   break;
  276.   default:
  277.   if (connected>=try_login)
  278.   {
  279.    readfd=readfd|(long)1<<(int)server;
  280.    for(i=0; i<C_DOWNLOADS; i++)
  281.    {
  282.     if(downloads[i].active==tc) writefd=writefd|(long)1<<(int)downloads[i].socket;
  283.     if(downloads[i].active>=get_one)
  284.                                readfd=readfd|(long)1<<(int)downloads[i].socket;
  285.    }
  286.   }
  287.  }
  288.  
  289.  for(i=0; i<C_INCOMING; i++)
  290.  {
  291.   if(incon[i].active) readfd=readfd|(long)1<<(int)incon[i].socket;
  292.  }
  293.  
  294.  timeout.sec=0; timeout.usec=0;
  295.  error(xsocket_select(32, (socket_fdset *) &readfd,
  296.                           (socket_fdset *) &writefd,
  297.                                NULL, &timeout, &nfound));
  298.  if(readfd&((long)1<<(int)listen))
  299.  {
  300.   if(!nerror(xsocket_accept(listen, NULL, NULL, &newsocket)))
  301.                                              napster_incoming(newsocket);
  302.  }
  303.  switch(connected)
  304.  {
  305.   case notc:
  306.   break;
  307.   case tc_redir:
  308.   if(writefd&((long)1<<(int)server)) connectedchange(get_redir);
  309.   break;
  310.   case get_redir:
  311.   if(readfd&((long)1<<(int)server)) napster_handle_bestserver();
  312.   break;
  313.   case tc_server:
  314.   if(writefd&((long)1<<(int)server))
  315.   {
  316.    motd_addline("Connected, trying to log in...");
  317.    if(!new_user)
  318.    napster_mo_userlogin(username, password, listening_port, connection, 0);
  319.    else napster_mo_newuser(username);
  320.    connectedchange(try_login);
  321.   }
  322.   break;
  323.   default:
  324.   if(connected>=try_login)
  325.   {
  326.    if(readfd&((long)1<<(int)server))
  327.    {
  328.     napster_handle_input();
  329.    }
  330.    for(i=0; i<C_DOWNLOADS; i++)
  331.    {
  332.     if((downloads[i].active==tc)&&(writefd&((long)1<<(int)downloads[i].socket)))
  333.       napster_handle_nfconnected(i);
  334.     if((downloads[i].active>=get_one)&&(readfd&((long)1<<(int)downloads[i].socket)))
  335.     {
  336.      switch(downloads[i].active)
  337.      {
  338.       case get_one:
  339.       napster_handle_one(i);
  340.       break;
  341.       case get_header:
  342.       napster_handle_header(i);
  343.       break;
  344.       case download:
  345.       napster_handle_download(i);
  346.       break;
  347.      }
  348.     }
  349.    }
  350.   }
  351.   break;
  352.  }
  353.  for(i=0; i<C_INCOMING; i++)
  354.  {
  355.   if((incon[i].active)&&(readfd&((long)1<<(int)incon[i].socket)))
  356.   {
  357.    napster_handle_inconheader(i);
  358.   }
  359.  }
  360.  return(0);
  361. }
  362.  
  363. void napster_incoming(socket_s newsocket)
  364. {
  365.  int cc=0;
  366.  int in_slot=0;
  367.  while((in_slot<=C_INCOMING)&&(incon[in_slot].active!=0))
  368.  {
  369.   in_slot++;
  370.  }
  371.  if(incon[in_slot].active!=0)
  372.  {
  373.   xsocket_close(newsocket);
  374.   return;
  375.  }
  376.  if (nerror(xsocket_send(newsocket, (byte *) "1", 1, 0, &cc)))
  377.  {
  378.   ui_messalert("ERRCOMC");
  379.   xsocket_close(newsocket);
  380.   return;
  381.  }
  382.  incon[in_slot].socket=newsocket;
  383.  incon[in_slot].active=1;
  384.  incon[in_slot].hpos=0;
  385.  incon[in_slot].header[0]='\0';
  386.  incon[in_slot].command=0;
  387. }
  388.  
  389. void napster_handle_inconheader(int ino)
  390. {
  391.  char c;
  392.  int cc=0, i;
  393.  if (nerror(xsocket_recv(incon[ino].socket, (byte *) &c, 1, 0, &cc)))
  394.  {
  395.   ui_messalert("ERRCOMC");
  396.   incon[ino].active=0;
  397.   xsocket_close(incon[ino].socket);
  398.   return;
  399.  }
  400.  incon[ino].header[incon[ino].hpos]=c;
  401.  incon[ino].hpos++;
  402.  incon[ino].header[incon[ino].hpos]='\0';
  403.  if(incon[ino].active==1)
  404.  {
  405.   if(!strcmp(incon[ino].header, "SEND"))
  406.   {
  407.    incon[ino].command=1;
  408.    incon[ino].hpos=0;
  409.    incon[ino].active=2;
  410.    return;
  411.   }
  412.  }
  413.  if(incon[ino].active==2)
  414.  {
  415.   if (c=='\"')
  416.   {
  417.    incon[ino].active=3;
  418.    return;
  419.   }
  420.  }
  421.  if(incon[ino].active==3)
  422.  {
  423.   if (c==' ')
  424.   {
  425.    for(i=0; i<C_DOWNLOADS; i++)
  426.    {
  427.     if((downloads[i].active==window)&&
  428.        (strstr(incon[ino].header, downloads[i].filename)))
  429.     {
  430.      cc=0;
  431.      if(nerror(xsocket_send(incon[ino].socket, (byte *) "0", 1, 0, &cc)))
  432.      {
  433.       incon[ino].active=0;
  434.       xsocket_close(incon[ino].socket);
  435.       ui_messalert("ERRCOMC");
  436.       return;
  437.      }
  438.      if(cc)
  439.      {
  440.       incon[ino].active=0;
  441.       downloads[i].socket=incon[ino].socket;
  442.       downloads[i].active=get_header;
  443.       downloads[i].headcount=0;
  444.      }
  445.     }
  446.    }
  447.   }
  448.  }
  449. }
  450.  
  451. void napster_handle_header(int tno)
  452. {
  453.  int cc;
  454.  char c;
  455.  if(nerror(xsocket_recv(downloads[tno].socket, (byte *) &c, 1,
  456.                                               socket_MSG_PEEK, &cc)))
  457.  {
  458.   ui_messalert("ERRCOMC");
  459.   napster_download_end(tno);
  460.  }
  461.  if (!isdigit((int) c))
  462.  {
  463.   downloads[tno].header[downloads[tno].headcount]='\0';
  464.   sprintf(debugmsg, "Got size header:  %s bytes", downloads[tno].header);
  465.   motd_addline(debugmsg);
  466.   napster_send((char *) "", 218, 0);
  467.   downloads[tno].totalsize=atoi((downloads[tno].header));
  468.   downloads[tno].active=download;
  469.  }
  470.  else
  471.  {
  472.   if(nerror(xsocket_recv(downloads[tno].socket, (byte *) &c, 1, 0, &cc)))
  473.   {
  474.    ui_messalert("ERRCOMC");
  475.    napster_download_end(tno);
  476.   }
  477.   downloads[tno].header[downloads[tno].headcount]=c;
  478.   downloads[tno].headcount++;
  479.  }
  480. }
  481.  
  482. void napster_handle_download(int tno)
  483. {
  484.  char buffer[2048];
  485.  int amount_recv, i;
  486.  for (i=0; i<2048; i++) buffer[i]=0;
  487.  /*amount_recv = recv(t_current.socket,buffer,2048,0);*/
  488.  nerror(xsocket_recv(downloads[tno].socket, (byte *)buffer,
  489.                                                  2048, 0, &amount_recv));
  490.  fwrite(buffer, sizeof(char), amount_recv, downloads[tno].filehandle);
  491.  downloads[tno].size += amount_recv;
  492.  if (downloads[tno].size>=downloads[tno].totalsize) napster_download_end(tno);
  493. }
  494.  
  495. void napster_download_end(int tno)
  496. {
  497.  if (downloads[tno].active==download)
  498.  {
  499.   napster_send((char *) "", 219, 0);
  500.  }
  501.  if (downloads[tno].active>=tc)
  502.  {
  503.   error(xsocket_close(downloads[tno].socket));
  504.   if (fclose(downloads[tno].filehandle)==EOF)
  505.   {
  506.    ui_messalert("ERRCSC");
  507.   }
  508.  }
  509.  get_closewin(tno);
  510.  downloads[tno].active=freesl;
  511. }
  512.  
  513. void napster_send(char * data, int type, int length)
  514. {
  515.  char msb, lsb;
  516.  char head[4];
  517.  char motd[255];
  518.  int cc;
  519.  msb=(length>>8);
  520.  lsb=length-(msb<<8);
  521.  head[0]=lsb; head[1]=msb;
  522.  msb=(type>>8);
  523.  lsb=type-(msb<<8);
  524.  head[2]=lsb; head[3]=msb;
  525.  if((nerror(xsocket_send(server, (byte *)head, 4, 0, &cc)))
  526.      ||(nerror(xsocket_send(server, (byte *)data, length, 0, &cc))))
  527.  {
  528.   ui_messalert("ERRCOMS");
  529.   napster_close();
  530.   return;
  531.  }
  532.  sprintf(motd, "> Type:%d Len:%d  %s", type, length, data);
  533.  motd_addline(motd);
  534. }
  535.  
  536. void napster_mess_loginerror(char * message)
  537. {
  538.  /*printf("Error from server: %s\n", message);*/
  539.  ui_alert(message);
  540.  napster_close();
  541. }
  542.  
  543. void napster_mess_error(char * message)
  544. {
  545.  ui_alert(message);
  546.  search_ungrey();
  547. }
  548.  
  549. void napster_mess_loginack(char * email)
  550. {
  551.  /*printf("Logged in, email is %s\n", email);*/
  552.  ui_messalert("SMLOGIN");
  553. /* napster_init_server();*/
  554.  connectedchange(loggedin);
  555. }
  556.  
  557. void napster_mess_regsuccess(void)
  558. {
  559.  /*printf("New user registration success\n");*/
  560.  ui_messalert("SMREGS");
  561.  napster_mo_userlogin(username, password, 6699, connection, 1);
  562. }
  563.  
  564. void napster_mess_alreadyreg(void)
  565. {
  566.  /*printf("Nickname is already in use by another user\n");*/
  567.  ui_messalert("SMNICK");
  568.  napster_close();
  569. }
  570.  
  571. void napster_mess_invalidreg(void)
  572. {
  573.  /*printf("Nickname is invalid\n");*/
  574.  ui_messalert("SMINV");
  575.  napster_close();
  576. }
  577.  
  578. void napster_mess_searchresponse(char * line)
  579. {
  580.  
  581.  search_result * result, * i;
  582.  char *filename,user[40],id[100];
  583.  int number,size,bitrate,frequency,speed;
  584.  unsigned int ip;
  585.  filename = line;
  586.  filename ++;
  587.  line = (char*)strchr(filename,'\"');
  588.  if(!line) {
  589.  /* printf("strange filename error\n");*/
  590.   os_writec('\4');
  591.   printf("%s\n", line);
  592.   ui_messalert("ERRSFILE");
  593.   return;
  594.  }
  595.  line[0] = '\0';
  596.  line ++;
  597.  result = malloc(sizeof(search_result));
  598.  if (result==NULL) return;
  599.  sscanf(line," %s %u %d %d %d %s %u %d",id,&size,&bitrate,&frequency,&number,user,&ip,&speed);
  600.  
  601.  strcpy(result->filename, filename);
  602.  strcpy(result->id, id);
  603.  result->number = number;
  604.  result->ip = ip;
  605.  strcpy(result->user, user);
  606.  result->size = size;
  607.  result->bitrate = bitrate;
  608.  result->frequency = frequency;
  609.  result->speed = speed;
  610.  result->next = NULL;
  611.  if (speed<0) return;
  612.  search_update(result);
  613. }
  614.  
  615. void napster_mess_searchend()
  616. {
  617.  search_ungrey();
  618.  search_finish();
  619. }
  620.  
  621. void napster_mess_dlack(char * buffer)
  622. {
  623.  /*char motdt[100];*/
  624.  char getstring[300];
  625.  char fn[300], fnt[255];
  626.  char *filename,*rest,user[40],id[40];
  627.  int port,speed;
  628.  unsigned int ip;
  629.  int tno=-1, i;
  630.  int b, used=0;
  631.  char dot[]=".";
  632.  socket_sockaddr otheruser;
  633.  filename = strchr(buffer,'\"');
  634.  filename[0] = '\0';
  635.  filename ++;
  636.  rest = strchr(filename,'\"');
  637.  rest[0] = '\0';
  638.  rest++;
  639.  sscanf(buffer,"%s %u %d ",user,&ip,&port);
  640.  sscanf(rest," %s %d",id,&speed);
  641.  sprintf(debugmsg, "Connect to port %d", port);
  642.  motd_addline(debugmsg);
  643.  
  644.  if(error(xos_read_var_val("Riscster$MusicDir", fn, 300, 0, os_VARTYPE_STRING,
  645.                                                           &used, NULL, NULL)))
  646.  {
  647.   ui_messalert("ERRMPNS");
  648.   return;
  649.  }
  650.  fn[used]='\0';
  651.  for (i=0; i<C_DOWNLOADS; i++)
  652.  {
  653.   if (downloads[i].active==window)
  654.   {
  655.    if (strcmp(downloads[i].filename, filename)==0) tno=i;
  656.   }
  657.  }
  658.  if (tno==-1)
  659.  {
  660.   return;
  661.  }
  662.  strcpy(fnt, filename);
  663.  strcat(fn, dot);
  664.  strcat(fn, napster_sanefile(fnt));
  665.  downloads[tno].filehandle=fopen(fn, "wb");
  666.  if (downloads[tno].filehandle==NULL)
  667.  {
  668.   ui_messalert("ERRSCRAP");
  669.   return;
  670.  }
  671.  error(xosfile_set_type(fn, 0x1ad));
  672.  /*downloads[tno].totalsize=(search_resblock+search_currentres)->size;*/
  673.  
  674.  if (port==0)
  675.  {
  676.   sprintf(getstring, "%s \"%s\" 0", downloads[tno].user, filename);
  677.   napster_send(getstring, 500, strlen(getstring));
  678.   return;
  679.  }
  680.  if(error(xsocket_creat(socket_AF_INET, socket_SOCK_STREAM, socket_IPPROTO_IP,
  681.                                                  &downloads[tno].socket)))
  682.  {
  683.   return;
  684.  }
  685.  error(xsocket_ioctl(downloads[tno].socket, socket_FIONBIO, (byte *) &on));
  686.  otheruser.sockaddr_in.af=socket_AF_INET;
  687.  otheruser.sockaddr_in.port=portconv(port);
  688.  otheruser.sockaddr_in.addr=ip;
  689.  for(b=0; b<8; b++) otheruser.sockaddr_in.data[b]=0;
  690.  
  691.  if(nerror(xsocket_connect(downloads[tno].socket, &otheruser, sizeof(otheruser))))
  692.  {
  693.   ui_messalert("ERRCNCN");
  694.   xsocket_close(downloads[tno].socket);
  695.   return;
  696.  }
  697.  downloads[tno].active=tc;
  698.  downloads[tno].headcount=0;
  699. }
  700.  
  701. void napster_handle_nfconnected(int tno)
  702. {
  703.  char getstring[300];
  704.  int cc=0;
  705.  nerror(xsocket_send(downloads[tno].socket, (byte *) "GET", 3, 0, &cc));
  706.  sprintf(getstring, "%s \"%s\" 0", username, downloads[tno].filename);
  707.  cc=0;
  708.  nerror(xsocket_send(downloads[tno].socket,
  709.                             (byte *) getstring, strlen(getstring), 0, &cc));
  710.  downloads[tno].active=get_one;
  711. }
  712.  
  713. void napster_handle_one(int tno)
  714. {
  715.  int cc=0;
  716.  char mustbeone;
  717.  nerror(xsocket_recv(downloads[tno].socket, (byte *) &mustbeone, 1, 0, &cc));
  718.  if (mustbeone!='1')
  719.  {
  720.   ui_messalert("ERRIHE");
  721.   napster_download_end(tno);
  722.  }
  723.  downloads[tno].active=get_header;
  724. }
  725.  
  726. char * napster_sanefile(char * file)
  727. {
  728.  char * nfile;
  729.  nfile=strrchr(file, (int) '\\');
  730.  if (nfile!=NULL) file=nfile+1;
  731.  nfile=file;
  732.  while (*nfile!='\0')
  733.  {
  734.   if (*nfile=='.') *nfile='/';
  735.   if (*nfile==' ') *nfile='_';
  736.   nfile++;
  737.  }
  738.  return(file);
  739. }
  740.  
  741. void napster_mess_motd(char * buffer)
  742. {
  743.  /*os_writec('\4');
  744.  printf("%s\n", buffer);*/
  745.  motd_addline(buffer);
  746. }
  747.  
  748. void napster_handle_input(void)
  749. {
  750.  char buffer2[0xffff];
  751.  switch(mess_stat)
  752.  {
  753.   case get_head:
  754.   {
  755.    int cc=0, i=0;
  756.    /*FILE * messydebug;*/
  757.    if(nerror(xsocket_recv(server, (byte *) &mess_header[mess_recvd],
  758.                                         1, 0, &cc)))
  759.    {
  760.     ui_messalert("ERRCOMS");
  761.     napster_close();
  762.     return;
  763.    }
  764.  
  765.    mess_recvd+=cc;
  766.    if(mess_recvd==4)
  767.    {
  768.     mess_len=mess_header[0]|(mess_header[1]<<8);
  769.     mess_command=mess_header[2]|(mess_header[3]<<8);
  770.     for(i=0; i<sizeof(buffer); i++) buffer[i]='\0';
  771.     if (mess_len>0) mess_stat=get_data;
  772.       else napster_handle_message(mess_command, buffer);
  773.     mess_recvd=0;
  774.     /*messydebug=fopen("RAM::RamDisc0.$.messdebug", "a");
  775.     fprintf(messydebug, "Length: %d  Type: %d\n", mess_len, mess_command);
  776.     fclose(messydebug);*/
  777.    }
  778.   }
  779.   break;
  780.   case get_data:
  781.   {
  782.    int cc=0, i=0;
  783.    /*FILE * messydebug;
  784.    messydebug=fopen("RAM::RamDisc0.$.messdebug", "a");
  785.    fprintf(messydebug, "Got Already: %d\n", mess_recvd);
  786.    fclose(messydebug);*/
  787.    for (i=0; i<sizeof(buffer2); i++) buffer2[i]='\0';
  788.    if(nerror(xsocket_recv(server, (byte *) buffer2,
  789.                             (mess_len-mess_recvd), 0, &cc)))
  790.    {
  791.     ui_messalert("ERRCOMS");
  792.     napster_close();
  793.    }
  794.    /*messydebug=fopen("RAM::RamDisc0.$.messdebug", "a");
  795.    fprintf(messydebug, "Just Got: %d\n", cc);
  796.    fclose(messydebug);*/
  797.    memcpy(buffer+mess_recvd, buffer2, cc);
  798.    mess_recvd+=cc;
  799.  
  800.    if(mess_recvd==mess_len)
  801.    {
  802.     napster_handle_message(mess_command, buffer);
  803.     mess_stat=get_head;
  804.     mess_len=0;
  805.     mess_command=0;
  806.     mess_recvd=0;
  807.    }
  808.   }
  809.   break;
  810.  }
  811. }
  812.  
  813. void napster_handle_message(int mc, char * buffer)
  814. {
  815.  switch(mc)
  816.  {
  817.   case 0:
  818.   napster_mess_loginerror(buffer); break;
  819.   case 3:
  820.   napster_mess_loginack(buffer); break;
  821.   case 8:
  822.   napster_mess_regsuccess(); break;
  823.   case 9:
  824.   napster_mess_alreadyreg(); break;
  825.   case 10:
  826.   napster_mess_invalidreg(); break;
  827.   case 201:
  828.   napster_mess_searchresponse(buffer); break;
  829.   case 202:
  830.   napster_mess_searchend(); break;
  831.   case 204:
  832.   napster_mess_dlack(buffer); break;
  833.   case 404:
  834.   napster_mess_error(buffer); break;
  835.   case 621:
  836.   napster_mess_motd(buffer); break;
  837.  }
  838. }
  839.  
  840. int napster_init_server()
  841. {
  842.  socket_sockaddr localport;
  843.  int b;
  844.  int tryport=6698;
  845.  if(error(xsocket_creat(socket_AF_INET,
  846.                   socket_SOCK_STREAM,
  847.                   socket_IPPROTO_IP, &listen))) return(-1);
  848.  error(xsocket_ioctl(listen, socket_FIONBIO, (byte *) &on));
  849.  do
  850.  {
  851.   tryport++;
  852.   localport.sockaddr_in.af=socket_AF_INET;
  853.   localport.sockaddr_in.port=portconv(tryport);
  854.   localport.sockaddr_in.addr=0;
  855.   for(b=0; b<8; b++) localport.sockaddr_in.data[b]=0;
  856.  
  857.  }while(xsocket_bind(listen, &localport, sizeof(localport))&&
  858.                                                      (tryport<6800));
  859.  listening_port=tryport;
  860.  if(error(xsocket_listen(listen, 5))) return(-2);
  861.  return(0);
  862. }
  863.  
  864. int napster_end_server()
  865. {
  866.  return(error(xsocket_close(listen)));
  867. }
  868.  
  869.  
  870.  
  871.