hdbintf.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916
  1. #if defined(SHARE_DEBUG)
  2. #undef LOG_UNGETTY
  3. #undef LOG_HDBDIAL
  4. #define LOG_UNGETTY
  5. #define LOG_HDBDIAL
  6. #endif
  7. /* #define ILLOGICAL *//* has holes - does not work */
  8. /*+-------------------------------------------------------------------------
  9. hdbintf.c - HDB UUCP database and /etc/utmp interface routines
  10. wht@wht.net
  11. Defined functions:
  12. _ungetty_return_line(line)
  13. add_to_ungetty_list(line)
  14. dialcodes_translate(phone)
  15. display_ungetty_list()
  16. dvtype_match(typespec, dvtype)
  17. enddlent()
  18. enddvent()
  19. getdlent()
  20. getdlentname(name)
  21. getdvbaud(baud)
  22. getdvent()
  23. getdvline(line)
  24. getdvtype(type)
  25. hdb_choose_Any(baud)
  26. hdb_choose_Device(type, baud)
  27. hdb_dial(presult)
  28. hdb_dial_error_text(errcode)
  29. hdb_init()
  30. in_ungetty_list(line)
  31. malformed_Devices_entry(text, ntokens, tokens)
  32. remove_from_ungetty_list(line)
  33. report_initial_line()
  34. reserve_line(line)
  35. setdlent()
  36. setdvent()
  37. strip_phone_num(sptr)
  38. ungetty_get_line(line)
  39. ungetty_return_all_but(line)
  40. ungetty_return_line(line, cause)
  41. Date: Fri, 23 Aug 91 18:30:06 +0300 (MSD)
  42. From: ache@hq.demos.su (Andrew A. Chernov, canton Uri's citizen)
  43. 1) HDB dialers may return connect speed as return code (!= 0)
  44. 2) Using HDB Dialcodes file for phone numbers translation now
  45. (\D,\T escape sequence)
  46. Many [Nobel physics] prizes have been given to people for telling us
  47. the universe is not as simple as we thought it was. -Stephen Hawking in
  48. A Brief History of Time In computing, there are no such prizes. -me
  49. --------------------------------------------------------------------------*/
  50. /*+:EDITS:*/
  51. /*:04-26-2000-11:16-wht@bob-RELEASE 4.42 */
  52. /*:11-16-1997-22:15-wht@kepler-regexp_compile changed shape */
  53. /*:01-24-1997-02:37-wht@yuriatin-SOURCE RELEASE 4.00 */
  54. /*:09-11-1996-20:00-wht@yuriatin-3.48-major telnet,curses,structural overhaul */
  55. /*:08-11-1996-02:10-wht@kepler-rename ecu_log_event to logevent */
  56. /*:12-06-1995-13:30-wht@n4hgf-termecu w/errno -1 consideration */
  57. /*:12-03-1995-19:57-wht@gyro-use Setuid */
  58. /*:11-23-1995-11:20-wht@kepler-source control 3.37 for tsx-11 */
  59. /*:11-14-1995-10:23-wht@kepler-3.37.80-source control point: SOCKETS */
  60. /*:11-03-1995-16:54-wht@wwtp1-use CFG_TelnetOption */
  61. /*:09-17-1995-16:28-wht@kepler-remove obsolete #if 0 code */
  62. /*:06-14-1995-19:16-wht@n4hgf-if appropriate, setuid before fork dial prog */
  63. /*:06-12-1995-15:25-wht@n4hgf-do not ungetty lines owned by user */
  64. /*:06-12-1995-15:24-wht@n4hgf-if uucp euid, do not ungetty uucp-owned lines */
  65. /*:05-11-1995-15:55-wht@n4hgf-ck_sigint fools optimizing compilers */
  66. /*:04-01-1995-18:41-wht@n4hgf-configure use of ungetty on non-Devices lines */
  67. /*:04-01-1995-17:48-wht@n4hgf-change hdb_choose_Device current line checking */
  68. /*:03-21-1995-14:45-wht@n4hgf-expresp_verbosity now set to proc_trace */
  69. /*:01-15-1995-02:49-wht@gyro-_ungetty_return_line might have been unused */
  70. /*:01-12-1995-15:20-wht@n4hgf-apply Andrew Chernov 8-bit clean+FreeBSD patch */
  71. /*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  72. /*:01-23-1994-14:48-wht@n4hgf-do not die on illogical utmp status, just flunk */
  73. /*:01-04-1994-06:31-wht@n4hgf-last_Speed_result improvement */
  74. /*:12-02-1993-15:30-wht@n4hgf-hbd_choose_Any could not handle DIALOUT */
  75. /*:08-30-1993-12:04-wht@n4hgf-with SCO companion lines, skip bad ecuungetty */
  76. /*:08-16-1993-17:19-wht@n4hgf-aid choose debug with report_initial_line() */
  77. /*:05-30-1993-15:25-wht@n4hgf-strip RC_ENABLED from wait_status */
  78. /*:05-29-1993-20:21-wht@n4hgf-change linst_err_text to LINST_text */
  79. /*:05-29-1993-20:18-wht@n4hgf-change ugstat_text to UG_text */
  80. /*:05-29-1993-20:13-wht@n4hgf-beef up debug log events */
  81. /*:03-27-1993-17:45-wht@n4hgf-SVR4 cc complained about strlen <= constant */
  82. /*:02-27-1993-13:55-wht@n4hgf-dialer prog in CFG_HdbLibDir can have simple path */
  83. /*:12-20-1992-12:20-wht@n4hgf-add setdvent and setdlent */
  84. /*:12-20-1992-12:17-wht@n4hgf-add getdvtype */
  85. /*:09-14-1992-04:05-wht@n4hgf-rcvr process was not going away reliably */
  86. /*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  87. /*:09-10-1992-03:35-wht@n4hgf-change the way we flunk a line=="-" */
  88. /*:09-04-1992-19:08-wht@n4hgf-harden Devices parsing */
  89. /*:08-29-1992-15:37-wht@n4hgf-absolutely prohibit /dev/tty fed to ecuungetty */
  90. /*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  91. /*:07-21-1992-17:20-wht@n4hgf-hdb_dial of "/=" type bug fixed */
  92. /*:07-19-1992-22:12-wht@n4hgf-move old check_utmp here+call it reserve_line */
  93. /*:07-19-1992-10:07-wht@n4hgf-add ungetty_return_all_but */
  94. /*:07-19-1992-09:11-wht@n4hgf-validate tty line name before ungetty get */
  95. /*:06-07-1992-17:05-wht@n4hgf-lock tty before ungetty get */
  96. /*:05-13-1992-13:27-wht@n4hgf-active_pde use */
  97. /*:05-13-1992-10:30-cma@ifsbd-Add bit rate checking to hdb_dial function */
  98. /*:05-04-1992-04:45-wht@n4hgf-wrong sense of strcmp in ,M test for SVR4 */
  99. /*:04-28-1992-03:29-wht@n4hgf-more fixes for abend due to line problems */
  100. /*:04-27-1992-20:02-wht@n4hgf-add ecuungetty error reporting */
  101. /*:04-25-1992-13:02-wht@n4hgf-some exits from hdb_choose_Any omitted enddvent */
  102. /*:04-24-1992-21:59-wht@n4hgf-more SCO tty name normalizing */
  103. /*:04-19-1992-03:21-jhpb@sarto.budd-lake.nj.us-3.18.37 has ESIX SVR4 */
  104. /*:01-18-1992-13:29-root@n4hgf-use proc_trace value for expresp_verbosity */
  105. /*:11-15-1991-04:02-wht@n4hgf-SCO tty naming now observed in getdvline */
  106. /*:09-01-1991-16:20-wht@n4hgf2-generalize HDB configuration files location */
  107. /*:09-01-1991-02:27-wht@n4hgf2-dialer gets file name instead of "ECUdial" */
  108. /*:08-25-1991-13:07-wht@n4hgf-apply ache@hq.demos.su patches */
  109. /*:08-10-1991-17:39-wht@n4hgf-US_WEGOTIT handling */
  110. /*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  111. /*:06-02-1991-17:42-wht@n4hgf-add getdvtype */
  112. /*:06-02-1991-17:27-wht@n4hgf-hdb_choose_Device + move hdb_choose_Any here */
  113. /*:10-16-1990-20:43-wht@n4hgf-add SHARE_DEBUG */
  114. /*:09-19-1990-19:36-wht@n4hgf-logevent now gets pid for log from caller */
  115. /*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  116. #include "ecu.h"
  117. #include "ecupde.h"
  118. #include "esd.h"
  119. #include "var.h"
  120. #include "termecu.h"
  121. #include "utmpstatus.h"
  122. #include "ecuungetty.h"
  123. #include "dvent.h"
  124. #include "dlent.h"
  125. #include "dialprog.h"
  126. #include <errno.h>
  127. #include <utmp.h>
  128. char *arg_token();
  129. char *skip_ld_break();
  130. char *dialcodes_translate();
  131. char *strip_phone_num();
  132. char *US_text();
  133. char *LINST_text();
  134. #if defined(CFG_UseUngetty)
  135. char *bamboozle();
  136. #endif
  137. extern char kbdintr; /* current input INTR */
  138. extern UINT32 colors_current;
  139. extern int expresp_verbosity;
  140. extern char last_Speed_result[];
  141. int there_is_hdb_on_this_machine = 0;
  142. char *hdblibdir = CFG_HdbLibDir; /* system independent location */
  143. char *Devices_file = "/usr/lib/uucp/Devices"; /* overriden by config */
  144. char *Dialers_file = "/usr/lib/uucp/Dialers";
  145. char *Dialcodes_file = "/usr/lib/uucp/Dialcodes";
  146. uchar last_ugstat = 0;
  147. #define UNGETTY_LIST_MAX 3
  148. char *ungetty_list[UNGETTY_LIST_MAX];
  149. static FILE *fpdv = (FILE *) 0;
  150. static FILE *fpdl = (FILE *) 0;
  151. /*+-------------------------------------------------------------------------
  152. display_ungetty_list() - display ungetty list with pputs()
  153. --------------------------------------------------------------------------*/
  154. #if defined(CFG_UseUngetty)
  155. void
  156. display_ungetty_list()
  157. {
  158. int itmp;
  159. int found_one = 0;
  160. for (itmp = 0; itmp < UNGETTY_LIST_MAX; itmp++)
  161. {
  162. if (*ungetty_list[itmp])
  163. {
  164. found_one = 1;
  165. break;
  166. }
  167. }
  168. if (!found_one)
  169. {
  170. pputs("No lines acquired by ecuungetty\n");
  171. return;
  172. }
  173. pputs("Acquired by ecuungetty: ");
  174. for (itmp = 0; itmp < UNGETTY_LIST_MAX; itmp++)
  175. {
  176. if (*ungetty_list[itmp])
  177. {
  178. pputs(ungetty_list[itmp]);
  179. pputs(" ");
  180. }
  181. }
  182. pputs("\n");
  183. } /* end of display_ungetty_list */
  184. #endif /* defined(CFG_UseUngetty) */
  185. /*+-------------------------------------------------------------------------
  186. in_ungetty_list(line) - check for line present in ungetty list
  187. --------------------------------------------------------------------------*/
  188. #if defined(CFG_UseUngetty)
  189. int
  190. in_ungetty_list(line)
  191. char *line;
  192. {
  193. int itmp;
  194. for (itmp = 0; itmp < UNGETTY_LIST_MAX; itmp++)
  195. {
  196. if (!strcmp(line, ungetty_list[itmp]))
  197. return (1);
  198. }
  199. return (0);
  200. } /* end of in_ungetty_list */
  201. #endif /* defined(CFG_UseUngetty) */
  202. /*+-------------------------------------------------------------------------
  203. add_to_ungetty_list(line) - add line to ungetty list
  204. --------------------------------------------------------------------------*/
  205. #if defined(CFG_UseUngetty)
  206. void
  207. add_to_ungetty_list(line)
  208. char *line;
  209. {
  210. int itmp;
  211. char *lptr;
  212. if (in_ungetty_list(line))
  213. return;
  214. for (itmp = 0; itmp < UNGETTY_LIST_MAX; itmp++)
  215. {
  216. if (!*(lptr = ungetty_list[itmp]))
  217. {
  218. strcpy(lptr, line);
  219. return;
  220. }
  221. }
  222. logevent(getpid(), "UNGETTY_LIST OVERFLOW");
  223. errno = -1;
  224. termecu(TERMECU_LOGIC_ERROR);
  225. /* NOTREACHED */
  226. } /* end of add_to_ungetty_list */
  227. #endif /* defined(CFG_UseUngetty) */
  228. /*+-------------------------------------------------------------------------
  229. remove_from_ungetty_list(line) - remove line from ungetty list
  230. --------------------------------------------------------------------------*/
  231. #if defined(CFG_UseUngetty)
  232. void
  233. remove_from_ungetty_list(line)
  234. char *line;
  235. {
  236. int itmp;
  237. char *lptr;
  238. for (itmp = 0; itmp < UNGETTY_LIST_MAX; itmp++)
  239. {
  240. if (!strcmp((lptr = ungetty_list[itmp]), line))
  241. {
  242. *lptr = 0;
  243. return;
  244. }
  245. }
  246. #ifdef CHOOSE_DEBUG
  247. vlogevent(getpid(), "REMOVE_FROM_UNGETTY_LIST FAILED FOR %s", line);
  248. #endif
  249. } /* end of remove_from_ungetty_list */
  250. #endif /* defined(CFG_UseUngetty) */
  251. /*+-------------------------------------------------------------------------
  252. ungetty_get_line(line) - acquire a line through ecuungetty protocol
  253. --------------------------------------------------------------------------*/
  254. enum linst
  255. ungetty_get_line(line)
  256. char *line;
  257. {
  258. #if !defined(CFG_UseUngetty)
  259. line = 0; /* -Wunused */
  260. return (LINST_OK);
  261. #else
  262. int itmp;
  263. int linst;
  264. int rtn = 0;
  265. int we_locked = 0;
  266. int ungetty_pid;
  267. CFG_SigType(*original_sighdlr) ();
  268. int wait_status;
  269. char ungetty[128];
  270. char bamboozlement[20];
  271. struct stat st;
  272. #if !defined(CFG_UngettyAllLines)
  273. struct dvent *dv = 0;
  274. #endif /* !CFG_UngettyAllLines */
  275. if (shm->Ltelnet)
  276. return (0);
  277. /*
  278. * quick check - ecuungetty does a much better job
  279. */
  280. if (!strcmp(line, "/dev/tty")) /* some keep getting /dev/tty chown'd! */
  281. return (LINST_INVALID);
  282. if (stat(line, &st))
  283. {
  284. if (errno == ENOENT)
  285. return (LINST_NODEV);
  286. return (LINST_OPNFAIL);
  287. }
  288. if ((st.st_mode & S_IFMT) != S_IFCHR)
  289. return (LINST_NOTCHR);
  290. if (st.st_uid == uid)
  291. return (0);
  292. if (setuid_uucp && (st.st_uid == uid_uucp))
  293. return (0);
  294. if (!there_is_hdb_on_this_machine)
  295. return (0);
  296. if (in_ungetty_list(line))
  297. return (0);
  298. /*
  299. * if device is not listed in devices, we do not want to change the
  300. * device ownership/mode
  301. */
  302. #if !defined(CFG_UngettyAllLines)
  303. enddvent(); /* should not be necessary -- but be safe */
  304. dv = getdvline(line + 5);
  305. enddvent();
  306. if (!dv)
  307. return (0);
  308. #endif /* !CFG_UngettyAllLines */
  309. /*
  310. * lock line before ecuungetty call
  311. */
  312. if ((linst = lock_tty(line)) && (linst != LINST_WEGOTIT))
  313. return (linst);
  314. we_locked = (!(int)itmp);
  315. sprintf(ungetty, "%s/ecuungetty", CFG_EcuLibDir);
  316. strcpy(bamboozlement, bamboozle(getpid()));
  317. if (access(ungetty, 1))
  318. {
  319. pperror(ungetty);
  320. rtn = LINST_ENABLED;
  321. goto FUNC_RETURN;
  322. }
  323. original_sighdlr = signal(SIGCLD, SIG_DFL);
  324. if (!(ungetty_pid = smart_fork()))
  325. {
  326. execl(ungetty, "ungetty", line, bamboozlement, (char *)0);
  327. _exit(UGE_DNE); /* did not execute */
  328. }
  329. while (((itmp = wait(&wait_status)) != ungetty_pid) && (itmp != -1))
  330. ;
  331. signal(SIGCLD, original_sighdlr);
  332. if (wait_status & 0xFF)
  333. last_ugstat = UGE_BOMB;
  334. else
  335. last_ugstat = (uchar) (wait_status >> 8);
  336. switch (last_ugstat)
  337. {
  338. case UG_NOTENAB: /* line acquired: not enabled */
  339. break;
  340. case UG_RESTART: /* line acquired: need ungetty -r when done */
  341. #if defined(LOG_UNGETTY)
  342. vlogevent(getpid(), "UNGETTY acquired %s", shm->Lline);
  343. #endif
  344. add_to_ungetty_list(line);
  345. break;
  346. case UG_FAIL: /* line in use */
  347. rtn = LINST_ENABLED_IN_USE;
  348. break;
  349. default:
  350. vlogevent(getpid(), "UNGETTY unknown status 0x%04x: %s",
  351. wait_status, UG_text(last_ugstat));
  352. rtn = (last_ugstat == UGE_BOMB)
  353. ? LINST_ECUUNGETTY2 : LINST_ECUUNGETTY;
  354. break;
  355. }
  356. FUNC_RETURN:
  357. if (rtn && we_locked)
  358. unlock_tty(line);
  359. return (rtn);
  360. #endif /* !defined(CFG_UseUngetty) */
  361. } /* end of ungetty_get_line */
  362. /*+-------------------------------------------------------------------------
  363. reserve_line(line)
  364. 'line' is "/dev/ttyxx"-style
  365. return 0 if line reserved, else LINST code
  366. --------------------------------------------------------------------------*/
  367. enum linst
  368. reserve_line(line)
  369. char *line;
  370. {
  371. enum utmp_status utmpst;
  372. enum linst linst = LINST_OK;
  373. #ifdef CFG_TelnetOption
  374. if (shm->Ltelnet)
  375. return (LINST_OK);
  376. #endif
  377. switch (utmpst = utmp_status(line))
  378. {
  379. case US_DIALOUT: /* enabled for login, currently dialout */
  380. linst = LINST_DIALOUT_IN_USE;
  381. break;
  382. case US_LOGGEDIN: /* enabled for login, in use */
  383. linst = LINST_ENABLED_IN_USE;
  384. break;
  385. case US_NOTFOUND: /* not in utmp, or getty dead */
  386. linst = LINST_OK;
  387. break;
  388. case US_WEGOTIT: /* we own the line */
  389. linst = LINST_WEGOTIT; /* not really an error */
  390. break;
  391. case US_LOGIN: /* enabled for login, idle */
  392. linst = ungetty_get_line(line);
  393. break;
  394. default:
  395. #if defined(ILLOGICAL)
  396. ff(se, "reserve_line illogical utmp status %s for %s\r\n",
  397. US_text(utmpst), line);
  398. errno = -1;
  399. termecu(TERMECU_LOGIC_ERROR);
  400. #else
  401. break;
  402. #endif
  403. }
  404. #if defined(CHOOSE_DEBUG)
  405. vlogevent(getpid(), "RESERVE %s '%s'", line, LINST_text(linst));
  406. #endif
  407. return (linst);
  408. } /* end of reserve_line */
  409. /*+-------------------------------------------------------------------------
  410. _ungetty_return_line(line) - return line to "getty" status
  411. --------------------------------------------------------------------------*/
  412. #if defined(CFG_UseUngetty)
  413. static void
  414. _ungetty_return_line(line)
  415. char *line;
  416. {
  417. int ungetty_pid;
  418. int itmp;
  419. CFG_SigType(*original_sighdlr) ();
  420. int wait_status = 0xDEAD;
  421. char ungetty[128];
  422. char bamboozlement[20];
  423. #if !defined(CFG_UngettyAllLines)
  424. struct dvent *dv = 0;
  425. #endif /* !CFG_UngettyAllLines */
  426. if (shm->Ltelnet)
  427. return;
  428. if (!there_is_hdb_on_this_machine)
  429. return;
  430. if (!in_ungetty_list(line))
  431. return;
  432. /*
  433. * if device is not listed in Devices, we do not want to change the
  434. * device ownership/mode
  435. */
  436. #if !defined(CFG_UngettyAllLines)
  437. enddvent(); /* should not be necessary -- but be safe */
  438. dv = getdvline(line + 5);
  439. enddvent();
  440. if (!dv)
  441. return;
  442. #endif /* !CFG_UngettyAllLines */
  443. sprintf(ungetty, "%s/ecuungetty", CFG_EcuLibDir);
  444. strcpy(bamboozlement, bamboozle(getpid()));
  445. /* call ungetty to see if we need to switch to dialin */
  446. #ifdef NEVER /* if in_ungetty_list, trust we need to -r */
  447. if (access(ungetty, 1))
  448. {
  449. pperror(ungetty);
  450. return;
  451. }
  452. original_sighdlr = signal(SIGCLD, SIG_DFL);
  453. if ((ungetty_pid = smart_fork()) == 0)
  454. {
  455. execl(ungetty, "ungetty", "-t", line, bamboozlement, (char *)0);
  456. logevent(getppid(), "could not exec ecuungetty -t");
  457. _exit(UGE_DNE); /* did not execute */
  458. }
  459. while (((itmp = wait(&wait_status)) != ungetty_pid) &&
  460. (itmp != -1))
  461. ;
  462. signal(SIGCLD, original_sighdlr);
  463. #if defined(LOG_UNGETTY)
  464. vlogevent(getpid(), "UNGETTY -t %s status %04x", line, wait_status);
  465. #endif
  466. switch ((uchar) (wait_status >> 8))
  467. {
  468. case UG_RESTART:
  469. break;
  470. default:
  471. remove_from_ungetty_list(line);
  472. return;
  473. }
  474. #endif /* NEVER */
  475. original_sighdlr = signal(SIGCLD, SIG_DFL);
  476. if ((ungetty_pid = smart_fork()) == 0)
  477. {
  478. execl(ungetty, "ungetty", "-r", line, bamboozlement, (char *)0);
  479. logevent(getppid(), "could not exec ecuungetty -r");
  480. _exit(UGE_DNE); /* did not execute */
  481. }
  482. while (((itmp = wait(&wait_status)) != ungetty_pid) &&
  483. (itmp != -1))
  484. ;
  485. #if defined(LOG_UNGETTY)
  486. if (wait_status)
  487. vlogevent(getpid(), "UNGETTY -r %s status 0x%04x", line, wait_status);
  488. else
  489. vlogevent(getpid(), "UNGETTY returned %s", line);
  490. #endif
  491. remove_from_ungetty_list(line);
  492. } /* end of _ungetty_return_line */
  493. #endif /* defined(CFG_UseUngetty) */
  494. /*+-------------------------------------------------------------------------
  495. ungetty_return_line(line,cause) - return one or all lines to "getty"
  496. cause is a debugging feature
  497. --------------------------------------------------------------------------*/
  498. void
  499. ungetty_return_line(line, cause)
  500. char *line;
  501. char *cause;
  502. {
  503. #if !defined(CFG_UseUngetty)
  504. line = 0; /* -Wunused */
  505. cause = 0; /* -Wunused */
  506. return;
  507. #else
  508. int itmp;
  509. #if defined(CHOOSE_DEBUG)
  510. vlogevent(getpid(), "ungetty_return_line '%s' because '%s'",
  511. (line) ? line : "<ALL>", cause);
  512. #endif /* CHOOSE_DEBUG */
  513. if (shm->Ltelnet)
  514. return;
  515. if (line)
  516. {
  517. #ifdef SCO_TTY_NAMING
  518. if (strcmp(shm->Lline, line) && (!strcmpi(shm->Lline, line)) &&
  519. in_ungetty_list(shm->Lline))
  520. {
  521. #ifdef CHOOSE_DEBUG
  522. vlogevent(getpid(), "ecuungetty -r skipped for companion %s",
  523. line);
  524. #endif
  525. return;
  526. }
  527. #endif /* SCO_TTY_NAMING */
  528. _ungetty_return_line(line);
  529. }
  530. else
  531. {
  532. for (itmp = 0; itmp < UNGETTY_LIST_MAX; itmp++)
  533. {
  534. if (*(line = ungetty_list[itmp]))
  535. _ungetty_return_line(line);
  536. }
  537. }
  538. #endif /* defined(CFG_UseUngetty) */
  539. } /* end of ungetty_return_line */
  540. /*+-------------------------------------------------------------------------
  541. ungetty_return_all_but(line) - return all lines but 'line'
  542. --------------------------------------------------------------------------*/
  543. void
  544. ungetty_return_all_but(line)
  545. char *line;
  546. {
  547. #if !defined(CFG_UseUngetty)
  548. line = 0; /* -Wunused */
  549. return;
  550. #else
  551. int itmp;
  552. if (shm->Ltelnet)
  553. return;
  554. for (itmp = 0; itmp < UNGETTY_LIST_MAX; itmp++)
  555. {
  556. if (ungetty_list[itmp][0] && strcmp(line, ungetty_list[itmp]))
  557. _ungetty_return_line(line);
  558. }
  559. #endif /* !defined(CFG_UseUngetty) */
  560. } /* end of ungetty_return_all_but */
  561. /*+-------------------------------------------------------------------------
  562. malformed_Devices_entry(text,ntokens,tokens)
  563. --------------------------------------------------------------------------*/
  564. void
  565. malformed_Devices_entry(text, ntokens, tokens)
  566. char *text;
  567. int ntokens;
  568. char **tokens;
  569. {
  570. char s512[512];
  571. char *cp;
  572. char *nlptr;
  573. static int already = 0;
  574. extern int tty_not_char_special;
  575. sprintf(s512, "malformed Devices entry (%s):\n", text);
  576. cp = s512 + strlen(s512);
  577. nlptr = cp - 1;
  578. while (ntokens--)
  579. {
  580. if (((cp - s512) + strlen(*tokens) + 2) > sizeof(s512))
  581. break;
  582. sprintf(cp, "%s ", *tokens++);
  583. cp += strlen(cp);
  584. }
  585. if (!already && !tty_not_char_special)
  586. {
  587. pputs("\7\n");
  588. pputs(s512);
  589. pputs("\nFurther Devices errors will not be displayed,\n");
  590. pputs("but are logged in ~/.ecu/log. Press any key to continue.\7");
  591. ttyflush(0);
  592. ttygetc(1);
  593. pputs("\n");
  594. }
  595. already = 1;
  596. memcpy(s512, "MALFORMED", 9); /* mod for log file */
  597. *nlptr = ' ';
  598. logevent(xmtr_pid, s512);
  599. } /* end of malformed_Devices_entry */
  600. /*+-------------------------------------------------------------------------
  601. getdvent() - get first or next Devices entry (a la getpwent)
  602. --------------------------------------------------------------------------*/
  603. DVE *
  604. getdvent()
  605. {
  606. int itmp;
  607. #define MAX_DV_TOKENS 9
  608. char *tokens[MAX_DV_TOKENS];
  609. int ntokens;
  610. char *cp;
  611. static DVE dve;
  612. static char dvstr[512];
  613. char *skip_ld_break();
  614. if (!there_is_hdb_on_this_machine)
  615. goto RETURN_NULL;
  616. if (!fpdv)
  617. {
  618. if (!(fpdv = fopen(Devices_file, "r")))
  619. {
  620. pperror(Devices_file);
  621. goto RETURN_NULL;
  622. }
  623. }
  624. while (1)
  625. {
  626. /*
  627. * read a Devices line
  628. */
  629. if (!fgets(dvstr, sizeof(dvstr), fpdv))
  630. {
  631. RETURN_NULL:
  632. #ifdef CHOOSE_DEBUG
  633. logevent(xmtr_pid, "getdvent returning NULL");
  634. #endif
  635. return ((DVE *) 0);
  636. }
  637. /*
  638. * weed out comments and blank lines
  639. */
  640. if ((unsigned)strlen(dvstr) <= (unsigned)1) /* blank line */
  641. continue;
  642. cp = skip_ld_break(dvstr); /* first non-blank */
  643. if (!*cp || strchr("#\n", *cp)) /* comment or all white space */
  644. continue;
  645. /*
  646. * tokenize
  647. */
  648. build_arg_array(dvstr, tokens, MAX_DV_TOKENS, &ntokens);
  649. /*
  650. * a bit of validation
  651. */
  652. if (ntokens < 4)
  653. {
  654. malformed_Devices_entry("too few fields", ntokens, tokens);
  655. continue;
  656. }
  657. break;
  658. }
  659. /*
  660. * we have a good entry
  661. */
  662. dve.type = tokens[0];
  663. dve.line = tokens[1];
  664. /*
  665. * get rid of possible SVR4 ",M" modem control suffix
  666. */
  667. itmp = strlen(dve.line);
  668. if ((itmp > 2) && !strcmp(dve.line + itmp - 2, ",M"))
  669. dve.line[itmp - 2] = 0;
  670. dve.dialer = tokens[2];
  671. if (!strcmpi(tokens[3], "Any"))
  672. {
  673. dve.low_baud = 1;
  674. dve.high_baud = 65535;
  675. }
  676. else
  677. {
  678. dve.low_baud = atoi(tokens[3]);
  679. if (!(cp = strchr(tokens[3], '-')))
  680. dve.high_baud = dve.low_baud;
  681. else
  682. dve.high_baud = atoi(cp + 1);
  683. }
  684. dve.dialprog = tokens[4];
  685. dve.token = tokens[5];
  686. #ifdef CHOOSE_DEBUG
  687. vlogevent(getpid(), "getdvent returning '%s' type='%s'",
  688. dve.line, dve.type);
  689. #endif
  690. return (&dve);
  691. } /* end of getdvent */
  692. /*+-------------------------------------------------------------------------
  693. setdvent()
  694. --------------------------------------------------------------------------*/
  695. void
  696. setdvent()
  697. {
  698. if (fpdv)
  699. rewind(fpdv);
  700. } /* end of setdvent */
  701. /*+-------------------------------------------------------------------------
  702. enddvent() - close Devices file
  703. --------------------------------------------------------------------------*/
  704. void
  705. enddvent()
  706. {
  707. if (fpdv)
  708. {
  709. fclose(fpdv);
  710. fpdv = (FILE *) 0;
  711. }
  712. } /* end of enddvent */
  713. /*+-------------------------------------------------------------------------
  714. getdvbaud(baud) - get Devices entry matching bit rate
  715. --------------------------------------------------------------------------*/
  716. DVE *
  717. getdvbaud(baud)
  718. UINT baud;
  719. {
  720. DVE *tdve;
  721. #ifdef CHOOSE_DEBUG
  722. vlogevent(getpid(), "getdvbaud looking for %u baud", baud);
  723. #endif
  724. while (1)
  725. {
  726. if ((tdve = getdvent()) == (DVE *) 0)
  727. return (tdve);
  728. #ifdef CHOOSE_DEBUG
  729. vlogevent(getpid(), "getdvbaud found %s type '%s' baud lo=%d hi=%d",
  730. tdve->line, tdve->type, tdve->low_baud, tdve->high_baud);
  731. #endif
  732. if (!strcmp(tdve->line, "-")) /* neo-entries like TCP have "-"
  733. * line */
  734. continue;
  735. if ((tdve->low_baud <= baud) && (baud <= tdve->high_baud))
  736. {
  737. #ifdef CHOOSE_DEBUG
  738. vlogevent(getpid(), "getdvbaud returning %s", tdve->line);
  739. #endif
  740. return (tdve);
  741. }
  742. }
  743. /* NOTREACHED */
  744. } /* end of getdvbaud */
  745. /*+-------------------------------------------------------------------------
  746. getdvline(line) - get Devices entry matching line
  747. calling argument 'line's is string AFTER "/dev/"
  748. --------------------------------------------------------------------------*/
  749. DVE *
  750. getdvline(line)
  751. char *line;
  752. {
  753. DVE *tdve;
  754. #ifdef CHOOSE_DEBUG
  755. vlogevent(getpid(), "getdvline looking for %s", line);
  756. #endif
  757. while (1)
  758. {
  759. if ((tdve = getdvent()) == (DVE *) 0)
  760. return (tdve);
  761. #ifdef CHOOSE_DEBUG
  762. vlogevent(getpid(), "getdvline %s found baud lo=%d hi=%d",
  763. tdve->line, tdve->low_baud, tdve->high_baud);
  764. #endif
  765. if (!TTYNAME_STRCMP(tdve->line, line))
  766. return (tdve);
  767. }
  768. /* NOTREACHED */
  769. } /* end of getdvline */
  770. /*+-------------------------------------------------------------------------
  771. dvtype_match(typespec,dvtype) - match between pde typespec and dvtype
  772. returns 1 if pde type specification 'typespec' matches Devices device 'type'
  773. --------------------------------------------------------------------------*/
  774. int
  775. dvtype_match(typespec, dvtype)
  776. char *typespec;
  777. char *dvtype;
  778. {
  779. char *match;
  780. int matchlen;
  781. int re_match = 1;
  782. char cmpbuf[128];
  783. if (*typespec == '=')
  784. typespec++;
  785. else if (*typespec == '/')
  786. {
  787. re_match = 0;
  788. typespec++;
  789. }
  790. if (re_match)
  791. {
  792. if (!strcmp(dvtype, typespec))
  793. return (1);
  794. }
  795. else
  796. {
  797. if (regexp_compile(typespec, cmpbuf, sizeof(cmpbuf)))
  798. return (0);
  799. if (regexp_scan(cmpbuf, dvtype, &match, &matchlen))
  800. return (1);
  801. }
  802. return (0);
  803. } /* end of dvtype_match */
  804. /*+-------------------------------------------------------------------------
  805. getdvtype(type) - get Devices entry matching type
  806. type is either 'Device_type' search for exact match on Device_type
  807. '=Device_type' search for exact match on Device_type
  808. '/regexp' search for match with regular expression
  809. you must make sure any supplied regexp is a valid one, for regexp
  810. compilation errors are indistinguishable from other seach failures
  811. uses optimized implementation of dvtype_match functionality
  812. --------------------------------------------------------------------------*/
  813. DVE *
  814. getdvtype(type)
  815. char *type;
  816. {
  817. DVE *tdve;
  818. char *emsg;
  819. char *match;
  820. int matchlen;
  821. int re_match = 0; /* regular expression match */
  822. char cmpbuf[128];
  823. if (*type == '=')
  824. type++;
  825. else if (*type == '/')
  826. {
  827. re_match = 1;
  828. type++;
  829. if (regexp_compile(type, cmpbuf, sizeof(cmpbuf), &emsg))
  830. return ((DVE *) 0);
  831. }
  832. while (tdve = getdvent())
  833. {
  834. if (!strcmp(tdve->line, "-")) /* neo-entries like TCP have "-"
  835. * line */
  836. continue;
  837. if (re_match)
  838. {
  839. if (regexp_scan(cmpbuf, tdve->type, &match, &matchlen))
  840. break;
  841. }
  842. else
  843. {
  844. if (!strcmp(tdve->type, type))
  845. break;
  846. }
  847. }
  848. return (tdve);
  849. } /* end of getdvtype */
  850. /*+-------------------------------------------------------------------------
  851. getdlent() - get first or next Dialers entry (a la getpwent)
  852. --------------------------------------------------------------------------*/
  853. struct dlent *
  854. getdlent()
  855. {
  856. int itmp;
  857. #define MAX_DL_TOKENS 3
  858. char *tokens[MAX_DL_TOKENS];
  859. static struct dlent dle;
  860. static char dlstr[128];
  861. if (!there_is_hdb_on_this_machine)
  862. return ((struct dlent *)0);
  863. if (!fpdl)
  864. {
  865. if (!(fpdl = fopen(Dialers_file, "r")))
  866. {
  867. pperror(Dialers_file);
  868. return ((struct dlent *)0);
  869. }
  870. }
  871. while (1)
  872. {
  873. if (!fgets(dlstr, sizeof(dlstr), fpdl))
  874. return ((struct dlent *)0);
  875. if (((itmp = strlen(dlstr)) <= 1) || (dlstr[0] == '#') ||
  876. (dlstr[0] == ' '))
  877. {
  878. continue;
  879. }
  880. dlstr[--itmp] = 0;
  881. for (itmp = 0; itmp < MAX_DL_TOKENS; itmp++)
  882. tokens[itmp] = "";
  883. if (tokens[0] = arg_token(dlstr, " \t\r\n"))
  884. {
  885. if (tokens[1] = arg_token((char *)0, " \t\r\n"))
  886. {
  887. extern char *str_token_static;
  888. tokens[2] = skip_ld_break(str_token_static);
  889. }
  890. }
  891. break;
  892. }
  893. dle.name = tokens[0];
  894. dle.tlate = tokens[1];
  895. dle.script = tokens[2];
  896. return (&dle);
  897. } /* end of getdlent */
  898. /*+-------------------------------------------------------------------------
  899. setdlent()
  900. --------------------------------------------------------------------------*/
  901. void
  902. setdlent()
  903. {
  904. if (fpdl)
  905. rewind(fpdl);
  906. } /* end of setdlent */
  907. /*+-------------------------------------------------------------------------
  908. enddlent() - close Dialers file
  909. --------------------------------------------------------------------------*/
  910. void
  911. enddlent()
  912. {
  913. if (fpdl)
  914. {
  915. fclose(fpdl);
  916. fpdl = (FILE *) 0;
  917. }
  918. } /* end of enddlent */
  919. /*+-------------------------------------------------------------------------
  920. getdlentname(name) - get Dialers entry by name
  921. --------------------------------------------------------------------------*/
  922. struct dlent *
  923. getdlentname(name)
  924. char *name;
  925. {
  926. DLE *tdle;
  927. while (tdle = getdlent())
  928. {
  929. if (!strcmp(name, tdle->name))
  930. break;
  931. }
  932. return (tdle);
  933. } /* end of getdlentname */
  934. /*+-------------------------------------------------------------------------
  935. hdb_choose_Any(baud) - user will take 'Any' line
  936. give preference to current line
  937. --------------------------------------------------------------------------*/
  938. DVE *
  939. hdb_choose_Any(baud)
  940. UINT baud;
  941. {
  942. DVE *tdve = (DVE *) 0;
  943. char newtty[sizeof(shm->Lline)];
  944. enum linst linst = LINST_OK;
  945. enum utmp_status utmpst = US_UNDEF;
  946. #ifdef CHOOSE_DEBUG
  947. char s512[512];
  948. vlogevent(getpid(), "CHOOSEANY REQUEST baud=%u (current line='%s')",
  949. baud, shm->Lline);
  950. #endif
  951. enddvent(); /* krock but safe */
  952. /*
  953. * see if shm->Lline in use by someone else; if not and bit rate ok,
  954. * no further
  955. */
  956. if (shm->Lline[0])
  957. {
  958. while (tdve = getdvline(shm->Lline + 5))
  959. {
  960. if ((tdve->low_baud <= baud) && (baud <= tdve->high_baud))
  961. break;
  962. }
  963. if (tdve)
  964. {
  965. switch (utmpst = utmp_status(shm->Lline))
  966. {
  967. case US_WEGOTIT: /* the line is already ours */
  968. case US_LOGIN: /* enabled for login, idle */
  969. goto FUNC_RETURN;
  970. case US_DIALOUT:
  971. case US_LOGGEDIN:
  972. break;
  973. case US_NOTFOUND: /* not in utmp, or getty dead */
  974. #if !defined(CFG_UseUngetty)
  975. if (access(shm->Lline, 6))
  976. break;
  977. #endif
  978. if ((linst = line_lock_status(shm->Lline)) &&
  979. (linst != LINST_WEGOTIT))
  980. {
  981. break;
  982. }
  983. goto FUNC_RETURN;
  984. default:
  985. break;
  986. }
  987. }
  988. enddvent();
  989. }
  990. /*
  991. * we've got to pick a new line
  992. */
  993. #ifdef CHOOSE_DEBUG
  994. strcpy(s512, "CHOOSEANY pick new line: ");
  995. if (!shm->Lline[0])
  996. strcat(s512, "none selected at all");
  997. else
  998. {
  999. sprintf(s512 + strlen(s512), "utmpst=%s linst=%s",
  1000. US_text(utmpst), LINST_text(linst));
  1001. }
  1002. logevent(getpid(), s512);
  1003. #endif
  1004. linst = LINST_OK;
  1005. while (tdve = getdvbaud(baud))
  1006. {
  1007. /* by now, we know shm->Lline wont work */
  1008. if (!TTYNAME_STRCMP(tdve->line, shm->Lline + 5))
  1009. continue;
  1010. /* if not acu, dont use it */
  1011. if (ulindex(tdve->type, "ACU") < 0)
  1012. continue;
  1013. sprintf(newtty, "/dev/%s", tdve->line);
  1014. switch (utmpst = utmp_status(newtty))
  1015. {
  1016. case US_NOTFOUND: /* not in utmp, or getty dead */
  1017. #if !defined(CFG_UseUngetty)
  1018. if (access(newtty, 6)) /* ecuungetty won't be able to
  1019. * help us */
  1020. break;
  1021. #endif
  1022. if ((linst = line_lock_status(newtty)) &&
  1023. (linst != LINST_WEGOTIT))
  1024. {
  1025. break;
  1026. }
  1027. goto FUNC_RETURN;
  1028. case US_LOGIN: /* enabled for login, idle */
  1029. goto FUNC_RETURN;
  1030. case US_WEGOTIT:
  1031. goto FUNC_RETURN;
  1032. default:
  1033. break;
  1034. }
  1035. }
  1036. FUNC_RETURN:
  1037. enddvent();
  1038. #ifdef LOG_HDBDIAL
  1039. vlogevent(getpid(), "CHOOSEANY RESULT %s (status utmp=%s line=%s)",
  1040. (tdve) ? tdve->line : "<none>", US_text(utmpst), LINST_text(linst));
  1041. #endif
  1042. return (tdve);
  1043. } /* end of hdb_choose_Any */
  1044. /*+-------------------------------------------------------------------------
  1045. hdb_choose_Device(type,baud) - need line with 'type' and 'baud'
  1046. return DVE pointer if line chosen, 0 if failed to find a line
  1047. Priority is NO LONGER given to retaining the current line as of rev 3.34
  1048. --------------------------------------------------------------------------*/
  1049. DVE *
  1050. hdb_choose_Device(type, baud)
  1051. char *type;
  1052. UINT baud;
  1053. {
  1054. DVE *tdve = (DVE *) 0;
  1055. char s32[32];
  1056. int itmp = 0;
  1057. enum utmp_status utmpst = US_UNDEF;
  1058. int done;
  1059. #ifdef CHOOSE_DEBUG
  1060. vlogevent(getpid(), "CHOOSEDEV REQUEST type='%s' baud=%u", type, baud);
  1061. #endif
  1062. /*
  1063. * we may have to pick a new line
  1064. */
  1065. done = 0;
  1066. while (!done)
  1067. {
  1068. /*
  1069. * get Devices entry matching type
  1070. */
  1071. if (!(tdve = getdvtype(type)))
  1072. {
  1073. #ifdef CHOOSE_DEBUG
  1074. vlogevent(getpid(), "CHOOSEDEV no line matches type '%s'", type);
  1075. #endif
  1076. break;
  1077. }
  1078. /*
  1079. * does bit rate match?
  1080. */
  1081. if ((tdve->low_baud > baud) || (baud > tdve->high_baud))
  1082. continue;
  1083. sprintf(s32, "/dev/%s", tdve->line);
  1084. utmpst = utmp_status(s32);
  1085. #ifdef CHOOSE_DEBUG
  1086. vlogevent(getpid(), "%s: utmp status=%s lock status=%s", s32,
  1087. US_text(utmpst), LINST_text(line_lock_status(s32)));
  1088. #endif
  1089. switch (utmpst)
  1090. {
  1091. case US_NOTFOUND: /* not in utmp, or getty dead */
  1092. if (!(itmp = line_lock_status(s32)) || (itmp == LINST_WEGOTIT))
  1093. done = 1;
  1094. break;
  1095. case US_WEGOTIT:/* we own the line */
  1096. /* this would be a curious case to succeed */
  1097. done = 1;
  1098. break;
  1099. case US_LOGIN: /* enabled for login, idle */
  1100. done = 1;
  1101. break;
  1102. default:
  1103. break;
  1104. }
  1105. }
  1106. enddvent();
  1107. #ifdef CHOOSE_DEBUG
  1108. vlogevent(getpid(), "CHOOSEDEV RESULT %s utmp status=%s",
  1109. (tdve) ? tdve->line : "<none>",
  1110. (tdve) ? US_text(utmpst) : "N/A");
  1111. #endif
  1112. return (tdve);
  1113. } /* end of hdb_choose_Device */
  1114. /*+-------------------------------------------------------------------------
  1115. hdb_dial_error(errcode) - dialer program error code to text
  1116. also sets iv[0] to dial command status
  1117. --------------------------------------------------------------------------*/
  1118. char *
  1119. hdb_dial_error_text(errcode)
  1120. int errcode;
  1121. {
  1122. static char errant[64];
  1123. iv[0] = 1;
  1124. switch (errcode &= 0x7F)
  1125. {
  1126. case RCE_INUSE:
  1127. return ("!Line in use");
  1128. case RCE_SIG:
  1129. iv[0] = 2;
  1130. return ("!Interrupted");
  1131. case RCE_ARGS:
  1132. return ("!Invalid arguments");
  1133. case RCE_PHNO:
  1134. return ("!Invalid phone number");
  1135. case RCE_SPEED:
  1136. return ("!Bad bit rate");
  1137. case RCE_OPEN:
  1138. return ("!Line open error");
  1139. case RCE_IOCTL:
  1140. return ("!Ioctl error");
  1141. case RCE_TIMOUT:
  1142. iv[0] = 3;
  1143. return ("!Modem Error");
  1144. case RCE_NOTONE:
  1145. return ("NO DIAL TONE");
  1146. case RCE_BUSY:
  1147. return ("BUSY");
  1148. case RCE_NOCARR:
  1149. return ("NO CARRIER");
  1150. case RCE_ANSWER:
  1151. return ("NO ANSWER");
  1152. default:
  1153. case RCE_NULL:
  1154. sprintf(errant, "unknown dialer error code %d", errcode);
  1155. return (errant);
  1156. }
  1157. /* NOTREACHED */
  1158. } /* end of hdb_dial_error */
  1159. /*+-------------------------------------------------------------------------
  1160. hdb_dial(presult) - dial with uucp dialer if we can
  1161. return 0 if connected
  1162. 1 if dial failed
  1163. 2 if interrupted
  1164. 3 if modem error
  1165. 4 if use ecu DCE dialer
  1166. --------------------------------------------------------------------------*/
  1167. int
  1168. hdb_dial(presult)
  1169. char **presult;
  1170. {
  1171. int itmp;
  1172. FILE *fp;
  1173. CFG_PidType dial_pid;
  1174. CFG_SigType(*original_sighdlr) ();
  1175. DVE *tdve;
  1176. char token[128]; /* translated dialer token */
  1177. int wait_status;
  1178. struct dlent *tdle = (struct dlent *)0;
  1179. char baudstr[16];
  1180. char dbgstr[16];
  1181. char dial_log[128];
  1182. char dialprog_path[ECU_MAXPN];
  1183. char *stripped_num;
  1184. char *sptr;
  1185. char *dptr;
  1186. struct stat st;
  1187. UINT32 colors_at_entry = colors_current;
  1188. char credit_file[ECU_MAXPN];
  1189. char *error_name = "";
  1190. int error_baud = 0;
  1191. int rcvr_restart = need_rcvr_restart();
  1192. int old_ttymode = get_ttymode();
  1193. static char stat_s64[64];
  1194. /*
  1195. * we may do nothing
  1196. */
  1197. if (ck_sigint()) /* don't even start if console interrupt
  1198. * posted */
  1199. {
  1200. sigint = 0;
  1201. return (2);
  1202. }
  1203. if (!there_is_hdb_on_this_machine)
  1204. return (4);
  1205. /*
  1206. * kill receiver if it is active
  1207. */
  1208. if (rcvr_restart)
  1209. kill_rcvr_process(SIGUSR1);
  1210. #if defined(CHOOSE_DEBUG)
  1211. vlogevent(getpid(), "HDB_DIAL Lline=%s Lbitrate=%d",
  1212. shm->Lline, shm->Lbitrate);
  1213. #endif
  1214. /*
  1215. * get a Devices entry appropriate for dialing on the line;
  1216. */
  1217. enddvent();
  1218. while (tdve = getdvline(shm->Lline + 5))
  1219. {
  1220. if ((tdve->low_baud <= shm->Lbitrate) &&
  1221. (shm->Lbitrate <= tdve->high_baud))
  1222. {
  1223. break;
  1224. }
  1225. }
  1226. error_name = shm->Lline + 5;
  1227. error_baud = shm->Lbitrate;
  1228. enddvent();
  1229. if (!tdve)
  1230. {
  1231. pprintf("no Devices entry for %s at %u baud ... trying ecu dialer\n",
  1232. error_name, error_baud);
  1233. return (4);
  1234. }
  1235. dial_log[0] = 0;
  1236. if (*tdve->dialprog != '/')
  1237. {
  1238. /*
  1239. * per user demand, check for dialer program w/o leading /
  1240. */
  1241. strcpy(dialprog_path, hdblibdir);
  1242. strcat(dialprog_path, "/");
  1243. itmp = strlen(dialprog_path);
  1244. strncat(dialprog_path, tdve->dialprog, sizeof(dialprog_path) - itmp);
  1245. dialprog_path[sizeof(dialprog_path) - 1] = 0;
  1246. if (!stat(dialprog_path, &st) && ((st.st_mode & S_IFMT) == S_IFREG) &&
  1247. (st.st_mode & 0111)) /* if regular file exists and
  1248. * executable */
  1249. {
  1250. tdve->dialprog = dialprog_path;
  1251. }
  1252. else
  1253. {
  1254. tdle = getdlentname(tdve->dialprog);
  1255. enddlent();
  1256. if (!tdle)
  1257. {
  1258. sprintf(dial_log,
  1259. "UUCPDIAL Devices entry %s: '%s' not found in Dialers",
  1260. shm->Lline + 5, tdve->dialprog);
  1261. }
  1262. }
  1263. }
  1264. else if (access(tdve->dialprog, 1))
  1265. {
  1266. sprintf(dial_log, "UUCPDIAL Devices entry %s: (%s) %s",
  1267. shm->Lline + 5, tdve->dialprog, strerror(errno));
  1268. }
  1269. if (dial_log[0])
  1270. {
  1271. #if defined(LOG_HDBDIAL)
  1272. logevent(getpid(), dial_log);
  1273. #endif
  1274. pputs(dial_log + 9);
  1275. pputs("\n");
  1276. return (4);
  1277. }
  1278. stripped_num = strip_phone_num(shm->Ltelno);
  1279. /*
  1280. * if trailing '$', read and append ~/.ecu/.credit
  1281. */
  1282. dptr = stripped_num;
  1283. if (*(dptr - 1) == '$')
  1284. {
  1285. *--dptr = 0;
  1286. get_home_dir(credit_file);
  1287. strcat(credit_file, "/.ecu/.credit");
  1288. chmod(credit_file, 0400); /* let's keep this one quiet */
  1289. if (fp = fopen(credit_file, "r"))
  1290. {
  1291. fgets(dptr, 30, fp);
  1292. fclose(fp);
  1293. }
  1294. if (!fp || !(*dptr))
  1295. {
  1296. strcpy(sv[0]->pb, "!CREDIT CARD ERROR");
  1297. sv[0]->cb = strlen(sv[0]->pb);
  1298. pputs("\ncredit card error\n");
  1299. iv[0] = 1;
  1300. return (1);
  1301. }
  1302. if (*(dptr + strlen(dptr) - 1) == 0x0A)
  1303. *(dptr + strlen(dptr) - 1) = 0; /* kill NL */
  1304. }
  1305. /* Translate Token now (thanks to ache@hq.demos.su) */
  1306. if (tdve->token == (char *)0 || !tdve->token[0])
  1307. strcpy(token, stripped_num);
  1308. else
  1309. {
  1310. dptr = token;
  1311. for (sptr = tdve->token; *sptr; sptr++)
  1312. if (*sptr != '\\')
  1313. *dptr++ = *sptr;
  1314. else
  1315. {
  1316. char *s, *t;
  1317. switch (*(sptr + 1))
  1318. {
  1319. /* Direct */
  1320. case 'D':
  1321. sptr++;
  1322. s = stripped_num;
  1323. while (*s)
  1324. *dptr++ = *s++;
  1325. break;
  1326. /* Dialcodes Translate */
  1327. case 'T':
  1328. sptr++;
  1329. s = stripped_num;
  1330. t = dialcodes_translate(&s);
  1331. while (*t)
  1332. *dptr++ = *t++;
  1333. while (*s)
  1334. *dptr++ = *s++;
  1335. break;
  1336. default:
  1337. *dptr++ = '\\';
  1338. break;
  1339. }
  1340. }
  1341. *dptr = 0;
  1342. }
  1343. pprintf("Type %s to abort ... ",
  1344. (kbdintr == 0x7F) ? "DEL" : graphic_char_text(kbdintr, 0));
  1345. setcolor(colors_normal);
  1346. if (Ldial_debug_level)
  1347. {
  1348. ttymode(0);
  1349. pputs("\n");
  1350. }
  1351. else
  1352. ttymode(2);
  1353. if (!tdle)
  1354. {
  1355. int accessible = (access(tdve->dialprog, 1) == 0);
  1356. int dial_as_uucp = 0;
  1357. /*
  1358. * access() checks to see if the ORIGINAL uid
  1359. * can access, not the euid
  1360. */
  1361. if(!accessible && setuid_uucp)
  1362. {
  1363. if (!stat(tdve->dialprog, &st) &&
  1364. ((unsigned)st.st_uid == (unsigned)uid_uucp) &&
  1365. !(st.st_mode & 1))
  1366. {
  1367. dial_as_uucp++;
  1368. accessible = 1;
  1369. }
  1370. }
  1371. /*
  1372. * check final word on accessibility
  1373. */
  1374. if (!accessible)
  1375. {
  1376. pperror(tdve->dialprog);
  1377. pputs("trying ecu dialer\n");
  1378. return (4);
  1379. }
  1380. /*
  1381. * stops a bug but is only a catch for one case
  1382. * (more work here)
  1383. */
  1384. if (!dial_as_uucp && setuid_uucp &&
  1385. !stat(shm->Lline, &st) &&
  1386. ((unsigned)st.st_uid == (unsigned)uid_uucp))
  1387. {
  1388. dial_as_uucp++;
  1389. }
  1390. sprintf(baudstr, "%u", shm->Lbitrate);
  1391. sprintf(dbgstr, "-x%d", Ldial_debug_level);
  1392. original_sighdlr = signal(SIGCLD, SIG_DFL);
  1393. if ((dial_pid = smart_fork()) == 0)
  1394. {
  1395. signal(SIGINT, SIG_DFL);
  1396. if(dial_as_uucp)
  1397. Setuid(uid_uucp);
  1398. execl(tdve->dialprog,
  1399. #if defined(WHT) || defined(CFG_UseEcuDial)
  1400. "ECUdial", /* tell dialer ECU is calling */
  1401. #else
  1402. tdve->dialprog,
  1403. #endif
  1404. dbgstr, shm->Lline, token, baudstr, (char *)0);
  1405. _exit(0xFF); /* did not execute */
  1406. }
  1407. wait_status = (RC_FAIL | RCE_SIG) << 8;
  1408. while (((itmp = wait(&wait_status)) != dial_pid) && (itmp != -1))
  1409. ;
  1410. signal(SIGCLD, original_sighdlr);
  1411. ttymode(old_ttymode);
  1412. ttyflush(0);
  1413. if (ck_sigint()) /* keyboard interrupt? */
  1414. {
  1415. kill((CFG_PidType) dial_pid, 9); /* kill dialer */
  1416. lflash_dtr(); /* drop line */
  1417. sigint = 0; /* reset SIGINT indication */
  1418. }
  1419. lreset_ksr(); /* uucp dialers are nice guys, but lets use
  1420. * our termio */
  1421. #if defined(LOG_HDBDIAL)
  1422. if (wait_status)
  1423. {
  1424. vlogevent(getpid(), "UUCPDIAL %s %s exit status0x%04x",
  1425. tdve->dialprog, token, wait_status & 0xFFFF);
  1426. }
  1427. #endif
  1428. /*
  1429. * if system reports interrupt, fake dial-reported status
  1430. */
  1431. if (wait_status & 0xFF)
  1432. wait_status = (RC_FAIL | RCE_SIG) << 8;
  1433. if ((wait_status & 0xFF00) == 0xFF00)
  1434. {
  1435. pprintf("%s did not execute ... trying ecu dialer\n", tdve->dialprog);
  1436. return (4);
  1437. }
  1438. wait_status = (wait_status >> 8) & 0xFF;
  1439. wait_status &= ~RC_ENABLED;
  1440. if (!(wait_status & ~RC_BAUD))
  1441. {
  1442. char *cp;
  1443. wait_status &= RC_BAUD;
  1444. switch (wait_status)
  1445. {
  1446. case 0:
  1447. cp = baudstr;
  1448. break; /* SAME */
  1449. case B50:
  1450. cp = "50";
  1451. break;
  1452. case B75:
  1453. cp = "75";
  1454. break;
  1455. case B110:
  1456. cp = "110";
  1457. break;
  1458. case B134:
  1459. cp = "134.5";
  1460. break;
  1461. case B150:
  1462. cp = "150";
  1463. break;
  1464. case B200:
  1465. cp = "200";
  1466. break;
  1467. case B300:
  1468. cp = "300";
  1469. break;
  1470. case B600:
  1471. cp = "600";
  1472. break;
  1473. case B1200:
  1474. cp = "1200";
  1475. break;
  1476. case B1800:
  1477. cp = "1800";
  1478. break;
  1479. case B2400:
  1480. cp = "2400";
  1481. break;
  1482. case B4800:
  1483. cp = "4800";
  1484. break;
  1485. case B9600:
  1486. cp = "9600";
  1487. break;
  1488. #if defined(B19200)
  1489. case B19200:
  1490. cp = "19200";
  1491. break;
  1492. #endif
  1493. #if defined(B38400)
  1494. case B38400:
  1495. cp = "38400";
  1496. break;
  1497. #endif
  1498. #if defined(B57600)
  1499. case B57600:
  1500. cp = "57600";
  1501. break;
  1502. #endif
  1503. #if defined(B115200)
  1504. case B115200:
  1505. cp = "115200";
  1506. break;
  1507. #endif
  1508. default:
  1509. switch (wait_status)
  1510. {
  1511. case EXTA:
  1512. cp = "EXTA";
  1513. break;
  1514. case EXTB:
  1515. cp = "EXTB";
  1516. break;
  1517. default:
  1518. cp = "????";
  1519. break;
  1520. }
  1521. }
  1522. sprintf(stat_s64, "CONNECT %s", cp);
  1523. *presult = stat_s64; /* DCE_dial will report result code */
  1524. return (0);
  1525. }
  1526. *presult = hdb_dial_error_text(wait_status);
  1527. setcolor(colors_error);
  1528. pputs(*presult);
  1529. setcolor(colors_at_entry);
  1530. pputc('\n');
  1531. lflash_dtr();
  1532. }
  1533. else
  1534. {
  1535. pprintf("using Dialers entry '%s'\n", tdle->name);
  1536. last_Speed_result[0] = 0;
  1537. if (execute_expresp(tdle->script))
  1538. {
  1539. *presult = "DIALER SCRIPT FAILED";
  1540. setcolor(colors_error);
  1541. pputs(*presult);
  1542. setcolor(colors_at_entry);
  1543. pputc('\n');
  1544. iv[0] = 1;
  1545. }
  1546. else
  1547. {
  1548. if (last_Speed_result[0])
  1549. *presult = last_Speed_result;
  1550. else
  1551. {
  1552. sprintf(stat_s64, "CONNECT %u", shm->Lbitrate);
  1553. *presult = stat_s64; /* DCE_dial will report result
  1554. * code */
  1555. }
  1556. setcolor(colors_at_entry);
  1557. iv[0] = 0;
  1558. }
  1559. }
  1560. /*
  1561. * restart receiver if we killed it
  1562. */
  1563. if (rcvr_restart)
  1564. start_rcvr_process(1);
  1565. return ((int)iv[0]);
  1566. } /* end of hdb_dial */
  1567. /*+-------------------------------------------------------------------------
  1568. hdb_init() - initialize HoneyDanBerInterface
  1569. --------------------------------------------------------------------------*/
  1570. void
  1571. hdb_init()
  1572. {
  1573. int itmp;
  1574. int buflen = strlen(hdblibdir) + 64;
  1575. char *emsg = "hdb_init memory allocation failed!\n";
  1576. struct stat st;
  1577. if (!(Devices_file = malloc(buflen)))
  1578. {
  1579. pputs(emsg);
  1580. errno = -1;
  1581. termecu(TERMECU_MALLOC);
  1582. }
  1583. strcpy(Devices_file, hdblibdir);
  1584. strcat(Devices_file, "/Devices");
  1585. if (!(Dialers_file = malloc(buflen)))
  1586. {
  1587. pputs(emsg);
  1588. errno = -1;
  1589. termecu(TERMECU_MALLOC);
  1590. }
  1591. for (itmp = 0; itmp < UNGETTY_LIST_MAX; itmp++)
  1592. {
  1593. if (!(ungetty_list[itmp] = malloc(64)))
  1594. {
  1595. pputs(emsg);
  1596. errno = -1;
  1597. termecu(TERMECU_MALLOC);
  1598. }
  1599. }
  1600. strcpy(Dialers_file, hdblibdir);
  1601. strcat(Dialers_file, "/Dialers");
  1602. if (!(Dialcodes_file = malloc(buflen)))
  1603. {
  1604. pputs(emsg);
  1605. errno = -1;
  1606. termecu(TERMECU_MALLOC);
  1607. }
  1608. strcpy(Dialcodes_file, hdblibdir);
  1609. strcat(Dialcodes_file, "/Dialcodes");
  1610. there_is_hdb_on_this_machine = !stat(Devices_file, &st);
  1611. } /* end of hdb_init */
  1612. /*+-------------------------------------------------------------------------
  1613. dialcodes_translate(phone) - translate first part of phone using Dialcodes
  1614. --------------------------------------------------------------------------*/
  1615. char *
  1616. dialcodes_translate(phone)
  1617. char **phone;
  1618. {
  1619. FILE *f;
  1620. int itmp;
  1621. #define MAX_DLC_TOKENS 2
  1622. char *tokens[MAX_DLC_TOKENS];
  1623. static char dlstr[128];
  1624. if (!(f = fopen(Dialcodes_file, "r")))
  1625. return ("");
  1626. while (fgets(dlstr, sizeof(dlstr), f))
  1627. {
  1628. if (((itmp = strlen(dlstr)) > 0) && (dlstr[itmp - 1] == '\n'))
  1629. dlstr[--itmp] = 0;
  1630. if ((dlstr[0] == '#') || (dlstr[0] == ' ') || (!itmp))
  1631. continue;
  1632. if (tokens[0] = arg_token(dlstr, " \t\r\n"))
  1633. {
  1634. if (!(tokens[1] = arg_token((char *)0, " \t\r\n")))
  1635. tokens[1] = "";
  1636. itmp = strlen(tokens[0]);
  1637. if (strncmp(*phone, tokens[0], itmp))
  1638. continue;
  1639. fclose(f);
  1640. *phone += itmp;
  1641. fclose(f);
  1642. return (tokens[1]);
  1643. }
  1644. break;
  1645. }
  1646. fclose(f);
  1647. return ("");
  1648. }
  1649. /*+-------------------------------------------------------------------------
  1650. strip_phone_num(sptr) - remove junk characters from phone
  1651. --------------------------------------------------------------------------*/
  1652. char *
  1653. strip_phone_num(sptr)
  1654. char *sptr;
  1655. {
  1656. static char stripped_num[64];
  1657. char *dptr;
  1658. dptr = stripped_num;
  1659. while (*sptr)
  1660. {
  1661. if ((*sptr == '(') || (*sptr == ')')
  1662. #if defined(WHT) || defined(STRIP_TELNO_HYPHENS)
  1663. || (*sptr == '-')/* some want '-' for pauses; I use ',' */
  1664. #endif
  1665. )
  1666. {
  1667. sptr++;
  1668. continue;
  1669. }
  1670. *dptr++ = *sptr++;
  1671. }
  1672. *dptr = 0;
  1673. return (stripped_num);
  1674. }
  1675. /*+-------------------------------------------------------------------------
  1676. report_initial_line()
  1677. --------------------------------------------------------------------------*/
  1678. void
  1679. report_initial_line()
  1680. {
  1681. #ifdef CHOOSE_DEBUG
  1682. vlogevent(getpid(), "INITIAL_LINE '%s'", shm->Lline);
  1683. #endif /* CHOOSE_DEBUG */
  1684. } /* end of report_initial_line */
  1685. /* vi: set tabstop=4 shiftwidth=4: */
  1686. /* end of hdbintf.c */