home *** CD-ROM | disk | FTP | other *** search
/ Techno Guide - Aspettando Windows 98 / TechnoGuide.iso / internet / netterm / neted.c < prev    next >
C/C++ Source or Header  |  1996-09-10  |  13KB  |  386 lines

  1. /* nted.c
  2.  * copyright 1996 David J. Binette
  3.  * Thu Sep 05 04:33:43 GMT 1996, dbin
  4.  *
  5.  * This program may ONLY be distributed with sourcecode.
  6.  * (and any extensions you add)
  7.  *
  8.  * This program is FREEWARE, use it entirely at your own risk.
  9.  * if you use it, you assume the risk and consequences of any
  10.  * problems that may arise.
  11.  *
  12.  *
  13.  * This program may be freely distributed for use with netterm.
  14.  * Please leave my name in the credits list. (and add yours)
  15.  * email  dbin@sce.de
  16.  * www    http://www.sce.de
  17.  *
  18.  * netterm 3.0 was the current release when this program was written
  19.  * netterm is copyright Intersoft International Inc
  20.  * netterm email:  72060.2331@compuserve.com
  21.  *
  22.  *
  23.  * This program requires Chuck Forsbergs' ZMODEM file transfer program.
  24.  * zmodem   sz for sending files
  25.  * zmodem   rz for receiving files
  26.  * www  http://www.omen.com
  27.  *
  28.  *
  29.  * The remote editing feature of netterm is a great idea!
  30.  * Zmodem is a fine file transfer program.
  31.  *
  32.  * This program is a bit of glue to help manage remote editing
  33.  * when accessing unix files from DOS.
  34.  *
  35.  * It handles the problems of DOS editors that don't understand
  36.  * *N*X newline conventions.
  37.  * With this program you can use "notepad" or any other plain text
  38.  * editor to edit UNIX files locally on your PC.
  39.  *
  40.  * (check out James Iulianos' "lemmy" a fine VI compatible editor for DOS)
  41.  * ( http://www.accessone.com/~jai )
  42.  *
  43.  *
  44.  * This program "nted" works with netterm to manage remote file editing using
  45.  * netterms magic <esc>[6i code sequence.
  46.  * nted sends a file via zmodem to the remote host.
  47.  * Then the magic sequence is sent, causing the remote host
  48.  * to edit the received file, and lock the terminal screen.
  49.  *
  50.  * When the remote user is finished editing the file, the netterm program
  51.  * sends many carriage returns and an 'rz' command
  52.  * ( this breaks menu programs badly)
  53.  *
  54.  * we use Zmodems -a option to handle DOS cr/nl mapping when we send the file.
  55.  * we wait for the remote side to return the file, then we
  56.  * convert it back to unix format
  57.  * This program also handles pathnames properly allowing you to edit
  58.  * files that are not in the current directory.
  59.  *
  60.  * the program returns 1 if there is any error
  61.  *                     0 if all went well
  62.  *
  63.  *
  64.  * TAB STOPS ON THIS FILE are set to 4 spaces
  65.  *
  66.  * If your *NIX does not have strrchr(), try rindex()
  67.  */
  68.  
  69. /*
  70.  * Revision history
  71.  * Tue Sep 10 08:53:16 GMT 1996, dbin
  72.  * added command line options -a -b -v and -z"xxx"
  73.  * added multiple file editing
  74.  * handled case where the received filename
  75.  *         is converted to all upper or lower case
  76.  */
  77.  
  78. #include <stdio.h>
  79. #include <string.h>
  80. #include <sys/types.h>
  81. #include <sys/stat.h>
  82. #include <ctype.h>
  83. #include <stdlib.h>
  84. #include <unistd.h>
  85.  
  86. /* =================================================== */
  87.  
  88. #define CNV_NONE 0
  89. #define CNV_2NIX 1
  90. #define CNV_2DOS 2
  91.  
  92. /* default Zmodem option is -y overwrite destination file */
  93. #define ZMODEM_OPTS     "-y"
  94.  
  95. /* =================================================== */
  96.  
  97. char *Progname;
  98.  
  99. /* =================================================== */
  100.  
  101. /* display usage information and exit */
  102. void usage(void)
  103. {
  104.         fprintf(stderr,"usage: %s [options] filename\n", Progname);
  105.         fprintf(stderr,"See nted.c for program documentation and usage precautions.\n");
  106.         fprintf(stderr,"NOT TO BE DISTRIBUTED WITHOUT SOURCECODE\n");
  107.         fprintf(stderr,"Program author: David J. Binette September 10 1996\n");
  108.         fprintf(stderr,"-a      transfer file as ascii\n");
  109.         fprintf(stderr,"-b      transfer file as binary\n");
  110.         fprintf(stderr,"-v      verbose output\n");
  111.         fprintf(stderr,"-z\"xxx\" zmodem options\n");
  112.         exit(1);
  113. }
  114.  
  115. /* =================================================== */
  116.  
  117. /* copy an ASCII file
  118.  * line length limit 8Kb
  119.  * if the dos2nix flag is set: cr/nl is converted to nl on output
  120.  * if the dos2nix flag is clr: no special processing id done
  121.  *
  122.  * return 1 if error
  123.  *        0 if all ok
  124.  */
  125.  
  126. int copyfile(char *source, char *dest, int convert)
  127. {
  128.         FILE *ifp;
  129.         FILE *ofp;
  130.         char buf[8194];
  131.         int n;
  132.  
  133.         if((ifp = fopen(source,"r")) == (FILE*)0)
  134.         {
  135.                 perror(source);
  136.                 return 1;
  137.         }
  138.         if((ofp = fopen(dest,"w")) == (FILE*)0)
  139.         {
  140.                 perror(dest);
  141.                 fclose(ifp);
  142.                 return 1;
  143.         }
  144.  
  145.         while(fgets(buf, 8192, ifp))
  146.         {
  147.                 if(convert == CNV_2NIX)         /* strip CR (dos to nix conversion) */
  148.                 {
  149.                         if((n = strlen(buf)) > 1)
  150.                         {
  151.                                 if((buf[n-2] == '\r') && (buf[n-1] == '\n'))
  152.                                 {
  153.                                         buf[n-2] = '\n';
  154.                                         buf[n-1] = '\0';
  155.                                 }
  156.                         }
  157.                 }
  158.                 else
  159.                 if(convert == CNV_2DOS)         /* add CR (nix to dos conversion) */
  160.                 {
  161.                         if((n = strlen(buf)) > 1)
  162.                         {
  163.                                 if(buf[n-1] == '\n')
  164.                                 {
  165.                                         buf[n-1] = '\r';
  166.                                         buf[n]   = '\n';
  167.                                         buf[n+1] = '\0';
  168.                                 }
  169.                         }
  170.                 }
  171.  
  172.                 if(fputs(buf,ofp) == EOF)
  173.                 {
  174.                         perror(dest);
  175.                         fclose(ofp);
  176.                         fclose(ifp);
  177.                         return 1;
  178.                 }
  179.         }
  180.         fclose(ofp);
  181.         fclose(ifp);
  182.  
  183.         return 0;
  184. }
  185.  
  186. /* =================================================== */
  187. /* return base name of path/file */
  188. char * basename(char *s)
  189. {
  190.         char *p = s;
  191.         if((p = strrchr(s,'/')) != (char*)0)
  192.                 ++p;
  193.         else
  194.                 p=s;
  195.         return p;
  196. }
  197.  
  198. /* =================================================== */
  199.  
  200. void main(int argc, char **argv)
  201. {
  202.         char * origpathfile;            /* the original complete path/filename */
  203.         char * filename;                        /* the filename without any leading path */
  204.         char * origdir;                         /* current working directory */
  205.         char * zopt = ZMODEM_OPTS;      /* default is to overwrite files */
  206.         char newpathfile[1024];         /* the new complete path/filename */
  207.         char tmpdir[1024];                      /* a temporary working dir */
  208.         char buf[1024];                         /* a command line buffer */
  209.         int     verbose = 0;                    /* verbose mode */
  210.         int c;
  211.         int retval = 0;
  212.         int convert = 1;                        /* default 1 = send as ascii files */
  213.         extern char *optarg;            /* for getopt */
  214.         extern int optind;                      /* for getopt */
  215.  
  216.         Progname = basename(argv[0]);
  217.  
  218.         while((c = getopt(argc, argv, "abvz:")) != -1)
  219.         {
  220.                 switch (c) {
  221.                 case 'a': convert = 1;          break;
  222.                 case 'b': convert = 0;;         break;
  223.                 case 'v': verbose = 1;;         break;
  224.                 case 'z': zopt = optarg;        break;
  225.                 case '?': usage();                      break;
  226.                 }
  227.         }
  228.  
  229.         if(optind == argc)
  230.                 usage();
  231.  
  232.         /* determine the current directory name */
  233.         if((origdir = getcwd(NULL, 2048)) == NULL)
  234.         {
  235.                 perror("pwd");
  236.                 exit(1);
  237.         }
  238.  
  239.         /* make a working directory */
  240.         sprintf(tmpdir,"/tmp/nted.%d", getpid());
  241.         if(mkdir(tmpdir, S_IEXEC | S_IREAD | S_IWRITE))
  242.         {
  243.                 perror(tmpdir);
  244.                 exit(1);
  245.         }
  246.  
  247.         /* now process all of the specified files */
  248.         /* each file is sent, edited and retrieved seperately */
  249.  
  250.         for( ; optind < argc; optind++)
  251.         {
  252.  
  253.                 /* split the original filename */
  254.                 origpathfile    = argv[optind];
  255.                 filename                = basename(argv[optind]);
  256.  
  257.                 /* copy the file to the temporary directory */
  258.                 sprintf(newpathfile,"%s/%s", tmpdir, filename);
  259.  
  260.                 if(copyfile(origpathfile, newpathfile, convert ? CNV_2DOS : 0))
  261.                 {
  262.                         unlink(newpathfile);
  263.                         rmdir(tmpdir);
  264.                         exit(1);
  265.                 }
  266.  
  267.                 /* make the temp directory the current directory */
  268.                 if(chdir(tmpdir))
  269.                 {
  270.                         perror(tmpdir);
  271.                         unlink(newpathfile);
  272.                         rmdir(tmpdir);
  273.                         exit(1);
  274.                 }
  275.  
  276.                 /* Use Zmodem to transfer the file */
  277.                 if(verbose)
  278.                         fprintf(stderr,"Sending file to PC for editing\n");
  279.                 sprintf(buf, "sz %s %s\n",zopt, filename);
  280.                 if((retval = system(buf)) != 0)
  281.                         fprintf(stderr,"%s: warning! system returned %d\n", retval);
  282.  
  283.                 /* trash the copy, we dont need it anymore */
  284.                 unlink(newpathfile);
  285.  
  286.                 /* send netterm magic */
  287.                 /* causes netterm to invoke editor on received file */
  288.                 fputs("\033[6i", stderr);
  289.                 fflush(stderr);
  290.  
  291.                 /* now wait for some kind of user input
  292.                  * or the other side to send back the file
  293.                  */
  294.  
  295.                 retval = 1;
  296.                 while(1)
  297.                 {
  298.                         if(verbose)
  299.                                 fprintf(stderr,
  300.                                         "You are remotely editing \"%s\"\n",
  301.                                         origpathfile);
  302.                         fprintf(stderr,"type OK to continue\n");
  303.                         fflush(stderr);
  304.  
  305.                         buf[0] = '\0';
  306.                         if(fgets(buf,sizeof(buf), stdin) == NULL)
  307.                                 break;
  308.  
  309.                         buf[0] = (char)tolower(buf[0]);
  310.                         buf[1] = (char)tolower(buf[1]);
  311.  
  312.                         if( (buf[0] == 'o') && (buf[1] == 'k') )
  313.                                 break;
  314.  
  315.                         /* receive the edited file */
  316.                         if((buf[0] == 'r') && (buf[1] == 'z'))
  317.                         {
  318.                                 if(verbose)
  319.                                         fprintf(stderr,
  320.                                                         "Now receiving updated file from remote editor\n");
  321.                                 system("rz");
  322.                                 retval = 0;
  323.                                 break;
  324.                         }
  325.                 }
  326.  
  327.                 /* go back to the original directory */
  328.                 chdir(origdir);
  329.  
  330.                 if(retval == 0) /* copy the file to its destination */
  331.                 {
  332.                         int filerror = 0;                       /* filename error? on receive */
  333.  
  334.                         if(access(newpathfile,F_OK))
  335.                         {
  336.                                 /* the expected file was NOT found */
  337.                                 /* convert it to lowercase and try again */
  338.                                 char *p;
  339.                                 p = basename(newpathfile);
  340.                                 while(p && *p)
  341.                                 {
  342.                                         *p = (char)tolower(*p);
  343.                                         p++;
  344.                                 }
  345.                         }
  346.                         if(access(newpathfile,F_OK))
  347.                         {
  348.                                 /* the expected file was NOT found */
  349.                                 /* convert it to uppercase and try again */
  350.                                 char *p;
  351.                                 p = basename(newpathfile);
  352.                                 while(p && *p)
  353.                                 {
  354.                                         *p = (char)toupper(*p);
  355.                                         p++;
  356.                                 }
  357.                         }
  358.                         if(access(newpathfile,F_OK))
  359.                         {
  360.                                 filerror = 1;
  361.                                 fprintf(stderr,
  362.                                                 "Sorry, the remote PC returned an unknown file\n");
  363.                                 fprintf(stderr,
  364.                                                 "look in %s\n",tmpdir);
  365.                         }
  366.                         else
  367.                         {
  368.                                 filerror = copyfile(newpathfile,
  369.                                                         origpathfile,
  370.                                                         convert ? CNV_2NIX : 0) != 0;
  371.                         }
  372.                         if(filerror)
  373.                         {
  374.                                 fprintf(stderr,"press [ENTER] to continue");
  375.                                 fgets(buf,sizeof(buf), stdin);
  376.                         }
  377.                 }
  378.  
  379.                 unlink(newpathfile);
  380.         }
  381.         rmdir(tmpdir);
  382.         exit(0);
  383. }
  384.  
  385. /* =================================================== */
  386.