home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCP_Blars.lzh / dcpxfer.c < prev    next >
Text File  |  1991-11-02  |  11KB  |  517 lines

  1. /*
  2.  * dcpxfer.c
  3.  *
  4.  * Revised edition of dcp
  5.  *
  6.  * Stuart Lynne May/87
  7.  *
  8.  * Copyright (c) Richard H. Lamb 1985, 1986, 1987
  9.  * Changes Copyright (c) Stuart Lynne 1987
  10.  * Ported to OS-9/68000:  Wolfgang Ocker    January 1988
  11.  * further fix by Bob Larson
  12.  */
  13. /*
  14.  * "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987
  15.  * file send routines
  16.  */
  17.  
  18. #include "dcp.h"
  19. #include "uucp.h"
  20. char   *mfgets();
  21.  
  22. static unsigned char rpacket[MAXPACK];
  23. static unsigned char spacket[MAXPACK];
  24.  
  25. static time_t starttime, endtime;
  26. static char id[40];
  27.  
  28. extern char s_publicdir[];
  29.  
  30. static char send_delete = 0;
  31.  
  32. /*
  33.  *  s d a t a
  34.  *  Send File Data
  35.  */
  36. sdata()
  37. {
  38.     for(;;) {
  39.     if ((size = bufill(spacket)) == 0)
  40.         return seof();
  41.  
  42.     if ((*sendpkt) (spacket, size, 0))
  43.         return (0);
  44.     }
  45. }
  46.  
  47.  
  48. /*
  49.  *  b u f i l l
  50.  *
  51.  *  Get a bufferful of data from the file that's being sent.
  52.  *  Only control-quoting is done; 8-bit & repeat count prefixes are
  53.  *  not handled.
  54.  */
  55. bufill(buffer)
  56. char   *buffer;            /* Buffer */
  57. {
  58.     int     i, len;
  59.  
  60.     len = read(fp, buffer, pktsize);    /* Handle partial buffer */
  61.  
  62.  
  63.     return len;
  64. }
  65.  
  66.  
  67. /*
  68.  *  s b r e a k
  69.  *
  70.  *  Send Break (EOT)
  71.  */
  72. sbreak()
  73. {
  74.     int     len, i;
  75.  
  76.     sprintf(spacket, "H");
  77.  
  78.     if ((*sendpkt) (spacket, 0, 1))
  79.     return (0);
  80.  
  81.     if ((*getpkt) (spacket, &len))
  82.     return (0);
  83.  
  84.     printmsg(2, "Switch modes");
  85.  
  86.     if (spacket[1] == 'N')
  87.     return ('G');
  88.     return ('Y');
  89. }
  90.  
  91.  
  92. /*
  93.  *  s e o f
  94.  *
  95.  *  Send End-Of-File.
  96.  */
  97. seof()
  98. {
  99.     int     len, i, size;
  100.     int     Tick;
  101.     short   Day;
  102.     unsigned char Date[4], Time[4];
  103.  
  104.     if ((*sendpkt) (spacket, 0, 0))
  105.     return (0);
  106.  
  107.     if ((*getpkt) (spacket, &len))
  108.     return (0);        /* rec CY or CN */
  109.  
  110.     if (strncmp(spacket, "CY", 2))
  111.     return (0);        /* cant send file */
  112.  
  113.     size = _gs_size(fp);
  114.     time(&endtime);        /* Ende-Zeit */
  115.  
  116.     close(fp);
  117.     fp = (-1);
  118.  
  119.     if (send_delete) {
  120.         if (unlink(fromfile) < 0) {
  121.         printmsg(3, "delete of \"%s\" failed error %d", fromfile, errno);
  122.     } else {
  123.         printmsg(3, "delete of \"%s\" done", fromfile);
  124.     }
  125.     send_delete = 0;
  126.     }
  127.     printmsg(0, "Transfer of %s (%s) completed", fromfile, hostfile);
  128.  
  129.     _sysdate(0, Time, Date, &Day, &Tick);    /* Zeit und Datum holen */
  130.  
  131.     fprintf(syslog, "%s!%s (%02d/%02d-%02d:%02d:%02d) -> %ld / %ld secs (transmit)\n",
  132.         rmtname, id, Date[2], Date[3], Time[1], Time[2], Time[3],
  133.         size, endtime - starttime);
  134.  
  135.     return 'F';            /* go get the next file to send */
  136. }
  137.  
  138. #define PKTSIZE 64
  139.  
  140. /*
  141.  *  s f i l e
  142.  *
  143.  *  Send File Header.
  144.  */
  145. sfile()
  146. {
  147.     int     i, len;
  148.     char   *cp;
  149.     char    line[132];
  150.     char   *flds[10];
  151.  
  152.     if (fp != -1) {
  153.         printmsg(0, "sfile: file already open?");
  154.     return ('A');        /* If somethings already open. were in trouble */
  155.     }
  156.     printmsg(3, "sfile: looking for next file...");
  157.  
  158.     
  159. /*
  160.  *  read the next line from the presently open workfile
  161.  *  (cfile) and determines from this the next file to be sent
  162.  *  (file) or requested.
  163.  */
  164.  
  165.     if (mfgets(line, 132, fw) == NULL) {
  166.     fclose(fw);
  167.  
  168.     if (unlink(cfile) < 0)    /* close and delete completed workfile */
  169.         printmsg(0, "unlink work file \"%s\" failed error %d", cfile, errno);
  170.     else printmsg(2, "work file \"%s\" unlinked", cfile);
  171.     fw = NULL;
  172.     return ('B');        /* end sending session */
  173.     }
  174.     strcpy(hostfile, line);
  175.     printmsg(7, "   getfile: hostfile=\"%s\".", hostfile);
  176.     i = dgetargs(line, flds);
  177.     if (i < 3) {
  178.         printmsg(0, "Bad line \"%s\" in work file \"%s\"", hostfile, cfile);
  179.     fclose(fw);
  180.     fw = NULL;
  181.         return 'B';
  182.     }
  183.     strcpy(fromfile, flds[1]);
  184.     strcpy(tofile, flds[2]);
  185.     if (i >= 4) strcpy(id, flds[3]);
  186.     else *id = '\0';
  187.     printmsg(3, "   getfile: fromfile=%s, tofile=%s, id=%s", fromfile, tofile, id);
  188.  
  189.     switch (flds[0][0]) {
  190.  
  191.     case 'S':                /* send file */
  192.         if (*fromfile != '/') sprintf(fromfile, "%s/%s", rmtname, flds[1]);
  193.         send_delete = (i >= 5) && index(flds[4], 'c') == NULL;
  194.     printmsg(3, "sfile: Opening %s (%s) for sending.", fromfile, hostfile);
  195.     fp = open(fromfile, S_IREAD);    /* open the file to be sent */
  196.     if (fp == -1) {        /* If bad file pointer, give up */
  197.         printmsg(0, "sfile: Cannot open file %s (%s).", fromfile, hostfile);
  198.         fclose(fw);
  199.         fw = NULL;
  200.         return 'B';        /* We want to continue anyway */
  201.     }
  202.  
  203.     time(&starttime);
  204.     printmsg(0, "sfile: Sending %s (%s) as %s", fromfile, hostfile, tofile);
  205.     strcpy(spacket, hostfile);
  206.     for (len = strlen(spacket), cp = (char *) spacket;
  207.         len >= PKTSIZE; len -= PKTSIZE, cp += PKTSIZE)
  208.         if ((*sendpkt) (cp, PKTSIZE, 1))
  209.         return 0;    /* send S fromfile tofile */
  210.  
  211.     if ((*sendpkt) (cp, 0, 1))
  212.         return 0;        /* send S fromfile tofile */
  213.  
  214.     if ((*getpkt) (spacket, &len))
  215.         return 0;        /* user - tofile 0666. */
  216.  
  217.     if (spacket[1] != 'Y')
  218.         return 'A';        /* If otherside says no-quit */
  219.  
  220.     return 'D';
  221.  
  222.     case 'R':            /* request file */
  223.     printmsg(3, "sfile: Opening %s for request.", tofile);
  224.     if(openrec(fromfile, tofile) != 'Y') return 'A';
  225.  
  226.     time(&starttime);
  227.     printmsg(0, "sfile: Requesting %s (%s) as %s", fromfile, hostfile, tofile);
  228.     strcpy(spacket, hostfile);
  229.  
  230.     /* send R fromfile tofile user */
  231.     for (len = strlen(spacket), cp = (char *)spacket;
  232.         len >= PKTSIZE; len -= PKTSIZE, cp += PKTSIZE)
  233.         if((*sendpkt)(cp, PKTSIZE, 1))
  234.             return 0;
  235.     if ((*sendpkt) (cp, 0, 1))
  236.         return 0;
  237.  
  238.     if((*getpkt) (spacket, &len))
  239.         return 0;
  240.     if (spacket[1] != 'Y') {
  241.         close(fp);
  242.         fp = -1;
  243.         return 'A';
  244.     }
  245.     return 'R';
  246.  
  247.     case '\0':
  248.     case '#':            /* comment */
  249.         return 'F';
  250.  
  251.     default:            /* Defective control file */
  252.         printmsg(0, "sfile: Unknown request \"%s\" in work file \"%s\"",
  253.         hostfile, cfile);
  254.     fclose(fw);
  255.     fw = NULL;
  256.     return 'B';
  257.     }
  258. }
  259.  
  260.  
  261. /*
  262.  *  s i n i t
  263.  *
  264.  *  Send Initiate: send this host's parameters and get other side's back.
  265.  */
  266. sinit()
  267. {
  268.     if ((*openpk) ())
  269.     return ('A');
  270.     return ('B');
  271. }
  272.  
  273.  
  274. /*
  275.  * SUB SUB PROTOCOL
  276.  *
  277.  * schkdir
  278.  * scan the dir
  279.  */
  280. schkdir()
  281. {
  282.     char    c;
  283.  
  284.     c = scandir(TRUE);
  285.     if (c == 'Q')
  286.     return ('Y');
  287.     if (c == 'S') {
  288.     sprintf(rpacket, "HN");
  289.     if ((*sendpkt) (rpacket, 0, 1))
  290.         return (0);
  291.     }
  292.     return ('B');
  293. }
  294.  
  295.  
  296. /*
  297.  *      endp() end protocol
  298. */
  299. endp()
  300. {
  301.     sprintf(rpacket, "HY");
  302.  
  303.     (*sendpkt) (rpacket, 0, 2);    /* dont wait for ACK */
  304.     (*closepk) ();
  305.     return ('P');
  306. }
  307.  
  308.  
  309. /*
  310.  * RECIEVE PROTOCOL
  311.  *
  312.  *  r d a t a
  313.  *
  314.  *  Receive Data
  315.  */
  316. rdata()
  317. {
  318.     int     i, len;
  319.     int     Tick;
  320.     short   Day;
  321.     unsigned char Date[4], Time[4];
  322.  
  323.     if ((*getpkt) (rpacket, &len))
  324.     return (0);
  325.  
  326.     if (len == 0) {
  327.     size = _gs_size(fp);
  328.     time(&endtime);        /* Ende-Zeit */
  329.  
  330.     close(fp);
  331.     fp = -1;
  332.  
  333.     sprintf(rpacket, "CY");
  334.  
  335.     if ((*sendpkt) (rpacket, 0, 1))
  336.         return (0);
  337.  
  338.     _sysdate(0, Time, Date, &Day, &Tick);    /* Zeit und Datum holen */
  339.  
  340.     fprintf(syslog, "%s!%s (%02d/%02d-%02d:%02d:%02d) <- %ld / %ld secs (receive)\n",
  341.         rmtname, id, Date[2], Date[3], Time[1], Time[2], Time[3],
  342.         size, endtime - starttime);
  343.  
  344.     printmsg(0, "transfer complete");
  345.     return ('F');
  346.     }
  347.     write(fp, rpacket, len);    /* Write the data to the file */
  348.     return 'R';            /* Remain in data state */
  349. }
  350.  
  351.  
  352. /*
  353.  *  r f i l e
  354.  *
  355.  *  Receive File Header
  356.  */
  357. rfile()
  358. {
  359.     char    buf[256];
  360.     char   *flds[10];
  361.     int     numflds;
  362.     int     len, i;
  363.     char   *cp;
  364.  
  365.     printmsg(3, "rfile entered");
  366.  
  367.     cp = buf;
  368.  
  369.     while (TRUE) {
  370.     if ((*getpkt) (rpacket, &len))
  371.         return (0);
  372.  
  373.     strncpy(cp, rpacket, len);
  374.     cp += len;
  375.     if (*(cp - 1) == '\0')
  376.         break;
  377.     }
  378.  
  379.     if ((buf[0] & 0x7f) == 'H')
  380.     return ('C');
  381.  
  382.     printmsg(3, "rfile: buf %d \"%s\"", len, buf);
  383.  
  384.     numflds = dgetargs(buf, flds);
  385.  
  386.     switch(flds[0][0]) {
  387.     case 'S':                /* remote system sending file */
  388.         printmsg(3, "rfile: receive file \"%s\"", flds[2]);
  389.  
  390.         if(openrec(flds[1], flds[2]) != 'Y') return 'A';
  391.         printmsg(0, "Receiving %s as %s", flds[1], tofile);
  392.         time(&starttime);
  393.         strcpy(id, flds[3]);
  394.  
  395.         strcpy(rpacket, "SY");
  396.         if ((*sendpkt) (rpacket, 0, 1))
  397.             return 0;
  398.         return 'R';            /* Switch to receive data state */
  399.  
  400.     case 'R':                /* remote system requesting file */
  401.         send_delete = 0;
  402.         printmsg(3, "rfile: send file \"%s\"", flds[1]);
  403.     /* There should be some kind of a permissions file to restrict what
  404.      * can be requested.  Currently allow only files in uucppublic.
  405.      * Specifying a directory also needs to be fixed.
  406.      */
  407.     if(flds[1][0]=='~' && flds[1][1]=='/') {
  408.         strcpy(fromfile, s_publicdir);
  409.         strcat(fromfile, flds[1]+1);
  410.         fp = open(fromfile, S_IREAD);
  411.         if (fp < 0) {
  412.             printmsg(3, "rfile: error %d opening \"%s\"", errno, fromfile);
  413.             strcpy(rpacket, "RN2");
  414.         } else {
  415.         strcpy(rpacket, "RY");
  416.         }
  417.     } else {            /* don't allow getting other files */
  418.         printmsg(3, "rfile: not allowed");
  419.         strcpy(rpacket, "RN2");
  420.     }
  421.     time(&starttime);
  422.     if ((*sendpkt) (rpacket, 0, 1))
  423.         return 0;
  424.     if (rpacket[1] != 'Y') return 'B';
  425.     return 'D';
  426.  
  427.     default:
  428.         printmsg(0, "rfile: got unknown request '%c'", flds[0][0]);
  429.         return 'A';
  430.     }
  431. }
  432.  
  433.  
  434. openrec(ffile, tfile)
  435. char *ffile, *tfile;
  436. {
  437.     register char *cp;
  438.     char    tmpfilename[256];    /* Holds the converted file name */
  439.  
  440.     /* check for ~/ destination -> /usr/spool/uucppublic */
  441.  
  442.     if (strncmp(tfile, "~/", 2) == SAME)
  443.     sprintf(tmpfilename, "%s%s", s_publicdir, tfile + 1);
  444.     else if (index(cp, '/') != NULL) {
  445.     printmsg(0, "rfile: illegal filename \"%s\"", tfile);
  446.     sprintf(tmpfilename, "%s/illegalXXXXXX", s_publicdir);
  447.     mktemp(tmpfilename);
  448.     printmsg(0, "rfile: received as \"%s\"", tmpfilename);
  449.     } else
  450.     strcpy(tmpfilename, tfile);
  451.  
  452.     makedirectories(tmpfilename);
  453.  
  454.     /* check for dirname only */
  455.     cp = tmpfilename + strlen(tmpfilename) - 1;
  456.     if (*cp == '\n' || *cp == '\l')
  457.     *cp-- = '\0';
  458.  
  459.     printmsg(3, "openrec: receive file \"%s\"", tmpfilename);
  460.  
  461.     /* let host munge filename as appropriate */
  462.     strcpy(tofile, tmpfilename);
  463.  
  464.     /* Try to open a new file */
  465.     if ((fp = create(tofile, S_IWRITE, S_IREAD + S_IWRITE)) == -1) {
  466.     if (errno == E_CEF) {    /* Must be a trunctated, old file */
  467.         cp = rindex(tofile, '/');
  468.         if(cp) cp++;
  469.         else cp = tofile;
  470.         sprintf(tmpfilename, "%s/.ERROR/%sXXXXXX", SPOOLDIR, cp);
  471.         mktemp(tmpfilename);
  472.         printmsg(0, "moving %s to %s", tofile, tmpfilename);
  473.         if (rename(tofile, tmpfilename) < 0) {
  474.         printmsg(0, "cannot rename %s", tofile);
  475.         return 'A';
  476.         }
  477.         if ((fp = create(tofile, S_IWRITE, S_IREAD + S_IWRITE)) == -1) {
  478.         printmsg(0, "cannot create %s", tofile);    /* Give up if can't */
  479.         return 'A';
  480.         }
  481.     } else {
  482.         printmsg(0, "cannot create %s", tofile);    /* Give up if can't */
  483.         return 'A';
  484.     }
  485.     }
  486.     return 'Y';
  487. }
  488.  
  489.  
  490. /*
  491.  *  r i n i t
  492.  *
  493.  *  Receive Initialization
  494.  */
  495. rinit()
  496. {
  497.     if ((*openpk) ())
  498.     return (0);
  499.     return ('F');
  500. }
  501.  
  502. makedirectories(pathname)
  503. char   *pathname;
  504. {
  505.     register char *cp;
  506.     char    pn[250];
  507.  
  508.     strcpy(pn, pathname);
  509.     cp = pn;
  510.  
  511.     while ((cp = index(cp, '/')) != NULL) {
  512.     *cp = '\0';
  513.     makdir(pn, S_IREAD + S_IWRITE);
  514.     *cp++ = '/';
  515.     }
  516. }
  517.