Logo Search packages:      
Sourcecode: fbb version File versions  Download package

k_tasks.c

   /****************************************************************
    Copyright (C) 1986-2000 by

    F6FBB - Jean-Paul ROUBELAT
    6, rue George Sand
    31120 - Roquettes - France
      jpr@f6fbb.org

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Parts of code have been taken from many other softwares.
    Thanks for the help.
    ****************************************************************/

/*
 * Taches auxilliaires demandees par le noyau
 *
 */

#include <serv.h>
#include <yapp.h>
#include <modem.h>

/* Timer head */
static FbbTimer *timer_head = NULL;

static int inbuf_bin (int);
static int inbuf_xmodem (int);
static int inbuf_yapp (int);
static int nb_buf (int);
static int trait_buf (int);

/* void mail_in (void); */
static void tst_buf (int);
static int tst_minfwd (int, int);

/* Horloge ticker */
long btime (void)
{
      static long oldtime = 0L;
      static long offset = 0L;
      long bt;

#ifdef __WINDOWS__
      struct time dt;

      gettime (&dt);
      bt = (((long) dt.ti_hour * 3600L + (long) dt.ti_min * 60L + (long) dt.ti_sec) << 14) / 900L;
      bt += (((long) dt.ti_hund * 10) << 16) / 3600000L;

      if (bt > 0x17ffffL)
            bt = 0x17ffffL;
      bt += offset;
      while (bt < oldtime)
      {
            /* Le jour a change... */
            offset += 0x180000L;
            bt += 0x180000L;
      }
      // WinDebug("bt = %ld\r\n", bt);
#endif

#ifdef __FBBDOS__
      bt = get_ticker ();
#endif

#ifdef __LINUX__
      struct timeval tv;
      struct timezone tz;

      gettimeofday (&tv, &tz);

      bt = ((tv.tv_sec % 86400L) << 16) / 3600L;
      bt += ((tv.tv_usec / 1000) << 16) / 3600000L;

      if (bt > 0x17ffffL)
            bt = 0x17ffffL;
      bt += offset;
      while (bt < oldtime)
      {
            /* Le jour a change... */
            offset += 0x180000L;
            bt += 0x180000L;
      }

#endif
      oldtime = bt;
      return (bt);
}

void k_tasks (void)
{
      int port, hour, min;
      int min_arret;
      int i;
      long caltemps;
      Forward *pfwd;
      static long balprec[NBPORT];

      df ("k_tasks", 0);

#ifdef __FBBDOS__
      if (video_off == 3)
            blank_screen ();
#endif

      if (dde_wp_serv)
      {
            wp_server ();
      }

#ifdef __FBBDOS__
      test_kb ();
#endif

#ifdef __WIN32__
      CheckTasks ();
#endif

      if (aff_use == 0)
      {
            free_use ();
            aff_use = -1;
      }

      if (throute)
      {
            hupdate ();
      }

      if ((p_forward) && (!svoie[CONSOLE]->sta.connect))
      {
            maj_fwd ();
      }

      /* Horloge minutes */
      time (&caltemps);
      min = minute (caltemps);
      hour = heure (caltemps);

      if (time_bcl == 0)
      {
            aff_etat ('Y');
            broadcast_list ();
            time_bcl = def_time_bcl;
      }

      /* On force l'arret a H+15 */
      min_arret = min - stop_min;
      if (min_arret < 0)
            min_arret += 60;

      if ((save_fic) && ((!actif (0)) || (min_arret >= 15)))
      {
            if (min != stop_min)
            {
                  aff_etat ('Y');
                  maintenance ();         /* reboot serveur */
#ifdef __WINDOWS__
                  fbb_quit (type_sortie);
                  return;
#else
                  exit (type_sortie);
#endif
            }
      }

      for (port = 0; port < NBPORT; port++)
      {
            if (save_fic)
                  break;
            if (p_port[port].pvalid)
            {
                  pfwd = p_port[port].listfwd;
                  while (pfwd)
                  {
                        if (pfwd->forward == -1)
                        {
                              aff_etat ('F');
                              appel_fwd (pfwd, port);
                        }
                        pfwd = pfwd->suite;
                  }
            }
      }

      if (test_fichiers)
      {
            aff_etat ('Y');
            test_fichiers = 0;
            /* Test des fichiers systeme */
            init_bbs ();
            test_buf_fwd ();
            init_buf_swap ();
            init_buf_rej ();
            load_themes ();
            test_message = 2;
      }

      if ((caltemps / 60) != timeprec)
      {

            /* Toutes les minutes */

            aff_etat ('Y');
            timeprec = caltemps / 60;
            aff_nbsta ();
            ferme_log ();                 /* Flush du log toutes les minutes */
            if ((!editor) && (blank > 0))
            {
                  if (--blank == 0)
                        video_off = 3;
            }

            nb_error = 0;
            /* fflush (log_ptr); */
#ifdef __FBBDOS__

            {
                  /* Test des espaces disque */
                  struct dfree free;
                  int sdisk = 0;
                  long k_cluster;

                  if (DISK[1] == ':')
                  {
                        sdisk = DISK[0] - '@';
                        getdfree (sdisk, &free);
                  }
                  else
                  {
                        sdisk = getdisk () + 1;
                        getdfree (sdisk, &free);
                  }

                  k_cluster = ((long) free.df_sclus * (long) free.df_bsec) / 1024L;
                  sys_disk = free.df_avail * k_cluster;

                  if ((sdisk) && (MBIN[1] == ':') && (MBIN[0] != DISK[0]))
                  {
                        k_cluster = ((long) free.df_sclus * (long) free.df_bsec) / 1024L;
                        sdisk = MBIN[0] - '@';
                        getdfree (sdisk, &free);
                        tmp_disk = free.df_avail * k_cluster;
                  }
                  else
                        tmp_disk = sys_disk;
            }

            if (ch_fen)
            {
                  maj_fen ();
            }
#endif
            aff_date ();
            env_date ();
            init_bbs ();
            if (hour != hour_time)
            {
                  hour_time = hour;
                  cron (caltemps);
                  send_wp_mess ();
            }
            if ((hour == h_maint) && (min == 0))
            {
                  house_keeping ();
            }

#ifdef __WINDOWS__
            if (!WindowService ())
#endif
                  mail_in ();

            /*          if (p_forward == 0) test_buf_fwd();           */
            init_hold ();
            init_buf_swap ();
            init_buf_rej ();
            load_themes ();

            aff_msg_cons ();

            for (port = 0; port < NBPORT; port++)
            {
                  if (save_fic)
                        break;

                  if (!p_port[port].pvalid)
                        continue;

                  if (tst_minfwd (min, port))
                  {
                        for (i = 0; i < NBMASK; i++)
                              p_port[port].fwd[i] = '\0';
                        pfwd = p_port[port].listfwd;
                        while (pfwd)
                        {
                              if ((pfwd->forward == 0) && (ch_voie (port, 0) != -1))
                              {
                                    *pfwd->fwdbbs = '\0';
                                    pfwd->forward = -1;
                                    pfwd->fwdpos = 0;
                                    pfwd->fin_fwd = pfwd->cptif = pfwd->fwdlig = 0;
                                    pfwd->reverse = 0;
                              }
                              if (pfwd->forward == -1)
                              {
                                    if (pfwd->fwdpos == 0xffff)
                                          pfwd->forward = 0;
                                    else
                                    {
                                          aff_etat ('F');
                                          appel_fwd (pfwd, port);
                                    }
                              }
                              pfwd = pfwd->suite;
                        }
                  }
                  if (t_balise[port] == 0)
                        continue;
                  if (caltemps / t_balise[port] != balprec[port])
                  {
                        balprec[port] = caltemps / t_balise[port];
                        if (!arret)
                        {
                              send_balise (port);
                        }
                  }
            }
      }
      ff ();
}

static int extern_task (int voie)
{
      if ((svoie[voie]->niv1 == N_MOD) &&
       ((svoie[voie]->niv3 == XS_EXTERN) || (svoie[voie]->niv3 == XR_EXTERN)))
            return 1;
#ifdef __WINDOWS__
      if (editor_on ())
            return (1);
#endif
      return (0);
}

static int off_time (void)
{
      static long prec_time = 0L;
      long diff_time;

      df ("off_time", 0);

      if (prec_time == 0L)
            prec_time = time (NULL);

      diff_time = time (NULL) - prec_time;
      prec_time += diff_time;

      ff ();
      return ((int) diff_time);
}

int del_timer (FbbTimer * timer_id)
{
      FbbTimer *tt = timer_head;
      FbbTimer *pr = NULL;

      while (tt)
      {
            if (tt == timer_id)
            {
                  if (pr)
                  {
                        pr->next = tt->next;
                        m_libere (tt, sizeof (FbbTimer));
                  }
                  else
                  {
                        timer_head = tt->next;
                        m_libere (tt, sizeof (FbbTimer));
                  }
                  return (1);
            }
            pr = tt;
            tt = tt->next;
      }
      return (0);
}

FbbTimer *add_timer (int delay, int port, void FAR * fct, void *userdata)
{
      FbbTimer *tt = timer_head;

      if (tt)
      {
            while (tt->next)
                  tt = tt->next;
            tt->next = (FbbTimer *) m_alloue (sizeof (FbbTimer));
            tt = tt->next;
      }
      else
            tt = timer_head = (FbbTimer *) m_alloue (sizeof (FbbTimer));

      tt->next = NULL;
      tt->userdata = userdata;
      tt->port = port;
      tt->temps = (delay * 182) / 10;
      tt->fct = fct;

      return (tt);
}

static void fbb_timer (void)
{
      static long bprec = -1;
      long bt;
      FbbTimer *tt;
      FbbTimer *pr;
      long delta;

      bt = btime ();
      delta = bt - bprec;

      if (delta == 0)
            return;

      bprec = bt;

      tt = timer_head;
      pr = NULL;

      while (tt)
      {
            if (tt->temps >= (time_t) delta)
                  tt->temps -= (time_t) delta;
            else
                  tt->temps = 0L;

            if (tt->temps == 0L)
            {
                  if (tt->fct)
                        (*tt->fct) (tt->port, tt->userdata);

                  /* Supprimer le timer */
                  del_timer (tt);

                  break;

                  /*if (pr)
                     tt = pr->next;
                     else
                     tt = timer_head; */
            }
            else
            {
                  pr = tt;
                  tt = tt->next;
            }
      }
}

void user_time_out (void)
{
      int voie;
      int port;
      int com;
      int dt = off_time ();

      fbb_timer ();

      if (dt == 0)
            return;

      df ("user_time_out", 0);

      /* System timers */
      if (t_tell > 0)
      {
            t_tell -= (18 * dt);
            if (t_tell < 0)
                  t_tell = 0;
      }

      if (time_bcl > 0)
      {
            time_bcl -= (18 * dt);
            if (time_bcl < 0)
                  time_bcl = 0;
      }

      for (com = 0; com < NBPORT; com++)
      {
            if (p_com[com].baud)
                  p_com[com].delai += dt;
      }

      for (port = 0; port < NBPORT; port++)
      {
            if ((p_port[port].pvalid) && (p_port[port].stop > 0))
            {
                  if (p_port[port].stop > dt)
                        p_port[port].stop -= dt;
                  else
                        p_port[port].stop = 0;
            }
      }

      for (voie = 0; voie < NBVOIES; voie++)
      {
            if ((!extern_task (voie)) && (svoie[voie]->sta.connect) && ((voie != CONSOLE) || (!editor)))
            {
                  if (time_att[voie] > 0)
                  {
                        time_att[voie] -= dt;
                        if (time_att[voie] <= 0)
                        {
                              time_att[voie] = 0;
                              if (svoie[voie]->nb_err == 10)
                              {
                                    /* Voie bloquee -> Liberation d'office */
                                    svoie[voie]->deconnect = svoie[voie]->sta.connect = FALSE;
                                    svoie[voie]->niv1 = svoie[voie]->niv2 = svoie[voie]->niv3 = 0;
                              }
                              else
                              {
                                    svoie[voie]->deconnect = 2;
                                    svoie[voie]->nb_err = 10;
                                    traite_voie (voie);
                              }
                        }
                  }
                  if (time_yapp[voie] > 0)
                  {
                        time_yapp[voie] -= dt;
                        if (time_yapp[voie] < 0)
                              time_yapp[voie] = 0;
                  }
            }
      }
      ff ();
}

void mail_in (void)
{
      struct stat buf;

      if ((!is_room ()) || (svoie[INEXPORT]->sta.connect) || (inexport))
            return;

      df ("mail_in", 0);

      mail_ch = INEXPORT;

      /* if (access (MAILIN, 0) == 0) */
      if (stat (MAILIN, &buf) == 0)
      {
            init_etat ();
            selvoie (mail_ch);
            strcpy (pvoie->sta.indicatif.call, mycall);
            pvoie->sta.indicatif.num = 0;
            pvoie->enrcur = 0L;
            pvoie->mode = F_FOR;
            pvoie->fbb = 0;
            pvoie->mbl_ext = 0;
            pvoie->prot_fwd = FWD_MBL;
            pvoie->finf.lang = langue[0]->numlang;
            pvoie->ncur = &def_cur;
            pvoie->tstat = pvoie->debut = time (NULL);
            pvoie->tmach = 0L;
            strcpy (io_fich, MAILIN);
            pvoie->sta.connect = inexport = 4;  /* Apres console_on ! */
            aff_event (mail_ch, 1);
            maj_niv (N_MBL, 99, 0);
#ifdef __WINDOWS__
            window_connect (voiecur);
#endif
            aff_nbsta ();
      }
      ff ();
}


int mail_out (char *fichier)
{
      if ((svoie[INEXPORT]->sta.connect) || (inexport))
            return (0);

      df ("mail_out", 2);

      mail_ch = INEXPORT;

      selvoie (mail_ch);
      n_cpy (256, io_fich, strlwr(fichier));
      strcpy (pvoie->sta.indicatif.call, "MAIL");
      pvoie->sta.indicatif.num = 0;
      aff_event (mail_ch, 1);
      pvoie->sta.connect = inexport = 4;
      pvoie->enrcur = 0L;
      pvoie->tstat = pvoie->debut = time (NULL);
      pvoie->tmach = 0L;
      pvoie->mode = F_FOR | F_HIE | F_BID | F_MID;
      pvoie->finf.lang = langue[0]->numlang;
      pvoie->ncur = &def_cur;
      maj_niv (N_MBL, 98, 0);
#ifdef __WINDOWS__
      window_connect (voiecur);
#endif
      aff_nbsta ();
      ff ();
      return (1);
}


int voie_forward (int voie)
{
      int port;
      Forward *pfwd;

      df ("voie_forward", 1);

      if (voie != CONSOLE)
      {
            for (port = 1; port < NBPORT; port++)
            {
                  if (p_port[port].pvalid)
                  {
                        pfwd = p_port[port].listfwd;
                        while (pfwd)
                        {
                              if (pfwd->forward == voie)
                              {
                                    ff ();
                                    return (1);
                              }
                              pfwd = pfwd->suite;
                        }
                  }
            }
      }
      ff ();
      return (0);
}


int tst_minfwd (int min, int noport)
{
      int test = p_port[noport].min_fwd;
      int inc = 0;

      df ("tst_minfwd", 2);

      while (inc < 60)
      {
            if (test == min)
            {
                  ff ();
                  return (1);
            }
            inc += p_port[noport].per_fwd;
            test += p_port[noport].per_fwd;
            if (test >= 60)
                  test -= 60;
      }
      ff ();
      return (0);
}


indicat *get_indic (char *chaine)
{
      int c = 0;
      int nb = 0;
      char *ptr;
      static indicat indic;

      df ("get_indic", 2);

      ptr = indic.call;

      while (isalnum (*chaine))
      {
            *ptr++ = toupper (*chaine);
            ++chaine;
            if (++nb == 6)
                  break;
      }
      *ptr = '\0';

      if (*chaine++ == '-')
            c = atoi (chaine);
      indic.num = c;

      ff ();
      return (&indic);
}


void add_heard (int port, indicat * indic)
{
      int i;
      long date = 0x7fffffffL;
      Heard *pobs = NULL;
      Heard *pheard = p_port[port].heard;

      df ("add_heard", 3);

      for (i = 0; i < NBHEARD; i++)
      {
            if ((pheard->last) && (strcmp (pheard->indic.call, indic->call) == 0) && (pheard->indic.num == indic->num))
            {
                  pheard->last = time (NULL);
                  ++pheard->nb;
                  ff ();
                  return;
            }
            if (date > pheard->last)
            {
                  date = pheard->last;
                  pobs = pheard;
            }
            ++pheard;
      }
      pobs->indic = *indic;
      pobs->first = pobs->last = time (NULL);
      pobs->nb = 1;
      ff ();
}


static void tst_buf (int voie)
{
      df ("tst_buf", 0);
      if ((svoie[voie]->memoc <= MAXMEM / 2) && (svoie[voie]->sr_mem))
      {
            ptype = SN;
            if (debug_on)
            {
                  fprintf (debug_fptr, "Tst_buf : %d\n", svoie[voie]->memoc);
            }
            traite_voie (voie);
      }
      ff ();
}

static int nb_buf (int voie)
{
      int port = no_port (voie);
      int nb = (int) p_port[port].frame * 2;

      df ("nb_buf", 1);
      switch (p_port[port].typort)
      {
      case TYP_PK:
      case TYP_KAM:
            if (nb > 6)
                  nb = 6;
            break;
      case TYP_DED:
            if (svoie[voie]->sta.mem < 100)
                  nb /= 2;
            break;
      case TYP_FLX:
            /* if (svoie[voie]->sta.mem < 8)
               nb /= 2;
               if (nb > 7) */
            nb = 7;
            break;
      case TYP_BPQ:
            if (svoie[voie]->sta.mem < 60)
                  nb /= 2;
            break;
#ifdef __WIN32__
      case TYP_MOD:
            nb = 50;
            break;
#endif
      }

      ff ();
      return (nb);
}


int ack_suiv (int voie)
{
      int nblig, n_buf, vide = TRUE, retour = 0;
      int ch_status;
      int port = no_port (voie);
      stat_ch sta;                        /* Etat de la voie */
      stat_ch sta_new;              /* Etat de la voie */

      df ("ack_suiv", 1);
      ch_status = svoie[voie]->ch_status;

      sta_new = sta = svoie[voie]->sta;

#ifdef __WINDOWS__
      if (ETHER (no_port (voie)))
      {
            sta_new.ack = tcp_busy (voie);
            svoie[voie]->sta = sta_new;

            if (memcmp (&sta, &sta_new, sizeof (stat_ch)) != 0)
                  ch_status = 1;
      }
      else
#endif
      if (sta_drv (voie, TNCSTAT, &sta_new))
      {
            if (svoie[voie]->sta.ack != sta_new.ack)
                  ch_status = 1;

            if (svoie[voie]->sta.ret != sta_new.ret)
                  ch_status = 1;

            svoie[voie]->sta = sta_new;

            /*if (memcmp(&sta, &sta_new, sizeof(stat_ch)) != 0)
               ch_status = 1; */
      }

      if (svoie[voie]->outptr == NULL)
            svoie[voie]->aut_nc = 0;

      if (svoie[voie]->dde_int)
            interruption (voie);

      svoie[voie]->maxbuf = nb_buf (voie);

      if (voie == CONSOLE)
            svoie[voie]->sta.ack = 0;

      if (svoie[voie]->ask)
      {
            svoie[voie]->ask = 0L;
            traite_voie (voie);
      }

#ifdef  __LINUX__
      /* dprintf("bin = %d\n", svoie[voie]->binary); */
      if (svoie[voie]->binary == 2)
      {
#if 0
            /* Process en FORK */
            char buffer[300];
            int fd = svoie[voie]->to_xfbb[0];
            int nb;

            int old = fcntl (fd, F_GETFL, 0);

            (void) fcntl (fd, F_SETFL, old | O_NDELAY);
            do
            {
                  nb = read (fd, buffer, 300);
                  if (nb < 0)
                  {
                        perror ("read");
                        nb = 0;
                  }
                  if (nb)
                  {
                        int i;

                        dprintf ("Recu %d carac de rszs (fd = %d)\n", nb, fd);
                        for (i = 0; i < nb; i++)
                              dprintf ("%02x ", buffer[i] & 0xff);
                        dprintf ("\n");
                        selvoie (voie);
                        outs (buffer, nb);
                  }
                  if (svoie[voie]->memoc >= MAXMEM)
                  {
                        /* pvoie->sr_mem = TRUE; */
                        break;
                  }
            }
            while (nb > 0);
            (void) fcntl (fd, F_SETFL, old);
#endif
      }
#endif
      if ((svoie[voie]->sta.ack) || (svoie[voie]->outptr))
      {
            if (!svoie[voie]->sta.connect)
            {
                  clear_outbuf (voie);
                  svoie[voie]->sta.ack = 0;
            }
            else
            {
                  if ((svoie[voie]->stop) && ((nblig = lig_bufi (voie)) != 0))
                  {
                        trait_buf (voie);
                        if (nblig != lig_bufi (voie))
                              prog_more (voie);
                  }
                  if (!svoie[voie]->stop)
                  {
                        int aff_status = 1;

                        /* status(voie) ; */
                        if ((voie == CONSOLE) || (DEBUG) || (!p_port[port].pvalid))
                        {
                              n_buf = svoie[voie]->maxbuf;
                              while ((!svoie[voie]->stop) && (svoie[voie]->outptr) && (n_buf--))
                              {
                                    if (aff_status)
                                    {
                                          aff_etat ('K');
                                          aff_status = 0;
                                          init_timout (voie);
                                          ch_status = 1;
                                          vide = FALSE;
                                    }
                                    aff_etat ('E');
                                    send_buf (voie);
                                    tst_buf (voie);
                              }
                        }
                        else
                        {

                              int lettre = 0;

                              while ((!svoie[voie]->stop) &&
                                       (svoie[voie]->outptr) &&
                                       (svoie[voie]->sta.ack < svoie[voie]->maxbuf) &&
                                       (min_ok (voie)))
                              {
                                    if (lettre == 0)
                                    {
                                          lettre = aff_etat ('E');
                                    }
                                    if (aff_status)
                                    {
                                          aff_etat ('K');
                                          aff_status = 0;
                                          init_timout (voie);
                                          ch_status = 1;
                                          vide = FALSE;
                                    }

                                    if (send_buf (voie) == 0)
                                          break;

                                    tst_buf (voie);

                                    aff_etat (lettre);
                              }

                              /* Repasse le TNC en reception */
                              if ((svoie[voie]->seq == 0) && (svoie[voie]->pack) && (svoie[voie]->t_tr == 0) && (svoie[voie]->outptr == NULL))
                              {
                                    tor_stop (voie);
                                    svoie[voie]->pack = 0;
                              }

                        }
                  }
                  retour = 1;
            }
      }

      if (ch_status)
            status (voie);

      if (vide)
            aff_etat ('A');

      ff ();
      return (retour);
}


int inbuf_ok (int voie)
{
      df ("inbuf_ok", 1);

      nb_trait = 0;
      if (svoie[voie]->binary)
      {
            switch (svoie[voie]->niv1)
            {
            case N_YAPP:
            case N_FORW:
                  ff ();
                  return (inbuf_yapp (voie));
            case N_MOD:
                  ff ();
                  return (inbuf_xmodem (voie));
            case N_BIN:
            case N_XFWD:
                  ff ();
                  return (inbuf_bin (voie));
            }
      }
      else
      {
            if (((v_tell) && (v_tell == voie) && (t_tell == 0)) ||
                  ((svoie[voie]->inbuf.nblig) && (!svoie[voie]->outptr)) ||
                  (svoie[voie]->deconnect > 0))
            {
                  if ((svoie[voie]->sta.connect == 0) && (svoie[voie]->deconnect == 0))
                        clear_inbuf (voie);
                  ff ();
                  return (1);
            }
      }
      ff ();
      return (0);
}


int inbuf_bin (int voie)
{
      int nb;

      df ("inbuf_xmodem", 1);

      nb = svoie[voie]->inbuf.nbcar;

      if (svoie[voie]->enrcur + (long) nb > svoie[voie]->tailm)
            nb_trait = (int) (svoie[voie]->tailm - svoie[voie]->enrcur);
      else
            nb_trait = nb;

      if (nb_trait == 0)
      {
            ff ();
            return (0);
      }

      ff ();
      return (1);
}


int inbuf_xmodem (int voie)
{
      df ("inbuf_xmodem", 1);

      if ((nb_trait = svoie[voie]->inbuf.nbcar) == 0)
      {
            ff ();
            return (0);
      }

      ff ();
      return (1);
}


int inbuf_yapp (int voie)
{
      char *ptr;
      lbuf *bptr;
      int nb, fct, ext;

      df ("inbuf_yapp", 1);

      if ((nb = svoie[voie]->inbuf.nbcar) < 2)
      {
            if (time_yapp[voie] == 0)
            {
                  nb_trait = 0;
                  ptype = TM;
                  time_yapp[voie] = -1;
                  ff ();
                  return (1);
            }
            else
            {
                  ff ();
                  return (0);
            }
      }
      ptr = svoie[voie]->inbuf.tete->buffer + svoie[voie]->inbuf.nocar;
      fct = *ptr++ & 0xff;
      if ((svoie[voie]->inbuf.tete->lgbuf - svoie[voie]->inbuf.nocar) == 1)
      {
            if (svoie[voie]->inbuf.tete->suite == NULL)
            {
                  cprintf ("suite nul - nocar %d - lgbuf %d - nbcar %d c1 %d c2 %d %s\r\n\n\n",
                               svoie[voie]->inbuf.nocar,
                               svoie[voie]->inbuf.tete->lgbuf,
                               svoie[voie]->inbuf.nbcar,
                               *(ptr - 2) & 0xff, *(ptr - 1) & 0xff,
                               svoie[voie]->sta.indicatif.call);
            }
            if (svoie[voie]->inbuf.tete->suite->buffer == NULL)
            {
                  cprintf ("buffer nul - nocar %d - lgbuf %d - nbcar %d c1 %d c2 %d %s\r\n\n\n",
                               svoie[voie]->inbuf.nocar,
                               svoie[voie]->inbuf.tete->lgbuf,
                               svoie[voie]->inbuf.nbcar,
                               *(ptr - 2) & 0xff, *(ptr - 1) & 0xff,
                               svoie[voie]->sta.indicatif.call);
            }
            ext = *(svoie[voie]->inbuf.tete->suite->buffer) & 0xff;
      }
      else
            ext = *ptr & 0xff;
      ptype = UK;
      switch (fct)
      {
      case ACK:
            nb_trait = 2;
            switch (ext)
            {
            case 1:
                  ptype = RR;
                  svoie[voie]->time_trans = time (NULL);
                  break;
            case 2:
                  ptype = RF;
                  svoie[voie]->time_trans = time (NULL);
                  svoie[voie]->type_yapp = 0;
                  break;
            case 3:
                  ptype = AF;
                  break;
            case 4:
                  ptype = AT;
                  break;
            case 5:
                  ptype = CA;
                  break;
            case ACK:
                  ptype = RF;
                  svoie[voie]->type_yapp = 1;
                  break;
            }
            break;
      case ENQ:
            nb_trait = 2;
            switch (ext)
            {
            case 1:
                  ptype = SI;
                  break;
            case 2:
                  ptype = RI;
                  break;
            }
            break;
      case SOH:
            nb_trait = (int) ext + 2;
            ptype = HD;
            break;
      case STX:
            nb_trait = (ext) ? (int) ext + 2 : 258;
            if (svoie[voie]->type_yapp)
                  ++nb_trait;
            ptype = DT;
            break;
      case ETX:
            nb_trait = 2;
            if (ext == 1)
                  ptype = EF;
            break;
      case EOT:
            nb_trait = 2;
            /*if (ext == 1) */ ptype = ET;
            break;
      case NAK:
            nb_trait = ext + 2;
            ptype = NR;
            break;
      case CAN:
            nb_trait = ext + 2;
            ptype = CN;
            break;
      case DLE:
            nb_trait = ext + 2;
            ptype = TX;
            break;
      default:
            --svoie[voie]->inbuf.nbcar;
            if (++svoie[voie]->inbuf.nocar == svoie[voie]->inbuf.tete->lgbuf)
            {
                  bptr = svoie[voie]->inbuf.tete->suite;
                  /* svoie[voie]->memoc -= svoie[voie]->inbuf.tete->lgbuf ; */
                  m_libere ((char *) svoie[voie]->inbuf.tete->buffer, svoie[voie]->inbuf.tete->lgbuf);
                  m_libere ((char *) svoie[voie]->inbuf.tete, sizeof (lbuf));
                  svoie[voie]->inbuf.tete = bptr;
                  svoie[voie]->inbuf.nocar = 0;
            }
            nb_trait = 0;
            ff ();
            return (0);
      }

      if (nb < nb_trait)
      {
            if (time_yapp[voie] == 0)
            {
                  nb_trait = 0;
                  ptype = TM;
                  time_yapp[voie] = -1;
                  ff ();
                  return (1);
            }
            ff ();
            return (0);
      }

      if (svoie[voie]->kiss == -2)
            init_timout (CONSOLE);

      if (ptype == TX)
      {
            trait_buf (voie);
            out_txt ();
            ff ();
            return (0);
      }

      ff ();
      return (1);
}


/*
 * Recopie dans data une ligne d'un max de 300 caracteres a traiter et
 * retourne le nb de caracteres a traiter
 */

int trait_buf (int voie)
{
      char *ptri;
      char *ptro = data;
      lbuf *bptr;
      int c, nb, nbtot, fin;
      FScreen *screen = &conbuf;

      df ("trait_buf", 1);

      fin = nbtot = 0;

      if ((svoie[voie]->binary) && (nb_trait == 0))
      {
            ff ();
            return (0);
      }

      while ((!fin) && (svoie[voie]->inbuf.tete))
      {
            ptri = svoie[voie]->inbuf.tete->buffer + svoie[voie]->inbuf.nocar;
            /* recopie buffer dans buffer de datas */
            nb = svoie[voie]->inbuf.tete->lgbuf - svoie[voie]->inbuf.nocar;
            while (nb)
            {
                  c = *ptri++;
                  --svoie[voie]->inbuf.nbcar;
                  ++svoie[voie]->inbuf.nocar;
                  nb--;
                  if ((svoie[voie]->binary) || (c != '\n'))
                  {
                        *ptro++ = c;
                        ++nbtot;
                        if (svoie[voie]->binary)
                        {
                              if (c == '\r')
                                    --svoie[voie]->inbuf.nblig;
                              if (--nb_trait == 0)
                              {
                                    fin = 1;
                                    break;
                              }
                        }
                        else
                        {
                              if (c == '\r')
                              {                 /* Sortie si fin de ligne */
                                    --svoie[voie]->inbuf.nblig;
                                    fin = 1;
                                    if ((voie == CONSOLE) && (screen->totlig))
                                    {
                                          data[nbtot] = '\0';
#ifdef __FBBDOS__
                                          inputs (CONSOLE, W_CNST, data);
#endif
                                    }
                                    break;
                              }
                        }
                        if (nbtot == DATABUF)
                        {
                              fin = 1;
                              break;
                        }
                  }
            }
            if (nb == 0)
            {
                  bptr = svoie[voie]->inbuf.tete->suite;
                  /* svoie[voie]->memoc -= svoie[voie]->inbuf.tete->lgbuf ;      */
                  m_libere ((char *) svoie[voie]->inbuf.tete->buffer, svoie[voie]->inbuf.tete->lgbuf);
                  m_libere ((char *) svoie[voie]->inbuf.tete, sizeof (lbuf));
                  svoie[voie]->inbuf.tete = bptr;
                  svoie[voie]->inbuf.nocar = 0;
            }
      }
      *ptro = '\0';

      ff ();
      return (nbtot);
}

void traite_voie (int voie)
{
      /* char *ptr = s ; */
      int nbuf, mode;
      long debtrait;

      df ("traite_voie", 1);
      aff_etat ('T');
      selvoie (voie);

      init_timout (voie);
      if (pvoie->sta.connect)
            init_langue (voie);
      status (voie);
      if ((voie == INEXPORT) && (inexport))
      {
            aff_traite (voiecur, TRUE);
            time (&debtrait);
            premier_niveau ();
            pvoie->tmach += time (NULL) - debtrait;
            aff_traite (voiecur, FALSE);
            vlang = 0;
            free_mem ();
            ff ();
            return;
      }
      if (pvoie->deconnect)
            clear_inbuf (voie);
      if (tot_mem > 5000L)
      {
            if ((!pvoie->binary) && (!svoie[CONSOLE]->sta.connect))
            {
                  aff_header (voie);
            }
            if ((!pvoie->deconnect) && (pvoie->sta.connect) && (voie >= 0) && (voie < NBVOIES))
            {
                  if ((!pvoie->seq) && (!pvoie->sr_mem))
                        prog_more (voie);
                  if (!pvoie->stop)
                  {
                        if ((!pvoie->sr_mem) && (!pvoie->seq))
                        {
                              nb_trait = trait_buf (voie);
                        }
                        else
                              nb_trait = 0;
                        if (aff_ok(voiecur))
                        {
                              deb_io ();
                              aff_bas (voiecur, W_RCVT, data, nb_trait);
                              fin_io ();
                        }
                        aff_traite (voiecur, TRUE);
                        time (&debtrait);
                        if ((voie == CONSOLE) && (print))
                        {
#if defined(__WINDOWS__) || defined(__LINUX__)
                              SpoolLine (voie, W_RCVT, data, strlen (data));
#else
                              fputs (data, file_prn);
                              if (data[nb_trait - 1] == '\r')
                                    fputc ('\n', file_prn);
#endif
                        }
                        if (pvoie->dde_marche)
                              en_navant_toute ();
                        else
                        {
                              indd = data;
                              pvoie->t_tr = 1;
#ifdef COMPUTE
                              deb_compute ();
#endif
                              premier_niveau ();
#ifdef COMPUTE
                              end_compute ();
#endif
                              pvoie->t_tr = 0;
                              data[0] = '\0';
                              nbuf = pvoie->maxbuf;
                              while ((nbuf-- > 0) &&
                                       (pvoie->sta.ack < 4) &&
                                       (pvoie->outptr) &&
                                       (min_ok (voie)))
                              {
                                    send_buf (voie);
                              }

                        }
                        pvoie->tmach += time (NULL) - debtrait;
                        aff_traite (voiecur, FALSE);
                  }

                  /* Repasse le TNC en reception */
                  if ((pvoie->seq == 0) && (pvoie->pack) && (pvoie->t_tr == 0) && (pvoie->outptr == NULL))
                  {
                        tor_stop (voiecur);
                        pvoie->pack = 0;
                  }

            }
      }
      if (pvoie->deconnect > 0)
      {
            switch (pvoie->deconnect)
            {
            case 1:
                  if ((!voie_forward (voie)) &&
                        (voie != CONSOLE) &&
                        (!P_GUEST (voie)) &&
                  /*                  (EXP(pvoie->finf.flags) == 0) && */
                        (BBS (pvoie->finf.flags) == 0) &&
                        (FOR (pvoie->mode) == 0)
                        )
                  {
                        texte (T_MES + 12);
                        aff_etat ('E');
                        send_buf (voie);
                  }
                  fbb_log (voiecur, 'X', "B");
                  pvoie->log = 0;
                  if (pvoie->deconnect == 1)
                        mode = bpq_deconnect;
                  else
                        mode = 1;
                  deconnexion (voie, mode);
                  break;
            case 2:
                  texte (T_ERR + 31);
                  aff_etat ('E');
                  send_buf (voie);
                  fbb_log (voiecur, 'X', "T");
                  pvoie->log = 0;
                  force_deconnexion (voie, 1);
                  break;
            case 3:
                  fbb_log (voiecur, 'X', "F");
                  pvoie->log = 0;
                  force_deconnexion (voie, 1);
                  break;
            case 4:
                  fbb_log (voiecur, 'X', "M");
                  pvoie->log = 0;
                  force_deconnexion (voie, 1);
                  break;
            case 5:
                  fbb_log (voiecur, 'X', "P");
                  pvoie->log = 0;
                  force_deconnexion (voie, 1);
                  break;
            case 6:
                  fbb_log (voiecur, 'X', "B");
                  pvoie->log = 0;
                  if (pvoie->deconnect == 1)
                        mode = bpq_deconnect;
                  else
                        mode = 1;
                  deconnexion (voie, mode);
                  break;
            case 7:
                  outln ("Sorry, no more channels available", 33);
                  aff_etat ('E');
                  send_buf (voie);
                  pvoie->log = 0;
                  force_deconnexion (voie, 1);
                  break;
            default:
                  fbb_log (voiecur, 'X', "?");
                  pvoie->log = 0;
                  force_deconnexion (voie, 1);
                  break;
            }
            pvoie->deconnect = -1;
      }
      vlang = 0;
      free_mem ();
      aff_etat ('A');
      ff ();
}


void premier_niveau (void)
{
      df ("premier_niveau", 0);

      /* Task identifier */
      ++tid;

      switch (pvoie->niv1)
      {
      case N_MENU:
            menu_principal ();
            break;
#ifndef MINISERV
      case N_QRA:
            qraloc ();
            break;
      case N_STAT:
            statistiques ();
            break;
      case N_INFO:
            documentations ();
            break;
      case N_NOMC:
            nomenclature ();
            break;
      case N_TRAJ:
            trajec ();
            break;
#endif
      case N_DOS:
            dos ();
            break;
      case N_MOD:
            modem ();
            break;
      case N_BIN:
            bin_transfer ();
            break;
      case N_MBL:
            mbl_emul ();
            break;
      case N_FORW:
            fwd ();
            break;
      case N_TELL:
            duplex_tnc ();
            break;
      case N_YAPP:
            yapp ();
            break;
      case N_CONF:
            conference ();
            break;
      case N_RBIN:
            send_bin_message ();
            break;
      case N_THEMES:
            themes ();
            break;
      case N_XFWD:
            xfwd ();
            break;
      default:
            fbb_error (ERR_NIVEAU, "KERNEL", pvoie->niv1);
            break;
      }
      ff ();
}

Generated by  Doxygen 1.6.0   Back to index