home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume22 / prtscrn / part01 next >
Encoding:
Text File  |  1991-08-17  |  10.6 KB  |  395 lines

  1. Newsgroups: comp.sources.misc
  2. From: Chip Rosenthal <chip@chinacat.unicom.com>
  3. Subject:  v22i027:  prtscrn - screen dump utility for SCO UNIX/XENIX, Part01/01
  4. Message-ID: <1991Aug18.004439.14517@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: a8f22b02e4d97730d2d486d63939d9f7
  6. Date: Sun, 18 Aug 1991 00:44:39 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Chip Rosenthal <chip@chinacat.unicom.com>
  10. Posting-number: Volume 22, Issue 27
  11. Archive-name: prtscrn/part01
  12. Environment: SCO
  13.  
  14. `prtscrn' grabs the contents of a console MultiScreen(tm) on SCO
  15. UNIX and XENIX systems, and sends them to stdout.
  16.  
  17. To dump the contents of /dev/tty01 to a file, you'd run:
  18.  
  19.     prtscrn -1 >filename
  20.  
  21. When compiling, be sure you specify either -DSCO_UNIX or -DSCO_XENIX.
  22.  
  23. #! /bin/sh
  24. # this is a "shar" archive - run through "/bin/sh" to extract 3 files:
  25. #   README prtscrn.c prtscrn.1
  26. # Wrapped by chip@chinacat on Sat Aug 17 18:30:56 CDT 1991
  27. # Unpacking this archive requires:  sed test wc (possibly mkdir)
  28. # Existing files will not be clobbered unless "-c" is specified on the cmd line.
  29. if test -f README -a "$1" != "-c" ; then
  30.     echo "README: file exists - will not be overwritten"
  31. else
  32.     echo "x - README (file 1 of 3, 1250 chars)"
  33.     sed -e 's/^X//' << 'END_OF_FILE_README' > README
  34. X`prtscrn' grabs the contents of a console MultiScreen(tm) on SCO
  35. XUNIX and XENIX systems.
  36. X
  37. XTo dump the contents of /dev/tty01 to a file, you'd run:
  38. X
  39. X    prtscrn -1 >filename
  40. X
  41. XWhen compiling, you need to define either SCO_UNIX or SCO_XENIX.
  42. X
  43. XSince this utility gropes through /dev/console, /dev/kmem, and the
  44. Xkernel (/xenix or /unix), it needs to be installed setuid.  Unfortunately,
  45. Xgiven the places it needs to grope, I don't think you'll get away with
  46. Xanything less than setting the ownership to `root'.  The privileges
  47. Xare renounced once `prtscrn' has the information it needs and *before*
  48. Xit attempts to grab the requested screen.  Therefore, this utility
  49. Xwill not access to a screen to which the user does not have permissions.
  50. X
  51. XTherefore, to build this you need to:
  52. X
  53. X    cc -O -DSCO_UNIX -o prtscrn prtscrn.c    (or -DSCO_XENIX)
  54. X    cp prtscrn /usr/bin/prtscrn
  55. X    chown root /usr/bin/prtscrn
  56. X    chmod 4711 /usr/bin/prtscrn
  57. X
  58. XI believe there is a bug in the SCO UNIX console driver which this
  59. Xprogram runs into.  A character gets munged in the screen printing
  60. Xsequence, so after you run this program you might find the character
  61. Xin the bottom-left corner of the screen to be a space.
  62. X
  63. XChip Rosenthal
  64. X<chip@chinacat.Unicom.COM>
  65. X
  66. X@(#) README 1.1 91/08/17 18:29:09
  67. X
  68. END_OF_FILE_README
  69.     size="`wc -c < README`"
  70.     if test 1250 -ne "$size" ; then
  71.     echo "README: extraction error - got $size chars"
  72.     fi
  73. fi
  74. if test -f prtscrn.c -a "$1" != "-c" ; then
  75.     echo "prtscrn.c: file exists - will not be overwritten"
  76. else
  77.     echo "x - prtscrn.c (file 2 of 3, 6099 chars)"
  78.     sed -e 's/^X//' << 'END_OF_FILE_prtscrn.c' > prtscrn.c
  79. X#ifndef lint
  80. Xstatic char SCCSID[] = "@(#) prtscrn.c 1.3 91/08/17 18:28:53";
  81. X#endif
  82. X
  83. X/*
  84. X * prtscrn - SCO UNIX/XENIX screen dump utility.
  85. X *
  86. X * This must be compiled with either SCO_XENIX or SCO_UNIX defined.
  87. X *
  88. X * This utility will grab the contents of another console multiscreen
  89. X * (permissions willing) and send it to the stdout of the process
  90. X * running on the invoking screen.
  91. X *
  92. X * Edit at tabstops=4.
  93. X *
  94. X * Chip Rosenthal, Unicom Systems Development, Inc.
  95. X * <chip@chinacat.unicom.com>
  96. X */
  97. X
  98. X#define USAGE    "usage: %s -screen_num\n"
  99. X
  100. X#include <stdio.h>
  101. X#include <ctype.h>
  102. X#include <string.h>
  103. X#include <fcntl.h>
  104. X#include <sys/types.h>
  105. X
  106. X#ifdef SCO_XENIX
  107. X#include <sys/a.out.h>
  108. X#include <sys/ioctl.h>
  109. X#include <sys/vid.h>
  110. X#define KERNEL    "/xenix"
  111. X#define KBGRP    "_cn_kbgr"
  112. X#endif /*SCO_XENIX*/
  113. X
  114. X#ifdef SCO_UNIX
  115. X#include <nlist.h>
  116. X#include <sys/vid.h>
  117. X#include <sys/console.h>
  118. X#define KERNEL    "/unix"
  119. X#define KBGRP    "cn_kbgrp"
  120. X#define SCO_CONSOLE_BUG
  121. X#endif /*SCO_UNIX*/
  122. X
  123. X#ifndef KERNEL
  124. X#error you need to define either SCO_UNIX or SCO_XENIX
  125. X#endif
  126. X
  127. X#ifdef strerror    /* so much for sqa */
  128. X# undef strerror
  129. X# define strerror(n) (sys_errlist[n])
  130. X#endif
  131. X
  132. X#define MAXCOLS    256
  133. X
  134. Xchar *Progname;
  135. Xchar *Kernel = KERNEL;
  136. X
  137. Xstruct {
  138. X    int mode;
  139. X    int ncols;
  140. X    int nrows;
  141. X} Disptab[] = {
  142. X    { M_B40x25,            40, 25 },
  143. X    { M_C40x25,            40, 25 },
  144. X    { M_ENH_B40x25,        40, 25 },
  145. X    { M_ENH_C40x25,        40, 25 },
  146. X    { M_VGA_40x25,        40, 25 },
  147. X    { M_B80x25,            80, 25 },
  148. X    { M_C80x25,            80, 25 },
  149. X    { M_EGAMONO80x25,    80, 25 },
  150. X    { M_ENH_B80x25,        80, 25 },
  151. X    { M_ENH_C80x25,        80, 25 },
  152. X    { M_VGA_80x25,        80, 25 },
  153. X    { M_VGA_M80x25,        80, 25 },
  154. X    { M_MCA_MODE,        80, 25 },
  155. X    { M_ENH_B80x43,        80, 43 },
  156. X    { M_ENH_C80x43,        80, 43 },
  157. X    { -1,                0,   0 }
  158. X};
  159. X
  160. Xstruct nlist nl[] = { 
  161. X    { KBGRP, },
  162. X    { "", },
  163. X};
  164. X
  165. Xchar *strtrim();
  166. X
  167. Xextern int errno;
  168. Xextern char *sys_errlist[];
  169. X
  170. X
  171. Xvoid setscreen(fd, scrnum)
  172. Xint fd, scrnum;
  173. X{
  174. X    char buf[8];
  175. X#ifdef SCO_CONSOLE_BUG
  176. X    /*
  177. X     * There is a bug in the SCO3.2v2.0 console driver.  When you use the
  178. X     * screen switch escape, a character gets munched.  We need to provide
  179. X     * a byte of fodder to preserve the switch screen sequence.
  180. X     */
  181. X    write(fd, " ", 1);
  182. X#endif
  183. X    sprintf(buf, "\033[%dz", scrnum-1);
  184. X    write(fd, buf, strlen(buf));
  185. X}
  186. X
  187. X
  188. Xmain(argc, argv)
  189. Xint argc;
  190. Xchar *argv[];
  191. X{
  192. X    char *disp_mem;            /* pointer to video display memory        */
  193. X    char scrname[64];        /* pathname to selected screen            */
  194. X    char linebuf[MAXCOLS+1];/* space to hold a lineful of chars        */
  195. X    int curr_scrn;            /* screen initially being displayed        */
  196. X    int sel_scrn;            /* selected screen to dump                */
  197. X    int disp_mode;            /* display mode of selected screen        */
  198. X    int num_cols;            /* number of columns in selected screen    */
  199. X    int num_rows;            /* number of rows in selected screen    */
  200. X    int fd_cons;            /* file descriptor for console output    */
  201. X    struct kbgrp kb;        /* kernel struct with curr screen info    */
  202. X    int row, col, fd, i;
  203. X
  204. X    Progname = argv[0];
  205. X
  206. X    if (argc != 2 && *argv[1] != '-') {
  207. X        fprintf(stderr, USAGE, Progname);
  208. X        exit(1);
  209. X    }
  210. X
  211. X    /*
  212. X     * See which screen we want to dump.
  213. X     */
  214. X    sel_scrn = atoi(argv[1]+1);
  215. X    if (sel_scrn < 1 || sel_scrn > MAXSCRN) {
  216. X        fprintf(stderr, "%s: bad screen number specified\n", Progname);
  217. X        exit(1);
  218. X    }
  219. X    sprintf(scrname, "/dev/tty%02d", sel_scrn);
  220. X
  221. X    /*
  222. X     * Open up the current screen.
  223. X     */
  224. X    if ((fd_cons = open("/dev/console", O_RDWR)) < 0) {
  225. X        fprintf(stderr, "%s: open(/dev/console) failed [%s]\n",
  226. X            Progname, strerror(errno));
  227. X        exit(1);
  228. X    }
  229. X
  230. X    /*
  231. X     * Rummage around in the kernel to determine currently active multiscreen.
  232. X     * Thanks to Karl Bunch <karl@ttank.com> for the idea on how to do this.
  233. X     */
  234. X    if (nlist(Kernel, nl) != 0) {
  235. X        fprintf(stderr, "%s: nlist(%s) failed [%s]\n",
  236. X            Progname, Kernel, strerror(errno));
  237. X        exit(1);
  238. X    }
  239. X    if (nl[0].n_value == 0) {
  240. X        fprintf(stderr, "%s: nlist(%s) failed\n", Progname, Kernel);
  241. X        exit(1);
  242. X    }
  243. X    if ((fd = open("/dev/kmem", O_RDONLY)) < 0) {
  244. X        fprintf(stderr, "%s: open(/dev/kmem) failed [%s]\n",
  245. X            Progname, strerror(errno));
  246. X        exit(1);
  247. X    }
  248. X    if (lseek(fd, (long)nl[0].n_value, 0) == -1) {
  249. X        fprintf(stderr, "%s: lseek(/dev/kmem) failed [%s]\n",
  250. X            Progname, strerror(errno));
  251. X        exit(1);
  252. X    }
  253. X    if (read(fd, (char *)&kb, sizeof(kb)) != sizeof(kb)) {
  254. X        fprintf(stderr, "%s: read(/dev/kmem) failed [%s]\n",
  255. X            Progname, strerror(errno));
  256. X        exit(1);
  257. X    }
  258. X    curr_scrn = kb.kg_curscrn+1;
  259. X    close(fd);
  260. X
  261. X    /*
  262. X     * We only needed priviliges to get the active screen.  Renounce them.
  263. X     */
  264. X    setuid(getuid());
  265. X    setgid(getgid());
  266. X
  267. X    /*
  268. X     * Open up the the selected screen.  Switch display to the selected
  269. X     * screen.  Get the display mode and map in the display memory.
  270. X     */
  271. X    if ((fd = open(scrname, O_RDWR)) < 0) {
  272. X        fprintf(stderr, "%s: could not open '%s' [%s]\n",
  273. X            Progname, scrname, strerror(errno));
  274. X        exit(1);
  275. X    }
  276. X    setscreen(fd_cons, sel_scrn);
  277. X    if ((disp_mode = ioctl(fd, CONS_GET, 0)) < 0) {
  278. X        setscreen(fd_cons, curr_scrn);
  279. X        fprintf(stderr, "%s: could not get display type [%s]\n",
  280. X            Progname, strerror(errno));
  281. X        exit(1);
  282. X    }
  283. X    if ((disp_mem = (char *)ioctl(fd, MAPCONS, 0)) == NULL) {
  284. X        setscreen(fd_cons, curr_scrn);
  285. X        fprintf(stderr, "%s: could not map display memory [%s]\n",
  286. X            Progname, strerror(errno));
  287. X        exit(1);
  288. X    }
  289. X    (void) close(fd);
  290. X
  291. X    /*
  292. X     * Determine the size of the screen in the current mode.
  293. X     */
  294. X    for (i = 0 ; Disptab[i].mode >= 0 && Disptab[i].mode != disp_mode ; ++i)
  295. X        ;
  296. X    if (Disptab[i].mode < 0) {
  297. X        setscreen(fd_cons, curr_scrn);
  298. X        fprintf(stderr, "%s: display not in supported text mode\n", Progname);
  299. X        exit(1);
  300. X    }
  301. X    num_cols = Disptab[i].ncols;
  302. X    num_rows = Disptab[i].nrows;
  303. X
  304. X    /*
  305. X     * Extract the characters from display memory and send to stdout.
  306. X     */
  307. X    for (row = 0 ; row < num_rows ; ++row) {
  308. X        for (col = 0 ; col < num_cols ; ++col) {
  309. X            linebuf[col] = *disp_mem;
  310. X            disp_mem += 2;
  311. X        }
  312. X        linebuf[col] = '\0';
  313. X        puts(strtrim(linebuf));
  314. X    }
  315. X
  316. X    /*
  317. X     * Restore back to the original screen.
  318. X     */
  319. X    setscreen(fd_cons, curr_scrn);
  320. X
  321. X    exit(0);
  322. X    /*NOTREACHED*/
  323. X}
  324. X
  325. X
  326. Xchar *strtrim(str)
  327. Xchar *str;
  328. X{
  329. X    char *s, *nonwhite;
  330. X
  331. X    for (nonwhite = NULL, s = str ; *s != '\0' ; ++s) {
  332. X        if (!isascii(*s) || !isspace(*s))
  333. X            nonwhite = s;
  334. X    }
  335. X
  336. X    if (nonwhite != NULL)
  337. X        *(nonwhite+1) = '\0';
  338. X
  339. X    return str;
  340. X}
  341. X
  342. END_OF_FILE_prtscrn.c
  343.     size="`wc -c < prtscrn.c`"
  344.     if test 6099 -ne "$size" ; then
  345.     echo "prtscrn.c: extraction error - got $size chars"
  346.     fi
  347. fi
  348. if test -f prtscrn.1 -a "$1" != "-c" ; then
  349.     echo "prtscrn.1: file exists - will not be overwritten"
  350. else
  351.     echo "x - prtscrn.1 (file 3 of 3, 550 chars)"
  352.     sed -e 's/^X//' << 'END_OF_FILE_prtscrn.1' > prtscrn.1
  353. X.\" @(#) prtscrn.1 1.2 91/08/17 18:28:53
  354. X.TH PRTSCRN 1L
  355. X.SH NAME
  356. Xprtscrn - Print contents of a console multiscreen.
  357. X.SH SYNTAX
  358. X.B prtscrn
  359. X.BR \- screen_num
  360. X.SH DESCRIPTION
  361. XThe contents of the specified console multiscreen are sent to the
  362. Xstandard output.  If the user does not have permissions to access the
  363. Xspecified screen, then
  364. X.I prtscrn
  365. Xwill fail with an error.
  366. X.SH BUGS
  367. XNever tested with multiple display adapters.
  368. XOnly supports text mode operation.
  369. X.SH AUTHOR
  370. XChip Rosenthal
  371. X.br
  372. XUnicom Systems Development, Inc.
  373. X.br
  374. X<chip@chinacat.unicom.com>
  375. END_OF_FILE_prtscrn.1
  376.     size="`wc -c < prtscrn.1`"
  377.     if test 550 -ne "$size" ; then
  378.     echo "prtscrn.1: extraction error - got $size chars"
  379.     fi
  380. fi
  381. echo "done - 3 files extracted"
  382. exit 0
  383. -- 
  384. Chip Rosenthal  512-482-8260  |  Lotus 1-2-3 for UNIX...it's a product
  385. Unicom Systems Development    |  you don't have to support.
  386. <chip@chinacat.Unicom.COM>    |    - recent Lotus 1-2-3 advert
  387.  
  388.  
  389. exit 0 # Just in case...
  390. -- 
  391. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  392. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  393. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  394. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  395.