home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume32 / ecu / part23 < prev    next >
Encoding:
Text File  |  1992-09-13  |  56.9 KB  |  2,184 lines

  1. Newsgroups: comp.sources.misc
  2. From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  3. Subject:  v32i058:  ecu - ECU Asynchronous Communications v3.20, Part23/40
  4. Message-ID: <1992Sep14.143823.20710@sparky.imd.sterling.com>
  5. X-Md4-Signature: a751b9ebe61e7696ed28c05ba92ceb1b
  6. Date: Mon, 14 Sep 1992 14:38:23 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  10. Posting-number: Volume 32, Issue 58
  11. Archive-name: ecu/part23
  12. Environment: SCO,XENIX,ISC,SUNOS,SYSVR4,HDB,Curses
  13. Supersedes: ecu: Volume 21, Issue 53-89
  14.  
  15. ---- Cut Here and feed the following to sh ----
  16. #!/bin/sh
  17. # this is ecu320.23 (part 23 of ecu320)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file help/ecuhelp.src continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 23; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping help/ecuhelp.src'
  35. else
  36. echo 'x - continuing file help/ecuhelp.src'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'help/ecuhelp.src' &&
  38. X
  39. XA similar feature is provided under SVR4 and SunOS.  See the ecu manual
  40. Xand your system's termio man page (termios for SunOS) for details.
  41. X#--------------------------------------------------------------------
  42. X%sdname
  43. XUsage: sdname [<filename> | ]
  44. X
  45. XThis command sets or displays the current screen dump filename.
  46. XUntil the command is issued, screen dump data is placed in
  47. X~/.ecu/screen.dump.
  48. X#--------------------------------------------------------------------
  49. X%sgr
  50. XUsage: sgr mode cmd
  51. X
  52. XThis experimental command is used to test the timed read primitive
  53. Xused by ECU.  The command <cmd> is sent to the line and a timed read
  54. Xis performed.  The data returned is displayed in hexadecimal format on
  55. Xthe console.  The stimulus (cmd) and response is logged in
  56. X./ecu.sgr.log if the current directory must be writable.  Refer to
  57. Xsource module ecugrabbag.c function send_get_response() for details.
  58. X#--------------------------------------------------------------------
  59. X%ts
  60. XUsage: ts
  61. X
  62. XThis experimental command displays raw termio structure information
  63. Xfor the console and the tty.  It is primarily used in debugging ECU.
  64. X#--------------------------------------------------------------------
  65. X%xlog
  66. XUsage: xlog [y | n]
  67. X
  68. XThis experimental command controls exhaustive logging by the X, Y, and
  69. XZMODEM file transfer protocols to files named /tmp/szNNNNN.log or
  70. X/tmp/rzNNNNN.log where NNNNN is the process id of the transfer process.
  71. X#--------------------------------------------------------------------
  72. X%eto
  73. XUsage: eto [msec]
  74. X
  75. XThis experimental command sets or displays the "escape timeout"
  76. Xfor non-multiscreen function key detection.  Use caution: although
  77. Xthe command has a lower limit, you may set the value low enough
  78. Xnot to be able to use the HOME key!
  79. X#--------------------------------------------------------------------
  80. X%nice
  81. XUsage: nice [niceval]
  82. X
  83. XThis command sets or displays the process nice value.  The usual
  84. Xrules apply (hint: you might accidently nice4 yourself into not
  85. Xgetting enough CPU!)
  86. X#--------------------------------------------------------------------
  87. X%pushd
  88. XUsage: pushd [ | <dir> ]
  89. X
  90. XThis command either 1) pushes the current directory pathname onto
  91. Xa stack and establishes a new direcctory or 2) shows the current
  92. Xstack.  Issuing the command with no argument displays the stack.
  93. X#--------------------------------------------------------------------
  94. X%popd
  95. XUsage: pushd [ | <#> | all ]
  96. X
  97. XThis command pops one, many or all of the entries off diretory stack,
  98. Xrestoring a previous directory.  No argument results in one directory
  99. Xbeing popped.  A numeric argument pops the stack to a specified level.
  100. X'all' is equal to the numeric value 0 (and may be abbreviasted 'a').
  101. SHAR_EOF
  102. echo 'File help/ecuhelp.src is complete' &&
  103. chmod 0644 help/ecuhelp.src ||
  104. echo 'restore of help/ecuhelp.src failed'
  105. Wc_c="`wc -c < 'help/ecuhelp.src'`"
  106. test 30182 -eq "$Wc_c" ||
  107.     echo 'help/ecuhelp.src: original size 30182, current size' "$Wc_c"
  108. rm -f _shar_wnt_.tmp
  109. fi
  110. # ============= ecuungetty/ecuungetty.c ==============
  111. if test -f 'ecuungetty/ecuungetty.c' -a X"$1" != X"-c"; then
  112.     echo 'x - skipping ecuungetty/ecuungetty.c (File already exists)'
  113.     rm -f _shar_wnt_.tmp
  114. else
  115. > _shar_wnt_.tmp
  116. echo 'x - extracting ecuungetty/ecuungetty.c (Text)'
  117. sed 's/^X//' << 'SHAR_EOF' > 'ecuungetty/ecuungetty.c' &&
  118. Xchar *revision = "@(#)ecuungetty 3.20";
  119. X
  120. X#if defined(SHARE_DEBUG)
  121. X#ifndef ECUUNGETTY_DEBUG
  122. X#define ECUUNGETTY_DEBUG
  123. X#endif
  124. X#endif
  125. X
  126. X/*+-------------------------------------------------------------------------
  127. X    ecuungetty.c - ecu "ungetty" program
  128. X    wht@n4hgf.Mt-Park.GA.US
  129. X
  130. XGet a line:
  131. Xecuungetty /dev/ttyxx <bamboozle-str>
  132. Xecuungetty -g /dev/ttyxx <bamboozle-str>
  133. X
  134. XTest a line's atatus:
  135. Xecuungetty -t /dev/ttyxx <bamboozle-str>
  136. X
  137. XReturn a line:
  138. Xecuungetty -r /dev/ttyxx <bamboozle-str>
  139. X
  140. X  Defined functions:
  141. X    assign_tty(tty,uid,gid,mode)
  142. X    ecu_log_event(pid,event_note)
  143. X    errno_text(errnum)
  144. X    eug_exit(code)
  145. X    main(argc,argv,envp)
  146. X    termecu()
  147. X
  148. XNo effort is made to close the passwd file with endpwent().
  149. XI use setpwent() instead.  It is so contrary for me to leave
  150. Xa file open that I just had to put a reminder to myself here.
  151. XIf the program lived for more than 1/2 second, I'd probably
  152. Xkeep to my usual practice.
  153. X--------------------------------------------------------------------------*/
  154. X/*+:EDITS:*/
  155. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  156. X/*:09-02-1992-07:10-wht@n4hgf-DEBUG now gets actual user log file name */
  157. X/*:09-02-1992-06:48-wht@n4hgf-UG_RESTART exit any time we chown tty to user */
  158. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  159. X/*:08-16-1992-01:59-wht@n4hgf-absolutely ensure no chown/chmod of /dev/tty */
  160. X/*:08-07-1992-18:50-wht@n4hgf-chown/chmod both tty names on SCO */
  161. X/*:07-19-1992-09:07-wht@n4hgf-"rudimentary" security/validity checks on tty */
  162. X/*:06-19-1992-20:27-root@n4hgf-needed ECUUNGETTY_CHOWN in another place */
  163. X/*:06-04-1992-12:21-wht@n4hgf-chown/chmod with debugging */
  164. X/*:04-27-1992-19:30-wht@n4hgf-add optional chown/chmod */
  165. X/*:04-24-1992-20:12-wht@n4hgf-bel@nosc.mil found long time bug - bad kill */
  166. X/*:08-10-1991-17:39-wht@n4hgf-US_WEGOTIT handling */
  167. X/*:08-07-1991-14:15-wht@n4hgf-add debug log event code */
  168. X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
  169. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  170. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  171. X
  172. X#include <stdio.h>
  173. X#include <ctype.h>
  174. X#include <fcntl.h>
  175. X#include <string.h>
  176. X#include <errno.h>
  177. X#include <signal.h>
  178. X#include "../ecu_types.h"
  179. X#include "../ecu_stat.h"
  180. X#include <utmp.h>
  181. X#include <sys/locking.h>
  182. X#include "../ecuungetty.h"
  183. X#include "../utmpstatus.h"
  184. X#include "../ttynaming.h"
  185. X
  186. X#ifdef ECUUNGETTY_CHOWN
  187. X#include <pwd.h>
  188. Xstruct passwd *uupw;
  189. Xstruct passwd uucp_pwd;
  190. X#endif
  191. X
  192. Xvoid eug_exit();
  193. X
  194. Xextern struct utmp last_utmp;
  195. X
  196. Xint real_uid;
  197. Xint xmtr_pid;
  198. Xstruct stat tstat;
  199. X
  200. Xchar **gargv;
  201. Xint gargc;
  202. X
  203. X#if defined(ECUUNGETTY_DEBUG)
  204. Xchar s256[256];
  205. X#endif /* ECUUNGETTY_DEBUG */
  206. X
  207. X/*+-------------------------------------------------------------------------
  208. X    ecu_log_event(pid,event_note)
  209. X--------------------------------------------------------------------------*/
  210. Xvoid
  211. Xecu_log_event(pid,event_note)
  212. Xint pid;
  213. Xchar *event_note;
  214. X{
  215. X#if defined(ECUUNGETTY_DEBUG)
  216. X    FILE *ecu_log_fp;
  217. X    static char logname[256] = "";
  218. X
  219. X    if(!logname[0])
  220. X    {
  221. X        struct passwd *uidpw;
  222. X        setpwent();
  223. X        if(!(uidpw = getpwuid(real_uid)))
  224. X            eug_exit(UGE_LOGIC);
  225. X        strcpy(logname,uidpw->pw_dir);
  226. X        strcat(logname,"/.ecu/log");
  227. X    }
  228. X
  229. X    if((ecu_log_fp = fopen(logname,"a")) != NULL)
  230. X    {
  231. X        locking(fileno(ecu_log_fp),LK_LOCK,0L);
  232. X        fputs("ECUUNGET",ecu_log_fp);
  233. X        fprintf(ecu_log_fp,"-%05d-(%05d) ",getppid(),pid);
  234. X        fputs(event_note,ecu_log_fp);
  235. X        fputs("\n",ecu_log_fp);
  236. X        fflush(ecu_log_fp);
  237. X        locking(fileno(ecu_log_fp),LK_UNLCK,0L);
  238. X        fclose(ecu_log_fp);
  239. X    }
  240. X#endif
  241. X}    /* end of ecu_log_event */
  242. X
  243. X/*+-------------------------------------------------------------------------
  244. X    assign_tty(tty,uid,gid,mode) - set a tty owner, group, mode
  245. X
  246. Xreturns 0 on success, -1 on error
  247. X--------------------------------------------------------------------------*/
  248. Xint
  249. Xassign_tty(tty,uid,gid,mode)
  250. Xchar *tty;
  251. Xint uid;
  252. Xint gid;
  253. Xint mode;
  254. X{
  255. X#ifndef ECUUNGETTY_CHOWN
  256. X    return(0);
  257. X#else
  258. X#if defined(ECUUNGETTY_DEBUG)
  259. X    struct stat tstat2;
  260. X#endif /* ECUUNGETTY_DEBUG */
  261. X#ifdef SCO_TTY_NAMING
  262. X    char other_tty[128];
  263. X    int itmp;
  264. X    char *cptr;
  265. X#endif /* SCO_TTY_NAMING */
  266. X#if defined(ECUUNGETTY_DEBUG) && defined(SCO_TTY_NAMING)
  267. X    struct stat otstat;
  268. X#endif /* ECUUNGETTY_DEBUG && SCO_TTY_NAMING */
  269. X
  270. X    if(!strcmp(tty,"/dev/tty"))    /* somebody reported this is still happening */
  271. X        eug_exit(UGE_BADARGV);
  272. X
  273. X#ifdef SCO_TTY_NAMING
  274. X    itmp = strlen(tty);
  275. X    if(itmp > 1)
  276. X    {
  277. X        strcpy(other_tty,tty);
  278. X        cptr = other_tty + itmp - 1;
  279. X        if(isalpha(*cptr))
  280. X            *cptr = (isupper(*cptr)) ? tolower(*cptr) : toupper(*cptr);
  281. X#if defined(ECUUNGETTY_DEBUG)
  282. X        stat(other_tty,&otstat);
  283. X#endif /* ECUUNGETTY_DEBUG */
  284. X        chown(other_tty,uid,gid);
  285. X        chmod(other_tty,(unsigned short)mode);
  286. X    }
  287. X#endif /* SCO_TTY_NAMING */
  288. X
  289. X    chown(tty,uid,gid);
  290. X    chmod(tty,(unsigned short)mode);
  291. X
  292. X#if defined(ECUUNGETTY_DEBUG)
  293. X    stat(tty,&tstat2);
  294. X    sprintf(s256,"TTY '%s' o=(%d,%d) m=0%o (was %d,%d,0%o)",
  295. X        tty,
  296. X        tstat2.st_uid,tstat2.st_gid,tstat2.st_mode & 0777,
  297. X        tstat.st_uid,tstat.st_gid,tstat.st_mode & 0777);
  298. X    ecu_log_event(getpid(),s256);
  299. X#ifdef SCO_TTY_NAMING
  300. X    stat(other_tty,&tstat2);
  301. X    sprintf(s256,"TTY '%s' o=(%d,%d) m=0%o (was %d,%d,0%o)",
  302. X        other_tty,
  303. X        tstat2.st_uid,tstat2.st_gid,tstat2.st_mode & 0777,
  304. X        otstat.st_uid,otstat.st_gid,otstat.st_mode & 0777);
  305. X    ecu_log_event(getpid(),s256);
  306. X#endif /* SCO_TTY_NAMING */
  307. X#endif /* ECUUNGETTY_DEBUG */
  308. X
  309. X#endif /* ECUUNGETTY_CHOWN */
  310. X}    /* end of assign_tty */
  311. X
  312. X/*+-------------------------------------------------------------------------
  313. X    eug_exit(code) - exit() with debug logging
  314. X--------------------------------------------------------------------------*/
  315. Xvoid
  316. Xeug_exit(code)
  317. Xint code;
  318. X{
  319. X#if defined(ECUUNGETTY_DEBUG)
  320. X    int iargv;
  321. X    char s1024[1024];
  322. X    s1024[0] = 0;
  323. X    for(iargv = 1; iargv < gargc; iargv++)
  324. X    {
  325. X        strcat(s1024,gargv[iargv]);
  326. X        strcat(s1024," ");
  327. X    }
  328. X    sprintf(s1024 + strlen(s1024),"exit code %d",code);
  329. X    ecu_log_event(getpid(),s1024);
  330. X#endif
  331. X    exit(code);
  332. X}    /* end of eug_exit */
  333. X
  334. X/*+-------------------------------------------------------------------------
  335. X    termecu() - "dummy" for utmpstat.c
  336. X
  337. XThis particular incantation will only be called if utmp is non-existent
  338. Xor not readable.......
  339. X--------------------------------------------------------------------------*/
  340. Xtermecu()
  341. X{
  342. X    eug_exit(UGE_LOGIC);
  343. X}    /* end of hangup */
  344. X
  345. X/*+-------------------------------------------------------------------------
  346. X    errno_text(errnum)
  347. X--------------------------------------------------------------------------*/
  348. Xchar *
  349. Xerrno_text(errnum)
  350. Xint errnum;
  351. X{
  352. X    static char errstr[16];
  353. X    sprintf(errstr,"%d",errnum);
  354. X    return(errstr);
  355. X}    /* end of errno_text */
  356. X
  357. X/*+-------------------------------------------------------------------------
  358. X    main(argc,argv,envp)
  359. X--------------------------------------------------------------------------*/
  360. Xmain(argc,argv,envp)
  361. Xint argc;
  362. Xchar **argv;
  363. Xchar **envp;
  364. X{
  365. X    int op = 'g';    /* assume "get" operation */
  366. X    int status;
  367. X    int itmp;
  368. X    char *cptr;
  369. X    char *tty = argv[1];
  370. X    char *bamboozlement = argv[2];
  371. X    char *bamboozle();
  372. X
  373. X    gargv = argv;
  374. X    gargc = argc;
  375. X
  376. X    real_uid = getuid();
  377. X    if(geteuid())
  378. X        eug_exit(UGE_NOTROOT);
  379. X
  380. X#ifdef ECUUNGETTY_CHOWN
  381. X    if(!(uupw = getpwnam("uucp")))
  382. X        eug_exit(UGE_NOUUCP);
  383. X    uucp_pwd = *uupw;
  384. X    uupw = &uucp_pwd;
  385. X#endif
  386. X
  387. X    if(*argv[1] == '-')
  388. X    {
  389. X        switch(op = *(argv[1] + 1))
  390. X        {
  391. X        case 'r':
  392. X        case 't':
  393. X            break;
  394. X        default:
  395. X            eug_exit(UGE_BADSWITCH);
  396. X        }
  397. X        if(argc < 3)
  398. X            eug_exit(UGE_BADARGC);
  399. X        tty = argv[2];
  400. X        bamboozlement = argv[3];
  401. X    }
  402. X    else if(argc <= 2)
  403. X        eug_exit(UGE_BADARGC);
  404. X
  405. X    if(real_uid)    /* if caller not actually root */
  406. X    {
  407. X        if(strcmp(bamboozlement,bamboozle(getppid())))
  408. X            eug_exit(UGE_CALLER);
  409. X    }
  410. X
  411. X    /*
  412. X     * rudimentary checks
  413. X     * must be in /dev, no ".." in path,not /dev/tty,must be char special
  414. X     */
  415. X    if(strncmp(tty,"/dev/",5))
  416. X        eug_exit(UGE_BADARGV);
  417. X    if((cptr = strchr(tty,'.')) && (*(cptr + 1) == '.'))
  418. X        eug_exit(UGE_BADARGV);
  419. X    if(!strcmp(tty,"/dev/tty"))
  420. X        eug_exit(UGE_BADARGV);
  421. X    if(stat(tty,&tstat))
  422. X    {
  423. X#if defined(ECUUNGETTY_DEBUG)
  424. X        sprintf(s256,"TTY '%s' stat error %d",tty,errno);
  425. X        ecu_log_event(getpid(),s256);
  426. X#endif /* ECUUNGETTY_DEBUG */
  427. X        eug_exit(UGE_BADARGV);
  428. X    }
  429. X    if((tstat.st_mode & S_IFMT) != S_IFCHR)
  430. X        eug_exit(UGE_BADARGV);
  431. X
  432. X    xmtr_pid = getppid();
  433. X    status = utmp_status(tty);
  434. X#if defined(ECUUNGETTY_DEBUG)
  435. X    sprintf(s256,"-%c utmp status=%d",op,status);
  436. X    ecu_log_event(getpid(),s256);
  437. X#endif
  438. X
  439. X    switch(op)
  440. X    {
  441. X    case 'g':
  442. X        switch(status)
  443. X        {
  444. X        case US_NOTFOUND:    /* not in utmp, or getty dead */
  445. X            itmp = assign_tty(tty,real_uid,getgid(),0622);
  446. X            eug_exit((itmp) ? UG_NOTENAB : UG_RESTART);
  447. X        case US_LOGIN:        /* enabled for login, idle */
  448. X            kill(last_utmp.ut_pid,SIGUSR1);
  449. X            nap(200L);
  450. X            itmp = assign_tty(tty,real_uid,getgid(),0622);
  451. X            eug_exit((itmp) ? UG_NOTENAB : UG_RESTART);
  452. X        case US_DIALOUT:    /* enabled for login, currently dialout */
  453. X        case US_LOGGEDIN:    /* enabled for login, in use */
  454. X            eug_exit(UG_FAIL);
  455. X        case US_WEGOTIT:    /* we on it */
  456. X            itmp = assign_tty(tty,real_uid,getgid(),0622);
  457. X#if 1
  458. X            eug_exit((itmp) ? UG_NOTENAB : UG_RESTART);
  459. X#else
  460. X            if(!kill(last_utmp.ut_pid,0))    /* is there a getty? */
  461. X                eug_exit(UG_RESTART);        /* yes */
  462. X            else
  463. X                eug_exit(UG_NOTENAB);
  464. X#endif
  465. X        }
  466. X        break;
  467. X
  468. X    case 't':    /* no longer called by ecu as of BETA 3.20.02 */
  469. X        switch(status)
  470. X        {
  471. X        case US_NOTFOUND:    /* not in utmp, or getty dead */
  472. X#ifdef ECUUNGETTY_CHOWN
  473. X            assign_tty(tty,uupw->pw_uid,uupw->pw_gid,0640);
  474. X#endif
  475. X            eug_exit(UGE_T_NOTFOUND);
  476. X        case US_LOGIN:        /* enabled for login, idle */
  477. X            eug_exit(UGE_T_LOGIN);
  478. X        case US_LOGGEDIN:    /* enabled for login, in use */
  479. X            eug_exit(UGE_T_LOGGEDIN);
  480. X        case US_WEGOTIT:    /* we have the line */
  481. X#ifdef ECUUNGETTY_CHOWN
  482. X            assign_tty(tty,uupw->pw_uid,uupw->pw_gid,0640);
  483. X#endif
  484. X            eug_exit(UG_RESTART);
  485. X        case US_DIALOUT:    /* enabled for login, currently dialout */
  486. X            eug_exit(UG_RESTART);
  487. X        }
  488. X        break;
  489. X
  490. X    case 'r':
  491. X        switch(status)
  492. X        {
  493. X        case US_NOTFOUND:    /* not in utmp, or getty dead */
  494. X        case US_LOGIN:        /* enabled for login, idle */
  495. X#ifdef ECUUNGETTY_CHOWN
  496. X            assign_tty(tty,uupw->pw_uid,uupw->pw_gid,0640);
  497. X#endif
  498. X            eug_exit(0);
  499. X        case US_LOGGEDIN:    /* enabled for login, in use */
  500. X            eug_exit(0);
  501. X        case US_WEGOTIT:    /* we own it */
  502. X        case US_DIALOUT:    /* enabled for login, currently dialout */
  503. X#ifdef ECUUNGETTY_CHOWN
  504. X            assign_tty(tty,uupw->pw_uid,uupw->pw_gid,0640);
  505. X#endif
  506. X            itmp = 5;
  507. X            while(itmp--)
  508. X            {
  509. X                if(kill(last_utmp.ut_pid,SIGUSR2))
  510. X                    break;
  511. X                nap(100L);
  512. X            }
  513. X            eug_exit(0);
  514. X        }
  515. X        break;
  516. X    }
  517. X    eug_exit(UGE_LOGIC);
  518. X}    /* end of main */
  519. X
  520. X/* vi: set tabstop=4 shiftwidth=4: */
  521. X/* end of ecuungetty.c */
  522. SHAR_EOF
  523. chmod 0644 ecuungetty/ecuungetty.c ||
  524. echo 'restore of ecuungetty/ecuungetty.c failed'
  525. Wc_c="`wc -c < 'ecuungetty/ecuungetty.c'`"
  526. test 10470 -eq "$Wc_c" ||
  527.     echo 'ecuungetty/ecuungetty.c: original size 10470, current size' "$Wc_c"
  528. rm -f _shar_wnt_.tmp
  529. fi
  530. # ============= z/baudtest.c ==============
  531. if test -f 'z/baudtest.c' -a X"$1" != X"-c"; then
  532.     echo 'x - skipping z/baudtest.c (File already exists)'
  533.     rm -f _shar_wnt_.tmp
  534. else
  535. > _shar_wnt_.tmp
  536. echo 'x - extracting z/baudtest.c (Text)'
  537. sed 's/^X//' << 'SHAR_EOF' > 'z/baudtest.c' &&
  538. X/*+-------------------------------------------------------------------------
  539. X    baudtest.c
  540. X    wht@n4hgf.Mt-Park.GA.US
  541. X
  542. XAlas, on some systems, curses insists on sgtty.h inclusion
  543. Xwhich does not get along with termio.h AT ALL
  544. X--------------------------------------------------------------------------*/
  545. X/*+:EDITS:*/
  546. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  547. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  548. X/*:08-28-1991-14:08-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  549. X/*:08-23-1991-18:33-wht@n4hgf2-disable force no curses for tty vs. line speed */
  550. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  551. X/*:12-04-1990-05:36-wht-creation */
  552. X
  553. X#include <stdio.h>
  554. X#include "../ecu_types.h"
  555. X#include <termio.h>
  556. X
  557. Xextern int iofd;
  558. Xextern int dumbtty;
  559. Xextern int report_verbosity;
  560. Xextern int report_init_complete;
  561. Xextern char *numeric_revision;
  562. X
  563. X/*+-------------------------------------------------------------------------
  564. X    test_tty_and_line_baud()
  565. X
  566. X  if non-multiscreen tty baud rate not at least that
  567. X  of the attached line, use no curses, but do be a bit more
  568. X  verbose than if tty not char special
  569. X
  570. X--------------------------------------------------------------------------*/
  571. X#ifdef TTY_VS_LINE_SPEED_NO_CURSES
  572. Xvoid
  573. Xtest_tty_and_line_baud()
  574. X{
  575. X    struct termio tty_termio;
  576. X    struct termio line_termio;
  577. X
  578. X    memset((char *)&tty_termio,0,sizeof(struct termio));
  579. X    memset((char *)&line_termio,0,sizeof(struct termio));
  580. X    if(ioctl(0,TCGETA,&tty_termio) || ioctl(iofd,TCGETA,&line_termio) ||
  581. X        (((unsigned)tty_termio.c_cflag & CBAUD) <
  582. X        (unsigned)((line_termio.c_cflag & CBAUD))))
  583. X    {
  584. X        dumbtty = 1;
  585. X        report_verbosity = 1;
  586. X        report_init_complete = 1;
  587. X    }
  588. X
  589. X}    /* end of test_tty_and_line_baud */
  590. X#endif
  591. X
  592. X/* vi: set tabstop=4 shiftwidth=4: */
  593. X/* end of baudtest.c */
  594. SHAR_EOF
  595. chmod 0644 z/baudtest.c ||
  596. echo 'restore of z/baudtest.c failed'
  597. Wc_c="`wc -c < 'z/baudtest.c'`"
  598. test 1751 -eq "$Wc_c" ||
  599.     echo 'z/baudtest.c: original size 1751, current size' "$Wc_c"
  600. rm -f _shar_wnt_.tmp
  601. fi
  602. # ============= z/ecurz.c ==============
  603. if test -f 'z/ecurz.c' -a X"$1" != X"-c"; then
  604.     echo 'x - skipping z/ecurz.c (File already exists)'
  605.     rm -f _shar_wnt_.tmp
  606. else
  607. > _shar_wnt_.tmp
  608. echo 'x - extracting z/ecurz.c (Text)'
  609. sed 's/^X//' << 'SHAR_EOF' > 'z/ecurz.c' &&
  610. Xchar *numeric_revision = "@(#)ecurz 3.20";
  611. X/*+-------------------------------------------------------------------------
  612. X    ecurz.c - X/Y/ZMODEM receive program
  613. X  Derived from public domain source by Chuck Forsberg, Omen Technologies
  614. X  Adaptation for ecu 1989 wht@n4hgf.Mt-Park.GA.US
  615. X
  616. X  Defined functions:
  617. X    SIGALRM_handler(sig)
  618. X    arg_token(parsestr,termchars)
  619. X    bye_bye(sig)
  620. X    cancel_transaction(can_code)
  621. X    close_and_report()
  622. X    flushline()
  623. X    fname_split(cmd,arg,arg_max_quan,narg_rtn)
  624. X    fname_too_long(fname)
  625. X    fname_truncated()
  626. X    getfree()
  627. X    isanylc(str)
  628. X    main(argc,argv,envp)
  629. X    make_dirs(pathname)
  630. X    mkdir(dpath,dmode)
  631. X    our_fopen(pathname,openmode)
  632. X    procheader(name)
  633. X    purgeline()
  634. X    readline(timeout)
  635. X    report_receive_progress(pos)
  636. X    rzfile()
  637. X    rzfiles()
  638. X    send_ZFIN()
  639. X    send_cancel(error)
  640. X    sendline(c)
  641. X    substr(str,token)
  642. X    sys2(shellcmd)
  643. X    tryz()
  644. X    uncaps(str)
  645. X    usage(fail_reason)
  646. X    wcgetsec(rxbuf,maxtime)
  647. X    wcreceive(argc,argp)
  648. X    wcrx()
  649. X    wcrxpn(rpn)
  650. X    write_sec_to_disk(buf,n)
  651. X    xsendline(c)
  652. X
  653. X      Usage:    ecurz -Z [-abeuy]    (ZMODEM)
  654. X                ecurz -Y [-abuy]     (YMODEM)
  655. X                ecurz -X [-abc] file (XMODEM or XMODEM-1k)
  656. X
  657. X          -a ASCII transfer (strip CR)
  658. X          -b Binary transfer for all files
  659. X          -c Use 16 bit CRC (XMODEM)
  660. X          -e Escape control characters  (ZMODEM)
  661. X          -p protect local files (ZMODEM)
  662. X          -t <tenths> rx timeout seconds
  663. X          -+ force append
  664. X          -u convert uppercase filenames to lower case
  665. X          -y Yes, clobber existing file if any
  666. X          -. line fd to use
  667. X          -, log protocol packets
  668. X
  669. X--------------------------------------------------------------------------*/
  670. X/*+:EDITS:*/
  671. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  672. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  673. X/*:08-16-1992-03:08-wht@n4hgf-head off another POSIX plot */
  674. X/*:08-10-1992-04:01-wht@n4hgf-use init_Nap */
  675. X/*:07-30-1992-16:35-wht@n4hgf-our_fopen fixes 3.2v4 ENAMETOOLONG ambiguity */
  676. X/*:07-20-1992-13:39-wht@n4hgf-need hzmsec for nap.c */
  677. X/*:04-24-1992-15:28-wht@n4hgf-start thinking about M_UNIX with long filenames */
  678. X/*:04-24-1992-15:23-wht@n4hgf-fix mkdir/make_dirs conditionals */
  679. X/*:01-27-1992-23:43-wht@n4hgf-more efficient fopen processing */
  680. X/*:01-20-1992-23:25-root@n4hgf-ZMAPND works now */
  681. X/*:12-16-1991-12:59-wht@n4hgf-support ZCRESUM */
  682. X/*:08-28-1991-14:08-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  683. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  684. X/*:04-30-1991-18:33-wht@n4hgf-gcc version coredumping on putc(); use fputc() */
  685. X/*:03-27-1991-21:21-wht@n4hgf-dont bump error count on send ZRPOS */
  686. X/*:02-03-1991-17:27-wht@n4hgf-version number change - see zcurses.c */
  687. X/*:12-18-1990-21:26-wht@n4hgf-better output control */
  688. X/*:10-04-1990-14:01-wht@n4hgf-add file finish warning for me */
  689. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  690. X/*:08-23-1990-14:14-wht@n4hgf-sending ZACK was erroneously counted as error */
  691. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  692. X
  693. X#include <stdio.h>
  694. X#include <signal.h>
  695. X#include <setjmp.h>
  696. X#include <ctype.h>
  697. X#include <string.h>
  698. X#include <errno.h>
  699. X#include <fcntl.h>
  700. X#include "zmodem.h"
  701. X#include <sys/param.h>
  702. X
  703. X#if defined(ENAMETOOLONG)
  704. Xchar *fname_truncated();
  705. X#endif
  706. X
  707. Xextern unsigned short crctab[];
  708. Xextern int force_dumbtty;
  709. Xextern int errno;
  710. Xextern char *sys_errlist[];
  711. Xextern int sys_nerr;
  712. Xextern char Attn[];        /* Attention string rx sends to tx on err */
  713. Xextern int Crc32;        /* Display flag indicating 32 bit CRC being received */
  714. Xextern int Rxcount;        /* Count of data bytes received */
  715. Xextern char Rxhdr[];    /* Received header */
  716. Xextern char Txhdr[];    /* Transmitted header */
  717. Xextern int Rxtimeout;    /* Tenths of seconds to wait for something */
  718. Xextern char s128[128];
  719. X
  720. X/*
  721. X * Max value for VMIN_COUNT is 255.  A larger value reduces system
  722. X * overhead but may evoke kernel bugs.  133 corresponds to an XMODEM/CRC
  723. X * sector.
  724. X
  725. XPaul Slootman said, though:
  726. X:PS: Something somewhere in the SVR4 kernel is a signed char, which causes
  727. X:PS: VMIN values of more than 127 to return *immediately* without ever
  728. X:PS: reading...
  729. X:PS:
  730. X:PS: I had troubles running the regular rz, which was where I saw
  731. X:PS: the bug the first time. I've also heard of this from someone
  732. X:PS: else, running something else than the ICL SPARC port for SVR4:
  733. X:PS:
  734. X:PS: Date: Sat, 3 Aug 91 11:41:16 EDT
  735. X:PS: From: tompkins@cat.syr.edu (Terry Tompkins)
  736. X:PS: Subject: Re:  Zmodem
  737. X:PS: 
  738. X:PS: Thanks for the info.  I just returned from vacation - sorry for the delay.
  739. X:PS: We are running AT&T 5.4 UNIX on an Osicom 25mhz 386.  If you hear of a 
  740. X:PS: fix for the OS, let me know - I feel a little apprehensive about a kernel
  741. X:PS: bug of this nature.  (The machine is a network server that we are using
  742. X:PS: for all kinds of things).
  743. X*/
  744. X
  745. X#if !defined(VMIN_COUNT)
  746. X# ifdef SVR4
  747. X#  define VMIN_COUNT 127
  748. X# else
  749. X#  define VMIN_COUNT 133
  750. X# endif
  751. X#endif
  752. Xunsigned char vmin_count = VMIN_COUNT;
  753. Xint Readnum = VMIN_COUNT;    /* num bytes to ask for in read() from modem */
  754. X
  755. X#define DEFBYTL 2000000000L    /* default rx file size */
  756. X#define RETRYMAX 5
  757. X
  758. XFILE *fout;
  759. Xlong rxfilepos;        /* received file seek position */
  760. Xlong initial_filepos;        /* initial file position */
  761. Xchar Lzmanag;        /* Local file management request */
  762. Xchar Pathname[PATHLEN];
  763. Xchar curr_dir[256];
  764. Xunsigned char linbuf[VMIN_COUNT];
  765. Xchar secbuf[1025];
  766. Xchar zconv;                /* ZMODEM file conversion request */
  767. Xchar zmanag;            /* ZMODEM file management request */
  768. Xchar ztrans;            /* ZMODEM file transport request */
  769. Xint Batch;
  770. Xint Blklen;                /* record length of received packets */
  771. Xint Crcflg;
  772. Xint Eofseen;            /* indicates cpm eof (^Z) has been received */
  773. Xint Filcnt;            /* count of number of files opened */
  774. Xint Filemode;            /* Unix style mode for incoming file */
  775. Xint Firstsec;
  776. Xint Lastrx;
  777. Xint Lleft;            /* number of characters in linbuf */
  778. Xint MakeLCPathname=1;    /* make received pathname lower case */
  779. Xint Nozmodem;        /* If invoked as "rb" */
  780. Xint Rxascii;            /* receive files in ascii (translate) mode */
  781. Xint Rxbinary;            /* receive all files in bin mode */
  782. Xint Rxclob;            /* Clobber existing file */
  783. Xint Thisbinary;            /* current file is to be received in bin mode */
  784. Xint Twostop;        /* use two stop bits */
  785. Xint Zctlesc;            /* Encode control characters */
  786. Xint Zmodem;            /* ZMODEM protocol requested */
  787. Xint Zrwindow = 1400;    /* RX window size (controls garbage count) */
  788. Xint ecusz_flag;
  789. Xint skip_count;        /* skipped files */
  790. Xint errors;
  791. Xint expect_zrpos;
  792. Xint iofd;
  793. Xint force_dumbtty;
  794. Xint can_on_eof;
  795. Xint log_packets;
  796. Xint npats;
  797. Xint oldBlklen = -1;        /* last block length */
  798. Xint this_file_errors;
  799. Xint tryzhdrtype=ZRINIT;    /* Header type to send corresponding to Last rx close */
  800. Xjmp_buf tohere;            /* For the interrupt on RX timeout */
  801. Xlong Bytesleft;            /* number of bytes of incoming file left */
  802. Xlong Modtime;            /* Unix style mod time for incoming file */
  803. Xlong TotalToReceive;
  804. Xlong rx_char_count;
  805. Xlong tx_char_count;
  806. Xstruct stat fout_stat;
  807. Xtime_t timep[2];
  808. Xunsigned Baudrate;
  809. Xunsigned long this_file_length;
  810. Xint required_type;
  811. Xchar *bottom_label = (char *)0;
  812. Xchar *got_garbage_txt = "got garbage (0x%02x)";
  813. Xchar **gargv;
  814. Xint gargc;
  815. X
  816. Xvoid purgeline();
  817. Xvoid send_cancel();
  818. X
  819. X/*+-----------------------------------------------------------------------
  820. X    arg_token(parsestr,termchars)
  821. X
  822. XGet next token from string parsestr ((char *)0 on 2nd, 3rd, etc.
  823. Xcalls), where tokens are nonempty strings separated by runs of chars
  824. Xfrom termchars.  Writes nulls into parsestr to end tokens.
  825. Xtermchars need not remain constant from call to call.
  826. X
  827. XTreats multiple occurrences of a termchar as one delimiter (does not
  828. Xallow null fields).
  829. X------------------------------------------------------------------------*/
  830. X#if defined(ENAMETOOLONG)
  831. Xstatic char *arg_token_static = (char *)0;
  832. Xchar *arg_token(parsestr,termchars)
  833. Xchar *parsestr;
  834. Xchar *termchars;
  835. X{
  836. X    register char *parseptr;
  837. X    char *token;
  838. X
  839. X    if(parsestr == (char *)0 && arg_token_static == (char *)0)
  840. X        return((char *)0);
  841. X
  842. X    if(parsestr)
  843. X        parseptr = parsestr;
  844. X    else
  845. X       parseptr = arg_token_static;
  846. X
  847. X    while(*parseptr)
  848. X    {
  849. X        if(!strchr(termchars,*parseptr))
  850. X            break;
  851. X        parseptr++;
  852. X    }
  853. X
  854. X    if(!*parseptr)
  855. X    {
  856. X        arg_token_static = (char *)0;
  857. X        return((char *)0);
  858. X    }
  859. X
  860. X    token = parseptr;
  861. X    if(*token == '\'')
  862. X    {
  863. X        token++;
  864. X        parseptr++;
  865. X        while(*parseptr)
  866. X        {
  867. X            if(*parseptr == '\'')
  868. X            {
  869. X                arg_token_static = parseptr + 1;
  870. X                *parseptr = 0;
  871. X                return(token);
  872. X            }
  873. X            parseptr++;
  874. X        }
  875. X        arg_token_static = (char *)0;
  876. X        return(token);
  877. X    }
  878. X    while(*parseptr)
  879. X    {
  880. X        if(strchr(termchars,*parseptr))
  881. X        {
  882. X            *parseptr = 0;
  883. X            arg_token_static = parseptr + 1;
  884. X            while(*arg_token_static)
  885. X            {
  886. X                if(!strchr(termchars,*arg_token_static))
  887. X                    break;
  888. X                arg_token_static++;
  889. X            }
  890. X            return(token);
  891. X        }
  892. X        parseptr++;
  893. X    }
  894. X    arg_token_static = (char *)0;
  895. X    return(token);
  896. X}    /* end of arg_token */
  897. X#endif
  898. X
  899. X/*+-------------------------------------------------------------------------
  900. X    fname_split(cmd,arg,arg_max_quan,&narg)
  901. X--------------------------------------------------------------------------*/
  902. X#if defined(ENAMETOOLONG)
  903. Xvoid
  904. Xfname_split(cmd,arg,arg_max_quan,narg_rtn)
  905. Xchar *cmd;
  906. Xchar **arg;
  907. Xint arg_max_quan;
  908. Xint *narg_rtn;
  909. X{
  910. X    register itmp;
  911. X    register narg;
  912. X
  913. X    for(itmp = 0; itmp < arg_max_quan; itmp++)
  914. X        arg[itmp] = (char *)0;
  915. X    arg[0] = arg_token(cmd,"/");
  916. X
  917. X    for(narg = 1; narg < arg_max_quan; ++narg)
  918. X    {
  919. X        if((arg[narg] = arg_token((char *)0,"/")) == (char *)0) 
  920. X            break;
  921. X    }
  922. X
  923. X    *narg_rtn = narg;
  924. X
  925. X}    /* end of fname_split */
  926. X#endif
  927. X
  928. X#if defined(ENAMETOOLONG)
  929. X#define MAX_COMPONENT_LEN    14
  930. X#define MAX_PATH_COMPONENTS    16
  931. Xstatic char trunc_fname[257];
  932. Xstatic char *trunc_components[MAX_PATH_COMPONENTS];
  933. Xstatic int trunc_components_quan;
  934. Xstatic int trunc_absolute_path;
  935. X#endif
  936. X
  937. X/*+-------------------------------------------------------------------------
  938. X    fname_too_long(fname) - check for any pathname component too long
  939. X--------------------------------------------------------------------------*/
  940. X#if defined(ENAMETOOLONG)
  941. Xint
  942. Xfname_too_long(fname)
  943. Xregister char *fname;
  944. X{
  945. X    register int itmp;
  946. X    register char **cpptr;
  947. X
  948. X    if(trunc_absolute_path = (*fname == '/'))
  949. X        fname++;
  950. X    strncpy(trunc_fname,fname,sizeof(trunc_fname) - 1);
  951. X    fname_split(trunc_fname,trunc_components,
  952. X        MAX_PATH_COMPONENTS,&trunc_components_quan);
  953. X    itmp = trunc_components_quan;
  954. X    cpptr = trunc_components;
  955. X    while(itmp--)
  956. X    {
  957. X        if(strlen(*cpptr) > MAX_COMPONENT_LEN)
  958. X            return(1);
  959. X        cpptr++;
  960. X    }
  961. X    return(0);
  962. X}    /* end of fname_too_long */
  963. X#endif
  964. X
  965. X/*+-------------------------------------------------------------------------
  966. X    fname_truncated() - build truncated path last checked by fname_too_long
  967. X--------------------------------------------------------------------------*/
  968. X#if defined(ENAMETOOLONG)
  969. Xchar *
  970. Xfname_truncated()
  971. X{
  972. X    register int icomp;
  973. X    char new_fname[257];
  974. X    register char *cptr = new_fname;
  975. X
  976. X    if(trunc_absolute_path)
  977. X    {
  978. X        *cptr = '/';
  979. X        *(cptr + 1) = 0;
  980. X    }
  981. X    else
  982. X        *cptr = 0;
  983. X    for(icomp = 0; icomp < trunc_components_quan; icomp++)
  984. X    {
  985. X        if(strlen(trunc_components[icomp]) > MAX_COMPONENT_LEN)
  986. X            *(trunc_components[icomp] + MAX_COMPONENT_LEN) = 0;
  987. X        strcat(cptr,trunc_components[icomp]);
  988. X        if(icomp < trunc_components_quan - 1)
  989. X            strcat(cptr,"/");
  990. X    }
  991. X    strcpy(trunc_fname,cptr);
  992. X    return(trunc_fname);
  993. X
  994. X}    /* end of fname_truncated */
  995. X#endif
  996. X
  997. X/*+-------------------------------------------------------------------------
  998. X    our_fopen(pathname,openmode) - fopen for write considering ENAMETOOLONG
  999. X
  1000. XThis can modify the pathname argument
  1001. X--------------------------------------------------------------------------*/
  1002. XFILE *
  1003. Xour_fopen(pathname,openmode)
  1004. Xchar *pathname;
  1005. Xchar *openmode;
  1006. X{
  1007. X    FILE *fp;
  1008. X
  1009. X    if(!(fp = fopen(pathname,openmode)))
  1010. X    {
  1011. X#if defined(ENAMETOOLONG)
  1012. X        if(errno == ENAMETOOLONG)
  1013. X        {
  1014. X            if(fname_too_long(pathname))
  1015. X            {
  1016. X                strcpy(s128,"truncated: ");
  1017. X                strncat(s128,pathname,sizeof(s128) - 12);
  1018. X                ecu_log_event(getppid(),s128);
  1019. X                report_str(s128,-1);
  1020. X                strcpy(pathname,fname_truncated());
  1021. X                fp = fopen(pathname,openmode);
  1022. X            }
  1023. X        }
  1024. X#else
  1025. X        ; /* dummy statement for anti new-fangled compiler warnings */
  1026. X#endif
  1027. X    }
  1028. X
  1029. X    return(fp);
  1030. X
  1031. X}    /* end of our_fopen */
  1032. X
  1033. X/*+-------------------------------------------------------------------------
  1034. X    substr(str,token)
  1035. X
  1036. X  searches for token in string str returns pointer to token within
  1037. X  string if found,NULL otherwise
  1038. X--------------------------------------------------------------------------*/
  1039. Xchar *
  1040. Xsubstr(str,token)
  1041. Xregister char *str,*token;
  1042. X{
  1043. X    register char *ss;
  1044. X    register char *tt;
  1045. X
  1046. X    /* search for first char of token */
  1047. X    for(ss=str; *str; str++)
  1048. X        if(*str == *token)
  1049. X            /* compare token with substring */
  1050. X            for(ss=str,tt=token; ;)
  1051. X            {
  1052. X                if(!*tt)
  1053. X                    return(str);
  1054. X                if(*ss++ != *tt++)
  1055. X                    break;
  1056. X            }
  1057. X    return(NULL);
  1058. X}    /* end of substr */
  1059. X
  1060. X/*+-------------------------------------------------------------------------
  1061. X    getfree()
  1062. X
  1063. X  Routine to calculate the free bytes on the current file system ~0
  1064. X  means many free bytes (unknown)
  1065. X--------------------------------------------------------------------------*/
  1066. Xlong
  1067. Xgetfree()
  1068. X{
  1069. X    return(~0L);    /* many free bytes ... */
  1070. X}    /* end of getfree */
  1071. X
  1072. X/*+-------------------------------------------------------------------------
  1073. X    usage(fail_reason)
  1074. X--------------------------------------------------------------------------*/
  1075. Xvoid
  1076. Xusage(fail_reason)
  1077. Xchar *fail_reason;
  1078. X{
  1079. X    fprintf(stderr,"%s\n",fail_reason);
  1080. X    exit(255);
  1081. X}    /* end of usage */
  1082. X
  1083. X/*+-------------------------------------------------------------------------
  1084. X    SIGALRM_handler(sig)
  1085. X--------------------------------------------------------------------------*/
  1086. Xvoid
  1087. XSIGALRM_handler(sig)
  1088. Xint sig;
  1089. X{
  1090. X    report_tx_ind(0);
  1091. X    report_rx_ind(0);
  1092. X    longjmp(tohere,-1);
  1093. X}    /* end of SIGALRM_handler */
  1094. X
  1095. X/*+-------------------------------------------------------------------------
  1096. X    bye_bye(sig)
  1097. X--------------------------------------------------------------------------*/
  1098. Xvoid
  1099. Xbye_bye(sig)
  1100. Xint sig;
  1101. X{
  1102. X    exit(sig+128);
  1103. X}    /* end of bye_bye */
  1104. X
  1105. X/*+-------------------------------------------------------------------------
  1106. X    cancel_transaction(can_code)
  1107. Xcalled by signal interrupt or terminate to clean things up
  1108. X--------------------------------------------------------------------------*/
  1109. Xvoid
  1110. Xcancel_transaction(can_code)
  1111. Xint can_code;
  1112. X{
  1113. X    purgeline();
  1114. X    if(Zmodem)
  1115. X        zmputs(Attn);
  1116. X    send_cancel(1);
  1117. X    mode(0);
  1118. X    if(can_code >= 0)
  1119. X    {
  1120. X        sprintf(s128,"ecurz aborted (signal %d)",can_code);
  1121. X        report_str(s128,0);
  1122. X    }
  1123. X    report_tx_ind(0);
  1124. X    report_rx_ind(0);
  1125. X    report_uninit(0);
  1126. X    bye_bye(can_code);
  1127. X
  1128. X}    /* end of cancel_transaction */
  1129. X
  1130. X/*+-------------------------------------------------------------------------
  1131. X    sendline(c) -  send a character to DCE
  1132. X--------------------------------------------------------------------------*/
  1133. Xvoid
  1134. Xsendline(c)
  1135. Xchar c;
  1136. X{
  1137. X    write(iofd,&c,1);
  1138. X    ++tx_char_count;
  1139. X}    /* end of sendline */
  1140. X
  1141. X/*+-------------------------------------------------------------------------
  1142. X    xsendline(c)
  1143. X--------------------------------------------------------------------------*/
  1144. Xvoid
  1145. Xxsendline(c)
  1146. Xint c;
  1147. X{
  1148. X    sendline(c);
  1149. X}    /* end of xsendline */
  1150. X
  1151. X/*+-------------------------------------------------------------------------
  1152. X    flushline()
  1153. X--------------------------------------------------------------------------*/
  1154. Xvoid
  1155. Xflushline()
  1156. X{
  1157. X}    /* end of flushline */
  1158. X
  1159. X/*+-------------------------------------------------------------------------
  1160. X    purgeline() - purge the modem input queue of all characters
  1161. X--------------------------------------------------------------------------*/
  1162. Xvoid
  1163. Xpurgeline()
  1164. X{
  1165. X    Lleft = 0;
  1166. X#if defined(TCFLSH)
  1167. X    ioctl(iofd,TCFLSH,0);
  1168. X#else
  1169. X    lseek(iofd,0L,2);
  1170. X#endif
  1171. X}    /* end of purgeline */
  1172. X
  1173. X/*+-------------------------------------------------------------------------
  1174. X    wcreceive(argc,argp)
  1175. X--------------------------------------------------------------------------*/
  1176. Xwcreceive(argc,argp)
  1177. Xint argc;
  1178. Xchar **argp;
  1179. X{
  1180. X    register c;
  1181. X
  1182. X    if(Batch || argc==0)
  1183. X    {
  1184. X        Crcflg=1;
  1185. X        c=tryz();
  1186. X        if(Zmodem)
  1187. X        {
  1188. X            report_protocol_type("ZMODEM");
  1189. X            report_protocol_crc_type((Crc32) ? "/CRC32" : "/CRC16");
  1190. X        }
  1191. X        if(c)
  1192. X        {
  1193. X            if(c == ZCOMPL)
  1194. X                return(OK);
  1195. X            if(c == ERROR)
  1196. X                goto FAIL;
  1197. X            c = rzfiles();
  1198. X            if(c)
  1199. X                goto FAIL;
  1200. X        } else 
  1201. X        {
  1202. X            report_protocol_type("YMODEM");
  1203. X            report_protocol_crc_type((Crcflg) ? "/CRC" : "/CHK");
  1204. X            for(;;)
  1205. X            {
  1206. X                if(wcrxpn(secbuf)== ERROR)
  1207. X                    goto FAIL;
  1208. X                if(secbuf[0]==0)
  1209. X                    return(OK);
  1210. X                if(procheader(secbuf) == ERROR)
  1211. X                    goto FAIL;
  1212. X                report_str("Receiving data",0);
  1213. X                if(wcrx()==ERROR)
  1214. X                    goto FAIL;
  1215. X            }
  1216. X        }
  1217. X    }
  1218. X    else 
  1219. X    {
  1220. X        report_protocol_type("XMODEM");
  1221. X        report_protocol_crc_type((Crcflg) ? "/CRC" : "/CHK");
  1222. X        Bytesleft = DEFBYTL;
  1223. X        Filemode = 0;
  1224. X        Modtime = 0L;
  1225. X        procheader("");
  1226. X        strcpy(Pathname,*argp);
  1227. X        if(!(fout=our_fopen(Pathname,"w")))
  1228. X        {
  1229. X            sprintf(s128,"%-0.64s: %-0.40s",Pathname,sys_errlist[errno]);
  1230. X            report_str(s128,1);
  1231. X            ecu_log_event(getppid(),s128);
  1232. X            goto FAIL;
  1233. X        }
  1234. X
  1235. X        ++Filcnt;
  1236. X        report_file_rcv_started(Pathname,0L,Modtime,(unsigned short)Filemode);
  1237. X        this_file_length = 0;
  1238. X        report_rxpos(0L);
  1239. X        report_str("Receiving data",0);
  1240. X        if(wcrx()==ERROR)
  1241. X            goto FAIL;
  1242. X    }
  1243. X    return(OK);
  1244. X
  1245. XFAIL:
  1246. X    send_cancel(1);
  1247. X    if(fout)
  1248. X    {
  1249. X        fflush(fout);
  1250. X        fstat(fileno(fout),&fout_stat);
  1251. X        report_file_byte_io((long)fout_stat.st_size - initial_filepos);
  1252. X        report_file_close(0);
  1253. X        fclose(fout);
  1254. X        fout = (FILE *)0;
  1255. X    }
  1256. X    return(ERROR);
  1257. X}    /* end of wcreceive */
  1258. X
  1259. X/*+-------------------------------------------------------------------------
  1260. X    wcgetsec(rxbuf,maxtime)
  1261. X
  1262. X  Wcgetsec fetches a Ward Christensen type sector.  Returns sector
  1263. X  number encountered or ERROR if valid sector not received, or CAN CAN
  1264. X  received or WCEOT if eot sector time is timeout for first char,set to
  1265. X  4 seconds thereafter. NO ACK IS SENT IF SECTOR IS RECEIVED OK. Caller
  1266. X  must do that when he is good and ready to get next sector.
  1267. X--------------------------------------------------------------------------*/
  1268. Xunsigned int
  1269. Xwcgetsec(rxbuf,maxtime)
  1270. Xchar *rxbuf;
  1271. Xint maxtime;
  1272. X{
  1273. X    register unsigned int firstch;
  1274. X    register unsigned short oldcrc;
  1275. X    register unsigned char checksum;
  1276. X    register wcj;
  1277. X    register char *p;
  1278. X    int sectcurr;
  1279. X
  1280. X    for(Lastrx=errors=0; errors<RETRYMAX; errors++)
  1281. X    {
  1282. X
  1283. X        firstch=readline(maxtime);
  1284. X        if((firstch == STX) || (firstch == SOH))
  1285. X        {
  1286. X            oldBlklen = Blklen;
  1287. X            if(firstch == STX)
  1288. X                Blklen=1024;
  1289. X            else
  1290. X                Blklen=128;
  1291. X            if(oldBlklen != Blklen)
  1292. X                report_rxblklen(Blklen);
  1293. X
  1294. X            sectcurr=readline(1);
  1295. X            if((sectcurr + (oldcrc=readline(1))) == 0xFF)
  1296. X            {
  1297. X                oldcrc=checksum=0;
  1298. X                for(p = rxbuf,wcj = Blklen; --wcj >= 0; )
  1299. X                {
  1300. X                    if((int)(firstch=readline(1)) < 0)
  1301. X                        goto bilge;
  1302. X                    oldcrc=updcrc(firstch,oldcrc);
  1303. X                    checksum += (*p++ = firstch);
  1304. X                }
  1305. X                if((int)(firstch=readline(1)) < 0)
  1306. X                    goto bilge;
  1307. X                if(Crcflg)
  1308. X                {
  1309. X                    oldcrc=updcrc(firstch,oldcrc);
  1310. X                    if((int)(firstch=readline(1)) < 0)
  1311. X                        goto bilge;
  1312. X                    oldcrc=updcrc(firstch,oldcrc);
  1313. X                    if(oldcrc)
  1314. X                    {
  1315. X                        sprintf(s128,"CRC error = 0x%04x",oldcrc);
  1316. X                        report_str(s128,1);
  1317. X                    }
  1318. X                    else 
  1319. X                    {
  1320. X                        Firstsec=0;
  1321. X                        return(sectcurr);
  1322. X                    }
  1323. X                }
  1324. X                else if((checksum-firstch)==0)
  1325. X                {
  1326. X                    Firstsec=0;
  1327. X                    return(sectcurr);
  1328. X                }
  1329. X                else
  1330. X                    report_str("checksum error",1);
  1331. X            }
  1332. X            else
  1333. X            {
  1334. X                report_last_txhdr("Noise",0);
  1335. X                sprintf(s128,"Sector garbled 0x%x 0x%x",sectcurr,oldcrc);
  1336. X                report_str(s128,1);
  1337. X            }
  1338. X        }
  1339. X        /* make sure eot really is eot and not just mixmash */
  1340. X#if defined(NFGVMIN)
  1341. X        else if(firstch==EOT && readline(1)==TIMEOUT)
  1342. X            return(WCEOT);
  1343. X#else
  1344. X        else if(firstch==EOT && Lleft==0)
  1345. X            return(WCEOT);
  1346. X#endif
  1347. X        else if(firstch==EOT)
  1348. X        {
  1349. X            report_str("Noisy EOT",2);
  1350. X        }
  1351. X        else if(firstch==CAN)
  1352. X        {
  1353. X            if(Lastrx==CAN)
  1354. X            {
  1355. X                report_str("Sender CANcelled",1);
  1356. X                report_last_rxhdr("CAN",1);
  1357. X                return(ERROR);
  1358. X            } else 
  1359. X            {
  1360. X                Lastrx=CAN;
  1361. X                continue;
  1362. X            }
  1363. X        }
  1364. X        else if(firstch==TIMEOUT)
  1365. X        {
  1366. X            if(Firstsec)
  1367. X                goto humbug;
  1368. Xbilge:
  1369. X            report_str("Timeout",1);
  1370. X        }
  1371. X        else
  1372. X        {
  1373. X            sprintf(s128,"Got 0x%02x sector header",firstch);
  1374. X            report_str(s128,1);
  1375. X        }
  1376. X
  1377. Xhumbug:
  1378. X        Lastrx=0;
  1379. X        while(readline(1)!=TIMEOUT)
  1380. X            ;
  1381. X        if(Firstsec)
  1382. X        {
  1383. X            sendline(Crcflg?WANTCRC:NAK);
  1384. X            report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
  1385. X            Lleft=0;    /* Do read next time ... */
  1386. X        } else 
  1387. X        {
  1388. X            maxtime=40;
  1389. X            sendline(NAK);
  1390. X            report_last_txhdr("NAK",1);
  1391. X            Lleft=0;    /* Do read next time ... */
  1392. X        }
  1393. X    }
  1394. X    /* try to stop the bubble machine. */
  1395. X    send_cancel(1);
  1396. X    return(ERROR);
  1397. X}    /* end of wcgetsec */
  1398. X
  1399. X/*+-------------------------------------------------------------------------
  1400. X    wcrxpn(rpn)
  1401. X
  1402. X  Fetch a pathname from the other end.  Length is indeterminate as long
  1403. X  as less than Blklen.  During YMODEM xfers, a null string represents no
  1404. X  more files.
  1405. X--------------------------------------------------------------------------*/
  1406. Xwcrxpn(rpn)
  1407. Xchar *rpn;    /* receive a pathname */
  1408. X{
  1409. X    register c;
  1410. X
  1411. X#if defined(NFGVMIN)
  1412. X    readline(1);
  1413. X#else
  1414. X    purgeline();
  1415. X#endif
  1416. X
  1417. Xet_tu:
  1418. X    Firstsec=1;
  1419. X    Eofseen=0;
  1420. X    sendline(Crcflg?WANTCRC:NAK);
  1421. X    report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
  1422. X    Lleft=0;    /* Do read next time ... */
  1423. X    while((c = wcgetsec(rpn,100)) != 0)
  1424. X    {
  1425. X        if(c == WCEOT)
  1426. X        {
  1427. X            sprintf(s128,"Pathname fetch returned %d",c);
  1428. X            report_str(s128,1);
  1429. X            sendline(ACK);
  1430. X            report_last_txhdr("ACK",0);
  1431. X            Lleft=0;    /* Do read next time ... */
  1432. X            readline(1);
  1433. X            goto et_tu;
  1434. X        }
  1435. X        return(ERROR);
  1436. X    }
  1437. X    sendline(ACK);
  1438. X    report_last_txhdr("ACK",0);
  1439. X    return(OK);
  1440. X}    /* end of wcrxpn */
  1441. X
  1442. X/*+-------------------------------------------------------------------------
  1443. X    report_receive_progress(pos)
  1444. X--------------------------------------------------------------------------*/
  1445. Xvoid
  1446. Xreport_receive_progress(pos)
  1447. Xlong pos;
  1448. X{
  1449. X
  1450. X    report_rxpos(pos);
  1451. X    if(this_file_length != 0)
  1452. X    {
  1453. X        sprintf(s128,"Receiving data (%u%% complete)",
  1454. X            (int)((unsigned long)pos * (unsigned long)100) / this_file_length);
  1455. X        report_str(s128,0);
  1456. X    }
  1457. X}    /* end of report_receive_progress */
  1458. X
  1459. X/*+-------------------------------------------------------------------------
  1460. X    write_sec_to_disk(buf,n)
  1461. X
  1462. X  Putsec writes the n characters of buf to receive file fout.  If not in
  1463. X  binary mode, carriage returns, and all characters starting with CPMEOF
  1464. X  are discarded.
  1465. X--------------------------------------------------------------------------*/
  1466. Xwrite_sec_to_disk(buf,n)
  1467. Xchar *buf;
  1468. Xregister n;
  1469. X{
  1470. X    register char *p;
  1471. X
  1472. X    if(!n)
  1473. X        return(OK);
  1474. X    if(Thisbinary)
  1475. X    {
  1476. X        for(p=buf; --n>=0; )
  1477. X            fputc( *p++,fout);
  1478. X    }
  1479. X    else 
  1480. X    {
  1481. X        if(Eofseen)
  1482. X            return(OK);
  1483. X        for(p=buf; --n>=0; ++p )
  1484. X        {
  1485. X            if( *p == '\r')
  1486. X                continue;
  1487. X            if(*p == CPMEOF)
  1488. X            {
  1489. X                Eofseen=1;
  1490. X                fflush(fout);
  1491. X                fstat(fileno(fout),&fout_stat);
  1492. X                report_rxpos(fout_stat.st_size);
  1493. X                return(OK);
  1494. X            }
  1495. X            fputc(*p,fout);
  1496. X        }
  1497. X    }
  1498. X    if(!Zmodem)
  1499. X    {
  1500. X        fflush(fout);
  1501. X        fstat(fileno(fout),&fout_stat);
  1502. X        report_rxpos(fout_stat.st_size);
  1503. X    }
  1504. X    return(OK);
  1505. X}    /* end of write_sec_to_disk */
  1506. X
  1507. X/*+-------------------------------------------------------------------------
  1508. X    wcrx() - receive an X/YMODEM sector
  1509. X
  1510. X  Adapted from CMODEM13.C,written by Jack M.  Wierda and Roderick W. Hart
  1511. X--------------------------------------------------------------------------*/
  1512. Xint
  1513. Xwcrx()
  1514. X{
  1515. X    register unsigned int sectnum,sectcurr;
  1516. X    register unsigned char sendchar;
  1517. X    int cblklen;            /* bytes to dump this block */
  1518. X
  1519. X    Firstsec=1;
  1520. X    sectnum=0;
  1521. X    Eofseen=0;
  1522. X    sendchar=Crcflg ? WANTCRC : NAK;
  1523. X    report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
  1524. X
  1525. X    for(;;)
  1526. X    {
  1527. X        sendline(sendchar);    /* send it now,we're ready! */
  1528. X        if(sendchar == ACK)
  1529. X            report_last_txhdr("ACK",0);
  1530. X        Lleft=0;    /* Do read next time ... */
  1531. X        sectcurr=wcgetsec(secbuf,(sectnum&0177)?50:130);
  1532. X        sprintf(s128,"Block %d received",sectnum);
  1533. X        report_last_rxhdr(s128,0);
  1534. X        fstat(fileno(fout),&fout_stat);
  1535. X        report_rxpos(fout_stat.st_size);
  1536. X        if(sectcurr == (sectnum+1 & 0xFF))
  1537. X        {
  1538. X            sectnum++;
  1539. X            cblklen = Bytesleft>Blklen ? Blklen : Bytesleft;
  1540. X            if(write_sec_to_disk(secbuf,cblklen) == ERROR)
  1541. X                return(ERROR);
  1542. X            if((Bytesleft-=cblklen) < 0)
  1543. X                Bytesleft = 0;
  1544. X            sendchar=ACK;
  1545. X        }
  1546. X        else if(sectcurr == sectnum)
  1547. X        {
  1548. X            report_str("Received duplicate Sector",-1);
  1549. X            sendchar = ACK;
  1550. X        }
  1551. X        else if(sectcurr == WCEOT)
  1552. X        {
  1553. X            if(close_and_report())
  1554. X                return(ERROR);
  1555. X            sendline(ACK);
  1556. X            report_last_txhdr("ACK",0);
  1557. X            Lleft=0;    /* Do read next time ... */
  1558. X            return(OK);
  1559. X        }
  1560. X        else if(sectcurr==ERROR)
  1561. X            return(ERROR);
  1562. X        else 
  1563. X        {
  1564. X            report_str( "Sync Error",1);
  1565. X            return(ERROR);
  1566. X        }
  1567. X    }
  1568. X}    /* end of wcrx */
  1569. X
  1570. X/*+-------------------------------------------------------------------------
  1571. X    readline(timeout)
  1572. X
  1573. X  read one or more characters timeout is in tenths of seconds
  1574. X--------------------------------------------------------------------------*/
  1575. Xreadline(timeout)
  1576. Xint timeout;
  1577. X{
  1578. X    VOLATILE int n;
  1579. X    static unsigned char *cdq;    /* pointer for removing chars from linbuf */
  1580. X
  1581. X    if(--Lleft >= 0)
  1582. X        return(*cdq++);
  1583. X
  1584. X    n = timeout/10;
  1585. X    if(n < 2)
  1586. X        n = 3;
  1587. X    if(setjmp(tohere))
  1588. X    {
  1589. X        Lleft = 0;
  1590. X        return(TIMEOUT);
  1591. X    }
  1592. X    signal(SIGALRM,SIGALRM_handler);
  1593. X    alarm(n);
  1594. X    Lleft = read(iofd,(char *)(cdq = linbuf),Readnum);
  1595. X    alarm(0);
  1596. X    rx_char_count += Lleft;
  1597. X
  1598. X    if(Lleft < 1)
  1599. X        return(TIMEOUT);
  1600. X
  1601. X    --Lleft;
  1602. X    return(*cdq++);
  1603. X
  1604. X}    /* end of readline */
  1605. X
  1606. X/*+-------------------------------------------------------------------------
  1607. X    mkdir(dpath,dmode)
  1608. X Directory-creating routines from Public Domain TAR by John Gilmore
  1609. X Make a directory.  Compatible with the mkdir() system call on 4.2BSD.
  1610. X--------------------------------------------------------------------------*/
  1611. X#if defined(M_XENIX)
  1612. X#define    TERM_SIGNAL(status)        ((status) & 0x7F)
  1613. X#define TERM_COREDUMP(status)    (((status) & 0x80) != 0)
  1614. X#define TERM_VALUE(status)        ((status) >> 8)
  1615. Xmkdir(dpath,dmode)
  1616. Xchar *dpath;
  1617. Xint dmode;
  1618. X{
  1619. X    int cpid,status;
  1620. X    struct stat statbuf;
  1621. X
  1622. X    if(!stat(dpath,&statbuf))
  1623. X    {
  1624. X        errno = EEXIST;        /* Stat worked,so it already exists */
  1625. X        return(-1);
  1626. X    }
  1627. X
  1628. X    /* If stat fails for a reason other than non-existence,return error */
  1629. X    if(errno != ENOENT)
  1630. X        return(-1);
  1631. X
  1632. X    switch(cpid = fork())
  1633. X    {
  1634. X
  1635. X    case -1:            /* Error in fork() */
  1636. X        return(-1);        /* Errno is set already */
  1637. X
  1638. X    case 0:                /* Child process */
  1639. X        /*
  1640. X         * Cheap hack to set mode of new directory.  Since this
  1641. X         * child process is going away anyway,we zap its umask.
  1642. X         * FIXME,this won't suffice to set SUID,SGID,etc. on this
  1643. X         * directory.  Does anybody care?
  1644. X         */
  1645. X        status = umask(0);    /* Get current umask */
  1646. X        status = umask(status | (0777 & ~dmode)); /* Set for mkdir */
  1647. X        execl("/bin/mkdir","mkdir",dpath,(char *)0);
  1648. X        _exit(-1);        /* Can't exec /bin/mkdir */
  1649. X
  1650. X    default:            /* Parent process */
  1651. X        while(cpid != wait(&status)) ;    /* Wait for kid to finish */
  1652. X    }
  1653. X
  1654. X    if(TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0)
  1655. X    {
  1656. X        errno = EIO;        /* We don't know why,but */
  1657. X        return(-1);        /* /bin/mkdir failed */
  1658. X    }
  1659. X
  1660. X    return(0);
  1661. X}    /* end of mkdir */
  1662. X#endif /* M_XENIX */
  1663. X
  1664. X/*+-------------------------------------------------------------------------
  1665. X    make_dirs(pathname)
  1666. X
  1667. X  Directory-creating routines from Public Domain TAR by John Gilmore
  1668. X  After a file/link/symlink/dir creation has failed, see if it's because
  1669. X  some required directory was not present, and if so, create all
  1670. X  required dirs.
  1671. X--------------------------------------------------------------------------*/
  1672. Xint
  1673. Xmake_dirs(pathname)
  1674. Xregister char *pathname;
  1675. X{
  1676. X    register char *p;            /* Points into path */
  1677. X    int madeone = 0;            /* Did we do anything yet? */
  1678. X    int save_errno = errno;        /* Remember caller's errno */
  1679. X
  1680. X    if(errno != ENOENT)
  1681. X        return(0);        /* Not our problem */
  1682. X
  1683. X    for(p = strchr(pathname,'/'); p != NULL; p = strchr(p+1,'/'))
  1684. X    {
  1685. X        /* Avoid mkdir of empty string,if leading or double '/' */
  1686. X        if(p == pathname || p[-1] == '/')
  1687. X            continue;
  1688. X        /* Avoid mkdir where last part of path is '.' */
  1689. X        if(p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
  1690. X            continue;
  1691. X        *p = 0;                /* Truncate the path there */
  1692. X        if( !mkdir(pathname,0777))    /* Try to create it as a dir */
  1693. X        {
  1694. X            sprintf(s128,"Made directory %s",pathname);
  1695. X            report_str(s128,-1);
  1696. X            madeone++;        /* Remember if we made one */
  1697. X            *p = '/';
  1698. X            continue;
  1699. X        }
  1700. X        *p = '/';
  1701. X        if(errno == EEXIST)        /* Directory already exists */
  1702. X            continue;
  1703. X        /*
  1704. X         * Some other error in the mkdir.  We return to the caller.
  1705. X         */
  1706. X        break;
  1707. X    }
  1708. X    errno = save_errno;        /* Restore caller's errno */
  1709. X    return(madeone);            /* Tell them to retry if we made one */
  1710. X}    /* end of make_dirs */
  1711. X
  1712. X/*+-------------------------------------------------------------------------
  1713. X    uncaps(str) - make string str lower case
  1714. X--------------------------------------------------------------------------*/
  1715. Xvoid
  1716. Xuncaps(str)
  1717. Xregister char *str;
  1718. X{
  1719. X    register int itmp;
  1720. X
  1721. X    while(itmp = *str)
  1722. X    {
  1723. X        if(isupper(itmp))
  1724. X            *str = tolower(itmp);
  1725. X        str++;
  1726. X    }
  1727. X}    /* end of uncaps */
  1728. X
  1729. X/*+-------------------------------------------------------------------------
  1730. X    isanylc(str) - returns 1 if string str has any lower case letters
  1731. X--------------------------------------------------------------------------*/
  1732. Xint
  1733. Xisanylc(str)
  1734. Xregister char *str;
  1735. X{
  1736. X    while(*str)
  1737. X    {
  1738. X        if(islower(*str))
  1739. X            return(1);
  1740. X        str++;
  1741. X    }
  1742. X    return(0);
  1743. X}    /* end of isanylc */
  1744. X
  1745. X/*+-------------------------------------------------------------------------
  1746. X    procheader(name) - process incoming file information header
  1747. X
  1748. Xreturns with 0 and FILE *fout open to receive file if good headers
  1749. Xand all is right with the filesystem, else returns error code
  1750. X--------------------------------------------------------------------------*/
  1751. Xint
  1752. Xprocheader(name)
  1753. Xchar *name;
  1754. X{
  1755. X    register char *openmode,*p;
  1756. X    char zmanag2;
  1757. X
  1758. X    /* set default parameters and overrides */
  1759. X    fout = (FILE *)0;
  1760. X    openmode = "w";
  1761. X    rxfilepos = 0L;
  1762. X    Thisbinary = (!Rxascii) || Rxbinary;
  1763. X    if(Lzmanag)
  1764. X        zmanag = Lzmanag;
  1765. X    zmanag2 = zmanag & ZMMASK;
  1766. X
  1767. X    /*
  1768. X     *  Process ZMODEM remote file management requests
  1769. X     */
  1770. X    if(!Rxbinary && zconv == ZCNL)    /* Remote ASCII override */
  1771. X        Thisbinary = 0;
  1772. X    if(zconv == ZCBIN)    /* Remote Binary override */
  1773. X        Thisbinary = 1;
  1774. X
  1775. X    report_xfer_mode(Thisbinary ? "BINARY" : "ASCII");
  1776. X    this_file_errors = 0;
  1777. X
  1778. X    Bytesleft = DEFBYTL;
  1779. X    Filemode = 0;
  1780. X    Modtime = 0L;
  1781. X    this_file_length = 0L;
  1782. X    initial_filepos = 0L;
  1783. X
  1784. X    if(strlen(name))
  1785. X        p = name + 1 + strlen(name);
  1786. X    else
  1787. X        p = name;
  1788. X
  1789. X    if(*p)
  1790. X    {    /* header has attributes */
  1791. X    int sscanf_count = 0;
  1792. X    int SerialNumber = 0;
  1793. X    int Filesleft = 0;
  1794. X    long TotalLeft = 0;
  1795. X
  1796. X        sscanf_count = sscanf(p,"%ld%lo%o%d&d&ld",
  1797. X            &Bytesleft,        /* file size */
  1798. X            &Modtime,        /* secs since 1970 */
  1799. X            &Filemode,        /* unix st_mode */
  1800. X            &SerialNumber,    /* vaxism */
  1801. X            &Filesleft,&TotalLeft);
  1802. X
  1803. X        switch(sscanf_count)
  1804. X        {
  1805. X            case 6:    /* TotalLeft */
  1806. X                if(!TotalToReceive)
  1807. X                    TotalToReceive = TotalLeft;
  1808. X            case 5:    /* Filesleft */
  1809. X                if(!npats)
  1810. X                    npats = Filesleft;
  1811. X            default:
  1812. X                break;
  1813. X        }
  1814. X
  1815. X        if(Thisbinary && (zconv == ZCRESUM))
  1816. X        {
  1817. X            if(!stat(name,&fout_stat))            /* if file accessible ... */
  1818. X            {
  1819. X                openmode = "r+";
  1820. X                rxfilepos = fout_stat.st_size - 1024; /* re-get last 1024 */
  1821. X                if(Bytesleft < rxfilepos)
  1822. X                    rxfilepos = 0;
  1823. X                if(rxfilepos < 0)
  1824. X                    rxfilepos = 0;
  1825. X                initial_filepos = rxfilepos;
  1826. X                expect_zrpos = 1;    /* don't count first ZRPOS as error */
  1827. X            }
  1828. X        }
  1829. X        else if(zmanag2 == ZMNEW)
  1830. X        {
  1831. X            if(!stat(name,&fout_stat))            /* if file accessible ... */
  1832. X            {
  1833. X                if(Modtime <= fout_stat.st_mtime)    /* ... and not older */
  1834. X                {
  1835. X                    sprintf(s128,"RECEIVE skipped: %s (same or later date)",
  1836. X                        name);
  1837. X                    report_str(s128 + 8,-1);
  1838. X                    skip_count++;
  1839. X                    report_error_count();
  1840. X#if defined(LOG_SKIP)
  1841. X                    ecu_log_event(getppid(),s128);
  1842. X#endif
  1843. X                    return(ERROR);
  1844. X                }
  1845. X                openmode = "w";
  1846. X                if(!(fout = our_fopen(name,openmode)))
  1847. X                    return ZFERR;
  1848. X            }
  1849. X        }
  1850. X        else if(zmanag2 == ZMAPND)
  1851. X        {
  1852. X            if(!stat(name,&fout_stat))            /* if file accessible ... */
  1853. X                initial_filepos = fout_stat.st_size;
  1854. X        }
  1855. X        else if(!Rxclob && ((zmanag2 != ZMCLOB)) && !access(name,0))
  1856. X        {
  1857. X            sprintf(s128,"RECEIVE skipped: %s (already exists)",name);
  1858. X            report_str(s128 + 8,-1);
  1859. X            skip_count++;
  1860. X            report_error_count();
  1861. X#if defined(LOG_SKIP)
  1862. X            ecu_log_event(getppid(),s128);
  1863. X#endif
  1864. X            return(ERROR);
  1865. X        }
  1866. X
  1867. X        if(Filemode & UNIXFILE)
  1868. X            ++Thisbinary;
  1869. X
  1870. X        report_rxpos(0L);
  1871. X        report_str("",0);    /* get rid of End of File */
  1872. X        if(Bytesleft != DEFBYTL)
  1873. X        {
  1874. X            long min_100;
  1875. X            this_file_length = Bytesleft;
  1876. X            min_100 = 2L + ((((Bytesleft - initial_filepos) * 11L)) * 10L) /
  1877. X                (Baudrate * 6L);
  1878. X            report_file_rcv_started(name,Bytesleft,
  1879. X                Modtime,(unsigned short)Filemode);
  1880. X            sprintf(s128,"Receive time this file ~= %2lu:%02lu",
  1881. X                min_100 / 100,((min_100 % 100) * 60L) / 100L);
  1882. X            if(TotalToReceive)
  1883. X            {
  1884. X                min_100 = 2L +
  1885. X                    (((TotalToReceive * 11L)) * 10L) / (Baudrate * 6L);
  1886. X                if(Baudrate > 4800)
  1887. X                {
  1888. X                    min_100 *= 13;
  1889. X                    min_100 /= 9;    /* yech ... empirical */
  1890. X                }
  1891. X                sprintf(&s128[strlen(s128)],", transaction ~= %2lu:%02lu",
  1892. X                    min_100 / 100,((min_100 % 100) * 60L) / 100L);
  1893. X            }
  1894. X            report_transaction(s128);
  1895. X            sprintf(s128,"Receiving data (%d%% complete)",(int)0);
  1896. X            report_str(s128,0);
  1897. X        }
  1898. X    }
  1899. X    else 
  1900. X    {
  1901. X        long now;
  1902. X        for(p=name; *p; ++p)        /* change / to _ */
  1903. X        {
  1904. X            if( *p == '/')
  1905. X                *p = '_';
  1906. X        }
  1907. X
  1908. X        if( *--p == '.')        /* zap trailing period */
  1909. X            *p = 0;
  1910. X        time(&now);
  1911. X        report_file_rcv_started(name,0,now,0);
  1912. X    }
  1913. X
  1914. X    if(!Zmodem && MakeLCPathname && !isanylc(name) && !(Filemode&UNIXFILE))
  1915. X        uncaps(name);
  1916. X
  1917. X    strcpy(Pathname,name);
  1918. X    report_xfer_mode(Thisbinary?"BINARY":"ASCII");
  1919. X    if(!fout)
  1920. X        fout = our_fopen(name,openmode);
  1921. X    if(!fout)
  1922. X    {
  1923. X        if(make_dirs(name))
  1924. X            fout = our_fopen(name,openmode);
  1925. X    }
  1926. X    if(!fout)
  1927. X    {
  1928. X        if(errno > sys_nerr)
  1929. X            sprintf(s128,"%-0.64s: open errno %d",name,errno);
  1930. X        else
  1931. X            sprintf(s128,"%-0.64s: open error: %s",name,sys_errlist[errno]);
  1932. X        ecu_log_event(getppid(),s128);
  1933. X        skip_count++;
  1934. X        report_error_count();
  1935. X        return(ERROR);
  1936. X    }
  1937. X    if(fseek(fout,rxfilepos,0))
  1938. X    {
  1939. X        fclose(fout);
  1940. X        fout = (FILE *)0;
  1941. X        if(errno > sys_nerr)
  1942. X            sprintf(s128,"%-0.64s: seek errno %d",name,errno);
  1943. X        else
  1944. X            sprintf(s128,"%-0.64s: seek error: %s",name,sys_errlist[errno]);
  1945. X        ecu_log_event(getppid(),s128);
  1946. X        skip_count++;
  1947. X        report_error_count();
  1948. X        return(ERROR);
  1949. X    }
  1950. X    this_file_errors = 0;
  1951. X    return(OK);
  1952. X}    /* end of procheader */
  1953. X
  1954. X/*+-------------------------------------------------------------------------
  1955. X    send_cancel(error) - send cancel string
  1956. X--------------------------------------------------------------------------*/
  1957. Xvoid
  1958. Xsend_cancel(error)
  1959. Xint error;
  1960. X{
  1961. X    static char canistr[] = {
  1962. X        24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  1963. X    };
  1964. X    register char *cptr = canistr;
  1965. X
  1966. X    purgeline();
  1967. X    report_str("",0);
  1968. X    report_last_txhdr("^X CAN",!!error);
  1969. X    while(*cptr)
  1970. X        sendline(*cptr++);
  1971. X    Lleft=0;
  1972. X}    /* end of send_cancel */
  1973. X
  1974. X/*+-------------------------------------------------------------------------
  1975. X    send_ZFIN() - send ZFIN frame and wait for "OO" ack
  1976. X--------------------------------------------------------------------------*/
  1977. Xvoid
  1978. Xsend_ZFIN()
  1979. X{
  1980. X    register n;
  1981. X
  1982. X    Readnum = 1;
  1983. X    stohdr(0L);
  1984. X    for(n = 0; n < 4; n++)
  1985. X    {
  1986. X        purgeline();
  1987. X        zshhdr(ZFIN,Txhdr);
  1988. X        switch(readline(100))
  1989. X        {
  1990. X        case 'O':
  1991. X            readline(1);    /* Discard 2nd 'O' */
  1992. X            return;
  1993. X        case RCDO:
  1994. X            return;
  1995. X        case TIMEOUT:
  1996. X        default:
  1997. X            break;
  1998. X        }
  1999. X    }
  2000. X}    /* end of send_ZFIN */
  2001. X
  2002. X/*+-------------------------------------------------------------------------
  2003. X    tryz()
  2004. X
  2005. X  Initialize for Zmodem receive attempt, try to activate Zmodem sender
  2006. X  Handles ZSINIT frame
  2007. X  Return ZFILE if Zmodem filename received,-1 on error,
  2008. X         ZCOMPL if transaction finished, else 0
  2009. X--------------------------------------------------------------------------*/
  2010. Xint
  2011. Xtryz()
  2012. X{
  2013. X    register c;
  2014. X    register n;
  2015. X
  2016. X    if(Nozmodem)        /* Check for "rb" program name */
  2017. X        return(0);
  2018. X
  2019. X    for(n=Zmodem?15:5; --n>=0; )
  2020. X    {
  2021. X        /* Set buffer length (0) and capability flags */
  2022. X        stohdr(0L);
  2023. X
  2024. X#if defined(CANBREAK)
  2025. X        Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
  2026. X#else
  2027. X        Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
  2028. X#endif
  2029. X        if(Zctlesc)
  2030. X            Txhdr[ZF0] |= TESCCTL;
  2031. X        zshhdr(tryzhdrtype,Txhdr);
  2032. X        if(tryzhdrtype == ZSKIP)    /* Don't skip too far */
  2033. X            tryzhdrtype = ZRINIT;    /* CAF 8-21-87 */
  2034. Xagain:
  2035. X        switch(zgethdr(Rxhdr,0))
  2036. X        {
  2037. X        case ZRQINIT:
  2038. X            continue;
  2039. X        case ZEOF:
  2040. X            continue;
  2041. X        case TIMEOUT:
  2042. X            continue;
  2043. X        case ZFILE:
  2044. X            zconv = Rxhdr[ZF0];
  2045. X            zmanag = Rxhdr[ZF1];
  2046. X            ztrans = Rxhdr[ZF2];
  2047. X
  2048. X            strcpy(s128,"Transfer type: ");
  2049. X            if(zconv == ZCRESUM)
  2050. X                strcat(s128,"resume interrupted transfer");
  2051. X            else
  2052. X            {
  2053. X                switch(c = zmanag & ZMMASK)
  2054. X                {
  2055. X                case 0:
  2056. X                    strcat(s128,"if destination nonexistent");
  2057. X                    break;
  2058. X                case ZMAPND:
  2059. X                    strcat(s128,"append to destination");
  2060. X                    break;
  2061. X                case ZMCLOB:
  2062. X                    strcat(s128,"unconditional (overwrite)");
  2063. X                    break;
  2064. X                case ZMNEW:
  2065. X                    strcat(s128,"if source newer");
  2066. X                    break;
  2067. X                default:
  2068. X                    strcat(s128,"management option ");
  2069. X                    switch(c)
  2070. X                    {
  2071. X                        case ZMNEWL:    strcat(s128,"ZMNEWL"); break;
  2072. X                        case ZMCRC:        strcat(s128,"ZMCRC"); break;
  2073. X                        case ZMDIFF:    strcat(s128,"ZMDIFF"); break;
  2074. X                        case ZMPROT:    strcat(s128,"ZMPROT"); break;
  2075. X                        default:
  2076. X                            sprintf(s128 + strlen(s128),"%u",c);
  2077. X                            break;
  2078. X                    }
  2079. X                    break;
  2080. X                }
  2081. X            }
  2082. X            report_str(s128,2);
  2083. X
  2084. X            tryzhdrtype = ZRINIT;
  2085. X            c = zrdata(secbuf,1024);
  2086. X            mode(3);
  2087. X            if(c == GOTCRCW)
  2088. X                return(ZFILE);
  2089. X            zshhdr(ZNAK,Txhdr);
  2090. X            goto again;
  2091. X        case ZSINIT:
  2092. X            Zctlesc = TESCCTL & Rxhdr[ZF0];
  2093. X            if(zrdata(Attn,ZATTNLEN) == GOTCRCW)
  2094. X            {
  2095. X                stohdr(1L);
  2096. X                zshhdr(ZACK,Txhdr);
  2097. X                report_str("",-1);
  2098. X                goto again;
  2099. X            }
  2100. X            zshhdr(ZNAK,Txhdr);
  2101. X            goto again;
  2102. X        case ZFREECNT:
  2103. X            stohdr(getfree());
  2104. X            zshhdr(ZACK,Txhdr);
  2105. X            report_str("",-1);
  2106. X            goto again;
  2107. X        case ZCOMMAND:
  2108. X            if(zrdata(secbuf,1024) == GOTCRCW)
  2109. X            {
  2110. X                stohdr(-1L);
  2111. X                purgeline();    /* dump impatient questions */
  2112. X                while(errors < 20)
  2113. X                {
  2114. X                    zshhdr(ZCOMPL,Txhdr);
  2115. X                    if(zgethdr(Rxhdr,1) == ZFIN)
  2116. X                        break;
  2117. X                }
  2118. X                send_ZFIN();
  2119. X                return(ZCOMPL);
  2120. X            }
  2121. X            zshhdr(ZNAK,Txhdr);
  2122. X            goto again;
  2123. X        case ZCOMPL:
  2124. X            goto again;
  2125. X        default:
  2126. X            continue;
  2127. X        case ZFIN:
  2128. X            send_ZFIN();
  2129. X            return(ZCOMPL);
  2130. X        case ZCAN:
  2131. X            return(ERROR);
  2132. X        }
  2133. X    }
  2134. X    return(0);
  2135. X}    /* end of tryz */
  2136. X
  2137. X/*+-------------------------------------------------------------------------
  2138. X    rzfile() - receive a file with ZMODEM protocol
  2139. X
  2140. X  assumes file name frame is in secbuf
  2141. X--------------------------------------------------------------------------*/
  2142. Xint
  2143. Xrzfile()
  2144. X{
  2145. X    register c,n;
  2146. X    char s64[64];
  2147. X
  2148. X    Eofseen=0;
  2149. X    rxfilepos = 0L;
  2150. X    if(procheader(secbuf) == ERROR)
  2151. X    {
  2152. X        return(tryzhdrtype = ZSKIP);
  2153. X    }
  2154. X
  2155. X    n = 20;
  2156. X
  2157. X    for(;;)
  2158. X    {
  2159. X        if(rxfilepos && !expect_zrpos)
  2160. X        {
  2161. X            sprintf(s64,"Sending ZRPOS (%ld)",rxfilepos);
  2162. X            report_str(s64,1);
  2163. X        }
  2164. X        else
  2165. X            report_str("Starting sender",0);
  2166. X        expect_zrpos = 0;
  2167. X        stohdr(rxfilepos);
  2168. X        zshhdr(ZRPOS,Txhdr);
  2169. Xnxthdr:
  2170. X        report_receive_progress(rxfilepos);
  2171. X        switch(c = zgethdr(Rxhdr,0))
  2172. X        {
  2173. X        default:
  2174. X            sprintf(s128,got_garbage_txt,c);
  2175. SHAR_EOF
  2176. true || echo 'restore of z/ecurz.c failed'
  2177. fi
  2178. echo 'End of ecu320 part 23'
  2179. echo 'File z/ecurz.c is continued in part 24'
  2180. echo 24 > _shar_seq_.tmp
  2181. exit 0
  2182.  
  2183. exit 0 # Just in case...
  2184.