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

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

#include <serv.h>

/*
 * Execution de programmes pour l'utilisateur
 *
 */

static void dir_pg (void);
static void pg_commande (void);
static void load_pg (void);

static int nbpg = 0;

#ifdef __LINUX__

#undef open

#include <termios.h>
#include <sys/ioctl.h>
#include <sys/signal.h>

cmdlist *tete_cmd = NULL;

static int pty_open (int *pty, struct winsize *winsize)
{
      int pid;
      int i;
      char line[20];
      int c;
      int tty, devtty;

      for (c = 'p'; c <= 's'; c++)
      {
            for (i = 0; i < 16; i++)
            {
                  sprintf (line, "/dev/pty%c%x", c, i);
                  *pty = open (line, O_RDWR | O_NOCTTY);
                  if (*pty >= 0)
                        break;
            }
            if (*pty >= 0)
                  break;
      }

      if (*pty < 0)
      {
            fprintf (stderr, "Out of pty\n");
            return -1;
      }

      ioctl (*pty, TIOCEXCL, NULL);

      if ((pid = fork ()) != 0)
            return pid;

      /* child */
      close (*pty);

      signal (SIGHUP, SIG_DFL);

      line[5] = 't';
      tty = open (line, O_RDWR);
      if (tty < 0)
      {
            fprintf (stderr, "Cannot open slave side\n");
            close (*pty);
            return -1;
      }
      (void) chown (line, getuid (), getgid ());
      (void) chmod (line, 0600);

      setsid ();                          /* will break terminal affiliation */
      ioctl (tty, TIOCSCTTY, (char *) 0);

      setuid (getuid ());
      setgid (getgid ());

      devtty = open ("/dev/tty", O_RDWR);
      if (devtty < 0)
      {
            perror ("cannot open /dev/tty");
            exit (1);
      }

      ioctl (devtty, TIOCSWINSZ, winsize);
      close (tty);
      dup2 (devtty, 0);
      dup2 (devtty, 1);
      dup2 (devtty, 2);

      return 0;
}

int is_cmd (int voie)
{
      struct timeval to;
      fd_set fds_read;

      if (svoie[voie]->niv1 == N_MBL && svoie[voie]->niv2 == 20 && svoie[voie]->niv3 > 0)
      {
            FD_ZERO (&fds_read);
            FD_SET (svoie[voie]->niv3, &fds_read);

            to.tv_sec = 0;
            to.tv_usec = 0;

            return (select (svoie[voie]->niv3 + 1, &fds_read, NULL, NULL, &to) > 0);
      }
      return 0;
}

void exec_cmd (cmdlist * cptr)
{
      if (pvoie->niv3 == 0)
      {
            int pid, ac;
            struct winsize win =
            {24, 80, 0, 0};
            char *av[20];

            if (cptr == NULL)
                  return;

            /* Create the child process */
            pid = pty_open (&pvoie->niv3, &win);
            if (pid == 0)
            {
                  /* child */
                  struct termios termios;
                  char *line;

                  memset ((char *) &termios, 0, sizeof (termios));

                  ioctl (0, TIOCSCTTY, (char *) 0);

                  termios.c_iflag = ICRNL | IXOFF;
                  termios.c_oflag = OPOST | ONLCR;
                  termios.c_cflag = CS8 | CREAD /*| CLOCAL */ ;
                  termios.c_lflag = ISIG | ICANON;
                  termios.c_cc[VINTR] = 127;
                  termios.c_cc[VQUIT] = 28;
                  termios.c_cc[VERASE] = 8;
                  termios.c_cc[VKILL] = 24;
                  termios.c_cc[VEOF] = 4;
                  cfsetispeed (&termios, B38400);
                  cfsetospeed (&termios, B38400);
                  tcsetattr (0, TCSANOW, &termios);

                  /* Transform the command line to list of arguments */
                  sup_ln (indd);
                  while (*indd && (!isspace (*indd)))
                        ++indd;

                  line = calloc (1, strlen (cptr->action) + strlen (indd) + 2);
                  strcpy (line, cptr->action);
                  strcat (line, indd);

                  ac = 0;
                  av[ac] = strtok (line, " \t\n\r");
                  while (av[ac])
                        av[++ac] = strtok (NULL, " \t\n");

                  /* 
                     envc = 0;
                     envp[envc] = (char *) malloc (30);
                     sprintf (envp[envc++], "AXCALL=%s", call);
                     envp[envc] = (char *) malloc (30);
                     sprintf (envp[envc++], "PROTOCOL=%s", protocol);
                     envp[envc] = (char *) malloc (30);
                     sprintf (envp[envc++], "TERM=linux");
                     envp[envc] = NULL;
                   */

                  execvp (av[0], av);

                  /* should never go there */
                  exit (1);
            }

      }


      else
      {
            /* read/write the child process */
            if (*indd)
                  write (pvoie->niv3, indd, strlen (indd));

            if (is_cmd (voiecur))
            {
                  char buf[250];
                  int cnt;

                  cnt = read (pvoie->niv3, buf, sizeof (buf));
                  if (cnt <= 0)
                  {
                        /* End of connection */
                        close (pvoie->niv3);
                        pvoie->niv3 = 0;
                        retour_mbl ();
                        return;
                  }
                  out (buf, cnt);
            }
      }
}
#endif

void exec_pg (void)
{
      int n_sauve;
      int ret;
      char s[256];
      char *ptr = NULL;
      FILE *fptr;

      if (pvoie->niv3 == 0)
      {
            /* if ... incindd(); */
            teste_espace ();
            sup_ln (indd);
            if (*indd)
            {
                  ptr = pvoie->appendf;
                  while (ISGRAPH (*indd))
                        *ptr++ = *indd++;
                  *ptr = '\0';
                  if (!tst_point (pvoie->appendf))
                  {
                        retour_mbl ();
                        return;
                  }
                  while_space ();
            }
            else
            {
                  dir_pg ();
                  retour_mbl ();
                  return;
            }
      }

      indd[80] = '\0';

      if (pvoie->ncur->coord != 0xffff)
      {
            /* Ecrit le record de l'utilisateur en fichier */
            fptr = ouvre_nomenc ();
            fseek (fptr, pvoie->ncur->coord * ((long) sizeof (info)), 0);
            fwrite ((char *) &(pvoie->finf), (int) sizeof (info), 1, fptr);
            ferme (fptr, 18);
      }

#if defined(__WINDOWS__) || defined(__MSDOS__)
#define     PG_BUF      32000
      {
            char *ptr = m_alloue (PG_BUF);

            if (ptr == NULL)
                  return;

            memset (ptr, '\0', PG_BUF);

#ifdef __LINUX__
            sprintf (s, "%s%s %s-%d %d %u %d %s",
                        PGDIR,
#elsif __WIN32__
            sprintf (s, "PG32\\%s %s-%d %d %u %d %s",
#else
            sprintf (s, "PG\\%s %s-%d %d %u %d %s",
#endif
                        pvoie->appendf, pvoie->sta.indicatif.call, pvoie->sta.indicatif.num,
                        pvoie->niv3, pvoie->finf.flags, pvoie->ncur->coord, indd);

            ret = filter (s, ptr, PG_BUF, NULL, NULL);

            ptr[PG_BUF - 1] = '\0';
            if (*ptr)
                  out (ptr, strlen (ptr));

            m_libere (ptr, PG_BUF);
      }
#endif
#ifdef __LINUX__
      {
            char deroute[80];
            char *pptr = s;

            sprintf (deroute, "%sEXECUTE.xxx", MBINDIR);

            sprintf (s, "%s%s %s-%d %d %u %d '%s'",
                         PGDIR, strlwr (pvoie->appendf), 
                         pvoie->sta.indicatif.call, pvoie->sta.indicatif.num,
                         pvoie->niv3, pvoie->finf.flags, pvoie->ncur->coord, indd);

            ret = call_nbdos (&pptr, 1, REPORT_MODE, deroute, PGDIR, NULL);
            if (ret != -1)
            {
                  outfich (deroute);
            }
            unlink (deroute);
      }
#endif
/*
   #ifdef __FBBDOS__

   sprintf (s, "PG\\%s %s-%d %d %u %d %s",
   pvoie->appendf, pvoie->sta.indicatif.call, pvoie->sta.indicatif.num,
   pvoie->niv3, pvoie->finf.flags, pvoie->ncur->coord, indd);

   ret = send_dos (4, s, NULL);

   #endif
 */
      if (pvoie->ncur->coord != 0xffff)
      {
            /* Relit le record de l'utilisateur du fichier */
            fptr = ouvre_nomenc ();
            fseek (fptr, pvoie->ncur->coord * ((long) sizeof (info)), 0);
            fread ((char *) &(pvoie->finf), (int) sizeof (info), 1, fptr);
            ferme (fptr, 18);
      }

      switch (ret)
      {

      case 0:
            init_hold ();
            retour_mbl ();
            break;

      case 1:
            ++pvoie->niv3;
            break;

      case 2:
            pvoie->deconnect = 6;
            break;

      case 3:
            pg_commande ();
            break;

      case 4:
            n_sauve = ++pvoie->niv3;
            init_hold ();
            pg_commande ();
            maj_niv (N_MBL, 17, n_sauve);
            break;

      case 5:
            break;

      case -1:
            clear_outbuf (voiecur);
            strcpy (varx[0], pvoie->appendf);
            texte (T_ERR + 1);
            retour_mbl ();
            break;

      default:
            retour_mbl ();
            break;
      }
}

static void dir_pg (void)
{
      int num = 0;
      char str[80];
      char *ptr;

#ifdef __WINDOWS__
#ifdef __WIN32__
      if (findfirst ("PG32\\*.*", &(pvoie->dirblk), FA_DIREC))
#else
      if (findfirst ("PG\\*.*", &(pvoie->dirblk), FA_DIREC))
#endif
      {
            texte (T_DOS + 2);
            return;
      }
#endif
#ifdef __FBBDOS__
      if (findfirst ("PG\\*.*", &(pvoie->dirblk), FA_DIREC))
      {
            texte (T_DOS + 2);
            return;
      }
#endif
#ifdef __LINUX__
      {
            cmdlist *clist = tete_cmd;

            while (clist)
            {
                  if (num == 4)
                  {
                        cr ();
                        num = 0;
                  }
                  sprintf (str, "%-10s", clist->cmd);
                  out (str, 10);
                  clist = clist->next;
            }
            if (num != 0)
                  cr ();
      }
      num = 0;

      sprintf(str, "%s*", PGDIR);
      if (findfirst (str, &(pvoie->dirblk), FA_DIREC))
      {
            texte (T_DOS + 2);
            return;
      }
#endif
      if (*pvoie->dirblk.ff_name == '.')
      {
            findnext (&(pvoie->dirblk));
            if (findnext (&(pvoie->dirblk)))
            {
                  texte (T_DOS + 2);
                  return;
            }
      }

      while (1)
      {
            if ((pvoie->dirblk.ff_attrib & FA_DIREC) == 0)
            {
                  if (num == 4)
                  {
                        cr ();
                        num = 0;
                  }
                  ptr = strrchr (pvoie->dirblk.ff_name, '.');
                  if (ptr)
                        *ptr = '\0';
                  sprintf (str, "%-10s", pvoie->dirblk.ff_name);
                  out (str, 10);
                  ++num;
            }
            if (findnext (&(pvoie->dirblk)))
                  break;
      }
      if (num != 0)
            cr ();
}

static void pg_commande (void)
{
      obuf *optr;
      char *ptr, *tptr;
      int ncars, nbcars, nocars;
      int maxcar = DATABUF;

      if ((optr = pvoie->outptr) != NULL)
      {
            ncars = 0;
            tptr = data;
            nbcars = optr->nb_car;
            nocars = optr->no_car;
            ptr = optr->buffer + nocars;
            while (1)
            {
                  if (nbcars == nocars)
                  {
                        pvoie->outptr = optr->suiv;
                        m_libere (optr, sizeof (obuf));
                        pvoie->memoc -= 250;
                        if ((optr = pvoie->outptr) != NULL)
                        {
                              nbcars = optr->nb_car;
                              nocars = 0;
                              ptr = optr->buffer;
                        }
                        else
                        {
                              /*            cprintf(" Vide ") ; */
                              break;
                        }
                  }
                  *tptr++ = *ptr;
                  ++nocars;
                  if (++ncars == maxcar)
                  {
                        optr->no_car = nocars;
                        break;
                  }
                  ++ptr;
            }
            *tptr = '\0';
            maj_niv (N_MBL, 0, 0);
            in_buf (voiecur, data, strlen (data));
            while (pvoie->inbuf.nblig)
                  traite_voie (voiecur);
      }
}

int appel_pg (char *nom)
{
      pglist *lptr = tete_pg;

#ifdef __LINUX__
      cmdlist *cptr = tete_cmd;

      strupr (nom);

      while (cptr)
      {
            if (strcmp (nom, cptr->cmd) == 0)
            {
                  maj_niv (N_MBL, 20, 0);
                  --indd;
                  exec_cmd (cptr);
                  return (1);
            }
            cptr = cptr->next;
      }

#else

      strupr (nom);

#endif

      while (lptr)
      {
            if (strcmp (nom, lptr->nom_pg) == 0)
            {
                  maj_niv (N_MBL, 17, 0);
                  --indd;
                  exec_pg ();
                  return (1);
            }
            lptr = lptr->suiv;
      }
      return (0);
}

#ifdef __LINUX__
static void load_cmd (void)
{
      FILE *fptr;
      char line[256];
      char cmd[256];
      char action[256];
      cmdlist *cptr;

      fptr = fopen (c_disque ("commands.sys"), "r");
      if (fptr == NULL)
            return;

      while (fgets (line, sizeof (line), fptr))
      {
            int nb = sscanf (line, "%s %[^\n]", cmd, action);

            if (nb < 2 || *cmd == '#')
                  continue;
            cptr = malloc (sizeof (cmdlist));
            if (cptr == NULL)
                  return;
            strupr (cmd);
            n_cpy (sizeof (cptr->cmd) - 1, cptr->cmd, cmd);
            cptr->action = strdup (action);
            cptr->next = tete_cmd;
            tete_cmd = cptr;

            ++nbpg;
            {
                  char text[80];

                  sprintf (text, "%d: CMD %s", nbpg, cptr->cmd);
                  InitText (text);
            }
      }

      fclose (fptr);
}
#endif

static void load_pg (void)
{
      char str[80];
      char *ptr;
      pglist *lptr = tete_pg;
      struct ffblk dirblk;

#if defined(__WINDOWS__) || defined(__FBBDOS__)
#ifdef __WIN32__
      if (findfirst ("PG32\\*.*", &dirblk, FA_DIREC))
#else
      if (findfirst ("PG\\*.*", &dirblk, FA_DIREC))
#endif
      {
            return;
      }
#endif
#if defined(__LINUX__)
      sprintf(str, "%s*", PGDIR);
      if (findfirst (str, &dirblk, FA_DIREC))
      {
            return;
      }
#endif

      if (*pvoie->dirblk.ff_name == '.')
      {
            findnext (&dirblk);
            if (findnext (&dirblk))
            {
                  return;
            }
      }
      ptr = strchr (dirblk.ff_name, '.');
      if (ptr)
            *ptr = '\0';
      if ((dirblk.ff_attrib & FA_DIREC) == 0)
      {
            if (lptr)
            {
                  lptr->suiv = (pglist *) m_alloue (sizeof (pglist));
                  lptr = lptr->suiv;
            }
            else
            {
                  tete_pg = lptr = (pglist *) m_alloue (sizeof (pglist));
            }
            lptr->suiv = NULL;
            strn_cpy (8, lptr->nom_pg, dirblk.ff_name);
#if defined(__WINDOWS__) || defined(__LINUX__)
            ++nbpg;
            {
                  char text[80];

                  sprintf (text, "%d: PG  %s", nbpg, lptr->nom_pg);
                  InitText (text);
            }
#endif
      }

      while (findnext (&dirblk) == 0)
      {
            ptr = strchr (dirblk.ff_name, '.');
            if (ptr)
                  *ptr = '\0';
            if ((dirblk.ff_attrib & FA_DIREC) == 0)
            {
                  if (lptr)
                  {
                        lptr->suiv = (pglist *) m_alloue (sizeof (pglist));
                        lptr = lptr->suiv;
                  }
                  else
                  {
                        tete_pg = lptr = (pglist *) m_alloue (sizeof (pglist));
                  }
                  lptr->suiv = NULL;
                  strn_cpy (8, lptr->nom_pg, dirblk.ff_name);
#if defined(__WINDOWS__) || defined(__LINUX__)
                  ++nbpg;
                  {
                        char text[80];

                        sprintf (text, "%d: PG  %s", nbpg, lptr->nom_pg);
                        InitText (text);
                  }
#endif
            }
      }
#ifdef __LINUX__
      /* Loads the commands of system/commands.sys */
      load_cmd ();
#endif
}

void end_pg (void)
{
      pglist *lptr;

#ifdef __LINUX__
      cmdlist *cptr;
      int voie;

      printf ("End PG ***\n");
      for (voie = 0; voie < NBVOIES; voie++)
      {
            /* Close open ttys */
            if (svoie[voie]->niv1 == N_MBL && svoie[voie]->niv2 == 20 && svoie[voie]->niv3 > 0)
            {
                  printf ("Closing tty %d\n", svoie[voie]->niv3);
                  close (svoie[voie]->niv3);
            }
      }

      while (tete_cmd)
      {
            cptr = tete_cmd;
            tete_cmd = cptr->next;
            m_libere (cptr->action, strlen (cptr->action) + 1);
            m_libere (cptr, sizeof (cmdlist));
      }
#endif

      while (tete_pg)
      {
            lptr = tete_pg;
            tete_pg = tete_pg->suiv;
            m_libere (lptr, sizeof (pglist));
      }

}

void affich_pg (int tp)
{
#ifdef __LINUX__

      load_pg ();

#endif
#ifdef __WINDOWS__

      load_pg ();

#endif
#ifdef __FBBDOS__
      fen *fen_ptr;
      pglist *lptr;
      int size, nb_pg = 0;

      load_pg ();

      lptr = tete_pg;
      while (lptr)
      {
            ++nb_pg;
            lptr = lptr->suiv;
      }

      if (nb_pg == 0)
            return;

      size = (nb_pg > 19 * 7) ? 19 : 1 + nb_pg / 7;
      lptr = tete_pg;
      deb_io ();

      nb_pg = 0;
      fen_ptr = open_win (10, 2, 76, 4 + size, INIT, "PG");
      while (lptr)
      {
            cprintf ("%-8s ", lptr->nom_pg);
            lptr = lptr->suiv;
      }
      attend_caractere (tp);
      close_win (fen_ptr);

      fin_io ();
#endif
}

Generated by  Doxygen 1.6.0   Back to index