source: git/Singular/ssiLink.cc @ 6c70ef

spielwiese
Last change on this file since 6c70ef was 6c70ef, checked in by Andreas Steenpaß <steenpas@…>, 13 years ago
new commands: waitall, waitfirst git-svn-id: file:///usr/local/Singular/svn/trunk@13587 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 30.8 KB
Line 
1/****************************************
2 * Computer Algebra System SINGULAR     *
3 ****************************************/
4/***************************************************************
5 * File:    ssiLink.h
6 *  Purpose: declaration of sl_link routines for ssi
7 *  Version: $Id$
8 ***************************************************************/
9#include <stdio.h>
10#include <fcntl.h>
11#include <errno.h>
12#include <unistd.h>
13#include <sys/types.h>
14#include <signal.h>
15#include <sys/types.h>          /* for portability */
16#include <sys/select.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <ctype.h>   /*for isdigit*/
20#include <netdb.h>
21
22
23#include "mod2.h"
24
25#include "tok.h"
26#include "ipid.h"
27#include <omalloc/omalloc.h>
28#include <kernel/ring.h>
29#include <kernel/matpol.h>
30#include <kernel/ideals.h>
31#include <kernel/polys.h>
32#include <kernel/longrat.h>
33#include <kernel/ideals.h>
34#include "subexpr.h"
35#include "silink.h"
36#include "lists.h"
37#include "ssiLink.h"
38
39typedef struct
40{
41  FILE *f_read;
42  FILE *f_write;
43  ring r;
44  pid_t pid; /* only valid for fork/tcp mode*/
45  int fd_read,fd_write; /* only valid for fork/tcp mode*/
46  char level;
47} ssiInfo;
48
49
50typedef struct
51{
52  leftv u;
53  si_link l;
54  void * next;
55} link_struct;
56
57typedef link_struct* link_list;
58
59link_list ssiToBeClosed=NULL;
60
61// the helper functions:
62void ssiSetCurrRing(const ring r)
63{
64  if (!rEqual(r,currRing,1))
65  {
66    char name[20];
67    int nr=0;
68    do
69    { sprintf(name,"ssiRing%d",nr); nr++; }
70    while(IDROOT->get(name, 0)!=NULL);
71    idhdl h=enterid(omStrDup(name),0,RING_CMD,&IDROOT,FALSE);
72    IDRING(h)=r;
73    r->ref++;
74    rSetHdl(h);
75  }
76}
77// the implementation of the functions:
78void ssiWriteInt(ssiInfo *d,const int i)
79{
80  fprintf(d->f_write,"%d ",i);
81  //if (d->f_debug!=NULL) fprintf(d->f_debug,"int: %d ",i);
82}
83
84void ssiWriteString(ssiInfo *d,const char *s)
85{
86  fprintf(d->f_write,"%d %s ",strlen(s),s);
87  //if (d->f_debug!=NULL) fprintf(d->f_debug,"stringi: %d \"%s\" ",strlen(s),s);
88}
89
90
91void ssiWriteBigInt(const ssiInfo *d, const number n)
92{
93  // syntax is as follows:
94  // case 2 Q:     3 4 <int>
95  //        or     3 3 <mpz_t nominator>
96  if(SR_HDL(n) & SR_INT)
97  {
98    fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
99    //if (d->f_debug!=NULL) fprintf(d->f_debug,"bigint: short \"%ld\" ",SR_TO_INT(n));
100  }
101  else if (n->s==3)
102  {
103    fprintf(d->f_write,"3 ");
104    mpz_out_str(d->f_write,10,n->z);
105    fprintf(d->f_write," ");
106    //gmp_fprintf(d->f_write,"3 %Zd ",n->z);
107    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"bigint: gmp \"%Zd\" ",n->z);
108  }
109  else Werror("illiegal bigint");
110}
111
112void ssiWriteNumber(const ssiInfo *d, const number n)
113{
114  // syntax is as follows:
115  // case 1 Z/p:   3 <int>
116  // case 2 Q:     3 4 <int>
117  //        or     3 0 <mpz_t nominator> <mpz_t denominator>
118  //        or     3 1  dto.
119  //        or     3 3 <mpz_t nominator>
120  //        or     3 5 <mpz_t raw nom.> <mpz_t raw denom.>
121  //        or     3 6 <mpz_t raw nom.> <mpz_t raw denom.>
122  //        or     3 7 <mpz_t raw nom.>
123  if(rField_is_Zp(d->r))
124  {
125    fprintf(d->f_write,"%d ",(int)(long)n);
126    //if (d->f_debug!=NULL) fprintf(d->f_debug,"number: \"%ld\" ",(int)(long)n);
127  }
128  else if (rField_is_Q(d->r))
129  {
130    if(SR_HDL(n) & SR_INT)
131    {
132      fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
133      //if (d->f_debug!=NULL) fprintf(d->f_debug,"number: short \"%ld\" ",SR_TO_INT(n));
134    }
135    else if (n->s<2)
136    {
137      //gmp_fprintf(d->f_write,"%d %Zd %Zd ",n->s,n->z,n->n);
138      fprintf(d->f_write,"%d ",n->s+5);
139      mpz_out_str (d->f_write,32, n->z);
140      fprintf(d->f_write," ");
141      mpz_out_str (d->f_write,32, n->n);
142      fprintf(d->f_write," ");
143
144      //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: s=%d gmp/gmp \"%Zd %Zd\" ",n->s,n->z,n->n);
145    }
146    else /*n->s==3*/
147    {
148      //gmp_fprintf(d->f_write,"3 %Zd ",n->z);
149      fprintf(d->f_write,"8 ");
150      mpz_out_str (d->f_write,32, n->z);
151      fprintf(d->f_write," ");
152     
153      //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: gmp \"%Zd\" ",n->z);
154    }
155  }
156  else WerrorS("coeff field not implemented");
157}
158
159void ssiWriteRing(ssiInfo *d,const ring r)
160{
161  /* 5 <ch> <N> <l1> <s1>....<ln> <sN> */
162  if (d->r!=NULL) rKill(d->r);
163  d->r=r;
164  d->r->ref++;
165  fprintf(d->f_write,"%d %d ",r->ch,r->N);
166
167  int i;
168  for(i=0;i<r->N;i++)
169  {
170    fprintf(d->f_write,"%d %s ",strlen(r->names[i]),r->names[i]);
171  }
172  /* number of orderings:*/
173  i=0;
174  while (r->order[i]!=0) i++;
175  fprintf(d->f_write,"%d ",i);
176  /* each ordering block: */
177  i=0;
178  while(r->order[i]!=0)
179  {
180    fprintf(d->f_write,"%d %d %d ",r->order[i],r->block0[i], r->block1[i]);
181    i++;
182  }
183}
184
185void ssiWritePoly(ssiInfo *d, int typ, poly p)
186{
187  fprintf(d->f_write,"%d ",pLength(p));//number of terms
188  int i;
189
190  while(p!=NULL)
191  {
192    ssiWriteNumber(d,pGetCoeff(p));
193    //nWrite(fich,pGetCoeff(p));
194    fprintf(d->f_write,"%ld ",p_GetComp(p,d->r));//component
195
196    for(int j=1;j<=rVar(d->r);j++)
197    {
198      fprintf(d->f_write,"%ld ",p_GetExp(p,j,d->r ));//x^j
199    }
200    pIter(p);
201  }
202}
203
204void ssiWriteIdeal(ssiInfo *d, int typ,ideal I)
205{
206   // syntax: 7 # of elements <poly 1> <poly2>.....
207   // syntax: 8 <rows> <cols> <poly 1> <poly2>.....
208   matrix M=(matrix)I;
209   if (typ==MATRIX_CMD)
210        fprintf(d->f_write,"%d %d ", MATROWS(M),MATCOLS(M));
211   else
212     fprintf(d->f_write,"%d ",IDELEMS(I));
213
214   int i;
215   int tt;
216   if (typ==MODUL_CMD) tt=VECTOR_CMD;
217   else                tt=POLY_CMD;
218
219   for(i=0;i<IDELEMS(I);i++)
220   {
221     ssiWritePoly(d,tt,I->m[i]);
222   }
223}
224void ssiWriteCommand(si_link l, command D)
225{
226  ssiInfo *d=(ssiInfo*)l->data;
227  // syntax: <num ops> <operation> <op1> <op2> ....
228  fprintf(d->f_write,"%d %d ",D->argc,D->op);
229  if (D->argc >0) ssiWrite(l, &(D->arg1));
230  if (D->argc < 4)
231  {
232    if (D->argc >1) ssiWrite(l, &(D->arg2));
233    if (D->argc >2) ssiWrite(l, &(D->arg3));
234  }
235}
236
237void ssiWriteProc(ssiInfo *d,procinfov p)
238{
239  ssiWriteString(d,p->data.s.body);
240}
241
242void ssiWriteList(si_link l,lists dd)
243{
244  ssiInfo *d=(ssiInfo*)l->data;
245  fprintf(d->f_write,"%d ",dd->nr+1);
246  int i;
247  for(i=0;i<=dd->nr;i++)
248  {
249    ssiWrite(l,&(dd->m[i]));
250  }
251}
252
253char *ssiReadString(ssiInfo *d)
254{
255  char *buf;
256  int l;
257  fscanf(d->f_read,"%d ",&l);
258  buf=(char*)omAlloc(l+1);
259  fread(buf,1,l,d->f_read);
260  buf[l]='\0';
261  return buf;
262}
263
264int ssiReadInt(FILE *fich)
265{
266  int d;
267  fscanf(fich,"%d",&d);
268  return d;
269}
270
271number ssiReadBigInt(ssiInfo *d)
272{
273   int sub_type=-1;
274   fscanf(d->f_read,"%d",&sub_type);
275   switch(sub_type)
276   {
277   case 3:
278     {// read int or mpz_t or mpz_t, mpz_t
279       number n=nlRInit(0);
280       mpz_inp_str(n->z,d->f_read,0);
281       n->s=sub_type;
282       return n;
283     }
284   case 4: { int dd; fscanf(d->f_read,"%d",&dd); return INT_TO_SR(dd); }
285   default: Werror("error in reading number: invalid subtype %d",sub_type);
286            return NULL;
287   }
288}
289
290number ssiReadNumber(ssiInfo *d)
291{
292  if (rField_is_Q(d->r))
293  {
294     int sub_type=-1;
295     fscanf(d->f_read,"%d",&sub_type);
296     switch(sub_type)
297     {
298     case 0:
299     case 1:
300       {// read mpz_t, mpz_t
301        number n=nlRInit(0);
302        mpz_init(n->n);
303        gmp_fscanf(d->f_read,"%Zd %Zd",n->z,n->n);
304        n->s=sub_type;
305        return n;
306       }
307
308     case 3:
309       {// read mpz_t
310         number n=nlRInit(0);
311         gmp_fscanf(d->f_read,"%Zd",n->z);
312         n->s=3; /*sub_type*/
313         return n;
314       }
315     case 4: { int dd; fscanf(d->f_read,"%d",&dd); return INT_TO_SR(dd); }
316     case 5:
317     case 6:
318       {// read raw mpz_t, mpz_t
319        number n=nlRInit(0);
320        mpz_init(n->n);
321        mpz_inp_str (n->z, d->f_read, 32);
322        mpz_inp_str (n->n, d->f_read, 32);
323        n->s=sub_type-5;
324        return n;
325       }
326     case 8:
327       {// read raw mpz_t
328        number n=nlRInit(0);
329        mpz_inp_str (n->z, d->f_read, 32);
330        n->s=sub_type=3; /*subtype-5*/
331        return n;
332       }
333
334     default: Werror("error in reading number: invalid subtype %d",sub_type);
335              return NULL;
336     }
337  }
338  else if (rField_is_Zp(d->r))
339  {
340    // read int
341    int dd;
342    fscanf(d->f_read,"%d",&dd);
343    return (number)dd;
344  }
345  else Werror("coeffs not implemented");
346  return NULL;
347}
348
349ring ssiReadRing(ssiInfo *d)
350{
351/* syntax is <ch> <N> <l1> <s1> ....<lN> <sN> */
352  int ch, N,i,l;
353  char **names;
354  fscanf(d->f_read,"%d %d ",&ch,&N);
355  names=(char**)omAlloc(N*sizeof(char*));
356  for(i=0;i<N;i++)
357  {
358    names[i]=ssiReadString(d);
359  }
360  // read the orderings:
361  int num_ord; // number of orderings
362  fscanf(d->f_read,"%d",&num_ord);
363  int *ord=(int *)omAlloc0((num_ord+1)*sizeof(int));
364  int *block0=(int *)omAlloc0((num_ord+1)*sizeof(int));
365  int *block1=(int *)omAlloc0((num_ord+1)*sizeof(int));
366  for(i=0;i<num_ord;i++)
367  {
368     fscanf(d->f_read,"%d %d %d",&ord[i],&block0[i],&block1[i]);
369  }
370  return rDefault(ch,N,names,num_ord,ord,block0,block1);
371}
372
373poly ssiReadPoly(ssiInfo *D)
374{
375// < # of terms> < term1> < .....
376  int n,i,l;
377  n=ssiReadInt(D->f_read);
378  //Print("poly: terms:%d\n",n);
379  poly p;
380  int j;
381  j=0;
382  poly ret=NULL;
383  poly prev=NULL;
384  for(l=0;l<n;l++) // read n terms
385  {
386// coef,comp.exp1,..exp N
387    p=p_Init(D->r);
388    pGetCoeff(p)=ssiReadNumber(D);
389    int d;
390    fscanf(D->f_read,"%d",&d);
391    p_SetComp(p,d,D->r);
392    for(i=1;i<=rVar(D->r);i++)
393    {
394      fscanf(D->f_read,"%d",&d);
395      p_SetExp(p,i,d,D->r);
396    }
397    p_Setm(p,D->r);
398    p_Test(p,D->r);
399    if (ret==NULL) ret=p;
400    else           pNext(prev)=p;
401    prev=p;
402 }
403 return ret;
404}
405
406ideal ssiReadIdeal(ssiInfo *d)
407{
408  int n,i;
409  ideal I;
410  fscanf(d->f_read,"%d",&n);
411  I=idInit(n,1);
412  for(i=0;i<IDELEMS(I);i++) // read n terms
413  {
414    I->m [i]=ssiReadPoly(d);
415  }
416  return I;
417}
418
419matrix ssiReadMatrix(ssiInfo *d)
420{
421  int n,m,i,j;
422  fscanf(d->f_read,"%d %d",&m,&n);
423  matrix M=mpNew(m,n);
424  poly p;
425  for(int i=1;i<=MATROWS(M);i++)
426    for(int j=1;j<=MATCOLS(M);j++)
427    {
428      p=ssiReadPoly(d);
429      MATELEM(M,i,j)=p;
430    }
431  return M;
432}
433
434command ssiReadCommand(si_link l)
435{
436  ssiInfo *d=(ssiInfo*)l->data;
437  // syntax: <num ops> <operation> <op1> <op2> ....
438  command D=(command)omAlloc0(sizeof(*D));
439  int argc,op;
440  fscanf(d->f_read,"%d %d",&argc,&op);
441  D->argc=argc; D->op=op;
442  leftv v;
443  if (argc >0)
444  {
445    v=ssiRead1(l);
446    memcpy(&(D->arg1),v,sizeof(*v));
447    omFreeBin(v,sleftv_bin);
448  }
449  if (argc <4)
450  {
451    if (D->argc >1)
452    {
453      v=ssiRead1(l);
454      memcpy(&(D->arg2),v,sizeof(*v));
455      omFreeBin(v,sleftv_bin);
456    }
457    if (D->argc >2)
458    {
459      v=ssiRead1(l);
460      memcpy(&(D->arg3),v,sizeof(*v));
461      omFreeBin(v,sleftv_bin);
462    }
463  }
464  else
465  {
466    leftv prev=&(D->arg1);
467    argc--;
468    while(argc >0)
469    {
470      v=ssiRead1(l);
471      prev->next=v;
472      prev=v;
473      argc--;
474    }
475  }
476  return D;
477}
478
479procinfov ssiReadProc(ssiInfo *d)
480{
481  char *s=ssiReadString(d);
482  procinfov p=(procinfov)omAlloc0Bin(procinfo_bin);
483  p->language=LANG_SINGULAR;
484  p->libname=omStrDup("");
485  p->procname=omStrDup("");
486  p->data.s.body=s;
487  return p;
488}
489lists ssiReadList(si_link l)
490{
491  ssiInfo *d=(ssiInfo*)l->data;
492  int nr;
493  fscanf(d->f_read,"%d",&nr);
494  lists L=(lists)omAlloc(sizeof(*L));
495  L->Init(nr);
496
497  int i;
498  leftv v;
499  for(i=0;i<nr;i++)
500  {
501    v=ssiRead1(l);
502    memcpy(&(L->m[i]),v,sizeof(*v));
503    omFreeBin(v,sleftv_bin);
504  }
505  return L;
506}
507
508//**************************************************************************/
509BOOLEAN ssiOpen(si_link l, short flag, leftv u)
510{
511  const char *mode;
512  ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
513  if (flag & SI_LINK_OPEN)
514  {
515    if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
516      flag = SI_LINK_READ;
517    else flag = SI_LINK_WRITE;
518  }
519
520  if (flag == SI_LINK_READ) mode = "r";
521  else if (strcmp(l->mode, "w") == 0) mode = "w";
522  else if (strcmp(l->mode, "fork") == 0) mode = "fork";
523  else if (strcmp(l->mode, "tcp") == 0) mode = "tcp";
524  else if (strcmp(l->mode, "connect") == 0) mode = "connect";
525  else mode = "a";
526
527
528  SI_LINK_SET_OPEN_P(l, flag);
529  l->data=d;
530  omFree(l->mode);
531  l->mode = omStrDup(mode);
532
533  if (l->name[0] == '\0')
534  {
535    if (strcmp(mode,"fork")==0)
536    {
537      link_list n=(link_list)omAlloc(sizeof(link_struct));
538      n->u=u;
539      n->l=l;
540      n->next=(void *)ssiToBeClosed;
541      ssiToBeClosed=n;
542
543      int pc[2];
544      int cp[2];
545      pipe(pc);
546      pipe(cp);
547      pid_t pid=fork();
548      if (pid==0) /*child*/
549      {
550        link_list hh=(link_list)ssiToBeClosed->next;
551        /* we know: l is the first entry in ssiToBeClosed-list */
552        while(hh!=NULL)
553        {
554          ssiInfo *dd=(ssiInfo*)hh->l->data;
555          fclose(dd->f_read);
556          fclose(dd->f_write);
557          if (dd->r!=NULL) rKill(dd->r);
558          omFreeSize((ADDRESS)dd,(sizeof *dd));
559          hh->l->data=NULL;
560          SI_LINK_SET_CLOSE_P(hh->l);
561          link_list nn=(link_list)hh->next;
562          omFree(hh);
563          hh=nn;
564        }
565        ssiToBeClosed->next=NULL;
566        close(pc[1]); close(cp[0]);
567        d->f_read=fdopen(pc[0],"r");
568        d->fd_read=pc[0];
569        d->f_write=fdopen(cp[1],"w");
570        d->fd_write=cp[1];
571        l->data=d;
572        omFree(l->mode);
573        l->mode = omStrDup(mode);
574        SI_LINK_SET_RW_OPEN_P(l);
575        //myynest=0;
576        fe_fgets_stdin=fe_fgets_dummy;
577        if ((u!=NULL)&&(u->rtyp==IDHDL))
578        {
579          idhdl h=(idhdl)u->data;
580          h->lev=0;
581        }
582        loop
583        {
584          leftv h=ssiRead1(l); /*contains an exit.... */
585          if (feErrors != NULL && *feErrors != '\0')
586          {
587            // handle errors:
588            PrintS(feErrors); /* currently quite simple */
589            *feErrors = '\0';
590          }
591          ssiWrite(l,h);
592          h->CleanUp();
593          omFreeBin(h, sleftv_bin);
594        }
595        /* never reached*/
596      }
597      else if (pid>0)
598      {
599        d->pid=pid;
600        close(pc[0]); close(cp[1]);
601        d->f_read=fdopen(cp[0],"r");
602        d->fd_read=cp[0];
603        d->f_write=fdopen(pc[1],"w");
604        d->fd_write=pc[1];
605        SI_LINK_SET_RW_OPEN_P(l);
606      }
607      else
608      {
609        Werror("fork failed (%d)",errno);
610        l->data=NULL;
611        omFree(d);
612        return TRUE;
613      }
614    }
615    else if (strcmp(mode,"tcp")==0)
616    {
617      int sockfd, newsockfd, portno, clilen;
618      struct sockaddr_in serv_addr, cli_addr;
619      int n;
620      sockfd = socket(AF_INET, SOCK_STREAM, 0);
621      if(sockfd < 0)
622      {
623        WerrorS("ERROR opening socket");
624        l->data=NULL;
625        omFree(d);
626        return TRUE;
627      }
628      memset((char *) &serv_addr,0, sizeof(serv_addr));
629      portno = 1024;
630      serv_addr.sin_family = AF_INET;
631      serv_addr.sin_addr.s_addr = INADDR_ANY;
632      do
633      {
634        portno++;
635        serv_addr.sin_port = htons(portno);
636        if(portno > 50000)
637        {
638          WerrorS("ERROR on binding (no free port available?)");
639          l->data=NULL;
640          omFree(d);
641          return TRUE;
642        }
643      }
644      while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
645      Print("waiting on port %d\n", portno);mflush();
646      listen(sockfd,5);
647      newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
648      if(newsockfd < 0)
649      {
650        WerrorS("ERROR on accept");
651        l->data=NULL;
652        omFree(d);
653        return TRUE;
654      }
655      PrintS("client accepted\n");
656      d->fd_read = newsockfd;
657      d->fd_write = newsockfd;
658      d->f_read = fdopen(newsockfd, "r");
659      d->f_write = fdopen(newsockfd, "w");
660      SI_LINK_SET_RW_OPEN_P(l);
661      close(sockfd);
662    }
663    // stdin or stdout
664    else if (flag == SI_LINK_READ)
665    {
666      d->f_read = stdin;
667      mode = "r";
668    }
669    else
670    {
671      d->f_write = stdout;
672      mode = "a";
673    }
674  }
675  else /*l->name=NULL*/
676  {
677    // tcp mode
678    if(strcmp(mode,"tcp")==0)
679    {
680      int sockfd, newsockfd, portno, clilen;
681      struct sockaddr_in serv_addr, cli_addr;
682      int n;
683      sockfd = socket(AF_INET, SOCK_STREAM, 0);
684      if(sockfd < 0)
685      {
686        WerrorS("ERROR opening socket");
687        l->data=NULL;
688        omFree(d);
689        return TRUE;
690      }
691      memset((char *) &serv_addr,0, sizeof(serv_addr));
692      portno = 1024;
693      serv_addr.sin_family = AF_INET;
694      serv_addr.sin_addr.s_addr = INADDR_ANY;
695      do
696      {
697        portno++;
698        serv_addr.sin_port = htons(portno);
699        if(portno > 50000)
700        {
701          WerrorS("ERROR on binding (no free port available?)");
702          l->data=NULL;
703          return TRUE;
704        }
705      }
706      while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
707      //Print("waiting on port %d\n", portno);mflush();
708      listen(sockfd,5);
709      char* cli_host = (char*)omAlloc(256);
710      char* path = (char*)omAlloc(1024);
711      int r = sscanf(l->name,"%255[^:]:%s",cli_host,path);
712      if(r == 0)
713      {
714        WerrorS("ERROR: no host specified");
715        l->data=NULL;
716        omFree(d);
717        return TRUE;
718      }
719      else if(r == 1)
720      {
721        path = "Singular";
722      }
723      char* ssh_command = (char*)omAlloc(256);
724      char* ser_host = (char*)omAlloc(64);
725      gethostname(ser_host,64);
726      sprintf(ssh_command,"ssh %s %s -q --batch --link=ssi --MPhost=%s --MPport=%d &",cli_host,path,ser_host,portno);
727      system(ssh_command);
728      //Print("client on %s started:%s\n",cli_host,path);
729      clilen = sizeof(cli_addr);
730      newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
731      if(newsockfd < 0)
732      {
733        WerrorS("ERROR on accept");
734        l->data=NULL;
735        omFree(d);
736        return TRUE;
737      }
738      //PrintS("client accepted\n");
739      d->fd_read = newsockfd;
740      d->fd_write = newsockfd;
741      d->f_read = fdopen(newsockfd, "r");
742      d->f_write = fdopen(newsockfd, "w");
743      SI_LINK_SET_RW_OPEN_P(l);
744      close(sockfd);
745    }
746    else if(strcmp(mode,"connect")==0)
747    {
748      char* host = (char*)omAlloc(256);
749      int sockfd, portno, n;
750      struct sockaddr_in serv_addr;
751      struct hostent *server;
752
753      sscanf(l->name,"%255[^:]:%d",host,&portno);
754      //Print("connect to host %s, port %d\n",host,portno);mflush();
755      if (portno!=0)
756      {
757        sockfd = socket(AF_INET, SOCK_STREAM, 0);
758        if (sockfd < 0) { WerrorS("ERROR opening socket"); return TRUE; }
759        server = gethostbyname(host);
760        if (server == NULL) {  WerrorS("ERROR, no such host");  return TRUE; }
761        memset((char *) &serv_addr, 0, sizeof(serv_addr));
762        serv_addr.sin_family = AF_INET;
763        memcpy((char *)&serv_addr.sin_addr.s_addr,
764              (char *)server->h_addr,
765              server->h_length);
766        serv_addr.sin_port = htons(portno);
767        if (connect(sockfd,(sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
768        { WerrorS("ERROR connecting"); return TRUE; }
769        //PrintS("connected\n");mflush();
770        d->f_read=fdopen(sockfd,"r");
771        d->fd_read=sockfd;
772        d->f_write=fdopen(sockfd,"w");
773        d->fd_write=sockfd;
774        SI_LINK_SET_RW_OPEN_P(l);
775        omFree(host);
776      }
777      else
778      {
779        l->data=NULL;
780        omFree(d);
781        return TRUE;
782      }
783    }
784    else
785    {
786      // normal ascii link to a file
787      FILE *outfile;
788      char *filename=l->name;
789
790      if(filename[0]=='>')
791      {
792        if (filename[1]=='>')
793        {
794          filename+=2;
795          mode = "a";
796        }
797        else
798        {
799          filename++;
800          mode="w";
801        }
802      }
803      outfile=myfopen(filename,mode);
804      if (outfile!=NULL)
805      {
806        if (strcmp(l->mode,"r")==0) d->f_read = outfile;
807        else d->f_write = outfile;
808      }
809      else
810      {
811        omFree(d);
812        l->data=NULL;
813        return TRUE;
814      }
815    }
816  }
817
818  return FALSE;
819}
820
821//**************************************************************************/
822LINKAGE BOOLEAN ssiClose(si_link l)
823{
824  ssiInfo *d = (ssiInfo *)l->data;
825  if (d!=NULL)
826  {
827    if ((strcmp(l->mode,"tcp")==0)
828    || (strcmp(l->mode,"fork")==0))
829    {
830      fprintf(d->f_write,"99\n");fflush(d->f_write);
831      link_list hh=ssiToBeClosed;
832      if (hh->l==l)
833      {
834         ssiToBeClosed=(link_list)hh->next;
835         omFreeSize(hh,sizeof(link_struct));
836      }
837      else while(hh!=NULL)
838      {
839        link_list hhh=(link_list)hh->next;
840        if (hhh->l==l)
841        {
842          hh->next=hhh->next;
843          omFreeSize(hhh,sizeof(link_struct));
844          break;
845        }
846        hh=(link_list)hh->next;
847      }
848    }
849    if (d->f_read!=NULL) fclose(d->f_read);
850    if (d->f_write!=NULL) fclose(d->f_write);
851    if (d->r!=NULL) rKill(d->r);
852    if (d->pid!=0) { kill(d->pid,15); kill(d->pid,9); }
853    omFreeSize((ADDRESS)d,(sizeof *d));
854  }
855  l->data=NULL;
856  SI_LINK_SET_CLOSE_P(l);
857  return FALSE;
858}
859
860//**************************************************************************/
861LINKAGE leftv ssiRead1(si_link l)
862{
863  ssiInfo *d = (ssiInfo *)l->data;
864  leftv res=(leftv)omAlloc0(sizeof(sleftv));
865  int t=0;
866  fscanf(d->f_read,"%d",&t);
867  //Print("got type %d\n",t);
868  switch(t)
869  {
870    case 1:res->rtyp=INT_CMD;
871           res->data=(char *)ssiReadInt(d->f_read);
872           break;
873    case 2:res->rtyp=STRING_CMD;
874           res->data=(char *)ssiReadString(d);
875           break;
876    case 3:res->rtyp=NUMBER_CMD;
877           res->data=(char *)ssiReadNumber(d);
878           break;
879    case 4:res->rtyp=BIGINT_CMD;
880           res->data=(char *)ssiReadBigInt(d);
881           break;
882    case 15:
883    case 5:{
884             d->r=ssiReadRing(d);
885             d->r->ref++;
886             res->rtyp=RING_CMD;
887             res->data=(char*)d->r;
888             // we are in the top-level, so set the basering to d->r:
889             ssiSetCurrRing(d->r);
890             if (t==15) return ssiRead1(l);
891           }
892           break;
893    case 6:res->rtyp=POLY_CMD;
894           if (d->r==NULL) goto no_ring;
895           res->data=(char*)ssiReadPoly(d);
896           break;
897    case 7:res->rtyp=IDEAL_CMD;
898           if (d->r==NULL) goto no_ring;
899           res->data=(char*)ssiReadIdeal(d);
900           break;
901    case 8:res->rtyp=MATRIX_CMD;
902           if (d->r==NULL) goto no_ring;
903           res->data=(char*)ssiReadMatrix(d);
904           break;
905    case 9:res->rtyp=VECTOR_CMD;
906           if (d->r==NULL) goto no_ring;
907           res->data=(char*)ssiReadPoly(d);
908           break;
909    case 10:res->rtyp=MODUL_CMD;
910           if (d->r==NULL) goto no_ring;
911           res->data=(char*)ssiReadIdeal(d);
912           break;
913    case 11:
914           {
915             res->rtyp=COMMAND;
916             res->data=ssiReadCommand(l);
917             int nok=res->Eval();
918             if (nok) WerrorS("error in eval");
919             break;
920           }
921    case 12: /*DEF_CMD*/
922           {
923             res->rtyp=0;
924             res->name=(char *)ssiReadString(d);
925             int nok=res->Eval();
926             if (nok) WerrorS("error in name lookup");
927             break;
928           }
929    case 13: res->rtyp=PROC_CMD;
930             res->data=ssiReadProc(d);
931             break;
932    case 14: res->rtyp=LIST_CMD;
933             res->data=ssiReadList(l);
934             break;
935    case 16: res->rtyp=NONE; res->data=NULL;
936             break;
937    case 99: ssiClose(l); exit(0);
938    case 0: if (feof(d->f_read))
939            {
940              ssiClose(l);
941              res->rtyp=DEF_CMD;
942              break;
943            }
944    default: Werror("not implemented (t:%d)",t);
945             omFreeSize(res,sizeof(sleftv));
946             res=NULL;
947             break;
948  }
949  return res;
950no_ring: WerrorS("no ring");
951  return NULL;
952}
953//**************************************************************************/
954LINKAGE BOOLEAN ssiWrite(si_link l, leftv data)
955{
956  if(SI_LINK_W_OPEN_P(l)==0) slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL);
957  ssiInfo *d = (ssiInfo *)l->data;
958  d->level++;
959  //FILE *fich=d->f;
960  while (data!=NULL)
961  {
962    int tt=data->Typ();
963    void *dd=data->Data();
964
965    switch(tt /*data->Typ()*/)
966    {
967          case NONE/* nothing*/:fprintf(d->f_write,"16 ");
968                          break;
969          case STRING_CMD: fprintf(d->f_write,"2 ");
970                           ssiWriteString(d,(char *)dd);
971                           break;
972          case INT_CMD: fprintf(d->f_write,"1 ");
973                        ssiWriteInt(d,(int)(long)dd);
974                        break;
975          case BIGINT_CMD:fprintf(d->f_write,"4 ");
976                        ssiWriteBigInt(d,(number)dd);
977                        break;
978          case NUMBER_CMD:
979                          if (d->r!=currRing)
980                          {
981                            fprintf(d->f_write,"15 ");
982                            ssiWriteRing(d,currRing);
983                            if (d->level<=1) fprintf(d->f_write,"\n");
984                          }
985                          fprintf(d->f_write,"3 ");
986                          ssiWriteNumber(d,(number)dd);
987                        break;
988          case RING_CMD:fprintf(d->f_write,"5 ");
989                        ssiWriteRing(d,(ring)dd);
990                        break;
991          case POLY_CMD:
992          case VECTOR_CMD:
993                        if (d->r!=currRing)
994                        {
995                          fprintf(d->f_write,"15 ");
996                          ssiWriteRing(d,currRing);
997                          if (d->level<=1) fprintf(d->f_write,"\n");
998                        }
999                        if(tt==POLY_CMD) fprintf(d->f_write,"6 ");
1000                        else             fprintf(d->f_write,"9 ");
1001                        ssiWritePoly(d,tt,(poly)dd);
1002                        break;
1003          case IDEAL_CMD:
1004          case MODUL_CMD:
1005          case MATRIX_CMD:
1006                        if (d->r!=currRing)
1007                        {
1008                          fprintf(d->f_write,"15 ");
1009                          ssiWriteRing(d,currRing);
1010                          if (d->level<=1) fprintf(d->f_write,"\n");
1011                        }
1012                        if(tt==IDEAL_CMD)       fprintf(d->f_write,"7 ");
1013                        else if(tt==MATRIX_CMD) fprintf(d->f_write,"8 ");
1014                        else                    fprintf(d->f_write,"10 ");
1015                        ssiWriteIdeal(d,tt,(ideal)dd);
1016                        break;
1017          case COMMAND:
1018                   fprintf(d->f_write,"11 ");
1019                   ssiWriteCommand(l,(command)dd);
1020                   break;
1021          case DEF_CMD: /* not evaluated stuff in quotes */
1022                   fprintf(d->f_write,"12 ");
1023                   ssiWriteString(d,data->Name());
1024                   break;
1025          case PROC_CMD:
1026                   fprintf(d->f_write,"13 ");
1027                   ssiWriteProc(d,(procinfov)dd);
1028                   break;
1029          case LIST_CMD:
1030                   fprintf(d->f_write,"14 ");
1031                   ssiWriteList(l,(lists)dd);
1032                   break;
1033          default: Werror("not implemented (t:%d, rtyp:%d)",tt, data->rtyp);
1034                   d->level=0;
1035                   return TRUE;
1036    }
1037    if (d->level<=1) { fprintf(d->f_write,"\n"); fflush(d->f_write); }
1038    data=data->next;
1039  }
1040  d->level--;
1041  return FALSE;
1042}
1043
1044si_link_extension slInitSsiExtension(si_link_extension s)
1045{
1046  s->Open=ssiOpen;
1047  s->Close=ssiClose;
1048  s->Kill=ssiClose;
1049  s->Read=ssiRead1;
1050  s->Read2=(slRead2Proc)NULL;
1051  s->Write=ssiWrite;
1052
1053  s->Status=slStatusSsi;
1054  s->type="ssi";
1055  return s;
1056}
1057const char* slStatusSsi(si_link l, const char* request)
1058{
1059  ssiInfo *d=(ssiInfo*)l->data;
1060  if (d==NULL) return "not open";
1061  if (((strcmp(l->mode,"fork")==0)||(strcmp(l->mode,"tcp")==0))
1062  && (strcmp(request, "read") == 0))
1063  {
1064    fd_set  mask, fdmask;
1065    struct timeval wt;
1066    loop
1067    {
1068      /* Don't block. Return socket status immediately. */
1069      wt.tv_sec  = 0;
1070      wt.tv_usec = 0;
1071
1072      FD_ZERO(&mask);
1073      FD_SET(d->fd_read, &mask);
1074      //Print("test fd %d\n",d->fd_read);
1075    /* check with select: chars waiting: no -> not ready */
1076      switch (select(d->fd_read+1, &mask, NULL, NULL, &wt))
1077      {
1078        case 0: /* not ready */ return "not ready";
1079        case -1: /*error*/      return "error";
1080        case 1: /*ready ? */    break;
1081      }
1082    /* yes: read 1 char*/
1083    /* if \n, check again with select else ungetc(c), ready*/
1084      int c=fgetc(d->f_read);
1085      //Print("try c=%d\n",c);
1086      if (c== -1) return "eof";
1087      else if (isdigit(c))
1088      { ungetc(c,d->f_read); return "ready"; }
1089      else if (c>' ')
1090      {
1091        Werror("unknown char in ssiLink(%d)",c);
1092        return "error";
1093      }
1094      /* else: next char */
1095    }
1096  }
1097  else if (strcmp(request, "read") == 0)
1098  {
1099    if (SI_LINK_R_OPEN_P(l) && (!feof(d->f_read))) return "ready";
1100    else return "not ready";
1101  }
1102  else if (strcmp(request, "write") == 0)
1103  {
1104    if (SI_LINK_W_OPEN_P(l)) return "ready";
1105    else return "not ready";
1106  }
1107  else return "unknown status request";
1108}
1109
1110int slStatusSsiL(lists L, int timeout)
1111{
1112  si_link l;
1113  ssiInfo *d;
1114  fd_set  mask, fdmask;
1115  FD_ZERO(&mask);
1116  int max_fd=0; /* max fd in fd_set */
1117  struct timeval wt;
1118  int i;
1119  for(i=L->nr; i>=0; i--)
1120  {
1121    if (L->m[i].Typ()!=LINK_CMD)
1122    { WerrorS("all elements must be of type link"); return -2;}
1123    l=(si_link)L->m[i].Data();
1124    if(SI_LINK_OPEN_P(l)==0)
1125    { WerrorS("all links must be open"); return -2;}
1126    if ((strcmp(l->m->type,"ssi")!=0)
1127    || ((strcmp(l->mode,"fork")!=0) && (strcmp(l->mode,"tcp")!=NULL)))
1128    { WerrorS("all links must be of type ssi:fork or ssi:tcp"); return -2;}
1129    d=(ssiInfo*)l->data;
1130    FD_SET(d->fd_read, &mask);
1131    if (d->fd_read> max_fd) max_fd=d->fd_read;
1132  }
1133  max_fd++;
1134  struct timeval *wt_ptr=&wt;
1135  if (timeout== -1)
1136  {
1137    wt_ptr=NULL;
1138  }
1139  else
1140  {
1141    wt.tv_sec  = timeout / 1000000;
1142    wt.tv_usec = timeout % 1000000;
1143  }
1144  /* check with select: chars waiting: no -> not ready */
1145  int s= select(max_fd, &mask, NULL, NULL, wt_ptr);
1146  if (s==-1) return -2; /*error*/
1147  if (s==0)
1148  {
1149    return -1; /*poll: not ready */
1150  }
1151  else /* s>0, at least one ready */
1152  {
1153    int j=0;
1154    while (j<=max_fd) { if (FD_ISSET(j,&mask)) break; j++; }
1155    for(i=L->nr; i>=0; i--)
1156    {
1157      l=(si_link)L->m[i].Data();
1158      d=(ssiInfo*)l->data;
1159      if(j==d->fd_read) break;
1160    }
1161    loop
1162    {
1163      /* yes: read 1 char*/
1164      /* if \n, check again with select else ungetc(c), ready*/
1165      /* setting: d: current ssiInfo, j current fd, i current entry in L*/
1166      int c=fgetc(d->f_read);
1167      //Print("try c=%d\n",c);
1168      if (c== -1) return 0;
1169      else if (isdigit(c))
1170      { ungetc(c,d->f_read); return i+1; }
1171      else if (c>' ')
1172      {
1173        Werror("unknown char in ssiLink(%d)",c);
1174        return -2;
1175      }
1176      /* else: next char */
1177    }
1178  }
1179}
1180
1181int ssiBatch(const char *host, const char * port)
1182/* return 0 on success, >0 else*/
1183{
1184  si_link l=(si_link) omAlloc0Bin(sip_link_bin);
1185  char *buf=(char*)omAlloc(256);
1186  sprintf(buf,"ssi:connect %s:%s",host,port);
1187  slInit(l, buf);
1188  slOpen(l,SI_LINK_OPEN,NULL);
1189  SI_LINK_SET_RW_OPEN_P(l);
1190  loop
1191  {
1192    leftv h=ssiRead1(l); /*contains an exit.... */
1193    if (feErrors != NULL && *feErrors != '\0')
1194    {
1195      // handle errors:
1196      PrintS(feErrors); /* currently quite simple */
1197      *feErrors = '\0';
1198    }
1199    ssiWrite(l,h);
1200    h->CleanUp();
1201    omFreeBin(h, sleftv_bin);
1202  }
1203  /* never reached*/
1204  exit(0);
1205}
1206
1207// ----------------------------------------------------------------
1208// format
1209// 1 int %d
1210// 2 string <len> %s
1211// 3 number
1212// 4 bigint 4 %d or 3 <mpz_t>
1213// 5 ring
1214// 6 poly
1215// 7 ideal
1216// 8 matrix
1217// 9 vector
1218// 10 module
1219// 11 command
1220// 12 def <len> %s
1221// 13 proc <len> %s
1222// 14 list %d <elem1> ....
1223// 15 setring .......
1224// 16 nothing
1225//
1226// 99: quit Singular
Note: See TracBrowser for help on using the repository browser.