コード例 #1
0
ファイル: eulerint.c プロジェクト: yfyang86/yytex
void lineto(FILE *output, double xs, double ys, double xf, double yf) {
	int ixs, iys, ixf, iyf;
	ixs = xmap(xs, ys); iys = ymap(xs, ys);
	ixf = xmap(xf, yf); iyf = ymap(xf, yf);	
	if (ixs == ixf && iys == iyf) {
		saywhere(stdout);
		printf("Worthless lineto (%lg %lg %lg %lg)\n", xs, ys, xf, yf);	
	}
	else fprintf(output, "%d %d l\n", ixf, iyf);
}
コード例 #2
0
        void TranslationWarperBase<P>::warpBackward(InputArray src, InputArray K, InputArray R, InputArray t,
                                                    int interp_mode, int border_mode,
                                                    Size dst_size, OutputArray dst) {
            projector_.setCameraParams(K, R, t);

            Point src_tl, src_br;
            detectResultRoi(dst_size, src_tl, src_br);

            Size size = src.size();
            CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height);

            Mat xmap(dst_size, CV_32F);
            Mat ymap(dst_size, CV_32F);

            float u, v;
            for (int y = 0; y < dst_size.height; ++y) {
                for (int x = 0; x < dst_size.width; ++x) {
                    projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
                    xmap.at<float>(y, x) = u - src_tl.x;
                    ymap.at<float>(y, x) = v - src_tl.y;
                }
            }

            dst.create(dst_size, src.type());
            remap(src, dst, xmap, ymap, interp_mode, border_mode);
        }
コード例 #3
0
ファイル: perf_imgproc.cpp プロジェクト: vpas/opencv
GPU_PERF_TEST(Remap, cv::gpu::DeviceInfo, cv::Size, MatType, Interpolation, BorderMode)
{
    cv::gpu::DeviceInfo devInfo = GET_PARAM(0);
    cv::gpu::setDevice(devInfo.deviceID());

    cv::Size size = GET_PARAM(1);
    int type = GET_PARAM(2);
    int interpolation = GET_PARAM(3);
    int borderMode = GET_PARAM(4);

    cv::Mat src_host(size, type);
    fill(src_host, 0, 255);

    cv::Mat xmap_host(size, CV_32FC1);
    fill(xmap_host, 0, size.width);

    cv::Mat ymap_host(size, CV_32FC1);
    fill(ymap_host, 0, size.height);

    cv::gpu::GpuMat src(src_host);
    cv::gpu::GpuMat xmap(xmap_host);
    cv::gpu::GpuMat ymap(ymap_host);
    cv::gpu::GpuMat dst;

    cv::gpu::remap(src, dst, xmap, ymap, interpolation, borderMode);

    declare.time(3.0);

    TEST_CYCLE()
    {
        cv::gpu::remap(src, dst, xmap, ymap, interpolation, borderMode);
    }
}
コード例 #4
0
ファイル: eulerint.c プロジェクト: yfyang86/yytex
void curveto(FILE *output, double xs, double ys, double xa, double ya, 
		double xb, double yb, double xf, double yf) {
	int ixs, iys, ixa, iya, ixb, iyb, ixf, iyf;
	ixs = xmap(xs, ys); iys = ymap(xs, ys);
	ixa = xmap(xa, ya); iya = ymap(xa, ya);
	ixb = xmap(xb, yb); iyb = ymap(xb, yb);	
	ixf = xmap(xf, yf); iyf = ymap(xf, yf);	

	if (ixs == ixf && iys == iyf) {
		saywhere(stdout);
		printf("Worthless curveto (%lg %lg %lg %lg %lg %lg %lg %lg)\n", 
			xs, ys, xa, ya, xb, yb, xf, yf);	
	}
	else fprintf(output, "%d %d %d %d %d %d c\n", 
		 ixa, iya, ixb, iyb, ixf, iyf);
}
コード例 #5
0
ファイル: XpetraEpetraMap.cpp プロジェクト: agrippa/Trilinos
int main(int narg, char **arg)
{
  Teuchos::GlobalMPISession session(&narg, &arg);
  Teuchos::RCP<const Teuchos::Comm<int> > tcomm = 
               Teuchos::DefaultComm<int>::getComm();
  Teuchos::RCP<const Epetra_Comm> ecomm = Xpetra::toEpetra(tcomm);

  const int nGlobRows = 50;
  const Epetra_Map emap(nGlobRows, 0, *ecomm);
  Teuchos::RCP<const Epetra_BlockMap> ebmap = Teuchos::rcpFromRef(emap);

  typedef Xpetra::EpetraMapT<int, Tpetra::Map<>::node_type> xemap_t;
  Teuchos::RCP<const xemap_t> xmap(new xemap_t(ebmap));
  
  const Teuchos::RCP<const Teuchos::Comm<int> > &xcomm = xmap->getComm();

  std::cout << "Teuchos:  Hello from " 
            << tcomm->getRank() << " of " 
            << tcomm->getSize() << std::endl;
  std::cout << "Epetra:   Hello from " 
            << ecomm->MyPID() << " of " 
            << ecomm->NumProc() << std::endl;
  std::cout << "Xpetra:   Hello from " 
            << xcomm->getRank() << " of " 
            << xcomm->getSize() << std::endl;
}
コード例 #6
0
ファイル: warpers_inl.hpp プロジェクト: Abai/OpenCVForiPhone
void RotationWarperBase<P>::warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
                                         Size dst_size, Mat &dst)
{
    projector_.setCameraParams(K, R);

    Point src_tl, src_br;
    detectResultRoi(dst_size, src_tl, src_br);
    CV_Assert(src_br.x - src_tl.x + 1 == src.cols && src_br.y - src_tl.y + 1 == src.rows);

    Mat xmap(dst_size, CV_32F);
    Mat ymap(dst_size, CV_32F);

    float u, v;
    for (int y = 0; y < dst_size.height; ++y)
    {
        for (int x = 0; x < dst_size.width; ++x)
        {
            projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
            xmap.at<float>(y, x) = u - src_tl.x;
            ymap.at<float>(y, x) = v - src_tl.y;
        }
    }

    dst.create(dst_size, src.type());
    remap(src, dst, xmap, ymap, interp_mode, border_mode);
}
コード例 #7
0
std::string AppMapServer::postMap(XMapMessage mapmsg)
{
    if (mapmsg.msg_type != XMAPMSG_POSTMAP)
        return "message type error!";
    try{
        XMap xmap(mapmsg.loc);
        xmap.setData(mapmsg.data, mapmsg.bias.x, mapmsg.bias.y, mapmsg.length).save();
        return "succeed";
    }
    catch(const mongo::DBException e){
        std::cout << "caught " << e.what() << std::endl;
        return "fail";
    }
}
コード例 #8
0
void
ScanSpoolFile(char *fpath, int gmt, int iter, uint16 spoolobj)
{
    int fd;
    char *base;
    int bytes;
    struct stat st;

    if (VerboseOpt)
	printf("  Scanning file: %s\n", fpath);

    errno = 0;
    if ((fd = open(fpath, O_RDONLY)) < 0) {
	printf("    %s\t%s\n", fpath, strerror(errno));
	return;
    }
    if (fstat(fd, &st) < 0) {
	printf("    %s\t%s\n", fpath, strerror(errno));
	close(fd);
	return;
    }
    bytes = st.st_size;

    base = xmap(NULL, bytes, PROT_READ, MAP_SHARED, fd, 0);
    if (base == NULL) {
	printf("    %s\t%s\n", fpath, strerror(errno));
	close(fd);
	return;
    }

    if (!QuietOpt)
	printf("    %s: ", fpath);

    if (bytes > 2 && (uint8)*base == (uint8)STORE_MAGIC1 &&
				(uint8)*(base + 1) == (uint8)STORE_MAGIC2)
	ScanSpoolFileMap(base, bytes, gmt, iter, fpath, spoolobj, fd);
    else
	ScanSpoolFileMapOld(base, bytes, gmt, iter, fpath, spoolobj);

    if (!QuietOpt)
	printf("\n");
    xunmap(base, bytes);
    close(fd);
}
コード例 #9
0
ファイル: testfastarecode.cpp プロジェクト: allenday/libmaus
int main(int argc, char * argv[])
{
	try
	{
		::libmaus::util::ArgInfo arginfo(argc,argv);
		::libmaus::util::TempFileRemovalContainer::setup();
		::std::vector<std::string> const & inputfilenames = arginfo.restargs;
		char const * fasuffixes[] = { ".fa", ".fasta", 0 };
		
		std::string deftmpname = libmaus::util::OutputFileNameTools::endClipLcp(inputfilenames,&fasuffixes[0]) + ".fa.tmp";
		while ( ::libmaus::util::GetFileSize::fileExists(deftmpname) )
			deftmpname += "_";
		std::string defoutname = libmaus::util::OutputFileNameTools::endClipLcp(inputfilenames,&fasuffixes[0]) + ".fa.recoded";
		while ( ::libmaus::util::GetFileSize::fileExists(defoutname) )
			defoutname += "_";

		std::string const tempfilename = arginfo.getValue<std::string>("tempfilename",deftmpname);
		std::string const outfilename = arginfo.getValue<std::string>("outputfilename",defoutname);
		std::string const indexfilename = tempfilename + ".index";
		unsigned int const addterm = arginfo.getValue<unsigned int>("addterm",0);
		unsigned int const termadd = addterm ? 1 : 0;

		::libmaus::util::TempFileRemovalContainer::addTempFile(tempfilename);
		::libmaus::util::TempFileRemovalContainer::addTempFile(indexfilename);
		
		std::cerr << "temp file name " << tempfilename << std::endl;
		std::cerr << "output file name " << outfilename << std::endl;
		
		/* uint64_t const numseq = */ ::libmaus::fastx::FastAReader::rewriteFiles(inputfilenames,tempfilename,indexfilename);
		uint64_t curpos = 0;
		::libmaus::aio::CheckedOutputStream COS(outfilename);
		
		// 0,A,C,G,T,N
		// map forward
		::libmaus::autoarray::AutoArray<char> cmap(256,false);
		std::fill(cmap.begin(),cmap.end(),5+termadd);
		cmap['\n'] = 0 + termadd;
		cmap['a'] = cmap['A'] = 1 + termadd;
		cmap['c'] = cmap['C'] = 2 + termadd;
		cmap['g'] = cmap['G'] = 3 + termadd;
		cmap['t'] = cmap['T'] = 4 + termadd;
		cmap['n'] = cmap['N'] = 5 + termadd;

		// map to reverse complement
		::libmaus::autoarray::AutoArray<char> rmap(256,false);
		std::fill(rmap.begin(),rmap.end(),5+termadd);
		rmap['\n'] = 0 + termadd;
		rmap['a'] = rmap['A'] = 4 + termadd;
		rmap['c'] = rmap['C'] = 3 + termadd;
		rmap['g'] = rmap['G'] = 2 + termadd;
		rmap['t'] = rmap['T'] = 1 + termadd;
		rmap['n'] = rmap['N'] = 5 + termadd;

		// reverse complement for mapped data
		::libmaus::autoarray::AutoArray<char> xmap(256,false);
		std::fill(xmap.begin(),xmap.end(),5+termadd);
		xmap[0] = 0 + termadd;
		xmap[1] = 4 + termadd;
		xmap[2] = 3 + termadd;
		xmap[3] = 2 + termadd;
		xmap[4] = 1 + termadd;
		xmap[5] = 5 + termadd;

		::libmaus::autoarray::AutoArray<char> imap(256,false);
		for ( uint64_t i = 0; i < imap.size(); ++i )
			imap[i] = static_cast<char>(i);
		
		::libmaus::fastx::FastAReader::RewriteInfoDecoder::unique_ptr_type infodec(new ::libmaus::fastx::FastAReader::RewriteInfoDecoder(indexfilename));
		::libmaus::fastx::FastAReader::RewriteInfo info;
		uint64_t maxseqlen = 0;
		while ( infodec->get(info) )
			maxseqlen = std::max(maxseqlen,info.seqlen);
			
		std::cerr << "[V] max seq len " << maxseqlen << std::endl;

		::libmaus::fastx::FastAReader::RewriteInfoDecoder::unique_ptr_type tinfodec(new ::libmaus::fastx::FastAReader::RewriteInfoDecoder(indexfilename));
		infodec = UNIQUE_PTR_MOVE(tinfodec);
		
		if ( maxseqlen <= 256*1024 )
		{
			::libmaus::aio::CheckedInputStream CIS(tempfilename);
			::libmaus::autoarray::AutoArray<uint8_t> B(maxseqlen+1,false);

			while ( infodec->get(info) )
			{
				// skip id
				CIS.ignore(info.idlen+2);
				// read sequence plus following terminator
				CIS.read(reinterpret_cast<char *>(B.begin()), info.seqlen+1);
				// map
				for ( uint64_t i = 0; i < info.seqlen+1; ++i )
					B[i] = cmap[B[i]];
				// write
				COS.write(reinterpret_cast<char const *>(B.begin()),info.seqlen+1);
				// remap
				for ( uint64_t i = 0; i < info.seqlen+1; ++i )
					B[i] = xmap[B[i]];
				// reverse
				std::reverse(B.begin(),B.begin()+info.seqlen);
				// write
				COS.write(reinterpret_cast<char const *>(B.begin()),info.seqlen+1);
			}
		}
		else
		{
			while ( infodec->get(info) )
			{
				// std::cerr << info.valid << "\t" << info.idlen << "\t" << info.seqlen << "\t" << info.getIdPrefix() << std::endl;
				uint64_t const seqbeg = curpos + (info.idlen+2);
				uint64_t const seqend = seqbeg + info.seqlen;
				
				::libmaus::aio::CheckedInputStream CIS(tempfilename); CIS.seekg(seqbeg);
				::libmaus::util::GetFileSize::copyMap(CIS,COS,cmap.begin(),seqend-seqbeg+1);
				
				::libmaus::aio::CircularReverseWrapper CRW(tempfilename,seqend);
				::libmaus::util::GetFileSize::copyMap(CRW,COS,rmap.begin(),seqend-seqbeg+1);
				
				curpos += (info.idlen+2) + (info.seqlen+1);
			}		
		}
		
		if ( addterm )
			COS.put(0);

		return EXIT_SUCCESS;
	}
	catch(std::exception const & ex)
	{
		std::cerr << ex.what() << std::endl;
		return EXIT_FAILURE;
	}
}
コード例 #10
0
ファイル: dreadart.c プロジェクト: jpmens/diablo
int
MapArticle(int fd, char *fname, char **base, History *h, int *extra, int *artSize, int *compressedFormat)
{
    if (SpoolCompressed(H_SPOOL(h->exp))) {
#ifdef USE_ZLIB
	gzFile gzf;
	SpoolArtHdr tah = { 0 };
	char *p;

	lseek(fd, h->boffset, 0);
	if (read(fd, &tah, sizeof(SpoolArtHdr)) != sizeof(SpoolArtHdr)) {
	    close(fd);
	    fprintf(LogFo, "Unable to read article header (%s)\n",
							strerror(errno));
	    return(-1);
	}
	if ((uint8)tah.Magic1 != STORE_MAGIC1 &&
					(uint8)tah.Magic2 != STORE_MAGIC2) {
	    lseek(fd, h->boffset, 0);
	    tah.Magic1 = STORE_MAGIC1;
	    tah.Magic2 = STORE_MAGIC2;
	    tah.HeadLen = sizeof(tah);
	    tah.ArtLen = h->bsize;
	    tah.ArtHdrLen = h->bsize;
	    tah.StoreLen = h->bsize;
	}
	gzf = gzdopen(fd, "r");
	if (gzf == NULL) {
	    fprintf(LogFo, "Error opening compressed article\n");
	    return(-1);
	}
	*base = (char *)malloc(tah.ArtLen + tah.HeadLen + 2);
	if (*base == NULL) {
	    fprintf(LogFo, "Unable to malloc %d bytes for article (%s)\n",
				tah.ArtLen + tah.HeadLen + 2, strerror(errno));
	    gzclose(gzf);
	    return(-1);
	}
	p = *base;
	*p++ = 0;
	bcopy(&tah, p, tah.HeadLen);
	p += tah.HeadLen;
	if (gzread(gzf, p, tah.ArtLen) != tah.ArtLen) {
	    fprintf(LogFo, "Error uncompressing article\n");
	    free(*base);
	    return(-1);
	}
	p[tah.ArtLen] = 0;
	*extra = 1;
	*artSize = tah.ArtLen;
	*artSize += tah.HeadLen;
	*compressedFormat = 1;
	gzclose(gzf);
#else
        fprintf(LogFo, "Article is on a compressed spool and compression support has not been enabled\n");
#endif
    } else {
	    *base = xmap(
		NULL, 
		h->bsize + *extra + 1, 
		PROT_READ,
		MAP_SHARED, 
		fd, 
		h->boffset - *extra
	    );
	    *artSize = h->bsize;
    }

    if (*base == NULL) {
	fprintf(LogFo, "Unable to map file %s: %s (%lld,%d,%d)\n",
				fname,
				strerror(errno),
				(long long)(h->boffset - *extra),
				 (int)(h->bsize + *extra + 1),
				*extra
	);
	return(-1);
    }
    return(0);
}
コード例 #11
0
ファイル: eulerint.c プロジェクト: yfyang86/yytex
int parseeuler(FILE *output, FILE *input) {
	double xstart, ystart;
	int n, nn, lineflag=0, lineflagn;
	double xs, ys, us, vs, xf, yf, uf, vf;
	double xsn, ysn, usn, vsn, ufn, vfn;
	double w;
	int width, widthbogus, wa, wb, m;
	int slannum=0, slanden=1;
	char *s;

/*	xf, yf, nn may be used before being initialized ? */
/*	lineflagn  may be used before being initialized ? */

	for(;;) {			/* scan over preamble - up to `charbegin' */
		if (fgets(buffer, MAXLINE, input) == NULL) {
			fprintf(errout, "EOF\n"); return -1;
		}
		line++;		
		if (*buffer == '%' || *buffer == '\n') continue;
		if (strstr(buffer, "adj_fill") != NULL) break;	/* continue char */
/*		if (strstr(buffer, "((") != NULL) break;	*//* continue char */
		if (strncmp(buffer, "endinput", 8) == 0) return -1; /* EOF */
		if (strncmp(buffer, "more_side", 9) == 0) {
			if(sscanf(buffer, "more_side(%lg", &moreside) < 1) {
				dontunder();
			}
			else if (traceflag != 0) printf("%s (%lg)", buffer, moreside);
		}
		if (strncmp(buffer, "initrot", 7) == 0) {
			if (sscanf(buffer, "initrot:=identity shifted(0,%lgv)", 
				&initshift) < 1) {
				if (strncmp(buffer, "initrot:=identity;",  18) == 0)
					initshift=0;
				else dontunder();
			}
			if (traceflag != 0) printf("%s (%lg)", buffer, initshift);
		}
		if (strncmp(buffer, "charbegin", 9) == 0) {
			if (traceflag != 0) printf("%s", buffer);
			s = buffer;
			if (strchr(s, '"') != NULL) {			/* quoted char name */
				if (sscanf(s, "charbegin( \"%c\",%n", charname, &m) > 0) {
					s += m;
					charname[1] = '\0';
					chrs = (int) charname[0];
					if (charname[0] >= '0' && charname[0] <= '9')
						replacedigit(charname);
				}
				else dontunder();
			}
			else {									/* character number */
				if (sscanf(s, "charbegin( %d,%n", &chrs, &m) > 0) {
					s += m;
					charname[0] = '\0';
				}
				else dontunder();
			}
			widthbogus = 0;
			if (sscanf(s, "%dh", &width) > 0) {			/* normal case */
				if (strchr(s, '+') != NULL ||
					strchr(s, '-') != NULL) {
					widthbogus = 1;
					if (traceflag != 0) printf("Width (%d) Bogus\n", width);
				}
			}
			else if (sscanf(s, " (%d+%d)*", &wa, &wb) == 2) {
				width = wa + wb;
			}
			else if (sscanf(s, " (%d-%d)*", &wa, &wb) == 2) {
				width = wa - wb;
			}			
			else dontunder();
			width = widths[chrs];				/* NEW */
			sidebearing = offsets[chrs];		/* NEW */
			mathcorrection = mathcorr[chrs];	/* NEW */
			w =  (double) width + moreside * 2.0 - mathcorrection;
			w = w + leftside + rightside;
			if (charname[0] != '\0')
				fprintf(output, "]\n%d %d %% %s\n", chrs, wmap(w), charname);
			else fprintf(output, "]\n%d %d\n", chrs, wmap(w)); 
	
/*	deal with more complex width formats above ? OK */	
	
			if (traceflag != 0) 
				printf("Read charbegin for char %d width %d\n", chrs, width);

			rotate = 0.0; cosrot = 1.0; sinrot = 0.0;
			xshift = 0.0; yshift = 0.0; slant = 0.0;

			break;
		}
	}

	for(;;) {				/* scan over preamble - up to first moveto */
		if (fgets(buffer, MAXLINE, input) == NULL) {
			fprintf(errout, "Unexpected EOF (%s)\n", "A"); return -1;
		}
		line++;		
		if (*buffer == '%' || *buffer == '\n') continue;
		if ((s = strstr(buffer, "rot :=")) != NULL) {
			if (traceflag != 0) printf("chrs %d %s", chrs, buffer);
			if (strstr(s, "rotatedaround") != NULL) {
				if (sscanf(s, "rot := identity rotatedaround((%lgh,%lgv),%lg)",
					&xcenter, &ycenter, &rotate) < 3) dontunder();
				rotate = rotate * pi / 180.0;
				cosrot = cos(rotate); sinrot = sin(rotate);
				xshift = xcenter -xcenter * cos(rotate) + ycenter * sin(rotate);
				yshift = ycenter - xcenter * sin(rotate) - ycenter * cos(rotate);
			}
			else if(sscanf(s, "rot := identity rotated %lg%n", &rotate, &n) 
					== 1) {
				s += n;
				rotate = rotate * pi / 180.0;
				cosrot = cos(rotate); sinrot = sin(rotate);
				xshift = 0.0; yshift = 0.0;	/* ??? */
				if(sscanf(s, " shifted (%lgh,%lgv)", &xshift, &yshift) < 2) {
					if(sscanf(s, " shifted (0,%lgv)", &yshift) < 1) {
						if(sscanf(s, " shifted (%lgh,0)", &xshift) < 1)	
							dontunder();
					}
				}
			}
			else if(sscanf(s, "rot := rot shifted (%lgh,%lgv)", 
				&xshift, &yshift) == 2) {  /* debugging only */
				printf("dx %lg dy %lg char %d\n", xshift, yshift, chrs);
			}
			else if (sscanf(s, "rot := identity slanted %d/%d", 
				&slannum, &slanden) == 2) {
				slant = (double) slannum / slanden;
				printf("Switching to slant %lg\n", slant);	/* debug */
			}
			else  dontunder();
		}
		if ((s = strstr(buffer, "slant")) != NULL) { /* new */
			if (sscanf(s, "slant %d/%d", &slannum, &slanden) > 0) {
				if (slannum == 0) slanden = 1;
				slant = (double) slannum / slanden; 
				printf("Switching to slant %lg\n", slant);	/* debug */
			}
			else if (strstr(buffer, "slanted") == NULL) dontunder();
		}
		if (strstr(buffer, "...") != NULL) {
			lineflag = 0; break;
		}
		else if (strstr(buffer, "--") != NULL) {
			lineflag = 1; break;
		}
/*		if (strstr(buffer, "((") != NULL) break; */
	}
	
	if (traceflag != 0) printf("%s", buffer);
	
	if (lineflag == 0) {
		n = sscanf(buffer, " ((%lg,%lg){%lg,%lg}...{%lg,%lg}",
			&xs, &ys, &us, &vs, &uf, &vf);
		if (n < 4) 	{ 
			dontunder();
			(void) scantoend(input);
			return 0;
		}
		if (allowslant != 0 && slant != 0.0) {
			xs = xs + ys * slant;
			us = us + vs * slant;
			uf = uf + vf * slant;
		}
/*		if (traceflag != 0) printf("Read ... form\n"); */
	}
	else {
		n = sscanf(buffer, " ((%lg,%lg)--",	&xs, &ys);
		if (n < 2) 	{
			dontunder();
			(void) scantoend(input);
			return 0;
		}
		if (allowslant != 0 && slant != 0.0) {
			xs = xs + ys * slant;
		}
/*		if (traceflag != 0) printf("Read -- form\n"); */
	}

	xstart = xs; ystart = ys;   /* remember for closing at end */
	fprintf(output, "%d %d m\n", xmap(xs, ys), ymap(xs, ys));  /* moveto  */
/*	if (traceflag != 0) 
		printf("Starting point (%lg %lg)\n", xstart, ystart); */

/*	read charpath - continue until hit line containing "cycle" */

	for(;;) {
		if (fgets(buffer, MAXLINE, input) == NULL) {
			fprintf(errout, "Unexpected EOF (%s)\n", "B"); return -1;
		}
		line++;
		if (*buffer == '%' || *buffer == '\n') continue;
		if ((s = strstr(buffer, "slant")) != NULL) { /* new */
			if (sscanf(s, "slant %d/%d", &slannum, &slanden) > 0) {
				if (slannum == 0) slanden = 1;
				slant = (double) slannum / slanden; 
				printf("Switching to slant %lg\n", slant);	/* debug */
			}
			else dontunder();	
			continue;
		}
		if (strstr(buffer, "((") != NULL) {
			dontunder();	
			(void) scantoend(input);
			break;
		}
		else if (strchr(buffer, '+') != NULL) {
			dontunder();			
			(void) scantoend(input);
			break;
		}
		else if (strstr(buffer, "...") != NULL) {
			lineflagn = 0;
			nn = sscanf(buffer, " (%lg,%lg){%lg,%lg}...{%lg,%lg}",
				&xsn, &ysn, &usn, &vsn, &ufn, &vfn);
			if (nn < 4)	{
				dontunder();
				continue;		/* IGNORE THIS POINT IF POSSIBLE */
			}
			if (allowslant != 0 && slant != 0.0) {
				xsn = xsn + ysn * slant;
				usn = usn + vsn * slant;
				ufn= ufn + vfn * slant;
			}
			if (n < 6) {   /* copy finish tangent direction previous */
				uf = usn; vf = vsn;
			}
		}
		else if (strstr(buffer, "--") != NULL) {
			lineflagn = 1;
			nn = sscanf(buffer, " (%lg,%lg)--",	&xsn, &ysn);
			if (nn < 2)	{
				dontunder();
				continue;		/* IGNORE THIS POINT IF POSSIBLE */
			}
			if (allowslant != 0 && slant != 0.0) {
				xsn = xsn + ysn * slant;
			}
			if (n < 6) {   /* copy finish tangent direction previous */
				if (lineflag == 0) {	/* OK if previous was "--" also */
					  saywhere(stdout);
					  printf("Incomplete curveto before lineto\n");
					  uf = us; vf = vs;    /* is this OK ??? */
				}
			}
		}
		xf = xsn; yf = ysn;		/* finish of previous is start of new */

		if (lineflag == 0) 
			(void) smoothknots(output, xs, ys, us, vs, xf, yf, uf, vf);
		else if (xf != xs || yf != ys) 
/*			fprintf(output, "%d %d l\n", xmap(xf, yf), ymap(xf, yf)); */
			lineto(output, xs, ys, xf, yf);
		else {	
			saywhere(stdout);
			printf("Coincident ends (%lg %lg)\n", xf, yf);
		}

/*		get ready for next */
		xs = xsn; ys = ysn; us = usn; vs = vsn; uf = ufn, vf = vfn; 
		lineflag = lineflagn; n = nn;
		
		if (strstr(buffer, "cycle") != NULL) {
/*			if (lineflag == 0) 
				(void) smoothknots(output, xs, ys, us, vs, xf, yf, uf, vf);
			else fprintf(output, "%d %d l\n", xmap(xf, yf), ymap(xf, yf)); */
			break;
		}
	}

/* this may be the end of the character, or there may be other paths */

	if (traceflag != 0) printf("%s", buffer);

/*	close the loop now */
	if (xstart != xf || ystart != yf) /* don't output worthless lineto */
/*		fprintf(output, "%d %d l\n", 
			xmap(xstart, ystart), ymap(xstart, ystart)); */
		lineto(output, xs, ys, xstart, ystart);
	else if (traceflag != 0) printf("Path already closed\n");
	fprintf(output, "h\n");
	return 0;
}
コード例 #12
0
ファイル: dlockhistory.c プロジェクト: jpmens/diablo
int
main(int argc, char **argv) {
    extern char *optarg;
    extern int optind;
    char *progname = *argv;
    char *HistoryFile;
    int SleepTime = 5;
    int Opened = 0;
    char ch;
    struct stat st;
    int PrevIno = -1;
    int Force = 0;
    char *map = NULL;
    off_t mapsize = 0;
    int All = 0;

    optind = 1;
    while ((ch = getopt(argc, argv, "afsV")) != -1) {
        switch(ch) {
        case 'a':
            All = 1;
            break;
        case 'f':
            Force = 1;
            break;
        case 's':
            SleepTime = strtol(optarg, NULL, 0);
            break;
        case 'V':
            PrintVersion();
            break;
        default:
            usage(argv[0]);
        }
    }

    argv += optind;
    if (*argv == NULL)
        usage(progname);
    HistoryFile = *argv;

    if (!Force && geteuid() != 0) {
        printf("This daemon must be run as root due to the use of mlock()\n");
        printf("which is only allowed to be executed by the root user\n");
        exit(1);
    }

    while (1) {
        if (!Opened) {
            if (stat(HistoryFile, &st) == 0)
                PrevIno = st.st_ino;
            if (All) {
                int fd;
                mapsize = st.st_size;
                fd = open(HistoryFile, O_RDONLY);
                if (fd == -1) {
                    perror("history open");
                    exit(1);
                }
                map = xmap(NULL, mapsize, PROT_READ, MAP_SHARED, fd, 0);
                close(fd);
                mlock(map, mapsize);
            } else {
                HistoryOpen(HistoryFile, HGF_MLOCK);
            }
            Opened = 1;
        }
        sleep(SleepTime);
        if (stat(HistoryFile, &st) != 0 || st.st_ino != PrevIno ||
                (All && st.st_size != mapsize)) {
            if (All && map != NULL) {
                munlock(map, mapsize);
                xunmap((void *)map, mapsize);
            } else {
                HistoryClose();
            }
            Opened = 0;
            printf("New history\n");
        }
    }
}
コード例 #13
0
ファイル: group.c プロジェクト: jpmens/diablo
const char *
GetOverRecord(OverInfo *ov, artno_t artno, int *plen, int *alen, TimeRestrict *tr, int *TimeRcvd)
{
    int hvpos;
    int xpos;
    int xsize;
    const OverArt *oa;
    OverData *od;

    oa = GetOverArt(ov, artno, NULL);

    if (oa == NULL || ! OA_ARTNOEQ(artno, oa->oa_ArtNo) || oa->oa_Bytes > OVER_HMAPSIZE / 2) {
	if (plen)
	    *plen = 0;
	return(NULL);
    }

    if (ov->ov_LimitSecs > 0) {

	int dt = (int)(CurTime.tv_sec - oa->oa_TimeRcvd);
	if (dt > ov->ov_LimitSecs) {
	    if (plen)
		*plen = 0;
	    return(NULL);
	}
    }

    if (tr && tr->tr_Time > oa->oa_TimeRcvd)
	return(NULL);

    if (TimeRcvd)
	*TimeRcvd = oa->oa_TimeRcvd;

    if (alen)
	*alen = oa->oa_ArtSize;

    if (plen == NULL) 
	return((const char *)1);

    if (oa->oa_SeekPos == -1)
	return(NULL);

    if ((od = MakeOverHFile(ov, artno, 0)) == NULL)
	return(NULL);

    /*
     * hvpos / oa->oa_Bytes.  Include the guard character(s) in our 
     * calculations.
     */

    hvpos = oa->oa_SeekPos;

    xsize = oa->oa_Bytes + 1;
    if ((xpos = hvpos) != 0) {
	--xpos;
	++xsize;
    }

    if (
	od->od_HMapBase == NULL || 
	xpos < od->od_HMapPos || 
	xpos + xsize > od->od_HMapPos + od->od_HMapBytes
    ) {
	struct stat st;

	if (od->od_HMapBase) {
	    xunmap((void *)od->od_HMapBase, od->od_HMapBytes);
	    od->od_HMapBase = NULL;
	    od->od_HMapBytes = 0;
	    od->od_HMapPos = 0;
	}

	st.st_size = 0;
	fstat(od->od_HFd, &st);

	/*
	 * Make sure the file is big enough to map requested header.  It
	 * is possible for it to not be.
	 */

	if (xpos + xsize > st.st_size)
	    return(NULL);

	od->od_HMapPos = xpos & ~(HMAPALIGN-1);
	od->od_HMapBytes = OVER_HMAPSIZE;
	if (od->od_HMapBytes + od->od_HMapPos > st.st_size)
	    od->od_HMapBytes = st.st_size - od->od_HMapPos;

	od->od_HMapBase = xmap(NULL, od->od_HMapBytes, PROT_READ, MAP_SHARED, od->od_HFd, od->od_HMapPos);
	if (od->od_HMapBase == NULL) {
	    logit(LOG_CRIT, "mmap() failed B %s", strerror(errno));
	    exit(1);
	}
    }

    /*
     * Return base of record, length in *plen.  But check for corruption...
     * if the overview starts with a nul we have a problem.
     */

    *plen = oa->oa_Bytes;
    {
	const char *r = od->od_HMapBase + hvpos - od->od_HMapPos;

	if (*r == 0)
	    return(NULL);
	if (xpos < hvpos && r[-1] != 0) {
	    logit(LOG_ERR, "corrupt overview entry for %s:%lld", ov->ov_Group, artno);
	    return(NULL);
	}
	if (r[oa->oa_Bytes] != 0) {
	    logit(LOG_ERR, "corrupt overview entry for %s:%lld", ov->ov_Group, artno);
	    return(NULL);
	}
	return(r);
    }
}
コード例 #14
0
ファイル: group.c プロジェクト: jpmens/diablo
OverInfo *
GetOverInfo(const char *group)
{
    OverInfo **pov = &OvHash[shash(group) & OVHMASK];
    OverInfo *ov;

    while ((ov = *pov) != NULL) {
	if (strcmp(group, ov->ov_Group) == 0)
	    break;
	pov = &ov->ov_Next;
    }
    if (ov == NULL) {
	OverExpire save;
	struct stat st;
	char *path;
	int iter = 0;
	artno_t endNo = 0;

	bzero(&st, sizeof(st));

	/*
	 * If our cache has grown too large, attempt to free up
	 * a bunch of overview structures.  Depending on the load,
	 * we may not be able to.
	 */

	if (NumOverInfo >= OV_CACHE_MAX) {
	    int i;
	    int freeup = OV_CACHE_MAX / 2;
	    static int OI = 0;

	    for (i = 0; i < OVHSIZE && freeup; ++i) {
		int ai = OI;
		OI = (ai + 1) & OVHMASK;

		pov = &OvHash[ai];
		while ((ov = *pov) != NULL) {
		    if (ov->ov_Refs == 0) {
			*pov = ov->ov_Next;
			FreeOverInfo(ov);
			--NumOverInfo;
			--freeup;
		    } else {
			pov = &ov->ov_Next;
		    }
		}
	    }
	}
	ov = zalloc(&SysMemPool, sizeof(OverInfo));
	ov->ov_Group = zallocStr(&SysMemPool, group);
	GetOverExpire(group, &save);
	ov->ov_LimitSecs = save.oe_LimitDays * 24.0 * 60.0 * 60.0;

	{
	    const char *rec;
	    int recLen;
	    if ((rec = KPDBReadRecord(KDBActive, group, KP_LOCK, &recLen)) == NULL) {
		return(NULL);
	    }
	    iter = strtol(KPDBGetField(rec, recLen, "ITER", NULL, "0"), NULL, 10);
	    endNo = strtoll(KPDBGetField(rec, recLen, "NE", NULL, "-1"), NULL, 10);
	    KPDBUnlock(KDBActive, rec);
	}

	path = zalloc(&SysMemPool, strlen(MyGroupHome) + 48);
again:
	{
	    const char *gfname = GFName(group, GRPFTYPE_OVER, 0, 1, iter,
						&DOpts.ReaderGroupHashMethod);

	    sprintf(path, "%s/%s", MyGroupHome, gfname);
	    ov->ov_OFd = -1;
	    if (MakeGroupDirectory(path) == -1)
		logit(LOG_ERR, "Error on overview dir open/create: %s (%s)",
						path, strerror(errno));
	    else
		ov->ov_OFd = xopen(O_RDWR|O_CREAT, 0644, "%s", path);
	}
	if (ov->ov_OFd < 0) {
	    logit(LOG_ERR, "Error on overview open/create for group %s: %s (%s)",
						group, path, strerror(errno));
	    FreeOverInfo(ov);
	    ov = NULL;
	} else {
	    OverHead oh;
	    int r;

	    /*
	     * Leave a shared lock on the over.* file so expireover knows when
	     * it is OK to resize the file.  If the file was renamed-over,
	     * we have to re-open it.
	     */

	    hflock(ov->ov_OFd, 4, XLOCK_SH);

	    if (fstat(ov->ov_OFd, &st) < 0 || st.st_nlink == 0) {
		hflock(ov->ov_OFd, 4, XLOCK_UN);
		close(ov->ov_OFd);
		ov->ov_OFd = -1;
		goto again;
	    }

	    /*
	     * check if new overview file or illegal overview file and size 
	     * accordingly
	     */
	    r = (read(ov->ov_OFd, &oh, sizeof(oh)) != sizeof(oh));
	    if (r == 0 && st.st_size == 0) {
		r = -1;
	    }
	    if (r == 0 && oh.oh_ByteOrder != OH_BYTEORDER) {
		logit(LOG_CRIT, "Incorrect overview byte order for %s (%s)",
								group, path);
		r = -1;
	    }
	    if (r == 0 && oh.oh_Version > OH_VERSION) {
		logit(LOG_CRIT, "Incorrect overview version for %s (%s)",
								group, path);
		r = -1;
	    }
	    if (r != 0) {
		hflock(ov->ov_OFd, 0, XLOCK_EX);
		/*
		 * we have to test again after we got the lock in case
		 * another process had a lock and adjusted the file.
		 */
		lseek(ov->ov_OFd, 0L, 0);
		if (read(ov->ov_OFd, &oh, sizeof(oh)) != sizeof(oh) ||
		    oh.oh_ByteOrder != OH_BYTEORDER
		) {

		    /*
		     * If 'aInitArts' option not given in expireCtl
		     */

		    if (save.oe_InitArts == 0)
			save.oe_InitArts = DEFARTSINGROUP;

		    ftruncate(ov->ov_OFd, 0);
		    st.st_size = sizeof(oh) + sizeof(OverArt) * save.oe_InitArts;
		    FileAllocSpace(ov->ov_OFd, 0, st.st_size);
		    fsync(ov->ov_OFd);
		    lseek(ov->ov_OFd, 0L, 0);
		    bzero(&oh, sizeof(oh));
		    oh.oh_Version = OH_VERSION;
		    oh.oh_ByteOrder = OH_BYTEORDER;
		    oh.oh_HeadSize = sizeof(oh);
		    oh.oh_MaxArts = save.oe_InitArts;
		    strncpy(oh.oh_Gname, group, sizeof(oh.oh_Gname) - 1);
		    oh.oh_DataEntries = save.oe_DataSize;
		    write(ov->ov_OFd, &oh, sizeof(oh));
		    fsync(ov->ov_OFd);
		}
		hflock(ov->ov_OFd, 0, XLOCK_UN);
	    }
	    if (oh.oh_Version < 3)
		oh.oh_DataEntries = OD_HARTS;
	    if ((oh.oh_DataEntries<=0) || ((oh.oh_DataEntries ^ (oh.oh_DataEntries - 1)) != (oh.oh_DataEntries << 1) - 1))
		oh.oh_DataEntries = OD_HARTS;
	    if (oh.oh_Version > 1 && strcmp(oh.oh_Gname, group) != 0) {
		hflock(ov->ov_OFd, 4, XLOCK_UN);
		close(ov->ov_OFd);
		ov->ov_OFd = -1;
		iter++;
		goto again;
	    }
	    if (iter > 0) {
		char tsBuf[64];
		sprintf(tsBuf,"%06d", iter);
		KPDBWrite(KDBActive, group, "ITER", tsBuf, 0);   
	    }
	    ov->ov_Iter = iter;
	    ov->ov_endNo = endNo;
	    ov->ov_Size = st.st_size;
	    ov->ov_MaxArts = (st.st_size - oh.oh_HeadSize) / sizeof(OverArt);
	    ov->ov_DataEntryMask = oh.oh_DataEntries - 1;
	    ov->ov_Head = xmap(NULL, ov->ov_Size, PROT_READ, MAP_SHARED, ov->ov_OFd, 0);
	    if (ov->ov_Head == NULL) {
		logit(LOG_ERR, "Error on overview mmap for group %s (%s)",
						group, strerror(errno));
		FreeOverInfo(ov);
		ov = NULL;
	    } else {
		xadvise(ov->ov_Head, ov->ov_Size, XADV_SEQUENTIAL);
		++NumOverInfo;
		pov = &OvHash[shash(group) & OVHMASK];
		ov->ov_Next = *pov;
		*pov = ov;
	    }
	}
	zfree(&SysMemPool, path, strlen(MyGroupHome) + 48);
    }
    if (ov)
	++ov->ov_Refs;
    return(ov);
}
コード例 #15
0
ファイル: group.c プロジェクト: jpmens/diablo
OverData *
MakeOverHFile(OverInfo *ov, artno_t artNo, int create)
{
    artno_t artBase = artNo & ~ov->ov_DataEntryMask;
    OverData **pod;
    OverData *od;
    int count = 0;
    int compressed = 0;
    int hfd, tmpfd, zfd, gzflags;
    unsigned char *zmap, *tmpmap, *zpos, tmpfile[256];
    struct stat st;
    unsigned long zlen;
    z_stream z;
    int code;

    if (create)
	create = O_CREAT;

    if (ov->ov_HCache && artBase == ov->ov_HCache->od_ArtBase)
	return(ov->ov_HCache);
    for (pod = &ov->ov_HData; (od = *pod) != NULL; pod = &od->od_Next) {
	if (artBase == od->od_ArtBase)
	    break;
	++count;
    }
    if (od == NULL) {
	const char *gfname = GFName(ov->ov_Group, GRPFTYPE_DATA, artBase, 1,
				ov->ov_Iter, &DOpts.ReaderGroupHashMethod);

	*pod = od = zalloc(&SysMemPool, sizeof(OverData));
        errno = 0;
	hfd = xopen(O_RDWR|create, 0644, "%s/%s", MyGroupHome, gfname);
	if (hfd < 0 && ! create) {
	    zfd = xopen(O_RDONLY, 0644, "%s/%s.gz", MyGroupHome, gfname);
	    if (! (zfd < 0)) {
		compressed++;

		snprintf(tmpfile, sizeof(tmpfile), "/tmp/dr-gzover.XXXXXXXX");
		tmpfd = mkstemp(tmpfile);

		if (! (tmpfd < 0)) {
		    st.st_size = 0;
	    	    fstat(zfd, &st);

		    zmap = xmap(NULL, st.st_size, PROT_READ, MAP_SHARED, zfd, 0);
	    	    if (! zmap) {
		        logit(LOG_ERR, "Unable to xmap for gzcat %s/%s: %s",
			    MyGroupHome,
		            gfname,
		            strerror(errno)
		        );
		    } else {
		        zpos = zmap + st.st_size - 4;
		        zlen = ((unsigned)zpos[0] & 0xff) |
			       ((unsigned)zpos[1] & 0xff) << 8 |
			       ((unsigned)zpos[2] & 0xff) << 16 |
			       ((unsigned)zpos[3] & 0xff) << 24;

		        if (zlen < 256 || zlen > (64 * 1048576)) {
			    logit(LOG_ERR, "Bad zlen %d for gzcat %s/%s",
			        zlen,
			        MyGroupHome,
			        gfname
			    );
			    xunmap((void *)zmap, st.st_size);
			    hfd = -1;
			    close(tmpfd);
			    tmpfd = -1;
		        } else {
		            ftruncate(tmpfd, zlen);
		            tmpmap = xmap(NULL, zlen, PROT_READ|PROT_WRITE, MAP_SHARED, tmpfd, 0);
	    	            if (! tmpmap) {
		                logit(LOG_ERR, "Unable to xmap for gztmp /tmp/%s: %s",
			            MyGroupHome,
		                    gfname,
		                    strerror(errno)
		                );
			        xunmap((void *)zmap, st.st_size);
			        hfd = -1;
			        close(tmpfd);
				tmpfd = -1;
		            } else {
				// handle gzip headers
				zpos = zmap;

				if (zpos[0] != GZ_MAGIC0 || zpos[1] != GZ_MAGIC1 || zpos[2] != Z_DEFLATED) {
				    logit(LOG_ERR, "gzip header error (%d, %d, %d) for gzcat %s/%s: %s",
				        zpos[0], zpos[1], zpos[2],
			                MyGroupHome,
		                        gfname,
				        z.msg
				    );
				}
				zpos += 3;

				gzflags = *zpos;
				zpos += 7;


				if ((gzflags & GZ_EXTRA)) {
				    zpos += zpos[0] + (zpos[1] << 8);
				}
				if ((gzflags & GZ_ORIGNAME)) {
				    for ( ; *zpos; zpos++) {
				    }
				    zpos++;
				}
				if ((gzflags & GZ_COMMENT)) {
				    for ( ; *zpos; zpos++) {
				    }
				    zpos++;
				}
				if ((gzflags & GZ_HEADCRC)) {
				    zpos += 2;
				}

				// begin uncompress
			        bzero(&z, sizeof(z));
    
			        z.next_in = zpos;
			        z.avail_in = st.st_size - (zpos - zmap);
    
			        z.next_out = tmpmap;
			        z.avail_out = zlen;

//				z.zalloc = zalloc;
//				z.zfree = zfree;
//				z.opaque = &SysMemPool;
    
				inflateInit2(&z, -MAX_WBITS);
			        code = inflate(&z, Z_FINISH);
				inflateEnd(&z);
    
			        if (code != Z_STREAM_END) {
				    logit(LOG_ERR, "inflate error (%i) for gzcat %s/%s: %s",
				        code, 
			                MyGroupHome,
		                        gfname,
				        z.msg
				    );
			            xunmap((void *)zmap, st.st_size);
			            xunmap((void *)tmpmap, zlen);
				    hfd = -1;
				    close(tmpfd);
				    tmpfd = -1;
			        } else {
			            xunmap((void *)zmap, st.st_size);
		                    hfd = tmpfd;

//				    od->od_HMapBase = tmpmap;
//				    od->od_HMapBytes = zlen;
			            xunmap((void *)tmpmap, zlen);
			        }
			    }
			}
		    }

		    close(zfd);
		    if (unlink(tmpfile) < 0) {
		        logit(LOG_ERR, "Unable to remove gztmp %s: %s",
		            tmpfile,
		            strerror(errno)
		        );
		    }
		} else {
		    logit(LOG_ERR, "Unable to open/create gztmp %s: %s",
		        tmpfile,
		        strerror(errno)
		    );
		    close(zfd);
		}
	    }
	}

	od->od_HFd = hfd;

	if (od->od_HFd < 0) {
	    if (create) {
		logit(LOG_ERR, "Unable to open/create %s/%s: %s",
		    MyGroupHome,
		    gfname,
		    strerror(errno)
		);
	    }
	    FreeOverData(od);
	    *pod = od = NULL;
	} else {
	    od->od_ArtBase = artBase;
	    if (count > DOpts.ReaderThreads) {
		OverData *t = ov->ov_HData;
		ov->ov_HData = t->od_Next;
		FreeOverData(t);
	    }
	}
    }
    ov->ov_HCache = od;

    return(od);
}
コード例 #16
0
ファイル: group.c プロジェクト: jpmens/diablo
void
OutputOverRange(OverInfo *ov, Connection *conn)
{
    int hvpos;
    int xpos=0;
    int xsize=0;
    int nart=0;
    const OverArt *oa;
    OverData *od;
    artno_t artBase = conn->co_ListBegNo & ~ov->ov_DataEntryMask;
    artno_t artend = conn->co_ListEndNo;
    TimeRestrict *tr = NULL;

    if (conn->co_ArtMode == COM_NEWNEWS)
	tr = &conn->co_TimeRestrict;

    /* one datafile at a time */
    if (artend>artBase+ov->ov_DataEntryMask) {
	artend = artBase+ov->ov_DataEntryMask;
    }
    /* process mmap needs */
    if ((conn->co_ListBegNo>artBase) || (artend<artBase+ov->ov_DataEntryMask)) {
	nart = ProcessOverMmapNeed(ov, conn, tr, artend, OVER_HMAPSIZE, &xpos, &xsize);
	if (nart==0) return;
	if (xpos) xpos--;
	xsize -= xpos-1;
    }

    /* mmaping datafile */
    if ((od = MakeOverHFile(ov, artBase, 0)) == NULL) {
	conn->co_ListBegNo = artend+1;
	return;
    }

    if (
	od->od_HMapBase == NULL || 
	nart == 0 ||
	xpos < od->od_HMapPos || 
	xpos + xsize > od->od_HMapPos + od->od_HMapBytes
    ) {
	struct stat st;
	int advise=XADV_WILLNEED;

	if (od->od_HMapBase) {
	    xunmap((void *)od->od_HMapBase, od->od_HMapBytes);
	    od->od_HMapBase = NULL;
	    od->od_HMapBytes = 0;
	    od->od_HMapPos = 0;
	}

	st.st_size = 0;
	fstat(od->od_HFd, &st);

	/*
	 * Make sure the file is big enough to map requested header.  It
	 * is possible for it to not be.
	 */

	if (!st.st_size) {
	    if (xsize) {
		logit(LOG_CRIT, "Group %s data file is empty (%i/%i)", conn->co_GroupName, st.st_size, xsize);
	    }
	    conn->co_ListBegNo = artend+1;
	    return;
	}
	if (xpos > st.st_size) {
	    logit(LOG_CRIT, "Group %s data file is too small to be mmapped (%i/%i)", conn->co_GroupName, st.st_size, xpos);
	    conn->co_ListBegNo = artend+1;
	    return;
	} 

	if (nart==0) {
	    if (st.st_size>OVER_HMAPSIZE) {
		nart = ProcessOverMmapNeed(ov, conn, tr, artend, OVER_HMAPSIZE, &xpos, &xsize);
		if (nart==0) return;
		if (xpos) xpos--;
		xsize -= xpos-1;
	    } else {
		xpos = 0;
		xsize = st.st_size;
	    }
	}
	
	od->od_HMapPos = xpos;
	if (xpos + xsize > st.st_size) {
	    /* check if first article is inside the file */
    	    oa = GetOverArt(ov, conn->co_ListBegNo, NULL);
	    if (oa->oa_SeekPos + oa->oa_Bytes > st.st_size) {
		logit(LOG_CRIT, "Group %s data file is too small to contain header #%lld (%i+%i>%i)", conn->co_GroupName, conn->co_ListBegNo, oa->oa_SeekPos, oa->oa_Bytes, st.st_size);
		conn->co_ListBegNo++;
		return;
	    }
	    logit(LOG_CRIT, "Group %s data file is too small to be fully mmapped (%i+%i>%i)", conn->co_GroupName, xpos, xsize, st.st_size);
	    od->od_HMapBytes = st.st_size - xpos;
	} else {
	    od->od_HMapBytes= xsize;
	}
	
	od->od_HMapBase = xmap(NULL, od->od_HMapBytes, PROT_READ, MAP_SHARED, od->od_HFd, od->od_HMapPos);
	if (od->od_HMapBase == NULL) {
	    logit(LOG_CRIT, "mmap() failed C (%s) group %s (%lld:%lld@%i:%i)", strerror(errno), conn->co_GroupName, conn->co_ListBegNo, artend, od->od_HMapPos, od->od_HMapBytes);
	    exit(1);
	}
	xadvise(od->od_HMapBase, od->od_HMapBytes, advise);
    }

    for( ; conn->co_ListBegNo <= artend ; conn->co_ListBegNo++) {

	oa = GetOverArt(ov, conn->co_ListBegNo, NULL);

	if (oa==NULL || ! OA_ARTNOEQ(conn->co_ListBegNo, oa->oa_ArtNo)) continue;
	if (tr && tr->tr_Time > oa->oa_TimeRcvd) continue;
    	if (oa->oa_SeekPos == -1) continue;

	/* check mmap */
	if ( (oa->oa_SeekPos<od->od_HMapPos) 
		|| (oa->oa_SeekPos+oa->oa_Bytes-od->od_HMapPos > od->od_HMapBytes)
	) return;

	/*
	 * hvpos / oa->oa_Bytes.  Include the guard character(s) in our 
	 * calculations.
	 */

	hvpos = oa->oa_SeekPos;

	xsize = oa->oa_Bytes + 1;
	if ((xpos = hvpos) != 0) {
	    --xpos;
	    ++xsize;
	}


	/*
	 * Return base of record, length in *plen.  But check for corruption...
	 * if the overview starts with a nul we have a problem.
	 */

	{
	    const char *r = od->od_HMapBase + hvpos - od->od_HMapPos;

	    if (*r == 0)
		continue;
	    if (xpos < hvpos && r[-1] != 0) {
		logit(LOG_ERR, "corrupt overview entry for %s:%lld", ov->ov_Group, conn->co_ListBegNo);
		continue;
	    }
	    if (r[oa->oa_Bytes] != 0) {
		logit(LOG_ERR, "corrupt overview entry for %s:%lld", ov->ov_Group, conn->co_ListBegNo);
		continue;
	    }
	    OutputOverview(conn, r, oa->oa_Bytes, oa->oa_ArtSize);
	}
    }
}