home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume16 / pan / part06 < prev    next >
Encoding:
Text File  |  1992-03-06  |  17.5 KB  |  625 lines

  1. Newsgroups: comp.sources.x
  2. Path: uunet!think.com!mips!msi!dcmartin
  3. From: jeff@rd1.interlan.com (Jeff Bailey)
  4. Subject: v16i142: pan - Post A Note (for Open Windows), Part06/06
  5. Message-ID: <1992Mar6.200422.8408@msi.com>
  6. Originator: dcmartin@fascet
  7. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  8. Organization: Molecular Simulations, Inc.
  9. References: <csx-16i137-pan@uunet.UU.NET>
  10. Date: Fri, 6 Mar 1992 20:04:22 GMT
  11. Approved: dcmartin@msi.com
  12.  
  13. Submitted-by: jeff@rd1.interlan.com (Jeff Bailey)
  14. Posting-number: Volume 16, Issue 142
  15. Archive-name: pan/part06
  16.  
  17.  
  18. ---- Cut Here and feed the following to sh ----
  19. #!/bin/sh
  20. # This is part 06 of a multipart archive
  21. # ============= search.c ==============
  22. if test -f 'search.c' -a X"$1" != X"-c"; then
  23.     echo 'x - skipping search.c (File already exists)'
  24. else
  25. echo 'x - extracting search.c (Text)'
  26. sed 's/^X//' << 'SHAR_EOF' > 'search.c' &&
  27. /*
  28. Post A Note V2.4
  29. Copyright (c) 1992, Jeffrey W. Bailey
  30. All rights reserved.
  31. X
  32. Permission is granted to distribute this program in exact, complete
  33. source form, which includes this copyright notice, as long as no fee
  34. other than media and distribution cost is charged.
  35. X
  36. This program may not be used in whole, or in part, in any other manner
  37. without prior written permission from the author.
  38. X
  39. This program may not be distributed in modified form without prior
  40. written permission from the author.  In other words, patches may be
  41. distributed, but modified source may not be distributed.
  42. X
  43. If there are any questions, comments or suggestions, the author may be
  44. contacted at:
  45. X
  46. X    jeff@rd1.interlan.com
  47. X
  48. X    or
  49. X
  50. X    Jeffrey Bailey
  51. X    Racal-Datacom, Inc.
  52. X    Mail Stop E-110
  53. X    1601 N. Harrison Parkway
  54. X    Sunrise, FL  33323-2899
  55. */
  56. X
  57. #include "pan.h"
  58. X
  59. extern char *malloc();
  60. extern char *getenv();
  61. X
  62. extern int errno;
  63. extern char *sys_errlist[];
  64. X
  65. int applysearch(), searchdone();
  66. Panel_item srchlist;
  67. X
  68. extern char *re_comp();
  69. X
  70. static char re [MAXSEARCHLEN + 1];
  71. X
  72. notesearch(item, event)
  73. X    Panel_item item;
  74. X    Event *event;
  75. X    {
  76. X    struct LLM_root root;
  77. X    char *err;
  78. X    struct SubDir *sp;
  79. X    struct Note *np;
  80. X    struct Note **npp;
  81. X    int  count;
  82. X    char buf [MAXSEARCHLEN + 1];
  83. X    char tbuf [MAXSEARCHLEN + 1];
  84. X
  85. X    count = 0;
  86. X    LLM_init(&root, sizeof(struct Note *));
  87. X
  88. X    strcpy(buf, (char *) xv_get(item, PANEL_VALUE));
  89. X    trim(buf);
  90. X    if(strlen(buf) == 0)
  91. X        {
  92. X        notice_prompt(main_frame, NULL,
  93. X            NOTICE_MESSAGE_STRINGS,
  94. X                "No search string entered",
  95. X                NULL,
  96. X            NOTICE_BUTTON_YES, "Acknowledge",
  97. X            NOTICE_NO_BEEPING, noticenobeep,
  98. X            NULL);
  99. X        return;
  100. X        }
  101. X    if((err = re_comp(buf)) != NULL)
  102. X        {
  103. X        notice_prompt(main_frame, NULL,
  104. X            NOTICE_MESSAGE_STRINGS,
  105. X                "Invalid regular expression entered",
  106. X                err,
  107. X                NULL,
  108. X            NOTICE_BUTTON_YES, "Acknowledge",
  109. X            NOTICE_NO_BEEPING, noticenobeep,
  110. X            NULL);
  111. X        return;
  112. X        }
  113. X    strcpy(re, buf);
  114. X    sp = (struct SubDir *) LLM_first(&subdir_rt);
  115. X    while(sp != NULL)
  116. X        {
  117. X        np = (struct Note *) LLM_first(&sp->note_rt);
  118. X        while(np != NULL)
  119. X            {
  120. X            strcpy(tbuf, np->ntitle);
  121. X            if(strlen(tbuf) == 0) strcpy(tbuf, NOTITLE);
  122. X            if(re_exec(tbuf) == 1)
  123. X                {
  124. X                if(np->state != Visible)
  125. X                    {
  126. X                    if(!np->mapped)
  127. X                        {
  128. X                        npp = (struct Note **) LLM_add(&root);
  129. X                        if(npp == NULL)
  130. X                            {
  131. X                            notice_prompt(main_frame, NULL,
  132. X                                NOTICE_MESSAGE_STRINGS,
  133. X                                    "Memory allocation failure",
  134. X                                    sys_errlist[errno],
  135. X                                    NULL,
  136. X                                NOTICE_BUTTON_YES, "Acknowledge",
  137. X                                NOTICE_NO_BEEPING, noticenobeep,
  138. X                                NULL);
  139. X                            LLM_free(&root);
  140. X                            return;
  141. X                            }
  142. X                        count++;
  143. X                        *npp = np;
  144. X                        }
  145. X                    }
  146. X                }
  147. X            np = (struct Note *) LLM_next(&sp->note_rt);
  148. X            }
  149. X        sp = (struct SubDir *) LLM_next(&subdir_rt);
  150. X        }
  151. X    if(count == 0)
  152. X        {
  153. X        notice_prompt(main_frame, NULL,
  154. X            NOTICE_MESSAGE_STRINGS,
  155. X                "No hidden notes matching search string found",
  156. X                NULL,
  157. X            NOTICE_BUTTON_YES, "Acknowledge",
  158. X            NOTICE_NO_BEEPING, noticenobeep,
  159. X            NULL);
  160. X        return;
  161. X        }
  162. X    if(count == 1)
  163. X        {
  164. X        npp = (struct Note **) LLM_first(&root);
  165. X        np = *npp;
  166. X        buildnote(np);
  167. X        xv_set(np->title, PANEL_VALUE, np->ntitle, NULL);
  168. X        xv_set(np->frame, XV_LABEL, np->ntitle, NULL);
  169. X        reseticon(np);
  170. X        np->state = Visible;
  171. X        update(np);
  172. X        updateinfo(np, FORCE);
  173. X        }
  174. X    else
  175. X        {
  176. X        postsearch(&root);
  177. X        }
  178. X    LLM_free(&root);
  179. X    }
  180. X
  181. postsearch(root)
  182. X    struct LLM_root *root;
  183. X    {
  184. X    struct Note **npp;
  185. X    Display *dpy;
  186. X    Xv_Screen screen;
  187. X    int  screen_num;
  188. X    int  screen_height;
  189. X    int  screen_width;
  190. X    int  row;
  191. X    Rect rect;
  192. X    Panel search_panel;
  193. X
  194. X    dpy = (Display *) xv_get(main_frame, XV_DISPLAY);
  195. X    screen = (Xv_Screen) xv_get(main_frame, XV_SCREEN);
  196. X    screen_num = xv_get(screen, SCREEN_NUMBER);
  197. X    screen_height = DisplayHeight(dpy, screen_num);
  198. X    screen_width = DisplayWidth(dpy, screen_num);
  199. X    frame_get_rect(main_frame, &rect);
  200. X    rect.r_left += SEARCHSPACING;
  201. X    if((rect.r_left + SEARCHWIDTH) > (screen_width - SEARCHSPACING))
  202. X        rect.r_left = screen_width - SEARCHWIDTH - SEARCHSPACING;
  203. X    if((rect.r_top + rect.r_height + 2 * SEARCHSPACING + SEARCHHEIGHT) < 
  204. X       screen_height)
  205. X        rect.r_top += (rect.r_height + SEARCHSPACING);
  206. X    else
  207. X        rect.r_top -= (SEARCHHEIGHT + 2 * SEARCHSPACING);
  208. X    search_frame = xv_create(main_frame, FRAME_CMD,
  209. X                           XV_LABEL, "Matching Notes",
  210. X                           XV_X, rect.r_left,
  211. X                           XV_Y, rect.r_top,
  212. X                           XV_WIDTH, SEARCHWIDTH,
  213. X                           XV_HEIGHT, SEARCHHEIGHT,
  214. X                           FRAME_NO_CONFIRM, TRUE,
  215. X                           FRAME_DONE_PROC, searchdone,
  216. X                           NULL);
  217. X    if(search_frame == NULL)
  218. X        {
  219. X        notice_prompt(main_frame, NULL,
  220. X            NOTICE_MESSAGE_STRINGS,
  221. X                "Unable to create sub-frame (internal error)",
  222. X                NULL,
  223. X            NOTICE_BUTTON_YES, "Acknowledge",
  224. X            NOTICE_NO_BEEPING, noticenobeep,
  225. X            NULL);
  226. X        return;
  227. X        }
  228. X    xv_set(search_frame, XV_SHOW, TRUE, NULL);
  229. X
  230. X    search_panel = (Panel) xv_get(search_frame, FRAME_CMD_PANEL);
  231. X    xv_set(search_panel, WIN_RETAINED, FALSE, NULL);
  232. X
  233. X    (void) xv_create(search_panel, PANEL_MESSAGE,
  234. X        XV_X, xv_col(search_panel, 0),
  235. X        XV_Y, xv_row(search_panel, 0),
  236. X        PANEL_LABEL_STRING, "Matching Notes",
  237. X        NULL);
  238. X    srchlist = xv_create(search_panel, PANEL_LIST,
  239. X        XV_X, xv_col(search_panel, 0),
  240. X        XV_Y, xv_row(search_panel, 1),
  241. X        PANEL_LIST_DISPLAY_ROWS, 7,
  242. X        PANEL_LIST_WIDTH, xv_col(search_panel, 15),
  243. X        PANEL_CHOOSE_ONE, FALSE,
  244. X        NULL);
  245. X    row = 0;
  246. X    npp = (struct Note **) LLM_first(root);
  247. X    while(npp != NULL)
  248. X        {
  249. X        xv_set(srchlist,
  250. X            PANEL_LIST_INSERT, row,
  251. X            PANEL_LIST_STRING, row, (*npp)->ntitle, 
  252. X            PANEL_LIST_CLIENT_DATA, row, *npp, 
  253. X            NULL);
  254. X        npp = (struct Note **) LLM_next(root);
  255. X        row++;
  256. X        }
  257. X
  258. X
  259. X    (void) xv_create(search_panel, PANEL_BUTTON,
  260. X                 XV_X, SEARCHWIDTH / 2 - 30,
  261. X                 XV_Y, SEARCHHEIGHT - 30,
  262. X                 PANEL_LABEL_STRING, "Apply",
  263. X                 PANEL_NOTIFY_PROC, applysearch,
  264. X                 NULL);
  265. X
  266. X    window_fit_height(search_panel);
  267. X
  268. X    (void) xv_set(search_item, PANEL_INACTIVE, TRUE, NULL);
  269. X    search_up = 1;
  270. X    }
  271. X
  272. searchdone()
  273. X    {
  274. X    xv_destroy_safe(search_frame);
  275. X    (void) xv_set(search_item, PANEL_INACTIVE, FALSE, NULL);
  276. X    (void) xv_set(main_panel, PANEL_CARET_ITEM, search_item, NULL);
  277. X    search_up = 0;
  278. X    }
  279. X
  280. applysearch(item, event)
  281. X    Panel_item item;
  282. X    Event *event;
  283. X    {
  284. X    struct Note *np;
  285. X    int  i, row;
  286. X
  287. X    row = xv_get(srchlist, PANEL_LIST_NROWS);
  288. X    for(i = 0; i < row; i++)
  289. X        {
  290. X        if(xv_get(srchlist, PANEL_LIST_SELECTED, i))
  291. X            {
  292. X            np = (struct Note *) xv_get(srchlist, PANEL_LIST_CLIENT_DATA, i);
  293. X            buildnote(np);
  294. X            xv_set(np->title, PANEL_VALUE, np->ntitle, NULL);
  295. X            xv_set(np->frame, XV_LABEL, np->ntitle, NULL);
  296. X            reseticon(np);
  297. X            np->state = Visible;
  298. X            update(np);
  299. X            updateinfo(np, FORCE);
  300. X            }
  301. X        }
  302. X    if(xv_get(search_frame, FRAME_CMD_PUSHPIN_IN) == FALSE)
  303. X        {
  304. X        xv_destroy_safe(search_frame);
  305. X        (void) xv_set(search_item, PANEL_INACTIVE, FALSE, NULL);
  306. X        (void) xv_set(main_panel, PANEL_CARET_ITEM, search_item, NULL);
  307. X        search_up = 0;
  308. X        }
  309. X    refresh_popups();
  310. X    }
  311. X
  312. refresh_search()
  313. X    {
  314. X    struct SubDir *sp;
  315. X    struct Note *np;
  316. X    int  i;
  317. X    int  row;
  318. X    char tbuf [MAXSEARCHLEN + 1];
  319. X
  320. X    if(!search_up) return;
  321. X
  322. X    xv_set(srchlist, XV_SHOW, FALSE, NULL);
  323. X
  324. X    row = xv_get(srchlist, PANEL_LIST_NROWS);
  325. X    for(i = row - 1; i >= 0; i--)
  326. X        {
  327. X        xv_set(srchlist, PANEL_LIST_DELETE, i, NULL);
  328. X        }
  329. X
  330. X    row = 0;
  331. X    re_comp(re);
  332. X    sp = (struct SubDir *) LLM_first(&subdir_rt);
  333. X    while(sp != NULL)
  334. X        {
  335. X        np = (struct Note *) LLM_first(&sp->note_rt);
  336. X        while(np != NULL)
  337. X            {
  338. X            strcpy(tbuf, np->ntitle);
  339. X            if(strlen(tbuf) == 0) strcpy(tbuf, NOTITLE);
  340. X            if(re_exec(tbuf) == 1)
  341. X                {
  342. X                if(np->state != Visible)
  343. X                    {
  344. X                    if(!np->mapped)
  345. X                        {
  346. X                        xv_set(srchlist,
  347. X                            PANEL_LIST_INSERT, row,
  348. X                            PANEL_LIST_STRING, row, tbuf, 
  349. X                            PANEL_LIST_CLIENT_DATA, row, np, 
  350. X                            NULL);
  351. X                        row++;
  352. X                        }
  353. X                    }
  354. X                }
  355. X            np = (struct Note *) LLM_next(&sp->note_rt);
  356. X            }
  357. X        sp = (struct SubDir *) LLM_next(&subdir_rt);
  358. X        }
  359. X
  360. X    xv_set(srchlist, XV_SHOW, TRUE, NULL);
  361. X    }
  362. SHAR_EOF
  363. chmod 0644 search.c ||
  364. echo 'restore of search.c failed'
  365. Wc_c="`wc -c < 'search.c'`"
  366. test 9860 -eq "$Wc_c" ||
  367.     echo 'search.c: original size 9860, current size' "$Wc_c"
  368. fi
  369. # ============= update.c ==============
  370. if test -f 'update.c' -a X"$1" != X"-c"; then
  371.     echo 'x - skipping update.c (File already exists)'
  372. else
  373. echo 'x - extracting update.c (Text)'
  374. sed 's/^X//' << 'SHAR_EOF' > 'update.c' &&
  375. /*
  376. Post A Note V2.4
  377. Copyright (c) 1992, Jeffrey W. Bailey
  378. All rights reserved.
  379. X
  380. Permission is granted to distribute this program in exact, complete
  381. source form, which includes this copyright notice, as long as no fee
  382. other than media and distribution cost is charged.
  383. X
  384. This program may not be used in whole, or in part, in any other manner
  385. without prior written permission from the author.
  386. X
  387. This program may not be distributed in modified form without prior
  388. written permission from the author.  In other words, patches may be
  389. distributed, but modified source may not be distributed.
  390. X
  391. If there are any questions, comments or suggestions, the author may be
  392. contacted at:
  393. X
  394. X    jeff@rd1.interlan.com
  395. X
  396. X    or
  397. X
  398. X    Jeffrey Bailey
  399. X    Racal-Datacom, Inc.
  400. X    Mail Stop E-110
  401. X    1601 N. Harrison Parkway
  402. X    Sunrise, FL  33323-2899
  403. */
  404. X
  405. #include "pan.h"
  406. X
  407. extern char *malloc();
  408. extern char *getenv();
  409. X
  410. extern int errno;
  411. extern char *sys_errlist[];
  412. X
  413. /*
  414. X    Routine called when an update of the notes size and position and title
  415. X    is desired.  Only write to a file if changes have been made or the
  416. X    force flag is set.
  417. */
  418. updateinfo(np, force)
  419. X    struct Note *np;
  420. X    int  force;
  421. X    {
  422. X    int  closed;
  423. X    FILE *fp;
  424. X    Rect rect;
  425. X    char fname[MAXBUFLEN];
  426. X
  427. X    if(!np->mapped) return;
  428. X    closed = xv_get(np->frame, FRAME_CLOSED);
  429. X    if(!closed)
  430. X        {
  431. X        frame_get_rect(np->frame, &rect);
  432. X        if(force != FORCE)
  433. X            {
  434. X            if(np->rect.r_left == rect.r_left &&
  435. X               np->rect.r_top == rect.r_top &&
  436. X               np->rect.r_width == rect.r_width &&
  437. X               np->rect.r_height == rect.r_height)
  438. X                {
  439. X                return;
  440. X                }
  441. X            }
  442. X        memcpy(&np->rect, &rect, sizeof(rect));
  443. X        }
  444. X    makeinfoname(fname, np);
  445. X    fp = fopen(fname, "w");
  446. X    if(fp != NULL)
  447. X        {
  448. X        if(np->state == Hidden)
  449. X            fprintf(fp, "%d\t%d\t%d\t%d\tHIDDEN\n", np->rect.r_left,
  450. X                np->rect.r_top, np->rect.r_width, np->rect.r_height);
  451. X        else
  452. X            fprintf(fp, "%d\t%d\t%d\t%d\tVISIBLE\n", np->rect.r_left,
  453. X                np->rect.r_top, np->rect.r_width, np->rect.r_height);
  454. X        fprintf(fp, "%s\n", np->ntitle);
  455. X        fprintf(fp, "%d\n", np->crttime);
  456. X        fclose(fp);
  457. X        }
  458. X    else
  459. X        {
  460. X        notice_prompt(main_frame, NULL,
  461. X            NOTICE_MESSAGE_STRINGS,
  462. X                "Couldn't open note geometry file",
  463. X                fname,
  464. X                sys_errlist[errno],
  465. X                NULL,
  466. X            NOTICE_BUTTON_YES, "Acknowledge",
  467. X            NOTICE_NO_BEEPING, noticenobeep,
  468. X            NULL);
  469. X        }
  470. X    }
  471. X
  472. /*
  473. X    Called when a save of the note text is desired.  Only writes to the file
  474. X    if modifications have been made.
  475. */
  476. update(np)
  477. X    struct Note *np;
  478. X    {
  479. X    int  mod;
  480. X    char fname[MAXBUFLEN];
  481. X
  482. X    if(!np->mapped) return(0);
  483. X    mod = xv_get(np->textsw, TEXTSW_MODIFIED);
  484. X    if(mod)
  485. X        {
  486. X        xv_set(np->textsw, TEXTSW_CONFIRM_OVERWRITE, FALSE, NULL);
  487. X        makename(fname, np);
  488. X        textsw_store_file(np->textsw, fname, 0, 0);
  489. X        }
  490. X    return(mod);
  491. X    }
  492. X
  493. /*
  494. X    Make a note file name.
  495. */
  496. makename(fname, np)
  497. X    char *fname;
  498. X    struct Note *np;
  499. X    {
  500. X    struct SubDir *sp;
  501. X
  502. X    sp = np->sp;
  503. X    sprintf(fname, "%s/%s/%s", note_dir, sp->subdir, np->basename);
  504. X    }
  505. X
  506. /*
  507. X    Make a note information file name.
  508. */
  509. makeinfoname(fname, np)
  510. X    char *fname;
  511. X    struct Note *np;
  512. X    {
  513. X    struct SubDir *sp;
  514. X
  515. X    sp = np->sp;
  516. X    sprintf(fname, "%s/%s/%s.info", note_dir, sp->subdir, np->basename);
  517. X    }
  518. SHAR_EOF
  519. chmod 0644 update.c ||
  520. echo 'restore of update.c failed'
  521. Wc_c="`wc -c < 'update.c'`"
  522. test 3574 -eq "$Wc_c" ||
  523.     echo 'update.c: original size 3574, current size' "$Wc_c"
  524. fi
  525. # ============= win.c ==============
  526. if test -f 'win.c' -a X"$1" != X"-c"; then
  527.     echo 'x - skipping win.c (File already exists)'
  528. else
  529. echo 'x - extracting win.c (Text)'
  530. sed 's/^X//' << 'SHAR_EOF' > 'win.c' &&
  531. /*
  532. Post A Note V2.4
  533. Copyright (c) 1992, Jeffrey W. Bailey
  534. All rights reserved.
  535. X
  536. Permission is granted to distribute this program in exact, complete
  537. source form, which includes this copyright notice, as long as no fee
  538. other than media and distribution cost is charged.
  539. X
  540. This program may not be used in whole, or in part, in any other manner
  541. without prior written permission from the author.
  542. X
  543. This program may not be distributed in modified form without prior
  544. written permission from the author.  In other words, patches may be
  545. distributed, but modified source may not be distributed.
  546. X
  547. If there are any questions, comments or suggestions, the author may be
  548. contacted at:
  549. X
  550. X    jeff@rd1.interlan.com
  551. X
  552. X    or
  553. X
  554. X    Jeffrey Bailey
  555. X    Racal-Datacom, Inc.
  556. X    Mail Stop E-110
  557. X    1601 N. Harrison Parkway
  558. X    Sunrise, FL  33323-2899
  559. */
  560. X
  561. #include "pan.h"
  562. X
  563. extern char *malloc();
  564. extern char *getenv();
  565. X
  566. extern int errno;
  567. extern char *sys_errlist[];
  568. X
  569. get_win(np)
  570. X    struct Note *np;
  571. X    {
  572. X    struct FreeWin *fp;
  573. X
  574. X    fp = (struct FreeWin *)LLM_first(&freewin_rt);
  575. X    if(fp == NULL) return(0);
  576. X    np->frame = fp->frame;
  577. X    np->panel = fp->panel;
  578. X    np->textsw = fp->textsw;
  579. X    np->title = fp->title;
  580. X    np->hide = fp->hide;
  581. X    np->destroy = fp->destroy;
  582. X    np->cdate = fp->cdate;
  583. X    np->ctime = fp->ctime;
  584. X    np->icon = fp->icon;
  585. X    LLM_delete(&freewin_rt, fp);
  586. X    return(1);
  587. X    }
  588. X
  589. put_win(np)
  590. X    struct Note *np;
  591. X    {
  592. X    struct FreeWin *fp;
  593. X
  594. X    fp = (struct FreeWin *)LLM_add(&freewin_rt);
  595. X    if(fp == NULL)
  596. X        {
  597. X        fprintf(stderr, "Internal memory allocation error\n");
  598. X        exit(1);
  599. X        }
  600. X    fp->frame = np->frame;
  601. X    fp->panel = np->panel;
  602. X    fp->textsw = np->textsw;
  603. X    fp->title = np->title;
  604. X    fp->hide = np->hide;
  605. X    fp->destroy = np->destroy;
  606. X    fp->cdate = np->cdate;
  607. X    fp->ctime = np->ctime;
  608. X    fp->icon = np->icon;
  609. X    xv_set(fp->frame, XV_SHOW, FALSE, NULL);
  610. X    xv_set(fp->title, PANEL_VALUE, "", NULL);
  611. X    }
  612. SHAR_EOF
  613. chmod 0644 win.c ||
  614. echo 'restore of win.c failed'
  615. Wc_c="`wc -c < 'win.c'`"
  616. test 1960 -eq "$Wc_c" ||
  617.     echo 'win.c: original size 1960, current size' "$Wc_c"
  618. fi
  619. exit 0
  620. -- 
  621. --
  622. Molecular Simulations, Inc.            mail: dcmartin@msi.com
  623. 796 N. Pastoria Avenue                uucp: uunet!dcmartin
  624. Sunnyvale, California 94086            at&t: 408/522-9236
  625.