Ejemplo n.º 1
0
FILE *HCache_open(const char *file, const char *opt) {
	FILE *first;
	char s_path[255];
		
	if( file[0] == '.' && file[1] == '/' )
		file += 2;
	else if( file[0] == '.' )
		file++;
	
	snprintf(s_path, 255, "./cache/%s", file);
	
	if( !(first = fopen(s_path,opt)) ) {
		return NULL;
	}
	
	if( opt[0] != 'r' ) {
		char dT[1];/* 1-byte key to ensure our method is the latest, we can modify to ensure the method matches */
		dT[0] = HCACHE_KEY;
		hwrite(dT,sizeof(dT),1,first);
		hwrite(&HCache->recompile_time,sizeof(HCache->recompile_time),1,first);
	}
	fseek(first, 20, SEEK_SET);/* skip first 20, might wanna store something else later */
	
	return first;
}
Ejemplo n.º 2
0
DLL_EXPORT int html_include(WEBBLK *webblk, char *filename)
{
    FILE *inclfile;
    char fullname[HTTP_PATH_LENGTH];
    char buffer[HTTP_PATH_LENGTH];
    int ret;

    strlcpy( fullname, http_serv.httproot, sizeof(fullname) );
    strlcat( fullname, filename,           sizeof(fullname) );

    inclfile = fopen(fullname,"rb");

    if (!inclfile)
    {
        WRMSG(HHC01800,"E","fopen()",strerror(errno));
        hprintf(webblk->sock,MSG(HHC01800,"E","fopen()",strerror(errno)));
        return FALSE;
    }

    while (!feof(inclfile))
    {
        ret = (int)fread(buffer, 1, sizeof(buffer), inclfile);
        if (ret <= 0) break;
        hwrite(webblk->sock,buffer, ret);
    }

    fclose(inclfile);
    return TRUE;
}
Ejemplo n.º 3
0
DLL_EXPORT int html_include(WEBBLK *webblk, char *filename)
{
    FILE *inclfile;
    char fullname[HTTP_PATH_LENGTH];
    char buffer[HTTP_PATH_LENGTH];
    int ret;

    strlcpy( fullname, sysblk.httproot, sizeof(fullname) );
    strlcat( fullname, filename,        sizeof(fullname) );

    inclfile = fopen(fullname,"rb");

    if (!inclfile)
    {
        logmsg(_("HHCHT011E html_include: Cannot open %s: %s\n"),
          fullname,strerror(errno));
        hprintf(webblk->sock,_("ERROR: Cannot open %s: %s\n"),
          filename,strerror(errno));
        return FALSE;
    }

    while (!feof(inclfile))
    {
        ret = fread(buffer, 1, sizeof(buffer), inclfile);
        if (ret <= 0) break;
        hwrite(webblk->sock,buffer, ret);
    }

    fclose(inclfile);
    return TRUE;
}
Ejemplo n.º 4
0
DLL_EXPORT int hprintf(int s,char *fmt,...)
{
    char *bfr;
    size_t bsize=1024;
    int rc;
    va_list vl;

    bfr=malloc(bsize);
    while(1)
    {
        if(!bfr)
        {
            return -1;
        }
        va_start(vl,fmt);
        rc=vsnprintf(bfr,bsize,fmt,vl);
        va_end(vl);
        if(rc<(int)bsize)
        {
            break;
        }
        bsize+=1024;
        bfr=realloc(bfr,bsize);
    }
    rc=hwrite(s,bfr,strlen(bfr));
    free(bfr);
    return rc;
}
Ejemplo n.º 5
0
static int
fromwebdir(HConnect *c)
{
	char buf[4096], *p, *ext, *type;
	int i, fd, n, defaulted;
	Dir *d;
	
	if(webroot == nil || strstr(c->req.uri, ".."))
		return hnotfound(c);
	snprint(buf, sizeof buf-20, "%s/%s", webroot, c->req.uri+1);
	defaulted = 0;
reopen:
	if((fd = open(buf, OREAD)) < 0)
		return hnotfound(c);
	d = dirfstat(fd);
	if(d == nil){
		close(fd);
		return hnotfound(c);
	}
	if(d->mode&DMDIR){
		if(!defaulted){
			defaulted = 1;
			strcat(buf, "/index.html");
			free(d);
			close(fd);
			goto reopen;
		}
		free(d);
		return hnotfound(c);
	}
	free(d);
	p = buf+strlen(buf);
	type = "application/octet-stream";
	for(i=0; exttab[i].ext; i++){
		ext = exttab[i].ext;
		if(p-strlen(ext) >= buf && strcmp(p-strlen(ext), ext) == 0){
			type = exttab[i].type;
			break;
		}
	}
	if(hsettype(c, type) < 0){
		close(fd);
		return 0;
	}
	while((n = read(fd, buf, sizeof buf)) > 0)
		if(hwrite(&c->hout, buf, n) < 0)
			break;
	close(fd);
	hflush(&c->hout);
	return 0;
}
Ejemplo n.º 6
0
static int
hmanager(HConnect *c)
{
	Hio *hout;
	int r;
	int i, k;
	Job *j;
	VtLog *l;
	VtLogChunk *ch;

	r = hsethtml(c);
	if(r < 0)
		return r;

	hout = &c->hout;
	hprint(hout, "<html><head><title>venti mgr status</title></head>\n");
	hprint(hout, "<body><h2>venti mgr status</h2>\n");

	for(i=0; i<njob; i++) {
		j = &job[i];
		hprint(hout, "<b>");
		if(j->nrun == 0)
			hprint(hout, "----/--/-- --:--:--");
		else
			hprint(hout, "%+T", (long)(j->runstart + time0));
		hprint(hout, " %s", j->name);
		if(j->nrun > 0) {
			if(j->newok == -1) {
				hprint(hout, " (running)");
			} else if(!j->newok) {
				hprint(hout, " <font color=\"#cc0000\">(FAILED)</font>");
			}
		}
		hprint(hout, "</b>\n");
		hprint(hout, "<font size=-1><pre>\n");
		l = j->newlog;
		ch = l->w;
		for(k=0; k<l->nchunk; k++){
			if(++ch == l->chunk+l->nchunk)
				ch = l->chunk;
			hwrite(hout, ch->p, ch->wp-ch->p);
		}
		hprint(hout, "</pre></font>\n");
		hprint(hout, "\n");
	}
	hprint(hout, "</body></html>\n");
	hflush(hout);
	return 0;
}
Ejemplo n.º 7
0
static void http_download(WEBBLK *webblk, char *filename)
{
    char buffer[HTTP_PATH_LENGTH];
    char tbuf[80];
    int fd, length;
    char *filetype;
    char fullname[HTTP_PATH_LENGTH];
    struct stat st;
    MIMETAB *mime_type = mime_types;

    strlcpy( fullname, http_serv.httproot, sizeof(fullname) );
    strlcat( fullname, filename,        sizeof(fullname) );

    http_verify_path(webblk,fullname);

    if(stat(fullname,&st))
        http_error(webblk, "404 File Not Found","",
                           strerror(errno));

    if(!S_ISREG(st.st_mode))
        http_error(webblk, "404 File Not Found","",
                           "The requested file is not a regular file");

    fd = HOPEN(fullname,O_RDONLY|O_BINARY,0);
    if (fd == -1)
        http_error(webblk, "404 File Not Found","",
                           strerror(errno));

    hprintf(webblk->sock,"HTTP/1.0 200 OK\n");
    if ((filetype = strrchr(filename,'.')))
        for(mime_type++;mime_type->suffix
          && strcasecmp(mime_type->suffix,filetype + 1);
          mime_type++);
    if(mime_type->type)
        hprintf(webblk->sock,"Content-Type: %s\n", mime_type->type);

    hprintf(webblk->sock,"Expires: %s\n",
      http_timestring(tbuf,sizeof(tbuf),time(NULL)+HTML_STATIC_EXPIRY_TIME));

    hprintf(webblk->sock,"Content-Length: %d\n\n", (int)st.st_size);
    while ((length = read(fd, buffer, sizeof(buffer))) > 0)
            hwrite(webblk->sock,buffer, length);
    close(fd);
    http_exit(webblk);
}
Ejemplo n.º 8
0
static int
herror(HConnect *c)
{
	int n;
	Hio *hout;
	
	hout = &c->hout;
	n = snprint(c->xferbuf, HBufSize, "<html><head><title>Error</title></head>\n<body><h1>Error</h1>\n<pre>%r</pre>\n</body></html>");
	hprint(hout, "%s %s\r\n", hversion, "400 Bad Request");
	hprint(hout, "Date: %D\r\n", time(nil));
	hprint(hout, "Server: Venti\r\n");
	hprint(hout, "Content-Type: text/html\r\n");
	hprint(hout, "Content-Length: %d\r\n", n);
	if(c->head.closeit)
		hprint(hout, "Connection: close\r\n");
	else if(!http11(c))
		hprint(hout, "Connection: Keep-Alive\r\n");
	hprint(hout, "\r\n");

	if(c->req.meth == nil || strcmp(c->req.meth, "HEAD") != 0)
		hwrite(hout, c->xferbuf, n);

	return hflush(hout);
}
Ejemplo n.º 9
0
void
vtloghdump(Hio *h, VtLog *l)
{
	int i;
	VtLogChunk *c;
	char *name;
	
	name = l ? l->name : "&lt;nil&gt;";

	hprint(h, "<html><head>\n");
	hprint(h, "<title>Venti Server Log: %s</title>\n", name);
	hprint(h, "</head><body>\n");
	hprint(h, "<b>Venti Server Log: %s</b>\n<p>\n", name);
	
	if(l){
		c = l->w;
		for(i=0; i<l->nchunk; i++){
			if(++c == l->chunk+l->nchunk)
				c = l->chunk;
			hwrite(h, c->p, c->wp-c->p);
		}
	}
	hprint(h, "</body></html>\n");
}
Ejemplo n.º 10
0
/*
 * send back a nice error message if the content is unacceptable
 * to get this message in ie, go to tools, internet options, advanced,
 * and turn off Show Friendly HTTP Error Messages under the Browsing category
 */
static int
notaccept(HConnect *c, HContent *type, HContent *enc, char *which)
{
	Hio *hout;
	char *s, *e;

	hout = &c->hout;
	e = &c->xferbuf[HBufSize];
	s = c->xferbuf;
	s = seprint(s, e, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
	s = seprint(s, e, "<html>\n<title>Unacceptable %s</title>\n<body>\n", which);
	s = seprint(s, e, "Your browser will not accept this data, %H, because of its %s.<br>\n", c->req.uri, which);
	s = seprint(s, e, "Its Content-Type is %s/%s", type->generic, type->specific);
	if(enc != nil)
		s = seprint(s, e, ", and Content-Encoding is %s", enc->generic);
	s = seprint(s, e, ".<br>\n\n");

	s = acceptcont(s, e, c->head.oktype, "Content-Type");
	s = acceptcont(s, e, c->head.okencode, "Content-Encoding");
	s = seprint(s, e, "</body>\n</html>\n");

	hprint(hout, "%s 406 Not Acceptable\r\n", hversion);
	hprint(hout, "Server: Plan9\r\n");
	hprint(hout, "Date: %D\r\n", time(nil));
	hprint(hout, "Content-Type: text/html\r\n");
	hprint(hout, "Content-Length: %lud\r\n", s - c->xferbuf);
	if(c->head.closeit)
		hprint(hout, "Connection: close\r\n");
	else if(!http11(c))
		hprint(hout, "Connection: Keep-Alive\r\n");
	hprint(hout, "\r\n");
	if(strcmp(c->req.meth, "HEAD") != 0)
		hwrite(hout, c->xferbuf, s - c->xferbuf);
	writelog(c, "Reply: 406 Not Acceptable\nReason: %s\n", which);
	return hflush(hout);
}
Ejemplo n.º 11
0
void cgibin_syslog(WEBBLK *webblk)
{
int     num_bytes;
int     logbuf_idx;
char   *logbuf_ptr;
char   *command;
char   *value;
int     autorefresh = 0;
int     refresh_interval = 5;
int     msgcount = 22;

    if ((command = cgi_variable(webblk,"command")))
    {
        panel_command(command);
        // Wait a bit before proceeding in case
        // the command issues a lot of messages
        usleep(50000);
    }

    if((value = cgi_variable(webblk,"msgcount")))
        msgcount = atoi(value);
    else
        if((value = cgi_cookie(webblk,"msgcount")))
            msgcount = atoi(value);

    if ((value = cgi_variable(webblk,"refresh_interval")))
        refresh_interval = atoi(value);

    if (cgi_variable(webblk,"autorefresh"))
        autorefresh = 1;
    else if (cgi_variable(webblk,"norefresh"))
        autorefresh = 0;
    else if (cgi_variable(webblk,"refresh"))
        autorefresh = 1;

    html_header(webblk);

    hprintf(webblk->sock,"<script language=\"JavaScript\">\n"
                          "<!--\n"
                          "document.cookie = \"msgcount=%d\";\n"
                          "//-->\n"
                          "</script>\n",
                          msgcount);

    hprintf(webblk->sock, "<H2>Hercules System Log</H2>\n");
    hprintf(webblk->sock, "<PRE>\n");

    // Get the index to our desired starting message...

    logbuf_idx = msgcount ? log_line( msgcount ) : -1;

    // Now read the logfile starting at that index. The return
    // value is the total #of bytes of messages data there is.

    if ( (num_bytes = log_read( &logbuf_ptr, &logbuf_idx, LOG_NOBLOCK )) > 0 )
    {
        // Copy the message data to a work buffer for processing.
        // This is to allow for the possibility, however remote,
        // that the logfile buffer actually wraps around and over-
        // lays the message data we were going to display (which
        // could happen if there's a sudden flood of messages)

        int   sav_bytes  =         num_bytes;
        char *wrk_bufptr = malloc( num_bytes );

        if ( wrk_bufptr ) strncpy( wrk_bufptr,  logbuf_ptr, num_bytes );
        else                       wrk_bufptr = logbuf_ptr;

        // We need to convert certain characters that might
        // possibly be erroneously interpretted as HTML code

#define  AMP_LT    "&lt;"       // (HTML code for '<')
#define  AMP_GT    "&gt;"       // (HTML code for '>')
#define  AMP_AMP   "&amp;"      // (HTML code for '&')

        while ( num_bytes-- )
        {
            switch ( *wrk_bufptr )
            {
            case '<':
                hwrite( webblk->sock, AMP_LT     , sizeof(AMP_LT) );
                break;
            case '>':
                hwrite( webblk->sock, AMP_GT     , sizeof(AMP_GT) );
                break;
            case '&':
                hwrite( webblk->sock, AMP_AMP    , sizeof(AMP_AMP));
                break;
            default:
                hwrite( webblk->sock, wrk_bufptr , 1              );
                break;
            }

            wrk_bufptr++;
        }

        // (free our work buffer if it's really ours)

        if ( ( wrk_bufptr -= sav_bytes ) != logbuf_ptr )
            free( wrk_bufptr );
    }

    hprintf(webblk->sock, "</PRE>\n");

    hprintf(webblk->sock, "<FORM method=post>Command:\n");
    hprintf(webblk->sock, "<INPUT type=text name=command size=80>\n");
    hprintf(webblk->sock, "<INPUT type=submit name=send value=\"Send\">\n");
    hprintf(webblk->sock, "<INPUT type=hidden name=%srefresh value=1>\n",autorefresh ? "auto" : "no");
    hprintf(webblk->sock, "<INPUT type=hidden name=refresh_interval value=%d>\n",refresh_interval);
    hprintf(webblk->sock, "<INPUT type=hidden name=msgcount value=%d>\n",msgcount);
    hprintf(webblk->sock, "</FORM>\n<BR>\n");

    hprintf(webblk->sock, "<A name=bottom>\n");

    hprintf(webblk->sock, "<FORM method=post>\n");
    if(!autorefresh)
    {
        hprintf(webblk->sock, "<INPUT type=submit value=\"Auto Refresh\" name=autorefresh>\n");
        hprintf(webblk->sock, "Refresh Interval: ");
        hprintf(webblk->sock, "<INPUT type=text name=\"refresh_interval\" size=2 value=%d>\n",
           refresh_interval);
    }
    else
    {
        hprintf(webblk->sock, "<INPUT type=submit name=norefresh value=\"Stop Refreshing\">\n");
        hprintf(webblk->sock, "<INPUT type=hidden name=refresh_interval value=%d>\n",refresh_interval);
        hprintf(webblk->sock, " Refresh Interval: %2d \n", refresh_interval);
    }
    hprintf(webblk->sock, "<INPUT type=hidden name=msgcount value=%d>\n",msgcount);
    hprintf(webblk->sock, "</FORM>\n");

    hprintf(webblk->sock, "<FORM method=post>\n");
    hprintf(webblk->sock, "Only show last ");
    hprintf(webblk->sock, "<INPUT type=text name=msgcount size=3 value=%d>",msgcount);
    hprintf(webblk->sock, " lines (zero for all loglines)\n");
    hprintf(webblk->sock, "<INPUT type=hidden name=%srefresh value=1>\n",autorefresh ? "auto" : "no");
    hprintf(webblk->sock, "<INPUT type=hidden name=refresh_interval value=%d>\n",refresh_interval);
    hprintf(webblk->sock, "</FORM>\n");

    if (autorefresh)
    {
        /* JavaScript to cause automatic page refresh */
        hprintf(webblk->sock, "<script language=\"JavaScript\">\n");
        hprintf(webblk->sock, "<!--\nsetTimeout('window.location.replace(\"%s"
               "?refresh_interval=%d"
               "&refresh=1"
               "&msgcount=%d"
               "\")', %d)\n",
               cgi_baseurl(webblk),
               refresh_interval,
               msgcount,
               refresh_interval*1000);
        hprintf(webblk->sock, "//-->\n</script>\n");
    }

    html_footer(webblk);

}
Ejemplo n.º 12
0
int main(void)
{
    static const int size[] = { 1, 13, 403, 999, 30000 };

    char buffer[40000];
    char *original;
    int c, i;
    ssize_t n;
    off_t off;

    reopen("vcf.c", "test/hfile1.tmp");
    while ((c = hgetc(fin)) != EOF) {
        if (hputc(c, fout) == EOF) fail("hputc");
    }
    if (herrno(fin)) { errno = herrno(fin); fail("hgetc"); }

    reopen("test/hfile1.tmp", "test/hfile2.tmp");
    if (hpeek(fin, buffer, 50) < 0) fail("hpeek");
    while ((n = hread(fin, buffer, 17)) > 0) {
        if (hwrite(fout, buffer, n) != n) fail("hwrite");
    }
    if (n < 0) fail("hread");

    reopen("test/hfile2.tmp", "test/hfile3.tmp");
    while ((n = hread(fin, buffer, sizeof buffer)) > 0) {
        if (hwrite(fout, buffer, n) != n) fail("hwrite");
        if (hpeek(fin, buffer, 700) < 0) fail("hpeek");
    }
    if (n < 0) fail("hread");

    reopen("test/hfile3.tmp", "test/hfile4.tmp");
    i = 0;
    off = 0;
    while ((n = hread(fin, buffer, size[i++ % 5])) > 0) {
        off += n;
        buffer[n] = '\0';
        check_offset(fin, off, "pre-peek");
        if (hputs(buffer, fout) == EOF) fail("hputs");
        if ((n = hpeek(fin, buffer, size[(i+3) % 5])) < 0) fail("hpeek");
        check_offset(fin, off, "post-peek");
    }
    if (n < 0) fail("hread");

    reopen("test/hfile4.tmp", "test/hfile5.tmp");
    n = hread(fin, buffer, 200);
    if (n < 0) fail("hread");
    else if (n != 200) fail("hread only got %d", (int)n);
    if (hwrite(fout, buffer, 1000) != 1000) fail("hwrite");
    check_offset(fin, 200, "input/first200");
    check_offset(fout, 1000, "output/first200");

    if (hseek(fin, 800, SEEK_CUR) < 0) fail("hseek/cur");
    check_offset(fin, 1000, "input/seek");
    for (off = 1000; (n = hread(fin, buffer, sizeof buffer)) > 0; off += n)
        if (hwrite(fout, buffer, n) != n) fail("hwrite");
    if (n < 0) fail("hread");
    check_offset(fin, off, "input/eof");
    check_offset(fout, off, "output/eof");

    if (hseek(fin, 200, SEEK_SET) < 0) fail("hseek/set");
    if (hseek(fout, 200, SEEK_SET) < 0) fail("hseek(output)");
    check_offset(fin, 200, "input/backto200");
    check_offset(fout, 200, "output/backto200");
    n = hread(fin, buffer, 800);
    if (n < 0) fail("hread");
    else if (n != 800) fail("hread only got %d", (int)n);
    if (hwrite(fout, buffer, 800) != 800) fail("hwrite");
    check_offset(fin, 1000, "input/wrote800");
    check_offset(fout, 1000, "output/wrote800");

    if (hflush(fout) == EOF) fail("hflush");

    original = slurp("vcf.c");
    for (i = 1; i <= 5; i++) {
        char *text;
        sprintf(buffer, "test/hfile%d.tmp", i);
        text = slurp(buffer);
        if (strcmp(original, text) != 0) {
            fprintf(stderr, "%s differs from vcf.c\n", buffer);
            return EXIT_FAILURE;
        }
        free(text);
    }
    free(original);

    if (hclose(fin) != 0) fail("hclose(input)");
    if (hclose(fout) != 0) fail("hclose(output)");

    fout = hopen("test/hfile_chars.tmp", "w");
    if (fout == NULL) fail("hopen(\"test/hfile_chars.tmp\")");
    for (i = 0; i < 256; i++)
        if (hputc(i, fout) != i) fail("chars: hputc (%d)", i);
    if (hclose(fout) != 0) fail("hclose(test/hfile_chars.tmp)");

    fin = hopen("test/hfile_chars.tmp", "r");
    if (fin == NULL) fail("hopen(\"test/hfile_chars.tmp\") for reading");
    for (i = 0; i < 256; i++)
        if ((c = hgetc(fin)) != i)
            fail("chars: hgetc (%d = 0x%x) returned %d = 0x%x", i, i, c, c);
    if ((c = hgetc(fin)) != EOF) fail("chars: hgetc (EOF) returned %d", c);
    if (hclose(fin) != 0) fail("hclose(test/hfile_chars.tmp) for reading");

    fin = hopen("data:hello, world!\n", "r");
    if (fin == NULL) fail("hopen(\"data:...\")");
    n = hread(fin, buffer, 300);
    if (n < 0) fail("hread");
    buffer[n] = '\0';
    if (strcmp(buffer, "hello, world!\n") != 0) fail("hread result");
    if (hclose(fin) != 0) fail("hclose(\"data:...\")");

    return EXIT_SUCCESS;
}
Ejemplo n.º 13
0
//main
int main (int argc, char* argv[])
{
    //keep frequencies in array
    for (int i = 0; i < SYMBOLS; i++)
        frequencies[i] = 0;
    
    //make sure user inputs two arguments
    if (argc != 3)
    {
        printf("You must enter %s input output\n", argv[0]);
        return 1;
    }
    
    //open input 
    FILE *fp = fopen(argv[1],"r" );
    if (fp == NULL)
    {
        printf("Could not open souce file: %s\n", argv[1]);
        return 1;
    }
    
    //open output
    Huffile *outfile = hfopen(argv[2], "w");
    if (outfile == NULL) 
    {
        printf("Could not open destination file: %s\n", argv[2]);
        return 1;
    }   
    
    //create a forest
    Forest *myForest = mkforest();
    if (myForest == NULL)
    {
    	printf("The forest could not be created :(\n");
    	return 1;
    }
    
    //read each character from source file
    for (int c = fgetc(fp); c!= EOF; c = fgetc(fp))
    {
        //printf("%c", c);
        
        //increment frequencies for char
        frequencies[c]++;
        
        //increment checksum
        checksum_counter++;
    }   
    
    //make and plant trees in sorted order
    for (int i = 0; i < SYMBOLS; i++)
    {
        if (frequencies[i] != 0)
        {
            //make the tree
            Tree *tempTree = mktree();
            tempTree->symbol = i;
            tempTree->frequency = frequencies[i];
            tempTree->left = NULL;
            tempTree->right = NULL;
            
            //plant tree in forest
            if (plant(myForest, tempTree) == false)
                printf("Could not plant tree %c\n", i);
        }
    }
    
    //build the huffman tree
    while (myForest->first->tree->frequency < checksum_counter)
    {
        //make the tree
        Tree *tempTree = mktree();
        tempTree->symbol = 0x00;
        tempTree->left = pick(myForest);
        tempTree->right = pick(myForest);
        if (tempTree->right != NULL)
            tempTree->frequency = tempTree->left->frequency + tempTree->right->frequency;
        else
            tempTree->frequency = tempTree->left->frequency;
            
        //plant tree in forest
        if (plant(myForest, tempTree) == false)
            printf("Could not plant parent tree\n");
    }
    
    //create encoding of each character
    for (int i = 0; i < SYMBOLS; i++)
    {
        if (frequencies[i] != 0)
        {
            //create a temporary array to store the encoded value
            char temp[256];
            for (int j = 0; j < 256; j++)
                temp[j] = '9';
            
            encode(myForest->first->tree, i, 0, "", &temp[0]);
            
            //copy temp to encoded
            strncpy(encoded[i], temp, strlen(temp));
            
            //printf("temp: %s\n", temp);
            //printf("encoded: %c, hops: %s ", i, encoded[i]);
        }
    }
    
    //create huffeader header
    Huffeader *header = malloc(sizeof(Huffeader));
    header->magic = MAGIC;
    for (int i = 0; i < SYMBOLS; i++)
        header->frequencies[i] = frequencies[i];
    header->checksum = checksum_counter;
    
    //write header
    hwrite(header, outfile);
   
    //move to beginning of source file
    rewind(fp);
    
    //keep track of how many bits we use
    int bit_count = 0;
    
    //read file per character, lookup frequency, and write to outfile
    for (int c = fgetc(fp); c!= EOF; c = fgetc(fp))
    {
        for (int i = 0; i < strlen(encoded[c]); i++)
        {
            bit_count++;
            
            int bit = 0;
            
            //write each bit
            if (encoded[c][i] == '0')
                bit = 0;
            else if (encoded[c][i] == '1') 
                bit = 1;
                
            bool write_output = bwrite(bit, outfile);
            if (write_output == false)
                printf("Error bwriting: %c\n", encoded[c][i]);
                
            //printf("%c bit_count: %d\n", encoded[c][i], bit_count);
        }
         
        //printf("%s", encoded[c]);
    }
    
    //figure out how many bits in second to last byte are used
    int bits_used = 0;
    if (bit_count <= 8)
        bits_used = bit_count;
    else
        bits_used = (bit_count % 8);
    
    //write trailing bits
    for (int i = 8 - bits_used; i > 1; i--)
    {
        //printf("0\n");
        
        bool write_output = bwrite(0, outfile);
        if (write_output == false)
                printf("Error bwriting: %c\n", '0');
    }  
    
    //cleanup
    outfile->ith = bits_used;
    free(header);
    rmforest(myForest);
    hfclose(outfile);
    fclose(fp);
    
    return 0;
}
Ejemplo n.º 14
0
/*
 * Reads a version 3 CRAM file and replaces the header in-place,
 * provided the header is small enough to fit without growing the
 * entire file.
 *
 * Version 3 format has a SAM header held as an (optionally)
 * compressed block within the header container.  Additional
 * uncompressed blocks or simply unallocated space (the difference
 * between total block sizes and the container size) are used to
 * provide room for growth or contraction of the compressed header.
 *
 * Returns 0 on success;
 *        -1 on general failure;
 *        -2 on failure due to insufficient size
 */
int cram_reheader_inplace3(cram_fd *fd, const bam_hdr_t *h, const char *arg_list,
                          int add_PG)
{
    cram_container *c = NULL;
    cram_block *b = NULL;
    SAM_hdr *hdr = NULL;
    off_t start, sz, end;
    int container_sz, max_container_sz;
    char *buf = NULL;
    int ret = -1;

    if (cram_major_vers(fd) < 2 ||
        cram_major_vers(fd) > 3) {
        fprintf(stderr, "[%s] unsupported CRAM version %d\n", __func__,
                cram_major_vers(fd));
        goto err;
    }

    if (!(hdr = sam_hdr_parse_(h->text, h->l_text)))
        goto err;

    if (add_PG && sam_hdr_add_PG(hdr, "samtools", "VN", samtools_version(),
                                 arg_list ? "CL": NULL,
                                 arg_list ? arg_list : NULL,
                                 NULL))
        goto err;

    int header_len = sam_hdr_length(hdr);
    /* Fix M5 strings? Maybe out of scope for this tool */

    // Find current size of SAM header block
    if ((start = hseek(cram_fd_get_fp(fd), 26, SEEK_SET)) != 26)
        goto err;

    if (!(c = cram_read_container(fd)))
        goto err;

    // +5 allows num_landmarks to increase from 0 to 1 (Cramtools)
    max_container_sz = cram_container_size(c)+5;

    sz = htell(cram_fd_get_fp(fd)) + cram_container_get_length(c) - start;
    end = htell(cram_fd_get_fp(fd)) + cram_container_get_length(c);

    // We force 1 block instead of (optionally) 2.  C CRAM
    // implementations for v3 were writing 1 compressed block followed
    // by 1 uncompressed block.  However this is tricky to deal with
    // as changing block sizes can mean the block header also changes
    // size due to itf8 and variable size integers.
    //
    // If we had 1 block, this doesn't change anything.
    // If we had 2 blocks, the new container header will be smaller by
    // 1+ bytes, requiring the cram_container_get_length(c) to be larger in value.
    // However this is an int32 instead of itf8 so the container
    // header structure stays the same size.  This means we can always
    // reduce the number of blocks without running into size problems.
    cram_container_set_num_blocks(c, 1);
    int32_t *landmark;
    int32_t num_landmarks;
    landmark = cram_container_get_landmarks(c, &num_landmarks);
    if (num_landmarks && landmark) {
        num_landmarks = 1;
        landmark[0] = 0;
    } else {
        num_landmarks = 0;
    }
    cram_container_set_landmarks(c, num_landmarks, landmark);

    buf = malloc(max_container_sz);
    container_sz = max_container_sz;
    if (cram_store_container(fd, c, buf, &container_sz) != 0)
        goto err;

    if (!buf)
        goto err;

    // Proposed new length, but changing cram_container_get_length(c) may change the
    // container_sz and thus the remainder (cram_container_get_length(c) itself).
    cram_container_set_length(c, sz - container_sz);

    int old_container_sz = container_sz;
    container_sz = max_container_sz;
    if (cram_store_container(fd, c, buf, &container_sz) != 0)
        goto err;

    if (old_container_sz != container_sz) {
        fprintf(stderr, "Quirk of fate makes this troublesome! "
                "Please use non-inplace version.\n");
        goto err;
    }



    // Version 3.0 supports compressed header
    b = cram_new_block(FILE_HEADER, 0);
    int32_put_blk(b, header_len);
    cram_block_append(b, sam_hdr_str(hdr), header_len);
    cram_block_update_size(b);

    cram_compress_block(fd, b, NULL, -1, -1);

    if (hseek(cram_fd_get_fp(fd), 26, SEEK_SET) != 26)
        goto err;

    if (cram_block_size(b) > cram_container_get_length(c)) {
        fprintf(stderr, "New header will not fit. Use non-inplace version"
                " (%d > %d)\n",
                (int)cram_block_size(b), cram_container_get_length(c));
        ret = -2;
        goto err;
    }

    if (cram_write_container(fd, c) == -1)
        goto err;

    if (cram_write_block(fd, b) == -1)
        goto err;

    // Blank out the remainder
    int rsz = end - htell(cram_fd_get_fp(fd));
    assert(rsz >= 0);
    if (rsz) {
        char *rem = calloc(1, rsz);
        ret = hwrite(cram_fd_get_fp(fd), rem, rsz) == rsz ? 0 : -1;
        free(rem);
    }

 err:
    if (c) cram_free_container(c);
    if (buf) free(buf);
    if (b) cram_free_block(b);
    if (hdr) sam_hdr_free(hdr);

    return ret;
}