/*! * return true iff we have a current database (called by both sync * sites and non-sync sites) How do we determine this? If we're the * sync site, we wait until recovery has finished fetching and * re-labelling its dbase (it may still be trying to propagate it out * to everyone else; that's THEIR problem). If we're not the sync * site, then we must have a dbase labelled with the right version, * and we must have a currently-good sync site. */ int urecovery_AllBetter(register struct ubik_dbase *adbase, int areadAny) { register afs_int32 rcode; ubik_dprint_25("allbetter checking\n"); rcode = 0; if (areadAny) { if (ubik_dbase->version.epoch > 1) rcode = 1; /* Happy with any good version of database */ } /* Check if we're sync site and we've got the right data */ else if (ubeacon_AmSyncSite() && (urecovery_state & UBIK_RECHAVEDB)) { rcode = 1; } /* next, check if we're aux site, and we've ever been sent the * right data (note that if a dbase update fails, we won't think * that the sync site is still the sync site, 'cause it won't talk * to us until a timeout period has gone by. When we recover, we * leave this clear until we get a new dbase */ else if ((uvote_GetSyncSite() && (vcmp(ubik_dbVersion, ubik_dbase->version) == 0))) { /* && order is important */ rcode = 1; } ubik_dprint_25("allbetter: returning %d\n", rcode); return rcode; }
void GetIServer() { int offset; void *vfunc = NULL; /* Get the offset into CreateFakeClient */ if (!g_pGameConf->GetOffset("sv", &offset)) { return; } #if defined METAMOD_PLAPI_VERSION /* Get the CreateFakeClient function pointer */ if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient))) { return; } /* Check if we're on the expected function */ if (!vcmp(vfunc, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN)) { return; } /* Finally we have the interface we were looking for */ iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset); #else /* Get the interface manually */ SourceHook::MemFuncInfo info = {true, -1, 0, 0}; SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info); vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex); if (!vfunc) { void **vtable = *reinterpret_cast<void ***>(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs); vfunc = vtable[info.vtblindex]; } /* Check if we're on the expected function */ if (!vcmp(vfunc, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN)) { return; } iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset); #endif }
void read_exif_header(FILE *fp, unsigned char *buffer, bool *is_valid, bool *is_little_endian) { // SOI vread(buffer, 2, fp, is_valid); vcmp(SOI, buffer, 2, is_valid); // APP1 Marker vread(buffer, 2, fp, is_valid); vcmp(APP1_MARKER, buffer, 2, is_valid); // EXIF Identifier Code vseek(fp, 2, SEEK_CUR, is_valid); // Skip (APP1 Length) vread(buffer, 6, fp, is_valid); vcmp(EXIF_IDENT_CODE, buffer, 6, is_valid); // Byte Order vread(buffer, 2, fp, is_valid); if(*is_valid && memcmp(TIFF_LITTLE_ENDIAN, buffer, 2) == 0) *is_little_endian = true; else if(*is_valid && memcmp(TIFF_BIG_ENDIAN, buffer, 2) == 0) *is_little_endian = false; else *is_valid = false; // EXIF Fixed Code vread(buffer, 2, fp, is_valid); vrev(buffer, 2, is_valid, is_little_endian); vcmp(EXIF_FIXED_CODE, buffer, 2, is_valid); // 0th IFD Offset vread(buffer, 4, fp, is_valid); vrev(buffer, 4, is_valid, is_little_endian); // 0th IFD vseek(fp, todecimal(buffer, 4) - 8, SEEK_CUR, is_valid); // 0th IFD Entry Count vread(buffer, 2, fp, is_valid); vrev(buffer, 2, is_valid, is_little_endian); }
int main(int argc, char** argv) { #ifdef LOGGING rlog::RLogInit(argc, argv); #endif std::string complex_fn, values_fn, output_prefix; bool skip_infinite_vines = false, explicit_events = false, save_vines = false; program_options(argc, argv, complex_fn, values_fn, output_prefix, skip_infinite_vines, save_vines, explicit_events); // Read in the complex PLVineyard::LSFiltration simplices; read_simplices(complex_fn, simplices); std::cout << "Complex read, size: " << simplices.size() << std::endl; // Read in vertex values VertexVectorVector vertices; read_vertices(values_fn, vertices); // Setup the vineyard VertexEvaluator veval(vertices[0]); PLVineyard::VertexComparison vcmp(veval); PLVineyard::SimplexComparison scmp(vcmp); simplices.sort(scmp); PLVineyard v(boost::counting_iterator<Vertex>(0), boost::counting_iterator<Vertex>(vertices[0].size()), simplices, veval); std::cout << "Pairing computed" << std::endl; // Compute vineyard for (size_t i = 1; i < vertices.size(); ++i) { veval = VertexEvaluator(vertices[i]); v.compute_vineyard(veval); std::cout << "Processed frame: " << i << std::endl; } std::cout << "Vineyard computed" << std::endl; if (save_vines) v.vineyard().save_vines(output_prefix, skip_infinite_vines); else v.vineyard().save_edges(output_prefix, skip_infinite_vines); }
/* * Implements version sort (-V). */ static int versioncoll(struct key_value *kv1, struct key_value *kv2, size_t offset __unused) { struct bwstring *s1, *s2; s1 = kv1->k; s2 = kv2->k; if (debug_sort) { bwsprintf(stdout, s1, "; k1=<", ">"); bwsprintf(stdout, s2, ", k2=<", ">"); } if (s1 == s2) return (0); return (vcmp(s1, s2)); }
/*! * \brief Main interaction loop for the recovery manager * * The recovery light-weight process only runs when you're the * synchronization site. It performs the following tasks, if and only * if the prerequisite tasks have been performed successfully (it * keeps track of which ones have been performed in its bit map, * \p urecovery_state). * * First, it is responsible for probing that all servers are up. This * is the only operation that must be performed even if this is not * yet the sync site, since otherwise this site may not notice that * enough other machines are running to even elect this guy to be the * sync site. * * After that, the recovery process does nothing until the beacon and * voting modules manage to get this site elected sync site. * * After becoming sync site, recovery first attempts to find the best * database available in the network (it must do this in order to * ensure finding the latest committed data). After finding the right * database, it must fetch this dbase to the sync site. * * After fetching the dbase, it relabels it with a new version number, * to ensure that everyone recognizes this dbase as the most recent * dbase. * * One the dbase has been relabelled, this machine can start handling * requests. However, the recovery module still has one more task: * propagating the dbase out to everyone who is up in the network. */ void * urecovery_Interact(void *dummy) { afs_int32 code, tcode; struct ubik_server *bestServer = NULL; struct ubik_server *ts; int dbok, doingRPC, now; afs_int32 lastProbeTime; /* if we're the sync site, the best db version we've found yet */ static struct ubik_version bestDBVersion; struct ubik_version tversion; struct timeval tv; int length, tlen, offset, file, nbytes; struct rx_call *rxcall; char tbuffer[1024]; struct ubik_stat ubikstat; struct in_addr inAddr; char hoststr[16]; char pbuffer[1028]; int fd = -1; afs_int32 pass; afs_pthread_setname_self("recovery"); /* otherwise, begin interaction */ urecovery_state = 0; lastProbeTime = 0; while (1) { /* Run through this loop every 4 seconds */ tv.tv_sec = 4; tv.tv_usec = 0; #ifdef AFS_PTHREAD_ENV select(0, 0, 0, 0, &tv); #else IOMGR_Select(0, 0, 0, 0, &tv); #endif ubik_dprint("recovery running in state %x\n", urecovery_state); /* Every 30 seconds, check all the down servers and mark them * as up if they respond. When a server comes up or found to * not be current, then re-find the the best database and * propogate it. */ if ((now = FT_ApproxTime()) > 30 + lastProbeTime) { for (ts = ubik_servers, doingRPC = 0; ts; ts = ts->next) { UBIK_BEACON_LOCK; if (!ts->up) { UBIK_BEACON_UNLOCK; doingRPC = 1; code = DoProbe(ts); if (code == 0) { UBIK_BEACON_LOCK; ts->up = 1; UBIK_BEACON_UNLOCK; DBHOLD(ubik_dbase); urecovery_state &= ~UBIK_RECFOUNDDB; DBRELE(ubik_dbase); } } else { UBIK_BEACON_UNLOCK; DBHOLD(ubik_dbase); if (!ts->currentDB) urecovery_state &= ~UBIK_RECFOUNDDB; DBRELE(ubik_dbase); } } if (doingRPC) now = FT_ApproxTime(); lastProbeTime = now; } /* Mark whether we are the sync site */ DBHOLD(ubik_dbase); if (!ubeacon_AmSyncSite()) { urecovery_state &= ~UBIK_RECSYNCSITE; DBRELE(ubik_dbase); continue; /* nothing to do */ } urecovery_state |= UBIK_RECSYNCSITE; /* If a server has just come up or if we have not found the * most current database, then go find the most current db. */ if (!(urecovery_state & UBIK_RECFOUNDDB)) { DBRELE(ubik_dbase); bestServer = (struct ubik_server *)0; bestDBVersion.epoch = 0; bestDBVersion.counter = 0; for (ts = ubik_servers; ts; ts = ts->next) { UBIK_BEACON_LOCK; if (!ts->up) { UBIK_BEACON_UNLOCK; continue; /* don't bother with these guys */ } UBIK_BEACON_UNLOCK; if (ts->isClone) continue; UBIK_ADDR_LOCK; code = DISK_GetVersion(ts->disk_rxcid, &ts->version); UBIK_ADDR_UNLOCK; if (code == 0) { /* perhaps this is the best version */ if (vcmp(ts->version, bestDBVersion) > 0) { /* new best version */ bestDBVersion = ts->version; bestServer = ts; } } } /* take into consideration our version. Remember if we, * the sync site, have the best version. Also note that * we may need to send the best version out. */ DBHOLD(ubik_dbase); if (vcmp(ubik_dbase->version, bestDBVersion) >= 0) { bestDBVersion = ubik_dbase->version; bestServer = (struct ubik_server *)0; urecovery_state |= UBIK_RECHAVEDB; } else { /* Clear the flag only when we know we have to retrieve * the db. Because urecovery_AllBetter() looks at it. */ urecovery_state &= ~UBIK_RECHAVEDB; } urecovery_state |= UBIK_RECFOUNDDB; urecovery_state &= ~UBIK_RECSENTDB; } if (!(urecovery_state & UBIK_RECFOUNDDB)) { DBRELE(ubik_dbase); continue; /* not ready */ } /* If we, the sync site, do not have the best db version, then * go and get it from the server that does. */ if ((urecovery_state & UBIK_RECHAVEDB) || !bestServer) { urecovery_state |= UBIK_RECHAVEDB; } else { /* we don't have the best version; we should fetch it. */ urecovery_AbortAll(ubik_dbase); /* Rx code to do the Bulk fetch */ file = 0; offset = 0; UBIK_ADDR_LOCK; rxcall = rx_NewCall(bestServer->disk_rxcid); ubik_print("Ubik: Synchronize database with server %s\n", afs_inet_ntoa_r(bestServer->addr[0], hoststr)); UBIK_ADDR_UNLOCK; code = StartDISK_GetFile(rxcall, file); if (code) { ubik_dprint("StartDiskGetFile failed=%d\n", code); goto FetchEndCall; } nbytes = rx_Read(rxcall, (char *)&length, sizeof(afs_int32)); length = ntohl(length); if (nbytes != sizeof(afs_int32)) { ubik_dprint("Rx-read length error=%d\n", code = BULK_ERROR); code = EIO; goto FetchEndCall; } /* give invalid label during file transit */ UBIK_VERSION_LOCK; tversion.epoch = 0; code = (*ubik_dbase->setlabel) (ubik_dbase, file, &tversion); UBIK_VERSION_UNLOCK; if (code) { ubik_dprint("setlabel io error=%d\n", code); goto FetchEndCall; } snprintf(pbuffer, sizeof(pbuffer), "%s.DB%s%d.TMP", ubik_dbase->pathName, (file<0)?"SYS":"", (file<0)?-file:file); fd = open(pbuffer, O_CREAT | O_RDWR | O_TRUNC, 0600); if (fd < 0) { code = errno; goto FetchEndCall; } code = lseek(fd, HDRSIZE, 0); if (code != HDRSIZE) { close(fd); goto FetchEndCall; } pass = 0; while (length > 0) { tlen = (length > sizeof(tbuffer) ? sizeof(tbuffer) : length); #ifndef AFS_PTHREAD_ENV if (pass % 4 == 0) IOMGR_Poll(); #endif nbytes = rx_Read(rxcall, tbuffer, tlen); if (nbytes != tlen) { ubik_dprint("Rx-read bulk error=%d\n", code = BULK_ERROR); code = EIO; close(fd); goto FetchEndCall; } nbytes = write(fd, tbuffer, tlen); pass++; if (nbytes != tlen) { code = UIOERROR; close(fd); goto FetchEndCall; } offset += tlen; length -= tlen; } code = close(fd); if (code) goto FetchEndCall; code = EndDISK_GetFile(rxcall, &tversion); FetchEndCall: tcode = rx_EndCall(rxcall, code); if (!code) code = tcode; if (!code) { /* we got a new file, set up its header */ urecovery_state |= UBIK_RECHAVEDB; UBIK_VERSION_LOCK; memcpy(&ubik_dbase->version, &tversion, sizeof(struct ubik_version)); snprintf(tbuffer, sizeof(tbuffer), "%s.DB%s%d", ubik_dbase->pathName, (file<0)?"SYS":"", (file<0)?-file:file); #ifdef AFS_NT40_ENV snprintf(pbuffer, sizeof(pbuffer), "%s.DB%s%d.OLD", ubik_dbase->pathName, (file<0)?"SYS":"", (file<0)?-file:file); code = unlink(pbuffer); if (!code) code = rename(tbuffer, pbuffer); snprintf(pbuffer, sizeof(pbuffer), "%s.DB%s%d.TMP", ubik_dbase->pathName, (file<0)?"SYS":"", (file<0)?-file:file); #endif if (!code) code = rename(pbuffer, tbuffer); if (!code) { (*ubik_dbase->open) (ubik_dbase, file); /* after data is good, sync disk with correct label */ code = (*ubik_dbase->setlabel) (ubik_dbase, 0, &ubik_dbase->version); } UBIK_VERSION_UNLOCK; #ifdef AFS_NT40_ENV snprintf(pbuffer, sizeof(pbuffer), "%s.DB%s%d.OLD", ubik_dbase->pathName, (file<0)?"SYS":"", (file<0)?-file:file); unlink(pbuffer); #endif } if (code) { unlink(pbuffer); /* * We will effectively invalidate the old data forever now. * Unclear if we *should* but we do. */ UBIK_VERSION_LOCK; ubik_dbase->version.epoch = 0; ubik_dbase->version.counter = 0; UBIK_VERSION_UNLOCK; ubik_print("Ubik: Synchronize database failed (error = %d)\n", code); } else { ubik_print("Ubik: Synchronize database completed\n"); urecovery_state |= UBIK_RECHAVEDB; } udisk_Invalidate(ubik_dbase, 0); /* data has changed */ #ifdef AFS_PTHREAD_ENV CV_BROADCAST(&ubik_dbase->version_cond); #else LWP_NoYieldSignal(&ubik_dbase->version); #endif } if (!(urecovery_state & UBIK_RECHAVEDB)) { DBRELE(ubik_dbase); continue; /* not ready */ } /* If the database was newly initialized, then when we establish quorum, write * a new label. This allows urecovery_AllBetter() to allow access for reads. * Setting it to 2 also allows another site to come along with a newer * database and overwrite this one. */ if (ubik_dbase->version.epoch == 1) { urecovery_AbortAll(ubik_dbase); UBIK_VERSION_LOCK; version_globals.ubik_epochTime = 2; ubik_dbase->version.epoch = version_globals.ubik_epochTime; ubik_dbase->version.counter = 1; code = (*ubik_dbase->setlabel) (ubik_dbase, 0, &ubik_dbase->version); UBIK_VERSION_UNLOCK; udisk_Invalidate(ubik_dbase, 0); /* data may have changed */ #ifdef AFS_PTHREAD_ENV CV_BROADCAST(&ubik_dbase->version_cond); #else LWP_NoYieldSignal(&ubik_dbase->version); #endif } /* Check the other sites and send the database to them if they * do not have the current db. */ if (!(urecovery_state & UBIK_RECSENTDB)) { /* now propagate out new version to everyone else */ dbok = 1; /* start off assuming they all worked */ /* * Check if a write transaction is in progress. We can't send the * db when a write is in progress here because the db would be * obsolete as soon as it goes there. Also, ops after the begin * trans would reach the recepient and wouldn't find a transaction * pending there. Frankly, I don't think it's possible to get past * the write-lock above if there is a write transaction in progress, * but then, it won't hurt to check, will it? */ if (ubik_dbase->flags & DBWRITING) { struct timeval tv; int safety = 0; long cur_usec = 50000; while ((ubik_dbase->flags & DBWRITING) && (safety < 500)) { DBRELE(ubik_dbase); /* sleep for a little while */ tv.tv_sec = 0; tv.tv_usec = cur_usec; #ifdef AFS_PTHREAD_ENV select(0, 0, 0, 0, &tv); #else IOMGR_Select(0, 0, 0, 0, &tv); #endif cur_usec += 10000; safety++; DBHOLD(ubik_dbase); } } for (ts = ubik_servers; ts; ts = ts->next) { UBIK_ADDR_LOCK; inAddr.s_addr = ts->addr[0]; UBIK_ADDR_UNLOCK; UBIK_BEACON_LOCK; if (!ts->up) { UBIK_BEACON_UNLOCK; ubik_dprint("recovery cannot send version to %s\n", afs_inet_ntoa_r(inAddr.s_addr, hoststr)); dbok = 0; continue; } UBIK_BEACON_UNLOCK; ubik_dprint("recovery sending version to %s\n", afs_inet_ntoa_r(inAddr.s_addr, hoststr)); if (vcmp(ts->version, ubik_dbase->version) != 0) { ubik_dprint("recovery stating local database\n"); /* Rx code to do the Bulk Store */ code = (*ubik_dbase->stat) (ubik_dbase, 0, &ubikstat); if (!code) { length = ubikstat.size; file = offset = 0; UBIK_ADDR_LOCK; rxcall = rx_NewCall(ts->disk_rxcid); UBIK_ADDR_UNLOCK; code = StartDISK_SendFile(rxcall, file, length, &ubik_dbase->version); if (code) { ubik_dprint("StartDiskSendFile failed=%d\n", code); goto StoreEndCall; } while (length > 0) { tlen = (length > sizeof(tbuffer) ? sizeof(tbuffer) : length); nbytes = (*ubik_dbase->read) (ubik_dbase, file, tbuffer, offset, tlen); if (nbytes != tlen) { ubik_dprint("Local disk read error=%d\n", code = UIOERROR); goto StoreEndCall; } nbytes = rx_Write(rxcall, tbuffer, tlen); if (nbytes != tlen) { ubik_dprint("Rx-write bulk error=%d\n", code = BULK_ERROR); goto StoreEndCall; } offset += tlen; length -= tlen; } code = EndDISK_SendFile(rxcall); StoreEndCall: code = rx_EndCall(rxcall, code); } if (code == 0) { /* we set a new file, process its header */ ts->version = ubik_dbase->version; ts->currentDB = 1; } else dbok = 0; } else { /* mark file up to date */ ts->currentDB = 1; } } if (dbok) urecovery_state |= UBIK_RECSENTDB; } DBRELE(ubik_dbase); } return NULL; }
struct ttyent * getttyent(void) { static struct ttyent tty; static char devpts_name[] = "pts/9999999999"; char *p; int c; size_t i; if (!tf && !setttyent()) return (NULL); for (;;) { if (!fgets(p = line, lbsize, tf)) { if (curpts <= maxpts) { sprintf(devpts_name, "pts/%d", curpts++); tty.ty_name = devpts_name; tty.ty_getty = NULL; tty.ty_type = NULL; tty.ty_status = TTY_NETWORK; tty.ty_window = NULL; tty.ty_comment = NULL; tty.ty_group = _TTYS_NOGROUP; return (&tty); } return (NULL); } /* extend buffer if line was too big, and retry */ while (!index(p, '\n') && !feof(tf)) { i = strlen(p); lbsize += MALLOCCHUNK; if ((p = realloc(line, lbsize)) == NULL) { endttyent(); return (NULL); } line = p; if (!fgets(&line[i], lbsize - i, tf)) return (NULL); } while (isspace((unsigned char)*p)) ++p; if (*p && *p != '#') break; } #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1]) #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' zapchar = 0; tty.ty_name = p; tty.ty_status = 0; tty.ty_window = NULL; tty.ty_group = _TTYS_NOGROUP; p = skip(p); if (!*(tty.ty_getty = p)) tty.ty_getty = tty.ty_type = NULL; else { p = skip(p); if (!*(tty.ty_type = p)) tty.ty_type = NULL; else { /* compatibility kludge: handle network/dialup specially */ if (scmp(_TTYS_DIALUP)) tty.ty_status |= TTY_DIALUP; else if (scmp(_TTYS_NETWORK)) tty.ty_status |= TTY_NETWORK; p = skip(p); } } for (; *p; p = skip(p)) { if (scmp(_TTYS_OFF)) tty.ty_status &= ~TTY_ON; else if (scmp(_TTYS_ON)) tty.ty_status |= TTY_ON; else if (scmp(_TTYS_SECURE)) tty.ty_status |= TTY_SECURE; else if (scmp(_TTYS_INSECURE)) tty.ty_status &= ~TTY_SECURE; else if (scmp(_TTYS_DIALUP)) tty.ty_status |= TTY_DIALUP; else if (scmp(_TTYS_NETWORK)) tty.ty_status |= TTY_NETWORK; else if (vcmp(_TTYS_WINDOW)) tty.ty_window = value(p); else if (vcmp(_TTYS_GROUP)) tty.ty_group = value(p); else break; } if (zapchar == '#' || *p == '#') while ((c = *++p) == ' ' || c == '\t') ; tty.ty_comment = p; if (*p == 0) tty.ty_comment = 0; if ( (p = index(p, '\n')) ) *p = '\0'; return (&tty); }
struct ttyent * getttyent(void) { static struct ttyent tty; int c; char *p; size_t len; static char *line = NULL; char zapchar; if (line) free(line); if (!tf && !setttyent()) return NULL; for (;;) { errno = 0; line = fparseln(tf, &len, &lineno, NULL, FPARSELN_UNESCALL); if (line == NULL) { if (errno != 0) warn("%s", __func__); return NULL; } for (p = line; *p && isspace((unsigned char)*p); p++) continue; if (*p && *p != '#') break; free(line); } tty.ty_name = p; p = skip(p, &zapchar); if (*(tty.ty_getty = p) == '\0') tty.ty_getty = tty.ty_type = NULL; else { p = skip(p, &zapchar); if (*(tty.ty_type = p) == '\0') tty.ty_type = NULL; else p = skip(p, &zapchar); } tty.ty_status = 0; tty.ty_window = NULL; tty.ty_class = NULL; #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && (isspace((unsigned char) p[sizeof(e) - 1]) || p[sizeof(e) - 1] == '\0') #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' for (; *p; p = skip(p, &zapchar)) { if (scmp(_TTYS_OFF)) tty.ty_status &= ~TTY_ON; else if (scmp(_TTYS_ON)) tty.ty_status |= TTY_ON; else if (scmp(_TTYS_SECURE)) tty.ty_status |= TTY_SECURE; else if (scmp(_TTYS_LOCAL)) tty.ty_status |= TTY_LOCAL; else if (scmp(_TTYS_RTSCTS)) tty.ty_status |= TTY_RTSCTS; else if (scmp(_TTYS_DTRCTS)) tty.ty_status |= TTY_DTRCTS; else if (scmp(_TTYS_SOFTCAR)) tty.ty_status |= TTY_SOFTCAR; else if (scmp(_TTYS_MDMBUF)) tty.ty_status |= TTY_MDMBUF; else if (vcmp(_TTYS_WINDOW)) tty.ty_window = value(p); else if (vcmp(_TTYS_CLASS)) tty.ty_class = value(p); else warnx("%s: %s, %lu: unknown option `%s'", __func__, _PATH_TTYS, (unsigned long)lineno, p); } if (zapchar == '#' || *p == '#') while ((c = *++p) == ' ' || c == '\t') continue; tty.ty_comment = p; if (*p == '\0') tty.ty_comment = NULL; if ((p = strchr(p, '\n')) != NULL) *p = '\0'; return &tty; }
int vfind( T*vv, T v, int count ) { int i=0; for(; i<count && !vcmp(vv[i],v) ; ++i ); return i; }
void FindConPrintf(void) { ConCommandBase *pBase = NULL; unsigned char *ptr = NULL; #ifdef GAME_ORANGE FnCommandCallback_t callback = NULL; #else FnCommandCallback callback = NULL; #endif int offs = 0; #if !defined ( GAME_CSGO ) pBase = g_pCVar->GetCommands(); while (pBase) { if ( strcmp(pBase->GetName(), "echo") == 0 ) { //callback = //*((FnCommandCallback *)((char *)pBase + offsetof(ConCommand, m_fnCommandCallback))); callback = ((ConCommand *)pBase)->m_fnCommandCallback; ptr = (unsigned char *)callback; if (vcmp(ptr, ENGINE486_SIG, SIGLEN)) { offs = ENGINE486_OFFS; } else if (vcmp(ptr, ENGINE686_SIG, SIGLEN)) { offs = ENGINE686_OFFS; } else if (vcmp(ptr, ENGINEAMD_SIG, SIGLEN)) { offs = ENGINEAMD_OFFS; } else if (vcmp(ptr, ENGINEW32_SIG, SIGLEN)) { offs = ENGINEW32_OFFS; } if (!offs || ptr[offs-1] != IA32_CALL) { return; } //get the relative offset MMsg = *((CONPRINTF_FUNC *)(ptr + offs)); //add the base offset, to the ip (which is the address+offset + 4 bytes for next instruction) MMsg = (CONPRINTF_FUNC)((unsigned long)MMsg + (unsigned long)(ptr + offs) + 4); Msg("Using conprintf\n"); return; } pBase = const_cast<ConCommandBase *>(pBase->GetNext()); } #else pBase = g_pCVar->FindCommand("echo"); callback = ((ConCommand *)pBase)->m_fnCommandCallback; ptr = (unsigned char *)callback; if (vcmp(ptr, ENGINE486_SIG, SIGLEN)) { offs = ENGINE486_OFFS; } else if (vcmp(ptr, ENGINE686_SIG, SIGLEN)) { offs = ENGINE686_OFFS; } else if (vcmp(ptr, ENGINEAMD_SIG, SIGLEN)) { offs = ENGINEAMD_OFFS; } else if (vcmp(ptr, ENGINEW32_SIG, SIGLEN)) { offs = ENGINEW32_OFFS; } if (!offs || ptr[offs-1] != IA32_CALL) { return; } //get the relative offset MMsg = *((CONPRINTF_FUNC *)(ptr + offs)); //add the base offset, to the ip (which is the address+offset + 4 bytes for next instruction) MMsg = (CONPRINTF_FUNC)((unsigned long)MMsg + (unsigned long)(ptr + offs) + 4); Msg("Using conprintf\n"); return; #endif Msg("Using Msg()\n"); MMsg = (CONPRINTF_FUNC)Msg; return; }