/opensource.apple.com/source/netinfo/netinfo-369.2/servers/netinfod/alert.c

# · C · 331 lines · 261 code · 40 blank · 30 comment · 26 complexity · 51f580301eeec55640aea959d6cd12d0 MD5 · raw file

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <title>alert.c</title>
  6. <style type="text/css">
  7. .enscript-comment { font-style: italic; color: rgb(178,34,34); }
  8. .enscript-function-name { font-weight: bold; color: rgb(0,0,255); }
  9. .enscript-variable-name { font-weight: bold; color: rgb(184,134,11); }
  10. .enscript-keyword { font-weight: bold; color: rgb(160,32,240); }
  11. .enscript-reference { font-weight: bold; color: rgb(95,158,160); }
  12. .enscript-string { font-weight: bold; color: rgb(188,143,143); }
  13. .enscript-builtin { font-weight: bold; color: rgb(218,112,214); }
  14. .enscript-type { font-weight: bold; color: rgb(34,139,34); }
  15. .enscript-highlight { text-decoration: underline; color: 0; }
  16. </style>
  17. </head>
  18. <body id="top">
  19. <h1 style="margin:8px;" id="f1">alert.c&nbsp;&nbsp;&nbsp;<span style="font-weight: normal; font-size: 0.5em;">[<a href="?txt">plain text</a>]</span></h1>
  20. <hr/>
  21. <div></div>
  22. <pre>
  23. <span class="enscript-comment">/*
  24. * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
  25. *
  26. * @APPLE_LICENSE_HEADER_START@
  27. *
  28. * This file contains Original Code and/or Modifications of Original Code
  29. * as defined in and that are subject to the Apple Public Source License
  30. * Version 2.0 (the 'License'). You may not use this file except in
  31. * compliance with the License. Please obtain a copy of the License at
  32. * <a href="http://www.opensource.apple.com/apsl/">http://www.opensource.apple.com/apsl/</a> and read it before using this
  33. * file.
  34. *
  35. * The Original Code and all software distributed under the License are
  36. * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  37. * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  38. * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  39. * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  40. * Please see the License for the specific language governing rights and
  41. * limitations under the License.
  42. *
  43. * @APPLE_LICENSE_HEADER_END@
  44. */</span>
  45. <span class="enscript-comment">/*
  46. * Alert handling (allow user to abort local domain binding)
  47. * Copyright (C) 1989 by NeXT, Inc.
  48. *
  49. */</span>
  50. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;NetInfo/config.h&gt;</span>
  51. <span class="enscript-comment">/*
  52. * Disabled for MacOS X for the momment,
  53. * There's no support for console alerts yet.
  54. */</span>
  55. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">_OS_APPLE_</span>
  56. <span class="enscript-type">static</span> <span class="enscript-type">int</span> aborted = 0;
  57. <span class="enscript-type">static</span> <span class="enscript-type">enum</span> {
  58. ALERT_FRESH,
  59. ALERT_OPENED,
  60. ALERT_PRINTED,
  61. ALERT_CLOSED
  62. } alert_state = ALERT_CLOSED;
  63. <span class="enscript-type">void</span>
  64. <span class="enscript-function-name">alert_enable</span>(<span class="enscript-type">int</span> enable)
  65. {
  66. <span class="enscript-keyword">if</span> (enable) alert_state = ALERT_FRESH;
  67. <span class="enscript-keyword">else</span> alert_state = ALERT_CLOSED;
  68. }
  69. <span class="enscript-type">int</span>
  70. <span class="enscript-function-name">alert_aborted</span>(<span class="enscript-type">void</span>)
  71. {
  72. <span class="enscript-keyword">return</span> aborted;
  73. }
  74. <span class="enscript-type">void</span>
  75. <span class="enscript-function-name">alert_close</span>(<span class="enscript-type">void</span>)
  76. {
  77. <span class="enscript-keyword">if</span> (alert_state != ALERT_PRINTED) <span class="enscript-keyword">return</span>;
  78. alert_state = ALERT_CLOSED;
  79. }
  80. <span class="enscript-type">void</span> <span class="enscript-function-name">alert_open</span>(<span class="enscript-type">const</span> <span class="enscript-type">char</span> *language)
  81. {
  82. <span class="enscript-keyword">if</span> (alert_state != ALERT_FRESH) <span class="enscript-keyword">return</span>;
  83. alert_state = ALERT_PRINTED;
  84. }
  85. #<span class="enscript-reference">else</span>
  86. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;stdio.h&gt;</span>
  87. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;unistd.h&gt;</span>
  88. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;string.h&gt;</span>
  89. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;sys/file.h&gt;</span>
  90. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;sys/param.h&gt;</span>
  91. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;errno.h&gt;</span>
  92. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">_OS_NEXT_</span>
  93. #<span class="enscript-reference">define</span> <span class="enscript-variable-name">BUNDLE_PATH</span> <span class="enscript-string">&quot;/usr/lib/NextStep/Resources&quot;</span>
  94. #<span class="enscript-reference">define</span> <span class="enscript-variable-name">_PATH_CONSOLE</span> <span class="enscript-string">&quot;/dev/console&quot;</span>
  95. #<span class="enscript-reference">else</span>
  96. #<span class="enscript-reference">define</span> <span class="enscript-variable-name">BUNDLE_PATH</span> <span class="enscript-string">&quot;/System/Library/CoreServices/Resources&quot;</span>
  97. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;sys/ioctl_compat.h&gt;</span>
  98. #<span class="enscript-reference">endif</span>
  99. #<span class="enscript-reference">ifndef</span> <span class="enscript-variable-name">_PATH_CONSOLE</span>
  100. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;paths.h&gt;</span>
  101. #<span class="enscript-reference">endif</span>
  102. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;ni_globals.h&quot;</span>
  103. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;system.h&quot;</span>
  104. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;NetInfo/system_log.h&gt;</span>
  105. #<span class="enscript-reference">define</span> <span class="enscript-variable-name">KERNEL_PRIVATE</span>
  106. #<span class="enscript-reference">include</span> <span class="enscript-string">&lt;dev/kmreg_com.h&gt;</span>
  107. #<span class="enscript-reference">undef</span> <span class="enscript-variable-name">KERNEL_PRIVATE</span>
  108. #<span class="enscript-reference">define</span> <span class="enscript-variable-name">MAXLINE</span> 4096
  109. #<span class="enscript-reference">define</span> <span class="enscript-variable-name">STRING_TABLE</span> <span class="enscript-string">&quot;NetInfo&quot;</span>
  110. <span class="enscript-type">static</span> <span class="enscript-type">const</span> <span class="enscript-type">char</span> SEARCH_MESSAGE[] =
  111. <span class="enscript-string">&quot;\\nStill searching for parent network administration (NetInfo) &quot;</span>
  112. <span class="enscript-string">&quot;server.\\nPlease wait, or press 'c' to continue without network &quot;</span>
  113. <span class="enscript-string">&quot;user accounts.\\n\\nSee your system administrator if you need help.\\n&quot;</span>;
  114. <span class="enscript-type">static</span> <span class="enscript-type">const</span> <span class="enscript-type">char</span> MESSAGE[] =
  115. <span class="enscript-string">&quot;\nStill searching for parent network administration (NetInfo) &quot;</span>
  116. <span class="enscript-string">&quot;server.\nPlease wait, or press 'c' to continue without network &quot;</span>
  117. <span class="enscript-string">&quot;user accounts.\n\nSee your system administrator if you need help.\n&quot;</span>;
  118. <span class="enscript-type">static</span> <span class="enscript-type">int</span> aborted = 0;
  119. <span class="enscript-type">static</span> <span class="enscript-type">int</span> console;
  120. <span class="enscript-type">static</span> <span class="enscript-type">int</span> console_flags;
  121. <span class="enscript-type">static</span> <span class="enscript-type">struct</span> sgttyb console_sg;
  122. <span class="enscript-type">static</span> <span class="enscript-type">enum</span> {
  123. ALERT_FRESH,
  124. ALERT_OPENED,
  125. ALERT_PRINTED,
  126. ALERT_CLOSED
  127. } alert_state = ALERT_CLOSED;
  128. <span class="enscript-comment">/*
  129. * Enable (or disable) alerts
  130. */</span>
  131. <span class="enscript-type">void</span>
  132. <span class="enscript-function-name">alert_enable</span>(<span class="enscript-type">int</span> enable)
  133. {
  134. <span class="enscript-keyword">if</span> (enable) alert_state = ALERT_FRESH;
  135. <span class="enscript-keyword">else</span> alert_state = ALERT_CLOSED;
  136. }
  137. <span class="enscript-comment">/*
  138. * Did the user abort the alert?
  139. */</span>
  140. <span class="enscript-type">int</span>
  141. <span class="enscript-function-name">alert_aborted</span>(<span class="enscript-type">void</span>)
  142. {
  143. <span class="enscript-keyword">return</span> (aborted);
  144. }
  145. <span class="enscript-comment">/*
  146. * Close an alert
  147. */</span>
  148. <span class="enscript-type">void</span>
  149. <span class="enscript-function-name">alert_close</span>(<span class="enscript-type">void</span>)
  150. {
  151. <span class="enscript-keyword">if</span> (alert_state != ALERT_PRINTED) <span class="enscript-keyword">return</span>;
  152. alert_state = ALERT_CLOSED;
  153. <span class="enscript-comment">/* Restore fd flags */</span>
  154. fcntl(console, F_SETFL, console_flags);
  155. <span class="enscript-comment">/* Restore terminal parameters */</span>
  156. ioctl(console, TIOCSETP, &amp;console_sg);
  157. <span class="enscript-comment">/* Remove the window */</span>
  158. ioctl(console, KMIOCRESTORE, 0);
  159. close(console);
  160. }
  161. <span class="enscript-comment">/*
  162. * We got a SIGIO. Handle it.
  163. */</span>
  164. <span class="enscript-type">static</span> <span class="enscript-type">void</span>
  165. <span class="enscript-function-name">handle_io</span>(<span class="enscript-type">int</span> ignored)
  166. {
  167. <span class="enscript-type">char</span> buf[512];
  168. <span class="enscript-type">char</span> *cp;
  169. <span class="enscript-type">int</span> nchars;
  170. <span class="enscript-keyword">while</span> ((nchars = read(console, (<span class="enscript-type">char</span> *)&amp;buf, <span class="enscript-keyword">sizeof</span>(buf))) &gt; 0)
  171. {
  172. cp = buf;
  173. <span class="enscript-keyword">while</span> (nchars--)
  174. {
  175. <span class="enscript-keyword">if</span> ((*cp == <span class="enscript-string">'c'</span>) || (*cp == <span class="enscript-string">'C'</span>))
  176. {
  177. system_log(LOG_DEBUG, <span class="enscript-string">&quot;Binding aborted&quot;</span>);
  178. aborted = 1;
  179. alert_close();
  180. <span class="enscript-keyword">return</span>;
  181. }
  182. cp++;
  183. }
  184. }
  185. <span class="enscript-keyword">if</span> (errno != EWOULDBLOCK) alert_close();
  186. }
  187. <span class="enscript-comment">/*
  188. * Open an alert
  189. */</span>
  190. <span class="enscript-type">void</span>
  191. <span class="enscript-function-name">alert_open</span>(<span class="enscript-type">const</span> <span class="enscript-type">char</span> *language)
  192. {
  193. <span class="enscript-type">struct</span> sgttyb sg;
  194. FILE *fp;
  195. <span class="enscript-type">char</span> filename[MAXPATHLEN + 1];
  196. <span class="enscript-type">char</span> buf[MAXLINE];
  197. <span class="enscript-type">char</span> outmsg[MAXLINE];
  198. <span class="enscript-type">int</span> i, j, len;
  199. <span class="enscript-keyword">if</span> (alert_state != ALERT_FRESH) <span class="enscript-keyword">return</span>;
  200. alert_state = ALERT_OPENED;
  201. <span class="enscript-comment">/* Open up the console */</span>
  202. <span class="enscript-keyword">if</span> ((console = open(_PATH_CONSOLE, (O_RDWR|O_ALERT), 0)) &lt; 0)
  203. {
  204. system_log(LOG_ERR, <span class="enscript-string">&quot;console open failed: %s&quot;</span>, strerror(errno));
  205. aborted = 1;
  206. <span class="enscript-keyword">return</span>;
  207. }
  208. <span class="enscript-comment">/* Flush any existing input */</span>
  209. ioctl(console, TIOCFLUSH, FREAD);
  210. <span class="enscript-comment">/* Set it up to interrupt on input */</span>
  211. <span class="enscript-keyword">if</span> ((console_flags = fcntl(console, F_GETFL, 0)) == -1)
  212. {
  213. system_log(LOG_ERR, <span class="enscript-string">&quot;console F_GETFL fcntl failed: %s&quot;</span>,
  214. strerror(errno));
  215. aborted = 1;
  216. close(console);
  217. <span class="enscript-keyword">return</span>;
  218. }
  219. <span class="enscript-keyword">if</span> (fcntl(console, F_SETFL, (console_flags|FASYNC|FNDELAY)) == -1)
  220. {
  221. system_log(LOG_ERR, <span class="enscript-string">&quot;console F_SETFL fcntl failed: %s&quot;</span>,
  222. strerror(errno));
  223. aborted = 1;
  224. close(console);
  225. <span class="enscript-keyword">return</span>;
  226. }
  227. signal(SIGIO, handle_io);
  228. <span class="enscript-comment">/* Put it in CBREAK mode */</span>
  229. <span class="enscript-keyword">if</span> (ioctl(console, TIOCGETP, &amp;sg) == -1)
  230. {
  231. system_log(LOG_ERR, <span class="enscript-string">&quot;console TIOCGETP ioctl failed: %s&quot;</span>,
  232. strerror(errno));
  233. aborted = 1;
  234. close(console);
  235. <span class="enscript-keyword">return</span>;
  236. }
  237. console_sg = sg;
  238. sg.sg_flags |= CBREAK;
  239. sg.sg_flags &amp;= ~ECHO;
  240. <span class="enscript-keyword">if</span> (ioctl(console, TIOCSETP, &amp;sg) == -1)
  241. {
  242. system_log(LOG_ERR, <span class="enscript-string">&quot;console TIOCSETP ioctl failed: %s&quot;</span>,
  243. strerror(errno));
  244. aborted = 1;
  245. close(console);
  246. <span class="enscript-keyword">return</span>;
  247. }
  248. alert_state = ALERT_PRINTED;
  249. sprintf(filename, <span class="enscript-string">&quot;%s/%s.lproj/%s.strings&quot;</span>,
  250. BUNDLE_PATH, language, STRING_TABLE);
  251. len = strlen(MESSAGE);
  252. fp = fopen(filename, <span class="enscript-string">&quot;r&quot;</span>);
  253. <span class="enscript-keyword">if</span> (fp == NULL)
  254. {
  255. write(console, MESSAGE, len);
  256. <span class="enscript-keyword">return</span>;
  257. }
  258. <span class="enscript-keyword">while</span> (fgets(buf, MAXLINE, fp) != NULL)
  259. {
  260. <span class="enscript-keyword">if</span> (!strncmp(buf+1, SEARCH_MESSAGE, len))
  261. {
  262. <span class="enscript-keyword">for</span> (i = strlen(buf); ((buf[i] != <span class="enscript-string">'\&quot;'</span>) &amp;&amp; (i &gt; 0)); i--);
  263. <span class="enscript-keyword">if</span> (i &lt;= 0) <span class="enscript-keyword">break</span>;
  264. buf[i] = <span class="enscript-string">'\0'</span>;
  265. <span class="enscript-keyword">for</span> (i = strlen(SEARCH_MESSAGE) + 2; ((buf[i] != <span class="enscript-string">'\0'</span>) &amp;&amp; (buf[i] != <span class="enscript-string">'\&quot;'</span>)); i++);
  266. <span class="enscript-keyword">if</span> (buf[i] == <span class="enscript-string">'\0'</span>) <span class="enscript-keyword">break</span>;
  267. i++;
  268. j = 0;
  269. <span class="enscript-keyword">for</span> (; buf[i] != <span class="enscript-string">'\0'</span>; i++)
  270. {
  271. <span class="enscript-keyword">if</span> ((buf[i] == <span class="enscript-string">'\\'</span>) &amp;&amp; (buf[i+1] == <span class="enscript-string">'n'</span>))
  272. {
  273. i++;
  274. outmsg[j++] = <span class="enscript-string">'\n'</span>;
  275. }
  276. <span class="enscript-keyword">else</span> outmsg[j++] = buf[i];
  277. }
  278. <span class="enscript-keyword">if</span> (j == 0) <span class="enscript-keyword">break</span>;
  279. fclose(fp);
  280. outmsg[j] = <span class="enscript-string">'\0'</span>;
  281. write(console, outmsg, j);
  282. <span class="enscript-keyword">return</span>;
  283. }
  284. }
  285. fclose(fp);
  286. write(console, MESSAGE, len);
  287. }
  288. #<span class="enscript-reference">endif</span> <span class="enscript-variable-name">NO_CONSOLE_SUPPORT</span>
  289. </pre>
  290. <hr />
  291. </body></html>