home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xmail / part07 < prev    next >
Encoding:
Text File  |  1993-04-27  |  57.8 KB  |  1,669 lines

  1. Newsgroups: comp.sources.x
  2. From: markham@cadence.com (Jeff Markham)
  3. Subject: v19i032:  xmail - X Window System interface to the mail program, Part07/10
  4. Message-ID: <1993Mar10.202949.11121@sparky.imd.sterling.com>
  5. X-Md4-Signature: 1ff1f8f228112041ef0665c267ad0612
  6. Date: Wed, 10 Mar 1993 20:29:49 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: markham@cadence.com (Jeff Markham)
  10. Posting-number: Volume 19, Issue 32
  11. Archive-name: xmail/part07
  12. Environment: X11
  13. Supersedes: xmail: Volume 15, Issue 18-26
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # Contents:  HelpText.c directory.c mail.c utils.c
  20. # Wrapped by chris@sparky on Wed Mar 10 14:17:49 1993
  21. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 7 (of 10)."'
  24. if test -f 'HelpText.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'HelpText.c'\"
  26. else
  27.   echo shar: Extracting \"'HelpText.c'\" \(18289 characters\)
  28.   sed "s/^X//" >'HelpText.c' <<'END_OF_FILE'
  29. X/*
  30. X * xmail - X window system interface to the mail program
  31. X *
  32. X * Copyright 1990,1991,1992 by National Semiconductor Corporation
  33. X *
  34. X * Permission to use, copy, modify, and distribute this software and its
  35. X * documentation for any purpose is hereby granted without fee, provided that
  36. X * the above copyright notice appear in all copies and that both that
  37. X * copyright notice and this permission notice appear in supporting
  38. X * documentation, and that the name of National Semiconductor Corporation not
  39. X * be used in advertising or publicity pertaining to distribution of the
  40. X * software without specific, written prior permission.
  41. X *
  42. X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
  43. X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS"
  44. X * WITHOUT EXPRESS OR IMPLIED WARRANTY.  NATIONAL SEMICONDUCTOR CORPORATION
  45. X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  46. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  47. X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
  48. X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  49. X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  50. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  51. X * PERFORMANCE OF THIS SOFTWARE.
  52. X *
  53. X * Author:  Michael C. Wagnitz - National Semiconductor Corporation
  54. X *
  55. X */
  56. X
  57. X#include    "global.h"
  58. X
  59. X
  60. XString    Autograph_Info[] = {
  61. X        "Append your 'Sign'ature (if any) to the message text",
  62. X        "Append your 'sign'ature (if any) to the message text",
  63. X        NULL
  64. X        };
  65. X
  66. XString    Copy_Info[] = {
  67. X                "Copy the selected message to the specified folder",
  68. X                "Copy the message to a folder named for it's author",
  69. X                NULL
  70. X                };
  71. X
  72. XString    Default_Status_Info = "Press <Middle-Mouse-Button> for help on any window";
  73. X
  74. XString    Delete_Info[] = {
  75. X                "Delete the currently selected message",
  76. X                "Undelete the selected or most recently deleted message",
  77. X                NULL
  78. X                };
  79. X
  80. XString    Deliver_Info[] = {
  81. X        "Deliver this message",
  82. X        "Re-edit this message",
  83. X        "Cancel the request but save the text in the dead letter file",
  84. X        "Abort this request and discard the text",
  85. X        NULL
  86. X        };
  87. X
  88. XString    Folder_Info[] = {
  89. X        "Access the specified folder, or select from the list",
  90. X        "Copy this folder name to the fileWindow",
  91. X        "Copy the folder path to the fileWindow or view the next level",
  92. X        NULL
  93. X        };
  94. X
  95. XString    Hold_Info[] = {
  96. X                "Preserve the selected message in the system folder",
  97. X                NULL
  98. X                };
  99. X
  100. XString    NewMail_Info[] = {
  101. X                "Re-read your system mail folder",
  102. X                "Incorporate new mail without committing any current changes",
  103. X                "Make xmail refresh the folder list next time it's displayed",
  104. X                NULL
  105. X                };
  106. X
  107. XString    Print_Info[] = {
  108. X                "Print the selected message on the system printer",
  109. X                NULL
  110. X                };
  111. X
  112. XString    Quit_Info[] = {
  113. X                "Quit xmail",
  114. X                "Leave xmail without committing any current changes",
  115. X                NULL
  116. X                };
  117. X
  118. XString    Read_Info[] = {
  119. X                "Read the next message",
  120. X                "Read the previous message",
  121. X                "Read the current message",
  122. X                "Read the current message, and include full mail headers",
  123. X                NULL
  124. X                };
  125. X
  126. XString    Reply_Info[] = {
  127. X                "Reply to the author of the message",
  128. X                "Reply to the author of, and include the message text",
  129. X                "Include all recipients of the original message in your reply",
  130. X                "Include all recipients, and the text, of this message",
  131. X                NULL
  132. X                };
  133. X
  134. XString    Save_Info[] = {
  135. X                "Save the selected message in the specified folder",
  136. X                "Save the message in a folder named for it's author",
  137. X                "Write the message to the folder, but don't include headers",
  138. X                NULL
  139. X                };
  140. X
  141. XString    Send_Info[] = {
  142. X                "Compose and send a new mail message",
  143. X                "Forward a copy of the selected mail message",
  144. X                NULL
  145. X                };
  146. X
  147. XString    SendMail_Info[] = {
  148. X        "Specify the name(s) of the recipient(s) (<Shift><Button2> for help)",
  149. X        "Enter the subject of this message (<Shift><Button2> for help)",
  150. X        "Specify the names of any carbon copy recipients (<Shift><Button2> for help)",
  151. X        "Enter the names of any blind carbon copy recipients (<Shift><Button2> for help)",
  152. X        NULL
  153. X        };
  154. X
  155. XString Abort_Help = "\n\n\n\n\n\n\
  156. X Pressing the \"Abort\" button cancels delivery of the\n\
  157. X message, and deletes any text that may have been created.";
  158. X
  159. XString    Bcc_Help = "\n\
  160. X Specify any blind carbon copy recipients for this message\n\
  161. X using the Bcc: window.  Blind carbon recipient names are\n\
  162. X removed from the message prior to delivery.\n\n\
  163. X Pressing the right mouse button in this window displays\n\
  164. X a list of your aliases.  Releasing the right mouse\n\
  165. X button while one of the alias names is highlighted\n\
  166. X copies that name into the window, preceding it with a\n\
  167. X comma if necessary.\n\n\
  168. X Standard editing functions associated with the text widget\n\
  169. X are supported, and can be altered using the application\n\
  170. X resources.";
  171. X
  172. XString Cancel_Help = "\n\n\n\n\n\
  173. X Pressing the \"Cancel\" button causes delivery of this\n\
  174. X message to be abandoned, but saves a copy of the message\n\
  175. X text in your dead letter file (default $HOME/dead.letter)\n\
  176. X without any header information.";
  177. X
  178. XString    Cc_Help = "\n\n\
  179. X Specify carbon copy recipients for this message using the\n\
  180. X Cc: window.  Multiple recipients should be comma separated.\n\n\
  181. X Pressing the right mouse button in this window displays a\n\
  182. X list of your aliases.  Releasing the right mouse button\n\
  183. X while one of the alias names is highlighted copies that\n\
  184. X name into this window, preceded with a comma if needed.\n\n\
  185. X Standard editing functions associated with the text widget\n\
  186. X are supported, and can be altered using the application\n\
  187. X resources.";
  188. X
  189. XString    Copy_Help = "\n\
  190. X Pressing this button copies the current message to the\n\
  191. X file or folder named in the File: window, without marking\n\
  192. X the original for removal.  (If a folder name is not\n\
  193. X specified, it will be copied to your mbox folder.)\n\n\
  194. X The right mouse button pops up a menu for both the copy\n\
  195. X and Copy commands.\n\n\
  196. X The uppercase (Copy) command copies the message to a file\n\
  197. X whose name is derived from the author of the message,\n\
  198. X rather than from any name currently in the File: window.\n\n\
  199. X See also the save command help for additional information.";
  200. X
  201. XString    Delete_Help = "\
  202. X Pressing this button removes the selected message from the\n\
  203. X current folder.\n\n\
  204. X The right mouse button displays a menu for both the delete\n\
  205. X and undelete commands.\n\n\
  206. X Undelete restores the selected message (if it has been\n\
  207. X marked 'D'eleted), otherwise the deleted message with the\n\
  208. X smallest message number is restored.\n\n\
  209. X Undelete may be used repeatedly to restore all deleted\n\
  210. X messages if changes have not yet been committed.\n\n\
  211. X See also preserve, save, folder, Newmail, and quit.";
  212. X
  213. XString    Deliver_Help = "\n\n\n\n\n\
  214. X The Deliver button will send the composed message text\n\
  215. X to your sendmail daemon for delivery to the specified\n\
  216. X recipient(s).";
  217. X
  218. XString    File_Help = "\n\
  219. X The File: window provides a mechanism for specifying a\n\
  220. X file or folder name for use by other xmail commands.\n\n\
  221. X Text entered beyond the right margin of the window will\n\
  222. X cause a horizontal scrollbar to appear, for scrolling the\n\
  223. X displayed text to the left or right as needed for viewing.\n\n\
  224. X Pressing the backspace or delete key erases a previously\n\
  225. X entered character.  Control_W (^W) erases a previous word\n\
  226. X and Control_U (^U) the entire line.\n\n\
  227. X See the folder and save commands for more information.";
  228. X
  229. XString    Folder_Help = "\
  230. X The left button changes the active folder to the one\n\
  231. X specified in the File: window.  Changing folders COMMITs\n\
  232. X any modifications to the current folder.\n\n\
  233. X The right button displays a menu of folders from which to\n\
  234. X choose.  Clicking the left button on a directory (indicated\n\
  235. X by trailing slash) while still holding down the right,\n\
  236. X expands that directory if it contains files.  Folders with\n\
  237. X unread messages will be highlighted by a hatch pattern.\n\
  238. X Releasing the right button copies the selected name to the\n\
  239. X File: window.\n\n\
  240. X The current menu can be erased (to include new folders\n\
  241. X created since the menu was last generated) by using the\n\
  242. X Drop option provided with the Newmail command button menu.";
  243. X
  244. XString    Hold_Help = "\n\
  245. X The Preserve command marks the selected message for\n\
  246. X retention in the system mailbox.  Normally when a message\n\
  247. X is 'saved' to some other folder file, it is automatically\n\
  248. X deleted from your system folder.  'Preserve' causes mail\n\
  249. X to not remove the original from your system mail folder.\n\n\
  250. X Pressing the right mouse button on the Preserve command\n\
  251. X presents a menu of four mail (and one xmail) variables\n\
  252. X that may be toggled while currently operating in xmail.\n\n\
  253. X Commands listed denote what state each variable will be\n\
  254. X changed to, if the appropriate label is highlighted when\n\
  255. X the right mouse button is released.";
  256. X
  257. XString    Index_Help = "\n\
  258. X The index window displays a list of mail messages in the\n\
  259. X current folder, as well as the currently selected message.\n\n\
  260. X Pressing the left mouse button anywhere on a line marks\n\
  261. X the message as selected (for other commands) but does not\n\
  262. X automatically display the message in the text window.\n\n\
  263. X Pressing the right button selects and also automatically\n\
  264. X displays the message.\n\
  265. X See also the next command help for additional information.\n\n\
  266. X The index window header list may be scrolled using either\n\
  267. X the scrollbar and mouse or keyboard keys.  See the Text\n\
  268. X window help for a description of the keys supported.";
  269. X
  270. XString    NewMail_Help = "\
  271. X The Newmail button will be highlighted with a hatching\n\
  272. X pattern whenever new mail has arrived for your account.\n\n\
  273. X Pressing the NewMail button accesses your system folder\n\
  274. X (if mail exists) and includes any new mail delivered\n\
  275. X since the last time your system folder was accessed.\n\
  276. X This action also resets any button highlighting, and\n\
  277. X COMMITS any changes that may have been made to the\n\
  278. X current folder.  (Confirmation provided if not expert.)\n\n\
  279. X The right mouse button provides a menu for committing\n\
  280. X changes, incorporating new messages without committing\n\
  281. X changes (only if currently in your system folder), or\n\
  282. X causing xmail to redetermine the list of mail folders.";
  283. X
  284. XString    Print_Help = "\n\n\n\
  285. X Pressing this button causes the selected message to be\n\
  286. X printed on the system printer.\n\n\
  287. X A message will be displayed in the status window\n\
  288. X indicating which message was printed, along with its\n\
  289. X size in bytes.\n\n\
  290. X See also the Index window for help on selecting a message.";
  291. X
  292. XString    Quit_Help = "\n\n\
  293. X quit - terminates xmail, committing changes made to the\n\
  294. X current folder.\n\n\
  295. X The right mouse button pops up a menu for the quit and\n\
  296. X exit commands.\n\n\
  297. X Use exit when you wish to leave xmail without committing\n\
  298. X the current folder's changes.\n\n\
  299. X See also the folder, Newmail, and delete commands.";
  300. X
  301. XString    Read_Help = "\n\
  302. X Pressing this button causes the next message in the list\n\
  303. X to be displayed in the text (bottom) window.\n\n\
  304. X Current message selection is indicated by caret (>) in\n\
  305. X the index (top) window.\n\n\
  306. X The right mouse button displays a menu for reading the\n\
  307. X next message, reading the previous or current message,\n\
  308. X or reading the current message with full headers (this\n\
  309. X overrides any suppression of normally ignored fields).\n\n\
  310. X See also the Index window help for more information.";
  311. X
  312. XString ReEdit_Help = "\n\n\n\n\n\
  313. X Use the ReEdit selection to perform additional changes\n\
  314. X to the current message composition.  When completed, you\n\
  315. X will again be presented with the send completion menu.";
  316. X
  317. XString    Reply_Help = "\n\n\
  318. X reply - initiates the mechanism to create and send a mail\n\
  319. X message to the author of a current message.\n\n\
  320. X The right mouse button displays a menu for selecting\n\
  321. X 'reply', 'reply included', 'replyall' (which addresses all\n\
  322. X recipients of the original mail), or 'replyall included'.\n\
  323. X The include options automatically copy the original\n\
  324. X message into the new one.\n\nSee also the Send command.";
  325. X
  326. XString    Save_Help = "\n\
  327. X save - copies a message to the file or folder named in\n\
  328. X the File: window, marking the original for deletion.\n\
  329. X If none is specified, the name in your environment MBOX\n\
  330. X is used ($HOME/mbox by default).\n\n\
  331. X The right button pops up a menu of related commands.\n\n\
  332. X A written (vs. copied) message does not include mail\n\
  333. X headers or trailing blank line.\n\n\
  334. X Uppercase commands create a file named from the author of\n\
  335. X the message, rather than any name in the File: window.";
  336. X
  337. XString    Send_Help = "\n\
  338. X send - initiates the mechanism to create and send a\n\
  339. X message to the designated recipient(s).  The right mouse\n\
  340. X button displays a menu which provides the choice of\n\
  341. X 'send'ing, or 'forwarding a message'.  Forwarding includes\n\
  342. X the text of the current message in the new one.\n\n\
  343. X As with the 'reply' command, a dialog box is provided to\n\
  344. X specify the name of the recipient(s), subject, and to whom\n\
  345. X to send copies of this message.  Pressing the 'Deliver'\n\
  346. X button completes the operation.\n\n\
  347. X See also the reply command help for additional information.";
  348. X
  349. XString    Sign_Help = "\n\n\n\
  350. X Pressing this Autograph button will append your .mailrc\n\
  351. X defined 'Sign'ature (uppercase 'S') text to the current\n\
  352. X message composition, replacing any backslash-'n' character\n\
  353. X combinations (\\n) found in it with true newline characters.\n\
  354. X (See the Mail(1) man page for details on defining a Sign.)\n\n\
  355. X If your .mailrc does not contain a Sign definition, xmail\n\
  356. X will look for a .Signature file in your home directory,\n\
  357. X appending its contents, if any, to the current composition.";
  358. X
  359. XString    sign_Help = "\n\n\n\
  360. X Pressing this autograph button will append your .mailrc\n\
  361. X defined 'sign'ature (lowercase 's') text to the current\n\
  362. X message composition, replacing any backslash-'n' character\n\
  363. X combinations (\\n) found in it with true newline characters.\n\
  364. X (See the Mail(1) man page for details on defining a sign.)\n\n\
  365. X If your .mailrc does not contain a sign definition, xmail\n\
  366. X will look for a .signature file in your home directory,\n\
  367. X appending its contents, if any, to the current composition.";
  368. X
  369. XString    Status_Help = "\n\n\n\
  370. X The Status window displays xmail program info, status, and\n\
  371. X error messages.\n\n\
  372. X Error messages usually cause the terminal bell to ring, to\n\
  373. X attract the user's attention.\n\n\
  374. X The BELL can be disabled, by either including the command\n\
  375. X line option -nb, or by specifying the '*bellRing' resource\n\
  376. X as False.";
  377. X
  378. XString    Subject_Help = "\n\n\
  379. X The Subject: window provides a method for specifying the\n\
  380. X subject for this mail message.\n\n\
  381. X Text entered beyond the right margin of the window will\n\
  382. X cause a horizontal scrollbar to appear, for scrolling the\n\
  383. X displayed text to the left or right as needed for viewing.\n\n\
  384. X Pressing the backspace or delete key erases a previously\n\
  385. X entered character, while Control_W (^W) erases a previous\n\
  386. X word and Control_U (^U) to the beginning of the line.";
  387. X
  388. XString    Text_Help = "\n\
  389. X The text window displays the currently selected message.\n\
  390. X See the Index window help on how to select a message.\n\n\
  391. X Text and index windows may be scrolled using either the\n\
  392. X mouse and scrollbar, or the keyboard keys in the manner\n\
  393. X of text display programs such as \"more\" and \"less\".\n\n\
  394. X spacebar - scroll down a page      b - scroll up a page\n\
  395. X return   - scroll down a line      k - scroll up a line\n\
  396. X   G      - go to end of text       ' - go to top of text\n\n\
  397. X The both windows also support keyboard access to each of\n\
  398. X the command buttons.  See the xmail man page for details\n\
  399. X or press the question mark key (?) within the text window.";
  400. X
  401. XString    Text2_Help = "\n\
  402. XKeyboard key defaults that duplicate command button actions:\n\n\
  403. X a - REPLY to ALL recipients    A  - REPLY to ALL INCLUDED\n\
  404. X c - COPY a message             C  - COPY to AUTHOR file\n\
  405. X d - DELETE the message         u  - UNDELETE a message\n\
  406. X f - READ with FULL headers     F  - FORWARD a message\n\
  407. X m - MAIL a message             M  - REPLY to a message\n\
  408. X i - Incorporate NEW MAIL       N  - retrieve NEW MAIL\n\
  409. X p - read PREVIOUS message      P  - PRINT a message\n\
  410. X r - READ the current message   R  - REPLY included\n\
  411. X s - SAVE current message       S  - SAVE to AUTHOR\n\
  412. X n - read the NEXT message      w  - WRITE current message\n\
  413. X q - QUIT, committing changes   x  - EXIT, no commits\n\
  414. X ? - DISPLAY this help info   <LF> - REMOVE this help info";
  415. X
  416. XString    Title_Help = "\n\n\n\n\
  417. XThe Titlebar window displays the xmail program name and the\n\
  418. Xcurrent version number, along with the name of the current\n\
  419. Xmail folder being accessed, and its message count(s).\n\n\
  420. XPressing the left mouse button on the National Semiconductor\n\
  421. XCorporation logo in the top left corner of the title bar\n\
  422. Xissues an XLib request to iconify this xmail application.";
  423. X
  424. XString    To_Help = "\n\
  425. X Use the To: window to specify the recipients for this mail\n\
  426. X message.  Text entered beyond the right margin of the\n\
  427. X window will cause a horizontal scrollbar to appear, for\n\
  428. X scrolling the displayed text left or right as desired for\n\
  429. X viewing.  Pressing the backspace or delete key erases the\n\
  430. X previously entered character, while Control_W (^W) erases\n\
  431. X a previous word and Control_U (^U) to the start of a line.\n\n\
  432. X Pressing the right mouse button in this window displays a\n\
  433. X list of your alias names.  Releasing the right mouse\n\
  434. X button while one of the names is highlighted will copy\n\
  435. X that name into the window, prepending it with a comma if\n\
  436. X needed.";
  437. X
  438. X/* HelpText */
  439. END_OF_FILE
  440.   if test 18289 -ne `wc -c <'HelpText.c'`; then
  441.     echo shar: \"'HelpText.c'\" unpacked with wrong size!
  442.   fi
  443.   # end of 'HelpText.c'
  444. fi
  445. if test -f 'directory.c' -a "${1}" != "-c" ; then 
  446.   echo shar: Will not clobber existing file \"'directory.c'\"
  447. else
  448.   echo shar: Extracting \"'directory.c'\" \(8030 characters\)
  449.   sed "s/^X//" >'directory.c' <<'END_OF_FILE'
  450. X/*
  451. X * xmail - X window system interface to the mail program
  452. X *
  453. X * Copyright 1990,1991,1992 by National Semiconductor Corporation
  454. X *
  455. X * Permission to use, copy, modify, and distribute this software and its
  456. X * documentation for any purpose is hereby granted without fee, provided that
  457. X * the above copyright notice appear in all copies and that both that
  458. X * copyright notice and this permission notice appear in supporting
  459. X * documentation, and that the name of National Semiconductor Corporation not
  460. X * be used in advertising or publicity pertaining to distribution of the
  461. X * software without specific, written prior permission.
  462. X *
  463. X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
  464. X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS"
  465. X * WITHOUT EXPRESS OR IMPLIED WARRANTY.  NATIONAL SEMICONDUCTOR CORPORATION
  466. X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  467. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  468. X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
  469. X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  470. X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  471. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  472. X * PERFORMANCE OF THIS SOFTWARE.
  473. X *
  474. X * Author:  Michael C. Wagnitz - National Semiconductor Corporation
  475. X *
  476. X */
  477. X
  478. X#include "global.h"
  479. X#include <sys/stat.h>
  480. X
  481. X#ifndef    S_ISDIR
  482. X#define    S_ISDIR(m)    (((m)&S_IFMT) == S_IFDIR)
  483. X#endif
  484. X
  485. X#ifdef USE_DIRENT
  486. X#include <dirent.h>
  487. X#else
  488. X#include <sys/dir.h>
  489. X#endif
  490. X
  491. X
  492. X/*
  493. X** @(#)SetDirectory() - Create popup list of directory folder names
  494. X*/
  495. X/* ARGSUSED */
  496. XXtActionProc
  497. XSetDirectory(w, event, params, num_params)
  498. XWidget        w;
  499. XXEvent        *event;
  500. XString        *params;
  501. XCardinal    *num_params;
  502. X{
  503. X int        depth, label_width, n, total, x;
  504. X char        buf[BUFSIZ], tmp[BUFSIZ], trans[BUFSIZ];
  505. X String        ep, name, path, s, List, *ftbl;
  506. X Widget        menu, layout, bw, above, to_left;
  507. X Arg        args[8];
  508. X DIR        *dirp;
  509. X struct    stat    st_buf;
  510. X#ifdef USE_DIRENT
  511. X struct dirent    *dp;
  512. X#else
  513. X struct direct    *dp;
  514. X#endif
  515. X
  516. X static String    dir_Trans = "<Btn1Down>: SetDirectory(%s, %s, %d)";
  517. X static String    m_Trans   = "<Leave>: MenuPopdown(%s)";
  518. X static String    b_Trans   = "<Enter>: set()\n<Leave>: unset()\n<Btn3Up>: MyNotify(%d) MenuPopdown(%s)";
  519. X
  520. X static XtCallbackRec callbacks[] = {
  521. X        { (XtCallbackProc) GetFolderName, NULL },
  522. X        { NULL,          NULL }
  523. X       };
  524. X
  525. X
  526. X name = params[0];
  527. X path = params[1];
  528. X (void) sscanf(params[2], "%d", &depth);
  529. X
  530. X depth      += 1;
  531. X label_width = 0;
  532. X
  533. X     /*
  534. X     ** To avoid problems later on with XtNameToWidget, don't create a
  535. X     ** menu if the name contains either a dot (.) or an asterisk (*).
  536. X     */
  537. X for (s = name; *s; s++)
  538. X     if (strchr(".*", *s) != NULL) break;
  539. X
  540. X menu = XtNameToWidget(w, name);
  541. X if (*s == NULL && menu == NULL) {    /* no dot or asterisk and no menu yet */
  542. X    SetCursor(WATCH);
  543. X    (void) sprintf(trans, m_Trans, name);
  544. X    XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(trans));
  545. X    menu = XtCreatePopupShell(name, overrideShellWidgetClass, w, args, ONE);
  546. X
  547. X    XtSetArg(args[0], XtNdefaultDistance, 1);
  548. X    layout = XtCreateManagedWidget("menu", formWidgetClass, menu, args, ONE);
  549. X    /*
  550. X    ** Copy folder names into a list
  551. X    */
  552. X    n = BUFSIZ;                    /* start with a BUFSIZ block */
  553. X    List = (String) XtMalloc((unsigned) n);
  554. X    List[0] = '\0';
  555. X
  556. X    if ((dirp = opendir(path)) == NULL)
  557. X       XtError("xmail cannot access directory name passed to SetDirectory()");
  558. X
  559. X    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
  560. X        if (dp->d_name[0] != '.') {        /* skip parent and dot files */
  561. X           if (strlen(List) + strlen(dp->d_name) + 2 >= n) {
  562. X              n += BUFSIZ;
  563. X              List = (String) XtRealloc(List, (unsigned) n);
  564. X             }
  565. X           if (List[0]) (void) strcat(List, " ");
  566. X           (void) strcat(List, dp->d_name);
  567. X          }
  568. X    (void) closedir(dirp);
  569. X
  570. X    List = (String) XtRealloc(List, (unsigned) strlen(List) + 2);
  571. X
  572. X    if (List[0]) {            /* if directory isn't empty... */
  573. X       /*
  574. X       ** Store pointers to folder names in a table array for sorting
  575. X       */
  576. X       for (total=1, s=List; *s; s++)    /* count number of names in the List */
  577. X           if (*s == ' ') total++;    /* (increase the folder name count) */
  578. X       ftbl = (String *) XtMalloc((unsigned) (total + 2) * sizeof(String *));
  579. X       x = n = 0;
  580. X       ep = &List[strlen(List)];    /* Find the end of this array */
  581. X       for (s = List; s < ep; s++) {    /* stuff word pointers into a table */
  582. X           while ((s+n < ep) && *(s+n) != ' ') n++;
  583. X           if (s+n < ep) *(s+n) = '\0';    /* mark off the end of this name */
  584. X           ftbl[x++] = s;        /* save this pointer in our table */
  585. X           s += n;            /* find start of next folder name */
  586. X           n  = 0;
  587. X          }
  588. X       ftbl[x] = NULL;            /* NULL terminate our table */
  589. X       /*
  590. X       ** (quick) sort our table into ascending alphabetical order
  591. X       */
  592. X       if (total > 1)
  593. X       qsort((char *)ftbl, total, sizeof(char *), str_compare);
  594. X       /*
  595. X       ** Then, determine label width by finding longest entry in our table
  596. X       */
  597. X       for (x = n = 0; n < total && ftbl[n]; n++)
  598. X           if (strlen(ftbl[n]) > strlen(ftbl[x])) x = n;
  599. X
  600. X       label_width = XTextWidth(XMail.buttonFont, ftbl[x], strlen(ftbl[x]));
  601. X      }
  602. X
  603. X    if (label_width) {
  604. X       (void) sprintf(trans, b_Trans, depth, name);
  605. X
  606. X       XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(trans));
  607. X       XtSetArg(args[1], XtNwidth, label_width + 12);
  608. X       XtSetArg(args[2], XtNfont, XMail.buttonFont);
  609. X       XtSetArg(args[3], XtNcallback, callbacks);
  610. X/*
  611. X** create the menu buttons
  612. X*/
  613. X       bw = above = to_left = NULL;
  614. X       for (x = 0; x < total; x++) {
  615. X           (void) sprintf(buf, "%s/%s", path, ftbl[x]);
  616. X           (void) strncpy(tmp, ftbl[x], BUFSIZ);
  617. X/*
  618. X           ** If this folder is also a directory, add a trailing slash '/'
  619. X*/
  620. X           if (stat(buf, &st_buf) == 0)        /* IF exists and is readable */
  621. X          if (S_ISDIR(st_buf.st_mode) && LASTCH(tmp) != '/')
  622. X                 (void) strcat(tmp, "/");    /* If a directory mark it so */
  623. X
  624. X           XtSetArg(args[4], XtNlabel, tmp);
  625. X           XtSetArg(args[5], XtNfromHoriz, to_left);
  626. X           if (! to_left)            /* (else keep current value) */
  627. X              XtSetArg(args[6], XtNfromVert, above);
  628. X
  629. X           bw = XtCreateManagedWidget("menubutton",commandWidgetClass,layout,args,7);
  630. X
  631. X           if (to_left == NULL) above = bw;
  632. X           if ((x+1) % 3 == 0)            /* make box three items wide */
  633. X              to_left = NULL;
  634. X           else to_left = bw;
  635. X
  636. X           if (LASTCH(tmp) != '/')
  637. X              AddInfoHandler(bw, Folder_Info[1]);
  638. X           else {
  639. X/*
  640. X              ** This is a directory.  Add a button popup menu for its files.
  641. X*/
  642. X              (void) sprintf(trans, dir_Trans, tmp, buf, depth);
  643. X              XtOverrideTranslations(bw, XtParseTranslationTable(trans));
  644. X              AddInfoHandler(bw, Folder_Info[2]);
  645. X             }
  646. X          } /* end - for each name in the folder table */
  647. X      } /* end - if there exists at least one folder name */
  648. X/*
  649. X** If no buttons were created for this menu, destroy the widget.
  650. X*/
  651. X    if (! label_width)
  652. X       XtDestroyWidget(menu);
  653. X    SetCursor(NORMAL);
  654. X    XtFree((String) ftbl);
  655. X    XtFree((String) List);
  656. X   } /* end - if menu had not yet been created */
  657. X/*
  658. X** If menu exists, pop it up, after setting x,y coordinates
  659. X*/
  660. X menu = XtNameToWidget(w, name);
  661. X
  662. X if (! menu || menu->core.being_destroyed)
  663. X    XBell(XtDisplay(toplevel), 33);
  664. X else {
  665. X    SetPopup(w, event, params, num_params);
  666. X    /*
  667. X    ** Mark folders with new messages by changing the background Pixmap
  668. X    */
  669. X    SetNewness(XtNameToWidget(menu, "*menu"), path);
  670. X
  671. X    XtSetArg(args[0], XtNy, NULL);
  672. X    XtGetValues(menu, args, ONE);
  673. X
  674. X    args[0].value -= XMail.menuY;    /* don't offset menu below cursor */
  675. X    XtSetValues(menu, args, ONE);
  676. X
  677. X    XtPopup(menu, XtGrabNone);
  678. X   }
  679. X} /* SetDirectory */
  680. END_OF_FILE
  681.   if test 8030 -ne `wc -c <'directory.c'`; then
  682.     echo shar: \"'directory.c'\" unpacked with wrong size!
  683.   fi
  684.   # end of 'directory.c'
  685. fi
  686. if test -f 'mail.c' -a "${1}" != "-c" ; then 
  687.   echo shar: Will not clobber existing file \"'mail.c'\"
  688. else
  689.   echo shar: Extracting \"'mail.c'\" \(14182 characters\)
  690.   sed "s/^X//" >'mail.c' <<'END_OF_FILE'
  691. X/*
  692. X * xmail - X window system interface to the mail program
  693. X *
  694. X * Copyright 1990,1991,1992 by National Semiconductor Corporation
  695. X *
  696. X * Permission to use, copy, modify, and distribute this software and its
  697. X * documentation for any purpose is hereby granted without fee, provided that
  698. X * the above copyright notice appear in all copies and that both that
  699. X * copyright notice and this permission notice appear in supporting
  700. X * documentation, and that the name of National Semiconductor Corporation not
  701. X * be used in advertising or publicity pertaining to distribution of the
  702. X * software without specific, written prior permission.
  703. X *
  704. X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
  705. X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS"
  706. X * WITHOUT EXPRESS OR IMPLIED WARRANTY.  NATIONAL SEMICONDUCTOR CORPORATION
  707. X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  708. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  709. X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
  710. X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  711. X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  712. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  713. X * PERFORMANCE OF THIS SOFTWARE.
  714. X *
  715. X * The following software modules were created and are Copyrighted by National
  716. X * Semiconductor Corporation:
  717. X *
  718. X * 1. warp_handler: 
  719. X * 2. extract_of: 
  720. X * 3. endEdits: 
  721. X * 4. editMail: 
  722. X * 5. makeHeading: 
  723. X * 6. makeButton: 
  724. X * 7. sendMail: 
  725. X *
  726. X * Author:  Michael C. Wagnitz - National Semiconductor Corporation
  727. X *
  728. X */
  729. X#include "global.h"
  730. X#include <sys/wait.h>
  731. X#include <sys/stat.h>
  732. X#include <signal.h>
  733. X#include <errno.h>
  734. X
  735. X#ifdef vms
  736. Xextern int    noshare errno;
  737. X#else
  738. Xextern int    errno;
  739. X#endif
  740. X
  741. X#if ! defined(SIGCHLD) && defined(SIGCLD)
  742. X#define    SIGCHLD        SIGCLD
  743. X#endif
  744. X
  745. X#ifndef    DEFAULT_VISUAL
  746. X#define    DEFAULT_VISUAL    "/usr/ucb/vi"
  747. X#endif
  748. X
  749. Xstatic int        editMail_pid;
  750. X
  751. X
  752. X/* ARGSUSED */
  753. XXtEventHandler
  754. Xwarp_handler(w, client_data, event)
  755. XWidget    w;
  756. Xcaddr_t    client_data;
  757. XXEvent    *event;
  758. X{
  759. X Widget Popup = XtNameToWidget(toplevel,"topBox.commandPanel.Send.popup");
  760. X Widget    To = XtNameToWidget(Popup, "SubjCc.To");
  761. X
  762. X if (event->type == MapNotify) {
  763. X    XWarpPointer(XtDisplay(toplevel), None, XtWindow(To), 0,0,0,0, 15, 10);
  764. X    XtRemoveEventHandler(Popup, StructureNotifyMask, False, warp_handler, NULL);
  765. X   }
  766. X}
  767. X
  768. X
  769. X/*
  770. X** @(#)extract_of - strip off header information from a buffer and return
  771. X**                  the extracted information and the incremented pointer
  772. X*/
  773. Xchar *
  774. Xextract_of(p)
  775. Xchar    **p;
  776. X{
  777. X int    n;
  778. X char    tmp[BUFSIZ];
  779. X
  780. X
  781. X for (n = 0; *(*p); (*p)++) {
  782. X     if (*(*p) == '\n' && *((*p) + 1) != ' ' && *((*p) + 1) != '\t') break;
  783. X     if (*(*p) == '\n') {
  784. X        if (tmp[n - 1] != ' ' && tmp[n - 1] != '\t') tmp[n++] = ' ';
  785. X        for ((*p)++; *(*p) && (*(*p) == ' ' || *(*p) == '\t');) (*p)++;
  786. X       }
  787. X     if (*(*p) != '\n') tmp[n++] = *(*p);
  788. X    }
  789. X tmp[n] = '\0';
  790. X return((char *)tmp);
  791. X}
  792. X
  793. X
  794. X/*
  795. X** @(#)endEdits() - catch the signal when the edit child finishes
  796. X**                  (The idea for this was ``borrowed'' from xrn.)
  797. X**                  If editheaders is set, extract selected header
  798. X**                  information from the message text file and
  799. X**                  install it in the appropriate header windows.
  800. X**                  Then, popup the completion window with header
  801. X**                  edit windows and completion control buttons.
  802. X*/
  803. Xint
  804. XendEdits(signum)
  805. Xint    signum;
  806. X{
  807. X int        fd, status;
  808. X String        p, q;
  809. X char        buf[BUFSIZ];
  810. X Widget        sb, Popup;
  811. X
  812. X
  813. X if (signum != SIGCHLD)
  814. X    return 1;
  815. X
  816. X if (editMail_pid != wait(&status))
  817. X    return 1;                /* the mail child could die too */
  818. X
  819. X (void) signal(SIGCHLD, SIG_DFL);    /* turn off the endEdits hook */
  820. X
  821. X sb = XtNameToWidget(toplevel, "topBox.commandPanel.Send");
  822. X
  823. X if (p = GetMailEnv("editheaders")) {
  824. X    XtFree((String) p);
  825. X    if ((fd = open(tmpName, O_RDONLY)) >= 0) {
  826. X       while (1) {
  827. X          bzero(Command, BUFSIZ);
  828. X          status = read(fd, Command, BUFSIZ);
  829. X          for (p = Command; *p; p++) {
  830. X              if (*p == '\n' && *(p - 1) == '\n') {
  831. X                 status = 0;
  832. X                 break;
  833. X                }
  834. X              if (strncmp(p, "To: ", 4) == 0) {
  835. X                 p += 4;
  836. X                 writeTo(XtNameToWidget(sb, "*To"), extract_of(&p), REPLACE);
  837. X                } else 
  838. X              if (strncmp(p, "Subject: ", 9) == 0) {
  839. X                 p += 9;
  840. X                 writeTo(XtNameToWidget(sb,"*Subject"),extract_of(&p),REPLACE);
  841. X                } else 
  842. X              if (strncmp(p, "In-Reply-To: ", 13) == 0) {
  843. X                 p += 13;
  844. X                 (void) strcpy(buf, extract_of(&p));
  845. X                 if (! (q = strchr(buf, ':')))
  846. X                    (void) sprintf(InReply, "In-Reply-To: %s", buf);
  847. X                 else {
  848. X                    q -= 5;
  849. X                    if (strncmp(q, "dated: ", 7) != 0)
  850. X                       (void) sprintf(InReply, "In-Reply-To: %s", buf);
  851. X                    else {
  852. X                       *(q - 1) = '\0';
  853. X                       (void) sprintf(InReply, "In-Reply-To: %s\n      ", buf);
  854. X                       (void) strcat(InReply, q);
  855. X                      }
  856. X                   }
  857. X                } else 
  858. X              if (strncmp(p, "Forwarding: ", 12) == 0) {
  859. X                 p += 12;
  860. X                 (void) strcpy(buf, extract_of(&p));
  861. X                 if (! (q = strchr(buf, ':')))
  862. X                    (void) sprintf(InReply, "Forwarding: %s", buf);
  863. X                 else {
  864. X                    q -= 5;
  865. X                    if (strncmp(q, "dated: ", 7) != 0)
  866. X                       (void) sprintf(InReply, "Forwarding: %s", buf);
  867. X                    else {
  868. X                       *(q - 1) = '\0';
  869. X                       (void) sprintf(InReply, "Forwarding: %s\n     ", buf);
  870. X                       (void) strcat(InReply, q);
  871. X                      }
  872. X                   }
  873. X                } else 
  874. X              if (strncmp(p, "Cc: ", 4) == 0) {
  875. X                 p += 4;
  876. X                 writeTo(XtNameToWidget(sb, "*Cc"), extract_of(&p), REPLACE);
  877. X                } else 
  878. X              if (strncmp(p, "Bcc: ", 5) == 0) {
  879. X                 p += 5;
  880. X                 writeTo(XtNameToWidget(sb, "*Bcc"), extract_of(&p), REPLACE);
  881. X                } else {
  882. X                 for (;*p && *p != '\n';) p++;
  883. X                }
  884. X             }
  885. X          if (status < BUFSIZ) break;
  886. X         }
  887. X       (void) close(fd);
  888. X      }
  889. X   }
  890. X
  891. X Popup = XtNameToWidget(sb, ".popup");
  892. X
  893. X SetXY(Popup, XtNameToWidget(toplevel, "topBox.commandPanel"), 0, 0);
  894. X
  895. X XtPopup(Popup, XtGrabNone);
  896. X
  897. X XSync(XtDisplay(toplevel), False);
  898. X
  899. X XtAddEventHandler(Popup, StructureNotifyMask, False, warp_handler, NULL);
  900. X
  901. X return 1;
  902. X}
  903. X
  904. X
  905. X/*
  906. X** @(#)editMail() - edit a mail message using the preferred editor
  907. X**
  908. X** Support is now provided for declaring the editor command as an xmail
  909. X** resource, ala xrn.  If the resource ``xmail.editorCommand'' is defined,
  910. X** it must contain an `sprintf'-able format string that provides for the
  911. X** inclusion of both a display name and the name of the file to be edited.
  912. X** If the resource declaration is not included, or does not contain the two
  913. X** required percent-s (%s) formatting strings, xmail will use the VISUAL
  914. X** resource.  If VISUAL is used, try to accommodate those editors (emacs,
  915. X** xedit...) which start their own window in X11.  We know for a fact that
  916. X** vi and ed variants do not invoke windows.  We assume any other editor
  917. X** specification does.
  918. X*/
  919. Xvoid
  920. XeditMail()
  921. X{
  922. X String        edit, cp;
  923. X char        cmd[BUFSIZ];
  924. X Display    *ad;
  925. X
  926. X
  927. X bzero(cmd, BUFSIZ);
  928. X
  929. X ad  = XtDisplay(XtNameToWidget(toplevel, "topBox.statusWindow"));
  930. X/*
  931. X** If editorCommand resource exists, use it (format validated during initialize)
  932. X*/
  933. X if (XMail.editorCommand)
  934. X    (void) sprintf(cmd, XMail.editorCommand, ad->display_name, tmpName);
  935. X else {
  936. X    /*
  937. X    ** Otherwise, default to the VISUAL method of starting things
  938. X    */
  939. X    if (! (edit = GetMailEnv("VISUAL")))
  940. X           edit = XtNewString(DEFAULT_VISUAL);
  941. X
  942. X    if ((cp = strrchr(edit, '/')) == NULL) cp = edit;
  943. X    else cp++;
  944. X
  945. X    if (strcmp(cp, "ed") == 0 ||
  946. X        strcmp(cp,"red") == 0 ||
  947. X        strcmp(cp, "ex") == 0 ||
  948. X        strcmp(cp, "vi") == 0) {
  949. X       (void) sprintf(cmd, "exec xterm -display %s -name XMail -title 'Message entry' -e %s %s",
  950. X                     ad->display_name, edit, tmpName);
  951. X      } else (void) sprintf(cmd, "exec %s -display %s %s", edit, ad->display_name, tmpName);
  952. X    XtFree((String) edit);
  953. X   }
  954. X
  955. X editMail_pid = fork();
  956. X
  957. X switch (editMail_pid) {
  958. X    case -1:            /* fork failed ... */
  959. X         if (errno == ENOMEM)
  960. X            Bell("Not enough core for edits\n");
  961. X         else
  962. X            Bell("No more processes - no edits\n");
  963. X         break;
  964. X
  965. X    case 0:            /* child starts the message entry session */
  966. X         (void) close(ConnectionNumber(XtDisplay(toplevel)));
  967. X         (void) execl("/bin/sh", "sh", "-c", cmd, 0);
  968. X         perror("editMail: Failed to start the text editor");
  969. X         (void) _exit(127);
  970. X         break;
  971. X
  972. X    default:            /* parent waits for editing to conclude */
  973. X         (void) signal(SIGCHLD, endEdits);
  974. X         break;
  975. X   }
  976. X} /* editMail */
  977. X
  978. X
  979. X/*
  980. X** @(#)readMail() - callback invoked every time input is pending on mail fd
  981. X**
  982. X** Calls QueryMail() to read all available data from mail file descriptor,
  983. X** and passes output to parse() for analysis and appropriate action.
  984. X*/
  985. X/* ARGSUSED */
  986. XXtInputCallbackProc
  987. XreadMail(client_data, source, id)
  988. Xcaddr_t   client_data;    /* unused */
  989. Xint       *source;    /* unused */
  990. XXtInputId *id;        /* unused */
  991. X{
  992. X SetCursor(WATCH);
  993. X parse(QueryMail(""));
  994. X} /* readMail */
  995. X
  996. X
  997. X/*
  998. X** @(#)makeHeading() - Create the specified message header windows
  999. X*/
  1000. Xvoid
  1001. XmakeHeading(parent, label_string, left, above, info, help_text)
  1002. XWidget    parent;
  1003. XString    label_string;
  1004. XWidget    *left, *above;
  1005. XString    info, help_text;
  1006. X{
  1007. X Arg    args[11];
  1008. X char    resource_name[10];
  1009. X Widget    input_window;
  1010. X
  1011. X
  1012. X XtSetArg(args[0], XtNfromVert, *left);
  1013. X XtSetArg(args[1], XtNfromHoriz, NULL);
  1014. X XtSetArg(args[2], XtNlabel, label_string);
  1015. X XtSetArg(args[3], XtNborderWidth, 0);
  1016. X XtSetArg(args[4], XtNfont, XMail.buttonFont);
  1017. X XtSetArg(args[5], XtNheight, XMail.buttonHeight + XMail.borderWidth + 7);
  1018. X XtSetArg(args[6], XtNwidth, XMail.buttonWidth);
  1019. X XtSetArg(args[7], XtNjustify, XtJustifyLeft);
  1020. X XtSetArg(args[8], XtNinternalHeight, 0);
  1021. X XtSetArg(args[9], XtNinternalWidth, 1);
  1022. X *left = XtCreateManagedWidget("SubjCc", labelWidgetClass, parent, args, 10);
  1023. X
  1024. X bzero(resource_name, 9);
  1025. X (void) strncpy(resource_name, label_string, strlen(label_string) - 1);
  1026. X input_window = CreateInputWindow(parent, resource_name);
  1027. X
  1028. X XtSetArg(args[0], XtNfromVert, *above);
  1029. X XtSetArg(args[1], XtNfromHoriz, *left);
  1030. X XtSetValues(input_window, args, 2);
  1031. X
  1032. X AddInfoHandler(input_window, info);
  1033. X
  1034. X AddHelpText(input_window, help_text);
  1035. X
  1036. X *above = input_window;
  1037. X} /* makeHeading */
  1038. X
  1039. X
  1040. X/*
  1041. X** @(#)makeButton() - Create the specified command button with callback
  1042. X*/
  1043. Xvoid
  1044. XmakeButton(parent, label, CBProc, CBData, info, help_text)
  1045. XWidget        parent;
  1046. XString        label;
  1047. XXtCallbackProc    CBProc;
  1048. XString        CBData, info, help_text;
  1049. X{
  1050. X Arg        args[3];
  1051. X Widget        button;
  1052. X int        width = (((XMail.shellWidth-2)/6) - XMail.borderWidth*2) - 4;
  1053. X
  1054. X
  1055. X XtSetArg(args[0], XtNfont, XMail.buttonFont);
  1056. X XtSetArg(args[1], XtNheight, XMail.buttonHeight);
  1057. X XtSetArg(args[2], XtNwidth, width);
  1058. X
  1059. X button = XtCreateManagedWidget(label, commandWidgetClass, parent, args, 3);
  1060. X
  1061. X XtAddCallback(button, XtNcallback, CBProc, CBData);
  1062. X
  1063. X AddInfoHandler(button, info);
  1064. X
  1065. X AddHelpText(button, help_text);
  1066. X} /* makeButton */
  1067. X
  1068. X
  1069. X/*
  1070. X** @(#)sendMail() - Create the send window popup for message headers
  1071. X*/
  1072. Xvoid
  1073. XsendMail(parent)
  1074. XWidget    parent;
  1075. X{
  1076. X Arg        args[11];
  1077. X Widget        Popup, Layout, Box, left, above;
  1078. X
  1079. X
  1080. X Popup = XtNameToWidget(parent, "popup");
  1081. X
  1082. X if (! Popup) {
  1083. X    XtSetArg(args[0], XtNinput, True);
  1084. X    XtSetArg(args[1], XtNwidth, XMail.shellWidth - 2);
  1085. X    XtSetArg(args[2], XtNheight,
  1086. X           XMail.borderWidth*3 + XMail.buttonHeight*5 + 44);
  1087. X    Popup = XtCreatePopupShell("popup",transientShellWidgetClass,parent,args,3);
  1088. X
  1089. X    XtSetArg(args[0], XtNdefaultDistance, 2);
  1090. X    Layout = XtCreateManagedWidget("SubjCc", formWidgetClass, Popup, args, 1);
  1091. X
  1092. X    left = above = NULL;
  1093. X
  1094. X    makeHeading(Layout,      "To:",&left,&above,SendMail_Info[0],To_Help);
  1095. X
  1096. X    makeHeading(Layout, "Subject:",&left,&above,SendMail_Info[1],Subject_Help);
  1097. X
  1098. X    makeHeading(Layout,      "Cc:",&left,&above,SendMail_Info[2],Cc_Help);
  1099. X
  1100. X    makeHeading(Layout,     "Bcc:",&left,&above,SendMail_Info[3],Bcc_Help);
  1101. X
  1102. X    XtRegisterGrabAction(SetAliases, True, ButtonPressMask | ButtonReleaseMask,
  1103. X                         GrabModeAsync, GrabModeAsync);
  1104. X
  1105. X    XtSetArg(args[0], XtNfont, XMail.buttonFont);
  1106. X    XtSetArg(args[1], XtNheight, XMail.buttonHeight + XMail.borderWidth*2 + 4);
  1107. X    XtSetArg(args[2], XtNwidth, XMail.shellWidth - 2);
  1108. X    XtSetArg(args[3], XtNfromVert, left);
  1109. X    XtSetArg(args[4], XtNfromHoriz, NULL);
  1110. X    XtSetArg(args[5], XtNborderWidth, 0);
  1111. X    XtSetArg(args[6], XtNresize, False);
  1112. X    XtSetArg(args[7], XtNmin, args[1].value);
  1113. X    XtSetArg(args[8], XtNmax, args[1].value);
  1114. X    XtSetArg(args[9], XtNhSpace, 2);
  1115. X    XtSetArg(args[10],XtNvSpace, 2);
  1116. X    Box = XtCreateManagedWidget("Box", boxWidgetClass, Layout, args, 11);
  1117. X
  1118. X    makeButton(Box, "Autograph", (XtCallbackProc) Autograph, "A",
  1119. X                     Autograph_Info[0], Sign_Help);
  1120. X
  1121. X    makeButton(Box, "autograph", (XtCallbackProc) Autograph, "a",
  1122. X                     Autograph_Info[1], sign_Help);
  1123. X
  1124. X    makeButton(Box, "ReEdit", (XtCallbackProc) ReEdit, "ReEdit",
  1125. X                     Deliver_Info[1], ReEdit_Help);
  1126. X
  1127. X    makeButton(Box, "Cancel", (XtCallbackProc) Done, "cancel",
  1128. X                     Deliver_Info[2], Cancel_Help);
  1129. X
  1130. X    makeButton(Box, "Abort", (XtCallbackProc) Done, "Cancel",
  1131. X                     Deliver_Info[3], Abort_Help);
  1132. X
  1133. X    makeButton(Box, "Deliver", (XtCallbackProc) Done, "Deliver",
  1134. X                     Deliver_Info[0], Deliver_Help);
  1135. X   }
  1136. X} /* sendMail */
  1137. X
  1138. X
  1139. X/*
  1140. X** @(#)writeMail() - Write command s to the mail process.
  1141. X*/
  1142. Xvoid
  1143. XwriteMail(s) 
  1144. Xchar *s;
  1145. X{
  1146. X (void) write(mail_fd, s, strlen(s));
  1147. X} /* writeMail */
  1148. END_OF_FILE
  1149.   if test 14182 -ne `wc -c <'mail.c'`; then
  1150.     echo shar: \"'mail.c'\" unpacked with wrong size!
  1151.   fi
  1152.   # end of 'mail.c'
  1153. fi
  1154. if test -f 'utils.c' -a "${1}" != "-c" ; then 
  1155.   echo shar: Will not clobber existing file \"'utils.c'\"
  1156. else
  1157.   echo shar: Extracting \"'utils.c'\" \(13989 characters\)
  1158.   sed "s/^X//" >'utils.c' <<'END_OF_FILE'
  1159. X/*
  1160. X * xmail - X window system interface to the mail program
  1161. X *
  1162. X * Copyright 1990,1991,1992 by National Semiconductor Corporation
  1163. X *
  1164. X * Permission to use, copy, modify, and distribute this software and its
  1165. X * documentation for any purpose is hereby granted without fee, provided that
  1166. X * the above copyright notice appear in all copies and that both that
  1167. X * copyright notice and this permission notice appear in supporting
  1168. X * documentation, and that the name of National Semiconductor Corporation not
  1169. X * be used in advertising or publicity pertaining to distribution of the
  1170. X * software without specific, written prior permission.
  1171. X *
  1172. X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
  1173. X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS"
  1174. X * WITHOUT EXPRESS OR IMPLIED WARRANTY.  NATIONAL SEMICONDUCTOR CORPORATION
  1175. X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  1176. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  1177. X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
  1178. X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  1179. X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  1180. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  1181. X * PERFORMANCE OF THIS SOFTWARE.
  1182. X *
  1183. X * The following software modules were created and are Copyrighted by
  1184. X * National Semiconductor Corporation:
  1185. X *
  1186. X * 1. markIndex:
  1187. X * 2. LastNumber:
  1188. X * 3. SelectionNumber:
  1189. X * 4. SetCursor: and
  1190. X * 5. SetXY.
  1191. X *
  1192. X * Author:  Michael C. Wagnitz - National Semiconductor Corporation
  1193. X *
  1194. X */
  1195. X
  1196. X
  1197. X#include <ctype.h>
  1198. X#include "global.h"
  1199. X#include "patchlevel.h"
  1200. X#include "revtable.h"
  1201. X
  1202. X
  1203. X/*
  1204. X** @(#)Bell() - write a status message and (optionally) ring the terminal bell
  1205. X*/
  1206. Xvoid
  1207. XBell(msg)
  1208. XString        msg;
  1209. X{
  1210. X Arg        args[1];
  1211. X char        *p;
  1212. X char        buf[BUFSIZ];
  1213. X int        size;
  1214. X static int    worthy = 0;        /* only msgs with ending newline are */
  1215. X
  1216. X
  1217. X size = strlen(msg);
  1218. X if (size >= BUFSIZ) size = BUFSIZ - 1;
  1219. X
  1220. X (void) strncpy(buf, msg, size);
  1221. X buf[size] = '\0';
  1222. X
  1223. X p = strchr(buf, '\n');            /* messages with newline get a bell */
  1224. X/*
  1225. X** Because we have now added enter/leave window event information messages,
  1226. X** we must play a slight game with incoming messages, to prevent any error
  1227. X** messages from a menu selection failure or status messages from a command
  1228. X** button being overwritten by the subsequent event info messages produced
  1229. X** when the menu popup is dismissed or the command completes.  To do this,
  1230. X** we make the bell worthy-ness flag static, and only replace a message after
  1231. X** first seeing a non-default status message, which will reset the worthy-ness
  1232. X** flag, but otherwise be ignored.  When the first non-default, non-error
  1233. X** message comes in, simply reset our bell worthy-ness flag and return, leaving
  1234. X** the previous error message still intact.  This means, to ensure seeing the
  1235. X** default message, first send a blank line to reset the worthy-ness flag.
  1236. X*/
  1237. X if (! XMail.Show_Info)            /* if NOT showing info flags always */
  1238. X    worthy = 0;                /* reset the bell worthy-ness flag */
  1239. X else {
  1240. X    if (worthy && p == NULL) {        /* if last was but this ain't urgent */
  1241. X       if (strcmp(buf, Default_Status_Info))    /* and not the default info */
  1242. X          worthy = 0;            /* reset the bell worthy-ness flag */
  1243. X       return;                /* ignore event info if menu errored */
  1244. X      }                    /* by leaving previous error message */
  1245. X   }
  1246. X
  1247. X if (size == 0)                /* if intent was just to reset flag */
  1248. X    return;
  1249. X
  1250. X if (p != NULL) {            /* Only display first line of output */
  1251. X    *p = '\0';                /* (no new line at end of label) */
  1252. X    worthy = 1;                /* this message is worthy of a bell */
  1253. X   }
  1254. X
  1255. X if (worthy && XMail.bellRing)        /* ring bell if not silenced by user */
  1256. X    XBell(XtDisplay (toplevel), 33);
  1257. X
  1258. X XtSetArg(args[0], XtNlabel, (XtArgVal) buf);    /* show this message text */
  1259. X XtSetValues(XtNameToWidget(toplevel, "topBox.statusWindow"), args, 1);
  1260. X XFlush(XtDisplay(toplevel));
  1261. X} /* Bell */
  1262. X
  1263. X
  1264. X/*
  1265. X** @(#)figureWidth() - determine the figure width of the specified font
  1266. X*/
  1267. Xint
  1268. XfigureWidth(font)
  1269. XXFontStruct *font;
  1270. X{
  1271. X Atom        _XA_FIGURE_WIDTH;
  1272. X unsigned long    width = 0;
  1273. X
  1274. X
  1275. X _XA_FIGURE_WIDTH = XInternAtom(XtDisplay(toplevel), "FIGURE_WIDTH", FALSE);
  1276. X if ((_XA_FIGURE_WIDTH != NULL) &&
  1277. X    ((! XGetFontProperty(font, _XA_FIGURE_WIDTH, &width)) || (width == 0)))
  1278. X    if (font->per_char && font->min_char_or_byte2 <= '$' &&
  1279. X                          font->max_char_or_byte2 >= '$')
  1280. X       width = font->per_char['$' - font->min_char_or_byte2].width;
  1281. X    else
  1282. X       width = font->max_bounds.width;
  1283. X
  1284. X return(width);
  1285. X} /* end - figureWidth */
  1286. X
  1287. X
  1288. X
  1289. X/*
  1290. X** @(#)markIndex() - add or remove a tag from the start of a mail header line
  1291. X**                   May be invoked by button press, which sets the insertion
  1292. X**                   pointer for the text to the current mouse cursor location.
  1293. X*/
  1294. Xvoid
  1295. XmarkIndex(s)
  1296. Xchar    *s;
  1297. X{
  1298. X int            size;
  1299. X XawTextPosition    pos, old;
  1300. X String            c, p = NULL;
  1301. X char            buf[3];
  1302. X Widget            iw = XtNameToWidget(toplevel, "topBox.indexWindow");
  1303. X Arg            args[1];
  1304. X XawTextBlock        text;
  1305. X
  1306. X
  1307. X (void) strcpy(buf, s);            /* make a copy of our marker string */
  1308. X
  1309. X XtSetArg(args[0], XtNstring, &p);    /* retrieve the current index buffer */
  1310. X XtGetValues(iw, args, 1);
  1311. X
  1312. X for (pos = XawTextGetInsertionPoint(iw); pos > 0 && p[pos-1] != '\n'; pos--);
  1313. X
  1314. X if (buf[0] == '>') {            /* if mark is for 'current' pointer */
  1315. X    XtSetArg(args[0], XtNstring, &p);    /* retrieve the current index buffer */
  1316. X    XtGetValues(iw, args, 1);
  1317. X
  1318. X    if (strlen(p) < 3)            /* trap for case of no index at all */
  1319. X       return;
  1320. X
  1321. X    if (strlen(p) > pos + 1)
  1322. X       if (p[pos + 1] == 'S')        /* keep the Save marker if it exists */
  1323. X          if (strlen(buf) > 1)
  1324. X             buf[1] = '\0';
  1325. X
  1326. X    for (c = p; *c; c++)
  1327. X        if (*c == '>' && (c == p || *(c - 1) == '\n')) {
  1328. X           old = c - p;            /* if found, remove the old '>' mark */
  1329. X           text.firstPos = 0;
  1330. X           text.length   = 1;
  1331. X           text.ptr      = " ";
  1332. X           text.format   = FMT8BIT;
  1333. X           XawTextReplace(iw, (XawTextPosition) old, (XawTextPosition) old + 1, &text);
  1334. X           break;
  1335. X          }
  1336. X   }
  1337. X
  1338. X size = strlen(buf);            /* now write the specified marker */
  1339. X old = (buf[0] == '>') ? pos : pos + 1;
  1340. X text.firstPos = 0;
  1341. X text.length   = size;
  1342. X text.ptr      = buf;
  1343. X text.format   = FMT8BIT;
  1344. X XawTextReplace(iw, (XawTextPosition) old, (XawTextPosition) old + size, &text);
  1345. X
  1346. X XawTextSetInsertionPoint(iw, pos);    /* reset our actual insertion point */
  1347. X} /* markIndex */
  1348. X
  1349. X
  1350. X/*
  1351. X** @(#)LastNumber() - Get mail index number for last message in folder
  1352. X*/
  1353. Xint
  1354. XLastNumber()
  1355. X{
  1356. X int            last_number;
  1357. X Arg            args[1];
  1358. X String            c, ep, str = NULL;
  1359. X Widget            iw = XtNameToWidget(toplevel, "topBox.indexWindow");
  1360. X
  1361. X XtSetArg(args[0], XtNstring, &str);
  1362. X XtGetValues(iw, args, 1);
  1363. X
  1364. X ep = &str[strlen(str) - 1];
  1365. X
  1366. X for (c = ep - 1; c > str; c--)
  1367. X     if (*(c - 1) == '\n' && *(c + 1) != 'D')
  1368. X        break;
  1369. X
  1370. X for (; c < ep && !isdigit(*c); c++);
  1371. X (void) sscanf(c, "%d", &last_number);
  1372. X
  1373. X return(last_number);
  1374. X} /* LastNumber */
  1375. X
  1376. X
  1377. X/*
  1378. X** @(#)SelectionNumber() - Get mail index number from line position
  1379. X*/
  1380. Xint
  1381. XSelectionNumber(undeleting)
  1382. Xint    undeleting;
  1383. X{
  1384. X Arg            args[1];
  1385. X String            c, str = NULL;
  1386. X Widget            iw = XtNameToWidget(toplevel, "topBox.indexWindow");
  1387. X XawTextPosition    pos;
  1388. X int            selection_number = 0;
  1389. X
  1390. X
  1391. X XtSetArg(args[0], XtNstring, &str);
  1392. X XtGetValues(iw, args, 1);
  1393. X
  1394. X for (pos = XawTextGetInsertionPoint(iw); pos > 0 && str[pos] != '\n'; pos--);
  1395. X pos++;
  1396. X
  1397. X if (! undeleting || str[pos + 1] == 'D') {
  1398. X    for (c = &str[pos]; *c && !isdigit(*c); c++);
  1399. X    (void) sscanf(c, "%d", &selection_number);
  1400. X   }
  1401. X
  1402. X return(selection_number);
  1403. X} /* SelectionNumber */
  1404. X
  1405. X
  1406. X/* ARGSUSED */
  1407. X/*
  1408. X** @(#)SetCursor() - sets the wait cursor or restores the default
  1409. X*/
  1410. Xvoid
  1411. XSetCursor(waiting)
  1412. Xint    waiting;        /* a non-zero value sets the busy cursor */
  1413. X{
  1414. X if (! waiting)
  1415. X    XUnmapWindow(XtDisplay(toplevel), WaitCursorWindow);
  1416. X else {
  1417. X      XMapWindow(XtDisplay(toplevel), WaitCursorWindow);
  1418. X    Waiting = TRUE;        /* to prevent overwrite of important info */
  1419. X   }
  1420. X
  1421. X XFlush(XtDisplay(toplevel));
  1422. X} /* SetCursor */
  1423. X
  1424. X
  1425. X/*
  1426. X** @(#)SetXY() - Set relative window coordinates including specified offset
  1427. X*/
  1428. Xvoid
  1429. XSetXY(target, reference, X_offset, Y_offset)
  1430. XWidget    target, reference;
  1431. Xint    X_offset, Y_offset;
  1432. X{
  1433. X Arg        args[2];
  1434. X Display    *dpy = XtDisplay(reference);
  1435. X Window        dumy;
  1436. X int        x, y;
  1437. X
  1438. X
  1439. X XTranslateCoordinates(dpy, XtWindow(reference),
  1440. X                       RootWindow(dpy, DefaultScreen(dpy)),
  1441. X                       X_offset, Y_offset, &x, &y, &dumy);
  1442. X /*
  1443. X ** Keep window within root window borders (don't place it off-screen)
  1444. X */
  1445. X if (! XtIsRealized(target))
  1446. X    XtRealizeWidget(target);        /* to get width and height values */
  1447. X
  1448. X if (x + target->core.width > RootWidth)
  1449. X    x = RootWidth - target->core.width - 2;
  1450. X
  1451. X if (y + target->core.height > RootHeight)
  1452. X    y = RootHeight - target->core.height - 2;
  1453. X
  1454. X XtSetArg(args[0], XtNx, x);
  1455. X XtSetArg(args[1], XtNy, y);
  1456. X XtSetValues(target, args, 2);
  1457. X} /* end - SetXY */
  1458. X
  1459. X
  1460. X/*
  1461. X** @(#)TextGetLastPos() - return position of last text character
  1462. X*/
  1463. XXawTextPosition
  1464. XTextGetLastPos(w)
  1465. XWidget w;
  1466. X{
  1467. X TextWidget ctx = (TextWidget) w;
  1468. X return (XawTextSourceScan(ctx->text.source,0,XawstAll,XawsdRight,1,TRUE));
  1469. X}
  1470. X
  1471. X
  1472. X/*
  1473. X** @(#)UpdateTitleBar() - replace information in the title bar title
  1474. X*/
  1475. Xvoid
  1476. XUpdateTitleBar(msg)
  1477. Xchar *msg;
  1478. X{
  1479. X char        message[BUFSIZ];
  1480. X Arg        args[1];
  1481. X Widget        w;
  1482. X
  1483. X
  1484. X (void) sprintf(message, "%s%d - %s", TITLE, PATCHLEVEL, msg);
  1485. X
  1486. X w = XtNameToWidget(toplevel, "topBox.titleBar.title");
  1487. X
  1488. X XtSetArg(args[0], XtNlabel, (XtArgVal) message);
  1489. X XtSetValues(w, args, 1);
  1490. X w = XtNameToWidget(toplevel, "topBox.commandPanel.Newmail.Newmail_menu.menu.inc");
  1491. X if (w)
  1492. X    XtSetSensitive(w, In_System_Folder());
  1493. X} /* UpdateTitleBar */
  1494. X
  1495. X
  1496. X/*
  1497. X** @(#)writeTo() - write data to the specified text widget
  1498. X*/
  1499. Xvoid
  1500. XwriteTo(w, data, do_append)
  1501. XWidget    w;
  1502. Xchar   *data;
  1503. Xint    do_append;
  1504. X{
  1505. X XawTextBlock        text;
  1506. X XawTextPosition    startPos, endPos;
  1507. X int            l, n;
  1508. X
  1509. X
  1510. X endPos         = TextGetLastPos(w) + (do_append ? 0 : 1);
  1511. X startPos       = (do_append ? endPos : 0);
  1512. X text.firstPos  = 0;
  1513. X text.length    = strlen(data);
  1514. X text.ptr       = data;
  1515. X text.format    = FMT8BIT;
  1516. X
  1517. X XawTextReplace(w, (XawTextPosition) startPos, (XawTextPosition) endPos, &text);
  1518. X
  1519. X XawTextSetInsertionPoint(w, (XawTextPosition) TextGetLastPos(w));
  1520. X
  1521. X XawTextInvalidate(w, (XawTextPosition) 0, (XawTextPosition) endPos);
  1522. X} /* writeTo */
  1523. X
  1524. X
  1525. X/*
  1526. X** @(#)writeText() - replace the current text string in the text window.
  1527. X**                 Also look for an X-Face: header and if found, display.
  1528. X*/
  1529. Xvoid
  1530. XwriteText(buf)
  1531. Xchar    *buf;
  1532. X{
  1533. X Arg            args[2];
  1534. X Widget        w = XtNameToWidget(toplevel, "topBox.textWindow.text");
  1535. X#ifdef X_FACE
  1536. X Display        *dpy = XtDisplay(w);
  1537. X Widget         fw;
  1538. X Window         rw;
  1539. X char           cb[1024], fb[2048], *ptr, *xface;
  1540. X int            i, n, x, y;
  1541. X#endif
  1542. X
  1543. X if (buf && *buf) {
  1544. X#ifndef X_FACE
  1545. X    XtSetArg(args[0], XtNstring, buf);
  1546. X    XtSetValues(w, args, 1);
  1547. X#else
  1548. X    if (! (fw = XtNameToWidget(XtParent(w), "face"))) {
  1549. X       XtSetArg(args[0], XtNstring, buf);
  1550. X       XtSetValues(w, args, 1);
  1551. X       return;
  1552. X      }
  1553. X    /*
  1554. X    ** First, unmap any current picture.
  1555. X    **
  1556. X    ** Look for a line containing an 'X-Face:' header, followed by 72
  1557. X    ** characters of compressed data.  The second and any subsequent lines
  1558. X    ** will contain an initial space (which is ignored), followed by 79
  1559. X    ** characters of compressed data.  The last line may contain fewer than 79
  1560. X    ** characters.
  1561. X    **
  1562. X    ** The X-Face: header and any immediate whitespace (tabs or spaces) will be
  1563. X    ** removed, and the remaining line placed in the internal buffer (minus
  1564. X    ** any trailing newline).  On subsequent lines, initial whitespace will be
  1565. X    ** removed, and the remainder of the data appended to the buffer (minus any
  1566. X    ** trailing newline).
  1567. X    **
  1568. X    ** A blank line, a line without an initial whitespace character,or the
  1569. X    ** end of the input buffer will signify the end of the X-Face data.  That
  1570. X    ** buffer will then be uncompressed, and if the data was valid, displayed.
  1571. X    */
  1572. X
  1573. X    if (XtIsManaged(fw))
  1574. X       XtUnmanageChild(fw);
  1575. X
  1576. X    for (ptr = buf; *ptr; ptr++) {
  1577. X        if (*ptr == '\n'                    ||
  1578. X           strncmp(ptr, "Status:", 7) == 0  ||
  1579. X           strncmp(ptr, "X-Face:", 7) == 0) break;
  1580. X
  1581. X        for (; *ptr && *ptr != '\n'; ptr++);
  1582. X       }
  1583. X
  1584. X    if (! *ptr || strncmp(ptr, "X-Face:", 7) != 0) {
  1585. X       XtSetArg(args[0], XtNstring, buf);
  1586. X       XtSetValues(w, args, 1);
  1587. X       return;
  1588. X      }
  1589. X
  1590. X    xface = ptr;    /* keep track of the start position of X-Face header */
  1591. X
  1592. X    bzero(fb, 2048);
  1593. X    for (i = 0, ptr += 7; *ptr; ptr++) {
  1594. X        if (*ptr != ' ' && *ptr != '\t' && *ptr != '\n')
  1595. X           fb[i++] = *ptr;
  1596. X        if (*ptr == '\n' && *(ptr+1) && *(ptr+1) != ' ' && *(ptr+1) != '\t')
  1597. X           break;
  1598. X       }
  1599. X
  1600. X    if (XMail.No_X_Hdr) {
  1601. X       if (*ptr) ptr++;
  1602. X       bcopy(ptr, xface, strlen(ptr) + 1);    /* suppress the X-Face header */
  1603. X      }
  1604. X
  1605. X    XtSetArg(args[0], XtNstring, buf);
  1606. X    XtSetValues(w, args, 1);
  1607. X
  1608. X    if (uncompface(fb) >= 0) {
  1609. X       bzero(cb, 1024);
  1610. X       for (i = n = 0;i < 1024;) {
  1611. X           if (! sscanf(&fb[n], "%i%n", &x, &y)) break;
  1612. X           cb[i++] = revtable[(x >> 8) & 0xFF];
  1613. X           cb[i++] = revtable[x & 0xFF];
  1614. X           n += y;
  1615. X           while (fb[n] && (fb[n]==',' || fb[n]=='\n')) n++;
  1616. X          }
  1617. X
  1618. X       XtSetArg(args[0], XtNwidth, NULL);
  1619. X       XtGetValues(XtParent(w), args, 1);
  1620. X       n = args[0].value - 48;
  1621. X       if (n < 0) n = 0;
  1622. X
  1623. X       XtSetArg(args[0], XtNbitmap, NULL);
  1624. X       XtGetValues(fw, args, 1);
  1625. X       if (args[0].value != None)
  1626. X          XFreePixmap(dpy, args[0].value);
  1627. X
  1628. X       rw = RootWindow(dpy, DefaultScreen(dpy));
  1629. X       XtSetArg(args[0], XtNbitmap, XCreateBitmapFromData(dpy, rw, cb, 48, 48));
  1630. X       XtSetArg(args[1], XtNhorizDistance, n);
  1631. X       XtSetValues(fw, args, 2);
  1632. X
  1633. X       XtManageChild(fw);
  1634. X      }
  1635. X#endif
  1636. X   }
  1637. X} /* writeText */
  1638. END_OF_FILE
  1639.   if test 13989 -ne `wc -c <'utils.c'`; then
  1640.     echo shar: \"'utils.c'\" unpacked with wrong size!
  1641.   fi
  1642.   # end of 'utils.c'
  1643. fi
  1644. echo shar: End of archive 7 \(of 10\).
  1645. cp /dev/null ark7isdone
  1646. MISSING=""
  1647. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  1648.     if test ! -f ark${I}isdone ; then
  1649.     MISSING="${MISSING} ${I}"
  1650.     fi
  1651. done
  1652. if test "${MISSING}" = "" ; then
  1653.     echo You have unpacked all 10 archives.
  1654.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1655. else
  1656.     echo You still must unpack the following archives:
  1657.     echo "        " ${MISSING}
  1658. fi
  1659. exit 0
  1660. exit 0 # Just in case...
  1661. -- 
  1662.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  1663. \X/  Amiga - The only way to fly!      |
  1664.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  1665.   casual observer..."                  |
  1666.