/* Send command by copying into command buffer as far forward as possible, after any pending output. Indicate an error by returning 0 if there is not space for the command. */ static int send_slow( register struct arcunit *up, int fd, const char *s ) { int sl = strlen(s); int spaceleft = space_left(up); #ifdef DEBUG if(debug > 1) { printf("arc: spaceleft = %d.\n", spaceleft); } #endif if(spaceleft < sl) { /* Should not normally happen... */ #ifdef DEBUG msyslog(LOG_NOTICE, "ARCRON: send-buffer overrun (%d/%d)", sl, spaceleft); #endif return(0); /* FAILED! */ } /* Copy in the command to be sent. */ while(*s && spaceleft > 0) { up->cmdqueue[CMDQUEUELEN - spaceleft--] = *s++; } return(1); }
inline void buffer::insert(char const* first, char const* last) { INVARIANT_CHECK; std::size_t n = last - first; #ifdef TORRENT_BUFFER_DEBUG if (m_pending_copy) { std::copy(m_write_cursor - m_pending_copy, m_write_cursor , m_debug.end() - m_pending_copy); m_pending_copy = 0; } m_debug.insert(m_debug.end(), first, last); #endif if (space_left() < n) { reserve(capacity() + n); } m_empty = false; char const* end = (m_last - m_write_cursor) < (std::ptrdiff_t)n ? m_last : m_write_cursor + n; std::size_t copied = end - m_write_cursor; std::memcpy(m_write_cursor, first, copied); m_write_cursor += copied; if (m_write_cursor > m_read_end) m_read_end = m_write_cursor; first += copied; n -= copied; if (n == 0) return; assert(m_write_cursor == m_last); m_write_cursor = m_first; memcpy(m_write_cursor, first, n); m_write_cursor += n; }
int Q3DockAreaLayout::layoutItems(const QRect &rect, bool testonly) { if (dockWindows->isEmpty()) return 0; dirty = false; // some corrections QRect r = rect; if (orientation() == Qt::Vertical) r.setHeight(r.height() - 3); // init lines.clear(); ls.clear(); int start = start_pos(r, orientation()); int pos = start; int sectionpos = 0; int linestrut = 0; QList<Q3DockData> lastLine; int tbstrut = -1; int maxsize = size_extent(rect.size(), orientation()); int visibleWindows = 0; // go through all widgets in the dock for (int i = 0; i < dockWindows->size(); ++i) { Q3DockWindow *dw = dockWindows->at(i); if (dw->isHidden()) continue; ++visibleWindows; // find position for the widget: This is the maximum of the // end of the previous widget and the offset of the widget. If // the position + the width of the widget dosn't fit into the // dock, try moving it a bit back, if possible. int op = pos; int dockExtend = dock_extent(dw, orientation(), maxsize); if (!dw->isStretchable()) { pos = qMax(pos, dw->offset()); if (pos + dockExtend > size_extent(r.size(), orientation()) - 1) pos = qMax(op, size_extent(r.size(), orientation()) - 1 - dockExtend); } if (!lastLine.isEmpty() && !dw->newLine() && space_left(rect, pos, orientation()) < dockExtend) shrink_extend(dw, dockExtend, space_left(rect, pos, orientation()), orientation()); // if the current widget doesn't fit into the line anymore and it is not the first widget of the line if (!lastLine.isEmpty() && (space_left(rect, pos, orientation()) < dockExtend || dw->newLine())) { if (!testonly) // place the last line, if not in test mode place_line(lastLine, orientation(), linestrut, size_extent(r.size(), orientation()), tbstrut, maxsize, this); // remember the line coordinats of the last line if (orientation() == Qt::Horizontal) lines.append(QRect(0, sectionpos, r.width(), linestrut)); else lines.append(QRect(sectionpos, 0, linestrut, r.height())); // do some clearing for the next line lastLine.clear(); sectionpos += linestrut; linestrut = 0; pos = start; tbstrut = -1; } // remember first widget of a line if (lastLine.isEmpty()) { ls.append(dw); // try to make the best position int op = pos; if (!dw->isStretchable()) pos = qMax(pos, dw->offset()); if (pos + dockExtend > size_extent(r.size(), orientation()) - 1) pos = qMax(op, size_extent(r.size(), orientation()) - 1 - dockExtend); } // do some calculations and add the remember the rect which the docking widget requires for the placing QRect dwRect(pos, sectionpos, dockExtend, dock_strut(dw, orientation() )); lastLine.append(Q3DockData(dw, dwRect)); if (qobject_cast<Q3ToolBar*>(dw)) tbstrut = qMax(tbstrut, dock_strut(dw, orientation())); linestrut = qMax(dock_strut(dw, orientation()), linestrut); add_size(dockExtend, pos, orientation()); } // if some stuff was not placed/stored yet, do it now if (!testonly) place_line(lastLine, orientation(), linestrut, size_extent(r.size(), orientation()), tbstrut, maxsize, this); if (orientation() == Qt::Horizontal) lines.append(QRect(0, sectionpos, r.width(), linestrut)); else lines.append(QRect(sectionpos, 0, linestrut, r.height())); if (lines.size() >= 2 && *(--lines.end()) == *(--(--lines.end()))) lines.removeLast(); bool hadResizable = false; for (int i = 0; i < dockWindows->size(); ++i) { Q3DockWindow *dw = dockWindows->at(i); if (!dw->isVisibleTo(parentWidget)) continue; hadResizable = hadResizable || dw->isResizeEnabled(); dw->updateSplitterVisibility(visibleWindows > 1); //!dw->area()->isLastDockWindow(dw)); if (Q3ToolBar *tb = qobject_cast<Q3ToolBar *>(dw)) tb->checkForExtension(dw->size()); } return sectionpos + linestrut; }
/* * arc_receive - receive data from the serial interface */ static void arc_receive( struct recvbuf *rbufp ) { register struct arcunit *up; struct refclockproc *pp; struct peer *peer; char c; int i, n, wday, month, flags, status; int arc_last_offset; static int quality_average = 0; static int quality_sum = 0; static int quality_polls = 0; /* * Initialize pointers and read the timecode and timestamp */ peer = (struct peer *)rbufp->recv_srcclock; pp = peer->procptr; up = (struct arcunit *)pp->unitptr; /* If the command buffer is empty, and we are resyncing, insert a g\r quality request into it to poll for signal quality again. */ if((up->resyncing) && (space_left(up) == CMDQUEUELEN)) { #ifdef DEBUG if(debug > 1) { printf("arc: inserting signal-quality poll.\n"); } #endif send_slow(up, pp->io.fd, "g\r"); } /* The `arc_last_offset' is the offset in lastcode[] of the last byte received, and which we assume actually received the input timestamp. (When we get round to using tty_clk and it is available, we assume that we will receive the whole timecode with the trailing \r, and that that \r will be timestamped. But this assumption also works if receive the characters one-by-one.) */ arc_last_offset = pp->lencode+rbufp->recv_length - 1; /* We catch a timestamp iff: * The command code is `o' for a timestamp. * If ARCRON_MULTIPLE_SAMPLES is undefined then we must have exactly char in the buffer (the command code) so that we only sample the first character of the timecode as our `on-time' character. * The first character in the buffer is not the echoed `\r' from the `o` command (so if we are to timestamp an `\r' it must not be first in the receive buffer with lencode==1. (Even if we had other characters following it, we probably would have a premature timestamp on the '\r'.) * We have received at least one character (I cannot imagine how it could be otherwise, but anyway...). */ c = rbufp->recv_buffer[0]; if((pp->a_lastcode[0] == 'o') && #ifndef ARCRON_MULTIPLE_SAMPLES (pp->lencode == 1) && #endif ((pp->lencode != 1) || (c != '\r')) && (arc_last_offset >= 1)) { /* Note that the timestamp should be corrected if >1 char rcvd. */ l_fp timestamp; timestamp = rbufp->recv_time; #ifdef DEBUG if(debug) { /* Show \r as `R', other non-printing char as `?'. */ printf("arc: stamp -->%c<-- (%d chars rcvd)\n", ((c == '\r') ? 'R' : (isgraph((int)c) ? c : '?')), rbufp->recv_length); } #endif /* Now correct timestamp by offset of last byte received---we subtract from the receive time the delay implied by the extra characters received. Reject the input if the resulting code is too long, but allow for the trailing \r, normally not used but a good handle for tty_clk or somesuch kernel timestamper. */ if(arc_last_offset > LENARC) { #ifdef DEBUG if(debug) { printf("arc: input code too long (%d cf %d); rejected.\n", arc_last_offset, LENARC); } #endif pp->lencode = 0; refclock_report(peer, CEVNT_BADREPLY); return; } L_SUBUF(×tamp, charoffsets[arc_last_offset]); #ifdef DEBUG if(debug > 1) { printf( "arc: %s%d char(s) rcvd, the last for lastcode[%d]; -%sms offset applied.\n", ((rbufp->recv_length > 1) ? "*** " : ""), rbufp->recv_length, arc_last_offset, mfptoms((unsigned long)0, charoffsets[arc_last_offset], 1)); } #endif #ifdef ARCRON_MULTIPLE_SAMPLES /* If taking multiple samples, capture the current adjusted sample iff: * No timestamp has yet been captured (it is zero), OR * This adjusted timestamp is earlier than the one already captured, on the grounds that this one suffered less delay in being delivered to us and is more accurate. */ if(L_ISZERO(&(up->lastrec)) || L_ISGEQ(&(up->lastrec), ×tamp)) #endif { #ifdef DEBUG if(debug > 1) { printf("arc: system timestamp captured.\n"); #ifdef ARCRON_MULTIPLE_SAMPLES if(!L_ISZERO(&(up->lastrec))) { l_fp diff; diff = up->lastrec; L_SUB(&diff, ×tamp); printf("arc: adjusted timestamp by -%sms.\n", mfptoms(diff.l_i, diff.l_f, 3)); } #endif } #endif up->lastrec = timestamp; } } /* Just in case we still have lots of rubbish in the buffer... */ /* ...and to avoid the same timestamp being reused by mistake, */ /* eg on receipt of the \r coming in on its own after the */ /* timecode. */ if(pp->lencode >= LENARC) { #ifdef DEBUG if(debug && (rbufp->recv_buffer[0] != '\r')) { printf("arc: rubbish in pp->a_lastcode[].\n"); } #endif pp->lencode = 0; return; } /* Append input to code buffer, avoiding overflow. */ for(i = 0; i < rbufp->recv_length; i++) { if(pp->lencode >= LENARC) { break; } /* Avoid overflow... */ c = rbufp->recv_buffer[i]; /* Drop trailing '\r's and drop `h' command echo totally. */ if(c != '\r' && c != 'h') { pp->a_lastcode[pp->lencode++] = c; } /* If we've just put an `o' in the lastcode[0], clear the timestamp in anticipation of a timecode arriving soon. We would expect to get to process this before any of the timecode arrives. */ if((c == 'o') && (pp->lencode == 1)) { L_CLR(&(up->lastrec)); #ifdef DEBUG if(debug > 1) { printf("arc: clearing timestamp.\n"); } #endif } } if (pp->lencode == 0) return; /* Handle a quality message. */ if(pp->a_lastcode[0] == 'g') { int r, q; if(pp->lencode < 3) { return; } /* Need more data... */ r = (pp->a_lastcode[1] & 0x7f); /* Strip parity. */ q = (pp->a_lastcode[2] & 0x7f); /* Strip parity. */ if(((q & 0x70) != 0x30) || ((q & 0xf) > MAX_CLOCK_QUALITY) || ((r & 0x70) != 0x30)) { /* Badly formatted response. */ #ifdef DEBUG if(debug) { printf("arc: bad `g' response %2x %2x.\n", r, q); } #endif return; } if(r == '3') { /* Only use quality value whilst sync in progress. */ if (up->quality_stamp < current_time) { struct calendar cal; l_fp new_stamp; get_systime (&new_stamp); caljulian (new_stamp.l_ui, &cal); up->quality_stamp = current_time + 60 - cal.second + 5; quality_sum = 0; quality_polls = 0; } quality_sum += (q & 0xf); quality_polls++; quality_average = (quality_sum / quality_polls); #ifdef DEBUG if(debug) { printf("arc: signal quality %d (%d).\n", quality_average, (q & 0xf)); } #endif } else if( /* (r == '2') && */ up->resyncing) { up->quality = quality_average; #ifdef DEBUG if(debug) { printf("arc: sync finished, signal quality %d: %s\n", up->quality, quality_action(up->quality)); } #endif msyslog(LOG_NOTICE, "ARCRON: sync finished, signal quality %d: %s", up->quality, quality_action(up->quality)); up->resyncing = 0; /* Resync is over. */ quality_average = 0; quality_sum = 0; quality_polls = 0; #ifdef ARCRON_KEEN /* Clock quality dubious; resync earlier than usual. */ if((up->quality == QUALITY_UNKNOWN) || (up->quality < MIN_CLOCK_QUALITY_OK)) { up->next_resync = current_time + RETRY_RESYNC_TIME; } #endif } pp->lencode = 0; return; } /* Stop now if this is not a timecode message. */ if(pp->a_lastcode[0] != 'o') { pp->lencode = 0; refclock_report(peer, CEVNT_BADREPLY); return; } /* If we don't have enough data, wait for more... */ if(pp->lencode < LENARC) { return; } /* WE HAVE NOW COLLECTED ONE TIMESTAMP (phew)... */ #ifdef DEBUG if(debug > 1) { printf("arc: NOW HAVE TIMESTAMP...\n"); } #endif /* But check that we actually captured a system timestamp on it. */ if(L_ISZERO(&(up->lastrec))) { #ifdef DEBUG if(debug) { printf("arc: FAILED TO GET SYSTEM TIMESTAMP\n"); } #endif pp->lencode = 0; refclock_report(peer, CEVNT_BADREPLY); return; } /* Append a mark of the clock's received signal quality for the benefit of Derek Mulcahy's Tcl/Tk utility (we map the `unknown' quality value to `6' for his s/w) and terminate the string for sure. This should not go off the buffer end. */ pp->a_lastcode[pp->lencode] = ((up->quality == QUALITY_UNKNOWN) ? '6' : ('0' + up->quality)); pp->a_lastcode[pp->lencode + 1] = '\0'; /* Terminate for printf(). */ #ifdef PRE_NTP420 /* We don't use the micro-/milli- second part... */ pp->usec = 0; pp->msec = 0; #else /* We don't use the nano-second part... */ pp->nsec = 0; #endif /* Validate format and numbers. */ if (pp->a_lastcode[0] != 'o' || !get2(pp->a_lastcode + 1, &pp->hour) || !get2(pp->a_lastcode + 3, &pp->minute) || !get2(pp->a_lastcode + 5, &pp->second) || !get1(pp->a_lastcode + 7, &wday) || !get2(pp->a_lastcode + 8, &pp->day) || !get2(pp->a_lastcode + 10, &month) || !get2(pp->a_lastcode + 12, &pp->year)) { #ifdef DEBUG /* Would expect to have caught major problems already... */ if(debug) { printf("arc: badly formatted data.\n"); } #endif pp->lencode = 0; refclock_report(peer, CEVNT_BADREPLY); return; } flags = pp->a_lastcode[14]; status = pp->a_lastcode[15]; #ifdef DEBUG if(debug) { printf("arc: status 0x%.2x flags 0x%.2x\n", flags, status); } #endif n = 9; /* Validate received values at least enough to prevent internal array-bounds problems, etc. */ if((pp->hour < 0) || (pp->hour > 23) || (pp->minute < 0) || (pp->minute > 59) || (pp->second < 0) || (pp->second > 60) /*Allow for leap seconds.*/ || (wday < 1) || (wday > 7) || (pp->day < 1) || (pp->day > 31) || (month < 1) || (month > 12) || (pp->year < 0) || (pp->year > 99)) { /* Data out of range. */ pp->lencode = 0; refclock_report(peer, CEVNT_BADREPLY); return; } if(peer->MODE == 0) { /* compatiblity to original version */ int bst = flags; /* Check that BST/UTC bits are the complement of one another. */ if(!(bst & 2) == !(bst & 4)) { pp->lencode = 0; refclock_report(peer, CEVNT_BADREPLY); return; } } if(status & 0x8) { msyslog(LOG_NOTICE, "ARCRON: battery low"); } /* Year-2000 alert! */ /* Attempt to wrap 2-digit date into sensible window. */ if(pp->year < YEAR_PIVOT) { pp->year += 100; } /* Y2KFixes */ pp->year += 1900; /* use full four-digit year */ /* Y2KFixes */ /* Attempt to do the right thing by screaming that the code will soon break when we get to the end of its useful life. What a hero I am... PLEASE FIX LEAP-YEAR AND WRAP CODE IN 209X! */ if(pp->year >= YEAR_PIVOT+2000-2 ) { /* Y2KFixes */ /*This should get attention B^> */ msyslog(LOG_NOTICE, "ARCRON: fix me! EITHER YOUR DATE IS BADLY WRONG or else I will break soon!"); } #ifdef DEBUG if(debug) { printf("arc: n=%d %02d:%02d:%02d %02d/%02d/%04d %1d %1d\n", n, pp->hour, pp->minute, pp->second, pp->day, month, pp->year, flags, status); } #endif /* The status value tested for is not strictly supported by the clock spec since the value of bit 2 (0x4) is claimed to be undefined for MSF, yet does seem to indicate if the last resync was successful or not. */ pp->leap = LEAP_NOWARNING; status &= 0x7; if(status == 0x3) { if(status != up->status) { msyslog(LOG_NOTICE, "ARCRON: signal acquired"); } } else { if(status != up->status) { msyslog(LOG_NOTICE, "ARCRON: signal lost"); pp->leap = LEAP_NOTINSYNC; /* MSF clock is free-running. */ up->status = status; pp->lencode = 0; refclock_report(peer, CEVNT_FAULT); return; } } up->status = status; if (peer->MODE == 0) { /* compatiblity to original version */ int bst = flags; pp->day += moff[month - 1]; if(isleap_4(pp->year) && month > 2) { pp->day++; }/* Y2KFixes */ /* Convert to UTC if required */ if(bst & 2) { pp->hour--; if (pp->hour < 0) { pp->hour = 23; pp->day--; /* If we try to wrap round the year * (BST on 1st Jan), reject.*/ if(pp->day < 0) { pp->lencode = 0; refclock_report(peer, CEVNT_BADTIME); return; } } } } if(peer->MODE > 0) { if(pp->sloppyclockflag & CLK_FLAG1) { struct tm local; struct tm *gmtp; time_t unixtime; /* * Convert to GMT for sites that distribute localtime. * This means we have to do Y2K conversion on the * 2-digit year; otherwise, we get the time wrong. */ memset(&local, 0, sizeof(local)); local.tm_year = pp->year-1900; local.tm_mon = month-1; local.tm_mday = pp->day; local.tm_hour = pp->hour; local.tm_min = pp->minute; local.tm_sec = pp->second; switch (peer->MODE) { case 1: local.tm_isdst = (flags & 2); break; case 2: local.tm_isdst = (flags & 2); break; case 3: switch (flags & 3) { case 0: /* It is unclear exactly when the Arcron changes from DST->ST and ST->DST. Testing has shown this to be irregular. For the time being, let the OS decide. */ local.tm_isdst = 0; #ifdef DEBUG if (debug) printf ("arc: DST = 00 (0)\n"); #endif break; case 1: /* dst->st time */ local.tm_isdst = -1; #ifdef DEBUG if (debug) printf ("arc: DST = 01 (1)\n"); #endif break; case 2: /* st->dst time */ local.tm_isdst = -1; #ifdef DEBUG if (debug) printf ("arc: DST = 10 (2)\n"); #endif break; case 3: /* dst time */ local.tm_isdst = 1; #ifdef DEBUG if (debug) printf ("arc: DST = 11 (3)\n"); #endif break; } break; default: msyslog(LOG_NOTICE, "ARCRON: Invalid mode %d", peer->MODE); return; break; } unixtime = mktime (&local); if ((gmtp = gmtime (&unixtime)) == NULL) { pp->lencode = 0; refclock_report (peer, CEVNT_FAULT); return; } pp->year = gmtp->tm_year+1900; month = gmtp->tm_mon+1; pp->day = ymd2yd(pp->year,month,gmtp->tm_mday); /* pp->day = gmtp->tm_yday; */ pp->hour = gmtp->tm_hour; pp->minute = gmtp->tm_min; pp->second = gmtp->tm_sec; #ifdef DEBUG if (debug) { printf ("arc: time is %04d/%02d/%02d %02d:%02d:%02d UTC\n", pp->year,month,gmtp->tm_mday,pp->hour,pp->minute, pp->second); } #endif } else { /* * For more rational sites distributing UTC */ pp->day = ymd2yd(pp->year,month,pp->day); } } if (peer->MODE == 0) { /* compatiblity to original version */ /* If clock signal quality is * unknown, revert to default PRECISION...*/ if(up->quality == QUALITY_UNKNOWN) { peer->precision = PRECISION; } else { /* ...else improve precision if flag3 is set... */ peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? HIGHPRECISION : PRECISION); } } else { if ((status == 0x3) && (pp->sloppyclockflag & CLK_FLAG2)) { peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? HIGHPRECISION : PRECISION); } else if (up->quality == QUALITY_UNKNOWN) { peer->precision = PRECISION; } else { peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ? HIGHPRECISION : PRECISION); } } /* Notice and log any change (eg from initial defaults) for flags. */ if(up->saved_flags != pp->sloppyclockflag) { #ifdef DEBUG msyslog(LOG_NOTICE, "ARCRON: flags enabled: %s%s%s%s", ((pp->sloppyclockflag & CLK_FLAG1) ? "1" : "."), ((pp->sloppyclockflag & CLK_FLAG2) ? "2" : "."), ((pp->sloppyclockflag & CLK_FLAG3) ? "3" : "."), ((pp->sloppyclockflag & CLK_FLAG4) ? "4" : ".")); /* Note effects of flags changing... */ if(debug) { printf("arc: PRECISION = %d.\n", peer->precision); } #endif up->saved_flags = pp->sloppyclockflag; } /* Note time of last believable timestamp. */ pp->lastrec = up->lastrec; #ifdef ARCRON_LEAPSECOND_KEEN /* Find out if a leap-second might just have happened... (ie is this the first hour of the first day of Jan or Jul?) */ if((pp->hour == 0) && (pp->day == 1) && ((month == 1) || (month == 7))) { if(possible_leap >= 0) { /* A leap may have happened, and no resync has started yet...*/ possible_leap = 1; } } else { /* Definitely not leap-second territory... */ possible_leap = 0; } #endif if (!refclock_process(pp)) { pp->lencode = 0; refclock_report(peer, CEVNT_BADTIME); return; } record_clock_stats(&peer->srcadr, pp->a_lastcode); refclock_receive(peer); }