/aminet/comm/term/term/Extras/Source/SendText.c

https://repo.or.cz/AROS-Contrib.git · C · 603 lines · 347 code · 161 blank · 95 comment · 84 complexity · 69a5b51ed78881cb17db778461e37252 MD5 · raw file

  1. /*
  2. ** SendText.c
  3. **
  4. ** Text sending support routines
  5. **
  6. ** Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. ** All Rights Reserved
  8. **
  9. ** :ts=4
  10. */
  11. #ifndef _GLOBAL_H
  12. #include "Global.h"
  13. #endif
  14. /* MatchPrompt():
  15. *
  16. * Search incoming data stream for a match.
  17. */
  18. BOOL
  19. MatchPrompt(STRPTR Data,LONG Size,STRPTR Prompt,LONG PromptLen)
  20. {
  21. STATIC LONG WaitCount,PromptCount;
  22. if(!Data)
  23. WaitCount = PromptCount = 0;
  24. else
  25. {
  26. UBYTE c,Mask;
  27. if(Config->SerialConfig->StripBit8)
  28. Mask = 0x7F;
  29. else
  30. Mask = 0xFF;
  31. do
  32. {
  33. if(c = ((*Data++) & Mask))
  34. {
  35. BOOL MatchMade;
  36. do
  37. {
  38. MatchMade = FALSE;
  39. if(PromptCount == WaitCount)
  40. {
  41. if(c == Prompt[WaitCount] & Mask)
  42. {
  43. MatchMade = TRUE;
  44. if(PromptLen == ++PromptCount)
  45. return(TRUE);
  46. }
  47. }
  48. if(MatchMade)
  49. WaitCount++;
  50. else
  51. {
  52. if(WaitCount)
  53. {
  54. WaitCount = 0;
  55. PromptCount = 0;
  56. }
  57. else
  58. break;
  59. }
  60. }
  61. while(!WaitCount);
  62. }
  63. }
  64. while(--Size);
  65. }
  66. return(FALSE);
  67. }
  68. /* LocalWaitForPrompt(STRPTR Prompt,LONG PromptLen):
  69. *
  70. * Scan the incoming data flow for a certain string.
  71. */
  72. STATIC BOOL
  73. LocalWaitForPrompt(STRPTR Prompt,LONG PromptLen)
  74. {
  75. ULONG Signals;
  76. BOOL GotIt;
  77. MatchPrompt(NULL,0,NULL,0);
  78. /* Start the timer. */
  79. StartTime(Config->ClipConfig->SendTimeout / 100,(Config->ClipConfig->SendTimeout % 100) * 10000);
  80. /* Lock the current xOFF state and clear the xOFF flag. */
  81. Lock_xOFF();
  82. Clear_xOFF();
  83. GotIt = FALSE;
  84. /* Loop until the prompt is found or the timer elapses. */
  85. do
  86. {
  87. Signals = (*SerialWaitForData)(SIG_TIMER);
  88. if(Signals & SIG_SERIAL)
  89. {
  90. ULONG Length;
  91. /* Check how much data is available. */
  92. if(Length = (*SerialGetWaiting)())
  93. {
  94. /* Don't read more than the buffer will hold. */
  95. if(Length > SerialBufferSize / 2)
  96. Length = SerialBufferSize / 2;
  97. /* Read the data. */
  98. if(Length = (*SerialRead)(ReadBuffer,Length))
  99. {
  100. /* Got some more data. */
  101. BytesIn += Length;
  102. /* Translate the buffer contents if necessary. */
  103. if(Translate_CR_LF)
  104. Length = (*Translate_CR_LF)(ReadBuffer,Length);
  105. else
  106. Length = 1;
  107. if(Length)
  108. {
  109. ConProcess(ReadBuffer,Length);
  110. /* Check if this is it. */
  111. if(MatchPrompt(ReadBuffer,Length,Prompt,PromptLen))
  112. GotIt = TRUE;
  113. }
  114. }
  115. }
  116. }
  117. /* Stop when the bell rings. */
  118. if(Signals & SIG_TIMER)
  119. break;
  120. }
  121. while(!GotIt);
  122. /* Stop the timer. */
  123. StopTime();
  124. Unlock_xOFF();
  125. return(GotIt);
  126. }
  127. /* SendLinePrompt(STRPTR Line,LONG Len):
  128. *
  129. * Send text line, wait for prompt.
  130. */
  131. BOOL
  132. SendLinePrompt(STRPTR Line,LONG Len)
  133. {
  134. LONG i;
  135. if(Len == -1)
  136. Len = strlen(Line);
  137. while(Len)
  138. {
  139. i = 0;
  140. while(i < Len && Line[i] != '\r')
  141. i++;
  142. if(Line[i] == '\r')
  143. {
  144. i++;
  145. SerWrite(Line,i);
  146. if(!LocalWaitForPrompt(SendPrompt,SendPromptLen))
  147. return(FALSE);
  148. }
  149. else
  150. {
  151. if(i)
  152. SerWrite(Line,i);
  153. }
  154. Len -= i;
  155. Line += i;
  156. }
  157. return(TRUE);
  158. }
  159. /* SendLineSimple(STRPTR Line,LONG Len):
  160. *
  161. * Send a text line, no fancy features.
  162. */
  163. BOOL
  164. SendLineSimple(STRPTR Line,LONG Len)
  165. {
  166. if(Len == -1)
  167. Len = strlen(Line);
  168. SerWrite(Line,Len);
  169. return(TRUE);
  170. }
  171. /* SendLineDial(STRPTR Line,LONG Len):
  172. *
  173. * The SendLineSimple for the dialer and init commands.
  174. */
  175. BOOL
  176. SendLineDial(STRPTR Line,LONG Len)
  177. {
  178. if(Len == -1)
  179. Len = strlen(Line);
  180. if(Config->ModemConfig->CharSendDelay > 0)
  181. {
  182. ULONG Seconds = Config->ModemConfig->CharSendDelay / MILLION,
  183. Micros = Config->ModemConfig->CharSendDelay % MILLION;
  184. while(Len--)
  185. {
  186. SerWrite(Line++,1);
  187. DelayTime(Seconds,Micros);
  188. }
  189. }
  190. else
  191. SerWrite(Line,Len);
  192. return(TRUE);
  193. }
  194. /* SendLineDelay(STRPTR Line,LONG Len):
  195. *
  196. * Send a text line, include a delay where necessary.
  197. */
  198. BOOL
  199. SendLineDelay(STRPTR Line,LONG Len)
  200. {
  201. if(Len == -1)
  202. Len = strlen(Line);
  203. while(Len--)
  204. {
  205. SerWrite(Line,1);
  206. if(*Line == '\r')
  207. DelayTime(Config->ClipConfig->LineDelay / 100,(Config->ClipConfig->LineDelay % 100) * 10000);
  208. else
  209. DelayTime(Config->ClipConfig->CharDelay / 100,(Config->ClipConfig->CharDelay % 100) * 10000);
  210. Line++;
  211. }
  212. return(TRUE);
  213. }
  214. /* SendLineEcho(STRPTR Line,LONG Len):
  215. *
  216. * Send a text line, wait for single characters to be echoed.
  217. */
  218. BOOL
  219. SendLineEcho(STRPTR Line,LONG Len)
  220. {
  221. ULONG Signals;
  222. BOOL GotIt;
  223. if(Len == -1)
  224. Len = strlen(Line);
  225. /* Lock the current xOFF state and clear the xOFF flag. */
  226. Lock_xOFF();
  227. Clear_xOFF();
  228. while(Len--)
  229. {
  230. /* Send the next character. */
  231. SerWrite(Line,1);
  232. /* Start the timer. */
  233. StartTime(Config->ClipConfig->SendTimeout / 100,(Config->ClipConfig->SendTimeout % 100) * 10000);
  234. /* Loop until we got the character we wanted or the time elapses. */
  235. GotIt = FALSE;
  236. do
  237. {
  238. Signals = (*SerialWaitForData)(SIG_TIMER);
  239. /* Did we receive new data? */
  240. if(Signals & SIG_SERIAL)
  241. {
  242. /* Is there any character waiting? */
  243. if((*SerialGetWaiting)())
  244. {
  245. /* Read that character. */
  246. if((*SerialRead)(ReadBuffer,1))
  247. {
  248. ULONG Length;
  249. BytesIn++;
  250. /* Check if the character needs translation. */
  251. if(Translate_CR_LF)
  252. Length = (*Translate_CR_LF)(ReadBuffer,1);
  253. else
  254. Length = 1;
  255. if(Length)
  256. ConProcess(ReadBuffer,Length);
  257. /* Is that it? */
  258. if(Length == 1 && ReadBuffer[0] == Line[0])
  259. GotIt = TRUE;
  260. }
  261. }
  262. }
  263. /* Did the bell ring? */
  264. if(Signals & SIG_TIMER)
  265. break;
  266. }
  267. while(!GotIt);
  268. /* Stop the timer. */
  269. StopTime();
  270. /* Check if we got the echo. If not, return an error. */
  271. if(!GotIt)
  272. {
  273. Unlock_xOFF();
  274. return(FALSE);
  275. }
  276. Line++;
  277. }
  278. Unlock_xOFF();
  279. return(TRUE);
  280. }
  281. /* SendLineAnyEcho(STRPTR Line,LONG Len):
  282. *
  283. * Send a text line, wait for characters to be echoed.
  284. */
  285. BOOL
  286. SendLineAnyEcho(STRPTR Line,LONG Len)
  287. {
  288. ULONG Signals;
  289. BOOL GotIt;
  290. if(Len == -1)
  291. Len = strlen(Line);
  292. /* Lock the current xOFF state and clear the xOFF flag. */
  293. Lock_xOFF();
  294. Clear_xOFF();
  295. while(Len--)
  296. {
  297. /* Send the next character. */
  298. SerWrite(Line,1);
  299. /* Start the timer. */
  300. StartTime(Config->ClipConfig->SendTimeout / 100,(Config->ClipConfig->SendTimeout % 100) * 10000);
  301. /* Loop until we got the character we wanted or the time elapses. */
  302. GotIt = FALSE;
  303. do
  304. {
  305. Signals = (*SerialWaitForData)(SIG_TIMER);
  306. /* Did we receive new data? */
  307. if(Signals & SIG_SERIAL)
  308. {
  309. /* Is there any character waiting? */
  310. if((*SerialGetWaiting)())
  311. {
  312. /* Read that character. */
  313. if((*SerialRead)(ReadBuffer,1))
  314. {
  315. LONG Length;
  316. BytesIn++;
  317. if(Translate_CR_LF)
  318. Length = (*Translate_CR_LF)(ReadBuffer,1);
  319. else
  320. Length = 1;
  321. if(Length)
  322. ConProcess(ReadBuffer,Length);
  323. GotIt = TRUE;
  324. }
  325. }
  326. }
  327. /* Did the bell ring? */
  328. if(Signals & SIG_TIMER)
  329. break;
  330. }
  331. while(!GotIt);
  332. /* Stop the timer. */
  333. StopTime();
  334. /* Check if we got the echo. If not, return an error. */
  335. if(!GotIt)
  336. {
  337. Unlock_xOFF();
  338. return(FALSE);
  339. }
  340. Line++;
  341. }
  342. Unlock_xOFF();
  343. return(TRUE);
  344. }
  345. /* SendLineKeyDelay(STRPTR Line,LONG Len):
  346. *
  347. * Send a text line, include keyboard delay pauses between characters.
  348. */
  349. BOOL
  350. SendLineKeyDelay(STRPTR Line,LONG Len)
  351. {
  352. struct Preferences Prefs;
  353. if(Len == -1)
  354. Len = strlen(Line);
  355. /* Get current key repeat delay. */
  356. GetPrefs(&Prefs,offsetof(struct Preferences,KeyRptDelay));
  357. /* Any delay specified at all? */
  358. if(Prefs.KeyRptSpeed.tv_secs || Prefs.KeyRptSpeed.tv_micro)
  359. {
  360. while(Len--)
  361. {
  362. SerWrite(Line++,1);
  363. if(Len)
  364. DelayTime(Prefs.KeyRptSpeed.tv_secs,Prefs.KeyRptSpeed.tv_micro);
  365. }
  366. }
  367. else
  368. SerWrite(Line,Len);
  369. return(TRUE);
  370. }
  371. /* ChangeSendLine(SENDLINE NewSendLine):
  372. *
  373. * Change the routine that sends full lines of text.
  374. */
  375. SENDLINE
  376. ChangeSendLine(SENDLINE NewSendLine)
  377. {
  378. SENDLINE OldSendLine;
  379. OldSendLine = SendLine;
  380. SendLine = NewSendLine;
  381. return(OldSendLine);
  382. }
  383. /* RestoreSendLine():
  384. *
  385. * Restore the SendLine pointer to its original routine.
  386. */
  387. VOID
  388. RestoreSendLine(SENDLINE ChangedSendLine,SENDLINE OriginalSendLine)
  389. {
  390. if(SendLine == ChangedSendLine)
  391. SendLine = OriginalSendLine;
  392. }
  393. /* SendSetup():
  394. *
  395. * Choose the right routine for the text line output job.
  396. */
  397. VOID
  398. SendSetup()
  399. {
  400. /* Prepare the prompt string. */
  401. if(Config->ClipConfig->LinePrompt[0])
  402. SendPromptLen = TranslateString(Config->ClipConfig->LinePrompt,SendPrompt);
  403. else
  404. {
  405. SendPrompt[0] = 0;
  406. SendPromptLen = 0;
  407. }
  408. /* Pick the line send routine. */
  409. switch(Config->ClipConfig->PacingMode)
  410. {
  411. case PACE_DIRECT:
  412. SendLine = (SENDLINE)SendLineSimple;
  413. break;
  414. case PACE_ECHO:
  415. if(Config->ClipConfig->SendTimeout)
  416. SendLine = (SENDLINE)SendLineEcho;
  417. else
  418. SendLine = (SENDLINE)SendLineSimple;
  419. break;
  420. case PACE_ANYECHO:
  421. if(Config->ClipConfig->SendTimeout)
  422. SendLine = (SENDLINE)SendLineAnyEcho;
  423. else
  424. SendLine = (SENDLINE)SendLineSimple;
  425. break;
  426. case PACE_PROMPT:
  427. if(Config->ClipConfig->SendTimeout)
  428. SendLine = (SENDLINE)SendLinePrompt;
  429. else
  430. SendLine = (SENDLINE)SendLineSimple;
  431. break;
  432. case PACE_DELAY:
  433. if(Config->ClipConfig->LineDelay || Config->ClipConfig->CharDelay)
  434. SendLine = (SENDLINE)SendLineDelay;
  435. else
  436. SendLine = (SENDLINE)SendLineSimple;
  437. break;
  438. case PACE_KEYBOARD:
  439. SendLine = (SENDLINE)SendLineKeyDelay;
  440. break;
  441. }
  442. }