/* * Traverse the file system in the level-order way. The description * and example is in the header file. */ int traverse_level(struct fs_traverse *ftp) { char path[PATH_MAX + 1]; /* full path name of the current dir */ char nm[NAME_MAX + 1]; /* directory entry name */ char *lp; /* last position on the path */ int next_dir, rv; int pl, el; /* path and directory entry length */ cstack_t *sp; fs_fhandle_t pfh, efh; struct stat64 pst, est; traverse_state_t *tsp; struct fst_node pn, en; /* parent and entry nodes */ dent_arg_t darg; if (!ftp || !ftp->ft_path || !*ftp->ft_path || !ftp->ft_callbk) { NDMP_LOG(LOG_DEBUG, "Invalid argument"); errno = EINVAL; return (-1); } /* set the default log function if it's not already set */ if (!ftp->ft_logfp) { ftp->ft_logfp = (ft_log_t)syslog; NDMP_LOG(LOG_DEBUG, "Log to system log \"%s\"", ftp->ft_path); } if (!ftp->ft_lpath) { NDMP_LOG(LOG_DEBUG, "report the same paths \"%s\"", ftp->ft_path); ftp->ft_lpath = ftp->ft_path; } pl = strlen(ftp->ft_lpath); if (pl + 1 > PATH_MAX) { /* +1 for the '/' */ NDMP_LOG(LOG_DEBUG, "lpath too long \"%s\"", ftp->ft_path); errno = ENAMETOOLONG; return (-1); } (void) strcpy(path, ftp->ft_lpath); (void) memset(&pfh, 0, sizeof (pfh)); rv = fs_getstat(ftp->ft_lpath, &pfh, &pst); if (rv != 0) { NDMP_LOG(LOG_DEBUG, "Error %d on fs_getstat(%s)", rv, ftp->ft_path); return (-1); } en.tn_path = NULL; en.tn_fh = NULL; en.tn_st = NULL; if (!S_ISDIR(pst.st_mode)) { pn.tn_path = ftp->ft_lpath; pn.tn_fh = &pfh; pn.tn_st = &pst; rv = CALLBACK(&pn, &en); if (VERBOSE(ftp)) NDMP_LOG(LOG_DEBUG, "CALLBACK(%s): %d", pn.tn_path, rv); free(pfh.fh_fpath); return (rv); } sp = cstack_new(); if (!sp) { free(pfh.fh_fpath); errno = ENOMEM; return (-1); } tsp = new_tsp(path); if (!tsp) { cstack_delete(sp); free(pfh.fh_fpath); errno = ENOMEM; return (-1); } darg.da_buf = ndmp_malloc(MAX_DENT_BUF_SIZE); if (!darg.da_buf) { cstack_delete(sp); free(pfh.fh_fpath); free(tsp); errno = ENOMEM; return (-1); } darg.da_size = MAX_DENT_BUF_SIZE; tsp->ts_ent = tsp->ts_end; tsp->ts_fh = pfh; tsp->ts_st = pst; pn.tn_path = path; pn.tn_fh = &tsp->ts_fh; pn.tn_st = &tsp->ts_st; /* call the callback function on the path itself */ traverse_stats.fss_dir_calls++; rv = CALLBACK(&pn, &en); if (rv < 0) { free(tsp); goto end; } if (rv == FST_SKIP) { traverse_stats.fss_dir_skipped++; free(tsp); rv = 0; goto end; } rv = 0; next_dir = 1; do { if (next_dir) { traverse_stats.fss_newdirs++; *tsp->ts_end = '\0'; if (VERBOSE(ftp)) NDMP_LOG(LOG_DEBUG, "pl %d \"%s\"", pl, path); rv = traverse_level_nondir(ftp, tsp, &pn, &darg); if (rv < 0) { NEGATE(rv); free(tsp->ts_fh.fh_fpath); free(tsp); break; } /* * If skipped by the callback function or * error happened reading the information */ if (rv == FST_SKIP || rv == SKIP_ENTRY) { /* * N.B. next_dir should be set to 0 as * well. This prevents the infinite loop. * If it's not set the same directory will * be poped from the stack and will be * scanned again. */ next_dir = 0; rv = 0; goto skip_dir; } /* re-start reading entries of the directory */ tsp->ts_dpos = 0; } next_dir = 0; do { el = NAME_MAX; rv = fs_readdir(&tsp->ts_fh, pn.tn_path, &tsp->ts_dpos, nm, &el, &efh, &est); if (rv != 0) { traverse_stats.fss_readdir_err++; NDMP_LOG(LOG_DEBUG, "Error %d on readdir(%s) pos %d", rv, path, tsp->ts_dpos); if (STOP_ONERR(ftp)) break; rv = SKIP_ENTRY; continue; } /* done with this directory */ if (el == 0) break; nm[el] = '\0'; if (rootfs_dot_or_dotdot(nm)) { free(efh.fh_fpath); continue; } if (VERBOSE(ftp)) NDMP_LOG(LOG_DEBUG, "%u dname: \"%s\"", tsp->ts_dpos, nm); if (pl + 1 + el > PATH_MAX) { /* * The long paths were already encountered * when processing non-dir entries in. * traverse_level_nondir. * We don't increase fss_longpath_err * counter for them again here. */ NDMP_LOG(LOG_ERR, "Path %s/%s is too long.", path, nm); if (STOP_ONLONG(ftp)) rv = ENAMETOOLONG; free(efh.fh_fpath); continue; } if (!S_ISDIR(est.st_mode)) continue; /* * Call the callback function for the new * directory found, then push the current * directory on to the stack. Then dive * into the entry found. */ traverse_stats.fss_dir_calls++; en.tn_path = nm; en.tn_fh = &efh; en.tn_st = &est; rv = CALLBACK(&pn, &en); if (rv < 0) { NEGATE(rv); free(efh.fh_fpath); break; } if (rv == FST_SKIP) { traverse_stats.fss_dir_skipped++; free(efh.fh_fpath); rv = 0; continue; } /* * Push the current directory on to the stack and * dive into the entry found. */ if (cstack_push(sp, tsp, 0)) { rv = ENOMEM; } else { traverse_stats.fss_pushes++; lp = tsp->ts_end; *tsp->ts_end = '/'; (void) strcpy(tsp->ts_end + 1, nm); tsp = new_tsp(path); if (!tsp) rv = ENOMEM; else { next_dir = 1; pl += el + 1; tsp->ts_fh = efh; tsp->ts_st = est; tsp->ts_ent = lp; pn.tn_fh = &tsp->ts_fh; pn.tn_st = &tsp->ts_st; } } break; } while (rv == 0); /* * A new directory must be processed, go to the start of * the loop, open it and process it. */ if (next_dir) continue; skip_dir: if (tsp) { free(tsp->ts_fh.fh_fpath); free(tsp); } if (rv == SKIP_ENTRY) rv = 0; if (rv == 0) { if (cstack_pop(sp, (void **)&tsp, (int *)NULL)) break; traverse_stats.fss_pops++; if (VERBOSE(ftp)) NDMP_LOG(LOG_DEBUG, "Poped pl %d \"%s\"", pl, path); *tsp->ts_end = '\0'; pl = tsp->ts_end - path; pn.tn_fh = &tsp->ts_fh; pn.tn_st = &tsp->ts_st; } } while (rv == 0); /* * Pop and free all the remaining entries on the stack. */ while (!cstack_pop(sp, (void **)&tsp, (int *)NULL)) { traverse_stats.fss_stack_residue++; free(tsp->ts_fh.fh_fpath); free(tsp); } end: free(darg.da_buf); cstack_delete(sp); return (rv); }
long GalleryUtil::GetNaturalRotation(const QString &filePathString) { long rotateAngle = 0; #ifdef EXIF_SUPPORT QByteArray filePathBA = filePathString.toLocal8Bit(); const char *filePath = filePathBA.constData(); try { char *exifvalue = new char[1024]; ExifData *data = exif_data_new_from_file (filePath); if (data) { for (int i = 0; i < EXIF_IFD_COUNT; i++) { ExifEntry *entry = exif_content_get_entry (data->ifd[i], EXIF_TAG_ORIENTATION); ExifByteOrder byteorder = exif_data_get_byte_order (data); if (entry) { ExifShort v_short = exif_get_short (entry->data, byteorder); VERBOSE(VB_GENERAL|VB_EXTRA, QString("Exif entry=%1").arg(v_short)); /* See http://sylvana.net/jpegcrop/exif_orientation.html*/ if (v_short == 8) { rotateAngle = -90; } else if (v_short == 6) { rotateAngle = 90; } break; } } exif_data_free(data); } else { VERBOSE(VB_FILE, LOC_ERR + QString("Could not load exif data from '%1'") .arg(filePath)); } delete [] exifvalue; #if 0 Exiv2::ExifData exifData; int rc = exifData.read(filePath); if (!rc) { Exiv2::ExifKey key = Exiv2::ExifKey("Exif.Image.Orientation"); Exiv2::ExifData::iterator pos = exifData.findKey(key); if (pos != exifData.end()) { long orientation = pos->toLong(); switch (orientation) { case 6: rotateAngle = 90; break; case 8: rotateAngle = -90; break; default: rotateAngle = 0; break; } } } #endif } catch (...) { VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to extract EXIF headers from '%1'") .arg(filePathString)); } #else // Shut the compiler up about the unused argument (void)filePathString; #endif // EXIF_SUPPORT return rotateAngle; }
int main (int argc, char **argv) { #ifdef CC_HAVE_WIN_UTF8 // UTF8 argv. g_win_utf8_enabled affects cc_fopen and cc_fprintf argv = win_utf8_argv(argc, argv, &g_win_utf8_enabled); #endif int rv = 1; int needs_usage_on_err = 1; int opt_verbose = 0; int opt_overwrite = 0; int opt_progress = 0; int opt_dummy = 0; char *in_name = NULL; char *out_name = NULL; FILE *in_file = NULL; FILE *out_file = NULL; int i = 0; opterr = 0; // suppress getopt error prints, we're handling them. int c; while (1) { // This is weird. GNU getopt can be made to work in POSIX compliant mode, // but in a way which breaks POSIX compliance... // We want to use getopt in standard posix mode, where it doesn't // permute argv, and returns -1 when it encounters a non-option. // GNU getopt doesn't default to posix mode. It uses posix mode either // when the env POSIXLY_CORRECT is set, or when optstring starts with +. // But + prefix is a GNU extension - proper posix getopt don't recognize // it as an indicator, therefore interpreting it as a valid option char. // So to cover both variants, we use the '+' to make GNU posix compliant, // but also expect it and then and reject it as an unknown option on posix getopt. if ((c = getopt (argc, argv, "+hdvfpo:")) != -1) { switch (c) { case 'h': help(); exit(0); case 'v': opt_verbose = 1; break; case 'f': opt_overwrite = 1; break; case 'p': opt_progress = 1; break; case 'd': opt_dummy = 1; break; case 'o': out_name = optarg; // Will also exit the while loop and start the ranges break; case '+': optopt = '+'; // fallthrough - proper POSIX (bsd, OS X, ...) case '?': if (optopt == 'o') ERR_EXIT("-o: missing output file name"); ERR_EXIT("unknown option -%c%s", optopt, (optopt >= '0' && optopt <= '9') ? " (missing -o OUT_FILE before the ranges?)" : ""); default : ERR_EXIT("(Internal) getopt - unexpected code %d", c); } } else if (optind < argc) { // still more arguments, so it's a value if (!in_name) { // still no input file, so this is it. in_name = argv[optind]; optind++; // skip the value and continue parsing. } else { ERR_EXIT("unexpected '%s' (missing -o OUT_FILE before the ranges?)", argv[optind]); } } else { // no more arguments to parse break; } if (out_name) // Once we got the output file, the rest should be ranges break; } // from here onwards, optind should point to the first range in argv VERBOSE("- Verbose mode enabled.\n"); if (opt_overwrite) VERBOSE("- Force overwrite output file if exists.\n"); if (opt_progress) VERBOSE("- Progress display enabled.\n"); if (opt_dummy) VERBOSE("- Dummy mode enabled.\n"); if (!in_name) ERR_EXIT("missing input file name"); if (!out_name) ERR_EXIT("missing output file name"); if (optind == argc) ERR_EXIT("no ranges defined, must have at least one range"); // Input file - verify, open and read size cc_off_t in_size = fsize(in_name); in_file = cc_fopen(in_name, "rb"); if (in_size < 0 || !in_file) ERR_EXIT("input file '%s' cannot be opened", in_name); VERBOSE("- Input file: '%s', size: %lld\n", in_name, (long long)in_size); // verify ranges and calculate expected output size cc_off_t expected_output_size = 0; cc_off_t prev_to = 0; for (i = optind; i < argc; i++) { range_t range; if (!get_range(in_size, prev_to, argv[i], &range)) ERR_EXIT("invalid range '%s'", argv[i]); expected_output_size += range.to - range.from; prev_to = range.to; VERBOSE("- Range #%d: '%s' -> [%lld, %lld) -> %lld bytes\n", i - optind + 1, argv[i], (long long)range.from, (long long)range.to, (long long)(range.to - range.from) ); } if (opt_dummy) { VERBOSE("- Done - dummy mode - skipped copying %lld bytes to '%s'%s.\n", (long long)expected_output_size, out_name, strcmp(out_name, "-") ? "" : " (stdout)"); rv = 0; goto exit_L; } // open/setup output if (!strcmp(out_name, "-")) { out_file = stdout; #ifdef _WIN32 // change stdout to binary mode, or else it messes with EOL chars if (_setmode(_fileno(stdout), O_BINARY) == -1) ERR_EXIT("cannot set stdout to binary mode"); #endif } else { FILE *tmp = cc_fopen(out_name, "r"); if (tmp) { fclose(tmp); if (!opt_overwrite) ERR_EXIT("output file '%s' exists, use -f to force overwrite", out_name); } out_file = cc_fopen(out_name, "wb"); if (!out_file) ERR_EXIT("output file '%s' cannot be created", out_name); } // args are valid, input file is valid, output file created. Start copy needs_usage_on_err = 0; VERBOSE("- About to copy overall %lld bytes to '%s'%s ...\n", (long long)expected_output_size, out_name, strcmp(out_name, "-") ? "" : " (stdout)"); char buf[RW_BUFFSIZE]; cc_off_t total_processed = 0; prev_to = 0; for (i = optind; (i < argc) && expected_output_size; i++) { range_t range; if (!get_range(in_size, prev_to, argv[i], &range)) ERR_EXIT("(Internal): range became invalid?! '%s'", argv[i]); prev_to = range.to; if (cc_fseek(in_file, range.from, SEEK_SET)) ERR_EXIT("cannot seek input file to offset %lld", (long long)range.from); cc_off_t toread = range.to - range.from; while (toread) { size_t single_read = (size_t)(cc_min(toread, (cc_off_t)RW_BUFFSIZE)); size_t got = fread(buf, 1, single_read, in_file); if (ferror(in_file) || got != single_read) ERR_EXIT("cannot read from input file"); if (got != fwrite(buf, 1, got, out_file)) ERR_EXIT("cannot write to output file"); toread -= got; total_processed += got; if (opt_progress) { int percent = (int)((double)total_processed / expected_output_size * 100); int prev_percent = (int)((double)(total_processed - got) / expected_output_size * 100); if (percent / PROGRESS_PER != prev_percent / PROGRESS_PER) cc_fprintf(stderr, " %d%% ", percent); else if (percent / PROGRESS_DOT != prev_percent / PROGRESS_DOT) cc_fprintf(stderr, "."); } } } if (opt_progress) { if (!expected_output_size) cc_fprintf(stderr, " %d%% ", 100); cc_fprintf(stderr, "\n"); } // success VERBOSE("- Done.\n"); rv = 0; exit_L: if (in_file) fclose(in_file); if (out_file && out_file != stdout) fclose(out_file); if (rv && needs_usage_on_err) { cc_fprintf(stderr, "\n"); usage(); } #ifdef CC_HAVE_WIN_UTF8 if (g_win_utf8_enabled) free_argvutf8(argc, argv); #endif return rv; }
/* * Read a directory, using filldir to fill the dirent memory. * smb_proc_readdir does the actual reading from the smb server. * * The cache code is almost directly taken from ncpfs */ static int smb_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct dentry *dentry = filp->f_dentry; struct inode *dir = dentry->d_inode; struct smb_sb_info *server = server_from_dentry(dentry); union smb_dir_cache *cache = NULL; struct smb_cache_control ctl; struct page *page = NULL; int result; ctl.page = NULL; ctl.cache = NULL; VERBOSE("reading %s/%s, f_pos=%d\n", DENTRY_PATH(dentry), (int) filp->f_pos); result = 0; lock_kernel(); switch ((unsigned int) filp->f_pos) { case 0: if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0) goto out; filp->f_pos = 1; /* fallthrough */ case 1: if (filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR) < 0) goto out; filp->f_pos = 2; } /* * Make sure our inode is up-to-date. */ result = smb_revalidate_inode(dentry); if (result) goto out; page = grab_cache_page(&dir->i_data, 0); if (!page) goto read_really; ctl.cache = cache = kmap(page); ctl.head = cache->head; if (!PageUptodate(page) || !ctl.head.eof) { VERBOSE("%s/%s, page uptodate=%d, eof=%d\n", DENTRY_PATH(dentry), PageUptodate(page),ctl.head.eof); goto init_cache; } if (filp->f_pos == 2) { if (jiffies - ctl.head.time >= SMB_MAX_AGE(server)) goto init_cache; /* * N.B. ncpfs checks mtime of dentry too here, we don't. * 1. common smb servers do not update mtime on dir changes * 2. it requires an extra smb request * (revalidate has the same timeout as ctl.head.time) * * Instead smbfs invalidates its own cache on local changes * and remote changes are not seen until timeout. */ } if (filp->f_pos > ctl.head.end) goto finished; ctl.fpos = filp->f_pos + (SMB_DIRCACHE_START - 2); ctl.ofs = ctl.fpos / SMB_DIRCACHE_SIZE; ctl.idx = ctl.fpos % SMB_DIRCACHE_SIZE; for (;;) { if (ctl.ofs != 0) { ctl.page = find_lock_page(&dir->i_data, ctl.ofs); if (!ctl.page) goto invalid_cache; ctl.cache = kmap(ctl.page); if (!PageUptodate(ctl.page)) goto invalid_cache; } while (ctl.idx < SMB_DIRCACHE_SIZE) { struct dentry *dent; int res; dent = smb_dget_fpos(ctl.cache->dentry[ctl.idx], dentry, filp->f_pos); if (!dent) goto invalid_cache; res = filldir(dirent, dent->d_name.name, dent->d_name.len, filp->f_pos, dent->d_inode->i_ino, DT_UNKNOWN); dput(dent); if (res) goto finished; filp->f_pos += 1; ctl.idx += 1; if (filp->f_pos > ctl.head.end) goto finished; } if (ctl.page) { kunmap(ctl.page); SetPageUptodate(ctl.page); unlock_page(ctl.page); page_cache_release(ctl.page); ctl.page = NULL; } ctl.idx = 0; ctl.ofs += 1; } invalid_cache: if (ctl.page) { kunmap(ctl.page); unlock_page(ctl.page); page_cache_release(ctl.page); ctl.page = NULL; } ctl.cache = cache; init_cache: smb_invalidate_dircache_entries(dentry); ctl.head.time = jiffies; ctl.head.eof = 0; ctl.fpos = 2; ctl.ofs = 0; ctl.idx = SMB_DIRCACHE_START; ctl.filled = 0; ctl.valid = 1; read_really: result = server->ops->readdir(filp, dirent, filldir, &ctl); if (result == -ERESTARTSYS && page) ClearPageUptodate(page); if (ctl.idx == -1) goto invalid_cache; /* retry */ ctl.head.end = ctl.fpos - 1; ctl.head.eof = ctl.valid; finished: if (page) { cache->head = ctl.head; kunmap(page); if (result != -ERESTARTSYS) SetPageUptodate(page); unlock_page(page); page_cache_release(page); } if (ctl.page) { kunmap(ctl.page); SetPageUptodate(ctl.page); unlock_page(ctl.page); page_cache_release(ctl.page); } out: unlock_kernel(); return result; }
int main() { int an_int; SQLUSMALLINT num_cols; float a_float; SQLCHAR buf1[MAX_LEN]; SQLCHAR buf2[MAX_LEN]; SQLUSMALLINT col; SQLSMALLINT col_len; SQLSMALLINT type; SQLUINTEGER sz; SQLSMALLINT scale; SQLSMALLINT can_null; GET_LOGIN_VARS(); VERBOSE("calling SQLAllocHandle(EnvHandle) \n"); rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &EnvHandle); assert(rc == SQL_SUCCESS); assert(EnvHandle != (SQLHANDLE) NULL); rc = SQLSetEnvAttr(EnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_UINTEGER); assert(rc == SQL_SUCCESS); VERBOSE("calling SQLAllocHandle(ConHandle) \n"); rc = SQLAllocHandle(SQL_HANDLE_DBC, EnvHandle, &ConHandle); assert(ConHandle != (SQLHANDLE) NULL); assert(rc == SQL_SUCCESS); if (dsn[0]) rc = SQLDriverConnect(ConHandle, NULL, dsn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); else rc = SQLConnect(ConHandle, twoTask, SQL_NTS, (SQLCHAR *) userName, SQL_NTS, (SQLCHAR *) pswd, SQL_NTS); assert(rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO); VERBOSE("connected to database %s\n", twoTask); VERBOSE("allocing handle\n"); rc = SQLAllocStmt(ConHandle, &StmtHandle); assert(rc == SQL_SUCCESS); sprintf(SQLStmt, "select max(an_int) from some_types"); VERBOSE("executing %s\n", SQLStmt); rc = SQLExecDirect(StmtHandle, SQLStmt, SQL_NTS); assert(rc == SQL_SUCCESS); rc = SQLNumResultCols(StmtHandle, &num_cols); assert(rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO); assert(num_cols == 1); for (col = 1; col <= num_cols; col++) { rc = SQLDescribeCol(StmtHandle, col, buf1, MAX_LEN, &col_len, &type, &sz, &scale, &can_null); assert(rc == SQL_SUCCESS); VERBOSE ("col=%d name:%s len=%d type=%d size=%d scale=%d nullable=%d\n", col, buf1, col_len, type, sz, scale, can_null); /* if(col==1)assert(type==SQL_INTEGER); if(col==2)assert(type==SQL_C_DOUBLE); if(col==3)assert(type==SQL_VARCHAR); */ rc = SQLColAttribute(StmtHandle, col, SQL_DESC_NAME, buf2, sizeof(buf2), &type, NULL); assert(rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO); assert(strcmp(buf1, buf2) == 0); } rc = SQLBindCol(StmtHandle, 1, SQL_C_SLONG, &an_int, sizeof(an_int), NULL); assert(rc == SQL_SUCCESS); do { rc = SQLFetch(StmtHandle); VERBOSE("an_int=%d \n", an_int); } while (rc == SQL_SUCCESS); assert(rc == SQL_NO_DATA); assert(an_int > 0); rc = SQLDisconnect(ConHandle); assert(rc == SQL_SUCCESS); VERBOSE("disconnected from database\n"); VERBOSE("calling SQLFreeHandle(ConHandle) \n"); assert(ConHandle != (SQLHANDLE) NULL); rc = SQLFreeHandle(SQL_HANDLE_DBC, ConHandle); assert(rc == SQL_SUCCESS); VERBOSE("calling SQLFreeHandle(EnvHandle) \n"); assert(EnvHandle != (SQLHANDLE) NULL); rc = SQLFreeHandle(SQL_HANDLE_ENV, EnvHandle); assert(rc == SQL_SUCCESS); return (rc); }
bool AudioOutputPulseAudio::ConnectPlaybackStream(void) { QString fn_log_tag = "ConnectPlaybackStream, "; pstream = pa_stream_new(pcontext, "MythTV playback", &sample_spec, &channel_map); if (!pstream) { VBERROR(fn_log_tag + QString("failed to create new playback stream")); return false; } pa_stream_set_state_callback(pstream, StreamStateCallback, this); pa_stream_set_write_callback(pstream, WriteCallback, this); pa_stream_set_overflow_callback(pstream, BufferFlowCallback, (char*)"over"); pa_stream_set_underflow_callback(pstream, BufferFlowCallback, (char*)"under"); if (set_initial_vol) { int volume = gCoreContext->GetNumSetting("MasterMixerVolume", 80); pa_cvolume_set(&volume_control, channels, (float)volume * (float)PA_VOLUME_NORM / 100.0f); } else pa_cvolume_reset(&volume_control, channels); fragment_size = (samplerate * 25 * output_bytes_per_frame) / 1000; buffer_settings.maxlength = (uint32_t)-1; buffer_settings.tlength = fragment_size * 4; buffer_settings.prebuf = (uint32_t)-1; buffer_settings.minreq = (uint32_t)-1; int flags = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_NO_REMIX_CHANNELS; pa_stream_connect_playback(pstream, NULL, &buffer_settings, (pa_stream_flags_t)flags, &volume_control, NULL); pa_context_state_t cstate; pa_stream_state_t sstate; bool connected = false, failed = false; while (!(connected || failed)) { switch (cstate = pa_context_get_state(pcontext)) { case PA_CONTEXT_FAILED: case PA_CONTEXT_TERMINATED: VERBOSE(VB_IMPORTANT, LOC_ERR + fn_log_tag + QString("context is stuffed, %1") .arg(pa_strerror(pa_context_errno( pcontext)))); failed = true; break; default: switch (sstate = pa_stream_get_state(pstream)) { case PA_STREAM_READY: connected = true; break; case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: VBERROR(fn_log_tag + QString("stream failed or was terminated, " "context state %1, stream state %2") .arg(cstate).arg(sstate)); failed = true; break; default: pa_threaded_mainloop_wait(mainloop); break; } } } const pa_buffer_attr *buf_attr = pa_stream_get_buffer_attr(pstream); fragment_size = buf_attr->tlength >> 2; soundcard_buffer_size = buf_attr->maxlength; VBAUDIO(fn_log_tag + QString("fragment size %1, soundcard buffer size %2") .arg(fragment_size).arg(soundcard_buffer_size)); return (connected && !failed); }
/** * Process a sentence with xml annotation * Xml tags may specifiy additional/replacing translation options * and reordering constraints * * \param line in: sentence, out: sentence without the xml * \param res vector with translation options specified by xml * \param reorderingConstraint reordering constraint zones specified by xml * \param walls reordering constraint walls specified by xml */ bool TreeInput::ProcessAndStripXMLTags(string &line, std::vector<XMLParseOutput> &sourceLabels, std::vector<XmlOption*> &xmlOptions) { //parse XML markup in translation line // no xml tag? we're done. if (line.find_first_of('<') == string::npos) { return true; } // hack. What pt should XML trans opt be assigned to? PhraseDictionary *firstPt = NULL; if (PhraseDictionary::GetColl().size() == 0) { firstPt = PhraseDictionary::GetColl()[0]; } // break up input into a vector of xml tags and text // example: (this), (<b>), (is a), (</b>), (test .) vector<string> xmlTokens = TokenizeXml(line); // we need to store opened tags, until they are closed // tags are stored as tripled (tagname, startpos, contents) typedef pair< string, pair< size_t, string > > OpenedTag; vector< OpenedTag > tagStack; // stack that contains active opened tags string cleanLine; // return string (text without xml) size_t wordPos = 0; // position in sentence (in terms of number of words) // keep this handy for later const vector<FactorType> &outputFactorOrder = StaticData::Instance().GetOutputFactorOrder(); // const string &factorDelimiter = StaticData::Instance().GetFactorDelimiter(); // loop through the tokens for (size_t xmlTokenPos = 0 ; xmlTokenPos < xmlTokens.size() ; xmlTokenPos++) { // not a xml tag, but regular text (may contain many words) if(!isXmlTag(xmlTokens[xmlTokenPos])) { // add a space at boundary, if necessary if (cleanLine.size()>0 && cleanLine[cleanLine.size() - 1] != ' ' && xmlTokens[xmlTokenPos][0] != ' ') { cleanLine += " "; } cleanLine += xmlTokens[xmlTokenPos]; // add to output wordPos = Tokenize(cleanLine).size(); // count all the words } // process xml tag else { // *** get essential information about tag *** // strip extra boundary spaces and "<" and ">" string tag = Trim(TrimXml(xmlTokens[xmlTokenPos])); VERBOSE(3,"XML TAG IS: " << tag << std::endl); if (tag.size() == 0) { TRACE_ERR("ERROR: empty tag name: " << line << endl); return false; } // check if unary (e.g., "<wall/>") bool isUnary = ( tag[tag.size() - 1] == '/' ); // check if opening tag (e.g. "<a>", not "</a>")g bool isClosed = ( tag[0] == '/' ); bool isOpen = !isClosed; if (isClosed && isUnary) { TRACE_ERR("ERROR: can't have both closed and unary tag <" << tag << ">: " << line << endl); return false; } if (isClosed) tag = tag.substr(1); // remove "/" at the beginning if (isUnary) tag = tag.substr(0,tag.size()-1); // remove "/" at the end // find the tag name and contents string::size_type endOfName = tag.find_first_of(' '); string tagName = tag; string tagContent = ""; if (endOfName != string::npos) { tagName = tag.substr(0,endOfName); tagContent = tag.substr(endOfName+1); } // *** process new tag *** if (isOpen || isUnary) { // put the tag on the tag stack OpenedTag openedTag = make_pair( tagName, make_pair( wordPos, tagContent ) ); tagStack.push_back( openedTag ); VERBOSE(3,"XML TAG " << tagName << " (" << tagContent << ") added to stack, now size " << tagStack.size() << endl); } // *** process completed tag *** if (isClosed || isUnary) { // pop last opened tag from stack; if (tagStack.size() == 0) { TRACE_ERR("ERROR: tag " << tagName << " closed, but not opened" << ":" << line << endl); return false; } OpenedTag openedTag = tagStack.back(); tagStack.pop_back(); // tag names have to match if (openedTag.first != tagName) { TRACE_ERR("ERROR: tag " << openedTag.first << " closed by tag " << tagName << ": " << line << endl ); return false; } // assemble remaining information about tag size_t startPos = openedTag.second.first; string tagContent = openedTag.second.second; size_t endPos = wordPos; // span attribute overwrites position string span = ParseXmlTagAttribute(tagContent,"span"); if (! span.empty()) { vector<string> ij = Tokenize(span, "-"); if (ij.size() != 1 && ij.size() != 2) { TRACE_ERR("ERROR: span attribute must be of the form \"i-j\" or \"i\": " << line << endl); return false; } startPos = atoi(ij[0].c_str()); if (ij.size() == 1) endPos = startPos + 1; else endPos = atoi(ij[1].c_str()) + 1; } VERBOSE(3,"XML TAG " << tagName << " (" << tagContent << ") spanning " << startPos << " to " << (endPos-1) << " complete, commence processing" << endl); if (startPos == endPos) { TRACE_ERR("WARNING: tag " << tagName << " span is empty. Ignoring: " << line << endl); continue; } else if (startPos > endPos) { TRACE_ERR("ERROR: tag " << tagName << " startPos > endPos: " << line << endl); return false; } // may be either a input span label ("label"), or a specified output translation "translation" string label = ParseXmlTagAttribute(tagContent,"label"); string translation = ParseXmlTagAttribute(tagContent,"translation"); // specified label if (translation.length() == 0 && label.length() > 0) { Range range(startPos,endPos-1); // really? XMLParseOutput item(label, range); sourceLabels.push_back(item); } // specified translations -> vector of phrases, separated by "||" if (translation.length() > 0 && StaticData::Instance().GetXmlInputType() != XmlIgnore) { vector<string> altTexts = TokenizeMultiCharSeparator(translation, "||"); vector<string> altLabel = TokenizeMultiCharSeparator(label, "||"); vector<string> altProbs = TokenizeMultiCharSeparator(ParseXmlTagAttribute(tagContent,"prob"), "||"); //TRACE_ERR("number of translations: " << altTexts.size() << endl); for (size_t i=0; i<altTexts.size(); ++i) { // set target phrase TargetPhrase targetPhrase(firstPt); // targetPhrase.CreateFromString(Output, outputFactorOrder,altTexts[i],factorDelimiter, NULL); targetPhrase.CreateFromString(Output, outputFactorOrder,altTexts[i], NULL); // set constituent label string targetLHSstr; if (altLabel.size() > i && altLabel[i].size() > 0) { targetLHSstr = altLabel[i]; } else { const UnknownLHSList &lhsList = StaticData::Instance().GetUnknownLHS(); UnknownLHSList::const_iterator iterLHS = lhsList.begin(); targetLHSstr = iterLHS->first; } Word *targetLHS = new Word(true); targetLHS->CreateFromString(Output, outputFactorOrder, targetLHSstr, true); UTIL_THROW_IF2(targetLHS->GetFactor(0) == NULL, "Null factor left-hand-side"); targetPhrase.SetTargetLHS(targetLHS); // not tested Phrase sourcePhrase = this->GetSubString(Range(startPos,endPos-1)); // get probability float probValue = 1; if (altProbs.size() > i && altProbs[i].size() > 0) { probValue = Scan<float>(altProbs[i]); } // convert from prob to log-prob float scoreValue = FloorScore(TransformScore(probValue)); targetPhrase.SetXMLScore(scoreValue); targetPhrase.EvaluateInIsolation(sourcePhrase); // set span and create XmlOption Range range(startPos+1,endPos); XmlOption *option = new XmlOption(range,targetPhrase); assert(option); xmlOptions.push_back(option); VERBOSE(2,"xml translation = [" << range << "] " << targetLHSstr << " -> " << altTexts[i] << " prob: " << probValue << endl); } altTexts.clear(); altProbs.clear(); } } } } // we are done. check if there are tags that are still open if (tagStack.size() > 0) { TRACE_ERR("ERROR: some opened tags were never closed: " << line << endl); return false; } // return de-xml'ed sentence in line line = cleanLine; return true; }
int handle_command(const MythCommandLineParser &cmdline) { QString eventString = cmdline.GetEventString(); if (!eventString.isEmpty()) { if (gCoreContext->ConnectToMasterServer()) { if (eventString.startsWith("SYSTEM_EVENT")) { eventString += QString(" SENDER %1") .arg(gCoreContext->GetHostName()); } RemoteSendMessage(eventString); return GENERIC_EXIT_OK; } return GENERIC_EXIT_NO_MYTHCONTEXT; } if (cmdline.WantUPnPRebuild()) { VERBOSE(VB_GENERAL, "Rebuilding UPNP Media Map is no longer supported. Rescan videos using MythVideo."); return GENERIC_EXIT_OK; } if (cmdline.SetVerbose()) { if (gCoreContext->ConnectToMasterServer()) { QString message = "SET_VERBOSE "; message += cmdline.GetNewVerbose(); RemoteSendMessage(message); VERBOSE(VB_IMPORTANT, QString("Sent '%1' message").arg(message)); return GENERIC_EXIT_OK; } else { VERBOSE(VB_IMPORTANT, "Unable to connect to backend, verbose level unchanged "); return GENERIC_EXIT_CONNECT_ERROR; } } if (cmdline.ClearSettingsCache()) { if (gCoreContext->ConnectToMasterServer()) { RemoteSendMessage("CLEAR_SETTINGS_CACHE"); VERBOSE(VB_IMPORTANT, "Sent CLEAR_SETTINGS_CACHE message"); return GENERIC_EXIT_OK; } else { VERBOSE(VB_IMPORTANT, "Unable to connect to backend, settings " "cache will not be cleared."); return GENERIC_EXIT_CONNECT_ERROR; } } if (cmdline.IsPrintScheduleEnabled() || cmdline.IsTestSchedulerEnabled()) { sched = new Scheduler(false, &tvList); if (!cmdline.IsTestSchedulerEnabled() && gCoreContext->ConnectToMasterServer()) { cout << "Retrieving Schedule from Master backend.\n"; sched->FillRecordListFromMaster(); } else { cout << "Calculating Schedule from database.\n" << "Inputs, Card IDs, and Conflict info may be invalid " "if you have multiple tuners.\n"; sched->FillRecordListFromDB(); } print_verbose_messages |= VB_SCHEDULE; sched->PrintList(true); return GENERIC_EXIT_OK; } if (cmdline.Reschedule()) { bool ok = false; if (gCoreContext->ConnectToMasterServer()) { VERBOSE(VB_IMPORTANT, "Connected to master for reschedule"); ScheduledRecording::signalChange(-1); ok = true; } else VERBOSE(VB_IMPORTANT, "Cannot connect to master for reschedule"); return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_CONNECT_ERROR; } if (cmdline.ScanVideos()) { bool ok = false; if (gCoreContext->ConnectToMasterServer()) { gCoreContext->SendReceiveStringList(QStringList() << "SCAN_VIDEOS"); VERBOSE(VB_IMPORTANT, "Requested video scan"); ok = true; } else VERBOSE(VB_IMPORTANT, "Cannot connect to master for video scan"); return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_CONNECT_ERROR; } if (!cmdline.GetPrintExpire().isEmpty()) { expirer = new AutoExpire(); expirer->PrintExpireList(cmdline.GetPrintExpire()); return GENERIC_EXIT_OK; } // This should never actually be reached.. return GENERIC_EXIT_OK; }
int connect_to_master(void) { MythSocket *tempMonitorConnection = new MythSocket(); if (tempMonitorConnection->connect( gCoreContext->GetSetting("MasterServerIP", "127.0.0.1"), gCoreContext->GetNumSetting("MasterServerPort", 6543))) { if (!gCoreContext->CheckProtoVersion(tempMonitorConnection)) { VERBOSE(VB_IMPORTANT, "Master backend is incompatible with " "this backend.\nCannot become a slave."); return GENERIC_EXIT_CONNECT_ERROR; } QStringList tempMonitorDone("DONE"); QStringList tempMonitorAnnounce("ANN Monitor tzcheck 0"); tempMonitorConnection->writeStringList(tempMonitorAnnounce); tempMonitorConnection->readStringList(tempMonitorAnnounce); if (tempMonitorAnnounce.empty() || tempMonitorAnnounce[0] == "ERROR") { tempMonitorConnection->DownRef(); tempMonitorConnection = NULL; if (tempMonitorAnnounce.empty()) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to open event socket, timeout"); } else { VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to open event socket" + ((tempMonitorAnnounce.size() >= 2) ? QString(", error was %1").arg(tempMonitorAnnounce[1]) : QString(", remote error"))); } } QStringList tzCheck("QUERY_TIME_ZONE"); if (tempMonitorConnection) { tempMonitorConnection->writeStringList(tzCheck); tempMonitorConnection->readStringList(tzCheck); } if (tzCheck.size() && !checkTimeZone(tzCheck)) { // Check for different time zones, different offsets, different // times VERBOSE(VB_IMPORTANT, "The time and/or time zone settings on " "this system do not match those in use on the master " "backend. Please ensure all frontend and backend " "systems are configured to use the same time zone and " "have the current time properly set."); VERBOSE(VB_IMPORTANT, "Unable to run with invalid time settings. Exiting."); tempMonitorConnection->writeStringList(tempMonitorDone); tempMonitorConnection->DownRef(); return GENERIC_EXIT_INVALID_TIMEZONE; } else { VERBOSE(VB_IMPORTANT, QString("Backend is running in %1 time zone.") .arg(getTimeZoneID())); } if (tempMonitorConnection) tempMonitorConnection->writeStringList(tempMonitorDone); } if (tempMonitorConnection) tempMonitorConnection->DownRef(); return GENERIC_EXIT_OK; }
void CVideoDecoder::ThreadEntry () { CDemux* pDemux = mpDemux; AVStream* pStream = mpStream; CVideoStubRender* pVStubRender = (CVideoStubRender*)mpStubRender; CMasterClock* pClock = mpClock; int Ret = ERR_NONE; int bFrameFinished = 0; AVCodecContext *pCodecContext = NULL; AVPacket AVPkt; int64_t PTS; if (pDemux == NULL || pStream == NULL || pVStubRender == NULL || pStream->codec == NULL) { ERROR ("mpDecoder || mpStream || mpStubRender || mpStream->codec== NULL!"); return; } pCodecContext = pStream->codec; memset((void*)&AVPkt,0,sizeof(AVPacket)); DEBUG ("start video decoder loop!"); for(;;) { if(mbQuit) { INFO("mbQuit"); PlayCore::GetInstance()->avcodec_flush_buffers(pCodecContext); break; } if(pDemux->GetSyncPTS()>=0.0)//已经设定了SyncPTS { if(!pDemux->IsSynced())//没有被音频流Sync { DEBUG("NO FOUND SYNCED !!"); usleep(25*1000); continue; } else if(!pClock->IsRun())//已经设定SyncPTs并且被其他流sync并且当前状态不是播放状态 { usleep(1*1000);//Reduce CPU usage continue; } } else { DEBUG("TRY SHOW FIRST KEY VIDEO FRAME mbFirstKeyFrame %s",mbFirstKeyFrame?"true":"false"); } if(mbNextFrame) { AVPkt = pDemux->GetVideoPacket (); if (AVPkt.data == 0 || AVPkt.size == 0) { INFO ("get NULL packet! continue! must be end of pStream!!! stop thread!"); break; } //如果A/V已经同步,但此时视频时间戳严重落后于系统时钟 if(pDemux->IsSynced()&&mbNeedReSync) { double CurClock = pClock->GetCurrentClock (); double FramePTS = AVPkt.pts * av_q2d (pStream->time_base); double Diff = FramePTS - CurClock; DEBUG ("V:SyncOut CurClock=%f, FramePTS=%f, Diff=%f", CurClock, FramePTS, Diff); if (Diff >= CMasterClock::AVThresholdSync) { DEBUG ("V:Sync CurClock=%f, FramePTS=%f, Diff=%f", CurClock, FramePTS, Diff); } else { PlayCore::GetInstance()->av_free_packet (&AVPkt); memset((void*)&AVPkt,0,sizeof(AVPacket)); continue; } } int len = CVideoDecoderImp::Decode (pCodecContext, mpFrame, &bFrameFinished, &AVPkt, &PTS); if (len < 0 || bFrameFinished == 0) { WARN ("CVideoDecoderImp::Decode fail! continue to next packet!"); PlayCore::GetInstance()->av_free_packet (&AVPkt); memset((void*)&AVPkt,0,sizeof(AVPacket)); continue; } DEBUG("mbFirstKeyFrame %d,key_frame %d,pict_type %d mbNeedReSync %d AV_PICTURE_TYPE_I %d",mbFirstKeyFrame,mpFrame->key_frame,mpFrame->pict_type,mbNeedReSync,AV_PICTURE_TYPE_I); //需要关键帧 if(!pDemux->IsSynced()) { //不是关键帧continue if(!(mpFrame->key_frame && mpFrame->pict_type == AV_PICTURE_TYPE_I)) { DEBUG("Not Key frame continue"); PlayCore::GetInstance()->av_free_packet (&AVPkt); memset((void*)&AVPkt,0,sizeof(AVPacket)); continue; } else //第一次音视频Sync { INFO("First Sync after opened"); mbFirstKeyFrame = true; } } else if(mbNeedReSync) //视频时间戳严重落后于系统时钟,第一个合适的关键帧 { if(!(mpFrame->key_frame && mpFrame->pict_type == AV_PICTURE_TYPE_I)) { DEBUG("Not Key frame continue"); PlayCore::GetInstance()->av_free_packet (&AVPkt); memset((void*)&AVPkt,0,sizeof(AVPacket)); continue; } else { INFO("mbNeedReSync %d",mbNeedReSync); mbNeedReSync = false; mbFirstKeyFrame = false; } } else//pDemux go on { mbFirstKeyFrame = false; } } if (pClock) { double FramePTS = PTS * av_q2d (pStream->time_base); //渲染视频首个关键帧并且不是播放过程中视频解码落后于系统时钟。设定音频同步时间点 if(mbFirstKeyFrame) { Ret = pVStubRender->ShowPicture (mpFrame); INFO("IS Key frame mbFirstKeyFrame %d FramePTS %f ShowPicture Ret %d",mbFirstKeyFrame,FramePTS,Ret); //成功渲染视频 if(Ret>=0 || Ret == ERR_DEVICE_NOSET) { //得到同步时间点, double SyncPTS = pDemux->GetSyncPTS(); INFO("pDemux->GetSyncPTS() %f",SyncPTS); if(SyncPTS<0.0) { //设定同步时间点 pDemux->SetSyncPTS(FramePTS); //设定时钟的起始时间点 pClock->SetOriginClock (FramePTS); //surface fixed pVStubRender->ShowPicture (mpFrame); //如果没有音频数据流设定为Synced; if(pDemux->GetAudioStreamIndex()<0) { pDemux->SetSynced(true); } mbFirstKeyFrame = false; mbNextFrame = true; } } } else { double CurClock = pClock->GetCurrentClock (); double Diff = FramePTS - CurClock; DEBUG ("V:CurClock=%f, FramePTS=%f, Diff=%f", CurClock, FramePTS, Diff); if (fabs(Diff) < CMasterClock::AVThresholdNoSync) { mbNextFrame = true; if (Diff <= 0) { VERBOSE ("show it at once."); } else { unsigned int usec = Diff * 1000 * 1000; VERBOSE ("wait %d usec", usec); usleep (usec); } Ret = pVStubRender->ShowPicture (mpFrame); } else { if (Diff < 0) { mbNextFrame = true; //如果系统时钟是以视频时钟为基准的,调整系统时钟 if(pClock->GetClockType()==CMasterClock::CLOCK_VIDEO) { WARN("we reset master timer to video FramePTS"); double ClockTime = PlayCore::GetInstance()->av_gettime() / 1000000.0; pClock->SetOriginClock (FramePTS, ClockTime); Ret = pVStubRender->ShowPicture (mpFrame); } else//否则是以其他(音频,系统时间)为系统时钟,此时视频严重落后于同步的时间范围值, { //对于直播不需要设定需要查找最近的关键帧标识 DEBUG("we need ReSync video FramePTS Diff %f",Diff); } } else { WARN ("video FramePTS far early than curr_pts Diff %f",Diff); unsigned int usec = Diff * 1000 * 1000; mbNextFrame = false; usleep (1*1000); } } DEBUG("ShowPicture Ret %d",Ret); } } else { ERROR ("you have not set Master Clock!!! will not show pictures!"); } PlayCore::GetInstance()->av_free_packet (&AVPkt); memset((void*)&AVPkt,0,sizeof(AVPacket)); } Reset(); if (AVPkt.data != 0) { PlayCore::GetInstance()->av_free_packet (&AVPkt); } DEBUG ("end of video out thread!"); }
KRB5Context::~KRB5Context() { VERBOSE("Destroying Kerberos Context"); krb5_free_context(m_context); }
int DVBRecorder::OpenFilterFd(uint pid, int pes_type, uint stream_type) { if (_open_pid_filters >= _max_pid_filters) return -1; // bits per millisecond uint bpms = (StreamID::IsVideo(stream_type)) ? 19200 : 500; // msec of buffering we want uint msec_of_buffering = max(POLL_WARNING_TIMEOUT + 50, 1500); // actual size of buffer we need uint pid_buffer_size = ((bpms*msec_of_buffering + 7) / 8); // rounded up to the nearest page pid_buffer_size = ((pid_buffer_size + 4095) / 4096) * 4096; VERBOSE(VB_RECORD, LOC + QString("Adding pid 0x%1 size(%2)") .arg(pid,0,16).arg(pid_buffer_size)); // Open the demux device QString dvbdev = CardUtil::GetDeviceName( DVB_DEV_DEMUX, _card_number_option); QByteArray dev = dvbdev.toAscii(); int fd_tmp = open(dev.constData(), O_RDWR); if (fd_tmp < 0) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not open demux device." + ENO); _max_pid_filters = _open_pid_filters; return -1; } // Try to make the demux buffer large enough to // allow for longish disk writes. uint sz = pid_buffer_size; uint usecs = msec_of_buffering * 1000; while (ioctl(fd_tmp, DMX_SET_BUFFER_SIZE, sz) < 0 && sz > 1024*8) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to set demux buffer size for "+ QString("pid 0x%1 to %2").arg(pid,0,16).arg(sz) + ENO); sz /= 2; sz = ((sz+4095)/4096)*4096; usecs /= 2; } /* VERBOSE(VB_RECORD, LOC + "Set demux buffer size for " + QString("pid 0x%1 to %2,\n\t\t\twhich gives us a %3 msec buffer.") .arg(pid,0,16).arg(sz).arg(usecs/1000)); */ // Set the filter type struct dmx_pes_filter_params params; memset(¶ms, 0, sizeof(params)); params.input = DMX_IN_FRONTEND; params.output = DMX_OUT_TS_TAP; params.flags = DMX_IMMEDIATE_START; params.pid = pid; params.pes_type = (dmx_pes_type_t) pes_type; if (ioctl(fd_tmp, DMX_SET_PES_FILTER, ¶ms) < 0) { close(fd_tmp); VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to set demux filter." + ENO); _max_pid_filters = _open_pid_filters; return -1; } _open_pid_filters++; return fd_tmp; }
bool DVBPIDInfo::Open(const QString &dvb_dev, bool use_section_reader) { if (filter_fd >= 0) { close(filter_fd); filter_fd = -1; } QString demux_fn = CardUtil::GetDeviceName(DVB_DEV_DEMUX, dvb_dev); QByteArray demux_ba = demux_fn.toAscii(); VERBOSE(VB_RECORD, LOC + QString("Opening filter for pid 0x%1") .arg(_pid, 0, 16)); int mux_fd = open(demux_ba.constData(), O_RDWR | O_NONBLOCK); if (mux_fd == -1) { VERBOSE(VB_IMPORTANT, LOC + QString("Failed to open demux device %1 " "for filter on pid 0x%2") .arg(demux_fn).arg(_pid, 0, 16)); return false; } if (!use_section_reader) { struct dmx_pes_filter_params pesFilterParams; memset(&pesFilterParams, 0, sizeof(struct dmx_pes_filter_params)); pesFilterParams.pid = (__u16) _pid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; pesFilterParams.flags = DMX_IMMEDIATE_START; pesFilterParams.pes_type = DMX_PES_OTHER; if (ioctl(mux_fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to set TS filter (pid 0x%1)") .arg(_pid, 0, 16)); close(mux_fd); return false; } } else { struct dmx_sct_filter_params sctFilterParams; memset(&sctFilterParams, 0, sizeof(struct dmx_sct_filter_params)); switch ( (__u16) _pid ) { case 0x0: // PAT sctFilterParams.filter.filter[0] = 0; sctFilterParams.filter.mask[0] = 0xff; break; case 0x0010: // assume this is for an NIT, NITo, PMT // This filter will give us table ids 0x00-0x03, 0x40-0x43 // we expect to see table ids 0x02, 0x40 and 0x41 on this PID // NOTE: In theory, this will break with ATSC when PID 0x10 // is used for ATSC/MPEG tables. This is frowned upon, // but PMTs have been seen on in the wild. sctFilterParams.filter.filter[0] = 0x00; sctFilterParams.filter.mask[0] = 0xbc; break; case 0x0011: // assume this is for an SDT, SDTo, PMT // This filter will give us table ids 0x02, 0x06, 0x42 and 0x46 // All but 0x06 are ones we want to see. // NOTE: In theory this will break with ATSC when pid 0x11 // is used for random ATSC tables. In practice only // video data has been seen on 0x11. sctFilterParams.filter.filter[0] = 0x02; sctFilterParams.filter.mask[0] = 0xbb; break; case 0x1ffb: // assume this is for various ATSC tables // MGT 0xC7, Terrestrial VCT 0xC8, Cable VCT 0xC9, RRT 0xCA, // STT 0xCD, DCCT 0xD3, DCCSCT 0xD4, Caption 0x86 sctFilterParams.filter.filter[0] = 0x80; sctFilterParams.filter.mask[0] = 0xa0; break; default: // otherwise assume it could be any table sctFilterParams.filter.filter[0] = 0x00; sctFilterParams.filter.mask[0] = 0x00; break; } sctFilterParams.pid = (__u16) _pid; sctFilterParams.timeout = 0; sctFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(mux_fd, DMX_SET_FILTER, &sctFilterParams) < 0) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to set \"section\" filter " + QString("(pid 0x%1) (filter %2)").arg(_pid, 0, 16) .arg(sctFilterParams.filter.filter[0])); close(mux_fd); return false; } } filter_fd = mux_fd; return true; }
/** \fn DVBStreamHandler::RunTS(void) * \brief Uses TS filtering devices to read a DVB device for tables & data * * This supports all types of MPEG based stream data, but is extreemely * slow with DVB over USB 1.0 devices which for efficiency reasons buffer * a stream until a full block transfer buffer full of the requested * tables is available. This takes a very long time when you are just * waiting for a PAT or PMT table, and the buffer is hundreds of packets * in size. */ void DVBStreamHandler::RunTS(void) { QByteArray dvr_dev_path = _dvr_dev_path.toAscii(); int dvr_fd; for (int tries = 1; ; ++tries) { dvr_fd = open(dvr_dev_path.constData(), O_RDONLY | O_NONBLOCK); if (dvr_fd >= 0) break; VERBOSE(VB_IMPORTANT, LOC_WARN + QString("Opening DVR device %1 failed : %2") .arg(_dvr_dev_path).arg(strerror(errno))); if (tries >= 20 || (errno != EBUSY && errno != EAGAIN)) { VERBOSE(VB_IMPORTANT, LOC + QString("Failed to open DVR device %1 : %2") .arg(_dvr_dev_path).arg(strerror(errno))); _error = true; return; } usleep(50000); } int remainder = 0; int buffer_size = TSPacket::kSize * 15000; unsigned char *buffer = new unsigned char[buffer_size]; if (!buffer) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to allocate memory"); close(dvr_fd); _error = true; return; } bzero(buffer, buffer_size); DeviceReadBuffer *drb = NULL; if (_needs_buffering) { drb = new DeviceReadBuffer(this); if (!drb->Setup(_device, dvr_fd)) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to allocate DRB buffer"); delete drb; delete[] buffer; close(dvr_fd); _error = true; return; } drb->Start(); } SetRunning(true, _needs_buffering, false); { QMutexLocker locker(&_start_stop_lock); _drb = drb; } VERBOSE(VB_RECORD, LOC + "RunTS(): begin"); bool _error = false; fd_set fd_select_set; FD_ZERO( &fd_select_set); FD_SET (dvr_fd, &fd_select_set); while (_running_desired && !_error) { RetuneMonitor(); UpdateFiltersFromStreamData(); ssize_t len = 0; if (drb) { len = drb->Read( &(buffer[remainder]), buffer_size - remainder); // Check for DRB errors if (drb->IsErrored()) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Device error detected"); _error = true; } if (drb->IsEOF()) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Device EOF detected"); _error = true; } } else { // timeout gets reset by select, so we need to create new one struct timeval timeout = { 0, 50 /* ms */ * 1000 /* -> usec */ }; int ret = select(dvr_fd+1, &fd_select_set, NULL, NULL, &timeout); if (ret == -1 && errno != EINTR) { VERBOSE(VB_IMPORTANT, LOC_ERR + "select() failed" + ENO); } else { len = read(dvr_fd, &(buffer[remainder]), buffer_size - remainder); } } if ((0 == len) || (-1 == len)) { usleep(100); continue; } len += remainder; if (len < 10) // 10 bytes = 4 bytes TS header + 6 bytes PES header { remainder = len; continue; } _listener_lock.lock(); if (_stream_data_list.empty()) { _listener_lock.unlock(); continue; } StreamDataList::const_iterator sit = _stream_data_list.begin(); for (; sit != _stream_data_list.end(); ++sit) remainder = sit.key()->ProcessData(buffer, len); _listener_lock.unlock(); if (remainder > 0 && (len > remainder)) // leftover bytes memmove(buffer, &(buffer[len - remainder]), remainder); } VERBOSE(VB_RECORD, LOC + "RunTS(): " + "shutdown"); RemoveAllPIDFilters(); { QMutexLocker locker(&_start_stop_lock); _drb = NULL; } if (drb) { if (drb->IsRunning()) drb->Stop(); delete drb; } close(dvr_fd); delete[] buffer; VERBOSE(VB_RECORD, LOC + "RunTS(): " + "end"); SetRunning(false, _needs_buffering, false); }
ULONG __stdcall IWaterMarkUI::AddRef() { VERBOSE(DLLTEXT("IWaterMarkUI:AddRef entry.\r\n")); return InterlockedIncrement(&m_cRef) ; }
bool setupTVs(bool ismaster, bool &error) { error = false; QString localhostname = gCoreContext->GetHostName(); MSqlQuery query(MSqlQuery::InitCon()); if (ismaster) { // Hack to make sure recorded.basename gets set if the user // downgrades to a prior version and creates new entries // without it. if (!query.exec("UPDATE recorded SET basename = CONCAT(chanid, '_', " "DATE_FORMAT(starttime, '%Y%m%d%H%i00'), '_', " "DATE_FORMAT(endtime, '%Y%m%d%H%i00'), '.nuv') " "WHERE basename = '';")) MythDB::DBError("Updating record basename", query.lastQuery()); // Hack to make sure record.station gets set if the user // downgrades to a prior version and creates new entries // without it. if (!query.exec("UPDATE channel SET callsign=chanid " "WHERE callsign IS NULL OR callsign='';")) MythDB::DBError("Updating channel callsign", query.lastQuery()); if (query.exec("SELECT MIN(chanid) FROM channel;")) { query.first(); int min_chanid = query.value(0).toInt(); if (!query.exec(QString("UPDATE record SET chanid = %1 " "WHERE chanid IS NULL;").arg(min_chanid))) MythDB::DBError("Updating record chanid", query.lastQuery()); } else MythDB::DBError("Querying minimum chanid", query.lastQuery()); MSqlQuery records_without_station(MSqlQuery::InitCon()); records_without_station.prepare("SELECT record.chanid," " channel.callsign FROM record LEFT JOIN channel" " ON record.chanid = channel.chanid WHERE record.station='';"); if (records_without_station.exec() && records_without_station.next()) { MSqlQuery update_record(MSqlQuery::InitCon()); update_record.prepare("UPDATE record SET station = :CALLSIGN" " WHERE chanid = :CHANID;"); do { update_record.bindValue(":CALLSIGN", records_without_station.value(1)); update_record.bindValue(":CHANID", records_without_station.value(0)); if (!update_record.exec()) { MythDB::DBError("Updating record station", update_record.lastQuery()); } } while (records_without_station.next()); } } if (!query.exec( "SELECT cardid, hostname " "FROM capturecard " "ORDER BY cardid")) { MythDB::DBError("Querying Recorders", query); return false; } vector<uint> cardids; vector<QString> hosts; while (query.next()) { uint cardid = query.value(0).toUInt(); QString host = query.value(1).toString(); QString cidmsg = QString("Card %1").arg(cardid); if (host.isEmpty()) { QString msg = cidmsg + " does not have a hostname defined.\n" "Please run setup and confirm all of the capture cards.\n"; VERBOSE(VB_IMPORTANT, msg); gCoreContext->LogEntry("mythbackend", LP_CRITICAL, "Problem with capture cards", msg); continue; } cardids.push_back(cardid); hosts.push_back(host); } for (uint i = 0; i < cardids.size(); i++) { if (hosts[i] == localhostname) new TVRec(cardids[i]); } for (uint i = 0; i < cardids.size(); i++) { uint cardid = cardids[i]; QString host = hosts[i]; QString cidmsg = QString("Card %1").arg(cardid); if (!ismaster) { if (host == localhostname) { TVRec *tv = TVRec::GetTVRec(cardid); if (tv && tv->Init()) { EncoderLink *enc = new EncoderLink(cardid, tv); tvList[cardid] = enc; } else { gCoreContext->LogEntry("mythbackend", LP_CRITICAL, "Problem with capture cards", cidmsg + " failed init"); delete tv; // The master assumes card comes up so we need to // set error and exit if a non-master card fails. error = true; } } } else { if (host == localhostname) { TVRec *tv = TVRec::GetTVRec(cardid); if (tv && tv->Init()) { EncoderLink *enc = new EncoderLink(cardid, tv); tvList[cardid] = enc; } else { gCoreContext->LogEntry("mythbackend", LP_CRITICAL, "Problem with capture cards", cidmsg + "failed init"); delete tv; } } else { EncoderLink *enc = new EncoderLink(cardid, NULL, host); tvList[cardid] = enc; } } } if (tvList.empty()) { VERBOSE(VB_IMPORTANT, LOC_WARN + "No valid capture cards are defined in the database."); gCoreContext->LogEntry("mythbackend", LP_WARNING, "No capture cards are defined", "This backend will not be used for recording."); } return true; }
void RaceAnalyzerComm::writeConfig(RaceCaptureConfig *config, RaceAnalyzerCommCallback * callback){ try{ wxDateTime start = wxDateTime::UNow(); CComm *serialPort = GetSerialPort(); if (NULL==serialPort) throw CommException(CommException::OPEN_PORT_FAILED); int updateCount = 0; for (int i = 0; i < CONFIG_ANALOG_CHANNELS;i++){ AnalogConfig &cfg = config->analogConfigs[i]; wxString cmd = "setAnalogCfg"; cmd = AppendIntParam(cmd, i); cmd = AppendChannelConfig(cmd, cfg.channelConfig); cmd = AppendIntParam(cmd, cfg.loggingPrecision); cmd = AppendIntParam(cmd, cfg.scalingMode); cmd = AppendFloatParam(cmd, cfg.linearScaling); ScalingMap &map = (cfg.scalingMap); for (int m=0; m < CONFIG_ANALOG_SCALING_BINS;m++){ cmd = AppendIntParam(cmd, map.rawValues[m]); } for (int m=0; m < CONFIG_ANALOG_SCALING_BINS;m++){ cmd = AppendFloatParam(cmd, map.scaledValue[m]); } wxString result = SendCommand(serialPort, cmd); CheckThrowResult(result); updateWriteConfigPct(++updateCount,callback); } for (int i = 0; i < CONFIG_TIMER_CHANNELS; i++){ TimerConfig &cfg = config->timerConfigs[i]; wxString cmd = "setTimerCfg"; cmd = AppendIntParam(cmd, i); AppendChannelConfig(cmd, cfg.channelConfig); cmd = AppendIntParam(cmd, cfg.loggingPrecision); cmd = AppendIntParam(cmd, cfg.slowTimerEnabled); cmd = AppendIntParam(cmd, cfg.mode); cmd = AppendIntParam(cmd, cfg.pulsePerRev); cmd = AppendIntParam(cmd, cfg.timerDivider); cmd = AppendIntParam(cmd, cfg.scaling); wxString result = SendCommand(serialPort, cmd); CheckThrowResult(result); updateWriteConfigPct(++updateCount,callback); } for (int i = 0; i < CONFIG_ACCEL_CHANNELS; i++){ AccelConfig &cfg = config->accelConfigs[i]; wxString cmd = "setAccelCfg"; cmd = AppendIntParam(cmd, i); cmd = AppendChannelConfig(cmd, cfg.channelConfig); cmd = AppendIntParam(cmd, cfg.mode); cmd = AppendIntParam(cmd, cfg.channel); cmd = AppendIntParam(cmd, cfg.zeroValue); wxString result = SendCommand(serialPort, cmd); CheckThrowResult(result); updateWriteConfigPct(++updateCount,callback); } for (int i = 0; i < CONFIG_ANALOG_PULSE_CHANNELS; i++){ PwmConfig &cfg = config->pwmConfigs[i]; wxString cmd = "setPwmCfg"; cmd = AppendIntParam(cmd, i); cmd = AppendChannelConfig(cmd, cfg.channelConfig); cmd = AppendIntParam(cmd, cfg.loggingPrecision); cmd = AppendIntParam(cmd, cfg.outputMode); cmd = AppendIntParam(cmd, cfg.loggingMode); cmd = AppendIntParam(cmd, cfg.startupDutyCycle); cmd = AppendIntParam(cmd, cfg.startupPeriod); cmd = AppendFloatParam(cmd, cfg.voltageScaling); wxString result = SendCommand(serialPort, cmd); CheckThrowResult(result); updateWriteConfigPct(++updateCount,callback); } for (int i = 0; i < CONFIG_GPIO_CHANNELS; i++){ GpioConfig &cfg = config->gpioConfigs[i]; wxString cmd = "setGpioCfg"; cmd = AppendIntParam(cmd,i); cmd = AppendChannelConfig(cmd, cfg.channelConfig); cmd = AppendIntParam(cmd, cfg.mode); wxString result = SendCommand(serialPort, cmd); CheckThrowResult(result); updateWriteConfigPct(++updateCount,callback); } { GpsConfig &cfg = config->gpsConfig; { wxString cmd = "setGpsCfg"; cmd = AppendIntParam(cmd, cfg.gpsInstalled); cmd = AppendChannelConfig(cmd, cfg.latitudeCfg); cmd = AppendChannelConfig(cmd, cfg.longitudeCfg); cmd = AppendChannelConfig(cmd, cfg.speedCfg); cmd = AppendChannelConfig(cmd, cfg.timeCfg); cmd = AppendChannelConfig(cmd, cfg.satellitesCfg); wxString result = SendCommand(serialPort, cmd); CheckThrowResult(result); updateWriteConfigPct(++updateCount,callback); } { wxString cmd = "setStartFinishCfg"; cmd = AppendChannelConfig(cmd, cfg.lapCountCfg); cmd = AppendChannelConfig(cmd, cfg.lapTimeCfg); cmd = AppendChannelConfig(cmd, cfg.splitTimeCfg); cmd = AppendFloatParam(cmd, cfg.startFinishTarget.latitude); cmd = AppendFloatParam(cmd, cfg.startFinishTarget.longitude); cmd = AppendFloatParam(cmd, cfg.startFinishTarget.targetRadius); cmd = AppendFloatParam(cmd, cfg.splitTarget.latitude); cmd = AppendFloatParam(cmd, cfg.splitTarget.longitude); cmd = AppendFloatParam(cmd, cfg.splitTarget.targetRadius); wxString result = SendCommand(serialPort, cmd); CheckThrowResult(result); updateWriteConfigPct(++updateCount,callback); } } { ConnectivityConfig &cfg = config->connectivityConfig; wxString cmd = "setOutputCfg"; cmd = AppendIntParam(cmd, cfg.sdLoggingMode); cmd = AppendIntParam(cmd, cfg.connectivityMode); cmd = AppendUIntParam(cmd, cfg.p2pConfig.destinationAddrHigh); cmd = AppendUIntParam(cmd, cfg.p2pConfig.destinationAddrLow); cmd = AppendStringParam(cmd, cfg.telemetryConfig.telemetryServer); cmd = AppendStringParam(cmd, cfg.telemetryConfig.telemetryDeviceId); wxString result = SendCommand(serialPort, cmd); CheckThrowResult(result); cmd = "setCellCfg"; cmd = AppendStringParam(cmd, cfg.cellularConfig.apnHost); cmd = AppendStringParam(cmd, cfg.cellularConfig.apnUser); cmd = AppendStringParam(cmd, cfg.cellularConfig.apnPass); result = SendCommand(serialPort, cmd); CheckThrowResult(result); updateWriteConfigPct(++updateCount,callback); } { writeScript(config->luaScript); updateWriteConfigPct(++updateCount,callback); } wxTimeSpan dur = wxDateTime::UNow() - start; VERBOSE(FMT("write config in %f",dur.GetMilliseconds().ToDouble())); callback->WriteConfigComplete(true,""); } catch(CommException &e){ callback->WriteConfigComplete(false, e.GetErrorMessage()); } CloseSerialPort(); }
int run_backend(const MythCommandLineParser &cmdline) { if (!setup_context(cmdline)) return GENERIC_EXIT_NO_MYTHCONTEXT; bool ismaster = gCoreContext->IsMasterHost(); if (!UpgradeTVDatabaseSchema(ismaster, ismaster)) { VERBOSE(VB_IMPORTANT, "Couldn't upgrade database to new schema"); return GENERIC_EXIT_DB_OUTOFDATE; } if (!ismaster) { int ret = connect_to_master(); if (ret != GENERIC_EXIT_OK) return ret; } QString myip = gCoreContext->GetSetting("BackendServerIP"); int port = gCoreContext->GetNumSetting("BackendServerPort", 6543); if (myip.isEmpty()) { cerr << "No setting found for this machine's BackendServerIP.\n" << "Please run setup on this machine and modify the first page\n" << "of the general settings.\n"; return GENERIC_EXIT_SETUP_ERROR; } MythSystemEventHandler *sysEventHandler = new MythSystemEventHandler(); if (ismaster) { VERBOSE(VB_GENERAL, LOC + "Starting up as the master server."); gCoreContext->LogEntry("mythbackend", LP_INFO, "MythBackend started as master server", ""); } else { VERBOSE(VB_GENERAL, LOC + "Running as a slave backend."); gCoreContext->LogEntry("mythbackend", LP_INFO, "MythBackend started as a slave backend", ""); } print_warnings(cmdline); bool fatal_error = false; bool runsched = setupTVs(ismaster, fatal_error); if (fatal_error) { delete sysEventHandler; return GENERIC_EXIT_SETUP_ERROR; } if (ismaster) { if (runsched) { sched = new Scheduler(true, &tvList); int err = sched->GetError(); if (err) return err; if (!cmdline.IsSchedulerEnabled()) sched->DisableScheduling(); } if (cmdline.IsHouseKeeperEnabled()) housekeeping = new HouseKeeper(true, ismaster, sched); if (cmdline.IsAutoExpirerEnabled()) { expirer = new AutoExpire(&tvList); if (sched) sched->SetExpirer(expirer); } } else if (cmdline.IsHouseKeeperEnabled()) { housekeeping = new HouseKeeper(true, ismaster, NULL); } if (cmdline.IsJobQueueEnabled()) jobqueue = new JobQueue(ismaster); // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- if (g_pUPnp == NULL) { g_pUPnp = new MediaServer(); g_pUPnp->Init(ismaster, !cmdline.IsUPnPEnabled()); } // ---------------------------------------------------------------------- // Setup status server // ---------------------------------------------------------------------- HttpStatus *httpStatus = NULL; HttpServer *pHS = g_pUPnp->GetHttpServer(); if (pHS) { VERBOSE(VB_IMPORTANT, "Main::Registering HttpStatus Extension"); httpStatus = new HttpStatus( &tvList, sched, expirer, ismaster ); pHS->RegisterExtension( httpStatus ); } VERBOSE(VB_IMPORTANT, QString("Enabled verbose msgs: %1") .arg(verboseString)); MainServer *mainServer = new MainServer( ismaster, port, &tvList, sched, expirer); int exitCode = mainServer->GetExitCode(); if (exitCode != GENERIC_EXIT_OK) { VERBOSE(VB_IMPORTANT, "Backend exiting, MainServer initialization " "error."); delete mainServer; return exitCode; } if (httpStatus && mainServer) httpStatus->SetMainServer(mainServer); StorageGroup::CheckAllStorageGroupDirs(); if (gCoreContext->IsMasterBackend()) SendMythSystemEvent("MASTER_STARTED"); /////////////////////////////// /////////////////////////////// exitCode = qApp->exec(); /////////////////////////////// /////////////////////////////// if (gCoreContext->IsMasterBackend()) { SendMythSystemEvent("MASTER_SHUTDOWN"); qApp->processEvents(); } gCoreContext->LogEntry("mythbackend", LP_INFO, "MythBackend exiting", ""); delete sysEventHandler; delete mainServer; cleanup(); return exitCode; }
int main(int argc, char **argv) { int ret; trap_ifc_spec_t ifc_spec; //char *ifc_params[] = {"traptestshm,650000;traptestshm,650000"}; //ifc_spec.types = "mm"; char *ifc_params[3] = { argv[0], "-i", "tt;localhost,11111,65533;11111,5,65533" }; int paramno = 3; uint64_t counter = 0; uint64_t iteration = 0; time_t duration; uint16_t payload_size; char *payload = NULL; //verbose = CL_VERBOSE_LIBRARY; trap_verbose = CL_VERBOSE_OFF; VERBOSE(CL_VERBOSE_OFF, "%s [number]\nnumber - size of data to send for testing", argv[0]); ret = trap_parse_params(¶mno, ifc_params, &ifc_spec); if (ret != TRAP_E_OK) { if (ret == TRAP_E_HELP) { // "-h" was found trap_print_help(&module_info); return 0; } fprintf(stderr, "ERROR in parsing of parameters for TRAP: %s\n", trap_last_error_msg); return 1; } // Initialize TRAP library (create and init all interfaces) ret = trap_init(&module_info, ifc_spec); if (ret != TRAP_E_OK) { fprintf(stderr, "ERROR in TRAP initialization %s\n", trap_last_error_msg); return 1; } duration = time(NULL); // Read data from input, process them and write to output while(!stop) { ret = trap_get_data(0, (const void **) &payload, &payload_size, TRAP_WAIT); if (ret != TRAP_E_OK) { VERBOSE(CL_ERROR, "error: %s", trap_last_error_msg); } ret = trap_send_data(0, (void *) payload, payload_size, TRAP_WAIT); if (ret == TRAP_E_OK) { counter++; } else { VERBOSE(CL_ERROR, "error: %s", trap_last_error_msg); } iteration++; if (counter == 10) { break; } } duration = time(NULL) - duration; printf("Number of iterations: %"PRIu64"\nLast sent: %"PRIu64"\nTime: %"PRIu64"s\n", (uint64_t) iteration, (uint64_t) counter-1, (uint64_t) duration); sleep(2); // Do all necessary cleanup before exiting // (close interfaces and free allocated memory) trap_finalize(); //free(payload); return 0; }
/// Compares two VideoMetadata instances bool VideoFilterSettings::meta_less_than(const VideoMetadata &lhs, const VideoMetadata &rhs, bool sort_ignores_case) const { bool ret = false; switch (orderby) { case kOrderByTitle: { VideoMetadata::SortKey lhs_key; VideoMetadata::SortKey rhs_key; if (lhs.HasSortKey() && rhs.HasSortKey()) { lhs_key = lhs.GetSortKey(); rhs_key = rhs.GetSortKey(); } else { lhs_key = VideoMetadata::GenerateDefaultSortKey(lhs, sort_ignores_case); rhs_key = VideoMetadata::GenerateDefaultSortKey(rhs, sort_ignores_case); } ret = lhs_key < rhs_key; break; } case kOrderBySeasonEp: { if ((lhs.GetSeason() == rhs.GetSeason()) && (lhs.GetEpisode() == rhs.GetEpisode()) && (lhs.GetSeason() == 0) && (rhs.GetSeason() == 0) && (lhs.GetEpisode() == 0) && (rhs.GetEpisode() == 0)) { VideoMetadata::SortKey lhs_key; VideoMetadata::SortKey rhs_key; if (lhs.HasSortKey() && rhs.HasSortKey()) { lhs_key = lhs.GetSortKey(); rhs_key = rhs.GetSortKey(); } else { lhs_key = VideoMetadata::GenerateDefaultSortKey(lhs, sort_ignores_case); rhs_key = VideoMetadata::GenerateDefaultSortKey(rhs, sort_ignores_case); } ret = lhs_key < rhs_key; } else if (lhs.GetSeason() == rhs.GetSeason() && lhs.GetTitle() == rhs.GetTitle()) ret = lhs.GetEpisode() < rhs.GetEpisode(); else ret = lhs.GetSeason() < rhs.GetSeason(); break; } case kOrderByYearDescending: { ret = lhs.GetYear() > rhs.GetYear(); break; } case kOrderByUserRatingDescending: { ret = lhs.GetUserRating() > rhs.GetUserRating(); break; } case kOrderByLength: { ret = lhs.GetLength() < rhs.GetLength(); break; } case kOrderByFilename: { QString lhsfn(sort_ignores_case ? lhs.GetFilename().toLower() : lhs.GetFilename()); QString rhsfn(sort_ignores_case ? rhs.GetFilename().toLower() : rhs.GetFilename()); ret = QString::localeAwareCompare(lhsfn, rhsfn) < 0; break; } case kOrderByID: { ret = lhs.GetID() < rhs.GetID(); break; } case kOrderByDateAddedDescending: { ret = lhs.GetInsertdate() > rhs.GetInsertdate(); break; } default: { VERBOSE(VB_IMPORTANT, QString("Error: unknown sort type %1") .arg(orderby)); } } return ret; }
void ScanWizard::SetPage(const QString &pageTitle) { VERBOSE(VB_CHANSCAN, QString("SetPage(%1)").arg(pageTitle)); if (pageTitle != ChannelScannerGUI::kTitle) { scannerPane->quitScanning(); return; } QMap<QString,QString> start_chan; DTVTunerType parse_type = DTVTunerType::kTunerTypeUnknown; uint cardid = configPane->GetCardID(); QString inputname = configPane->GetInputName(); uint sourceid = configPane->GetSourceID(); int scantype = configPane->GetScanType(); bool do_scan = true; VERBOSE(VB_CHANSCAN, LOC + "SetPage(): " + QString("type(%1) cardid(%2) inputname(%3)") .arg(scantype).arg(cardid).arg(inputname)); if (scantype == ScanTypeSetting::DVBUtilsImport) { scannerPane->ImportDVBUtils(sourceid, lastHWCardType, configPane->GetFilename()); } else if (scantype == ScanTypeSetting::NITAddScan_DVBT) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeDVBT; } else if (scantype == ScanTypeSetting::NITAddScan_DVBS) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeDVBS1; } else if (scantype == ScanTypeSetting::NITAddScan_DVBS2) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeDVBS2; } else if (scantype == ScanTypeSetting::NITAddScan_DVBC) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeDVBC; } else if (scantype == ScanTypeSetting::IPTVImport) { do_scan = false; scannerPane->ImportM3U(cardid, inputname, sourceid); } else if ((scantype == ScanTypeSetting::FullScan_ATSC) || (scantype == ScanTypeSetting::FullTransportScan) || (scantype == ScanTypeSetting::TransportScan) || (scantype == ScanTypeSetting::FullScan_DVBC) || (scantype == ScanTypeSetting::FullScan_DVBT) || (scantype == ScanTypeSetting::FullScan_Analog)) { ; } else if (scantype == ScanTypeSetting::ExistingScanImport) { do_scan = false; uint scanid = configPane->GetScanID(); ScanDTVTransportList transports = LoadScan(scanid); ChannelImporter ci(true, true, true, true, false, configPane->DoFreeToAirOnly(), configPane->GetServiceRequirements()); ci.Process(transports); } else { do_scan = false; VERBOSE(VB_CHANSCAN, LOC_ERR + "SetPage(): " + QString("type(%1) src(%2) cardid(%3) not handled") .arg(scantype).arg(sourceid).arg(cardid)); MythPopupBox::showOkPopup( GetMythMainWindow(), tr("ScanWizard"), tr("Programmer Error, see console")); } // Just verify what we get from the UI... DTVMultiplex tuning; if ((parse_type != DTVTunerType::kTunerTypeUnknown) && !tuning.ParseTuningParams( parse_type, start_chan["frequency"], start_chan["inversion"], start_chan["symbolrate"], start_chan["fec"], start_chan["polarity"], start_chan["coderate_hp"], start_chan["coderate_lp"], start_chan["constellation"], start_chan["trans_mode"], start_chan["guard_interval"], start_chan["hierarchy"], start_chan["modulation"], start_chan["bandwidth"], start_chan["mod_sys"], start_chan["rolloff"])) { MythPopupBox::showOkPopup( GetMythMainWindow(), tr("ScanWizard"), tr("Error parsing parameters")); do_scan = false; } if (do_scan) { QString table_start, table_end; configPane->GetFrequencyTableRange(table_start, table_end); scannerPane->Scan( configPane->GetScanType(), configPane->GetCardID(), configPane->GetInputName(), configPane->GetSourceID(), configPane->DoIgnoreSignalTimeout(), configPane->DoFollowNIT(), configPane->DoTestDecryption(), configPane->DoFreeToAirOnly(), configPane->GetServiceRequirements(), // stuff needed for particular scans configPane->GetMultiplex(), start_chan, configPane->GetFrequencyStandard(), configPane->GetModulation(), configPane->GetFrequencyTable(), table_start, table_end); } }
bool VideoFilterDialog::Create() { if (!LoadWindowFromXML("video-ui.xml", "filter", this)) return false; bool err = false; UIUtilE::Assign(this, m_textfilter, "textfilter_input", &err); UIUtilE::Assign(this, m_yearList, "year_select", &err); UIUtilE::Assign(this, m_userratingList, "userrating_select", &err); UIUtilE::Assign(this, m_categoryList, "category_select", &err); UIUtilE::Assign(this, m_countryList, "country_select", &err); UIUtilE::Assign(this, m_genreList, "genre_select", &err); UIUtilE::Assign(this, m_castList, "cast_select", &err); UIUtilE::Assign(this, m_runtimeList, "runtime_select", &err); UIUtilE::Assign(this, m_browseList, "browse_select", &err); UIUtilE::Assign(this, m_watchedList, "watched_select", &err); UIUtilE::Assign(this, m_inetrefList, "inetref_select", &err); UIUtilE::Assign(this, m_coverfileList, "coverfile_select", &err); UIUtilE::Assign(this, m_orderbyList, "orderby_select", &err); UIUtilE::Assign(this, m_doneButton, "done_button", &err); UIUtilE::Assign(this, m_saveButton, "save_button", &err); UIUtilE::Assign(this, m_numvideosText, "numvideos_text", &err); if (err) { VERBOSE(VB_IMPORTANT, "Cannot load screen 'filter'"); return false; } BuildFocusList(); fillWidgets(); update_numvideo(); connect(m_yearList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(SetYear(MythUIButtonListItem*))); connect(m_userratingList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(SetUserRating(MythUIButtonListItem*))); connect(m_categoryList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(SetCategory(MythUIButtonListItem*))); connect(m_countryList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(setCountry(MythUIButtonListItem*))); connect(m_genreList,SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(setGenre(MythUIButtonListItem*))); connect(m_castList,SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(SetCast(MythUIButtonListItem*))); connect(m_runtimeList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(setRunTime(MythUIButtonListItem*))); connect(m_browseList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(SetBrowse(MythUIButtonListItem*))); connect(m_watchedList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(SetWatched(MythUIButtonListItem*))); connect(m_inetrefList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(SetInetRef(MythUIButtonListItem*))); connect(m_coverfileList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(SetCoverFile(MythUIButtonListItem*))); connect(m_orderbyList, SIGNAL(itemSelected(MythUIButtonListItem*)), SLOT(setOrderby(MythUIButtonListItem*))); connect(m_textfilter, SIGNAL(valueChanged()), SLOT(setTextFilter())); connect(m_saveButton, SIGNAL(Clicked()), SLOT(saveAsDefault())); connect(m_doneButton, SIGNAL(Clicked()), SLOT(saveAndExit())); return true; }
/** * Copy in @host_path the equivalent of "@tracee->root + * canonicalize(@dir_fd + @guest_path)". If @guest_path is not * absolute then it is relative to the directory referred by the * descriptor @dir_fd (AT_FDCWD is for the current working directory). * See the documentation of canonicalize() for the meaning of * @deref_final. This function returns -errno if an error occured, * otherwise 0. */ int translate_path(Tracee *tracee, char host_path[PATH_MAX], int dir_fd, const char *guest_path, bool deref_final) { int status; /* Use "/" as the base if it is an absolute guest path. */ if (guest_path[0] == '/') { strcpy(host_path, "/"); } /* It is relative to the current working directory or to a * directory referred by a descriptors, see openat(2) for * details. */ else if (dir_fd == AT_FDCWD) { status = getcwd2(tracee, host_path); if (status < 0) return status; } else { struct stat statl; /* /proc/@tracee->pid/fd/@dir_fd -> host_path. */ status = readlink_proc_pid_fd(tracee->pid, dir_fd, host_path); if (status < 0) return status; /* Ensure it points to a directory. */ status = stat(host_path, &statl); if (status < 0) return -errno; if (!S_ISDIR(statl.st_mode)) return -ENOTDIR; /* Remove the leading "root" part of the base * (required!). */ status = detranslate_path(tracee, host_path, NULL); if (status < 0) return status; } VERBOSE(tracee, 2, "pid %d: translate(\"%s\" + \"%s\")", tracee != NULL ? tracee->pid : 0, host_path, guest_path); status = notify_extensions(tracee, GUEST_PATH, (intptr_t)host_path, (intptr_t)guest_path); if (status < 0) return status; if (status > 0) goto skip; /* Canonicalize regarding the new root. */ status = canonicalize(tracee, guest_path, deref_final, host_path, 0); if (status < 0) return status; /* Final binding substitution to convert "host_path" into a host * path, since canonicalize() works from the guest * point-of-view. */ status = substitute_binding(tracee, GUEST, host_path); if (status < 0) return status; skip: VERBOSE(tracee, 2, "pid %d: -> \"%s\"", tracee != NULL ? tracee->pid : 0, host_path); return 0; }
void MythSocketThread::run(void) { VERBOSE(VB_SOCKET, "MythSocketThread: readyread thread start"); QMutexLocker locker(&m_readyread_lock); m_readyread_started_wait.wakeAll(); while (m_readyread_run) { VERBOSE(VB_SOCKET|VB_EXTRA, "ProcessAddRemoveQueues"); ProcessAddRemoveQueues(); VERBOSE(VB_SOCKET|VB_EXTRA, "Construct FD_SET"); // construct FD_SET for all connected and unlocked sockets... int maxfd = -1; fd_set rfds; FD_ZERO(&rfds); QList<MythSocket*>::const_iterator it = m_readyread_list.begin(); for (; it != m_readyread_list.end(); ++it) { if (!(*it)->TryLock(false)) continue; if ((*it)->state() == MythSocket::Connected && !(*it)->m_notifyread) { FD_SET((*it)->socket(), &rfds); maxfd = std::max((*it)->socket(), maxfd); } (*it)->Unlock(false); } // There are no unlocked sockets, wait for event before we continue.. if (maxfd < 0) { VERBOSE(VB_SOCKET|VB_EXTRA, "Empty FD_SET, sleeping"); if (m_readyread_wait.wait(&m_readyread_lock)) VERBOSE(VB_SOCKET|VB_EXTRA, "Empty FD_SET, woken up"); else VERBOSE(VB_SOCKET|VB_EXTRA, "Empty FD_SET, timed out"); continue; } int rval = 0; if (m_readyread_pipe[0] >= 0) { // Clear out any pending pipe reads, we have already taken care of // this event above under the m_readyread_lock. char dummy[128]; if (m_readyread_pipe_flags[0] & O_NONBLOCK) { rval = ::read(m_readyread_pipe[0], dummy, 128); FD_SET(m_readyread_pipe[0], &rfds); maxfd = std::max(m_readyread_pipe[0], maxfd); } // also exit select on exceptions on same descriptors fd_set efds; memcpy(&efds, &rfds, sizeof(fd_set)); // The select waits forever for data, so if we need to process // anything else we need to write to m_readyread_pipe[1].. // We unlock the ready read lock, because we don't need it // and this will allow WakeReadyReadThread() to run.. m_readyread_lock.unlock(); VERBOSE(VB_SOCKET|VB_EXTRA, "Waiting on select.."); rval = select(maxfd + 1, &rfds, NULL, &efds, NULL); VERBOSE(VB_SOCKET|VB_EXTRA, "Got data on select"); m_readyread_lock.lock(); if (rval > 0 && FD_ISSET(m_readyread_pipe[0], &rfds)) { int ret = ::read(m_readyread_pipe[0], dummy, 128); if (ret < 0) { VERBOSE(VB_SOCKET|VB_EXTRA, "Strange.. failed to read event pipe"); } } } else { VERBOSE(VB_SOCKET|VB_EXTRA, "Waiting on select.. (no pipe)"); // also exit select on exceptions on same descriptors fd_set efds; memcpy(&efds, &rfds, sizeof(fd_set)); // Unfortunately, select on a pipe is not supported on all // platforms. So we fallback to a loop that instead times out // of select and checks for wakeAll event. while (!rval) { struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = kShortWait * 1000; rval = select(maxfd + 1, &rfds, NULL, &efds, &timeout); if (!rval) m_readyread_wait.wait(&m_readyread_lock, kShortWait); } VERBOSE(VB_SOCKET|VB_EXTRA, "Got data on select (no pipe)"); } if (rval <= 0) { if (rval == 0) { // Note: This should never occur when using pipes. When there // is no error there should be data in at least one fd.. VERBOSE(VB_SOCKET|VB_EXTRA, "MythSocketThread: select timeout"); } else VERBOSE(VB_SOCKET, "MythSocketThread: select returned error" + ENO); m_readyread_wait.wait(&m_readyread_lock, kShortWait); continue; } // ReadyToBeRead allows calls back into the socket so we need // to release the lock for a little while. // since only this loop updates m_readyread_list this is safe. m_readyread_lock.unlock(); // Actually read some data! This is a form of co-operative // multitasking so the ready read handlers should be quick.. uint downref_tm = 0; if (!m_readyread_downref_list.empty()) { VERBOSE(VB_SOCKET|VB_EXTRA, "Deleting stale sockets"); QTime tm = QTime::currentTime(); for (it = m_readyread_downref_list.begin(); it != m_readyread_downref_list.end(); ++it) { (*it)->DownRef(); } m_readyread_downref_list.clear(); downref_tm = tm.elapsed(); } VERBOSE(VB_SOCKET|VB_EXTRA, "Processing ready reads"); QMap<uint,uint> timers; QTime tm = QTime::currentTime(); it = m_readyread_list.begin(); for (; it != m_readyread_list.end() && m_readyread_run; ++it) { if (!(*it)->TryLock(false)) continue; int socket = (*it)->socket(); if (socket >= 0 && (*it)->state() == MythSocket::Connected && FD_ISSET(socket, &rfds)) { QTime rrtm = QTime::currentTime(); ReadyToBeRead(*it); timers[socket] = rrtm.elapsed(); } (*it)->Unlock(false); } if (VERBOSE_LEVEL_CHECK(VB_SOCKET|VB_EXTRA)) { QString rep = QString("Total read time: %1ms, on sockets") .arg(tm.elapsed()); QMap<uint,uint>::const_iterator it = timers.begin(); for (; it != timers.end(); ++it) rep += QString(" {%1,%2ms}").arg(it.key()).arg(*it); if (downref_tm) rep += QString(" {downref, %1ms}").arg(downref_tm); VERBOSE(VB_SOCKET|VB_EXTRA, QString("MythSocketThread: ") + rep); } m_readyread_lock.lock(); VERBOSE(VB_SOCKET|VB_EXTRA, "Reacquired ready read lock"); } VERBOSE(VB_SOCKET, "MythSocketThread: readyread thread exit"); }
void CSystemBundleActivator::SaveBundleRegistryState() { VERBOSE("[SysBndleActivator] %s", __FUNCTION__); }
/** \fn ThreadedFileWriter::Write(const void*, uint) * \brief Writes data to the end of the write buffer * * NOTE: This blocks while buffer is in use by the write to disk thread. * * \param data pointer to data to write to disk * \param count size of data in bytes */ uint ThreadedFileWriter::Write(const void *data, uint count) { if (count == 0) return 0; if (count > tfw_buf_size) { VERBOSE(VB_IMPORTANT, LOC + QString("WARNING: count(%1), tfw_buf_size(%2)") .arg(count).arg(tfw_buf_size)); } uint iobound_cnt = 0; uint remaining = count; char *wdata = (char *)data; while (remaining) { bool first = true; buflock.lock(); while (BufFreePriv() == 0) { if (first) { ++iobound_cnt; VERBOSE(VB_IMPORTANT, LOC_ERR + "Write() -- IOBOUND begin " + QString("remaining(%1) free(%2) size(%3) cnt(%4)") .arg(remaining).arg(BufFreePriv()) .arg(tfw_buf_size).arg(iobound_cnt)); first = false; } bufferWroteData.wait(&buflock, 1000); } uint twpos = wpos; uint bytes = (BufFreePriv() < remaining) ? BufFreePriv() : remaining; buflock.unlock(); if (!first) VERBOSE(VB_IMPORTANT, LOC_ERR + "Write() -- IOBOUND end"); if (no_writes) return 0; if ((twpos + bytes) > tfw_buf_size) { int first_chunk_size = tfw_buf_size - twpos; int second_chunk_size = bytes - first_chunk_size; memcpy(buf + twpos, wdata, first_chunk_size); memcpy(buf, wdata + first_chunk_size, second_chunk_size); } else { memcpy(buf + twpos, wdata, bytes); } buflock.lock(); if (twpos == wpos) { wpos = (wpos + bytes) % tfw_buf_size; } else { VERBOSE(VB_IMPORTANT, LOC_ERR + "Programmer Error detected! " "wpos was changed from under the Write() function."); } buflock.unlock(); bufferHasData.wakeAll(); remaining -= bytes; wdata += bytes; if (remaining) { buflock.lock(); if (0 == BufFreePriv()) bufferWroteData.wait(&buflock, 10000); buflock.unlock(); } } return count; }
QString GalleryUtil::GetCaption(const QString &filePath) { QString caption(""); try { #ifdef EXIF_SUPPORT char *exifvalue = new char[1024]; ExifData *data = exif_data_new_from_file( filePath.toLocal8Bit().constData()); if (data) { for (int i = 0; i < EXIF_IFD_COUNT; i++) { ExifEntry *entry = exif_content_get_entry (data->ifd[i], EXIF_TAG_USER_COMMENT); if (entry) { #if NEW_LIB_EXIF exif_entry_get_value(entry, exifvalue, 1023); caption = exifvalue; #else caption = exif_entry_get_value(entry); #endif // Found one, done if(!caption.trimmed().isEmpty()) break; } entry = exif_content_get_entry (data->ifd[i], EXIF_TAG_IMAGE_DESCRIPTION); if (entry) { #if NEW_LIB_EXIF exif_entry_get_value(entry, exifvalue, 1023); caption = exifvalue; #else caption = exif_entry_get_value(entry); #endif // Found one, done if(!caption.trimmed().isEmpty()) break; } } exif_data_free(data); } else { VERBOSE(VB_FILE, LOC_ERR + QString("Could not load exif data from '%1'") .arg(filePath)); } delete [] exifvalue; #endif // EXIF_SUPPORT } catch (...) { VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to extract EXIF headers from '%1'") .arg(filePath)); } return caption; }
/** \fn ThreadedFileWriter::DiskLoop(void) * \brief The thread run method that actually calls safe_write(). */ void ThreadedFileWriter::DiskLoop(void) { uint size = 0; written = 0; while (!in_dtor || BufUsed() > 0) { buflock.lock(); size = BufUsedPriv(); if (size == 0) { buflock.unlock(); bufferEmpty.wakeAll(); buflock.lock(); } if (!size || (!in_dtor && !flush && ((size < tfw_min_write_size) && (written >= tfw_min_write_size)))) { bufferHasData.wait(&buflock, 100); buflock.unlock(); continue; } uint trpos = rpos; buflock.unlock(); /* cap the max. write size. Prevents the situation where 90% of the buffer is valid, and we try to write all of it at once which takes a long time. During this time, the other thread fills up the 10% that was free... */ size = (size > TFW_MAX_WRITE_SIZE) ? TFW_MAX_WRITE_SIZE : size; bool write_ok; if (ignore_writes) ; else if ((trpos + size) > tfw_buf_size) { int first_chunk_size = tfw_buf_size - trpos; int second_chunk_size = size - first_chunk_size; size = safe_write(fd, buf + trpos, first_chunk_size, write_ok); if ((int)size == first_chunk_size && write_ok) size += safe_write(fd, buf, second_chunk_size, write_ok); } else { size = safe_write(fd, buf + trpos, size, write_ok); } if (!ignore_writes && !write_ok && ((EFBIG == errno) || (ENOSPC == errno))) { QString msg; switch (errno) { case EFBIG: msg = "Maximum file size exceeded by '%1'" "\n\t\t\t" "You must either change the process ulimits, configure" "\n\t\t\t" "your operating system with \"Large File\" support, or use" "\n\t\t\t" "a filesystem which supports 64-bit or 128-bit files." "\n\t\t\t" "HINT: FAT32 is a 32-bit filesystem."; break; case ENOSPC: msg = "No space left on the device for file '%1'" "\n\t\t\t" "file will be truncated, no further writing will be done."; break; } VERBOSE(VB_IMPORTANT, msg.arg(filename)); ignore_writes = true; } if (written <= tfw_min_write_size) { written += size; } buflock.lock(); if (trpos == rpos) { rpos = (rpos + size) % tfw_buf_size; } else { VERBOSE(VB_IMPORTANT, LOC_ERR + "Programmer Error detected! " "rpos was changed from under the DiskLoop() function."); } m_file_wpos += size; buflock.unlock(); bufferWroteData.wakeAll(); } }
void CPUCALL interrupt(int num, int intrtype, int errorp, int error_code) { descriptor_t gsd; UINT idt_idx; UINT32 new_ip; UINT16 new_cs; int exc_errcode; VERBOSE(("interrupt: num = 0x%02x, intrtype = %s, errorp = %s, error_code = %08x", num, (intrtype == INTR_TYPE_EXTINTR) ? "external" : (intrtype == INTR_TYPE_EXCEPTION ? "exception" : "softint"), errorp ? "on" : "off", error_code)); if(num == 0x21 && md_int21()) { return; } CPU_SET_PREV_ESP(); if (!CPU_STAT_PM) { /* real mode */ CPU_WORKCLOCK(20); idt_idx = num * 4; if (idt_idx + 3 > CPU_IDTR_LIMIT) { VERBOSE(("interrupt: real-mode IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT)); EXCEPTION(GP_EXCEPTION, idt_idx + 2); } if ((intrtype == INTR_TYPE_EXTINTR) && CPU_STAT_HLT) { VERBOSE(("interrupt: reset HTL in real mode")); CPU_EIP++; CPU_STAT_HLT = 0; } REGPUSH0(REAL_FLAGREG); REGPUSH0(CPU_CS); REGPUSH0(CPU_IP); CPU_EFLAG &= ~(T_FLAG | I_FLAG | AC_FLAG | RF_FLAG); CPU_TRAP = 0; new_ip = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx); new_cs = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx + 2); LOAD_SEGREG(CPU_CS_INDEX, new_cs); CPU_EIP = new_ip; } else { /* protected mode */ CPU_WORKCLOCK(200); VERBOSE(("interrupt: -------------------------------------------------------------- start")); VERBOSE(("interrupt: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP)); #if defined(DEBUG) if (num == 0x80) { /* Linux, FreeBSD, NetBSD, OpenBSD system call */ VERBOSE(("interrupt: syscall# = %d\n%s", CPU_EAX, cpu_reg2str())); } #endif idt_idx = num * 8; exc_errcode = idt_idx + 2; if (intrtype == INTR_TYPE_EXTINTR) exc_errcode++; if (idt_idx + 7 > CPU_IDTR_LIMIT) { VERBOSE(("interrupt: IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT)); EXCEPTION(GP_EXCEPTION, exc_errcode); } /* load a gate descriptor from interrupt descriptor table */ memset(&gsd, 0, sizeof(gsd)); load_descriptor(&gsd, CPU_IDTR_BASE + idt_idx); if (!SEG_IS_VALID(&gsd)) { VERBOSE(("interrupt: gate descripter is invalid.")); EXCEPTION(GP_EXCEPTION, exc_errcode); } if (!SEG_IS_SYSTEM(&gsd)) { VERBOSE(("interrupt: gate descriptor is not system segment.")); EXCEPTION(GP_EXCEPTION, exc_errcode); } switch (gsd.type) { case CPU_SYSDESC_TYPE_TASK: case CPU_SYSDESC_TYPE_INTR_16: case CPU_SYSDESC_TYPE_INTR_32: case CPU_SYSDESC_TYPE_TRAP_16: case CPU_SYSDESC_TYPE_TRAP_32: break; default: VERBOSE(("interrupt: invalid gate type (%d)", gsd.type)); EXCEPTION(GP_EXCEPTION, exc_errcode); break; } /* 5.10.1.1. 例外/割り込みハンドラ・プロシージャの保護 */ if ((intrtype == INTR_TYPE_SOFTINTR) && (gsd.dpl < CPU_STAT_CPL)) { VERBOSE(("interrupt: intrtype(softint) && DPL(%d) < CPL(%d)", gsd.dpl, CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, exc_errcode); } if (!SEG_IS_PRESENT(&gsd)) { VERBOSE(("interrupt: gate descriptor is not present.")); EXCEPTION(NP_EXCEPTION, exc_errcode); } if ((intrtype == INTR_TYPE_EXTINTR) && CPU_STAT_HLT) { VERBOSE(("interrupt: reset HTL in protected mode")); CPU_EIP++; CPU_STAT_HLT = 0; } switch (gsd.type) { case CPU_SYSDESC_TYPE_TASK: interrupt_task_gate(&gsd, intrtype, errorp, error_code); break; case CPU_SYSDESC_TYPE_INTR_16: case CPU_SYSDESC_TYPE_INTR_32: case CPU_SYSDESC_TYPE_TRAP_16: case CPU_SYSDESC_TYPE_TRAP_32: interrupt_intr_or_trap(&gsd, intrtype, errorp, error_code); break; default: EXCEPTION(GP_EXCEPTION, exc_errcode); break; } VERBOSE(("interrupt: ---------------------------------------------------------------- end")); } CPU_CLEAR_PREV_ESP(); }
/* * In one pass, read all the directory entries of the specified * directory and call the callback function for non-directory * entries. * * On return: * 0: Lets the directory to be scanned for directory entries. * < 0: Completely stops traversing. * FST_SKIP: stops further scanning of the directory. Traversing * will continue with the next directory in the hierarchy. * SKIP_ENTRY: Failed to get the directory entries, so the caller * should skip this entry. */ static int traverse_level_nondir(struct fs_traverse *ftp, traverse_state_t *tsp, struct fst_node *pnp, dent_arg_t *darg) { int pl; /* path length */ int rv; struct fst_node en; /* entry node */ longlong_t cookie_verf; fs_dent_info_t *dent; struct dirent *buf; size_t len = 0; int fd; rv = 0; pl = strlen(pnp->tn_path); buf = ndmp_malloc(MAX_DENT_BUF_SIZE); if (buf == NULL) return (errno); fd = open(tsp->ts_fh.fh_fpath, O_RDONLY); if (fd == -1) { free(buf); return (errno); } while (rv == 0) { long i, n_entries; darg->da_end = 0; n_entries = 0; rv = fs_getdents(fd, buf, &len, pnp->tn_path, &tsp->ts_dpos, &cookie_verf, &n_entries, darg); if (rv < 0) { traverse_stats.fss_readdir_err++; NDMP_LOG(LOG_DEBUG, "Error %d on readdir(%s) pos %d", rv, pnp->tn_path, tsp->ts_dpos); if (STOP_ONERR(ftp)) break; /* * We cannot read the directory entry, we should * skip to the next directory. */ rv = SKIP_ENTRY; continue; } else { /* Break at the end of directory */ if (rv > 0) rv = 0; else break; } /* LINTED imporper alignment */ dent = (fs_dent_info_t *)darg->da_buf; /* LINTED imporper alignment */ for (i = 0; i < n_entries; i++, dent = (fs_dent_info_t *) ((char *)dent + dent->fd_len)) { if (VERBOSE(ftp)) NDMP_LOG(LOG_DEBUG, "i %u dname: \"%s\"", dent->fd_fh.fh_fid, dent->fd_name); if ((pl + strlen(dent->fd_name)) > PATH_MAX) { traverse_stats.fss_longpath_err++; NDMP_LOG(LOG_ERR, "Path %s/%s is too long.", pnp->tn_path, dent->fd_name); if (STOP_ONLONG(ftp)) rv = -ENAMETOOLONG; free(dent->fd_fh.fh_fpath); continue; } /* * The entry is not a directory so the callback * function must be called. */ if (!S_ISDIR(dent->fd_attr.st_mode)) { traverse_stats.fss_nondir_calls++; en.tn_path = dent->fd_name; en.tn_fh = &dent->fd_fh; en.tn_st = &dent->fd_attr; rv = CALLBACK(pnp, &en); dent->fd_fh.fh_fpath = NULL; if (rv < 0) break; if (rv == FST_SKIP) { traverse_stats.fss_nondir_skipped++; break; } } } } free(buf); (void) close(fd); return (rv); }