Exemple #1
0
static void de_run_wri(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	i64 pos;

	d = de_malloc(c, sizeof(lctx));

	if(c->input_encoding==DE_ENCODING_UNKNOWN)
		d->input_encoding = DE_ENCODING_WINDOWS1252;
	else
		d->input_encoding = c->input_encoding;

	d->extract_text = de_get_ext_option_bool(c, "wri:extracttext", 1);
	d->extract_ole = de_get_ext_option_bool(c, "wri:extractole",
		(c->extract_level>=2)?1:0);

	pos = 0;
	if(!do_header(c, d, pos)) goto done;
	if(d->extract_text) {
		do_html_begin(c, d);
	}

	do_para_info(c, d);

done:
	do_html_end(c, d);
	de_free(c, d);
}
Exemple #2
0
/*
 * count all the devices of a certain type and recurse to count
 * whatever the device is connected to
 */
void
do_count(const char *dev, const char *hname, int search)
{
	struct device *dp, *mp;
	int count;

	for (count = 0,dp = dtab; dp != 0; dp = dp->d_next)
		if (dp->d_unit != -1 && eq(dp->d_name, dev)) {
			/*
			 * Avoid making .h files for bus types on sun machines
			 */
			if ((machine == MACHINE_SUN2 ||
			     machine == MACHINE_SUN3 ||
			     machine == MACHINE_SUN4)
			    && dp->d_conn == TO_NEXUS){
				return;
			}
			if (dp->d_type == PSEUDO_DEVICE) {
				count =
				    dp->d_slave != UNKNOWN ? dp->d_slave : 1;
				if (dp->d_flags)
					dev = NULL;
				break;
			}
                        if (machine != MACHINE_SUN2 && machine != MACHINE_SUN3
			    && machine != MACHINE_SUN4)
				/* avoid ie0,ie0,ie1 setting NIE to 3 */
			count++;
			/*
			 * Allow holes in unit numbering,
			 * assumption is unit numbering starts
			 * at zero.
			 */
			if (dp->d_unit + 1 > count)
				count = dp->d_unit + 1;
			if (search) {
				mp = dp->d_conn;
                                if (mp != 0 && mp != TO_NEXUS &&
				    mp->d_conn != TO_NEXUS) {
                                        /*
					 * Check for the case of the
					 * controller that the device
					 * is attached to is in a separate
					 * file (e.g. "sd" and "sc").
					 * In this case, do NOT define
					 * the number of controllers
					 * in the hname .h file.
					 */
					if (!file_needed(mp->d_name))
					    do_count(mp->d_name, hname, 0);
					search = 0;
				}
			}
		}
	do_header(dev, hname, count);
}
Exemple #3
0
static void top(void)
{
	xenstat_domain **domains;
	unsigned int i, num_domains = 0;

	/* Now get the node information */
	if (prev_node != NULL)
		xenstat_free_node(prev_node);
	prev_node = cur_node;
	cur_node = xenstat_get_node(xhandle, XENSTAT_ALL);
	if (cur_node == NULL)
		fail("Failed to retrieve statistics from libxenstat\n");

	/* dump summary top information */
	if (!batch)
		do_summary();

	/* Count the number of domains for which to report data */
	num_domains = xenstat_node_num_domains(cur_node);

	domains = calloc(num_domains, sizeof(xenstat_domain *));
	if(domains == NULL)
		fail("Failed to allocate memory\n");

	for (i=0; i < num_domains; i++)
		domains[i] = xenstat_node_domain_by_index(cur_node, i);

	/* Sort */
	qsort(domains, num_domains, sizeof(xenstat_domain *),
	      (int(*)(const void *, const void *))compare_domains);

	if(first_domain_index >= num_domains)
		first_domain_index = num_domains-1;

	for (i = first_domain_index; i < num_domains; i++) {
		if(!batch && current_row() == lines()-1)
			break;
		if (i == first_domain_index || repeat_header)
			do_header();
		do_domain(domains[i]);
		if (show_vcpus)
			do_vcpu(domains[i]);
		if (show_networks)
			do_network(domains[i]);
		if (show_vbds)
			do_vbd(domains[i]);
		if (show_tmem)
			do_tmem(domains[i]);
	}

	if (!batch)
		do_bottom_line();

	free(domains);
}
Exemple #4
0
static void de_run_wad(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	i64 pos;

	d = de_malloc(c, sizeof(lctx));

	pos = 0;
	if(!do_header(c, d, pos)) goto done;
	pos += 12;

	do_directory(c, d, d->dir_pos);

done:
	de_free(c, d);
}
Exemple #5
0
void line_eval(char* line)
{
    if(line[0] == '/') {

        char inpt_command = line[1];

        if(inpt_command == 'f') {
            add_friend();
        }

        else if (inpt_command == 'r') {
            do_header();
            printf("\n\n");
        }

        else if (inpt_command == 'l') {
            list_friends();
        }

        else if (inpt_command == 'd') {
            delete_friend();
        }
        /* Send message to friend */
        else if (inpt_command == 'm') {
            message_friend();
        }

        else if (inpt_command == 'n') {
            change_nickname();
        }

        else if (inpt_command == 's') {
            change_status(1);
        }

        else if (inpt_command == 'a') {
            if (friend_request_received == 1)
                accept_friend_request(line);
        }
        /* EXIT */
        else if (inpt_command == 'q') {
            strcpy(line, "---Offline");
            change_status(0);
            exit(EXIT_SUCCESS);
        }
    }
}
Exemple #6
0
/*
 * PQprint()
 *
 * Format results of a query for printing.
 *
 * PQprintOpt is a typedef (structure) that contains
 * various flags and options. consult libpq-fe.h for
 * details
 *
 * This function should probably be removed sometime since psql
 * doesn't use it anymore. It is unclear to what extent this is used
 * by external clients, however.
 */
void
PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
{
	int			nFields;

	nFields = PQnfields(res);

	if (nFields > 0)
	{							/* only print rows with at least 1 field.  */
		int			i,
					j;
		int			nTups;
		int		   *fieldMax = NULL;	/* in case we don't use them */
		unsigned char *fieldNotNum = NULL;
		char	   *border = NULL;
		char	  **fields = NULL;
		const char **fieldNames;
		int			fieldMaxLen = 0;
		int			numFieldName;
		int			fs_len = strlen(po->fieldSep);
		int			total_line_length = 0;
		int			usePipe = 0;
		char	   *pagerenv;

#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
		sigset_t	osigset;
		bool		sigpipe_masked = false;
		bool		sigpipe_pending;
#endif
#if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
		pqsigfunc	oldsigpipehandler = NULL;
#endif

#ifdef TIOCGWINSZ
		struct winsize screen_size;
#else
		struct winsize
		{
			int			ws_row;
			int			ws_col;
		}			screen_size;
#endif

		nTups = PQntuples(res);
		if (!(fieldNames = (const char **) calloc(nFields, sizeof(char *))))
		{
			fprintf(stderr, libpq_gettext("out of memory\n"));
			abort();
		}
		if (!(fieldNotNum = (unsigned char *) calloc(nFields, 1)))
		{
			fprintf(stderr, libpq_gettext("out of memory\n"));
			abort();
		}
		if (!(fieldMax = (int *) calloc(nFields, sizeof(int))))
		{
			fprintf(stderr, libpq_gettext("out of memory\n"));
			abort();
		}
		for (numFieldName = 0;
			 po->fieldName && po->fieldName[numFieldName];
			 numFieldName++)
			;
		for (j = 0; j < nFields; j++)
		{
			int			len;
			const char *s = (j < numFieldName && po->fieldName[j][0]) ?
			po->fieldName[j] : PQfname(res, j);

			fieldNames[j] = s;
			len = s ? strlen(s) : 0;
			fieldMax[j] = len;
			len += fs_len;
			if (len > fieldMaxLen)
				fieldMaxLen = len;
			total_line_length += len;
		}

		total_line_length += nFields * strlen(po->fieldSep) + 1;

		if (fout == NULL)
			fout = stdout;
		if (po->pager && fout == stdout && isatty(fileno(stdin)) &&
			isatty(fileno(stdout)))
		{
			/*
			 * If we think there'll be more than one screen of output, try to
			 * pipe to the pager program.
			 */
#ifdef TIOCGWINSZ
			if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
				screen_size.ws_col == 0 ||
				screen_size.ws_row == 0)
			{
				screen_size.ws_row = 24;
				screen_size.ws_col = 80;
			}
#else
			screen_size.ws_row = 24;
			screen_size.ws_col = 80;
#endif
			pagerenv = getenv("PAGER");
			if (pagerenv != NULL &&
				pagerenv[0] != '\0' &&
				!po->html3 &&
				((po->expanded &&
				  nTups * (nFields + 1) >= screen_size.ws_row) ||
				 (!po->expanded &&
				  nTups * (total_line_length / screen_size.ws_col + 1) *
				  (1 + (po->standard != 0)) >= screen_size.ws_row -
				  (po->header != 0) *
				  (total_line_length / screen_size.ws_col + 1) * 2
				  - (po->header != 0) * 2		/* row count and newline */
				  )))
			{
				fout = popen(pagerenv, "w");
				if (fout)
				{
					usePipe = 1;
#ifndef WIN32
#ifdef ENABLE_THREAD_SAFETY
					if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
						sigpipe_masked = true;
#else
					oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
#endif   /* ENABLE_THREAD_SAFETY */
#endif   /* WIN32 */
				}
				else
					fout = stdout;
			}
		}

		if (!po->expanded && (po->align || po->html3))
		{
			if (!(fields = (char **) calloc(nFields * (nTups + 1), sizeof(char *))))
			{
				fprintf(stderr, libpq_gettext("out of memory\n"));
				abort();
			}
		}
		else if (po->header && !po->html3)
		{
			if (po->expanded)
			{
				if (po->align)
					fprintf(fout, libpq_gettext("%-*s%s Value\n"),
							fieldMaxLen - fs_len, libpq_gettext("Field"), po->fieldSep);
				else
					fprintf(fout, libpq_gettext("%s%sValue\n"), libpq_gettext("Field"), po->fieldSep);
			}
			else
			{
				int			len = 0;

				for (j = 0; j < nFields; j++)
				{
					const char *s = fieldNames[j];

					fputs(s, fout);
					len += strlen(s) + fs_len;
					if ((j + 1) < nFields)
						fputs(po->fieldSep, fout);
				}
				fputc('\n', fout);
				for (len -= fs_len; len--; fputc('-', fout));
				fputc('\n', fout);
			}
		}
		if (po->expanded && po->html3)
		{
			if (po->caption)
				fprintf(fout, "<center><h2>%s</h2></center>\n", po->caption);
			else
				fprintf(fout,
						"<center><h2>"
						"Query retrieved %d rows * %d fields"
						"</h2></center>\n",
						nTups, nFields);
		}
		for (i = 0; i < nTups; i++)
		{
			if (po->expanded)
			{
				if (po->html3)
					fprintf(fout,
							"<table %s><caption align=\"top\">%d</caption>\n",
							po->tableOpt ? po->tableOpt : "", i);
				else
					fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i);
			}
			for (j = 0; j < nFields; j++)
				do_field(po, res, i, j, fs_len, fields, nFields,
						 fieldNames, fieldNotNum,
						 fieldMax, fieldMaxLen, fout);
			if (po->html3 && po->expanded)
				fputs("</table>\n", fout);
		}
		if (!po->expanded && (po->align || po->html3))
		{
			if (po->html3)
			{
				if (po->header)
				{
					if (po->caption)
						fprintf(fout,
						   "<table %s><caption align=\"top\">%s</caption>\n",
								po->tableOpt ? po->tableOpt : "",
								po->caption);
					else
						fprintf(fout,
								"<table %s><caption align=\"top\">"
								"Retrieved %d rows * %d fields"
								"</caption>\n",
						   po->tableOpt ? po->tableOpt : "", nTups, nFields);
				}
				else
					fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");
			}
			if (po->header)
				border = do_header(fout, po, nFields, fieldMax, fieldNames,
								   fieldNotNum, fs_len, res);
			for (i = 0; i < nTups; i++)
				output_row(fout, po, nFields, fields,
						   fieldNotNum, fieldMax, border, i);
			free(fields);
			if (border)
				free(border);
		}
		if (po->header && !po->html3)
			fprintf(fout, "(%d row%s)\n\n", PQntuples(res),
					(PQntuples(res) == 1) ? "" : "s");
		free(fieldMax);
		free(fieldNotNum);
		free((void *) fieldNames);
		if (usePipe)
		{
#ifdef WIN32
			_pclose(fout);
#else
			pclose(fout);

#ifdef ENABLE_THREAD_SAFETY
			/* we can't easily verify if EPIPE occurred, so say it did */
			if (sigpipe_masked)
				pq_reset_sigpipe(&osigset, sigpipe_pending, true);
#else
			pqsignal(SIGPIPE, oldsigpipehandler);
#endif   /* ENABLE_THREAD_SAFETY */
#endif   /* WIN32 */
		}
		if (po->html3 && !po->expanded)
			fputs("</table>\n", fout);
	}
}
Exemple #7
0
int main(int argc, char *argv[])
{
    if (argc < 4) {
        printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]);
        exit(0);
    }
    if (initMessenger() == -1) {
        printf("initMessenger failed");
        exit(0);
    }
    if (argc > 4) {
        if(strncmp(argv[4], "nokey", 6) < 0) {
        }
    } else {
        load_key();
    }

    int nameloaded = 0;
    int statusloaded = 0;

    FILE* name_file = NULL;
    name_file = fopen("namefile.txt", "r");
    if(name_file) {
        uint8_t name[MAX_NAME_LENGTH];
        while (fgets(line, MAX_NAME_LENGTH, name_file) != NULL) {
            sscanf(line, "%s", (char*)name);
        }
        setname(name, strlen((char*)name)+1);
        nameloaded = 1;
        printf("%s\n", name);
    }
    fclose(name_file);

    FILE* status_file = NULL;
    status_file = fopen("statusfile.txt", "r");
    if(status_file) {
        uint8_t status[MAX_USERSTATUS_LENGTH];
        while (fgets(line, MAX_USERSTATUS_LENGTH, status_file) != NULL) {
            sscanf(line, "%s", (char*)status);
        }
        m_set_userstatus(status, strlen((char*)status)+1);
        statusloaded = 1;
        printf("%s\n", status);
    }
    fclose(status_file);

    m_callback_friendrequest(print_request);
    m_callback_friendmessage(print_message);
    m_callback_namechange(print_nickchange);
    m_callback_userstatus(print_statuschange);
    char idstring1[PUB_KEY_BYTES][5];
    char idstring2[PUB_KEY_BYTES][5];
    int i;
    for(i = 0; i < PUB_KEY_BYTES; i++)
    {
        if(self_public_key[i] < (PUB_KEY_BYTES/2))
            strcpy(idstring1[i],"0");
        else 
            strcpy(idstring1[i], "");
        sprintf(idstring2[i], "%hhX",self_public_key[i]);
    }
    strcpy(users_id,"[i] your ID: ");
    int j;
    for (j = 0; j < PUB_KEY_BYTES; j++) {
        strcat(users_id,idstring1[j]);
        strcat(users_id,idstring2[j]);
    }

    do_header();
    
    IP_Port bootstrap_ip_port;
    bootstrap_ip_port.port = htons(atoi(argv[2]));
    int resolved_address = resolve_addr(argv[1]);
    if (resolved_address != 0)
        bootstrap_ip_port.ip.i = resolved_address;
    else 
        exit(1);
    
    DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));

    int c;
    int on = 0;

    _beginthread(get_input, 0, NULL);

    if (nameloaded == 1) {
        printf("\nNickname automatically loaded");
        printf("\n---------------------------------");
    }

    if (statusloaded == 1) {
        printf("\nStatus automatically loaded");
        printf("\n---------------------------------");
    }

    while(1) {
        if (on == 1 && DHT_isconnected() == -1) {
            printf("\n---------------------------------");
            printf("\n[i] Disconnected from the DHT");
            printf("\n---------------------------------\n\n");
            on = 0;
        }
        if (on == 0 && DHT_isconnected()) {
            printf("\n[i] Connected to DHT");
            printf("\n---------------------------------\n\n");
            on = 1;
        }
        doMessenger();
        Sleep(1);
    }
    return 0;
}
Exemple #8
0
void line_eval(char* line)
{
    if(line[0] == '/') {
        char inpt_command = line[1];
        /* Add friend */
        if(inpt_command == 'f') {
            int i;
            char temp_id[128];
            for (i = 0; i < 128; i++) 
                temp_id[i] = line[i+3];
            int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
            if (num >= 0) {
                char numstring[100];
                sprintf(numstring, "\n[i] Friend request sent. Wait to be accepted. Friend id: %d\n\n", num);
                printf(numstring);
            }
            else if (num == -1) 
                printf("\n[i] Message is too long.\n\n");
            else if (num == -2)
                printf("\n[i] Please add a message to your friend request.\n\n");
            else if (num == -3)
                printf("\n[i] That appears to be your own ID.\n\n");
            else if (num == -4)
                printf("\n[i] Friend request already sent.\n\n");
            else if (num == -5)
                printf("\n[i] Undefined error when adding friend\n\n");
        }

        else if (inpt_command == 'r') {
            do_header();
            printf("\n\n");
        }

        else if (inpt_command == 'l') {
            int activefriends = 0;
            int i;

            for (i = 0; i <= getnumfriends(); i++)
            {
                if (m_friendstatus(i) == 4)
                    activefriends++;
            }

            printf("\n[i] Friend List | Total: %d\n\n", activefriends);

            for (i = 0; i <= getnumfriends(); i++) {
                char name[MAX_NAME_LENGTH];
                getname(i, (uint8_t*)name);
                if (m_friendstatus(i) == 4)    
                    printf("[%d] %s\n\n", i, (uint8_t*)name);
            }
        }

        else if (inpt_command == 'd') {
            size_t len = strlen(line);
            char numstring[len-3];
            int i;
            for (i = 0; i < len; i++) {
                if (line[i+3] != ' ') {
                    numstring[i] = line[i+3];
                }
            }
            int num = atoi(numstring);
            m_delfriend(num);
            printf("\n\n");
        }
        /* Send message to friend */
        else if (inpt_command == 'm') {
            size_t len = strlen(line);
            char numstring[len-3];
            char message[len-3];
            int i;
            for (i = 0; i < len; i++) {
                if (line[i+3] != ' ') {
                    numstring[i] = line[i+3];
                } else {
                    int j;
                    for (j = (i+1); j < len; j++)
                        message[j-i-1] = line[j+3];
                    break;
                }
            }
            int num = atoi(numstring);
            if(m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) {
                printf("\n[i] could not send message (they may be offline): %s\n", message);
            } else {
                //simply for aesthetics
                printf("\n");
            }
        }

        else if (inpt_command == 'n') {
            uint8_t name[MAX_NAME_LENGTH];
            int i = 0;
            size_t len = strlen(line);
            for (i = 3; i < len; i++) {
                if (line[i] == 0 || line[i] == '\n') break;
                name[i-3] = line[i];
            }
            name[i-3] = 0;
            setname(name, i);
            char numstring[100];
            sprintf(numstring, "\n[i] changed nick to %s\n\n", (char*)name);
            printf(numstring);

            FILE *name_file = NULL;
            name_file = fopen("namefile.txt", "w");
            fprintf(name_file, "%s", (char*)name);
            fclose(name_file);
        }

        else if (inpt_command == 's') {
            uint8_t status[MAX_USERSTATUS_LENGTH];
            int i = 0;
            size_t len = strlen(line);
            for (i = 3; i < len; i++) {
                if (line[i] == 0 || line[i] == '\n') break;
                status[i-3] = line[i];
            }
            status[i-3] = 0;
            m_set_userstatus(status, strlen((char*)status));
            char numstring[100];
            sprintf(numstring, "\n[i] changed status to %s\n\n", (char*)status);
            printf(numstring);

            FILE* status_file = NULL;
            status_file = fopen("statusfile.txt", "w");
            fprintf(status_file, "%s", (char*)status);
            fclose(status_file);
        }

        else if (inpt_command == 'a') {
            uint8_t numf = atoi(line + 3);
            char numchar[100];
            sprintf(numchar, "\n[i] friend request %u accepted\n\n", numf);
            printf(numchar);
            int num = m_addfriend_norequest(pending_requests[numf]);
            sprintf(numchar, "\n[i] added friendnumber %d\n\n", num);
            printf(numchar);
        }
        /* EXIT */
        else if (inpt_command == 'q') { 
            uint8_t status[MAX_USERSTATUS_LENGTH] = "Offline";
            m_set_userstatus(status, strlen((char*)status));
            exit(EXIT_SUCCESS);
        }
    } else {
        //nothing atm
    }
}
int main(int argc, char *argv[])
{
    if (argc < 4) {
        printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]);
        exit(0);
    }

    if (initMessenger() == -1) {
        printf("initMessenger failed");
        exit(0);
    }

    
    if (argc > 4) {
        if(strncmp(argv[4], "nokey", 6) < 0) {
            //nothing
        } else {
            load_key();
        }
    }
    
    m_callback_friendrequest(print_request);
    m_callback_friendmessage(print_message);
    m_callback_namechange(print_nickchange);
    m_callback_userstatus(print_statuschange);

    system("cls");

    char idstring0[200];
    char idstring1[32][5];
    char idstring2[32][5];
    uint32_t i;
    for(i = 0; i < 32; i++)
    {
        if(self_public_key[i] < 16)
            strcpy(idstring1[i],"0");
        else 
            strcpy(idstring1[i], "");
        sprintf(idstring2[i], "%hhX",self_public_key[i]);
    }
    strcpy(idstring0,"\n[i] your ID: ");
    for (i=0; i<32; i++) {
        strcat(idstring0,idstring1[i]);
        strcat(idstring0,idstring2[i]);
    }

    printf(idstring0);
    do_header();
    

    IP_Port bootstrap_ip_port;
    bootstrap_ip_port.port = htons(atoi(argv[2]));
    int resolved_address = resolve_addr(argv[1]);
    if (resolved_address != -1)
        bootstrap_ip_port.ip.i = resolved_address;
    else 
        exit(1);
    
    DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));


    int c;
    int on = 0;

    _beginthread(get_input, 0, NULL);

    while(1) {
        if (on == 0 && DHT_isconnected()) {
            printf("\n[i] connected to DHT\n\n");
            on = 1;
        }

        doMessenger();
    }

    return 0;
}
Exemple #10
0
static void doline(struct rfc2045 *p)
{
size_t	cnt=p->workbuflen;
char *c=p->workbuf;
size_t	n=cnt-1;	/* Strip \n (we always get at least a \n here) */
struct rfc2045 *newp;
struct rfc2045ac *rwp=p->rfc2045acptr;
unsigned num_levels=0;

size_t	k;
int	bit8=0;

	if (p->numparts > MAXPARTS)
	{
		p->rfcviolation |= RFC2045_ERR2COMPLEX;
		return;
	}

	for (k=0; k<cnt; k++)
	{
		if (c[k] == 0)
			c[k]=' ';
		if (c[k] & 0x80)	bit8=1;
	}

	if (n && c[n-1] == '\r')	/* Strip trailing \r */
		--n;

	/* Before the main drill down loop before, look ahead and see if we're
	** in a middle of a form-data section.  */

	for (newp=p; newp->lastpart &&
			!newp->lastpart->workclosed; newp=newp->lastpart,
			++num_levels)
	{
		if (ContentBoundary(newp) == 0 || newp->workinheader)
			continue;

		if (newp->lastpart->informdata)
		{
			p=newp->lastpart;
			p->informdata=0;
			break;
		}
	}

	/* Drill down until we match a boundary, or until we've reached
	the last RFC2045 section that has been opened.
	*/

	while (p->lastpart)
	{
	size_t l;
	const char *cb;

		if (p->lastpart->workclosed)
		{
			update_counts(p, p->endpos+cnt, p->endpos+n, 1);
			return;
		}
		/* Leftover trash -- workclosed is set when the final
		** terminating boundary has been seen */

		/* content_boundary may be set before the entire header
		** has been seen, so continue drilling down in that case
		*/

		cb=ContentBoundary(p);

		if (cb == 0 || p->workinheader)
		{
			p=p->lastpart;
			++num_levels;
			continue;
		}

		l=strlen(cb);

		if (c[0] == '-' && c[1] == '-' && n >= 2+l &&
			strncasecmp(cb, c+2, l) == 0)
		{

			if (rwp && (!p->lastpart || !p->lastpart->isdummy))
				(*rwp->end_section)();

		/* Ok, we've found a boundary */

			if (n >= 4+l && strncmp(c+2+l, "--", 2) == 0)
			{
			/* Last boundary */

				p->lastpart->workclosed=1;
				update_counts(p, p->endpos+cnt, p->endpos+cnt,
					1);
				return;
			}

		/* Create new RFC2045 section */

			newp=append_part(p, p->endpos+cnt);
			update_counts(p, p->endpos+cnt, p->endpos+n, 1);

			/* The new RFC2045 section is MIME compliant */

			if ((newp->mime_version=strdup(p->mime_version)) == 0)
				rfc2045_enomem();
			return;
		}
		p=p->lastpart;
		++num_levels;
	}

	/* Ok, we've found the RFC2045 section that we're working with.
	** No what?
	*/

	if (! p->workinheader)
	{
		/* Processing body, just update the counts. */

	size_t cnt_update=cnt;

		if (bit8 && !p->content_8bit &&
			(p->rfcviolation & RFC2045_ERR8BITCONTENT) == 0)
		{
		struct rfc2045 *q;

			for (q=p; q; q=q->parent)
				q->rfcviolation |= RFC2045_ERR8BITCONTENT;
		}

		/*
		** In multiparts, the final newline in a part belongs to the
		** boundary, otherwise, include it in the text.
		*/
		if (p->parent && p->parent->content_type &&
				strncasecmp(p->parent->content_type,
						"multipart/", 10) == 0)
			cnt_update=n;

		if (!p->lastpart || !p->lastpart->workclosed)
		{
			if (rwp && !p->isdummy)
				(*rwp->section_contents)(c, cnt);

			update_counts(p, p->endpos+cnt, p->endpos+cnt_update,
				1);
		}
		return;
	}

	if (bit8 && (p->rfcviolation & RFC2045_ERR8BITHEADER) == 0)
	{
	struct rfc2045 *q;

		for (q=p; q; q=q->parent)
			q->rfcviolation |= RFC2045_ERR8BITHEADER;
	}

	/* In the header */

	if ( n == 0 )	/* End of header, body begins.  Parse header. */
	{
		do_header(p);	/* Clean up any left over header line */
		p->workinheader=0;

		/* Message body starts right here */

		p->startbody=p->endpos+cnt;
		update_counts(p, p->startbody, p->startbody, 1);
		--p->nbodylines;	/* Don't count the blank line */

		/* Discard content type and boundary if I don't understand
		** this MIME flavor.
		*/

		if (!RFC2045_ISMIME1(p->mime_version))
		{
			set_string(&p->content_type, 0);

			rfc2045_freeattr(p->content_type_attr);
			p->content_type_attr=0;
			set_string(&p->content_disposition, 0);
			rfc2045_freeattr(p->content_disposition_attr);
			p->content_disposition_attr=0;
			if (p->boundary)
			{
				free(p->boundary);
				p->boundary=0;
			}
		}

		/* Normally, if we don't have a content_type, default it
		** to text/plain.  However, if the multipart type is
		** multipart/digest, it is message/rfc822.
		*/

		if (RFC2045_ISMIME1(p->mime_version) && !p->content_type)
		{
		char	*q="text/plain";

			if (p->parent && p->parent->content_type &&
				strcmp(p->parent->content_type,
					"multipart/digest") == 0)
				q="message/rfc822";
			set_string(&p->content_type, q);
		}

		/* If this is not a multipart section, we don't want to
		** hear about any boundaries
		*/

		if (!p->content_type ||
			strncmp(p->content_type, "multipart/", 10))
		{
			if (p->boundary)
				free(p->boundary);
			p->boundary=0;
		}

		/* If this section's a message, we will expect to see
		** more RFC2045 stuff, so create a nested RFC2045 structure,
		** and indicate that we expect to see headers.
		*/

		if (p->content_type &&
			strcmp(p->content_type, "message/rfc822") == 0)
		{
			newp=append_part_noinherit(p, p->startbody);
			newp->workinheader=1;
			return;
		}

		/*
		** If this is a multipart message (boundary defined),
		** create a RFC2045 structure for the pseudo-section
		** that precedes the first boundary line.
		*/

		if (ContentBoundary(p))
		{
			newp=append_part(p, p->startbody);
			newp->workinheader=0;
			newp->isdummy=1;
				/* It's easier just to create it. */
			return;
		}

		if (rwp)
			(*rwp->start_section)(p);
		return;
	}

	/* RFC822 header continues */

	update_counts(p, p->endpos + cnt, p->endpos+n, 1);

	/* If this header line starts with a space, append one space
	** to the saved contents of the previous line, and append this
	** line to it.
	*/

	if (isspace((int)(unsigned char)*c))
	{
		rfc2045_add_buf(&p->header, &p->headersize, &p->headerlen, " ", 1);
	}
	else
	{
	/* Otherwise the previous header line is complete, so process it */

		do_header(p);
		p->headerlen=0;
	}

	/* Save this line in the header buffer, because the next line
	** could be a continuation.
	*/

	rfc2045_add_buf( &p->header, &p->headersize, &p->headerlen, c, n);
}