Beispiel #1
0
static bfd_boolean
check_for_whirl(char *name, bfd_boolean *is_elf)
{
    int fd = -1;
    char *raw_bits = NULL;
    int size,bufsize;
    Elf32_Ehdr *p_ehdr = NULL;
    struct stat statb;
    int test;
    
#ifdef KEY
    *is_elf = FALSE;
#endif

    fd = OPEN(name, O_RDONLY, 0755);
    if (fd < 0)
	return FALSE;

    if ((test = fstat(fd, &statb) != 0)) {
    	CLOSE(fd);
	return FALSE;
    }

    if (statb.st_size < sizeof(Elf64_Ehdr)) {
    	CLOSE(fd);
    	return FALSE;
    }
    
    bufsize = sizeof(Elf64_Ehdr);
    
    raw_bits = (char *)MALLOC(bufsize*4);
    MALLOC_ASSERT(raw_bits);

    size = READ(fd, raw_bits, bufsize);
    
		/*
		 * Check that the file is an elf executable.
		 */
    p_ehdr = (Elf32_Ehdr *)raw_bits;
    if (p_ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
	p_ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
	p_ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
	p_ehdr->e_ident[EI_MAG3] != ELFMAG3) {
	    CLOSE(fd);
	    FREE(raw_bits);
	    return(FALSE);
    }

#ifdef KEY
    *is_elf = TRUE;
#endif

    if(p_ehdr->e_ident[EI_CLASS] == ELFCLASS32){
    	Elf32_Ehdr *p32_ehdr = (Elf32_Ehdr *)raw_bits;
	if (p32_ehdr->e_type == ET_SGI_IR) {
	    CLOSE(fd);
	    FREE(raw_bits);
	    return TRUE;
	}
    }
    else {
	Elf64_Ehdr *p64_ehdr = (Elf64_Ehdr *)raw_bits;
	if (p64_ehdr->e_type == ET_SGI_IR) {
	    CLOSE(fd);
	    FREE(raw_bits);
	    return TRUE;
	}
     }

    CLOSE(fd);
    FREE(raw_bits);
    return FALSE;
    
 }
Beispiel #2
0
int
main(int argc, char *argv[])
{
	int fd;
	size_t mapped_len;
	char *dest;
	char *dest1;
	char *ret;

	START(argc, argv, "pmem_memset");

	if (argc != 4)
		UT_FATAL("usage: %s file offset length", argv[0]);

	fd = OPEN(argv[1], O_RDWR);

	/* open a pmem file and memory map it */
	if ((dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL)) == NULL)
		UT_FATAL("!Could not mmap %s\n", argv[1]);

	int dest_off = atoi(argv[2]);
	size_t bytes = strtoul(argv[3], NULL, 0);

	char *buf = MALLOC(bytes);

	memset(dest, 0, bytes);
	util_persist_auto(util_fd_is_device_dax(fd), dest, bytes);
	dest1 = MALLOC(bytes);
	memset(dest1, 0, bytes);

	/*
	 * This is used to verify that the value of what a non persistent
	 * memset matches the outcome of the persistent memset. The
	 * persistent memset will match the file but may not be the
	 * correct or expected value.
	 */
	memset(dest1 + dest_off, 0x5A, bytes / 4);
	memset(dest1 + dest_off  + (bytes / 4), 0x46, bytes / 4);

	/* Test the corner cases */
	ret = pmem_memset_persist(dest + dest_off, 0x5A, 0);
	UT_ASSERTeq(ret, dest + dest_off);
	UT_ASSERTeq(*(char *)(dest + dest_off), 0);

	/*
	 * Do the actual memset with persistence.
	 */
	ret = pmem_memset_persist(dest + dest_off, 0x5A, bytes / 4);
	UT_ASSERTeq(ret, dest + dest_off);
	ret = pmem_memset_persist(dest + dest_off  + (bytes / 4),
					0x46, bytes / 4);
	UT_ASSERTeq(ret, dest + dest_off + (bytes / 4));

	if (memcmp(dest, dest1, bytes / 2))
		UT_ERR("%s: first %zu bytes do not match",
			argv[1], bytes / 2);

	LSEEK(fd, (off_t)0, SEEK_SET);
	if (READ(fd, buf, bytes / 2) == bytes / 2) {
		if (memcmp(buf, dest, bytes / 2))
			UT_ERR("%s: first %zu bytes do not match",
				argv[1], bytes / 2);
	}

	UT_ASSERTeq(pmem_unmap(dest, mapped_len), 0);

	FREE(dest1);
	FREE(buf);
	CLOSE(fd);

	DONE(NULL);
}
Beispiel #3
0
/** Execute a command with arguments in a chroot.
 * @param handle the context handle
 * @param cmd command to execute
 * @param argv arguments to pass to cmd
 * @return 0 on success, 1 on error
 */
int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[])
{
	pid_t pid;
	int pipefd[2], cwdfd;
	int retval = 0;

	/* save the cwd so we can restore it later */
	OPEN(cwdfd, ".", O_RDONLY);
	if(cwdfd < 0) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
	}

	/* just in case our cwd was removed in the upgrade operation */
	if(chdir(handle->root) != 0) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
				handle->root, strerror(errno));
		goto cleanup;
	}

	_alpm_log(handle, ALPM_LOG_DEBUG, "executing \"%s\" under chroot \"%s\"\n",
			cmd, handle->root);

	/* Flush open fds before fork() to avoid cloning buffers */
	fflush(NULL);

	if(pipe(pipefd) == -1) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not create pipe (%s)\n"), strerror(errno));
		retval = 1;
		goto cleanup;
	}

	/* fork- parent and child each have seperate code blocks below */
	pid = fork();
	if(pid == -1) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not fork a new process (%s)\n"), strerror(errno));
		retval = 1;
		goto cleanup;
	}

	if(pid == 0) {
		/* this code runs for the child only (the actual chroot/exec) */
		CLOSE(1);
		CLOSE(2);
		while(dup2(pipefd[1], 1) == -1 && errno == EINTR);
		while(dup2(pipefd[1], 2) == -1 && errno == EINTR);
		CLOSE(pipefd[0]);
		CLOSE(pipefd[1]);

		/* use fprintf instead of _alpm_log to send output through the parent */
		if(chroot(handle->root) != 0) {
			fprintf(stderr, _("could not change the root directory (%s)\n"), strerror(errno));
			exit(1);
		}
		if(chdir("/") != 0) {
			fprintf(stderr, _("could not change directory to %s (%s)\n"),
					"/", strerror(errno));
			exit(1);
		}
		umask(0022);
		execv(cmd, argv);
		/* execv only returns if there was an error */
		fprintf(stderr, _("call to execv failed (%s)\n"), strerror(errno));
		exit(1);
	} else {
		/* this code runs for the parent only (wait on the child) */
		int status;
		FILE *pipe_file;

		CLOSE(pipefd[1]);
		pipe_file = fdopen(pipefd[0], "r");
		if(pipe_file == NULL) {
			CLOSE(pipefd[0]);
			retval = 1;
		} else {
			while(!feof(pipe_file)) {
				char line[PATH_MAX];
				if(fgets(line, PATH_MAX, pipe_file) == NULL)
					break;
				alpm_logaction(handle, "%s", line);
				EVENT(handle, ALPM_EVENT_SCRIPTLET_INFO, line, NULL);
			}
			fclose(pipe_file);
		}

		while(waitpid(pid, &status, 0) == -1) {
			if(errno != EINTR) {
				_alpm_log(handle, ALPM_LOG_ERROR, _("call to waitpid failed (%s)\n"), strerror(errno));
				retval = 1;
				goto cleanup;
			}
		}

		/* report error from above after the child has exited */
		if(retval != 0) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("could not open pipe (%s)\n"), strerror(errno));
			goto cleanup;
		}
		/* check the return status, make sure it is 0 (success) */
		if(WIFEXITED(status)) {
			_alpm_log(handle, ALPM_LOG_DEBUG, "call to waitpid succeeded\n");
			if(WEXITSTATUS(status) != 0) {
				_alpm_log(handle, ALPM_LOG_ERROR, _("command failed to execute correctly\n"));
				retval = 1;
			}
		}
	}

cleanup:
	if(cwdfd >= 0) {
		if(fchdir(cwdfd) != 0) {
			_alpm_log(handle, ALPM_LOG_ERROR,
					_("could not restore working directory (%s)\n"), strerror(errno));
		}
		CLOSE(cwdfd);
	}

	return retval;
}
Beispiel #4
0
int32_t drn_open(drn_t * cache, const char * filename, int mode)
{
    int fd = OPEN(filename, OPEN_MODE);
    if (fd <=0)
    {
        return -1;
    }
    cache->fd = fd;
    cache->mmap_size = drn_fsize(fd);
    cache->mode = mode;
    if (mode == DRN_READ_NOLOAD)
    {
        uint64_t i;
        size_t bytes;
        drn_desc_t hashes_desc;
        drn_map_container_t * map_containers;

        cache->mmap_start = 0;
        cache->data = 0;
        cache->header = ALLOCATE(sizeof(drn_header_container_t));
        bytes = READ(fd, cache->header, sizeof(drn_header_container_t));
        assert(bytes == sizeof(drn_header_container_t));
        if (drn_get_version(cache) != DRN_WRITER_VERSION)
            return 1;
        cache->descriptors = ALLOCATE(cache->header->chunk_count * sizeof(drn_desc_t));
        LSEEK(fd, cache->header->index_offset, SEEK_SET);
        bytes = READ(fd, cache->descriptors, READ_COUNT_CAST ((size_t) cache->header->chunk_count) * sizeof(drn_desc_t));
        assert(bytes == cache->header->chunk_count * sizeof(drn_desc_t));

        hashes_desc =  drn_get_desc(cache, cache->header->maps_chunk_id);
        cache->map_count = hashes_desc.size / sizeof(drn_map_container_t);
        cache->maps = ALLOCATE(sizeof(drn_map_t) * (size_t) cache->map_count);
        map_containers = ALLOCATE(hashes_desc.size);
        drn_read_chunk(cache, cache->header->maps_chunk_id, map_containers);
        for (i = 0; i < cache->map_count; ++i)
        {
            drn_desc_t d;
            const drn_map_container_t * c = map_containers + i;
            drn_map_t * h = cache->maps + i;

            h->hash = ALLOCATE(drn_get_desc(cache, c->hash_chunk_id).size);
            drn_read_chunk(cache, c->hash_chunk_id, (void *) h->hash);
            h->name = ALLOCATE(drn_get_desc(cache, c->name_chunk_id).size);
            drn_read_chunk(cache, c->name_chunk_id, (void *) h->name);
            d = drn_get_desc(cache, c->descriptors_chunk_id);
            h->chunk_count = d.size / sizeof(drn_hash_desc_t);
            h->descriptors = ALLOCATE(d.size);
            drn_read_chunk(cache, c->descriptors_chunk_id, (void *) h->descriptors);
            h->value_strings = ALLOCATE(drn_get_desc(cache, c->value_strings_chunk_id).size);
            drn_read_chunk(cache, c->value_strings_chunk_id, (void *)h->value_strings);
        }
        FREE(map_containers);
    }
    else
    {
        uint64_t i;
        drn_desc_t maps_desc;
        drn_map_container_t * map_containers;

        if (mode == DRN_READ_MMAP)
        {
#ifdef _MSC_VER
			wchar_t * w_filename;
			size_t bytes;

			CLOSE(fd);
			w_filename = ALLOCATE((strlen(filename)+1) * sizeof(wchar_t));
			bytes = mbstowcs(w_filename, filename, strlen(filename)+1);
			//cache->w_fhandle = CreateFile(L"test.drn", GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
			cache->w_fhandle = CreateFile(w_filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
			FREE(w_filename);
			if ((int) cache->w_fhandle  == HFILE_ERROR)
			{
				DWORD err = GetLastError();
				printf("ERROR %Ld\n", err);
				return -1;
			}
			cache->w_mhandle = CreateFileMapping(cache->w_fhandle, NULL, PAGE_READONLY, 0, 0, NULL);
			if (cache->w_mhandle  == NULL)
			{
				DWORD err = GetLastError();
				return -1;
			}
			cache->mmap_start = MapViewOfFile(cache->w_mhandle, FILE_MAP_READ, 0, 0, (size_t) cache->mmap_size);
			if (cache->mmap_start  == NULL)
			{
				DWORD err = GetLastError();
				return -1;
			}
#else
            cache->mmap_start = mmap(0, cache->mmap_size, PROT_READ, MAP_PRIVATE, fd, 0);
			CLOSE(fd);
#endif
        }
        else if (mode == DRN_READ_LOAD)
        {
            size_t bytes;

            cache->mmap_start = ALLOCATE(cache->mmap_size);
            bytes = READ(fd, cache->mmap_start, READ_COUNT_CAST (size_t) cache->mmap_size);
            assert(bytes == cache->mmap_size);
			CLOSE(fd);
        }
        cache->data = (char *) cache->mmap_start + sizeof(drn_header_container_t);
        cache->header = (drn_header_container_t *) cache->mmap_start;
        if (drn_get_version(cache) != DRN_WRITER_VERSION)
            return 1;
        cache->descriptors = (drn_desc_t *) ((char *)cache->mmap_start + cache->header->index_offset);
        maps_desc =  drn_get_desc(cache, cache->header->maps_chunk_id);
        cache->map_count = maps_desc.size / sizeof(drn_map_container_t);
        map_containers = (drn_map_container_t *) drn_get_chunk(cache, cache->header->maps_chunk_id);
        cache->maps = ALLOCATE(sizeof(drn_map_t) * (size_t) cache->map_count);
        for (i = 0; i < cache->map_count; ++i)
        {
            drn_desc_t d;
            const drn_map_container_t * c = map_containers + i;
            drn_map_t * h = cache->maps + i;

            h->hash =  drn_get_chunk(cache, c->hash_chunk_id);
            h->name =  drn_get_chunk(cache, c->name_chunk_id);
            d = drn_get_desc(cache, c->descriptors_chunk_id);
            h->chunk_count = d.size / sizeof(drn_hash_desc_t);
            h->descriptors =  drn_get_chunk(cache, c->descriptors_chunk_id);
            h->value_strings =  drn_get_chunk(cache, c->value_strings_chunk_id);
        }
    }
    return 0;
}
/* goodB2G() uses the BadSource with the GoodSink */
static void goodB2GSource(int &data)
{
    /* POTENTIAL FLAW: Open a file - need to make sure it is closed properly in the sink */
    data = OPEN("BadSource_open.txt", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
}
void bad()
{
    wchar_t * data;
    wchar_t * &dataRef = data;
    wchar_t dataBuffer[FILENAME_MAX] = BASEPATH;
    data = dataBuffer;
    {
#ifdef _WIN32
        WSADATA wsaData;
        int wsaDataInit = 0;
#endif
        int recvResult;
        struct sockaddr_in service;
        wchar_t *replace;
        SOCKET listenSocket = INVALID_SOCKET;
        SOCKET acceptSocket = INVALID_SOCKET;
        size_t dataLen = wcslen(data);
        do
        {
#ifdef _WIN32
            if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
            {
                break;
            }
            wsaDataInit = 1;
#endif
            /* POTENTIAL FLAW: Read data using a listen socket */
            listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            if (listenSocket == INVALID_SOCKET)
            {
                break;
            }
            memset(&service, 0, sizeof(service));
            service.sin_family = AF_INET;
            service.sin_addr.s_addr = INADDR_ANY;
            service.sin_port = htons(TCP_PORT);
            if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR)
            {
                break;
            }
            if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR)
            {
                break;
            }
            acceptSocket = accept(listenSocket, NULL, NULL);
            if (acceptSocket == SOCKET_ERROR)
            {
                break;
            }
            /* Abort on error or the connection was closed */
            recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (FILENAME_MAX - dataLen - 1), 0);
            if (recvResult == SOCKET_ERROR || recvResult == 0)
            {
                break;
            }
            /* Append null terminator */
            data[dataLen + recvResult / sizeof(wchar_t)] = L'\0';
            /* Eliminate CRLF */
            replace = wcschr(data, L'\r');
            if (replace)
            {
                *replace = L'\0';
            }
            replace = wcschr(data, L'\n');
            if (replace)
            {
                *replace = L'\0';
            }
        }
        while (0);
        if (listenSocket != INVALID_SOCKET)
        {
            CLOSE_SOCKET(listenSocket);
        }
        if (acceptSocket != INVALID_SOCKET)
        {
            CLOSE_SOCKET(acceptSocket);
        }
#ifdef _WIN32
        if (wsaDataInit)
        {
            WSACleanup();
        }
#endif
    }
    {
        wchar_t * data = dataRef;
        {
            int fileDesc;
            /* POTENTIAL FLAW: Possibly opening a file without validating the file name or path */
            fileDesc = OPEN(data, O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
            if (fileDesc != -1)
            {
                CLOSE(fileDesc);
            }
        }
    }
}
Beispiel #7
0
int
main(int argc, char *argv[])
{
	int fd;
	struct stat stbuf;
	void *dest;
	void *src;
	off_t dest_off = 0;
	off_t src_off = 0;
	uint64_t bytes = 0;
	int who = 0;
	off_t overlap = 0;

	START(argc, argv, "pmem_memmove");

	fd = OPEN(argv[1], O_RDWR);
	FSTAT(fd, &stbuf);

	if (argc < 3)
		USAGE();

	for (int arg = 2; arg < argc; arg++) {
		if (strchr("dsboS",
		    argv[arg][0]) == NULL || argv[arg][1] != ':')
			FATAL("op must be d: or s: or b: or o: or S:");

		off_t val = strtoul(&argv[arg][2], NULL, 0);

		switch (argv[arg][0]) {
		case 'd':
			if (val <= 0)
				FATAL("bad offset (%lu) with d: option", val);
			dest_off = val;
			break;

		case 's':
			if (val <= 0)
				FATAL("bad offset (%lu) with s: option", val);
			src_off = val;
			break;

		case 'b':
			if (val <= 0)
				FATAL("bad length (%lu) with b: option", val);
			bytes = val;
			break;

		case 'o':
			if (val != 1 && val != 2)
				FATAL("bad val (%lu) with o: option", val);
			who = (int)val;
			break;

		case 'S':
			overlap = val;
			break;
		}
	}

	if (who == 0 && overlap != 0)
		USAGE();

	/* for overlap the src and dest must be created differently */
	if (who == 0) {
		/* src > dest */
		dest = pmem_map(fd);
		if (dest == NULL)
			FATAL("!could not mmap dest file %s", argv[1]);

		src = MMAP(dest + stbuf.st_size, stbuf.st_size,
			PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
			-1, 0);
		/*
		 * Its very unlikely that src would not be > dest. pmem_map
		 * chooses the first unused address >= 1TB, large
		 * enough to hold the give range, and 1GB aligned. Log
		 * the error if the mapped addresses cannot be swapped
		 * but allow the test to continue.
		 */
		if (src <= dest) {
			swap_mappings(&dest, &src, stbuf.st_size, fd);
			if (src <= dest)
				ERR("cannot map files in memory order");
		}

		do_memmove(fd, dest, src, argv[1], dest_off, src_off,
			0, bytes);

		/* dest > src */
		swap_mappings(&dest, &src, stbuf.st_size, fd);

		if (dest <= src)
			ERR("cannot map files in memory order");

		do_memmove(fd, dest, src, argv[1], dest_off, src_off, 0,
			bytes);
		MUNMAP(dest, stbuf.st_size);
		MUNMAP(src, stbuf.st_size);
	} else if (who == 1) {
		/* src overlap with dest */
		dest = pmem_map(fd);
		if (dest == NULL)
			FATAL("!Could not mmap %s: \n", argv[1]);

		src = dest + overlap;
		memset(dest, 0, bytes);
		do_memmove(fd, dest, src, argv[1], dest_off, src_off,
			overlap, bytes);
		MUNMAP(dest, stbuf.st_size);
	} else {
		/* dest overlap with src */
		dest = pmem_map(fd);
		if (dest == NULL) {
			FATAL("!Could not mmap %s: \n", argv[1]);
		}
		src = dest;
		dest = src + overlap;
		memset(src, 0, bytes);
		do_memmove(fd, dest, src, argv[1], dest_off, src_off,
			overlap, bytes);
		MUNMAP(src, stbuf.st_size);
	}

	CLOSE(fd);

	DONE(NULL);
}
Beispiel #8
0
bool QFile::open( int m )
{
    if ( isOpen() ) {				// file already open
#if defined(CHECK_STATE)
	qWarning( "QFile::open: File already open" );
#endif
	return FALSE;
    }
    if ( fn.isNull() ) {			// no file name defined
#if defined(CHECK_NULL)
	qWarning( "QFile::open: No file name specified" );
#endif
	return FALSE;
    }
    init();					// reset params
    setMode( m );
    if ( !(isReadable() || isWritable()) ) {
#if defined(CHECK_RANGE)
	qWarning( "QFile::open: File access not specified" );
#endif
	return FALSE;
    }
    bool ok = TRUE;
    STATBUF st;
    if ( isRaw() ) {				// raw file I/O
	int oflags = OPEN_RDONLY;
	if ( isReadable() && isWritable() )
	    oflags = OPEN_RDWR;
	else if ( isWritable() )
	    oflags = OPEN_WRONLY;
	if ( flags() & IO_Append ) {		// append to end of file?
	    if ( flags() & IO_Truncate )
		oflags |= (OPEN_CREAT | OPEN_TRUNC);
	    else
		oflags |= (OPEN_APPEND | OPEN_CREAT);
	    setFlags( flags() | IO_WriteOnly ); // append implies write
	} else if ( isWritable() ) {		// create/trunc if writable
	    if ( flags() & IO_Truncate )
		oflags |= (OPEN_CREAT | OPEN_TRUNC);
	    else
		oflags |= OPEN_CREAT;
	}
#if defined(HAS_TEXT_FILEMODE)
	if ( isTranslated() )
	    oflags |= OPEN_TEXT;
	else
	    oflags |= OPEN_BINARY;
#endif
#if defined(HAS_ASYNC_FILEMODE)
	if ( isAsynchronous() )
	    oflags |= OPEN_ASYNC;
#endif
	fd = OPEN( QFile::encodeName(fn), oflags, 0666 );

	if ( fd != -1 ) {			// open successful
	    FSTAT( fd, &st ); // get the stat for later usage
	} else {
	    ok = FALSE;
	}
    } else {					// buffered file I/O
	QCString perm;
	char perm2[4];
	bool try_create = FALSE;
	if ( flags() & IO_Append ) {		// append to end of file?
	    setFlags( flags() | IO_WriteOnly ); // append implies write
	    perm = isReadable() ? "a+" : "a";
	} else {
	    if ( isReadWrite() ) {
		if ( flags() & IO_Truncate ) {
		    perm = "w+";
		} else {
		    perm = "r+";
		    try_create = TRUE;		// try to create if not exists
		}
	    } else if ( isReadable() ) {
		perm = "r";
	    } else if ( isWritable() ) {
		perm = "w";
	    }
	}
	qstrcpy( perm2, perm );
#if defined(HAS_TEXT_FILEMODE)
	if ( isTranslated() )
	    strcat( perm2, "t" );
	else
	    strcat( perm2, "b" );
#endif
	while (1) { // At most twice

	    fh = fopen( QFile::encodeName(fn), perm2 );

	    if ( !fh && try_create ) {
		perm2[0] = 'w';			// try "w+" instead of "r+"
		try_create = FALSE;
	    } else {
		break;
	    }
	}
	if ( fh ) {
	    FSTAT( FILENO(fh), &st ); // get the stat for later usage
	} else {
	    ok = FALSE;
	}
    }
    if ( ok ) {
	setState( IO_Open );
	// on successful open the file stat was got; now test what type
	// of file we have
	if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
	    // non-seekable
	    setType( IO_Sequential );
	    length = INT_MAX;
	    ioIndex  = (flags() & IO_Append) == 0 ? 0 : length;
	} else {
	    length = (int)st.st_size;
	    ioIndex  = (flags() & IO_Append) == 0 ? 0 : length;
	    if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
		// try if you can read from it (if you can, it's a sequential
		// device; e.g. a file in the /proc filesystem)
		int c = getch();
		if ( c != -1 ) {
		    ungetch(c);
		    setType( IO_Sequential );
		    length = INT_MAX;
		}
	    }
	}
    } else {
	init();
	if ( errno == EMFILE )			// no more file handles/descrs
	    setStatus( IO_ResourceError );
	else
	    setStatus( IO_OpenError );
    }
    return ok;
}
Beispiel #9
0
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <stdint.h>
#include "zlex.h"
#include "kernel.h"

zkernel()
{
/* redefinition of the syntax */

OPEN(stat) M("/") GSB(lvalue) M("->") GSB($thread) GSB($action) 
      PROC(z_link_rule_default) END
OPEN(stat) M("/(") GSB(lvalue) M(")") GSB(ident) M("->") GSB($thread) 
  GSB($action) PROC(z_link_rule) END

/* action */
OPEN($action) END
OPEN($action) GSB(list) PROC(z_set_action) END
OPEN($action) M("{") GSB($ablock) M("}") PROC(z_set_action) END
OPEN($action) M(":") GSB(ident) PROC(z_set_action) END
OPEN($action) M(":return") GSB($arg) PROC(z_set_return_action) END
OPEN($action) M(":return") GSB($arg)M("as") GSB(ident)
   PROC(z_set_return_action)END

/* execute the action when last rule defined is re-defined */
OPEN(stat) M("/when change action") GSB(list_e) 
Beispiel #10
0
void mupip_upgrade(void)
{
	bool		rbno;
	unsigned char 	*upgrd_buff[2], upgrd_label[GDS_LABEL_SZ]="UPGRADE0304";
	char		fn[256];
	char		answer[4];
	unsigned short	fn_len;
	int4		fd, save_errno, old_hdr_size, new_hdr_size, status, bufsize, dsize, datasize[2];
	int4            old_hdr_size_vbn, new_hdr_size_vbn;
	int		fstat_res;
	off_t 		last_full_grp_startoff, old_file_len, old_file_len2, read_off, write_off, old_start_vbn_off;
	block_id	last_full_grp_startblk;
	v3_sgmnt_data	old_head_data, *old_head;
	sgmnt_data	new_head_data, *new_head;
 	struct stat    	stat_buf;

	error_def(ERR_MUNODBNAME);
	error_def(ERR_MUNOUPGRD);
	error_def(ERR_DBOPNERR);
	error_def(ERR_DBRDONLY);
	error_def(ERR_DBFILOPERR);
	error_def(ERR_DBPREMATEOF);

	ESTABLISH(mupip_upgrade_ch);
	fn_len = sizeof(fn);
	if (!cli_get_str("FILE", fn, &fn_len))
		rts_error(VARLSTCNT(1) ERR_MUNODBNAME);
	if (!(mupip_upgrade_standalone(fn, &upgrade_standalone_sems)))
		rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
	if (-1 == (fd = OPEN(fn, O_RDWR)))
	{
		save_errno = errno;
		if (-1 != (fd = OPEN(fn, O_RDONLY)))
		{
			util_out_print("Cannot update read-only database.", FLUSH);
			rts_error(VARLSTCNT(5) ERR_DBRDONLY, 2, fn_len, fn, errno);
		}
		rts_error(VARLSTCNT(5) ERR_DBRDONLY, 2, fn_len, fn, save_errno);
	}
	/* Confirm before proceed */
	if (!mu_upgrd_confirmed(TRUE))
	{
		util_out_print("Upgrade canceled by user", FLUSH);
		rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
	}
	util_out_print("Do not interrupt to avoid damage in database!!", FLUSH);
	util_out_print("Mupip upgrade started ...!/", FLUSH);
	mu_upgrd_sig_init();
	/* get file status */
	FSTAT_FILE(fd, &stat_buf, fstat_res);
	if (-1 == fstat_res)
		rts_error(VARLSTCNT(5) ERR_DBOPNERR, 2, fn_len, fn, errno);
	old_file_len = stat_buf.st_size;

	/* Prepare v3.x file header buffer */
	old_hdr_size  = sizeof(*old_head);
	old_head = &old_head_data;
	/* Prepare v4.x file header buffer */
	new_hdr_size = sizeof(*new_head);
	new_head = &new_head_data;
	memset(new_head, 0, new_hdr_size);
	old_hdr_size_vbn = DIVIDE_ROUND_UP(old_hdr_size, DISK_BLOCK_SIZE);
	new_hdr_size_vbn = DIVIDE_ROUND_UP(new_hdr_size, DISK_BLOCK_SIZE);
	/* READ header from V3.x file */
	LSEEKREAD(fd, 0, old_head, old_hdr_size, status);
	if (0 != status)
		if (-1 == status)
			rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
		else
			rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
	/* Check version */
	if (memcmp(&old_head->label[0], GDS_LABEL, GDS_LABEL_SZ - 1))
	{
		if (memcmp(&old_head->label[0], GDS_LABEL, GDS_LABEL_SZ - 3))
		{	/* it is not a GTM database */
			close(fd);
			util_out_print("File !AD is not a GT.M database.!/", FLUSH, fn_len, fn);
			rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
		}else
		{	/* it is GTM database */
			/* is it not v3.x database?  */
			if (memcmp(&old_head->label[GDS_LABEL_SZ - 3],GDS_V30,2) !=0  &&
		   	    memcmp(&old_head->label[GDS_LABEL_SZ - 3],GDS_ALT_V30,2) != 0)
			{
				close(fd);
				util_out_print("File !AD has an unrecognized database version!/", FLUSH, fn_len, fn);
				rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
			}
		}
	}
	else
	{	/* Note: We assume that if the V4.x header and current GT.M file header
		 *       has same field names, they are at same offset */
		/* READ the header from file again as V4.x header */
                LSEEKREAD(fd, 0, new_head, new_hdr_size, status);
                if (0 != status)
			if (-1 != status)
				rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
			else
				rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
                if (QWNE(new_head->reg_seqno, seq_num_zero) ||
                    QWNE(new_head->resync_seqno, seq_num_zero) ||
                    (new_head->resync_tn != 0) ||
                    new_head->repl_state != repl_closed)
                {
                        util_out_print("!AD might already have been upgraded", FLUSH, fn_len, fn);
                        util_out_print("Do you wish to continue with the upgrade? [y/n] ", FLUSH);
                        SCANF("%s", answer);
                        if (answer[0] != 'y' && answer[0] != 'Y')
                        {
                                close(fd);
                                util_out_print("Upgrade canceled by user", FLUSH);
                                rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
                        }
                }
                init_replication(new_head);
		new_head->max_update_array_size = new_head->max_non_bm_update_array_size
                                       = ROUND_UP2(MAX_NON_BITMAP_UPDATE_ARRAY_SIZE(new_head), UPDATE_ARRAY_ALIGN_SIZE);
		new_head->max_update_array_size += ROUND_UP2(MAX_BITMAP_UPDATE_ARRAY_SIZE, UPDATE_ARRAY_ALIGN_SIZE);
		new_head->mutex_spin_parms.mutex_hard_spin_count = MUTEX_HARD_SPIN_COUNT;
		new_head->mutex_spin_parms.mutex_sleep_spin_count = MUTEX_SLEEP_SPIN_COUNT;
		new_head->mutex_spin_parms.mutex_spin_sleep_mask = MUTEX_SPIN_SLEEP_MASK;
		new_head->semid = INVALID_SEMID;
		new_head->shmid = INVALID_SHMID;
		if (JNL_ALLOWED(new_head))
		{	/* Following 3 are new fields starting from V43001.
			 * Initialize them appropriately.
			 */
			new_head->epoch_interval = DEFAULT_EPOCH_INTERVAL;
			new_head->alignsize = DISK_BLOCK_SIZE * JNL_DEF_ALIGNSIZE;
			if (!new_head->jnl_alq)
				new_head->jnl_alq = JNL_ALLOC_DEF;
			/* note new_head->jnl_deq is carried over without any change even if it is zero since a zero
			 * jnl file extension size is supported starting V43001
			 */
			new_head->autoswitchlimit = ALIGNED_ROUND_DOWN(JNL_ALLOC_MAX, new_head->jnl_alq, new_head->jnl_deq);
			/* following field is assumed as non-zero by set_jnl_info starting V43001A */
			if (JNL_ALLOWED(new_head) && !new_head->jnl_buffer_size)
				new_head->jnl_buffer_size = JNL_BUFFER_DEF;
		} else
		{
			new_head->epoch_interval = 0;
			new_head->alignsize = 0;
			new_head->autoswitchlimit = 0;
		}
		new_head->yield_lmt = DEFAULT_YIELD_LIMIT;
                /* writing header */
                LSEEKWRITE(fd, 0, new_head, new_hdr_size, status);
                if (0 != status)
                        rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
                close(fd);
                util_out_print("File !AD successfully upgraded.!/", FLUSH, fn_len, fn);
		if (0 != sem_rmid(upgrade_standalone_sems))
		{
			util_out_print("Error with sem_rmid : %d [0x%x]", TRUE, upgrade_standalone_sems, upgrade_standalone_sems);
			rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
		}
                mupip_exit(SS_NORMAL);
	}
	util_out_print("Old header size: !SL", FLUSH, old_hdr_size);
	util_out_print("New header size: !SL", FLUSH, new_hdr_size);
	if (old_head->createinprogress)
	{
		close(fd);
		util_out_print("Database creation in progress on file !AD.!/", FLUSH, fn_len, fn);
		rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
	}
	if (old_head->file_corrupt)
	{
		close(fd);
		util_out_print("Database !AD is corrupted.!/", FLUSH, fn_len, fn);
		rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
	}
	if ((((off_t)old_head->start_vbn - 1) * DISK_BLOCK_SIZE +
		(off_t)old_head->trans_hist.total_blks * old_head->blk_size + (off_t)DISK_BLOCK_SIZE != old_file_len) &&
	   (((off_t)old_head->start_vbn - 1) * DISK_BLOCK_SIZE +
		(off_t)old_head->trans_hist.total_blks * old_head->blk_size + (off_t)old_head->blk_size != old_file_len))
	{
		util_out_print("Incorrect start_vbn !SL or, block size !SL or, total blocks !SL",
			FLUSH, old_head->start_vbn, old_head->blk_size, old_head->trans_hist.total_blks);
		rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
	}
	if (ROUND_DOWN(old_head->blk_size, DISK_BLOCK_SIZE) != old_head->blk_size)
	{
		util_out_print("Database block size !SL is not divisible by DISK_BLOCK_SIZE", FLUSH, old_head->blk_size);
		rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
	}
        mu_upgrd_header(old_head, new_head); /* Update header from v3.x to v4.x  */
        new_head->start_vbn = new_hdr_size_vbn + 1;
        new_head->free_space = 0;
        new_head->wc_blocked_t_end_hist.evnt_cnt = old_head->wc_blocked_t_end_hist2.evnt_cnt;
        new_head->wc_blocked_t_end_hist.evnt_tn  = old_head->wc_blocked_t_end_hist2.evnt_tn;
        init_replication(new_head);
	/*
	   A simple way of doing mupip upgrade is to move all the data after file header
	   towards the eof to make space and write down the header. This does not need any
	   computation or, change in data/index blocks.  This is a slow process because it
	   has mainly I/O, though no manipulation of database structures.  or index blocks.
	   This is okay for small database.

	   A time efficient way is to physically move second group of BLKS_PER_LMAP number of
	   blocks towards the eof and move first group of BLKS_PER_LMAP number of blocks in
	   place of 2nd group. Finally adjust all indices to point to the blocks correctly.
	   Also adjust master bit map.
	   (note: we cannot move first group from the beginning).

	   Detail algorithm as follows:
	   ---------------------------
	   // Allocate two buffers each to hold one group of data.
	   Read v3.x header and upgrade to v4.x
	   if file is big enough
	  	read group 1 in buff[0]
	   	read_off = offset of starting block of 2nd group.
	  	read group 2 in buff[1]
		write buff[0] at offset read_off

	        last_full_grp_startblk = points to the block where 2nd group of 512 blocks
			of old file will be written back.
		//Instead of searching for a free group we will write at the last full group
		//Say, we have 3000 blocks.  last_full_grp_startblk = 2048
		//			     (not 2560, because it is not full)
		//All data from that point upto eof will be read and saved in buffer
		read all remaining data from the point last_full_grp_startblk upto eof in buff[0]
		write buff[1] at the point of last_full_grp_startblk
		Now write buff[0] at the end of last write
		//Graphical Example: Each letter corresponds to a group of 512 blocks where first block
		// 	is local bit map. Last group U may be a group of less than 512 blocks.
		//      Extend towards right ------------------------------------------------------->
		//	old permutation:    [v3 head]  A B C D E F G H   I J K L M N O P  Q R S T U
		//	new permutation:    [v4 head ]   A C D E F G H   I J K L M N O P  Q R S T B U
		Finally traverse the tree and adjust block pointers
		Adjust master map
		write new v4.x header at bof

	    else
	    	bufsize = size of data for a group
		rbno = 0    // read buffer no. This switches between 0 and 1
		read_off = 0
		write_off = 0
		upgrd_buff[rbno] = new header
		data_size[rbno] = new header size
		rbno = INVERT(rbno);
		do while not eof
			data_size[rbno] = MIN(bufsize, remaining_data_size)
			Read data of size data_size[rbno] in upgrd_buff[rbno] and adjust read_off
			rbno = INVERT(rbno);
			Write upgrd_buff[rbno] of datasize[rbno] at write_off and increase write_off
		Enddo
		rbno = INVERT(rbno)
		Write upgrd_buff[rbno] of datasize[rbno] at write_off
	    endif
	*/
	bufsize = old_head->blk_size * BLKS_PER_LMAP;
	upgrd_buff[0] = (unsigned char*) malloc(bufsize);
	upgrd_buff[1] = (unsigned char*) malloc(bufsize);
	read_off =  old_start_vbn_off = (off_t)(old_head->start_vbn - 1) * DISK_BLOCK_SIZE; /* start vbn offset in bytes */
	last_full_grp_startblk = ROUND_DOWN(new_head->trans_hist.total_blks, BLKS_PER_LMAP); /* in block_id */
	last_full_grp_startoff = old_start_vbn_off + (off_t)last_full_grp_startblk * new_head->blk_size; /* offset in bytes */
	/* this calculation is used because some 3.2x database has GDS blk_size bytes at the end
	   instead of DISK_BLOCK_SIZE bytes. */
	old_file_len2 = old_head->start_vbn * DISK_BLOCK_SIZE + (off_t)old_head->blk_size * old_head->trans_hist.total_blks;
	/* Change Label to a temporary dummy value, so that other GTM process does not come
	while doing upgrade and corrupts database */
	LSEEKWRITE(fd, 0, upgrd_label, GDS_LABEL_SZ - 1, status);
	if (0 != status)
		rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
	if (old_head->trans_hist.total_blks > BLKS_PER_LMAP * 2)
	{
		/* recalculate start_vbn and free space, because there will be a gap after header */
		new_head->start_vbn = old_head->start_vbn + bufsize / DISK_BLOCK_SIZE;
		new_head->free_space = bufsize - (new_hdr_size_vbn - old_hdr_size_vbn) * DISK_BLOCK_SIZE;
		util_out_print("New starting VBN is: !SL !/", FLUSH, new_head->start_vbn);

		/* read 1st group of blocks */
		LSEEKREAD(fd, read_off, upgrd_buff[0], bufsize, status);
		if (0 != status)
			if (-1 == status)
				rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
			else
				rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
		read_off = read_off + bufsize;
		/* read 2nd group of blocks */
		LSEEKREAD(fd, read_off, upgrd_buff[1], bufsize, status);
		if (0 != status)
			if (-1 == status)
				rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
			else
				rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
		/* write 1st group of blocks in place of 2nd group */
		write_off = old_start_vbn_off + bufsize;
		LSEEKWRITE(fd, write_off, upgrd_buff[0], bufsize, status);
		if (0 != status)
			rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
		/* read last group (# of blks <= BLKS_PER_LMAP) */
		dsize = old_file_len2 - last_full_grp_startoff;
		assert (dsize <= bufsize);
		LSEEKREAD(fd, last_full_grp_startoff, upgrd_buff[0], dsize, status);
		if (0 != status)
			if (-1 == status)
				rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
			else
				rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
		/* write 2nd group of blocks */
		LSEEKWRITE(fd, last_full_grp_startoff, upgrd_buff[1], bufsize, status);
		if (0 != status)
			rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
		 /* write last group read from old file */
		LSEEKWRITE(fd, last_full_grp_startoff + bufsize, upgrd_buff[0], dsize, status);
		if (0 != status)
			rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
		util_out_print("Please wait while index is being adjusted...!/", FLUSH);
		mu_upgrd_adjust_blkptr(1L, TRUE, new_head, fd, fn, fn_len);
		mu_upgrd_adjust_mm(new_head->master_map, DIVIDE_ROUND_UP(new_head->trans_hist.total_blks+1,BLKS_PER_LMAP));
		/* writing header */
		LSEEKWRITE(fd, 0, new_head, new_hdr_size, status);
		if (0 != status)
			rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
	}
	else /* very small database */
	{
		rbno = 0;
		write_off = 0;

		datasize[rbno] = new_hdr_size;
		memcpy(upgrd_buff[0], new_head, new_hdr_size);
		rbno = INVERT(rbno);

		while(read_off < old_file_len2)
		{
			datasize[rbno] = MIN (old_file_len2 - read_off, bufsize);
			LSEEKREAD(fd, read_off, upgrd_buff[rbno], datasize[rbno], status);
			if (0 != status)
				if (-1 == status)
					rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
				else
					rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
			read_off += datasize[rbno];
			rbno = INVERT(rbno);


			LSEEKWRITE(fd, write_off, upgrd_buff[rbno], datasize[rbno], status);
			if (0 != status)
				rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
			write_off+= datasize[rbno];
		}
		rbno = INVERT(rbno);
		LSEEKWRITE(fd, write_off, upgrd_buff[rbno], datasize[rbno], status);
		if (0 != status)
			rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, fn_len, fn, status);
	} /* end if small database */
	free(upgrd_buff[0]);
	free(upgrd_buff[1]);
	close(fd);
	util_out_print("File !AD successfully upgraded.!/", FLUSH, fn_len, fn);
	REVERT;
	if (0 != sem_rmid(upgrade_standalone_sems))
	{
		util_out_print("Error with sem_rmid : %d [0x%x]", TRUE, upgrade_standalone_sems, upgrade_standalone_sems);
		rts_error(VARLSTCNT(1) ERR_MUNOUPGRD);
	}
	mupip_exit(SS_NORMAL);
}
Beispiel #11
0
   void rec1_open_file( int expand, const char *file, INT file_len, char mode,
                        INT *slot, int *newslot )
   {
/*+                                                                         */
/* Name:                                                                    */
/*    rec1_open_file                                                        */

/* Purpose:                                                                 */
/*    Open an existing file.                                                */

/* Invocation:                                                              */
/*    rec1_open_file( expand, file, file_len, mode, slot, newslot )         */

/* Description:                                                             */
/*    This function opens an existing container file for reading or writing */
/*    and allocates a new File Control Vector slot (if necessary) to refer  */
/*    to the file. Any new FCV slot is initialised and its number is        */
/*    returned. The file's reference count is left unchanged if it is       */
/*    already in use, or is set to zero if it is being opened for the first */
/*    time.                                                                 */

/* Parameters:                                                              */
/*    int expand                                                            */
/*       If expand is non-zero, then the file name supplied will be         */
/*       regarded as an abbreviated form of the full name of the file and   */
/*       will be expanded (according to the underlying operating system's   */
/*       rules) before use. Otherwise, the file name supplied is regarded   */
/*       as already fully expanded and will be used literally.  This        */
/*       mechanism is provided to allow previously-expanded file names to   */
/*       be given, while allowing for the fact that expanding a file name   */
/*       twice may cause the wrong file to be identified (if the underlying */
/*       file system has changed and/or the expanded file name contains     */
/*       special characters, for instance).                                 */
/*    const char *file                                                      */
/*       Pointer to a char array containing the host file-system name of    */
/*       the container file to be opened. It should not be null terminated. */
/*       If expand is non-zero, then leading and trailing white space will  */
/*       be ignored. If expand is zero, then the file name must be          */
/*       fully-expanded and white space may be significant.                 */
/*    INT file_len                                                          */
/*       Number of characters in the file name (excluding any terminating   */
/*       null, if present).                                                 */
/*    char mode                                                             */
/*       A character specifying the required file access mode: 'R' for      */
/*       read-only access or 'W' for write (or update) access.              */
/*    INT *slot                                                             */
/*       Pointer to an integer in which the File Control Vector slot number */
/*       allocated to the file will be returned.                            */
/*    int *newslot                                                          */
/*       Returns 1 if the FCV slot is a new one, otherwise 0 if the slot    */
/*       was already in use (i.e. the file was already open).               */

/* Returned Value:                                                          */
/*    void                                                                  */

/* Copyright:                                                               */
/*    Copyright (C) 1992 Science & Engineering Research Council             */
/*    Copyright (C) 2005 Particle Physics and Astronomy Research Council    */

/*  Licence:                                                                */
/*     This program is free software; you can redistribute it and/or        */
/*     modify it under the terms of the GNU General Public License as       */
/*     published by the Free Software Foundation; either version 2 of       */
/*     the License, or (at your option) any later version.                  */

/*     This program is distributed in the hope that it will be              */
/*     useful, but WITHOUT ANY WARRANTY; without even the implied           */
/*     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR              */
/*     PURPOSE. See the GNU General Public License for more details.        */

/*     You should have received a copy of the GNU General Public            */
/*     License along with this program; if not, write to the Free           */
/*     Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,       */
/*     MA 02110-1301, USA                                                   */

/* Authors:                                                                 */
/*    RFWS: R.F. Warren-Smith (STARLINK)                                    */
/*    TIMJ: Tim Jenness (JAC, Hawaii)                                       */
/*    {@enter_new_authors_here@}                                            */

/* History:                                                                 */
/*    28-MAR-1991 (RFWS):                                                   */
/*       Added prologue.                                                    */
/*    3-APR-1991 (RFWS):                                                    */
/*       Fixed bug in passing of file name for error message.               */
/*    3-MAY-1991 (RFWS):                                                    */
/*       Re-structured to return an FCV slot number and to initialise the   */
/*       slot if necessary.                                                 */
/*    7-MAY-1991 (RFWS):                                                    */
/*       Added a portable implementation.                                   */
/*    21-MAY-1991 (RFWS):                                                   */
/*       Remove trailing blanks from file names (portable version).         */
/*    22-MAY-1991 (RFWS):                                                   */
/*       Added defaulting of ".sdf" file extension in portable version.     */
/*    12-JUN-1991 (RFWS):                                                   */
/*       Fixed bug in testing of access mode.                               */
/*    28-JUN-1991 (RFWS):                                                   */
/*       Removed initialisation of the VMS-specific FCV lid field (not      */
/*       necessary). Added function prototypes for VMS system calls.        */
/*    11-SEP-1992 (RFWS):                                                   */
/*       Do not increment the file reference count. This is now the         */
/*       caller's responsibility.                                           */
/*    14-OCT-1992 (RFWS):                                                   */
/*       Changed to a void function and to use separate string pointer and  */
/*       length arguments.                                                  */
/*    24-NOV-1992 (RFWS):                                                   */
/*       Fixed error in assigning access mode for error message.            */
/*    25-NOV-1992 (RFWS):                                                   */
/*       Changed to extend the File Control Vector when necessary.          */
/*    26-NOV-1992 (RFWS):                                                   */
/*       Enhanced file name handling by using rec1_get_path.                */
/*    1-DEC-1992 (RFWS):                                                    */
/*       Added the expand parameter.                                        */
/*    28-DEC-2005 (TIMJ):                                                   */
/*       Use DAT__FLEXT rather than hard-coded ".SDF"                       */
/*    02-FEB-2006 (TIMJ):                                                   */
/*       Free malloced memory if the slot is reused.                        */
/*    {@enter_further_changes_here@}                                        */

/* Bugs:                                                                    */
/*    {@note_any_bugs_here@}                                                */

/*-                                                                         */

/* Local Variables:                                                         */
#if defined (vms )               /* VMS version local variables:            */
      char esabuf[ NAM$C_MAXRSS ]; /* Expanded file name string buffer      */
      char rsabuf[ NAM$C_MAXRSS ]; /* Resultant file name string buffer     */
      struct FAB fab;            /* RMS file access block                   */
      struct NAM nam;            /* RMS NAM block                           */
      unsigned int systat;       /* System status code                      */
      unsigned short int iochan; /* File I/O channel                        */

#else                            /* Portable version local variables:       */
      FILE *iochan=NULL;         /* File I/O stream                         */
#endif

      INT i;                     /* Loop counter for FCV slots              */
      INT lfns;                  /* Length of File Name String              */
      INT start;                 /* Array offset of first non-blank char    */
      char *fns;                 /* Pointer to file name string             */
      int mustopen=0;            /* File must be opened?                    */
      struct FCV *fcv;           /* Pointer to File Control Vector element  */
      struct FID *fid;           /* Pointer to File ID                      */

/* External References:                                                     */
#if defined( vms )               /* VMS version system calls:               */
      unsigned int SYS$OPEN( struct FAB *fab );
      unsigned int SYS$PARSE( struct FAB *fab );
      unsigned int SYS$SEARCH( struct FAB *fab );
#endif

/*.                                                                         */

/* Check the inherited global status.                                       */
      if ( !_ok( hds_gl_status ) ) return;

/* Initialise.                                                              */
      fns = NULL;
      fid = NULL;

/* If necessary, modify the file name length to omit any trailing white     */
/* space.                                                                   */
      start = 0;
      if ( expand )
      {
         for ( ; file_len > 0; file_len-- )
         {
            if ( !isspace( file[ file_len - 1 ] ) ) break;
         }

/* Also strip white space from the start of the file name (but leave at     */
/* least one character, even if the string is completely blank).            */
         for ( start = 0; start < ( file_len - 1 ); start++ )
         {
            if ( !isspace( file[ start ] ) ) break;
         }
      }

/* VMS version:                                                             */
/* ===========                                                              */
#if defined( vms )

/* Initialise the file FAB and NAM blocks.                                  */
      fab = cc$rms_fab;
      fab.fab$l_dna = DAT__FLEXT;
      fab.fab$b_dns = DAT__SZFLX;
      fab.fab$l_fna = file + start;
      fab.fab$b_fns = file_len - start;
      fab.fab$l_nam = &nam;

      nam = cc$rms_nam;
      nam.nam$l_esa = esabuf;
      nam.nam$b_ess = NAM$C_MAXRSS;
      nam.nam$l_rsa = rsabuf;
      nam.nam$b_rss = NAM$C_MAXRSS;

/* Parse the file name, reporting any errors.                               */
      systat = SYS$PARSE( &fab );
      if ( !( systat & STS$M_SUCCESS ) )
      {
         hds_gl_status = ( systat == RMS$_PRV ) ? DAT__FILPR : DAT__FILNF;
         emsSetnc( "FILE", file + start, file_len - start );
         emsSyser( "MESSAGE", systat );
         emsRep( "REC1_OPEN_FILE_1",
                    "Error in file name \'^FILE\' - ^MESSAGE.",
                    &hds_gl_status );
      }

/*  Search for the file, again reporting errors.                            */
      if ( _ok( hds_gl_status ) )
      {
         systat = SYS$SEARCH( &fab );
         if ( !( systat & STS$M_SUCCESS ) )
         {
            hds_gl_status = ( systat == RMS$_PRV ) ? DAT__FILPR : DAT__FILNF;
            emsSetnc( "FILE", esabuf, nam.nam$b_esl );
            emsSyser( "MESSAGE", systat );
            emsRep( "REC1_OPEN_FILE_2",
                       "Error searching for file ^FILE - ^MESSAGE.",
                       &hds_gl_status );
         }

/* If the file was found successfully, then allocate memory to hold the     */
/* File Name String and the File ID and copy the relevant information from  */
/* the NAM block into this memory (adding a terminating null to the file    */
/* name).                                                                   */
         else
         {
            lfns = nam.nam$b_rsl;
            rec_alloc_mem( lfns + 1, (void **) &fns );
            rec_alloc_mem( sizeof( struct FID ), (void **) &fid );
            if ( _ok( hds_gl_status ) )
            {
               (void) memcpy( (void *) fns, (const void *) nam.nam$l_rsa,
                              (size_t) lfns );
               fns[ lfns ] = '\0';
               (void) memcpy( (void *) fid, (const void *) nam.nam$t_dvi,
                              sizeof( struct FID ) );
            }
         }
      }

/* Portable version:                                                        */
/* ================                                                         */
#else
/* If required, obtain the full path name of the file.                      */
      if ( expand )
      {
         rec1_get_path( file + start, file_len - start, &fns, &lfns );
      }

/* Otherwise, allocate space and copy the file name for use directly.       */
      else
      {
         lfns = file_len - start;
         rec_alloc_mem( lfns + 1, (void **) &fns );
         if ( _ok( hds_gl_status ) )
         {
            (void) memcpy( (void *) fns, (const void *) ( file + start ),
                           (size_t) lfns );
            fns[ lfns ] = '\0';
         }
      }

/* Allocate memory to hold the File ID and store file identification        */
/* information in it.                                                       */
      rec_alloc_mem( sizeof( struct FID ), (void **) &fid );
      rec1_get_fid( fns, fid );
#endif

/* Loop to search the File Control Vector for any slot which is currently   */
/* open and associated with the same file.                                  */
      if ( _ok( hds_gl_status ) )
      {
         *slot = rec_gl_endslot;
         *newslot = 1;
         for ( i = 0; i < rec_gl_endslot; i++ )
         {

/* Remember the number of the last slot which is not being used.            */
            if ( !rec_ga_fcv[ i ].open )
            {
               *slot = i;
            }

/* If a slot is open and the identification matches, then note that a new   */
/* slot is not needed and quit searching                                    */
            else if ( !memcmp( (const void *) rec_ga_fcv[ i ].fid,
                               (const void *) fid, sizeof( struct FID ) ) )
            {
               *slot = i;
               *newslot = 0;
               break;
            }
         }

/* If no File ID match or unused FCV slot was found, then a new slot must   */
/* be used.                                                                 */
         if ( *slot == rec_gl_endslot )
         {

/* If there is insufficient space for another slot in the File Control      */
/* Vector, then extend the FCV by doubling its size. If successful,         */
/* initialise the new region to zero and record the new size.               */
            if ( *slot >= rec_gl_mxslot )
            {
               rec_reall_mem( rec_gl_mxslot * 2 * sizeof( struct FCV ),
                              (void **) &rec_ga_fcv );
               if ( _ok( hds_gl_status ) )
               {
                  (void) memset( (void *) ( rec_ga_fcv + rec_gl_mxslot ), 0,
                                 sizeof( struct FCV ) *
                                 (size_t) rec_gl_mxslot );
                  rec_gl_mxslot *= 2;
               }
            }

/* If OK, increment the count of FCV slots used.                            */
            if ( _ok( hds_gl_status ) )
            {
               rec_gl_endslot++;
            }
         }
      }

/* See if the file needs opening. This will be necessary if a new FCV slot  */
/* is being used or if the file is currently open for read-only access and  */
/* write access is now required.                                            */
      if ( _ok( hds_gl_status ) )
      {
         mustopen = *newslot ||
                    ( ( mode != 'R' ) &&
                      ( rec_ga_fcv[ *slot ].write == REC__NOIOCHAN ) );

/* If the file is to be opened...                                           */
         if ( mustopen )
         {

/* VMS version:                                                             */
/* ===========                                                              */
#if defined( vms )

/* Initialise the FAB block.                                                */
            fab.fab$l_fop = FAB$M_UFO | FAB$M_NAM;
            fab.fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_UPI;
            fab.fab$b_fac = ( mode == 'R' ) ?
                              FAB$M_GET : ( FAB$M_GET | FAB$M_PUT );

/* Open the file, reporting any errors.                                     */
            systat = SYS$OPEN( &fab );
            if ( !( systat & STS$M_SUCCESS ) )
            {
               hds_gl_status = ( systat == RMS$_PRV ) ?
                               DAT__FILPR : DAT__FILNF;
               emsSetnc( "FILE", rsabuf, nam.nam$b_rsl );
               emsSetnc( "ACCESS", ( mode == 'R' ) ?
                                     "reading" : "writing", EMS__SZTOK );
               emsSyser( "MESSAGE", systat );
               emsRep( "REC1_OPEN_FILE_3",
                          "Unable to open file ^FILE for ^ACCESS - ^MESSAGE.",
                          &hds_gl_status );
            }

/* If the file was opened successfully, extract its I/O channel from the    */
/* FAB block.                                                               */
            else
            {
               iochan = (int) fab.fab$l_stv;
            }

/* Portable version:                                                        */
/* ================                                                         */
#else
/* Open the file, checking for errors.                                      */
            iochan = fopen( (const char *) fns,
                            ( mode == 'R' ) ? "rb" : "r+b");
            if ( iochan == NULL )
            {

/* Categorise the possible error conditions, setting the appropriate status */
/* value.                                                                   */
               switch ( errno )
               {
                  case EACCES:
                     hds_gl_status = DAT__FILPR; /* Access denied           */
                     break;
                  case EISDIR:
                     hds_gl_status = DAT__FILIN; /* File is a directory     */
                     break;
                  case EROFS:
                     hds_gl_status = DAT__FILPR; /* Read-only file system   */
                     break;
                  default:                       /* All other errors ==>    */
                     hds_gl_status = DAT__FILNF; /* File not found          */
                     break;
               }

/* Report the error.                                                        */
               emsSyser( "MESSAGE", errno );
               emsSetnc( "FILE", fns, EMS__SZTOK );
               emsSetnc( "ACCESS", ( mode == 'R' ) ? "read" : "read/write",
                           EMS__SZTOK );
               emsRep( "REC1_OPEN_FILE_4",
                          "Error opening file ^FILE for ^ACCESS access - \
^MESSAGE",
                          &hds_gl_status );
            }
#endif
         }
      }

/* If the file has been opened successfully but an old slot has been used,  */
/* then simply store the new I/O channel in the slot.                       */
      if ( _ok( hds_gl_status ) )
      {
         if ( mustopen )
         {
            if ( !*newslot )
            {
               rec_ga_fcv[ *slot ].write = iochan;
            }

/* If a new slot is being used, fill in the File Control Vector fields,     */
/* marking the slot as open.                                                */
            else
            {
               fcv = &rec_ga_fcv[ *slot ];
               fcv->name = fns;
               fcv->fid = fid;
               fcv->read = ( mode == 'R' ) ? iochan : REC__NOIOCHAN;
               fcv->write = ( mode == 'R' ) ? REC__NOIOCHAN : iochan;
               fcv->count = 0;
               fcv->dele = 0;
               fcv->open = 1;
               fcv->locked = 0;
               fcv->hcb = NULL;
               fcv->hcbmodify = 0;
            }
         }
      }

/* If an error occurred, then deallocate any memory allocated for the File  */
/* Name String and File ID.                                                 */
/* Also free the memory if we are reusing a slot (since the name is already */
/* stored and the copy is not used.                                         */
      if ( !_ok( hds_gl_status ) || !*newslot )
      {
         rec_deall_mem( lfns + 1, (void **) &fns );
         rec_deall_mem( sizeof( struct FID ), (void **) &fid );
      }

/* Exit the routine.                                                        */
      return;
   }
Beispiel #12
0
static void write_db(char * df) {
    _DB db;
    datum key, value;
    UL ul, kul;
    US us, kus;
    int ofrom;
    int vlen;
    US count;
    char *val, *p;
    int i, j;
    char version[80];

    if (verbose)
        printf("Writing\n");
    if((db=OPEN(df,WRITE)) == 0) {
        fprintf(stderr, "Can't create '%s' - %s\n", df, GET_ERR);
        exit(EXIT_FAILURE);
    }
    /* tablelen .. len of table entries */
    /* keylen = keysize */
    if (maxnum > keylen)
        keylen=maxnum;
    keylen = keylen > 0xffff ? 4 : 2;
    tablelen = tablelen > 0xffff ? 4 : tablelen > 0xff ? 2 : 1;

    /* write version & table */
    key.dptr = "vErSiO";
    key.dsize = 7;
    /* version of zone.c must be not smaller than dataversion */
    sprintf(version,"V1.25 K%c C%c N%d T%d O%d L%d",
            keylen==2?'S':'L',tablelen==1?'C':tablelen==2?'S':'L',
            nn,n, ortszone, numlen?numlen:keydigs);
    value.dptr = version;
    value.dsize = strlen(version)+1;
    if(STORE(db, key, value)) {
        fprintf(stderr, "Error storing version key - %s\n", GET_ERR);
        exit(EXIT_FAILURE);
    }

    if ((p = val = calloc(nn, tablelen)) == 0) {
        fprintf(stderr, "Out of mem\n");
        exit(EXIT_FAILURE);
    }
    key.dptr = "_tAbLe\0";
    key.dsize = 7;
    for (i=0; i<nn; i++)
        if(tablelen==1)
            *p++ = (UC)table[i];
        else if(tablelen == 2) {
            // *((US*)p)++ = (US)table[i];
            tools_pack16(p, (US)table[i]);
            p += 2;
        }
        else {
            // *((UL*)p)++ = (UL)table[i];
            tools_pack32(p, (UL)table[i]);
            p += 4;
        }
    value.dptr = val;
    value.dsize = nn*tablelen;
    if(STORE(db, key, value)) {
        fprintf(stderr, "Error storing table key - %s\n", GET_ERR);
        exit(EXIT_FAILURE);
    }
    free(val);

    /* and write data */
    val = malloc(2); /* size of count */
    vlen = 2;
    ofrom = -1;
    count = 0;
    for (i=0; i<n; i++) {
        bool found = false;
        UC uc;
        unsigned char buf[4];

        if (verbose && stdoutisatty && (i % 1000) == 0) {
            printf("%d\r", i);
            fflush(stdout);
        }
        if (ofrom != -1 && ofrom != zones[i][0]) {
            // *((US*)val) = count;
            tools_pack16(val, count);
            value.dptr = val;
            value.dsize = vlen;
            if(STORE(db, key, value)) {
                fprintf(stderr, "Error storing key '%d' - %s\n",ofrom,GET_ERR);
                exit(EXIT_FAILURE);
            }
            free(value.dptr); /* the realloced val */
        }
        if (ofrom != zones[i][0]) {
            count = 0;
            val = malloc(2); /* size */
            vlen = 2;
            /* set up key */
            ofrom = zones[i][0];
            if (keylen == 4) {
                kul = (UL)ofrom;
                tools_pack32(buf, kul);
                key.dptr = buf;
            }
            else {
                kus = (US)ofrom;
                tools_pack16(buf, kus);
                key.dptr = buf;
            }
            key.dsize = keylen;
        }
        count++;
        for (j=0; j<nn; j++)
            if(table[j] == zones[i][1]) {
                found = true;
                val = realloc(val, vlen+2);
                uc = (UC)zones[i][2];
                val[vlen++] = uc;
                uc = (UC)j;
                val[vlen++] = uc;
                break;
            }
        if (!found) {
            val = realloc(val, vlen+1+keylen);
            zones[i][2] |= 128;
            uc = (UC)zones[i][2];
            val[vlen++] = uc;
            if(keylen == 2) {
                us = (US)zones[i][1];
                // *((US*)(&val[vlen])) = us;
                tools_pack16(&val[vlen], us);
            }
            else {
                ul = (UL)zones[i][1];
                // *((UL*)(&val[vlen])) = ul;
                tools_pack32(&val[vlen], ul);
            }
            vlen+=keylen;
        }
    }
    if(verbose)
        printf("%d\n", i);
    /* write last */
    // *((US*)val) = count;
    tools_pack16(val, count);

    value.dptr = val;
    value.dsize = vlen;
    STORE(db, key, value);
    free(value.dptr);
    CLOSE(db);
    free(zones);
    free(df);
}
Beispiel #13
0
int	VM_rest(char *f)
{
	short	mb;
	register int	i, b;
	VMPTR	p;
	int	h, s = (sizeof(VMHEAD) * VMLEGSIZ);
	VMHEAD	HUGE	*v;
	char	HUGE	*t;
	FNAME(VM_rest);

	TEST(fun, 0);
	VM_end();
	VM_init();
	h = OPEN(f, O_RDONLY | O_BINARY);
	if (h == -1)		return(1);
	if (sizeof(VMfree) != read(h, (char *) &VMfree,	sizeof(VMfree)))  {
		rest_clean(1, h, -1, -1);
		return(2);
	}
	if (sizeof(mb) != read(h, (char	*) &mb,	sizeof(mb)))  {
		rest_clean(1, h, -1, -1);
		return(2);
	}
	for (i=0 ; i !=	mb ; ++i)  {
		VMbase[i] = (VMHEAD HUGE *) rmalloc((MAX_SIZ_TYP) s);
		if (!VMbase[i])	 {
			rest_clean(2, h, -1, -1);
			return(3);
		}
		if (s != read(h, (char HUGE *) VMbase[i], s))  {
			rest_clean(2, h, -1, -1);
			return(2);
		}
	}
	for (b=0 ; b !=	mb ; ++b)  {
		v = VMbase[b];
		for (i=b?0:1 ; i != VMLEGSIZ  ;	++i)  {
			if (v[i].type != MT_NOTUSED  &&	 !(v[i].type & MT_IMEDIATE))
				VMtotal	+= v[i].size;
			if (v[i].type != MT_NOTUSED  &&	 (!(v[i].type &	MT_DISK)  ||  v[i].diskadd != -1L))
				VMlive++;
			if (v[i].type &	MT_MEMORY  ||  v[i].type & MT_DISK  &&	v[i].diskadd !=	-1L)  {
				v[i].type = MT_MEMORY |	MT_DIRTY;
				if (!(t	= rmalloc(v[i].size)))	{
					rest_clean(3, h, b, i);
					return(3);
				}

/* this	must be	done because rmalloc calls compact which may change the	address	of VMbase[x]  */
				v = VMbase[b];
				v[i].mem = t;

				if ((long) v[i].size != longread(h, v[i].mem, (long) v[i].size))  {
					rest_clean(3, h, b, i+1);
					return(2);
				}
				p.p.b =	b;
				p.p.l =	i;
				vm_link(&v[i], p.i);
				v[i].diskadd = -1L;
			}
		}
	}
	if (-1 == close(h))
		error(fun, "close");
	TEST(fun, 1);
	return(0);
}
Beispiel #14
0
int	VM_dump(char *f)
{
	short	mb;
	register int	i, b;
	int	h, s = (sizeof(VMHEAD) * VMLEGSIZ);
#ifdef NO_ALLOCA
	char	dbuf[NO_ALLOCA];
	unsigned	bufsiz = NO_ALLOCA;
#else
	char	*dbuf;
	unsigned	bufsiz = 2048;
#endif
	VMHEAD	HUGE *v;
	FNAME(VM_dump);

	TEST(fun, 0);
	h = OPEN(f, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE);
	if (h == -1)		return(1);
#ifndef NO_ALLOCA
	while (NULL == (dbuf = alloca(bufsiz)))
		bufsiz /= 2;
#endif
	if (sizeof(VMfree) != write(h, (char *)	&VMfree, sizeof(VMfree)))
		goto er2;

	for (mb=0 ; mb != VMBASESIZ  &&	 VMbase[mb] ; ++mb);
	if (sizeof(mb) != write(h, (char *) &mb, sizeof(mb)))
		goto er2;
	for (i=0 ; i !=	mb ; ++i)
		if (s != write(h, (char	HUGE *) VMbase[i], s))
			goto er2;
	for (b=0 ; b !=	mb ; ++b)  {
		v = VMbase[b];
		for (i=b?0:1 ; i != VMLEGSIZ  ;	++i)  {
			if (v[i].type &	MT_MEMORY)  {
				if ((long) v[i].size != longwrite(h, v[i].mem, (long) v[i].size))
					goto er2;
			}  else	 if (v[i].type & MT_DISK  &&  v[i].diskadd != -1L)  {
				unsigned int n = bufsiz	< v[i].size ? bufsiz : v[i].size;
				MAX_SIZ_TYP	m = v[i].size;

				if (-1L	== lseek(DMhandle, v[i].diskadd, SEEK_SET))
					error(fun, "lseek");
				while (m)  {
					n = n >	m ? m :	n;
					if (n != read(DMhandle,	dbuf, n))
						error(fun, "read");
					if (n != write(h, dbuf,	n))
						goto er2;
					m -= n;
				}
			}
		}
	}
	if (-1 == close(h))
		error(fun, "close");
	TEST(fun, 1);
	return(0);
er2:
	if (-1 == close(h))
		error(fun, "close");
	if (-1 == unlink(f))
		error(fun, "unlink");
	TEST(fun, 2);
	return(2);		/*  write error	*/
}
Beispiel #15
0
/**
 * Main request handler.
 */
static int
access_handler_callback (void *cls, struct MHD_Connection *connection,
                         const char *url, const char *method,
                         const char *version, const char *upload_data,
                         size_t * upload_data_size, void **con_cls)
{
  static int dummy;
  static const struct Entry map[] = {
    { "prefix", "prefix" },
    { "name", "name" },
    { "suffix", "suffix" },
    { "street", "street" },
    { "city", "city" },
    { "phone", "phone" },
    { "fax", "fax" },
    { "email", "email"},
    { "homepage", "homepage" },
    { "orga", "orga"},
    { "departmenti18n", "departmentde"},
    { "departmenten", "departmenten"},
    { "subdepartmenti18n", "subdepartmentde"},
    { "subdepartmenten", "subdepartmenten"},
    { "jobtitlei18n", "jobtitlegerman"},
    { "jobtitleen", "jobtitleenglish"},
    { "subdepartmenten", "subdepartmenten"},
    { NULL, NULL }
  };

  if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _("Refusing `%s' request to HTTP server\n"),
                method);
    return MHD_NO;
  }
  if (NULL == *con_cls)
  {
    (*con_cls) = &dummy;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Sending 100 CONTINUE reply\n");
    return MHD_YES;             /* send 100 continue */
  }
  if (0 == strcasecmp (url, "/"))
    return MHD_queue_response (connection,
                               MHD_HTTP_OK,
                               main_response);
  if (0 == strcasecmp (url, "/submit.pdf"))
  {
    unsigned int i;
    char *p;
    char *tmp;
    char *deffile;
    struct GNUNET_CRYPTO_EcdsaPublicKey pub;
    size_t slen;
    FILE *f;
    struct stat st;
    struct MHD_Response *response;
    int fd;
    int ret;

    const char *gpg_fp = MHD_lookup_connection_value (connection,
                                                      MHD_GET_ARGUMENT_KIND,
                                                      "gpgfingerprint");
    const char *gns_nick = MHD_lookup_connection_value (connection,
                                                        MHD_GET_ARGUMENT_KIND,
                                                        "gnsnick");
    const char *gnskey = MHD_lookup_connection_value (connection,
                                                      MHD_GET_ARGUMENT_KIND,
                                                      "gnskey");
    if ( (NULL == gnskey) ||
         (GNUNET_OK !=
          GNUNET_CRYPTO_ecdsa_public_key_from_string (gnskey,
                                                      strlen (gnskey),
                                                      &pub)))
    {
      return MHD_queue_response (connection,
                                 MHD_HTTP_OK,
                                 invalid_gnskey_response);
    }
    tmp = GNUNET_DISK_mkdtemp (gnskey);
    if (NULL == tmp)
    {
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mktemp", gnskey);
      return MHD_NO;
    }
    GNUNET_asprintf (&deffile,
                     "%s%s%s",
                     tmp, DIR_SEPARATOR_STR, "def.tex");
    f = FOPEN (deffile, "w");
    if (NULL == f)
    {
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", deffile);
      GNUNET_free (deffile);
      GNUNET_DISK_directory_remove (tmp);
      GNUNET_free (tmp);
      return MHD_NO;
    }
    for (i=0; NULL != map[i].formname; i++)
    {
      const char *val =  MHD_lookup_connection_value (connection,
                                                      MHD_GET_ARGUMENT_KIND,
                                                      map[i].formname);
      if (NULL != val)
        FPRINTF (f,
                 "\\def\\%s{%s}\n",
                 map[i].texname, val);
      else
        FPRINTF (f,
                 "\\def\\%s{}\n",
                 map[i].texname);
    }
    if (NULL != gpg_fp)
    {
      char *gpg1;
      char *gpg2;

      slen = strlen (gpg_fp);
      gpg1 = GNUNET_strndup (gpg_fp, slen / 2);
      gpg2 = GNUNET_strdup (&gpg_fp[slen / 2]);
      FPRINTF (f,
               "\\def\\gpglineone{%s}\n\\def\\gpglinetwo{%s}\n",
               gpg1, gpg2);
      GNUNET_free (gpg2);
      GNUNET_free (gpg1);
    }
    FPRINTF (f,
             "\\def\\gns{%s/%s}\n",
             gnskey,
             (NULL == gns_nick) ? "" : gns_nick);
    FCLOSE (f);
    GNUNET_asprintf (&p,
                     "cd %s; cp %s gns-bcd.tex | pdflatex --enable-write18 gns-bcd.tex > /dev/null 2> /dev/null",
                     tmp,
                     resfile);
    GNUNET_free (deffile);
    ret = system (p);
    if (WIFSIGNALED (ret) || (0 != WEXITSTATUS(ret)))
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                                "system",
                                p);
    GNUNET_asprintf (&deffile,
                     "%s%s%s",
                     tmp, DIR_SEPARATOR_STR, "gns-bcd.pdf");
    fd = OPEN (deffile, O_RDONLY);
    if (-1 == fd)
    {
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                                "open",
                                deffile);
      GNUNET_free (deffile);
      GNUNET_free (p);
      GNUNET_DISK_directory_remove (tmp);
      GNUNET_free (tmp);
      return MHD_NO;
    }
    GNUNET_break (0 == STAT (deffile, &st));
    if (NULL == (response = MHD_create_response_from_fd ((size_t) st.st_size, fd)))
    {
      GNUNET_break (0);
      GNUNET_break (0 == CLOSE (fd));
      GNUNET_free (deffile);
      GNUNET_free (p);
      GNUNET_DISK_directory_remove (tmp);
      GNUNET_free (tmp);
      return MHD_NO;
    }
    (void) MHD_add_response_header (response,
                                    MHD_HTTP_HEADER_CONTENT_TYPE,
                                    "application/pdf");
    ret = MHD_queue_response (connection,
                              MHD_HTTP_OK,
                              response);
    MHD_destroy_response (response);
    GNUNET_free (deffile);
    GNUNET_free (p);
    GNUNET_DISK_directory_remove (tmp);
    GNUNET_free (tmp);
    return ret;
  }
  return MHD_queue_response (connection,
                             MHD_HTTP_NOT_FOUND,
                             not_found_response);
}
Beispiel #16
0
int main() {
    int tcase;
    int i,j;
    scanf("%d", &tcase);

    while(tcase--) {
        char buf[LIMIT] = {};
        int buflen;
        struct data s[LIMIT] = {};
        int s_idx=0;
        struct data nums[LIMIT] = {};
        int nums_idx=0;
        int b_close = 0;
        int temp=0, error=0;
        scanf("%s", buf);
        buflen = strlen(buf);
//        printf("start\n");

        for(i=0;i<buflen;i++) {
            if(OPEN(buf[i])) {
                s[s_idx].data = buf[i];
                s[s_idx++].index = i;
                b_close = 0;
            }
            else if(sametype(s[s_idx-1].data, buf[i])) {
                temp = 0;
                if(b_close) {
                    while(nums[nums_idx-1].index > s[s_idx-1].index) {
                        temp += nums[--nums_idx].data;
//                        printf("add %d to temp : %d\n", nums[nums_idx+1].data, temp);
                    }
                    temp *= bton(s[--s_idx].data);
                    nums[nums_idx++].data = temp;

//                    printf("multi data temp %d\n", temp);
                }
                else {
                    nums[nums_idx].data = bton(s[s_idx-1].data);
                    nums[nums_idx++].index = s[--s_idx].index;
/*                    printf("push num stack %d index %d\n", nums[nums_idx-1].data, nums[nums_idx-1].index);
                    for(j=0;j<nums_idx;j++) {
                        printf("%d ", nums[j].data);
                    }
                    putchar ('\n');
*/
                }
                b_close = 1;
            }
            else {
                printf("0\n");
                error = 1;
                break;
            }
        }
        if(error) continue;
/*        for(j=0;j<nums_idx;j++) {
            printf("%d ", nums[j].data);
        }
        putchar ('\n');*/
        if(s_idx){ 
            printf("0\n");
            continue;
        }

        temp = 0;
        while(nums_idx--) {
            temp += nums[nums_idx].data;
        }


        printf("%d\n", temp);

    }
    return 0;
}
Beispiel #17
0
/**
 * Listen to the pipe, decode messages and send to core.
 */
static void *
listenAndDistribute (void *unused)
{
  char *line;
  unsigned int linesize;
  SMTPMessage *mp;
  FILE *fdes;
  char *retl;
  char *out;
  unsigned int size;
  GNUNET_TransportPacket *coreMP;
  int fd;
  unsigned int pos;

  linesize = ((GNUNET_MAX_BUFFER_SIZE * 4 / 3) + 8) * (MAX_CHAR_PER_LINE + 2) / MAX_CHAR_PER_LINE;      /* maximum size of a line supported */
  line = GNUNET_malloc (linesize + 2);  /* 2 bytes for off-by-one errors, just to be safe... */

#define READLINE(l,limit) \
  do { retl = fgets(l, (limit), fdes);				\
    if ( (retl == NULL) || (smtp_shutdown == GNUNET_YES)) {\
      goto END; \
    }\
    if (core_api->load_monitor != NULL) \
     GNUNET_network_monitor_notify_transmission(core_api->load_monitor, GNUNET_ND_DOWNLOAD, strlen(retl)); \
  } while (0)


  while (smtp_shutdown == GNUNET_NO)
  {
    fd = OPEN (pipename, O_RDONLY | O_ASYNC);
    if (fd == -1)
    {
      if (smtp_shutdown == GNUNET_NO)
        GNUNET_thread_sleep (5 * GNUNET_CRON_SECONDS);
      continue;
    }
    fdes = fdopen (fd, "r");
    while (smtp_shutdown == GNUNET_NO)
    {
      /* skip until end of header */
      do
      {
        READLINE (line, linesize);
      }
      while ((line[0] != '\r') && (line[0] != '\n'));   /* expect newline */
      READLINE (line, linesize);        /* read base64 encoded message; decode, process */
      pos = 0;
      while (1)
      {
        pos = strlen (line) - 1;        /* ignore new line */
        READLINE (&line[pos], linesize - pos);  /* read base64 encoded message; decode, process */
        if ((line[pos] == '\r') || (line[pos] == '\n'))
          break;                /* empty line => end of message! */
      }
      size = GNUNET_STRINGS_base64_decode (line, pos, &out);
      if (size < sizeof (SMTPMessage))
      {
        GNUNET_GE_BREAK (ectx, 0);
        GNUNET_free (out);
        goto END;
      }

      mp = (SMTPMessage *) &out[size - sizeof (SMTPMessage)];
      if (ntohs (mp->header.size) != size)
      {
        GNUNET_GE_LOG (ectx,
                       GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
                       _("Received malformed message via %s. Ignored.\n"),
                       "SMTP");
#if DEBUG_SMTP
        GNUNET_GE_LOG (ectx,
                       GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
                       "Size returned by base64=%d, in the msg=%d.\n", size,
                       ntohl (mp->size));
#endif
        GNUNET_free (out);
        goto END;
      }
      if (stats != NULL)
        stats->change (stat_bytesReceived, size);
      coreMP = GNUNET_new (GNUNET_TransportPacket);
      coreMP->msg = out;
      coreMP->size = size - sizeof (SMTPMessage);
      coreMP->tsession = NULL;
      coreMP->sender = mp->sender;
#if DEBUG_SMTP
      GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
                     "SMTP message passed to the core.\n");
#endif

      core_api->receive (coreMP);
    }
END:
#if DEBUG_SMTP
    GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
                   "SMTP message processed.\n");
#endif
    if (fdes != NULL)
      fclose (fdes);
  }
  GNUNET_free (line);
  return NULL;
}
Beispiel #18
0
int
main(int argc, char *argv[])
{
    START(argc, argv, "pmem_map");

    if (argc != 2)
        FATAL("usage: %s file", argv[0]);

    int fd;
    void *addr;

    fd = OPEN(argv[1], O_RDWR);

    struct stat stbuf;
    FSTAT(fd, &stbuf);

    char pat[CHECK_BYTES];
    char buf[CHECK_BYTES];

    addr = pmem_map(fd);
    if (addr == NULL) {
        OUT("!pmem_map");
        goto err;
    }

    /* write some pattern to the file */
    memset(pat, 0x5A, CHECK_BYTES);
    WRITE(fd, pat, CHECK_BYTES);


    if (memcmp(pat, addr, CHECK_BYTES))
        OUT("%s: first %d bytes do not match",
            argv[1], CHECK_BYTES);

    /* fill up mapped region with new pattern */
    memset(pat, 0xA5, CHECK_BYTES);
    memcpy(addr, pat, CHECK_BYTES);

    MUNMAP(addr, stbuf.st_size);

    LSEEK(fd, (off_t)0, SEEK_SET);
    if (READ(fd, buf, CHECK_BYTES) == CHECK_BYTES) {
        if (memcmp(pat, buf, CHECK_BYTES))
            OUT("%s: first %d bytes do not match",
                argv[1], CHECK_BYTES);
    }

    CLOSE(fd);

    /* re-open the file with read-only access */
    fd = OPEN(argv[1], O_RDONLY);

    addr = pmem_map(fd);
    if (addr != NULL) {
        MUNMAP(addr, stbuf.st_size);
        OUT("expected pmem_map failure");
    }

err:
    CLOSE(fd);

    DONE(NULL);
}
Beispiel #19
0
/*
 * Alias ld.so entry point -- receives a bootstrap structure and a vector
 * of strings.  The vector is "well-known" to us, and consists of pointers
 * to string constants.  This aliasing bootstrap requires no relocation in
 * order to run, save for the pointers of constant strings.  This second
 * parameter provides this.  Note that this program is carefully coded in
 * order to maintain the "no bootstrapping" requirement -- it calls only
 * local functions, uses no intrinsics, etc.
 */
void *
__rtld(Elf32_Boot *ebp, const char *strings[], int (*funcs[])())
{
	int i, j, p;			/* working */
	int page_size = 0;		/* size of a page */
	const char *program_name = EMPTY; /* our name */
	int ldfd;			/* fd assigned to ld.so */
	int dzfd = 0;			/* fd assigned to /dev/zero */
	Elf32_Ehdr *ehdr;		/* ELF header of ld.so */
	Elf32_Phdr *phdr;		/* first Phdr in file */
	Elf32_Phdr *pptr;		/* working Phdr */
	Elf32_Phdr *lph;		/* last loadable Phdr */
	Elf32_Phdr *fph = 0;		/* first loadable Phdr */
	caddr_t	maddr;			/* pointer to mapping claim */
	Elf32_Off mlen;			/* total mapping claim */
	caddr_t faddr;			/* first program mapping of ld.so */
	Elf32_Off foff;			/* file offset for segment mapping */
	Elf32_Off flen;			/* file length for segment mapping */
	caddr_t addr;			/* working mapping address */
	caddr_t zaddr;			/* /dev/zero working mapping addr */
	struct stat sb;			/* stat buffer for sizing */
	auxv_t *ap;			/* working aux pointer */

	/*
	 * Discover things about our environment: auxiliary vector (if
	 * any), arguments, program name, and the like.
	 */
	while (ebp->eb_tag != NULL) {
		switch (ebp->eb_tag) {
		case EB_ARGV:
			program_name = *((char **)ebp->eb_un.eb_ptr);
			break;
		case EB_AUXV:
			for (ap = (auxv_t *)ebp->eb_un.eb_ptr;
			    ap->a_type != AT_NULL; ap++)
				if (ap->a_type == AT_PAGESZ) {
					page_size = ap->a_un.a_val;
					break;
				}
			break;
		}
		ebp++;
	}

	/*
	 * If we didn't get a page size from looking in the auxiliary
	 * vector, we need to get one now.
	 */
	if (page_size == 0) {
		page_size = SYSCONFIG(_CONFIG_PAGESIZE);
		ebp->eb_tag = EB_PAGESIZE, (ebp++)->eb_un.eb_val =
		    (Elf32_Word)page_size;
	}

	/*
	 * Map in the real ld.so.  Note that we're mapping it as
	 * an ELF database, not as a program -- we just want to walk it's
	 * data structures.  Further mappings will actually establish the
	 * program in the address space.
	 */
	if ((ldfd = OPEN(LDSO, O_RDONLY)) == -1)
		PANIC(program_name);
/* NEEDSWORK (temp kludge to use xstat so we can run on G6) */
	if (FSTAT(2, ldfd, &sb) == -1)
		PANIC(program_name);
	ehdr = (Elf32_Ehdr *)MMAP(0, sb.st_size, PROT_READ | PROT_EXEC,
	    MAP_SHARED, ldfd, 0);
	if (ehdr == (Elf32_Ehdr *)-1)
		PANIC(program_name);

	/*
	 * Validate the file we're looking at, ensure it has the correct
	 * ELF structures, such as: ELF magic numbers, coded for 386,
	 * is a ".so", etc.
	 */
	if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
	    ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
	    ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
	    ehdr->e_ident[EI_MAG3] != ELFMAG3)
		PANIC(program_name);
	if (ehdr->e_ident[EI_CLASS] != ELFCLASS32 ||
	    ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
		PANIC(program_name);
	if (ehdr->e_type != ET_DYN)
		PANIC(program_name);
	if (ehdr->e_machine != EM_386)
		PANIC(program_name);
	if (ehdr->e_version > EV_CURRENT)
		PANIC(program_name);

	/*
	 * Point at program headers and start figuring out what to load.
	 */
	phdr = (Elf32_Phdr *)((caddr_t)ehdr + ehdr->e_phoff);
	for (p = 0, pptr = phdr; p < (int)ehdr->e_phnum; p++,
	    pptr = (Elf32_Phdr *)((caddr_t)pptr + ehdr->e_phentsize))
		if (pptr->p_type == PT_LOAD) {
			if (fph == 0) {
				fph = pptr;
			} else if (pptr->p_vaddr <= lph->p_vaddr)
				PANIC(program_name);
			lph = pptr;
		}

	/*
	 * We'd better have at least one loadable segment.
	 */
	if (fph == 0)
		PANIC(program_name);

	/*
	 * Map enough address space to hold the program (as opposed to the
	 * file) represented by ld.so.  The amount to be assigned is the
	 * range between the end of the last loadable segment and the
	 * beginning of the first PLUS the alignment of the first segment.
	 * mmap() can assign us any page-aligned address, but the relocations
	 * assume the alignments included in the program header.  As an
	 * optimization, however, let's assume that mmap() will actually
	 * give us an aligned address -- since if it does, we can save
	 * an munmap() later on.  If it doesn't -- then go try it again.
	 */
	mlen = ROUND((lph->p_vaddr + lph->p_memsz) -
	    ALIGN(fph->p_vaddr, page_size), page_size);
	maddr = (caddr_t)MMAP(0, mlen, PROT_READ | PROT_EXEC,
	    MAP_SHARED, ldfd, 0);
	if (maddr == (caddr_t)-1)
		PANIC(program_name);
	faddr = (caddr_t)ROUND(maddr, fph->p_align);

	/*
	 * Check to see whether alignment skew was really needed.
	 */
	if (faddr != maddr) {
		(void) MUNMAP(maddr, mlen);
		mlen = ROUND((lph->p_vaddr + lph->p_memsz) -
		    ALIGN(fph->p_vaddr, fph->p_align) + fph->p_align,
		    page_size);
		maddr = (caddr_t)MMAP(0, mlen, PROT_READ | PROT_EXEC,
		    MAP_SHARED, ldfd, 0);
		if (maddr == (caddr_t)-1)
			PANIC(program_name);
		faddr = (caddr_t)ROUND(maddr, fph->p_align);
	}

	/*
	 * We have the address space reserved, so map each loadable segment.
	 */
	for (p = 0, pptr = phdr; p < (int)ehdr->e_phnum; p++,
	    pptr = (Elf32_Phdr *)((caddr_t)pptr + ehdr->e_phentsize)) {

		/*
		 * Skip non-loadable segments or segments that don't occupy
		 * any memory.
		 */
		if ((pptr->p_type != PT_LOAD) || (pptr->p_memsz == 0))
			continue;

		/*
		 * Determine the file offset to which the mapping will
		 * directed (must be aligned) and how much to map (might
		 * be more than the file in the case of .bss.)
		 */
		foff = ALIGN(pptr->p_offset, page_size);
		flen = pptr->p_memsz + (pptr->p_offset - foff);

		/*
		 * Set address of this segment relative to our base.
		 */
		addr = (caddr_t)ALIGN(faddr + pptr->p_vaddr, page_size);

		/*
		 * If this is the first program header, record our base
		 * address for later use.
		 */
		if (pptr == phdr) {
			ebp->eb_tag = EB_LDSO_BASE;
			(ebp++)->eb_un.eb_ptr = (Elf32_Addr)addr;
		}

		/*
		 * Unmap anything from the last mapping address to this
		 * one.
		 */
		if (addr - maddr) {
			(void) MUNMAP(maddr, addr - maddr);
			mlen -= addr - maddr;
		}

		/*
		 * Determine the mapping protection from the section
		 * attributes.
		 */
		i = 0;
		if (pptr->p_flags & PF_R)
			i |= PROT_READ;
		if (pptr->p_flags & PF_W)
			i |= PROT_WRITE;
		if (pptr->p_flags & PF_X)
			i |= PROT_EXEC;
		if ((caddr_t)MMAP((caddr_t)addr, flen, i,
		    MAP_FIXED | MAP_PRIVATE, ldfd, foff) == (caddr_t)-1)
			PANIC(program_name);

		/*
		 * If the memory occupancy of the segment overflows the
		 * definition in the file, we need to "zero out" the
		 * end of the mapping we've established, and if necessary,
		 * map some more space from /dev/zero.
		 */
		if (pptr->p_memsz > pptr->p_filesz) {
			foff = (int)faddr + pptr->p_vaddr + pptr->p_filesz;
			zaddr = (caddr_t)ROUND(foff, page_size);
			for (j = 0; j < (int)(zaddr - foff); j++)
				*((char *)foff + j) = 0;
			j = (faddr + pptr->p_vaddr + pptr->p_memsz) - zaddr;
			if (j > 0) {
				if (dzfd == 0) {
					dzfd = OPEN(ZERO, O_RDWR);
					if (dzfd == -1)
						PANIC(program_name);
				}
				if ((caddr_t)MMAP((caddr_t)zaddr, j, i,
				    MAP_FIXED | MAP_PRIVATE, dzfd,
				    0) == (caddr_t)-1)
					PANIC(program_name);
			}
		}

		/*
		 * Update the mapping claim pointer.
		 */
		maddr = addr + ROUND(flen, page_size);
		mlen -= maddr - addr;
	}

	/*
	 * Unmap any final reservation.
	 */
	if (mlen > 0)
		(void) MUNMAP(maddr, mlen);

	/*
	 * Clean up file descriptor space we've consumed.  Pass along
	 * the /dev/zero file descriptor we got -- every cycle counts.
	 */
	(void) CLOSE(ldfd);
	if (dzfd != 0)
		ebp->eb_tag = EB_DEVZERO, (ebp++)->eb_un.eb_val = dzfd;

	ebp->eb_tag = EB_NULL, ebp->eb_un.eb_val = 0;

	/* The two bytes before _rt_boot is for the alias entry point */
	return (void *) (ehdr->e_entry + faddr - 2);
}
Beispiel #20
0
int main(int ac, char **av) {
  int                         opt;
  char const                  *message = NULL;
  char                        *conn_addr = NULL;
  ssize_t                     rv;
  struct NaClDesc             *channel;
  struct NaClNrdXferEffector  eff;
  struct NaClDescEffector     *effp;
  struct NaClDesc             *pair[2];
  struct NaClSocketAddress    nsa;
  struct NaClDescConnCap      ndcc;
  struct NaClImcTypedMsgHdr   msg_hdr;
  struct NaClImcMsgIoVec      iov[1];
  struct NaClDesc             *desc_buffer[NACL_ABI_IMC_USER_DESC_MAX];
  char                        data_buffer[4096];
  size_t                      i;
  char                        *transfer_file = NULL;

  printf("Hello world\n");

  NaClNrdAllModulesInit();

  printf("Learning to walk... (parsing command line)\n");

  while (EOF != (opt = getopt(ac, av, "c:m:st:v"))) {
    switch (opt) {
      case 'c':
        conn_addr = optarg;
        break;
      case 'm':
        message = optarg;
        break;
      case 's':
        server = 1;
        break;
      case 't':
        transfer_file = optarg;
        break;
      case 'v':
        NaClLogIncrVerbosity();
        break;
      default:
        fprintf(stderr,
                "Usage: nrd_xfer_test [-sv] [-c connect-addr] [-m message]\n"
                "         [-t transfer_file_name]\n"
                "\n");
        fprintf(stderr,
                 "    -s run in server mode (prints NaCl sock addr)\n"
                 "    -v increases verbosity in the NRD xfer library\n"
                 "    -c run in client mode, with server NaCl sock addr as\n"
                 "       parameter\n"
                 "    -m message to be sent to peer (client sends message\n"
                 "       as payload data in IMC datagram; and if -t was\n"
                 "       specifed in the client to transfer a file\n"
                 "       descriptor to the server, the server will write its\n"
                 "       message into the file via the transferred\n"
                 "       descriptor\n");
        return 1;
    }
  }

  printf("Learning to talk... (setting up channels)\n");

  if (NULL == message) {
    if (server) {
      message = "\"Hello world!\", from server\n";
    } else {
      message = "\"Goodbye cruel world!\", from client\n";
    }
  }

  if (0 != (rv = NaClCommonDescMakeBoundSock(pair))) {
    fprintf(stderr, "make bound sock returned %"NACL_PRIdS"\n", rv);
    return 2;
  }

  if (!NaClNrdXferEffectorCtor(&eff, pair[0])) {
    fprintf(stderr, "EffectorCtor failed\n");
    return 3;
  }
  effp = (struct NaClDescEffector *) &eff;
  memset(desc_buffer, 0, sizeof desc_buffer);
  memset(data_buffer, 0, sizeof data_buffer);

  if (server) {
    /*
     * print out our sockaddr, accept a connection, then receive a message,
     * and print it out
     */

    /* not opaque type */
    printf("Server socket address:\n%.*s\n",
           NACL_PATH_MAX,
           ((struct NaClDescConnCap *) pair[1])->cap.path);
    fflush(stdout);

    if (0 != (rv = (*pair[0]->vtbl->AcceptConn)(pair[0], effp))) {
      fprintf(stderr, "AcceptConn returned %"NACL_PRIdS"\n", rv);
      return 4;
    }

    channel = NaClNrdXferEffectorTakeDesc(&eff);
    if (NULL == channel) {
      fprintf(stderr, "Could not take descriptor from accept\n");
      return 5;
    }

    iov[0].base = data_buffer;
    iov[0].length = sizeof data_buffer;

    msg_hdr.iov = iov;
    msg_hdr.iov_length = NACL_ARRAY_SIZE(iov);
    msg_hdr.ndescv = desc_buffer;
    msg_hdr.ndesc_length = NACL_ARRAY_SIZE(desc_buffer);

    rv = NaClImcRecvTypedMessage(channel, effp, &msg_hdr, 0);

    printf("Receive returned %"NACL_PRIdS"\n", rv);

    if (!NaClIsNegErrno(rv)) {
      /* Sanity check: make sure the return value is within range.
       * This is a panic check because NaClImcRecvTypedMessage should
       * never return more than the amount of data we asked for, and
       * that should never be more than INT_MAX.
       */
      if(((size_t)rv > sizeof data_buffer) || (rv > INT_MAX)) {
        NaClLog(LOG_FATAL, "Buffer overflow in NaClImcRecvTypedMessage. "
                "Requested %"NACL_PRIdS" bytes, received %"NACL_PRIdS".",
                sizeof data_buffer, rv);
      }
      /* Casting rv to int here because otherwise the pedantic Mac compiler
       * will complain. Cast is safe due to the range check above.
       */
      printf("Data bytes: %.*s\n", (int)rv, data_buffer);
      printf("Got %"NACL_PRIdNACL_SIZE" NaCl descriptors\n",
             msg_hdr.ndesc_length);

      for (i = 0; i < msg_hdr.ndesc_length; ++i) {
        struct NaClDesc *ndp;
        size_t msglen = strlen(message);
        ssize_t write_result;
        /*
         * TODO(bsy): a bit gross; we should expose type tags and RTTI
         * in a better way, e.g, downcast functions.  (Though exposing
         * type tags allows users to use a switch statement on the
         * type tag, rather than linearly trying to downcast to all
         * subclasses.)
         */
        ndp = msg_hdr.ndescv[i];
        printf(" type %d\n", ndp->vtbl->typeTag);

        write_result = (*ndp->vtbl->Write)(ndp,
                                           effp,
                                           (void *) message,
                                           msglen);
        if (-1 == write_result || msglen != (size_t) write_result) {
          printf("Write failed: got %"NACL_PRIdS", expected %"NACL_PRIuS"\n",
                 write_result, msglen);
        }

        NaClDescUnref(ndp);
      }
    }

    NaClDescUnref(channel);
    NaClDescUnref(pair[0]);
    NaClDescUnref(pair[1]);

  } else {
    if (NULL == conn_addr) {
      fprintf(stderr,
              "Client needs server socket address to which to connect\n");
      return 100;
    }

    memset(&nsa, 0, sizeof nsa);
    strncpy(nsa.path, conn_addr, sizeof nsa.path);  /* not nec'y NUL term'd */

    if (!NaClDescConnCapCtor(&ndcc, &nsa)) {
      fprintf(stderr,
              "Client conn cap initialization failed\n");
      return 101;
    }

    rv = (*ndcc.base.vtbl->ConnectAddr)((struct NaClDesc *) &ndcc, effp);

    printf("Connect returned %"NACL_PRIdS"\n", rv);

    if (0 != rv) {
      fprintf(stderr, "Client could not connect\n");
      return 102;
    }

    channel = NaClNrdXferEffectorTakeDesc(&eff);
    if (NULL == channel) {
      fprintf(stderr, "Could not take descriptor from connect\n");
      return 103;
    }

    strncpy(data_buffer, message, sizeof data_buffer);
    iov[0].base = data_buffer;
    iov[0].length = strlen(data_buffer);

    msg_hdr.iov = iov;
    msg_hdr.iov_length = NACL_ARRAY_SIZE(iov);
    msg_hdr.ndesc_length = 0;
    msg_hdr.ndescv = desc_buffer;

    if (NULL != transfer_file) {
      int                 xfer_fd;
      struct NaClHostDesc *nhdp = malloc(sizeof *nhdp);

      xfer_fd = OPEN(transfer_file, O_CREAT| O_WRONLY | O_TRUNC, 0777);
      if (-1 == xfer_fd) {
        fprintf(stderr, "Could not open file \"%s\" to transfer descriptor.\n",
                transfer_file);
        return 104;
      }
      NaClHostDescPosixTake(nhdp, xfer_fd, O_RDWR);
      desc_buffer[0] = (struct NaClDesc *) NaClDescIoDescMake(nhdp);
      msg_hdr.ndesc_length = 1;
    }

    rv = NaClImcSendTypedMessage(channel, effp, &msg_hdr, 0);

    if (NULL != desc_buffer[0]) {
      NaClDescUnref(desc_buffer[0]);
      desc_buffer[0] = NULL;
    }

    printf("Send returned %"NACL_PRIdS"\n", rv);
  }

  (*effp->vtbl->Dtor)(effp);

  NaClNrdAllModulesFini();
  return 0;
}
void bad()
{
    wchar_t * data;
    wchar_t dataBuffer[FILENAME_MAX] = BASEPATH;
    data = dataBuffer;
    switch(6)
    {
    case 6:
    {
#ifdef _WIN32
        WSADATA wsaData;
        int wsaDataInit = 0;
#endif
        int recvResult;
        struct sockaddr_in service;
        wchar_t *replace;
        SOCKET connectSocket = INVALID_SOCKET;
        size_t dataLen = wcslen(data);
        do
        {
#ifdef _WIN32
            if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
            {
                break;
            }
            wsaDataInit = 1;
#endif
            /* POTENTIAL FLAW: Read data using a connect socket */
            connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            if (connectSocket == INVALID_SOCKET)
            {
                break;
            }
            memset(&service, 0, sizeof(service));
            service.sin_family = AF_INET;
            service.sin_addr.s_addr = inet_addr(IP_ADDRESS);
            service.sin_port = htons(TCP_PORT);
            if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR)
            {
                break;
            }
            /* Abort on error or the connection was closed, make sure to recv one
             * less char than is in the recv_buf in order to append a terminator */
            /* Abort on error or the connection was closed */
            recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (FILENAME_MAX - dataLen - 1), 0);
            if (recvResult == SOCKET_ERROR || recvResult == 0)
            {
                break;
            }
            /* Append null terminator */
            data[dataLen + recvResult / sizeof(wchar_t)] = L'\0';
            /* Eliminate CRLF */
            replace = wcschr(data, L'\r');
            if (replace)
            {
                *replace = L'\0';
            }
            replace = wcschr(data, L'\n');
            if (replace)
            {
                *replace = L'\0';
            }
        }
        while (0);
        if (connectSocket != INVALID_SOCKET)
        {
            CLOSE_SOCKET(connectSocket);
        }
#ifdef _WIN32
        if (wsaDataInit)
        {
            WSACleanup();
        }
#endif
    }
    break;
    default:
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
        break;
    }
    {
        int fileDesc;
        /* POTENTIAL FLAW: Possibly opening a file without validating the file name or path */
        fileDesc = OPEN(data, O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
        if (fileDesc != -1)
        {
            CLOSE(fileDesc);
        }
    }
}
/* goodB2G() uses the BadSource with the GoodSink */
static void goodB2GSource(int &data)
{
    /* POTENTIAL FLAW: Open a file without closing it */
    data = OPEN("BadSource_open.txt", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
}
Beispiel #23
0
int4 mupip_set_file(int db_fn_len, char *db_fn)
{
	bool			got_standalone;
	boolean_t		bypass_partial_recov, need_standalone = FALSE;
	char			acc_spec[MAX_ACC_METH_LEN], ver_spec[MAX_DB_VER_LEN], exit_stat, *fn;
	unsigned short		acc_spec_len = MAX_ACC_METH_LEN, ver_spec_len = MAX_DB_VER_LEN;
	int			fd, fn_len;
	int4			status;
	int4			status1;
	int			glbl_buff_status, defer_status, rsrvd_bytes_status,
				extn_count_status, lock_space_status, disk_wait_status;
	int4			new_disk_wait, new_cache_size, new_extn_count, new_lock_space, reserved_bytes, defer_time;
	sgmnt_data_ptr_t	csd;
	tp_region		*rptr, single;
	enum db_acc_method	access, access_new;
	enum db_ver		desired_dbver;
	gd_region		*temp_cur_region;
	char			*errptr, *command = "MUPIP SET VERSION";
	int			save_errno;

	error_def(ERR_DBPREMATEOF);
	error_def(ERR_DBRDERR);
	error_def(ERR_DBRDONLY);
	error_def(ERR_INVACCMETHOD);
	error_def(ERR_MUNOACTION);
	error_def(ERR_RBWRNNOTCHG);
	error_def(ERR_WCERRNOTCHG);
	error_def(ERR_WCWRNNOTCHG);
	error_def(ERR_MMNODYNDWNGRD);

	exit_stat = EXIT_NRM;
	defer_status = cli_present("DEFER_TIME");
	if (defer_status)
		need_standalone = TRUE;
	bypass_partial_recov = cli_present("PARTIAL_RECOV_BYPASS") == CLI_PRESENT;
	if (bypass_partial_recov)
		need_standalone = TRUE;
	if (disk_wait_status = cli_present("WAIT_DISK"))
	{
		if (cli_get_int("WAIT_DISK", &new_disk_wait))
		{
			if (new_disk_wait < 0)
			{
				util_out_print("!UL negative, minimum WAIT_DISK allowed is 0.", TRUE, new_disk_wait);
				return (int4)ERR_WCWRNNOTCHG;
			}
			need_standalone = TRUE;
		} else
		{
			util_out_print("Error getting WAIT_DISK qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
	}
	if (glbl_buff_status = cli_present("GLOBAL_BUFFERS"))
	{
		if (cli_get_int("GLOBAL_BUFFERS", &new_cache_size))
		{
			if (new_cache_size > WC_MAX_BUFFS)
			{
				util_out_print("!UL too large, maximum write cache buffers allowed is !UL", TRUE, new_cache_size,
						WC_MAX_BUFFS);
				return (int4)ERR_WCWRNNOTCHG;
			}
			if (new_cache_size < WC_MIN_BUFFS)
			{
				util_out_print("!UL too small, minimum cache buffers allowed is !UL", TRUE, new_cache_size,
						WC_MIN_BUFFS);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting GLOBAL BUFFER qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	/* EXTENSION_COUNT does not require standalone access and hence need_standalone will not be set to TRUE for this. */
	if (extn_count_status = cli_present("EXTENSION_COUNT"))
	{
		if (cli_get_int("EXTENSION_COUNT", &new_extn_count))
		{
			if (new_extn_count > MAX_EXTN_COUNT)
			{
				util_out_print("!UL too large, maximum extension count allowed is !UL", TRUE, new_extn_count,
						MAX_EXTN_COUNT);
				return (int4)ERR_WCWRNNOTCHG;
			}
			if (new_extn_count < MIN_EXTN_COUNT)
			{
				util_out_print("!UL too small, minimum extension count allowed is !UL", TRUE, new_extn_count,
						MIN_EXTN_COUNT);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting EXTENSION COUNT qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
	}
	if (lock_space_status = cli_present("LOCK_SPACE"))
	{
		if (cli_get_int("LOCK_SPACE", &new_lock_space))
		{
			if (new_lock_space > MAX_LOCK_SPACE)
			{
				util_out_print("!UL too large, maximum lock space allowed is !UL", TRUE,
						new_lock_space, MAX_LOCK_SPACE);
				return (int4)ERR_WCWRNNOTCHG;
			}
			else if (new_lock_space < MIN_LOCK_SPACE)
			{
				util_out_print("!UL too small, minimum lock space allowed is !UL", TRUE,
						new_lock_space, MIN_LOCK_SPACE);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting LOCK_SPACE qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	if (rsrvd_bytes_status = cli_present("RESERVED_BYTES"))
	{
		if (!cli_get_int("RESERVED_BYTES", &reserved_bytes))
		{
			util_out_print("Error getting RESERVED BYTES qualifier value", TRUE);
			return (int4)ERR_RBWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	if (cli_present("ACCESS_METHOD"))
	{
		cli_get_str("ACCESS_METHOD", acc_spec, &acc_spec_len);
		cli_strupper(acc_spec);
		if (0 == memcmp(acc_spec, "MM", acc_spec_len))
			access = dba_mm;
		else  if (0 == memcmp(acc_spec, "BG", acc_spec_len))
			access = dba_bg;
		else
			mupip_exit(ERR_INVACCMETHOD);
		need_standalone = TRUE;
	} else
		access = n_dba;		/* really want to keep current method,
					    which has not yet been read */
	if (cli_present("VERSION"))
	{
		assert(!need_standalone);
		cli_get_str("VERSION", ver_spec, &ver_spec_len);
		cli_strupper(ver_spec);
		if (0 == memcmp(ver_spec, "V4", ver_spec_len))
			desired_dbver = GDSV4;
		else  if (0 == memcmp(ver_spec, "V5", ver_spec_len))
			desired_dbver = GDSV5;
		else
			GTMASSERT;		/* CLI should prevent us ever getting here */
	} else
		desired_dbver = GDSVLAST;	/* really want to keep version, which has not yet been read */
	if (region)
		rptr = grlist;
	else
	{
		rptr = &single;
		memset(&single, 0, sizeof(single));
	}

	csd = (sgmnt_data *)malloc(ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE));
	in_backup = FALSE;		/* Only want yes/no from mupfndfil, not an address */
	for (;  rptr != NULL;  rptr = rptr->fPtr)
	{
		if (region)
		{
			if (dba_usr == rptr->reg->dyn.addr->acc_meth)
			{
				util_out_print("!/Region !AD is not a GDS access type", TRUE, REG_LEN_STR(rptr->reg));
				exit_stat |= EXIT_WRN;
				continue;
			}
			if (!mupfndfil(rptr->reg, NULL))
				continue;
			fn = (char *)rptr->reg->dyn.addr->fname;
			fn_len = rptr->reg->dyn.addr->fname_len;
		} else
		{
			fn = db_fn;
			fn_len = db_fn_len;
		}
		mu_gv_cur_reg_init();
		strcpy((char *)gv_cur_region->dyn.addr->fname, fn);
		gv_cur_region->dyn.addr->fname_len = fn_len;
		if (!need_standalone)
		{
			gvcst_init(gv_cur_region);
			change_reg();	/* sets cs_addrs and cs_data */
			if (gv_cur_region->read_only)
			{
				gtm_putmsg(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
				exit_stat |= EXIT_ERR;
				gds_rundown();
				mu_gv_cur_reg_free();
				continue;
			}
			grab_crit(gv_cur_region);
			status = EXIT_NRM;
			access_new = (n_dba == access ? cs_data->acc_meth : access);
							/* recalculate; n_dba is a proxy for no change */
			change_fhead_timer("FLUSH_TIME", cs_data->flush_time,
					   (dba_bg == access_new ? TIM_FLU_MOD_BG : TIM_FLU_MOD_MM),
					   FALSE);
			if (GDSVLAST != desired_dbver)
			{
				if ((dba_mm != access_new) || (GDSV4 != desired_dbver))
					status1 = desired_db_format_set(gv_cur_region, desired_dbver, command);
				else
				{
					status1 = ERR_MMNODYNDWNGRD;
					gtm_putmsg(VARLSTCNT(4) status1, 2, REG_LEN_STR(gv_cur_region));
				}
				if (SS_NORMAL != status1)
				{	/* "desired_db_format_set" would have printed appropriate error messages */
					if (ERR_MUNOACTION != status1)
					{	/* real error occurred while setting the db format. skip to next region */
						status = EXIT_ERR;
					}
				}
			}
			if (EXIT_NRM == status)
			{
				if (extn_count_status)
					cs_data->extension_size = (uint4)new_extn_count;
				wcs_flu(WCSFLU_FLUSH_HDR);
				if (extn_count_status)
					util_out_print("Database file !AD now has extension count !UL",
						TRUE, fn_len, fn, cs_data->extension_size);
				if (GDSVLAST != desired_dbver)
					util_out_print("Database file !AD now has desired DB format !AD", TRUE,
						fn_len, fn, LEN_AND_STR(gtm_dbversion_table[cs_data->desired_db_format]));
			} else
				exit_stat |= status;
			rel_crit(gv_cur_region);
			gds_rundown();
		} else
		{	/* Following part needs standalone access */
			assert(GDSVLAST == desired_dbver);
			got_standalone = mu_rndwn_file(gv_cur_region, TRUE);
			if (FALSE == got_standalone)
				return (int4)ERR_WCERRNOTCHG;
			/* we should open it (for changing) after mu_rndwn_file, since mu_rndwn_file changes the file header too */
			if (-1 == (fd = OPEN(fn, O_RDWR)))
			{
				save_errno = errno;
				errptr = (char *)STRERROR(save_errno);
				util_out_print("open : !AZ", TRUE, errptr);
				exit_stat |= EXIT_ERR;
				db_ipcs_reset(gv_cur_region, FALSE);
				mu_gv_cur_reg_free();
				continue;
			}
			LSEEKREAD(fd, 0, csd, sizeof(sgmnt_data), status);
			if (0 != status)
			{
				save_errno = errno;
				PERROR("Error reading header of file");
				errptr = (char *)STRERROR(save_errno);
				util_out_print("read : !AZ", TRUE, errptr);
				util_out_print("Error reading header of file", TRUE);
				util_out_print("Database file !AD not changed:  ", TRUE, fn_len, fn);
				if (-1 != status)
					rts_error(VARLSTCNT(4) ERR_DBRDERR, 2, fn_len, fn);
				else
					rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
			}
			if (rsrvd_bytes_status)
			{
				if (reserved_bytes > MAX_RESERVE_B(csd))
				{
					util_out_print("!UL too large, maximum reserved bytes allowed is !UL for database file !AD",
							TRUE, reserved_bytes, MAX_RESERVE_B(csd), fn_len, fn);
					close(fd);
					db_ipcs_reset(gv_cur_region, FALSE);
					return (int4)ERR_RBWRNNOTCHG;
				}
				csd->reserved_bytes = reserved_bytes;
			}
			access_new = (n_dba == access ? csd->acc_meth : access);
							/* recalculate; n_dba is a proxy for no change */
			change_fhead_timer("FLUSH_TIME", csd->flush_time,
					   (dba_bg == access_new ? TIM_FLU_MOD_BG : TIM_FLU_MOD_MM),
					   FALSE);
			if ((n_dba != access) && (csd->acc_meth != access))	/* n_dba is a proxy for no change */
			{
				if (dba_mm == access)
					csd->defer_time = 1;			/* defer defaults to 1 */
				csd->acc_meth = access;
				if (0 == csd->n_bts)
				{
					csd->n_bts = WC_DEF_BUFFS;
					csd->bt_buckets = getprime(csd->n_bts);
				}
			}
			if (glbl_buff_status)
			{
				csd->n_bts = BT_FACTOR(new_cache_size);
				csd->bt_buckets = getprime(csd->n_bts);
				csd->n_wrt_per_flu = 7;
				csd->flush_trigger = FLUSH_FACTOR(csd->n_bts);
			}
			if (disk_wait_status)
				csd->wait_disk_space = new_disk_wait;
			if (extn_count_status)
				csd->extension_size = (uint4)new_extn_count;
			if (lock_space_status)
				csd->lock_space_size = (uint4)new_lock_space * OS_PAGELET_SIZE;
			if (bypass_partial_recov)
			{
				csd->file_corrupt = FALSE;
				util_out_print("Database file !AD now has partial recovery flag set to  !UL(FALSE) ",
						TRUE, fn_len, fn, csd->file_corrupt);
			}
			if (dba_mm == access_new)
			{
				if (CLI_NEGATED == defer_status)
					csd->defer_time = 0;
				else  if (CLI_PRESENT == defer_status)
				{
					if (!cli_get_num("DEFER_TIME", &defer_time))
					{
						util_out_print("Error getting DEFER_TIME qualifier value", TRUE);
						db_ipcs_reset(gv_cur_region, FALSE);
						return (int4)ERR_RBWRNNOTCHG;
					}
					if (-1 > defer_time)
					{
						util_out_print("DEFER_TIME cannot take negative values less than -1", TRUE);
						util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
						exit_stat |= EXIT_WRN;
						db_ipcs_reset(gv_cur_region, FALSE);
						mu_gv_cur_reg_free();
						continue;
					}
					csd->defer_time = defer_time;
				}
				if (csd->blks_to_upgrd)
				{
					util_out_print("MM access method cannot be set if there are blocks to upgrade",	TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				if (GDSVCURR != csd->desired_db_format)
				{
					util_out_print("MM access method cannot be set in DB compatibility mode",
						TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				if (JNL_ENABLED(csd) && csd->jnl_before_image)
				{
					util_out_print("MM access method cannot be set with BEFORE image journaling", TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				csd->jnl_before_image = FALSE;
			} else
			{
				if (defer_status)
				{
					util_out_print("DEFER cannot be specified with BG access method.", TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
			}
			LSEEKWRITE(fd, 0, csd, sizeof(sgmnt_data), status);
			if (0 != status)
			{
				save_errno = errno;
				errptr = (char *)STRERROR(save_errno);
				util_out_print("write : !AZ", TRUE, errptr);
				util_out_print("Error writing header of file", TRUE);
				util_out_print("Database file !AD not changed: ", TRUE, fn_len, fn);
				rts_error(VARLSTCNT(4) ERR_DBRDERR, 2, fn_len, fn);
			}
			close(fd);
			/* --------------------- report results ------------------------- */
			if (glbl_buff_status)
				util_out_print("Database file !AD now has !UL global buffers",
						TRUE, fn_len, fn, csd->n_bts);
			if (defer_status && (dba_mm == csd->acc_meth))
				util_out_print("Database file !AD now has defer_time set to !SL",
						TRUE, fn_len, fn, csd->defer_time);
			if (rsrvd_bytes_status)
				util_out_print("Database file !AD now has !UL reserved bytes",
						TRUE, fn_len, fn, csd->reserved_bytes);
			if (extn_count_status)
				util_out_print("Database file !AD now has extension count !UL",
						TRUE, fn_len, fn, csd->extension_size);
			if (lock_space_status)
				util_out_print("Database file !AD now has lock space !UL pages",
						TRUE, fn_len, fn, csd->lock_space_size/OS_PAGELET_SIZE);
			if (disk_wait_status)
				util_out_print("Database file !AD now has wait disk set to !UL seconds",
						TRUE, fn_len, fn, csd->wait_disk_space);
			db_ipcs_reset(gv_cur_region, FALSE);
		} /* end of else part if (!need_standalone) */
		mu_gv_cur_reg_free();
	}
	free(csd);
	assert(!(exit_stat & EXIT_INF));
	return (exit_stat & EXIT_ERR ? (int4)ERR_WCERRNOTCHG :
		(exit_stat & EXIT_WRN ? (int4)ERR_WCWRNNOTCHG : SS_NORMAL));
}
Beispiel #24
0
static boolean disk_file_init(DISK_FILE* file, uint32 DesiredAccess, uint32 CreateDisposition, uint32 CreateOptions)
{
    const static int mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
    struct STAT st;
    boolean exists;
#ifndef WIN32
    boolean largeFile = false;
#endif
    int oflag = 0;

    if (STAT(file->fullpath, &st) == 0)
    {
        file->is_dir = (S_ISDIR(st.st_mode) ? true : false);
#ifndef WIN32
        if (st.st_size > (unsigned long)0x07fffffff)
            largeFile = true;
#endif
        exists = true;
    }
    else
    {
        file->is_dir = ((CreateOptions & FILE_DIRECTORY_FILE) ? true : false);
        if (file->is_dir)
        {
            //Should only create the directory if the disposition allows for it
            if ((CreateDisposition == FILE_OPEN_IF) || (CreateDisposition == FILE_CREATE))
            {
                if (mkdir(file->fullpath, mode) != 0)
                {
                    file->err = errno;
                    return true;
                }
            }
        }
        exists = false;
    }

    if (file->is_dir)
    {
        file->dir = opendir(file->fullpath);
        if (file->dir == NULL)
        {
            file->err = errno;
            return true;
        }
    }
    else
    {
        switch (CreateDisposition)
        {
        case FILE_SUPERSEDE:
            oflag = O_TRUNC | O_CREAT;
            break;
        case FILE_OPEN:
            break;
        case FILE_CREATE:
            oflag = O_CREAT | O_EXCL;
            break;
        case FILE_OPEN_IF:
            oflag = O_CREAT;
            break;
        case FILE_OVERWRITE:
            oflag = O_TRUNC;
            break;
        case FILE_OVERWRITE_IF:
            oflag = O_TRUNC | O_CREAT;
            break;
        default:
            break;
        }

        if (CreateOptions & FILE_DELETE_ON_CLOSE && DesiredAccess & DELETE)
        {
            file->delete_pending = true;
        }

        if ((DesiredAccess & GENERIC_ALL)
                || (DesiredAccess & GENERIC_WRITE)
                || (DesiredAccess & FILE_WRITE_DATA)
                || (DesiredAccess & FILE_APPEND_DATA))
        {
            oflag |= O_RDWR;
        }
        else
        {
            oflag |= O_RDONLY;
        }
#ifndef WIN32
        if (largeFile)
        {
            oflag |= O_LARGEFILE;
        }
#endif
        file->fd = OPEN(file->fullpath, oflag, mode);
        if (file->fd == -1)
        {
            file->err = errno;
            return true;
        }
    }

    return true;
}
Beispiel #25
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "checksum");

	if (argc < 2)
		UT_FATAL("usage: %s files...", argv[0]);

	for (int arg = 1; arg < argc; arg++) {
		int fd = OPEN(argv[arg], O_RDONLY);

		os_stat_t stbuf;
		FSTAT(fd, &stbuf);
		size_t size = (size_t)stbuf.st_size;

		void *addr =
			MMAP(NULL, size, PROT_READ|PROT_WRITE,
					MAP_PRIVATE, fd, 0);

		uint64_t *ptr = addr;

		/*
		 * Loop through, selecting successive locations
		 * where the checksum lives in this block, and
		 * let util_checksum() insert it so it can be
		 * verified against the gold standard fletcher64
		 * routine in this file.
		 */
		while ((char *)(ptr + 1) < (char *)addr + size) {
			/* save whatever was at *ptr */
			uint64_t oldval = *ptr;

			/* mess with it */
			*ptr = htole64(0x123);

			/*
			 * calculate a checksum and have it installed
			 */
			util_checksum(addr, size, ptr, 1, 0);

			uint64_t csum = *ptr;

			/*
			 * verify inserted checksum checks out
			 */
			UT_ASSERT(util_checksum(addr, size, ptr, 0, 0));

			/* put a zero where the checksum was installed */
			*ptr = 0;

			/* calculate a checksum */
			uint64_t gold_csum = fletcher64(addr, size);

			/* put the old value back */
			*ptr = oldval;

			/*
			 * verify checksum now fails
			 */
			UT_ASSERT(!util_checksum(addr, size, ptr,
					0, 0));

			/*
			 * verify the checksum matched the gold version
			 */
			UT_ASSERTeq(csum, gold_csum);
			UT_OUT("%s:%" PRIu64 " 0x%" PRIx64, argv[arg],
				(char *)ptr - (char *)addr, csum);

			ptr++;
		}

		uint64_t *addr2 =
			MMAP(NULL, size, PROT_READ|PROT_WRITE,
				MAP_PRIVATE, fd, 0);

		uint64_t *csum = (uint64_t *)addr;

		/*
		 * put a zero where the checksum will be installed
		 * in the second map
		 */
		*addr2 = 0;
		for (size_t i = size / 8 - 1; i > 0; i -= 1) {
			/* calculate a checksum and have it installed */
			util_checksum(addr, size, csum, 1, i * 8);

			/*
			 * put a zero in the second map where an ignored part is
			 */
			*(addr2 + i) = 0;

			/* calculate a checksum */
			uint64_t gold_csum = fletcher64(addr2, size);
			/*
			 * verify the checksum matched the gold version
			 */
			UT_ASSERTeq(*csum, gold_csum);
		}

		CLOSE(fd);
		MUNMAP(addr, size);
		MUNMAP(addr2, size);

	}

	DONE(NULL);
}
CWE675_Duplicate_Operations_on_Resource__open_84_goodG2B::CWE675_Duplicate_Operations_on_Resource__open_84_goodG2B(int dataCopy)
{
    data = dataCopy;
    /* FIX: Open, but do not close the file in the source */
    data = OPEN("GoodSource_open.txt", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
}
Beispiel #27
0
/** Unpack a list of files in an archive.
 * @param handle the context handle
 * @param path the archive to unpack
 * @param prefix where to extract the files
 * @param list a list of files within the archive to unpack or NULL for all
 * @param breakfirst break after the first entry found
 * @return 0 on success, 1 on failure
 */
int _alpm_unpack(alpm_handle_t *handle, const char *path, const char *prefix,
		alpm_list_t *list, int breakfirst)
{
	int ret = 0;
	mode_t oldmask;
	struct archive *archive;
	struct archive_entry *entry;
	struct stat buf;
	int fd, cwdfd;

	fd = _alpm_open_archive(handle, path, &buf, &archive, ALPM_ERR_PKG_OPEN);
	if(fd < 0) {
		return 1;
	}

	oldmask = umask(0022);

	/* save the cwd so we can restore it later */
	OPEN(cwdfd, ".", O_RDONLY);
	if(cwdfd < 0) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
	}

	/* just in case our cwd was removed in the upgrade operation */
	if(chdir(prefix) != 0) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
				prefix, strerror(errno));
		ret = 1;
		goto cleanup;
	}

	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
		const char *entryname;
		mode_t mode;

		entryname = archive_entry_pathname(entry);

		/* If specific files were requested, skip entries that don't match. */
		if(list) {
			char *entry_prefix = strdup(entryname);
			char *p = strstr(entry_prefix,"/");
			if(p) {
				*(p+1) = '\0';
			}
			char *found = alpm_list_find_str(list, entry_prefix);
			free(entry_prefix);
			if(!found) {
				if(archive_read_data_skip(archive) != ARCHIVE_OK) {
					ret = 1;
					goto cleanup;
				}
				continue;
			} else {
				_alpm_log(handle, ALPM_LOG_DEBUG, "extracting: %s\n", entryname);
			}
		}

		mode = archive_entry_mode(entry);
		if(S_ISREG(mode)) {
			archive_entry_set_perm(entry, 0644);
		} else if(S_ISDIR(mode)) {
			archive_entry_set_perm(entry, 0755);
		}

		/* Extract the archive entry. */
		int readret = archive_read_extract(archive, entry, 0);
		if(readret == ARCHIVE_WARN) {
			/* operation succeeded but a non-critical error was encountered */
			_alpm_log(handle, ALPM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),
					entryname, archive_error_string(archive));
		} else if(readret != ARCHIVE_OK) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("could not extract %s (%s)\n"),
					entryname, archive_error_string(archive));
			ret = 1;
			goto cleanup;
		}

		if(breakfirst) {
			break;
		}
	}

cleanup:
	umask(oldmask);
	archive_read_finish(archive);
	CLOSE(fd);
	if(cwdfd >= 0) {
		if(fchdir(cwdfd) != 0) {
			_alpm_log(handle, ALPM_LOG_ERROR,
					_("could not restore working directory (%s)\n"), strerror(errno));
		}
		CLOSE(cwdfd);
	}

	return ret;
}
Beispiel #28
0
/**
 * Main function that will be run.
 *
 * @param cls closure
 * @param args remaining command-line arguments
 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
 * @param c configuration
 */
static void
run (void *cls,
     char *const *args,
     const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *c)
{
  struct stat st;
  char *dir;
  char *fn;
  int fd;

  cfg = c;
  dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
  GNUNET_assert (NULL != dir);
  GNUNET_asprintf (&fn,
                   "%s%s%s",
                   dir,
                   DIR_SEPARATOR_STR,
                   "gns-bcd.html");
  GNUNET_asprintf (&resfile,
                   "%s%s%s",
                   dir,
                   DIR_SEPARATOR_STR,
                   "gns-bcd.tex");
  GNUNET_free (dir);
  fd = OPEN (fn, O_RDONLY);
  if (-1 == fd)
  {
    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                              "open",
                              fn);
    GNUNET_free (fn);
    return;
  }
  if (0 != STAT (fn, &st))
  {
    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                              "open",
                              fn);
    GNUNET_free (fn);
    CLOSE (fd);
    return;
  }
  GNUNET_free (fn);
  if (NULL == (main_response = MHD_create_response_from_fd ((size_t) st.st_size, fd)))
  {
    GNUNET_break (0);
    GNUNET_break (0 == CLOSE (fd));
    return;
  }
  (void) MHD_add_response_header (main_response,
                                  MHD_HTTP_HEADER_CONTENT_TYPE,
                                  "text/html");
  invalid_gnskey_response = MHD_create_response_from_buffer (strlen (INVALID_GNSKEY),
                                                             INVALID_GNSKEY,
                                                             MHD_RESPMEM_PERSISTENT);
  (void) MHD_add_response_header (invalid_gnskey_response,
                                  MHD_HTTP_HEADER_CONTENT_TYPE,
                                  "text/html");
  not_found_response = MHD_create_response_from_buffer (strlen (NOT_FOUND),
                                                        NOT_FOUND,
                                                        MHD_RESPMEM_PERSISTENT);
  (void) MHD_add_response_header (not_found_response,
                                  MHD_HTTP_HEADER_CONTENT_TYPE,
                                  "text/html");
  if (GNUNET_OK !=
      server_start ())
    return;
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
                                &server_stop,
                                NULL);
}
Beispiel #29
0
static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
		struct archive_entry *entry, alpm_pkg_t *newpkg, alpm_pkg_t *oldpkg)
{
	const char *entryname = archive_entry_pathname(entry);
	mode_t entrymode = archive_entry_mode(entry);
	alpm_backup_t *backup = _alpm_needbackup(entryname, newpkg);
	char filename[PATH_MAX]; /* the actual file we're extracting */
	int needbackup = 0, notouch = 0;
	const char *hash_orig = NULL;
	int isnewfile = 0, errors = 0;
	struct stat lsbuf;
	size_t filename_len;

	if(*entryname == '.') {
		return extract_db_file(handle, archive, entry, newpkg, entryname);
	}

	if (!alpm_filelist_contains(&newpkg->files, entryname)) {
		_alpm_log(handle, ALPM_LOG_WARNING,
				_("file not found in file list for package %s. skipping extraction of %s\n"),
				newpkg->name, entryname);
		return 0;
	}

	/* build the new entryname relative to handle->root */
	filename_len = snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname);
	if(filename_len >= PATH_MAX) {
		_alpm_log(handle, ALPM_LOG_ERROR,
				_("unable to extract %s%s: path too long"), handle->root, entryname);
		return 1;
	}

	/* if a file is in NoExtract then we never extract it */
	if(_alpm_fnmatch_patterns(handle->noextract, entryname) == 0) {
		_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoExtract,"
				" skipping extraction of %s\n",
				entryname, filename);
		archive_read_data_skip(archive);
		return 0;
	}

	/* Check for file existence. This is one of the more crucial parts
	 * to get 'right'. Here are the possibilities, with the filesystem
	 * on the left and the package on the top:
	 * (F=file, N=node, S=symlink, D=dir)
	 *               |  F/N  |   D
	 *  non-existent |   1   |   2
	 *  F/N          |   3   |   4
	 *  D            |   5   |   6
	 *
	 *  1,2- extract, no magic necessary. lstat (llstat) will fail here.
	 *  3,4- conflict checks should have caught this. either overwrite
	 *      or backup the file.
	 *  5- file replacing directory- don't allow it.
	 *  6- skip extraction, dir already exists.
	 */

	isnewfile = llstat(filename, &lsbuf) != 0;
	if(isnewfile) {
		/* cases 1,2: file doesn't exist, skip all backup checks */
	} else if(S_ISDIR(lsbuf.st_mode) && S_ISDIR(entrymode)) {
#if 0
		uid_t entryuid = archive_entry_uid(entry);
		gid_t entrygid = archive_entry_gid(entry);
#endif

		/* case 6: existing dir, ignore it */
		if(lsbuf.st_mode != entrymode) {
			/* if filesystem perms are different than pkg perms, warn user */
			mode_t mask = 07777;
			_alpm_log(handle, ALPM_LOG_WARNING, _("directory permissions differ on %s\n"
					"filesystem: %o  package: %o\n"), filename, lsbuf.st_mode & mask,
					entrymode & mask);
			alpm_logaction(handle, ALPM_CALLER_PREFIX,
					"warning: directory permissions differ on %s\n"
					"filesystem: %o  package: %o\n", filename, lsbuf.st_mode & mask,
					entrymode & mask);
		}

#if 0
		/* Disable this warning until our user management in packages has improved.
		   Currently many packages have to create users in post_install and chown the
		   directories. These all resulted in "false-positive" warnings. */

		if((entryuid != lsbuf.st_uid) || (entrygid != lsbuf.st_gid)) {
			_alpm_log(handle, ALPM_LOG_WARNING, _("directory ownership differs on %s\n"
					"filesystem: %u:%u  package: %u:%u\n"), filename,
					lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
			alpm_logaction(handle, ALPM_CALLER_PREFIX,
					"warning: directory ownership differs on %s\n"
					"filesystem: %u:%u  package: %u:%u\n", filename,
					lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
		}
#endif

		_alpm_log(handle, ALPM_LOG_DEBUG, "extract: skipping dir extraction of %s\n",
				filename);
		archive_read_data_skip(archive);
		return 0;
	} else if(S_ISDIR(lsbuf.st_mode)) {
		/* case 5: trying to overwrite dir with file, don't allow it */
		_alpm_log(handle, ALPM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"),
				filename);
		archive_read_data_skip(archive);
		return 1;
	} else if(S_ISDIR(entrymode)) {
		/* case 4: trying to overwrite file with dir */
		_alpm_log(handle, ALPM_LOG_DEBUG, "extract: overwriting file with dir %s\n",
				filename);
	} else {
		/* case 3: trying to overwrite file with file */
		/* if file is in NoUpgrade, don't touch it */
		if(_alpm_fnmatch_patterns(handle->noupgrade, entryname) == 0) {
			notouch = 1;
		} else {
			alpm_backup_t *oldbackup;
			if(oldpkg && (oldbackup = _alpm_needbackup(entryname, oldpkg))) {
				hash_orig = oldbackup->hash;
				needbackup = 1;
			} else if(backup) {
				/* allow adding backup files retroactively */
				needbackup = 1;
			}
		}
	}

	if(notouch || needbackup) {
		if(filename_len + strlen(".pacnew") >= PATH_MAX) {
			_alpm_log(handle, ALPM_LOG_ERROR,
					_("unable to extract %s.pacnew: path too long"), filename);
			return 1;
		}
		strcpy(filename + filename_len, ".pacnew");
		isnewfile = (llstat(filename, &lsbuf) != 0 && errno == ENOENT);
	}

	_alpm_log(handle, ALPM_LOG_DEBUG, "extracting %s\n", filename);
	if(perform_extraction(handle, archive, entry, filename)) {
		errors++;
		return errors;
	}

	if(backup) {
		FREE(backup->hash);
		backup->hash = alpm_compute_md5sum(filename);
	}

	if(notouch) {
		alpm_event_pacnew_created_t event = {
			.type = ALPM_EVENT_PACNEW_CREATED,
			.from_noupgrade = 1,
			.oldpkg = oldpkg,
			.newpkg = newpkg,
			.file = filename
		};
		/* "remove" the .pacnew suffix */
		filename[filename_len] = '\0';
		EVENT(handle, &event);
		alpm_logaction(handle, ALPM_CALLER_PREFIX,
				"warning: %s installed as %s.pacnew\n", filename, filename);
	} else if(needbackup) {
		char *hash_local = NULL, *hash_pkg = NULL;
		char origfile[PATH_MAX] = "";

		strncat(origfile, filename, filename_len);

		hash_local = alpm_compute_md5sum(origfile);
		hash_pkg = backup ? backup->hash : alpm_compute_md5sum(filename);

		_alpm_log(handle, ALPM_LOG_DEBUG, "checking hashes for %s\n", origfile);
		_alpm_log(handle, ALPM_LOG_DEBUG, "current:  %s\n", hash_local);
		_alpm_log(handle, ALPM_LOG_DEBUG, "new:      %s\n", hash_pkg);
		_alpm_log(handle, ALPM_LOG_DEBUG, "original: %s\n", hash_orig);

		if(hash_local && hash_pkg && strcmp(hash_local, hash_pkg) == 0) {
			/* local and new files are the same, updating anyway to get
			 * correct timestamps */
			_alpm_log(handle, ALPM_LOG_DEBUG, "action: installing new file: %s\n",
					origfile);
			if(try_rename(handle, filename, origfile)) {
				errors++;
			}
		} else if(hash_orig && hash_pkg && strcmp(hash_orig, hash_pkg) == 0) {
			/* original and new files are the same, leave the local version alone,
			 * including any user changes */
			_alpm_log(handle, ALPM_LOG_DEBUG,
					"action: leaving existing file in place\n");
			if(isnewfile) {
				unlink(filename);
			}
		} else if(hash_orig && hash_local && strcmp(hash_orig, hash_local) == 0) {
			/* installed file has NOT been changed by user,
			 * update to the new version */
			_alpm_log(handle, ALPM_LOG_DEBUG, "action: installing new file: %s\n",
					origfile);
			if(try_rename(handle, filename, origfile)) {
				errors++;
			}
		} else {
			/* none of the three files matched another,  leave the unpacked
			 * file alongside the local file */
			alpm_event_pacnew_created_t event = {
				.type = ALPM_EVENT_PACNEW_CREATED,
				.from_noupgrade = 0,
				.oldpkg = oldpkg,
				.newpkg = newpkg,
				.file = origfile
			};
			_alpm_log(handle, ALPM_LOG_DEBUG,
					"action: keeping current file and installing"
					" new one with .pacnew ending\n");
			EVENT(handle, &event);
			alpm_logaction(handle, ALPM_CALLER_PREFIX,
					"warning: %s installed as %s\n", origfile, filename);
		}

		free(hash_local);
		if(!backup) {
			free(hash_pkg);
		}
	}
	return errors;
}

static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
		size_t pkg_current, size_t pkg_count)
{
	int i, ret = 0, errors = 0;
	int is_upgrade = 0;
	alpm_pkg_t *oldpkg = NULL;
	alpm_db_t *db = handle->db_local;
	alpm_trans_t *trans = handle->trans;
	alpm_progress_t progress = ALPM_PROGRESS_ADD_START;
	alpm_event_package_operation_t event;
	const char *log_msg = "adding";
	const char *pkgfile;

	ASSERT(trans != NULL, return -1);

	/* see if this is an upgrade. if so, remove the old package first */
	if((oldpkg = newpkg->oldpkg)) {
		int cmp = _alpm_pkg_compare_versions(newpkg, oldpkg);
		if(cmp < 0) {
			log_msg = "downgrading";
			progress = ALPM_PROGRESS_DOWNGRADE_START;
			event.operation = ALPM_PACKAGE_DOWNGRADE;
		} else if(cmp == 0) {
			log_msg = "reinstalling";
			progress = ALPM_PROGRESS_REINSTALL_START;
			event.operation = ALPM_PACKAGE_REINSTALL;
		} else {
			log_msg = "upgrading";
			progress = ALPM_PROGRESS_UPGRADE_START;
			event.operation = ALPM_PACKAGE_UPGRADE;
		}
		is_upgrade = 1;

		/* copy over the install reason */
		newpkg->reason = alpm_pkg_get_reason(oldpkg);
	} else {
		event.operation = ALPM_PACKAGE_INSTALL;
	}

	event.type = ALPM_EVENT_PACKAGE_OPERATION_START;
	event.oldpkg = oldpkg;
	event.newpkg = newpkg;
	EVENT(handle, &event);

	pkgfile = newpkg->origin_data.file;

	_alpm_log(handle, ALPM_LOG_DEBUG, "%s package %s-%s\n",
			log_msg, newpkg->name, newpkg->version);
		/* pre_install/pre_upgrade scriptlet */
	if(alpm_pkg_has_scriptlet(newpkg) &&
			!(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
		const char *scriptlet_name = is_upgrade ? "pre_upgrade" : "pre_install";

		_alpm_runscriptlet(handle, pkgfile, scriptlet_name,
				newpkg->version, oldpkg ? oldpkg->version : NULL, 1);
	}

	/* we override any pre-set reason if we have alldeps or allexplicit set */
	if(trans->flags & ALPM_TRANS_FLAG_ALLDEPS) {
		newpkg->reason = ALPM_PKG_REASON_DEPEND;
	} else if(trans->flags & ALPM_TRANS_FLAG_ALLEXPLICIT) {
		newpkg->reason = ALPM_PKG_REASON_EXPLICIT;
	}

	if(oldpkg) {
		/* set up fake remove transaction */
		if(_alpm_remove_single_package(handle, oldpkg, newpkg, 0, 0) == -1) {
			handle->pm_errno = ALPM_ERR_TRANS_ABORT;
			ret = -1;
			goto cleanup;
		}
	}

	/* prepare directory for database entries so permissions are correct after
	   changelog/install script installation */
	if(_alpm_local_db_prepare(db, newpkg)) {
		alpm_logaction(handle, ALPM_CALLER_PREFIX,
				"error: could not create database entry %s-%s\n",
				newpkg->name, newpkg->version);
		handle->pm_errno = ALPM_ERR_DB_WRITE;
		ret = -1;
		goto cleanup;
	}

	if(!(trans->flags & ALPM_TRANS_FLAG_DBONLY)) {
		struct archive *archive;
		struct archive_entry *entry;
		struct stat buf;
		int fd, cwdfd;

		_alpm_log(handle, ALPM_LOG_DEBUG, "extracting files\n");

		fd = _alpm_open_archive(db->handle, pkgfile, &buf,
				&archive, ALPM_ERR_PKG_OPEN);
		if(fd < 0) {
			ret = -1;
			goto cleanup;
		}

		/* save the cwd so we can restore it later */
		OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC);
		if(cwdfd < 0) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
		}

		/* libarchive requires this for extracting hard links */
		if(chdir(handle->root) != 0) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
					handle->root, strerror(errno));
			_alpm_archive_read_free(archive);
			if(cwdfd >= 0) {
				close(cwdfd);
			}
			close(fd);
			ret = -1;
			goto cleanup;
		}

		/* call PROGRESS once with 0 percent, as we sort-of skip that here */
		PROGRESS(handle, progress, newpkg->name, 0, pkg_count, pkg_current);

		for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) {
			int percent;

			if(newpkg->size != 0) {
				/* Using compressed size for calculations here, as newpkg->isize is not
				 * exact when it comes to comparing to the ACTUAL uncompressed size
				 * (missing metadata sizes) */
				int64_t pos = _alpm_archive_compressed_ftell(archive);
				percent = (pos * 100) / newpkg->size;
				if(percent >= 100) {
					percent = 100;
				}
			} else {
				percent = 0;
			}

			PROGRESS(handle, progress, newpkg->name, percent, pkg_count, pkg_current);

			/* extract the next file from the archive */
			errors += extract_single_file(handle, archive, entry, newpkg, oldpkg);
		}
		_alpm_archive_read_free(archive);
		close(fd);

		/* restore the old cwd if we have it */
		if(cwdfd >= 0) {
			if(fchdir(cwdfd) != 0) {
				_alpm_log(handle, ALPM_LOG_ERROR,
						_("could not restore working directory (%s)\n"), strerror(errno));
			}
			close(cwdfd);
		}

		if(errors) {
			ret = -1;
			if(is_upgrade) {
				_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while upgrading %s\n"),
						newpkg->name);
				alpm_logaction(handle, ALPM_CALLER_PREFIX,
						"error: problem occurred while upgrading %s\n",
						newpkg->name);
			} else {
				_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while installing %s\n"),
						newpkg->name);
				alpm_logaction(handle, ALPM_CALLER_PREFIX,
						"error: problem occurred while installing %s\n",
						newpkg->name);
			}
		}
	}

	/* make an install date (in UTC) */
	newpkg->installdate = time(NULL);

	_alpm_log(handle, ALPM_LOG_DEBUG, "updating database\n");
	_alpm_log(handle, ALPM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);

	if(_alpm_local_db_write(db, newpkg, INFRQ_ALL)) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not update database entry %s-%s\n"),
				newpkg->name, newpkg->version);
		alpm_logaction(handle, ALPM_CALLER_PREFIX,
				"error: could not update database entry %s-%s\n",
				newpkg->name, newpkg->version);
		handle->pm_errno = ALPM_ERR_DB_WRITE;
		ret = -1;
		goto cleanup;
	}

	if(_alpm_db_add_pkgincache(db, newpkg) == -1) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not add entry '%s' in cache\n"),
				newpkg->name);
	}

	PROGRESS(handle, progress, newpkg->name, 100, pkg_count, pkg_current);

	switch(event.operation) {
		case ALPM_PACKAGE_INSTALL:
			alpm_logaction(handle, ALPM_CALLER_PREFIX, "installed %s (%s)\n",
					newpkg->name, newpkg->version);
			break;
		case ALPM_PACKAGE_DOWNGRADE:
			alpm_logaction(handle, ALPM_CALLER_PREFIX, "downgraded %s (%s -> %s)\n",
					newpkg->name, oldpkg->version, newpkg->version);
			break;
		case ALPM_PACKAGE_REINSTALL:
			alpm_logaction(handle, ALPM_CALLER_PREFIX, "reinstalled %s (%s)\n",
					newpkg->name, newpkg->version);
			break;
		case ALPM_PACKAGE_UPGRADE:
			alpm_logaction(handle, ALPM_CALLER_PREFIX, "upgraded %s (%s -> %s)\n",
					newpkg->name, oldpkg->version, newpkg->version);
			break;
		default:
			/* we should never reach here */
			break;
	}

	/* run the post-install script if it exists */
	if(alpm_pkg_has_scriptlet(newpkg)
			&& !(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
		char *scriptlet = _alpm_local_db_pkgpath(db, newpkg, "install");
		const char *scriptlet_name = is_upgrade ? "post_upgrade" : "post_install";

		_alpm_runscriptlet(handle, scriptlet, scriptlet_name,
				newpkg->version, oldpkg ? oldpkg->version : NULL, 0);
		free(scriptlet);
	}

	event.type = ALPM_EVENT_PACKAGE_OPERATION_DONE;
	EVENT(handle, &event);

cleanup:
	return ret;
}
CWE773_Missing_Reference_to_Active_File_Descriptor_or_Handle__open_84_bad::CWE773_Missing_Reference_to_Active_File_Descriptor_or_Handle__open_84_bad(int dataCopy)
{
    data = dataCopy;
    /* POTENTIAL FLAW: Create a file descriptor using open() that may not be closed properly */
    data = OPEN("BadSource_open.txt", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
}