/*
 * Copyright 1988, 1989, 1990, 1991 Massachusetts Institute of Technology
 */
#include"structs.h"
dealwithit(i)
int i;
{
  Galatea_packet commandline, hostcommand;
  int cc, tm, msgsock;
  struct timeval to;
  fd_set ready;

  msgsock = clients[i].sock;
  bzero(&commandline,sizeof(commandline));
  cc = serv_full_read(msgsock,commandline.parm,sizeof(commandline), MAX_BLOCK);
  if (cc < 0) {
    bsdsyslog(LOG_INFO,
	      "Error reading stream packet from client %d, fd = %d", i,
	      clients[i].sock);
  }
  if (cc <= 0) {
    close_client(i);
    return(0);
  }
  num_requests++;
  nettohostcom(&commandline,&hostcommand,10);
#ifdef FULLDEBUG
  if (DEBUG) printf("Request number from client %d is %d\n", i, 
		    hostcommand.parm[0]);
  if (DEBUG) printf("hostcommand = %d %d %d %d %d %d %d %d %d %d\n",
		    hostcommand.parm[0],hostcommand.parm[1],
		    hostcommand.parm[2],hostcommand.parm[3],
		    hostcommand.parm[4],hostcommand.parm[5],
		    hostcommand.parm[6],hostcommand.parm[7],
		    hostcommand.parm[8],hostcommand.parm[9]);
#endif /* FULLDEBUG */
  switch(hostcommand.parm[0]) {
  case G_OpenServer:
    cc = DoOpenServer(msgsock,&hostcommand,i);
    break;
  case G_Switch:
    cc = DoSwitch(msgsock,&hostcommand,i);
    break;
  case G_Search:
    cc = DoSearch(msgsock,&hostcommand,i);
    break;
  case G_Index:
    cc = DoIndex(msgsock,&hostcommand,i);
    break;
  case G_Configure:
    cc = DoConfigure(msgsock,&hostcommand,i);
    break;
  case G_Load:
    cc = DoLoad(msgsock,&hostcommand,i);
    break;
  case G_Release:
    return(0);
    break;
  case G_Run:
    cc = DoRun(msgsock,&hostcommand,i);
    break;
  case G_Jog:
    cc = DoJog(msgsock,&hostcommand,i);
    break;
  case G_Still:
    cc = DoStill(msgsock,&hostcommand,i);
    break;
  case G_GetFrame:
    cc = DoGetFrame(msgsock,&hostcommand,i);
    break;
  case G_GetSpeed:
    cc = DoGetSpeed(msgsock,&hostcommand,i);
    break;
  case G_Reset:
    cc = DoReset(msgsock,&hostcommand,i);
    break;
  case G_PlaySeg:
    cc = DoPlaySeg(msgsock,&hostcommand,i);
    break;
  case G_PlaySequence:
    cc = DoPlaySequence(msgsock,&hostcommand,i);
    break;
  case G_CheckRevision:
    cc = DoCheckRevision(msgsock,&hostcommand,i);
    break;
  case G_Lock:
    cc = DoLock(msgsock,&hostcommand,i);
    break;
  case G_UnLock:
    cc = DoUnLock(msgsock,&hostcommand,i);
    break;
  case G_ShutOff:
    cc = DoShutOff(msgsock, &hostcommand, i);
    break;
  case G_RequestNotification:
    cc = DoRequestNotification(msgsock, &hostcommand, i);
    break;
  case G_GetServerTime:
    cc = DoGetServerTime(msgsock, &hostcommand, i);
    break;
  case G_GetStatistics:
    cc = DoGetStatistics(msgsock, &hostcommand, i);
    break;
  case G_Rebuild:
    cc = DoRebuild(msgsock, &hostcommand, i);
    break;
  case G_Mount:
    cc = DoMount(msgsock, &hostcommand, i);
    break;
  case G_Umount:
    cc = DoUmount(msgsock, &hostcommand, i);
    break;
  case G_GetMounts:
    cc = DoGetMounts(msgsock, &hostcommand, i);
    break;
  case G_Alloc:
    cc = DoAlloc(msgsock, &hostcommand, i);
    break;
  case G_AllocAtFrame:
    cc = DoAllocAtFrame(msgsock, &hostcommand, i);
    break;
  case G_Free:
    cc = DoFree(msgsock, &hostcommand, i);
    break;
  case G_Record:
    cc = DoRecord(msgsock, &hostcommand, i);
    break;
  case G_Dub:
    cc = DoDub(msgsock, &hostcommand, i);
    break;
  case G_RecordPreview:
    cc = DoRecordPreview(msgsock, &hostcommand, i);
    break;
#ifdef DBM
  case G_GetDatabases:
    cc = DoGetDatabases(msgsock, &hostcommand, i);
    break;
#endif /* DBM */
  default:
    cc = extdeal(msgsock, &hostcommand, i);
    break;
  }

/* subroutines send sync  */

  if (cc == -1) {
    bsdsyslog(LOG_INFO,
	      "Communications error with client %d, fd = %d", i,
	      clients[i].sock);
    close_client(i);
    unlock_all();
    return(0);
  }
  if (cc == -2) {
    unlock_all();
    return(0);
  }
  FD_ZERO(&ready);
  FD_SET(msgsock,&ready);
  to.tv_sec = RELEASE_TIMEOUT;
  to.tv_usec = 0;
  tm = select(MAXSOCKETS,&ready,0,0,&to);
  if (tm < 0)
    bsdsyslog(LOG_NOTICE,"Error in waiting for client[%d] OK",i);
  else if (tm == 0)
    bsdsyslog(LOG_NOTICE,"Timeout in waiting for client[%d] OK",i);
  unlock_all();
  return(0);
}

close_client(j)
     int j;
{
  if (DEBUG) printf("Closing connection %d, fd = %d.\n",j, clients[j].sock);
  close(clients[j].sock);
  if (LOCKED && whichlock == j) {
    clean_lock();
  }
  FD_CLR(clients[j].sock,&allavail);
  clients[j].sock = -1;
  if (clients[j].address) free(clients[j].address);
  if (notify_list[j]) {
    free(notify_list[j]);
    notify_list[j] = NULL;
    write_host_file();
  }
  recurse_free_segments(clients[j].seglist);
  recurse_free_seglist(clients[j].seglist);
  return(0);
}

recurse_free_segments(top_seglist)
     RPD_SEGLIST *top_seglist;
{

  if (top_seglist == (RPD_SEGLIST *)NULL) return;
  if (top_seglist->next != (RPD_SEGLIST *)NULL)
    recurse_free_segments(top_seglist->next);
  if (top_seglist->nframes)
    vfree(players[volumes[top_seglist->volume_id].resource[volumes[top_seglist->volume_id].cur_resource]], top_seglist->start, top_seglist->nframes);
  return;
}

clean_clients()
{
#ifdef OBSOLETE
  int j;
  for (j = 0; j < MAXSOCKETS; j++) {
    recurse_free_seglist(clients[j].seglist);
    clients[j].seglist = (RPD_SEGLIST *)NULL;
  }
#endif OBSOLETE
}

restore_allocations()
{
  int j, cur_volume, ret;
  RPD_SEGLIST *cur_segment;

  for (j = 0; j < MAXSOCKETS; j++) {
      cur_segment = clients[j].seglist;
      while (cur_segment != NULL) {
	  cur_volume = findvolumeid(cur_segment->volume_name, clients[j].output);
	  if (DEBUG) printf("Trying to restore alloc: %s = %d, %d for %d...",
			    cur_segment->volume_name, cur_volume, 
			    cur_segment->start, cur_segment->nframes);
	  ret = -1;
	  if (cur_volume != -1 && volumes[cur_volume].recordable) {
	      ret = vid_allocatframe(players[volumes[cur_volume].resource[volumes[cur_volume].cur_resource]], cur_segment->start, cur_segment->nframes);
	  }
	  if (ret != -1) {
	      if (DEBUG) printf("succeeded.\n");
	      cur_segment->volume_id = cur_volume;
	  }
	  else {
	      if (DEBUG) printf("failed.\n");
	      cur_segment->nframes = 0;
	  }
	  cur_segment = cur_segment->next;
      }
  }
}






