dave@onfcanim.UUCP (12/03/87)
The set of patches to uucp recently posted by Rick Adams contained lots of good fixes; unfortunately they seem to have introduced one new bug. It's not really his fault - Acuopn() was rather convoluted. Here is a modifcation to make it really do what I think the original author intended, with Rick's change included. Subject: Acuopn() has several bugs. Index: usr.bin/uucp/condevs.c 4.3BSD Description: Acuopn counted a locked line as part of the limit of TRYCALLS attempts. Rick Adams posted a fix for this, but his fix would generate the log message "NO DEVICE" when the problem was really that all lines are locked. If the condevs table contains no entry matching the "method" and "brand" of the ACU specified in the L-devices table, it doesn't detect the fact that it didn't find a match. This probably dereferences a null pointer when it tries calling. There is code to print out an unsupported ACU type in L-devices, but only when it doesn't find any other supported type. This code never works anyway, due to the previous bug. Repeat-By: Read the code. Some of these conditions can be demonstrated by corrupting the "brand" field in the L-devices file, and by trying calls when the available lines are locked by tip or other uucico's. Fix: The real problem is that someone tried to be too clever, using a single variable "acustatus" to keep track of whether an ACU was found and how many call attempts have been made. Changing the code challenges your sanity. Separate the functions of "acustatus" into two variables. Check for unsuccessful search of condevs table. Print out unsupported ACU types as found, not later sometimes. The following patch should be applied to the original 4.3BSD code as distributed. If you've already applied Rick Adams' fix, and don't use RCS or SCCS, hand examination of the diff should show what to do, since Rick's change was really only 1 line. *** /tmp/,RCSt1013708 Wed Dec 2 18:34:51 1987 --- condevs.c Wed Dec 2 18:34:02 1987 *************** *** 1,9 **** /* * $Log: condevs.c,v $ * Revision 1.2 87/05/28 16:07:30 root * Added Vadic 2400 entry. * ! * $Header: condevs.c,v 1.2 87/05/28 16:07:30 root Exp $ */ #ifndef lint --- 1,13 ---- /* * $Log: condevs.c,v $ + * Revision 1.3 87/12/02 18:33:18 dave + * General cleanup of Acuopn(); several bugs fixed. + * A locked line no longer counts in the limit of TRYCALLS call attempts. + * * Revision 1.2 87/05/28 16:07:30 root * Added Vadic 2400 entry. * ! * $Header: condevs.c,v 1.3 87/12/02 18:33:18 dave Exp $ */ #ifndef lint *************** *** 279,289 **** { char phone[MAXPH+1]; register struct condev *cd; ! register int fd, acustatus; register FILE *dfp; struct Devices dev; int retval = CF_NODEV; ! char nobrand[MAXPH], *line; exphone(flds[F_PHONE], phone); if (snccmp(flds[F_LINE], "LOCAL") == SAME) --- 283,294 ---- { char phone[MAXPH+1]; register struct condev *cd; ! register int fd, ntries; ! int acufound; register FILE *dfp; struct Devices dev; int retval = CF_NODEV; ! char *line; exphone(flds[F_PHONE], phone); if (snccmp(flds[F_LINE], "LOCAL") == SAME) *************** *** 291,302 **** else line = flds[F_LINE]; devSel[0] = '\0'; - nobrand[0] = '\0'; DEBUG(4, "Dialing %s\n", phone); dfp = fopen(DEVFILE, "r"); ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); ! acustatus = 0; /* none found, none locked */ while (rddev(dfp, &dev) != FAIL) { /* * for each ACU L.sys line, try at most twice --- 296,307 ---- else line = flds[F_LINE]; devSel[0] = '\0'; DEBUG(4, "Dialing %s\n", phone); dfp = fopen(DEVFILE, "r"); ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); ! acufound = 0; ! ntries = 0; while (rddev(dfp, &dev) != FAIL) { /* * for each ACU L.sys line, try at most twice *************** *** 308,314 **** * To try 'harder' to connect to a remote site, * use multiple L.sys entries. */ ! if (acustatus > TRYCALLS) break; if (strcmp(flds[F_CLASS], dev.D_class) != SAME) continue; --- 313,319 ---- * To try 'harder' to connect to a remote site, * use multiple L.sys entries. */ ! if (ntries > TRYCALLS) break; if (strcmp(flds[F_CLASS], dev.D_class) != SAME) continue; *************** *** 319,337 **** continue; } for(cd = condevs; cd->CU_meth != NULL; cd++) { ! if (snccmp(line, cd->CU_meth) == SAME) { ! if (snccmp(dev.D_brand, cd->CU_brand) == SAME) ! break; ! strncpy(nobrand, dev.D_brand, sizeof nobrand); ! } } ! ! if (mlock(dev.D_line) == FAIL) { ! acustatus++; continue; } ! if (acustatus < 1) ! acustatus = 1; /* has been found */ #ifdef DIALINOUT #ifdef ALLACUINOUT if (1) { --- 324,342 ---- continue; } for(cd = condevs; cd->CU_meth != NULL; cd++) { ! if (snccmp(line, cd->CU_meth) == SAME && ! snccmp(dev.D_brand, cd->CU_brand) == SAME) ! break; } ! if (cd->CU_meth == NULL) { ! logent(dev.D_brand, "unsupported ACU type"); continue; } ! acufound = 1; ! ! if (mlock(dev.D_line) == FAIL) ! continue; ! #ifdef DIALINOUT #ifdef ALLACUINOUT if (1) { *************** *** 347,353 **** #endif DIALINOUT DEBUG(4, "Using %s\n", cd->CU_brand); ! acustatus++; fd = (*(cd->CU_open))(phone, flds, &dev); if (fd > 0) { CU_end = cd->CU_clos; /* point CU_end at close func */ --- 352,358 ---- #endif DIALINOUT DEBUG(4, "Using %s\n", cd->CU_brand); ! ntries++; fd = (*(cd->CU_open))(phone, flds, &dev); if (fd > 0) { CU_end = cd->CU_clos; /* point CU_end at close func */ *************** *** 359,371 **** retval = CF_DIAL; } fclose(dfp); ! if (acustatus == 0) { ! if (nobrand[0]) ! logent(nobrand, "unsupported ACU type"); ! else ! logent("L-devices", "No appropriate ACU"); ! } ! if (acustatus == 1) logent("DEVICE", "NO"); return retval; } --- 364,372 ---- retval = CF_DIAL; } fclose(dfp); ! if (!acufound) ! logent("L-devices", "No appropriate ACU"); ! else if (ntries == 0) logent("DEVICE", "NO"); return retval; }