home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / sources / misc / 3950 < prev    next >
Encoding:
Text File  |  1992-09-14  |  57.1 KB  |  2,190 lines

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