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

xmodem.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.
    ****************************************************************/

/*
 *    MODULE X, Y, ZMODEM
 */

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

#ifdef __LINUX__
#include <signal.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <termios.h>
#endif

#ifdef __WINDOWS__
char *xmodem_str (int voie, char *s)
{
#define XMODLEN 44
      static char stdesc[10][11] =
      {
            "SendInit  ",
            "SendData  ",
            "SendData  ",
            "SendEof   ",
            "RcvInit   ",
            "RcvLabel  ",
            "RcvData   ",
            "RcvEnd    ",
            "XmodmAbort",
            "ZsInit    "
      };

      static char xmod_name[4][5] =
      {"Xmod", "Xm1K", "Ymod", "Zmod"};
      char taille[40];
      int n;
      int niv = svoie[voie]->niv3;
      long offset = svoie[voie]->enrcur;

      if (offset < 0L)
            offset = 0L;

      *s = '\0';
      if ((niv >= 0) && (niv < 10))
      {
            if (svoie[voie]->tailm)
            {
                  sprintf (taille, "/%ld", svoie[voie]->tailm);
            }
            else
            {
                  *taille = '\0';
            }
            sprintf (s, "%s:%s %s %ld%s",
                         xmod_name[svoie[voie]->type_yapp],
                         stdesc[niv], svoie[voie]->appendf,
                         offset, taille);
      }
      return (s);
}
#else
static void aff_xmodem (int ok)
{
#define XMODLEN 44
      static char stdesc[10][11] =
      {
            "SendInit  ",
            "SendData  ",
            "SendData  ",
            "SendEof   ",
            "RcvInit   ",
            "RcvLabel  ",
            "RcvData   ",
            "RcvEnd    ",
            "XmodmAbort",
            "ZsInit    "
      };

      static char xmod_name[4][5] =
      {"Xmod", "Xm1K", "Ymod", "Zmod"};
      char s[80];
      char taille[40];
      int n;
      int niv = pvoie->niv3;
      long offset = pvoie->enrcur;

      if (offset < 0L)
            offset = 0L;

      *s = '\0';
      if (ok)
      {
            if ((niv >= 0) && (niv < 10))
            {
                  if (pvoie->tailm)
                  {
                        sprintf (taille, "/%ld", pvoie->tailm);
                  }
                  else
                  {
                        *taille = '\0';
                  }
                  sprintf (s, "%s:%s %s %ld%s",
                               xmod_name[pvoie->type_yapp],
                               stdesc[niv], pvoie->appendf,
                               offset, taille);
            }
      }
      for (n = strlen (s); n < XMODLEN; n++)
            s[n] = ' ';
      s[XMODLEN] = '\0';
      aff_chaine (W_DEFL, 17, 3, s);
}
#endif

void display_dsz_perf (int voie)
{
      int save_voie;
      FILE *fptr;
      long lg_file;
      Ylist *temp;
      Ylist *yptr;
      char ligne[256];

      selvoie (voie);

      cr ();

      pvoie->size_trans = 0L;

      fptr = fopen (svoie[voie]->ch_temp, "rt");
      if (fptr == NULL)
            return;

      yptr = svoie[voie]->ytete;
      while (yptr)
      {
            char tmp1[80];
            char tmp2[80];
            char tmp3[80];

            temp = yptr;
            strcpy (svoie[voie]->appendf, yptr->filename);
            fgets (ligne, sizeof (ligne), fptr);
            WinDebug ("Res -> %s\r\n", ligne);
            sscanf (ligne, "%s %s %s %s %s",
                        tmp1, varx[0], tmp2, tmp3, varx[1]);
            lg_file = atol (varx[0]);
            pvoie->size_trans += lg_file;

            if (pvoie->kiss == -2)
            {
                  save_voie = voiecur;
                  selvoie (CONSOLE);
                  texte (T_DOS + 5);
                  selvoie (save_voie);
            }
            else
                  texte (T_DOS + 5);

            yptr = yptr->next;
            m_libere (temp, sizeof (Ylist));
      }
      svoie[voie]->ytete = NULL;

      fclose (fptr);
      unlink (svoie[voie]->ch_temp);
      sprintf (ligne, "%sDSZFIL.%d", MBINDIR, voiecur);
      unlink (ligne);
}

void xmodem_mode (int mode, int voie)
{
#ifdef __FBBDOS__
      RSEGS rsegs;
      int port = no_port (voie);

      memset (&rsegs, 0, sizeof (RSEGS));
      rsegs.DX = (int) p_port[port].ccom - 1;
      rsegs.AX = 0x0e00 | (mode & 0xff);
      int14real (&rsegs);
#endif
}


static void zmodem_tx_on (int voie, int type, int lg)
{
#ifdef __FBBDOS__
      RSEGS rsegs;
      int port = no_port (voie);

      memset (&rsegs, 0, sizeof (RSEGS));
      rsegs.DX = (int) p_port[port].ccom - 1;
      rsegs.AX = 0x0e00 | ((type) ? 0x9 : 0x8);
      rsegs.CX = lg;
      int14real (&rsegs);
#endif
}


void get_zrpos (int voie)
{
#ifdef __FBBDOS__
      RSEGS rsegs;
      int port = no_port (voie);
      char str[80];

      selvoie (voie);
      memset (&rsegs, 0, sizeof (RSEGS));
      rsegs.DX = (int) p_port[port].ccom - 1;
      rsegs.AX = 0x0e0a;
      rsegs.BX = 0x00;
      int14real (&rsegs);

      svoie[voie]->enrcur = (((long) rsegs.BX) << 16) | (((long) rsegs.AX) & 0xffff);

      if (svoie[voie]->enrcur)
      {
            sprintf (str, "ZRPOS to %ld\r", svoie[voie]->enrcur);
            aff_bas (voie, W_RCVT, str, strlen (str));
      }

      clear_outbuf (voie);
      svoie[voie]->stop = 0;
      ch_niv3 (XS_SEND);
      xmodem ();
#endif
}


static char *ymodem_header (int voie, long date, int *lg)
{
      static char ybuf[128];
      char *ptr;
      int len = 0;

      memset (ybuf, 0, 128);

      strcpy (ybuf, svoie[voie]->appendf);

      ptr = ybuf;
      while (*ptr)
      {
            ++ptr;
            ++len;
      }
      ++ptr;
      ++len;
      sprintf (ptr, "%ld %lo ", svoie[voie]->tailm, date);
      *lg = strlen (ptr) + len + 1;

      return (ybuf);
}

void libere_ymodem (int voie, int display)
{
      Ylist *yptr, *temp;

      yptr = svoie[voie]->ytete;

      while (yptr)
      {
            temp = yptr;
            if ((display) && (yptr->ok == 1))
            {
                  svoie[voie]->size_trans = temp->size_trans;
                  svoie[voie]->time_trans = temp->time_trans;
                  strcpy (svoie[voie]->appendf, temp->filename);
                  display_perf (voie);
            }
            yptr = yptr->next;
            m_libere (temp, sizeof (Ylist));
      }

      svoie[voie]->ytete = NULL;
}

static int ymodem_files (void)
{
      int nb = 0;
      Ylist *yptr;
      struct stat bufstat;

      libere_ymodem (voiecur, 0);

      yptr = pvoie->ytete;

      strtok (indd, " \r");

      indd[40] = '\0';

      if ((indd = strtok (NULL, " \r")) == NULL)
      {
            texte (T_ERR + 20);
            retour_appel ();
            return (0);
      }

      do
      {

            if ((tst_point (indd)) &&
                  (stat (nom_yapp (), &bufstat) != -1) &&
                  ((bufstat.st_mode & S_IFREG) != 0))
            {
                  if (yptr)
                  {
                        yptr->next = (Ylist *) m_alloue (sizeof (Ylist));
                        yptr = yptr->next;
                  }
                  else
                  {
                        pvoie->ytete = yptr = (Ylist *) m_alloue (sizeof (Ylist));
                  }
                  n_cpy (255, yptr->filename, pvoie->appendf);
                  ++nb;
            }
            else
                  texte (T_ERR + 11);

      }
      while ((indd = strtok (NULL, " \r")) != NULL);

      yptr = pvoie->ytete;
      if (yptr)
      {
            *pvoie->appendf = '\0';
            while (yptr)
            {
                  strcat (pvoie->appendf, yptr->filename);
                  yptr = yptr->next;
                  if (yptr)
                        strcat (pvoie->appendf, " ");
            }
            texte (T_YAP + 0);
            aff_etat ('E');
            send_buf (voiecur);
            sleep_ (1);
      }
      else
      {
            retour_appel ();
      }
      return (nb);
}

static void zmodem_init (void)
{
      static char zrqinit[25] = "rz\r**\030B00000000000000\r\n\021";

      md_no_echo (voiecur);
      outs (zrqinit, strlen (zrqinit));
      ch_niv3 (ZS_FILE);
}

static int zmodem_tx (int voie)
{
      int lg;
      int retour = 0;
      struct stat bufstat;
      Ylist *yptr;
      char *ptr;


      yptr = svoie[voie]->ytete;

      while ((yptr) && (yptr->ok))
            yptr = yptr->next;

      while ((retour == 0) && (yptr))
      {

            indd = yptr->filename;

            if ((tst_point (indd)) && (stat (nom_yapp (), &bufstat) != -1) &&
                  ((bufstat.st_mode & S_IFREG) != 0))
            {
                  while (!modem_vide (voie))
                        ;
                  sleep_ (1);
                  pvoie->enrcur = -1L;
                  pvoie->tailm = file_size (pvoie->sr_fic);
                  set_binary (voiecur, 1);
                  pvoie->xferok = 1;
                  pvoie->size_trans = 0L;
                  pvoie->time_trans = 0L;
                  prog_more (voie);
                  ptr = ymodem_header (voie, bufstat.st_ctime, &lg);
                  zmodem_tx_on (voie, (yptr->next != NULL), lg);
                  outs (ptr, lg);
                  svoie[voie]->stop = 0;
                  ch_niv3 (XS_WAIT);
                  retour = 1;
            }
            else
            {
                  yptr->ok = -1;
                  yptr = yptr->next;
            }
      }
      return (retour);
}


static int ymodem_tx (int voie)
{
      int lg;
      int retour = 0;
      struct stat bufstat;
      Ylist *yptr;
      char *ptr;


      yptr = svoie[voie]->ytete;

      while ((yptr) && (yptr->ok))
            yptr = yptr->next;

      while ((retour == 0) && (yptr))
      {

            indd = yptr->filename;

            if ((tst_point (indd)) && (stat (nom_yapp (), &bufstat) != -1) &&
                  ((bufstat.st_mode & S_IFREG) != 0))
            {
                  while (!modem_vide (voie))
                        ;
                  sleep_ (1);
                  pvoie->enrcur = 0L;
                  pvoie->tailm = file_size (pvoie->sr_fic);
                  set_binary (voiecur, 1);
                  pvoie->xferok = 1;
                  pvoie->size_trans = 0L;
                  pvoie->time_trans = 0L;
                  prog_more (voie);
                  ptr = ymodem_header (voie, bufstat.st_ctime, &lg);
                  ymodem_tx_on (voie, (yptr->next != NULL));
                  outs (ptr, 128);
                  if (senddata (1))
                  {
                        ch_niv3 (XS_QUEUE);
                  }
                  else
                        ch_niv3 (XS_SEND);
                  retour = 1;
            }
            else
            {
                  yptr->ok = -1;
                  yptr = yptr->next;
            }
      }
      return (retour);
}


#ifdef __FBBDOS__
static int xmodem_tx (int voie)
{
      int retour = 0;
      struct stat bufstat;
      char *ptr;

      strtok (indd, " \r");
      if ((indd = strtok (NULL, " \r")) == NULL)
      {
            texte (T_ERR + 20);
            retour_appel ();
      }
      else if ((tst_point (indd)) && (stat (nom_yapp (), &bufstat) != -1) &&
                   ((bufstat.st_mode & S_IFREG) != 0))
      {
            texte (T_YAP + 0);
            aff_etat ('E');
            send_buf (voie);
            while (!modem_vide (voie))
                  ;
            sleep_ (1);
            pvoie->enrcur = 0L;
            if ((ptr = strtok (NULL, " \r")) != NULL)
                  pvoie->enrcur = atol (ptr);
            pvoie->tailm = file_size (pvoie->sr_fic);
            set_binary (voiecur, 1);
            pvoie->xferok = 1;
            pvoie->size_trans = 0L;
            pvoie->time_trans = 0L;
            prog_more (voie);
            switch (pvoie->type_yapp)
            {
            case 0:
                  xmodem_tx_on (voie);
                  break;
            case 1:
                  xmodem_tx_1k (voie);
                  break;
            }
            if (senddata (1))
            {
                  ch_niv3 (XS_QUEUE);
            }
            else
                  ch_niv3 (XS_SEND);
            retour = 1;
      }
      else
      {
            texte (T_ERR + 11);
            retour_appel ();
      }
      return (retour);
}
#endif


static int xmodem_rx (int voie)
{
      int fd;
      int retour = 0;
      struct stat bufstat;

      strtok (indd, " \r");

      if (read_only ())
            retour_appel ();
      else if ((indd = strtok (NULL, " \r")) == NULL)
      {
            texte (T_ERR + 20);
            retour_appel ();
      }
      else if ((tst_point (indd)) && (stat (nom_yapp (), &bufstat) == -1))
      {
            fd = open (svoie[voie]->sr_fic, O_CREAT | O_WRONLY | O_TRUNC, S_IREAD | S_IWRITE);
            if (fd > 0)
            {
                  close (fd);
                  unlink (svoie[voie]->sr_fic);
                  pvoie->ytete = (Ylist *) m_alloue (sizeof (Ylist));
                  n_cpy (255, pvoie->ytete->filename, pvoie->appendf);

                  texte (T_YAP + 3);
                  ch_niv3 (XR_LABL);
                  del_temp (voie);
                  pvoie->enrcur = 0L;
                  pvoie->tailm = 0L;
                  pvoie->size_trans = 0L;
                  pvoie->time_trans = time (NULL);
                  retour = 1;
            }
            else
            {
                  texte (T_ERR + 30);
                  retour_appel ();
            }
      }
      else
      {
            texte (T_ERR + 23);
            retour_appel ();
      }
      return (retour);
}

#define hex(d) ((d > '9') ? d-55 : d-48)

static int gethex (void)
{
      int val = 0;

      val = (int) (hex (*indd)) << 4;
      ++indd;
      val += (int) (hex (*indd));
      ++indd;

      return (val);
}

static int ztyp_header (long *f)
{
      long fl = 0L;
      int type = ZFERR;
      int i;

      while ((*indd) && (*indd != '*'))
            ++indd;

      if (*indd)
      {
            while (*indd == '*')
                  ++indd;
            if (*indd == 24)
                  ++indd;
            if (*indd == 'B')
            {
                  ++indd;
                  type = gethex ();
                  for (i = 0; i < 4; i++)
                  {
                        fl <<= 8;
                        fl += gethex ();
                  }
            }
      }
      *f = fl;
      return (type);
}

#ifdef __LINUX__

void m_flush (int fd)
{
      ioctl (fd, TCFLSH, TCOFLUSH);
}

void kill_rzsz (int voie)
{
      if (svoie[voiecur]->rzsz_pid != -1)
      {
            kill (svoie[voie]->rzsz_pid, SIGTERM);
      }
}

static void sig_child (int sig)
{
      int ret;
      int pid;
      int voie;
      int status;

      pid = wait (&status);
      ret = WEXITSTATUS (status);

      for (voie = 0; voie < NBVOIES; voie++)
      {
            if (svoie[voie]->rzsz_pid == pid)
            {
                  svoie[voie]->rzsz_pid = -1;
                  svoie[voie]->ask = 1;
                  break;
            }
      }
      signal (SIGCHLD, sig_child);
}

int run_rzsz (int voie, char *cmde)
{
      char *args[128];
      struct termios tty;
      defcom *ptrcom = &p_com[(int)p_port[no_port (voie)].ccom];
      int n;

      printf ("Commande = <%s>\n", cmde);

      set_binary (voie, 2);
      signal (SIGPIPE, SIG_IGN);
      signal (SIGCHLD, sig_child);

      /* Serial port in binary raw mode */
      tcgetattr (ptrcom->comfd, &tty);
      tty.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC |
                               IXANY | IXON | IXOFF | INPCK | ISTRIP);
      tty.c_iflag |= (BRKINT | IGNPAR);
      tty.c_oflag &= ~OPOST;
      tty.c_lflag = ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK);
      tcsetattr (ptrcom->comfd, TCSANOW, &tty);

      /* pipe(svoie[voie]->to_xfbb); */
      /* pipe(svoie[voie]->to_rzsz); */

      switch (svoie[voie]->rzsz_pid = fork ())
      {
      case -1:
            return (0);
      case 0:                             /* Child */
            dup2 (ptrcom->comfd, 0);
            dup2 (ptrcom->comfd, 1);
            for (n = 1; n < NSIG; n++)
                  signal (n, SIG_DFL);

            n = 0;
            args[n] = strtok (cmde, " ");
            while (args[n])
            {
                  if (n == 127)
                  {
                        args[n] = NULL;
                        break;
                  }
                  args[++n] = strtok (NULL, " ");
            }

            (void) execvp (args[0], args);
            printf ("Exec %s failed\n", args[0]);
            exit (1);

      default:                            /* Parent */
            break;
      }
      return (1);
}
#endif

void xmodem (void)
{
      long f;
      int ok = 1;
      int ncars;
      obuf *msgtemp;
      char *ptcur;
      char *ptr;
      Ylist *yptr;

      switch (pvoie->type_yapp)
      {
      case 0:
            var_cpy (0, "XMODEM");
            break;
      case 1:
            var_cpy (0, "1K-XMODEM");
            break;
      case 2:
            var_cpy (0, "YMODEM");
            break;
      case 3:
            var_cpy (0, "ZMODEM");
            break;
      }

      switch (pvoie->niv3)
      {
      case XS_EXTERN:

            /* Infos pour statistiques */
            pvoie->time_trans = time (NULL) - pvoie->time_trans;
            pvoie->finf.download += (int) (pvoie->size_trans / 1024L);

#ifdef __LINUX__
            /* Attend le vidage de la queue */
            set_binary (voiecur, 0);

            ioctl (p_com[(int)p_port[no_port (voiecur)].ccom].comfd, TCFLSH, 2);

            /* Reinitialise le port */
            init_modem (no_port (voiecur));

            clear_inbuf (voiecur);

#else
            /* Reeinitialisation du modem */
#ifdef __WIN32__
            {
                  int val = 0;

                  sta_drv (voiecur, SUSPCMD, &val);
            }
#else
            init_modem (no_port (voiecur));
#endif
#endif

            aff_header (voiecur);
            display_dsz_perf (voiecur);

            pvoie->finf.download += (int) (pvoie->size_trans / 1024L);

            retour_appel ();
            break;

      case XS_INIT:
            switch (pvoie->type_yapp)
            {
            case 0:
            case 1:
#ifdef __LINUX__
                  if (BIOS (no_port (voiecur)) == P_LINUX)
                  {
                        if (ymodem_files ())
                        {
                              /* Runs DSZ or equivalent */
                              char cmde[1024];
                              int ok_send = 0;

                              if (pvoie->type_yapp == 0)
                                    sprintf (cmde, "fbb_zm sx ");
                              else
                                    sprintf (cmde, "fbb_zm sx -k ");

                              yptr = svoie[voiecur]->ytete;
                              while (yptr)
                              {
                                    strcat (cmde, " ");
                                    indd = yptr->filename;
                                    strcat (cmde, back2slash (nom_yapp ()));
                                    yptr = yptr->next;
                                    ok_send = 1;
                                    break;
                              }

                              /* Execute la commande en tache de fond */
                              ok = 0;
                              if (ok_send)
                              {
                                    pvoie->sta.ack = 0;

                                    /* Attend le vidage de la queue */
                                    while (!modem_vide (voiecur));
                                    sleep (1);

                                    if (run_rzsz (voiecur, cmde))
                                    {
                                          pvoie->xferok = 1;
                                          pvoie->size_trans = 0L;
                                          pvoie->time_trans = 0L;
                                          prog_more (voiecur);
                                          ch_niv3 (XS_EXTERN);
                                          ok = 1;
                                    }
                              }
                        }
                  }
#endif
#ifdef __WINDOWS__
                  if (BIOS (no_port (voiecur)) == P_WINDOWS)
                  {
#ifdef __WIN32__
                        if (ymodem_files ())
                        {
                              /* Runs DSZ or equivalent */
                              char cmde[256];
                              int ok_send = 0;

                              sprintf (pvoie->ch_temp, "%sDSZLOG.%d", MBIN, voiecur);

                              if (pvoie->type_yapp == 0)
                                    sprintf (cmde, "sx -g %s", pvoie->ch_temp);
                              else
                                    sprintf (cmde, "sx -k -g %s", pvoie->ch_temp);

                              yptr = svoie[voiecur]->ytete;
                              while (yptr)
                              {
                                    strcat (cmde, " ");
                                    indd = yptr->filename;
                                    strcat (cmde, nom_yapp ());
                                    yptr = yptr->next;
                                    ok_send = 1;
                                    break;      /* Only 1 file with XModem */

                              }

                              /* Execute la commande en tache de fond */
                              ok = 0;
                              if (ok_send)
                              {
                                    int val = 1;

                                    pvoie->sta.ack = 0;

                                    /* Attend le vidage de la queue */
                                    while (!modem_vide (voiecur));

                                    // sta_drv(voiecur, SUSPCMD, &val);
                                    // sleep(1);

                                    if (run_rzsz (voiecur, cmde) == 0)
                                    {
                                          pvoie->xferok = 1;
                                          pvoie->size_trans = 0L;
                                          pvoie->time_trans = 0L;
                                          prog_more (voiecur);
                                          /* pvoie->seq = 1; */
                                          ch_niv3 (XS_EXTERN);
                                          ok = 1;
                                    }
                              }
                        }
                        else
                              ok = 0;
#else
                        if (ymodem_files ())
                        {
                              /* Runs DSZ or equivalent */
                              char cmde[256];
                              int ok_send = 0;

                              sprintf (pvoie->ch_temp, "%sDSZLOG.%d", MBIN, voiecur);
                              if (pvoie->type_yapp == 0)
                                    wsprintf (cmde, "DSZ.PIF %s %x %d speed %ld handshake on sx",
                                                  pvoie->ch_temp, p_com[com].cbase, p_com[com].irq, p_com[com].baud);
                              else
                                    wsprintf (cmde, "DSZ.PIF %s %x %d speed %ld handshake on sx",
                                                  pvoie->ch_temp, p_com[com].cbase, p_com[com].irq, p_com[com].baud);

                              yptr = svoie[voiecur]->ytete;
                              while (yptr)
                              {
                                    strcat (cmde, " ");
                                    indd = yptr->filename;
                                    strcat (cmde, nom_yapp ());
                                    yptr = yptr->next;
                                    ok_send = 1;
                                    break;      /* Only 1 file with XModem */

                              }

                              /* Execute la commande en tache de fond */
                              if (ok_send)
                              {
                                    closecom_windows (p_port[no_port (voiecur)].ccom);
                                    pvoie->sta.ack = 0;
                                    win_execute (cmde);
                                    ch_niv3 (XS_EXTERN);
                                    ok = 1;
                              }
                              else
                                    ok = 0;
                        }
                        else
                              ok = 0;
#endif
                  }
#endif
#ifdef __FBBDOS__
                  ok = xmodem_tx (voiecur);
#endif

                  break;
            case 2:
                  if (ymodem_files ())
                  {
#ifdef __LINUX__
                        if (BIOS (no_port (voiecur)) == P_LINUX)
                        {
                              /* Runs DSZ or equivalent */
                              char cmde[1024];
                              int ok_send = 0;

                              sprintf (cmde, "fbb_zm sb -k ");

                              yptr = svoie[voiecur]->ytete;
                              while (yptr)
                              {
                                    strcat (cmde, " ");
                                    indd = yptr->filename;
                                    strcat (cmde, back2slash (nom_yapp ()));
                                    yptr = yptr->next;
                                    ok_send = 1;
                              }

                              /* Execute la commande en tache de fond */
                              ok = 0;
                              if (ok_send)
                              {
                                    pvoie->sta.ack = 0;

                                    /* Attend le vidage de la queue */
                                    while (!modem_vide (voiecur));
                                    sleep (1);

                                    if (run_rzsz (voiecur, cmde))
                                    {
                                          pvoie->xferok = 1;
                                          pvoie->size_trans = 0L;
                                          pvoie->time_trans = 0L;
                                          prog_more (voiecur);
                                          /* pvoie->seq = 1; */
                                          ch_niv3 (XS_EXTERN);
                                          ok = 1;
                                    }
                              }
                        }
#endif
#ifdef __WINDOWS__
                        if (BIOS (no_port (voiecur)) == P_WINDOWS)
                        {
#ifdef __WIN32__
                              /* Runs DSZ or equivalent */
                              char cmde[256];
                              int ok_send = 0;

                              sprintf (pvoie->ch_temp, "%sDSZLOG.%d", MBIN, voiecur);
                              sprintf (cmde, "sb -k -g %s", pvoie->ch_temp);

                              yptr = svoie[voiecur]->ytete;
                              while (yptr)
                              {
                                    strcat (cmde, " ");
                                    indd = yptr->filename;
                                    strcat (cmde, nom_yapp ());
                                    yptr = yptr->next;
                                    ok_send = 1;
                                    break;      /* 1 file with YModem */

                              }

                              /* Execute la commande en tache de fond */
                              ok = 0;
                              if (ok_send)
                              {
                                    int val = 1;

                                    pvoie->sta.ack = 0;

                                    /* Attend le vidage de la queue */
                                    while (!modem_vide (voiecur));

                                    sta_drv (voiecur, SUSPCMD, &val);
                                    sleep (1);

                                    if (run_rzsz (voiecur, cmde) == 0)
                                    {
                                          pvoie->xferok = 1;
                                          pvoie->size_trans = 0L;
                                          pvoie->time_trans = 0L;
                                          prog_more (voiecur);
                                          /* pvoie->seq = 1; */
                                          ch_niv3 (XS_EXTERN);
                                          ok = 1;
                                    }
                              }
#else
                              /* Runs DSZ or equivalent */
                              char cmde[256];
                              int ok_send = 0;

                              wsprintf (cmde, "DSZ.PIF %s %x %d speed %ld handshake on sb -k",
                                            pvoie->ch_temp, p_com[com].cbase, p_com[com].irq, p_com[com].baud);

                              yptr = svoie[voiecur]->ytete;
                              while (yptr)
                              {
                                    strcat (cmde, " ");
                                    indd = yptr->filename;
                                    strcat (cmde, nom_yapp ());
                                    yptr = yptr->next;
                                    ok_send = 1;
                                    break;      /* 1 file with YModem */

                              }

                              /* Execute la commande en tache de fond */
                              if (ok_send)
                              {
                                    char env[256];

                                    closecom_windows (p_port[no_port (voiecur)].ccom);
                                    pvoie->sta.ack = 0;
                                    win_execute (cmde);

                                    ch_niv3 (XS_EXTERN);
                                    ok = 1;
                              }
                              else
                                    ok = 0;
#endif
                        }
#endif
#ifdef __FBBDOS__
                        ok = ymodem_tx (voiecur);
#endif
                  }
                  else
                        ok = 0;
                  break;
            case 3:                       /* ZModem */
                  if (ymodem_files ())
                  {
#ifdef __LINUX__
                        if (BIOS (no_port (voiecur)) == P_LINUX)
                        {
                              /* Runs DSZ or equivalent */
                              char cmde[1024];
                              int ok_send = 0;

                              sprintf (cmde, "fbb_zm sz ");

                              yptr = svoie[voiecur]->ytete;
                              while (yptr)
                              {
                                    strcat (cmde, " ");
                                    indd = yptr->filename;
                                    strcat (cmde, back2slash (nom_yapp ()));
                                    yptr = yptr->next;
                                    ok_send = 1;
                              }

                              /* Execute la commande en tache de fond */
                              ok = 0;
                              if (ok_send)
                              {
                                    pvoie->sta.ack = 0;

                                    /* Attend le vidage de la queue */
                                    while (!modem_vide (voiecur));
                                    sleep (1);

                                    if (run_rzsz (voiecur, cmde))
                                    {
                                          pvoie->xferok = 1;
                                          pvoie->size_trans = 0L;
                                          pvoie->time_trans = 0L;
                                          prog_more (voiecur);
                                          /* pvoie->seq = 1; */
                                          ch_niv3 (XS_EXTERN);
                                          ok = 1;
                                    }
                              }
                        }
#endif
#ifdef __WINDOWS__
                        if (BIOS (no_port (voiecur)) == P_WINDOWS)
                        {
#ifdef __WIN32__
                              /* Runs DSZ or equivalent */
                              char cmde[1024];
                              int val;
                              int ok_send = 0;

                              sprintf (pvoie->ch_temp, "%sDSZLOG.%d", MBIN, voiecur);
                              sprintf (cmde, "sz -g %s", pvoie->ch_temp);

                              yptr = svoie[voiecur]->ytete;
                              while (yptr)
                              {
                                    strcat (cmde, " ");
                                    indd = yptr->filename;
                                    strcat (cmde, nom_yapp ());
                                    yptr = yptr->next;
                                    ok_send = 1;
                              }

                              /* Execute la commande en tache de fond */
                              ok = 0;
                              if (ok_send)
                              {
                                    pvoie->sta.ack = 0;

                                    /* Attend le vidage de la queue */
                                    while (!modem_vide (voiecur));
                                    val = 1;
                                    sta_drv (voiecur, SUSPCMD, &val);
                                    sleep (1);

                                    if (run_rzsz (voiecur, cmde) == 0)
                                    {
                                          pvoie->xferok = 1;
                                          pvoie->size_trans = 0L;
                                          pvoie->time_trans = 0L;
                                          prog_more (voiecur);
                                          /* pvoie->seq = 1; */
                                          ch_niv3 (XS_EXTERN);
                                          ok = 1;
                                    }
                              }
#else
                              /* Runs DSZ or equivalent */
                              char cmde[256];
                              char env[128];
                              char fil[128];
                              int ok_send = 0;
                              FILE *fptr;

                              sprintf (pvoie->ch_temp, "%sDSZLOG.%d", MBIN, voiecur);
                              sprintf (env, "%sDSZFIL.%d", MBIN, voiecur);
                              wsprintf (cmde, "DSZ.PIF %s %x %d speed %ld handshake on sz -b -m -rr @%s",
                                            pvoie->ch_temp,
                                      p_com[com].cbase, p_com[com].irq, p_com[com].baud,
                                            env);

                              yptr = svoie[voiecur]->ytete;
                              fptr = fopen (env, "wt");
                              if (fptr == NULL)
                              {
                                    ok = 0;
                                    break;
                              }
                              while (yptr)
                              {
                                    /*
                                       strcat(cmde, " ");
                                       indd = yptr->filename;
                                       strcat(cmde, nom_yapp());
                                     */
                                    indd = yptr->filename;
                                    fputs (nom_yapp (), fptr);
                                    fputc ('\n', fptr);
                                    yptr = yptr->next,
                                          ok_send = 1;
                              }
                              fclose (fptr);

                              /* Execute la commande en tache de fond */
                              if (ok_send)
                              {
                                    closecom_windows (p_port[no_port (voiecur)].ccom);
                                    pvoie->sta.ack = 0;
                                    win_execute (cmde);

                                    ch_niv3 (XS_EXTERN);
                                    ok = 1;
                              }
                              else
                                    ok = 0;
#endif
                        }
#endif
#ifdef __FBBDOS__
                        {
                              zmodem_init ();
                              ok = 1;
                        }
#endif
                  }
                  else
                        ok = 0;
                  break;
            }
            break;

      case ZS_FILE:
            switch (ztyp_header (&f))
            {
            case ZRINIT:
                  zmodem_tx (voiecur);
                  break;
            case ZCOMM:
                  zmodem_init ();
                  break;
            case ZRQINIT:
                  break;
            default:
                  ch_niv3 (XM_ABORT);
                  xmodem ();
                  ok = 0;
                  break;
            }
            break;

      case XS_SEND:
#ifdef __FBBDOS__
            if (senddata (1))
            {
                  ch_niv3 (XS_QUEUE);
            }
#endif
            break;

      case XS_WAIT:
            break;

      case XS_QUEUE:
            break;

      case XS_END:
            xmodem_off (voiecur);
            set_binary (voiecur, 0);
            aff_header (voiecur);
            pvoie->time_trans = time (NULL) - pvoie->time_trans;
            pvoie->finf.download += (int) (pvoie->size_trans / 1024L);

            if ((pvoie->type_yapp == 2) || (pvoie->type_yapp == 3))
            {
                  yptr = svoie[voiecur]->ytete;
                  while ((yptr) && (yptr->ok))
                        yptr = yptr->next;
                  if (pvoie->type_yapp == 3)
                        pvoie->size_trans = pvoie->enrcur;
                  yptr->time_trans = pvoie->time_trans;
                  yptr->size_trans = pvoie->size_trans;
                  if (yptr)
                  {
                        yptr->ok = 1;
                        yptr = yptr->next;
                  }
                  if (yptr)
                  {
                        switch (pvoie->type_yapp)
                        {
                        case 2:
                              ch_niv3 (XS_INIT);
                              ok = ymodem_tx (voiecur);
                              break;
                        case 3:
                              ok = zmodem_tx (voiecur);
                              break;
                        }
                  }
                  else
                  {
                        libere_ymodem (voiecur, 1);
                        retour_appel ();
                        ok = 0;
                  }
            }
            else
            {
                  display_perf (voiecur);
                  retour_appel ();
                  ok = 0;
            }
            break;

      case XR_EXTERN:

            /* Infos pour statistiques */
            pvoie->time_trans = time (NULL) - pvoie->time_trans;

#ifdef __LINUX__
            /* Attend le vidage de la queue */
            set_binary (voiecur, 0);

            ioctl (p_com[(int)p_port[no_port (voiecur)].ccom].comfd, TCFLSH, 2);

            /* Reinitialise le port */
            init_modem (no_port (voiecur));

            clear_inbuf (voiecur);

#else
            /* Reeinitialisation du modem */
#ifdef __WIN32__
            {
                  int val = 0;

                  sta_drv (voiecur, SUSPCMD, &val);
            }
#else
            init_modem (no_port (voiecur));
#endif
#endif

            /* Appel du filtre... */
            if (test_temp (voiecur))
            {
                  rename_temp (voiecur, pvoie->sr_fic);
                  wr_dir (pvoie->sr_fic, pvoie->sta.indicatif.call);
                  pvoie->time_trans = time (NULL) - pvoie->time_trans;
            }
            aff_header (voiecur);

            display_dsz_perf (voiecur);

            retour_appel ();
            break;

      case XR_INIT:
            ok = xmodem_rx (voiecur);
            break;

      case XR_LABL:
            while ((*indd) && (!ISPRINT (*indd)))
                  ++indd;

            w_label (pvoie->sr_fic, sup_ln (indd));
            n_cpy (LABEL_NOM - 1, pvoie->label, sup_ln (indd));

            texte (T_YAP + 1);
            aff_etat ('E');
            send_buf (voiecur);
            while (!modem_vide (voiecur))
                  ;
#ifdef __LINUX__
            if (BIOS (no_port (voiecur)) == P_LINUX)
            {
                  char cmde[256];
                  char temp[256];

                  temp_name (voiecur, temp);
                  sprintf (pvoie->ch_temp, "%sDSZLOG.%d", MBINDIR, voiecur);

                  switch (pvoie->type_yapp)
                  {
                  case 0:
                  case 1:
                        sprintf (cmde, "fbb_zm rx %s", temp);
                        break;
                  case 2:
                        sprintf (cmde, "fbb_zm rb %s", temp);
                        break;
                  case 3:
                        sprintf (cmde, "fbb_zm rz %s", temp);
                        break;
                  }

                  pvoie->sta.ack = 0;

                  /* Attend le vidage de la queue */
                  while (!modem_vide (voiecur));
                  sleep (1);

                  if (run_rzsz (voiecur, cmde))
                  {
                        pvoie->xferok = 1;
                        pvoie->size_trans = 0L;
                        pvoie->time_trans = 0L;
                        prog_more (voiecur);
                        ch_niv3 (XR_EXTERN);
                        ok = 1;
                  }
                  else
                        retour_dos ();
            }
#endif
#ifdef __WINDOWS__
            if (BIOS (no_port (voiecur)) == P_WINDOWS)
            {
#ifdef __WIN32__
                  char cmde[256];
                  char temp[256];
                  int ok_send = 0;

                  temp_name (voiecur, temp);
                  sprintf (pvoie->ch_temp, "%sDSZLOG.%d", MBIN, voiecur);

                  switch (pvoie->type_yapp)
                  {
                  case 0:
                  case 1:
                        wsprintf (cmde, "rx %s -g %s", temp, pvoie->ch_temp);
                        break;
                  case 2:
                        wsprintf (cmde, "rb %s -g %s", temp, pvoie->ch_temp);
                        break;
                  case 3:
                        wsprintf (cmde, "rz %s -g %s", temp, pvoie->ch_temp);
                        break;
                  }

                  /* Execute la commande en tache de fond */
                  pvoie->sta.ack = 0;

                  /* Attend le vidage de la queue */
                  while (!modem_vide (voiecur));

                  {
                        int val = 1;

                        sta_drv (voiecur, SUSPCMD, &val);
                        sleep (1);
                        if (run_rzsz (voiecur, cmde) == 0)
                        {
                              /*
                                 pvoie->xferok = 1;
                                 pvoie->size_trans = 0L;
                                 pvoie->time_trans = 0L;
                                 prog_more (voiecur);
                               */
                              /* pvoie->seq = 1; */
                              ch_niv3 (XR_EXTERN);
                        }
                  }
#else
                  char cmde[256];
                  char temp[256];
                  int ok_send = 0;

                  temp_name (voiecur, temp);
                  sprintf (pvoie->ch_temp, "%sDSZLOG.%d", MBIN, voiecur);

                  switch (pvoie->type_yapp)
                  {
                  case 0:
                  case 1:
                        wsprintf (cmde, "DSZ.PIF %s %x %d speed %ld handshake on rx %s",
                                      pvoie->ch_temp, p_com[com].cbase, p_com[com].irq, p_com[com].baud, temp);
                        break;
                  case 2:
                        wsprintf (cmde, "DSZ.PIF %s %x %d speed %ld handshake on rb %s",
                                      pvoie->ch_temp, p_com[com].cbase, p_com[com].irq, p_com[com].baud, temp);
                        break;
                  case 3:
                        wsprintf (cmde, "DSZ.PIF %s %x %d speed %ld handshake on rz %s",
                                      pvoie->ch_temp, p_com[com].cbase, p_com[com].irq, p_com[com].baud, temp);
                        break;
                  }

                  /* Execute la commande en tache de fond */
                  closecom_windows (p_port[no_port (voiecur)].ccom);
                  pvoie->sta.ack = 0;
                  win_execute (cmde);
                  ch_niv3 (XR_EXTERN);
#endif
            }
#endif
#ifdef __FBBDOS__
            {
                  sleep_ (1);
                  set_binary (voiecur, 1);
                  pvoie->xferok = 0;
                  prog_more (voiecur);
                  xmodem_rx_on (voiecur);
                  ch_niv3 (XR_RECV);
            }
#endif
            break;

      case XR_RECV:
            pvoie->size_trans += (long) nb_trait;
            pvoie->enrcur += (long) nb_trait;
            if ((msgtemp = pvoie->msgtete) != NULL)
            {
                  while (msgtemp->suiv)
                        msgtemp = msgtemp->suiv;
            }
            else
            {
                  msgtemp = (obuf *) m_alloue (sizeof (obuf));
                  pvoie->msgtete = msgtemp;
                  msgtemp->nb_car = msgtemp->no_car = 0;
                  msgtemp->suiv = NULL;
            }
            ncars = msgtemp->nb_car;
            ptcur = msgtemp->buffer + ncars;
            ptr = data;
            while (nb_trait--)
            {
                  ++pvoie->memoc;
                  *ptcur++ = *ptr++;
                  if (++ncars == 250)
                  {
                        msgtemp->nb_car = ncars;
                        msgtemp->suiv = (obuf *) m_alloue (sizeof (obuf));
                        msgtemp = msgtemp->suiv;
                        msgtemp->nb_car = msgtemp->no_car = ncars = 0;
                        msgtemp->suiv = NULL;
                        ptcur = msgtemp->buffer;
                  }
            }
            msgtemp->nb_car = ncars;
            if (pvoie->memoc > MAXMEM)
            {
                  ok = write_mess_temp (O_BINARY, voiecur);
            }
            if (ok)
            {
                  break;
            }
            /* Si erreur continue sur XR_END ! */

      case XR_END:
            write_mess_temp (O_BINARY, voiecur);
            xmodem_off (voiecur);
            set_binary (voiecur, 0);
            if (test_temp (voiecur))
            {
                  rename_temp (voiecur, pvoie->sr_fic);
                  wr_dir (pvoie->sr_fic, pvoie->sta.indicatif.call);
                  pvoie->time_trans = time (NULL) - pvoie->time_trans;
                  display_perf (voiecur);
            }
            else
                  del_temp (voiecur);
            aff_header (voiecur);
            retour_appel ();
            ok = 0;
            break;

      case XM_ABORT:
            clear_outbuf (voiecur);
            xmodem_off (voiecur);
            set_binary (voiecur, 0);
            if (!pvoie->xferok)
                  del_temp (voiecur);
            aff_header (voiecur);
            pvoie->finf.download += (int) (pvoie->size_trans / 1024L);
            retour_appel ();
            ok = 0;
            break;

      }
#ifndef __WINDOWS__
      aff_xmodem (ok);
#endif
}


void modem (void)
{
      switch (pvoie->niv2)
      {
      case 0:
            accueil_modem ();
            break;
      case 1:
            indic_modem ();
            break;
      case 2:
            passwd_modem ();
            break;
      case 3:
            passwd_change ();
            break;
      case 4:
            xmodem ();
            break;
      default:
            fbb_error (ERR_NIVEAU, "MODEM", pvoie->niv2);
            break;
      }
}

Generated by  Doxygen 1.6.0   Back to index