Пример #1
0
bool
conf_update_from_environment(struct conf *conf, char **errmsg)
{
	char **p;
	char *q;
	char *key;
	char *errmsg2;
	const struct env_to_conf_item *env_to_conf_item;
	bool negate;
	size_t key_start;

	for (p = environ; *p; ++p) {
		if (!str_startswith(*p, "CCACHE_")) {
			continue;
		}
		q = strchr(*p, '=');
		if (!q) {
			continue;
		}

		if (str_startswith(*p + 7, "NO")) {
			negate = true;
			key_start = 9;
		} else {
			negate = false;
			key_start = 7;
		}
		key = x_strndup(*p + key_start, q - *p - key_start);

		++q; /* Now points to the value. */

		env_to_conf_item = find_env_to_conf(key);
		if (!env_to_conf_item) {
			free(key);
			continue;
		}

		if (!handle_conf_setting(
			    conf, env_to_conf_item->conf_name, q, &errmsg2, true, negate,
			    "environment")) {
			*errmsg = format("%s: %s", key, errmsg2);
			free(errmsg2);
			free(key);
			return false;
		}

		free(key);
	}

	return true;
}
Пример #2
0
/* Some files should always be built locally... */
int
dcc_source_needs_local(const char *filename)
{
    const char *p;

    p = dcc_find_basename(filename);

    if (str_startswith("conftest.", p) || str_startswith("tmp.conftest.", p)) {
        rs_trace("autoconf tests are run locally: %s", filename);
        return EXIT_DISTCC_FAILED;
    }

    return 0;
}
Пример #3
0
/*
 * Convert any "-Wp," options into regular gcc options.
 * We do this because it simplifies the command-line
 * option handling elsewhere; this is the only place
 * that needs to parse "-Wp," options.
 * Returns 0 on success, nonzero for error (out of memory).
 *
 * The argv array pointed to by argv_ptr when this function
 * is called must have been dynamically allocated.  It remains
 * the caller's responsibility to deallocate it.
 */
int dcc_expand_preprocessor_options(char ***argv_ptr) {
    int i, j, ret;
    char **argv = *argv_ptr;
    char **new_argv;
    int argc = dcc_argv_len(argv);
    for (i = 0; argv[i]; i++) {
        if (str_startswith("-Wp,", argv[i])) {
            /* First, calculate how many extra arguments we'll need. */
            int extra_args = count_extra_args(argv[i]);
            assert(extra_args >= 1);

            new_argv = calloc(argc + extra_args, sizeof(char *));
            if (!new_argv) {
                return EXIT_OUT_OF_MEMORY;
            }
            for (j = 0; j < i; j++) {
                new_argv[j] = argv[j];
            }
            if ((ret = copy_extra_args(new_argv + i, argv[i],
                                       extra_args)) != 0) {
                free(new_argv);
                return ret;
            }
            for (j = i + 1; j <= argc; j++) {
                new_argv[j + extra_args - 1] = argv[j];
            }
            free(argv);
            *argv_ptr = argv = new_argv;
        }
    }
    return 0;
}
Пример #4
0
/* performs an HTTP post to the given URL, with callback */
int
netio_http_post(char *url, char *content_type, char *data, int data_len,
		void (*func) (char *url, int respcode, char *data, int data_len, void *pkg),
		void *pkg) 
{
	char *host = 0, *path = 0;
	int hostlen, ret = -1;

	/* parse url */
	ASSERT_TRUE(str_startswith(url, "http://"), err);
	
	url += 7;
	path = strchr(url, '/');
	if (!path) {
		hostlen = strlen(url);
		path = strdup("/");
	} else {
		hostlen = path - url;
		path = strdup(path);
	}
	
	ASSERT_TRUE(host = strndup((const char*)url, (size_t)hostlen), err);
	ret = netio_http_post_host(host, path, url-7, content_type, data, data_len, func, pkg);
err:
	freez(host);
	freez(path);
	return ret;
}
Пример #5
0
END_TEST

START_TEST (test_encode_zeros) {
    struct latlon_double lls[4] = {{0, 0}, { 40.700, -120.950}, { 40.700, -120.950}, { 40.700, -120.950}};
    encode (lls, 4);
    ck_assert (str_endswith(polyline_result(), "????"));
    ck_assert (str_startswith(polyline_result(), "??"));
}
Пример #6
0
/* Subroutine of dcc_expand_preprocessor_options().
 * Calculate how many extra arguments we'll need to convert
 * a "-Wp,..." option into regular gcc options.
 * Returns the number of extra arguments needed.
 */
static int count_extra_args(char *dash_Wp_option) {
    int extra_args = 0;
    char *comma = dash_Wp_option + strlen("-Wp");
    while (comma != NULL) {
        char *opt = comma + 1;
        comma = strchr(opt, ',');
        if (str_startswith("-MD,", opt) ||
            str_startswith("-MMD,", opt))
        {
            char *filename = comma + 1;
            comma = strchr(filename, ',');
            extra_args += 3;  /* "-MD", "-MF", filename. */
        } else {
            extra_args++;
        }
    }
    return extra_args;
}
Пример #7
0
	virtual IOHANDLE OpenFile(const char *pFilename, int Flags, int Type, char *pBuffer = 0, int BufferSize = 0)
	{
		char aBuffer[MAX_PATH_LENGTH];
		if(!pBuffer)
		{
			pBuffer = aBuffer;
			BufferSize = sizeof(aBuffer);
		}

		if(Type == TYPE_ABSOLUTE)
		{
			return io_open(pFilename, Flags);
		}
		if(str_startswith(pFilename, "mapres/../skins/"))
		{
			pFilename = pFilename + 10; // just start from skins/
		}
		if(pFilename[0] == '/' || pFilename[0] == '\\' || str_find(pFilename, "../") != NULL || str_find(pFilename, "..\\") != NULL
		#ifdef CONF_FAMILY_WINDOWS
			|| (pFilename[0] && pFilename[1] == ':')
		#endif
		)
		{
			// don't escape base directory
		}
		else if(Flags&IOFLAG_WRITE)
		{
			return io_open(GetPath(TYPE_SAVE, pFilename, pBuffer, BufferSize), Flags);
		}
		else
		{
			IOHANDLE Handle = 0;

			if(Type <= TYPE_ALL)
			{
				// check all available directories
				for(int i = 0; i < m_NumPaths; ++i)
				{
					Handle = io_open(GetPath(i, pFilename, pBuffer, BufferSize), Flags);
					if(Handle)
						return Handle;
				}
			}
			else if(Type >= 0 && Type < m_NumPaths)
			{
				// check wanted directory
				Handle = io_open(GetPath(Type, pFilename, pBuffer, BufferSize), Flags);
				if(Handle)
					return Handle;
			}
		}

		pBuffer[0] = 0;
		return 0;
	}
Пример #8
0
int assets_list(const char *url, void *user,
                int (*f)(int i, const char *path, void *user))
{
    int i, j = 0;
    for (i = 0; ASSETS[i].path; i++) {
        if (str_startswith(ASSETS[i].path, url)) {
            if (!f || f(j, ASSETS[i].path, user) == 0) j++;
        }
    }
    return j;
}
Пример #9
0
const void *assets_get(const char *url, int *size)
{
    int i;
    if (str_startswith(url, "asset://")) url += 8; // Skip asset://
    for (i = 0; ASSETS[i].path; i++) {
        if (str_equ(ASSETS[i].path, url)) {
            if (size) *size = ASSETS[i].size;
            return ASSETS[i].data;
        }
    }
    return NULL;
}
Пример #10
0
const char *
hy_advisory_get_id(HyAdvisory advisory)
{
    const char *id;

    id = pool_lookup_str(advisory->pool, advisory->a_id, SOLVABLE_NAME);
    assert(str_startswith(id, SOLVABLE_NAME_ADVISORY_PREFIX));
    //remove the prefix
    id += strlen(SOLVABLE_NAME_ADVISORY_PREFIX);

    return id;
}
Пример #11
0
void interactive_kernel_loop() {
    char *buff = (char*) 0x10000;
    uint32_t len = 0x20000 - 0x10000;
    char *decodebuff = (char*) 0x20000;
    uint32_t decodebufflen = 0x30000 - 0x20000;
    int status = 0;
    while (1) {
        status = uart_getln(buff, len);
        if (status == 0) {
            uart_puts(uart_newline);
            if (str_startswith(buff, "b64 ")) {
                uint32_t bytes_decoded = b64_decode(buff+4, decodebuff, decodebufflen);
                uart_puts("base64 decoded #bytes: ");
                char tmp[32];
                uint32_t tmplen = ARR_LEN(tmp);
                uart_puts(str_int_to_str(bytes_decoded, tmp, tmplen));
                uart_puts(uart_newline);
                // Copy the code of bootstrap_decoded_binary somewhere safe.
                uint32_t func_len = 64; // wild guess
                mem_cpy((uint32_t)bootstrap_decoded_binary, 0x30000, func_len);
                // Call bootstrap_decoded_binary from that safe location
                BRANCHTO(0x30000);
            } else if (str_startswith(buff, "m ")) {
                inspect_memory(buff+2);
            } else if (str_startswith(buff, "r ")) {
                inspect_reg(buff+2);
            } else if (str_startswith(buff, "icky")) {
                uart_puts(yoo);
            } else if (str_startswith(buff, "usr0")) {
                if (pr0) {
                    switch_to_user_process(pr0);
                }
            } else if (str_startswith(buff, "freloc")) {
                char tmp[32];
                uint32_t tmplen = ARR_LEN(tmp);
                uint32_t func_len = ((uint32_t) str_parse_int) - ((uint32_t) str_len);
                mem_cpy((uint32_t)str_len, 0x30000, func_len);
                uart_puts(str_int_to_str(CALL_1(0x30000, "xyz"), tmp, tmplen));
            } else if (str_startswith(buff, "version")) {
                uart_puts(version);
                uart_puts("\r\n");
            } else {
                int strlen = str_len(buff) - 1;
                int j = 0;
                for (; strlen != -1; --strlen, ++j) {
                    decodebuff[j] = buff[strlen];
                }
                decodebuff[j] = 0;
                uart_puts(decodebuff);
            }
        }
        uart_puts(uart_newline);
    }
}
Пример #12
0
/**
 * Read in @p filename from inside @p dirname, and try to parse it as
 * a status file.
 *
 * If a new entry is read, a pointer to it is returned in @p lp.
 **/
static int dcc_mon_do_file(char *dirname, char *filename,
                           struct dcc_task_state **lp)
{
    int fd;
    char *fullpath;
    int ret;

    *lp = NULL;

    /* Is this a file we want to see */
    if (!str_startswith(dcc_state_prefix, filename)) {
/*         rs_trace("skipped"); */
        return 0;
    }

    checked_asprintf(&fullpath, "%s/%s", dirname, filename);
    if (fullpath == NULL) {
      return EXIT_OUT_OF_MEMORY;
    }
    rs_trace("process %s", fullpath);

    /* Remember that the file might disappear at any time, so open it
     * now so that we can hang on. */
    if ((fd = open(fullpath, O_RDONLY|O_BINARY, 0)) == -1) {
        if (errno == ENOENT) {
            rs_trace("%s disappeared", fullpath);
            ret = 0;
            goto out_free;
        } else { /* hm */
            rs_log_warning("failed to open %s: %s",
                           fullpath, strerror(errno));
            ret = EXIT_IO_ERROR;
            goto out_free;
        }
    }

    if ((ret = dcc_mon_kill_old(fd, fullpath))) {
        /* closes fd on failure */
        goto out_free;
    }

    ret = dcc_mon_load_state(fd, fullpath, lp);

    dcc_close(fd);

    out_free:
    free(fullpath);
    return ret;           /* ok */
}
Пример #13
0
// Strip any arguments beginning with the specified prefix.
void
args_strip(struct args *args, const char *prefix)
{
	for (int i = 0; i < args->argc;) {
		if (str_startswith(args->argv[i], prefix)) {
			free(args->argv[i]);
			memmove(&args->argv[i],
			        &args->argv[i+1],
			        (args->argc - i) * sizeof(args->argv[i]));
			args->argc--;
		} else {
			i++;
		}
	}
}
Пример #14
0
/* this builds the list of files in the cache */
static void
traverse_fn(const char *fname, struct stat *st)
{
	char *p;

	if (!S_ISREG(st->st_mode)) {
		return;
	}

	p = basename(fname);
	if (str_eq(p, "stats")) {
		goto out;
	}

	if (str_startswith(p, ".nfs")) {
		/* Ignore temporary NFS files that may be left for open but deleted
		 * files. */
		goto out;
	}

	if (strstr(p, ".tmp.")) {
		/* delete any tmp files older than 1 hour */
		if (st->st_mtime + 3600 < time(NULL)) {
			x_unlink(fname);
			goto out;
		}
	}

	if (strstr(p, "CACHEDIR.TAG")) {
		goto out;
	}

	if (num_files == allocated) {
		allocated = 10000 + num_files*2;
		files = (struct files **)x_realloc(files, sizeof(struct files *)*allocated);
	}

	files[num_files] = (struct files *)x_malloc(sizeof(struct files));
	files[num_files]->fname = x_strdup(fname);
	files[num_files]->mtime = st->st_mtime;
	files[num_files]->size = file_size(st);
	cache_size += files[num_files]->size;
	files_in_cache++;
	num_files++;

out:
	free(p);
}
Пример #15
0
	void LoadPaths(const char *pArgv0)
	{
		// check current directory
		IOHANDLE File = io_open("storage.cfg", IOFLAG_READ);
		if(!File)
		{
			// check usable path in argv[0]
			unsigned int Pos = ~0U;
			for(unsigned i = 0; pArgv0[i]; i++)
				if(pArgv0[i] == '/' || pArgv0[i] == '\\')
					Pos = i;
			if(Pos < MAX_PATH_LENGTH)
			{
				char aBuffer[MAX_PATH_LENGTH];
				str_copy(aBuffer, pArgv0, Pos+1);
				str_append(aBuffer, "/storage.cfg", sizeof(aBuffer));
				File = io_open(aBuffer, IOFLAG_READ);
			}

			if(Pos >= MAX_PATH_LENGTH || !File)
			{
				dbg_msg("storage", "couldn't open storage.cfg");
				return;
			}
		}

		char *pLine;
		CLineReader LineReader;
		LineReader.Init(File);

		while((pLine = LineReader.Get()))
		{
			const char *pLineWithoutPrefix = str_startswith(pLine, "add_path ");
			if(pLineWithoutPrefix)
			{
				AddPath(pLineWithoutPrefix);
			}
		}

		io_close(File);

		if(!m_NumPaths)
			dbg_msg("storage", "no paths found in storage.cfg");
	}
Пример #16
0
static char *
path_from_uri(WebdavBackendFs *pbctx, const char *real_uri) {
  char *toret = NULL;

  assert(str_startswith(real_uri, "/"));

  toret = davfuse_util_strdup(pbctx->base_path);
  if (!toret) goto err;

  if (str_equals(real_uri, "/")) return toret;

  const char *start_of_dirname = real_uri;
  while (*start_of_dirname) {
    start_of_dirname += 1;

    const char *next = strchr(start_of_dirname, '/');
    if (!next) next = start_of_dirname + strlen(start_of_dirname);

    char *path_comp = malloc(next - start_of_dirname + 1);
    if (!path_comp) goto err;

    memcpy(path_comp, start_of_dirname, next - start_of_dirname);
    path_comp[next - start_of_dirname] = '\0';

    char *newtoret = util_fs_path_join(pbctx->fs, toret, path_comp);
    free(path_comp);

    if (!newtoret) goto err;
    free(toret);
    toret = newtoret;

    start_of_dirname = next;
  }

  if (false) {
  err:
    free(toret);
    toret = NULL;
  }

  return toret;
}
Пример #17
0
/**
 * Remove "-o" options from argument list.
 *
 * This is used when running the preprocessor, when we just want it to write
 * to stdout, which is the default when no -o option is specified.
 *
 * Structurally similar to dcc_strip_local_args()
 **/
int dcc_strip_dasho(char **from, char ***out_argv)
{
    char **to;
    int from_i, to_i;
    int from_len;

    from_len = dcc_argv_len(from);
    *out_argv = to = malloc((from_len + 1) * sizeof (char *));

    if (!to) {
        rs_log_error("failed to allocate space for arguments");
        return EXIT_OUT_OF_MEMORY;
    }

    /* skip through argv, copying all arguments but skipping ones that
     * ought to be omitted */
    for (from_i = to_i = 0; from[from_i]; ) {
        if (!strcmp(from[from_i], "-o")) {
            /* skip "-o  FILE" */
            from_i += 2;
        }
        else if (str_startswith("-o", from[from_i])) {
            /* skip "-oFILE" */
            from_i++;
        }
        else {
            to[to_i++] = from[from_i++];
        }
    }

    /* NULL-terminate */
    to[to_i] = NULL;

    dcc_trace_argv("result", to);

    return 0;
}
Пример #18
0
void CAutoMapper::Load(const char* pTileName)
{
	char aPath[256];
	str_format(aPath, sizeof(aPath), "editor/%s.rules", pTileName);
	IOHANDLE RulesFile = m_pEditor->Storage()->OpenFile(aPath, IOFLAG_READ, IStorage::TYPE_ALL);
	if(!RulesFile)
		return;

	CLineReader LineReader;
	LineReader.Init(RulesFile);

	CConfiguration *pCurrentConf = 0;
	CRun *pCurrentRun = 0;
	CIndexRule *pCurrentIndex = 0;

	char aBuf[256];

	// read each line
	while(char *pLine = LineReader.Get())
	{
		// skip blank/empty lines as well as comments
		if(str_length(pLine) > 0 && pLine[0] != '#' && pLine[0] != '\n' && pLine[0] != '\r'
			&& pLine[0] != '\t' && pLine[0] != '\v' && pLine[0] != ' ')
		{
			if(pLine[0]== '[')
			{
				// new configuration, get the name
				pLine++;
				CConfiguration NewConf;
				NewConf.m_StartX = 0;
				NewConf.m_StartY = 0;
				NewConf.m_EndX = 0;
				NewConf.m_EndY = 0;
				int ConfigurationID = m_lConfigs.add(NewConf);
				pCurrentConf = &m_lConfigs[ConfigurationID];
				str_copy(pCurrentConf->m_aName, pLine, str_length(pLine));

				// add start run
				CRun NewRun;
				NewRun.m_AutomapCopy = true;
				int RunID = pCurrentConf->m_aRuns.add(NewRun);
				pCurrentRun = &pCurrentConf->m_aRuns[RunID];
			}
			else if(str_startswith(pLine, "NewRun"))
			{
				// add new run
				CRun NewRun;
				NewRun.m_AutomapCopy = true;
				int RunID = pCurrentConf->m_aRuns.add(NewRun);
				pCurrentRun = &pCurrentConf->m_aRuns[RunID];
			}
			else if(str_startswith(pLine, "Index") && pCurrentRun)
			{
				// new index
				int ID = 0;
				char aOrientation1[128] = "";
				char aOrientation2[128] = "";
				char aOrientation3[128] = "";

				sscanf(pLine, "Index %d %127s %127s %127s", &ID, aOrientation1, aOrientation2, aOrientation3);

				CIndexRule NewIndexRule;
				NewIndexRule.m_ID = ID;
				NewIndexRule.m_Flag = 0;
				NewIndexRule.m_RandomProbability = 1.0;
				NewIndexRule.m_DefaultRule = true;
				NewIndexRule.m_SkipEmpty = false;
				NewIndexRule.m_SkipFull = false;

				if(str_length(aOrientation1) > 0)
				{
					if(!str_comp(aOrientation1, "XFLIP"))
						NewIndexRule.m_Flag |= TILEFLAG_VFLIP;
					else if(!str_comp(aOrientation1, "YFLIP"))
						NewIndexRule.m_Flag |= TILEFLAG_HFLIP;
					else if(!str_comp(aOrientation1, "ROTATE"))
						NewIndexRule.m_Flag |= TILEFLAG_ROTATE;
				}

				if(str_length(aOrientation2) > 0)
				{
					if(!str_comp(aOrientation2, "XFLIP"))
						NewIndexRule.m_Flag |= TILEFLAG_VFLIP;
					else if(!str_comp(aOrientation2, "YFLIP"))
						NewIndexRule.m_Flag |= TILEFLAG_HFLIP;
					else if(!str_comp(aOrientation2, "ROTATE"))
						NewIndexRule.m_Flag |= TILEFLAG_ROTATE;
				}

				if(str_length(aOrientation3) > 0)
				{
					if(!str_comp(aOrientation3, "XFLIP"))
						NewIndexRule.m_Flag |= TILEFLAG_VFLIP;
					else if(!str_comp(aOrientation3, "YFLIP"))
						NewIndexRule.m_Flag |= TILEFLAG_HFLIP;
					else if(!str_comp(aOrientation3, "ROTATE"))
						NewIndexRule.m_Flag |= TILEFLAG_ROTATE;
				}

				// add the index rule object and make it current
				int IndexRuleID = pCurrentRun->m_aIndexRules.add(NewIndexRule);
				pCurrentIndex = &pCurrentRun->m_aIndexRules[IndexRuleID];
			}
			else if(str_startswith(pLine, "Pos") && pCurrentIndex)
			{
				int x = 0, y = 0;
				char aValue[128];
				int Value = CPosRule::NORULE;
				array<CIndexInfo> NewIndexList;

				sscanf(pLine, "Pos %d %d %127s", &x, &y, aValue);

				if(!str_comp(aValue, "EMPTY"))
				{
					Value = CPosRule::INDEX;
					CIndexInfo NewIndexInfo = {0, 0, false};
					NewIndexList.add(NewIndexInfo);
				}
				else if(!str_comp(aValue, "FULL"))
				{
					Value = CPosRule::NOTINDEX;
					CIndexInfo NewIndexInfo1 = {0, 0, false};
					//CIndexInfo NewIndexInfo2 = {-1, 0};
					NewIndexList.add(NewIndexInfo1);
					//NewIndexList.add(NewIndexInfo2);
				}
				else if(!str_comp(aValue, "INDEX") || !str_comp(aValue, "NOTINDEX"))
				{
					if(!str_comp(aValue, "INDEX"))
						Value = CPosRule::INDEX;
					else
						Value = CPosRule::NOTINDEX;

					int pWord = 4;
					while(true) {
						int ID = 0;
						char aOrientation1[128] = "";
						char aOrientation2[128] = "";
						char aOrientation3[128] = "";
						char aOrientation4[128] = "";
						sscanf(str_trim_words(pLine, pWord), "%d %127s %127s %127s %127s", &ID, aOrientation1, aOrientation2, aOrientation3, aOrientation4);

						CIndexInfo NewIndexInfo;
						NewIndexInfo.m_ID = ID;
						NewIndexInfo.m_Flag = 0;
						NewIndexInfo.m_TestFlag = false;

						if(!str_comp(aOrientation1, "OR")) {
							NewIndexList.add(NewIndexInfo);
							pWord += 2;
							continue;
						} else if(str_length(aOrientation1) > 0) {
							NewIndexInfo.m_TestFlag = true;
							if(!str_comp(aOrientation1, "XFLIP"))
								NewIndexInfo.m_Flag = TILEFLAG_VFLIP;
							else if(!str_comp(aOrientation1, "YFLIP"))
								NewIndexInfo.m_Flag = TILEFLAG_HFLIP;
							else if(!str_comp(aOrientation1, "ROTATE"))
								NewIndexInfo.m_Flag = TILEFLAG_ROTATE;
							else if(!str_comp(aOrientation1, "NONE"))
								NewIndexInfo.m_Flag = 0;
							else
								NewIndexInfo.m_TestFlag = false;
						} else {
							NewIndexList.add(NewIndexInfo);
							break;
						}

						if(!str_comp(aOrientation2, "OR")) {
							NewIndexList.add(NewIndexInfo);
							pWord += 3;
							continue;
						} else if(str_length(aOrientation2) > 0 && NewIndexInfo.m_Flag != 0) {
							if(!str_comp(aOrientation2, "XFLIP"))
								NewIndexInfo.m_Flag |= TILEFLAG_VFLIP;
							else if(!str_comp(aOrientation2, "YFLIP"))
								NewIndexInfo.m_Flag |= TILEFLAG_HFLIP;
							else if(!str_comp(aOrientation2, "ROTATE"))
								NewIndexInfo.m_Flag |= TILEFLAG_ROTATE;
						} else {
							NewIndexList.add(NewIndexInfo);
							break;
						}

						if(!str_comp(aOrientation3, "OR")) {
							NewIndexList.add(NewIndexInfo);
							pWord += 4;
							continue;
						} else if(str_length(aOrientation3) > 0 && NewIndexInfo.m_Flag != 0) {
							if(!str_comp(aOrientation3, "XFLIP"))
								NewIndexInfo.m_Flag |= TILEFLAG_VFLIP;
							else if(!str_comp(aOrientation3, "YFLIP"))
								NewIndexInfo.m_Flag |= TILEFLAG_HFLIP;
							else if(!str_comp(aOrientation3, "ROTATE"))
								NewIndexInfo.m_Flag |= TILEFLAG_ROTATE;
						} else {
							NewIndexList.add(NewIndexInfo);
							break;
						}

						if(!str_comp(aOrientation4, "OR")) {
							NewIndexList.add(NewIndexInfo);
							pWord += 5;
							continue;
						} else {
							NewIndexList.add(NewIndexInfo);
							break;
						}
					}
				}

				if(Value != CPosRule::NORULE) {
					CPosRule NewPosRule = {x, y, Value, NewIndexList};
					pCurrentIndex->m_aRules.add(NewPosRule);

					pCurrentConf->m_StartX = min(pCurrentConf->m_StartX, NewPosRule.m_X);
					pCurrentConf->m_StartY = min(pCurrentConf->m_StartY, NewPosRule.m_Y);
					pCurrentConf->m_EndX = max(pCurrentConf->m_EndX, NewPosRule.m_X);
					pCurrentConf->m_EndY = max(pCurrentConf->m_EndY, NewPosRule.m_Y);

					if(x == 0 && y == 0) {
						for(int i = 0; i < NewIndexList.size(); ++i) 
						{
							if(Value == CPosRule::INDEX && NewIndexList[i].m_ID == 0)
								pCurrentIndex->m_SkipFull = true;
							else
								pCurrentIndex->m_SkipEmpty = true;
						}
					}
				}
			}
			else if(str_startswith(pLine, "Random") && pCurrentIndex)
			{
				float Value;
				char Specifier = ' ';
				sscanf(pLine, "Random %f%c", &Value, &Specifier);
				if(Specifier == '%')
				{
					pCurrentIndex->m_RandomProbability = Value / 100.0;
				}
				else
				{
					pCurrentIndex->m_RandomProbability = 1.0 / Value;
				}
			}
			else if(str_startswith(pLine, "NoDefaultRule") && pCurrentIndex)
			{
				pCurrentIndex->m_DefaultRule = false;
			}
			else if(!str_comp_num(pLine, "NoLayerCopy", 11) && pCurrentRun)
			{
				pCurrentRun->m_AutomapCopy = false;
			}
		}
	}

	// add default rule for Pos 0 0 if there is none
	for (int g = 0; g < m_lConfigs.size(); ++g)
	{
		for (int h = 0; h < m_lConfigs[g].m_aRuns.size(); ++h)
		{
			for(int i = 0; i < m_lConfigs[g].m_aRuns[h].m_aIndexRules.size(); ++i)
			{
				CIndexRule *pIndexRule = &m_lConfigs[g].m_aRuns[h].m_aIndexRules[i];
				bool Found = false;
				for(int j = 0; j < pIndexRule->m_aRules.size(); ++j)
				{
					CPosRule *pRule = &pIndexRule->m_aRules[j];
					if(pRule && pRule->m_X == 0 && pRule->m_Y == 0)
					{
						Found = true;
						break;
					}
				}
				if(!Found && pIndexRule->m_DefaultRule)
				{
					array<CIndexInfo> NewIndexList;
					CIndexInfo NewIndexInfo = {0, 0, false};
					NewIndexList.add(NewIndexInfo);
					CPosRule NewPosRule = {0, 0, CPosRule::NOTINDEX, NewIndexList};
					pIndexRule->m_aRules.add(NewPosRule);
					
					pIndexRule->m_SkipEmpty = true;
					pIndexRule->m_SkipFull = false;
				}
				if(pIndexRule->m_SkipEmpty && pIndexRule->m_SkipFull)
				{
					pIndexRule->m_SkipFull = false;
				}
			}
		}
	}

	io_close(RulesFile);

	str_format(aBuf, sizeof(aBuf),"loaded %s", aPath);
	m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "editor", aBuf);

	m_FileLoaded = true;
}
Пример #19
0
/* Client program */
int
main(int argc, char *argv[])
{
	char server[256];
	char fullhostname[64];
	char domain[256];
	char shell[256];
	char directory[256];
	RD_BOOL prompt_password, deactivated;
	struct passwd *pw;
	uint32 flags, ext_disc_reason = 0;
	char *p;
	int c;
	char *locale = NULL;
	int username_option = 0;
	RD_BOOL geometry_option = False;
#ifdef WITH_RDPSND
	char *rdpsnd_optarg = NULL;
#endif

#ifdef HAVE_LOCALE_H
	/* Set locale according to environment */
	locale = setlocale(LC_ALL, "");
	if (locale)
	{
		locale = xstrdup(locale);
	}

#endif

	/* Ignore SIGPIPE, since we are using popen() */
	struct sigaction act;
	memset(&act, 0, sizeof(act));
	act.sa_handler = SIG_IGN;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	sigaction(SIGPIPE, &act, NULL);

	/* setup default flags for TS_INFO_PACKET */
	flags = RDP_INFO_MOUSE | RDP_INFO_DISABLECTRLALTDEL
		| RDP_INFO_UNICODE | RDP_INFO_MAXIMIZESHELL | RDP_INFO_ENABLEWINDOWSKEY;

	prompt_password = False;
	g_seamless_spawn_cmd[0] = domain[0] = g_password[0] = shell[0] = directory[0] = 0;
	g_embed_wnd = 0;

	g_num_devices = 0;

#ifdef RDP2VNC
#define VNCOPT "V:Q:"
#else
#define VNCOPT
#endif
	while ((c = getopt(argc, argv,
			   VNCOPT "A:u:L:d:s:c:p:n:k:g:o:fbBeEitmzCDKS:T:UNX:a:x:Pr:045h?")) != -1)
	{
		switch (c)
		{
#ifdef RDP2VNC
			case 'V':
				rfb_port = strtol(optarg, NULL, 10);
				if (rfb_port < 100)
					rfb_port += 5900;
				break;

			case 'Q':
				defer_time = strtol(optarg, NULL, 10);
				if (defer_time < 0)
					defer_time = 0;
				break;
#endif

			case 'A':
				g_seamless_rdp = True;
				STRNCPY(g_seamless_shell, optarg, sizeof(g_seamless_shell));
				break;

			case 'u':
				g_username = (char *) xmalloc(strlen(optarg) + 1);
				STRNCPY(g_username, optarg, strlen(optarg) + 1);
				username_option = 1;
				break;

			case 'L':
#ifdef HAVE_ICONV
				STRNCPY(g_codepage, optarg, sizeof(g_codepage));
#else
				error("iconv support not available\n");
#endif
				break;

			case 'd':
				STRNCPY(domain, optarg, sizeof(domain));
				break;

			case 's':
				STRNCPY(shell, optarg, sizeof(shell));
				g_seamless_persistent_mode = False;
				break;

			case 'c':
				STRNCPY(directory, optarg, sizeof(directory));
				break;

			case 'p':
				if ((optarg[0] == '-') && (optarg[1] == 0))
				{
					prompt_password = True;
					break;
				}

				STRNCPY(g_password, optarg, sizeof(g_password));
				flags |= RDP_INFO_AUTOLOGON;

				/* try to overwrite argument so it won't appear in ps */
				p = optarg;
				while (*p)
					*(p++) = 'X';
				break;
#ifdef WITH_SCARD
			case 'i':
				flags |= RDP_INFO_PASSWORD_IS_SC_PIN;
				g_use_password_as_pin = True;
				break;
#endif
			case 't':
				g_use_ctrl = False;
				break;

			case 'n':
				STRNCPY(g_hostname, optarg, sizeof(g_hostname));
				break;

			case 'k':
				STRNCPY(g_keymapname, optarg, sizeof(g_keymapname));
				break;

			case 'g':
				geometry_option = True;
				g_fullscreen = False;
				if (!strcmp(optarg, "workarea"))
				{
					g_sizeopt = 1;
					break;
				}

				g_width = strtol(optarg, &p, 10);
				if (g_width <= 0)
				{
					error("invalid geometry\n");
					return EX_USAGE;
				}

				if (*p == 'x')
					g_height = strtol(p + 1, &p, 10);

				if (g_height <= 0)
				{
					error("invalid geometry\n");
					return EX_USAGE;
				}

				if (*p == '%')
				{
					g_sizeopt = -g_width;
					g_width = 800;
					p++;
				}

				if (*p == '+' || *p == '-')
				{
					g_pos |= (*p == '-') ? 2 : 1;
					g_xpos = strtol(p, &p, 10);

				}
				if (*p == '+' || *p == '-')
				{
					g_pos |= (*p == '-') ? 4 : 1;
					g_ypos = strtol(p, NULL, 10);
				}

				break;

			case 'f':
				g_fullscreen = True;
				break;

			case 'b':
				g_bitmap_cache = False;
				break;

			case 'B':
				g_ownbackstore = False;
				break;

			case 'e':
				g_encryption_initial = g_encryption = False;
				break;
			case 'E':
				g_packet_encryption = False;
				break;
			case 'm':
				g_sendmotion = False;
				break;

			case 'C':
				g_owncolmap = True;
				break;

			case 'D':
				g_hide_decorations = True;
				break;

			case 'K':
				g_grab_keyboard = False;
				break;

			case 'U':
				g_ungrab_on_ctrlalt = True;
				break;

			case 'S':
				if (!strcmp(optarg, "standard"))
				{
					g_win_button_size = 18;
					break;
				}

				g_win_button_size = strtol(optarg, &p, 10);

				if (*p)
				{
					error("invalid button size\n");
					return EX_USAGE;
				}

				break;

			case 'T':
				STRNCPY(g_title, optarg, sizeof(g_title));
				break;

			case 'N':
				g_numlock_sync = True;
				break;

			case 'X':
				g_embed_wnd = strtol(optarg, NULL, 0);
				break;

			case 'a':
				g_server_depth = strtol(optarg, NULL, 10);
				if (g_server_depth != 8 &&
				    g_server_depth != 16 &&
				    g_server_depth != 15 && g_server_depth != 24
				    && g_server_depth != 32)
				{
					error("Invalid server colour depth.\n");
					return EX_USAGE;
				}
				break;

			case 'z':
				DEBUG(("rdp compression enabled\n"));
				flags |= (RDP_INFO_COMPRESSION | RDP_INFO_COMPRESSION2);
				break;

			case 'x':
				if (str_startswith(optarg, "m"))	/* modem */
				{
					g_rdp5_performanceflags = RDP5_NO_CURSOR_SHADOW |
						RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
						RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
				}
				else if (str_startswith(optarg, "b"))	/* broadband */
				{
					g_rdp5_performanceflags =
						RDP5_NO_CURSOR_SHADOW | RDP5_NO_WALLPAPER;
				}
				else if (str_startswith(optarg, "l"))	/* lan */
				{
					g_rdp5_performanceflags =
						RDP5_NO_CURSOR_SHADOW | RDP5_DISABLE_NOTHING;
				}
				else
				{
					g_rdp5_performanceflags =
						RDP5_NO_CURSOR_SHADOW | strtol(optarg, NULL, 16);
				}
				break;

			case 'P':
				g_bitmap_cache_persist_enable = True;
				break;

			case 'r':

				if (str_startswith(optarg, "sound"))
				{
					optarg += 5;

					if (*optarg == ':')
					{
						optarg++;
						while ((p = next_arg(optarg, ',')))
						{
							if (str_startswith(optarg, "remote"))
								flags |= RDP_INFO_REMOTE_CONSOLE_AUDIO;

							if (str_startswith(optarg, "local"))
#ifdef WITH_RDPSND
							{
								rdpsnd_optarg =
									next_arg(optarg, ':');
								g_rdpsnd = True;
							}

#else
								warning("Not compiled with sound support\n");
#endif

							if (str_startswith(optarg, "off"))
#ifdef WITH_RDPSND
								g_rdpsnd = False;
#else
								warning("Not compiled with sound support\n");
#endif

							optarg = p;
						}
					}
					else
					{
#ifdef WITH_RDPSND
						g_rdpsnd = True;
#else
						warning("Not compiled with sound support\n");
#endif
					}
				}
				else if (str_startswith(optarg, "disk"))
				{
					/* -r disk:h:=/mnt/floppy */
					disk_enum_devices(&g_num_devices, optarg + 4);
				}
				else if (str_startswith(optarg, "comport"))
				{
					serial_enum_devices(&g_num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "lspci"))
				{
					g_lspci_enabled = True;
				}
				else if (str_startswith(optarg, "lptport"))
				{
					parallel_enum_devices(&g_num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "printer"))
				{
					printer_enum_devices(&g_num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "clientname"))
				{
					g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
					strcpy(g_rdpdr_clientname, optarg + 11);
				}
				else if (str_startswith(optarg, "clipboard"))
				{
					optarg += 9;

					if (*optarg == ':')
					{
						optarg++;

						if (str_startswith(optarg, "off"))
							g_rdpclip = False;
						else
							cliprdr_set_mode(optarg);
					}
					else
						g_rdpclip = True;
				}
				else if (strncmp("scard", optarg, 5) == 0)
				{
#ifdef WITH_SCARD
					scard_enum_devices(&g_num_devices, optarg + 5);
#else
					warning("Not compiled with smartcard support\n");
#endif
				}
				else
				{
					warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n");
				}
				break;

			case '0':
				g_console_session = True;
				break;

			case '4':
				g_rdp_version = RDP_V4;
				break;

			case '5':
				g_rdp_version = RDP_V5;
				break;
#if WITH_SCARD
			case 'o':
				{
					char *p = strchr(optarg, '=');
					if (p == NULL)
					{
						warning("Skipping option '%s' specified, lacks name=value format.\n");
						continue;
					}

					if (strncmp(optarg, "sc-csp-name", strlen("sc-scp-name")) ==
					    0)
						g_sc_csp_name = strdup(p + 1);
					else if (strncmp
						 (optarg, "sc-reader-name",
						  strlen("sc-reader-name")) == 0)
						g_sc_reader_name = strdup(p + 1);
					else if (strncmp
						 (optarg, "sc-card-name",
						  strlen("sc-card-name")) == 0)
						g_sc_card_name = strdup(p + 1);
					else if (strncmp
						 (optarg, "sc-container-name",
						  strlen("sc-container-name")) == 0)
						g_sc_container_name = strdup(p + 1);

				}
				break;
#endif
			case 'h':
			case '?':
			default:
				usage(argv[0]);
				return EX_USAGE;
		}
	}

	if (argc - optind != 1)
	{
		usage(argv[0]);
		return EX_USAGE;
	}

	STRNCPY(server, argv[optind], sizeof(server));
	parse_server_and_port(server);

	if (g_seamless_rdp)
	{
		if (shell[0])
			STRNCPY(g_seamless_spawn_cmd, shell, sizeof(g_seamless_spawn_cmd));

		STRNCPY(shell, g_seamless_shell, sizeof(shell));

		if (g_win_button_size)
		{
			error("You cannot use -S and -A at the same time\n");
			return EX_USAGE;
		}
		g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
		if (geometry_option)
		{
			error("You cannot use -g and -A at the same time\n");
			return EX_USAGE;
		}
		if (g_fullscreen)
		{
			error("You cannot use -f and -A at the same time\n");
			return EX_USAGE;
		}
		if (g_hide_decorations)
		{
			error("You cannot use -D and -A at the same time\n");
			return EX_USAGE;
		}
		if (g_embed_wnd)
		{
			error("You cannot use -X and -A at the same time\n");
			return EX_USAGE;
		}
		if (g_rdp_version < RDP_V5)
		{
			error("You cannot use -4 and -A at the same time\n");
			return EX_USAGE;
		}
		g_sizeopt = -100;
		g_grab_keyboard = False;
	}

	if (!username_option)
	{
		pw = getpwuid(getuid());
		if ((pw == NULL) || (pw->pw_name == NULL))
		{
			error("could not determine username, use -u\n");
			return EX_OSERR;
		}
		/* +1 for trailing \0 */
		int pwlen = strlen(pw->pw_name) + 1;
		g_username = (char *) xmalloc(pwlen);
		STRNCPY(g_username, pw->pw_name, pwlen);
	}

#ifdef HAVE_ICONV
	if (g_codepage[0] == 0)
	{
		if (setlocale(LC_CTYPE, ""))
		{
			STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage));
		}
		else
		{
			STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage));
		}
	}
#endif

	if (g_hostname[0] == 0)
	{
		if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
		{
			error("could not determine local hostname, use -n\n");
			return EX_OSERR;
		}

		p = strchr(fullhostname, '.');
		if (p != NULL)
			*p = 0;

		STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
	}

	if (g_keymapname[0] == 0)
	{
		if (locale && xkeymap_from_locale(locale))
		{
			fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname);
		}
		else
		{
			STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname));
		}
	}
	if (locale)
		xfree(locale);


	if (prompt_password && read_password(g_password, sizeof(g_password)))
		flags |= RDP_INFO_AUTOLOGON;

	if (g_title[0] == 0)
	{
		strcpy(g_title, "rdesktop - ");
		strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
	}

#ifdef RDP2VNC
	rdp2vnc_connect(server, flags, domain, g_password, shell, directory);
	return EX_OK;
#else

	/* Only startup ctrl functionality is seamless are used for now. */
	if (g_use_ctrl && g_seamless_rdp)
	{
		if (ctrl_init(server, domain, g_username) < 0)
		{
			error("Failed to initialize ctrl mode.");
			exit(1);
		}

		if (ctrl_is_slave())
		{
			fprintf(stdout,
				"rdesktop in slave mode sending command to master process.\n");

			if (g_seamless_spawn_cmd[0])
				return ctrl_send_command("seamless.spawn", g_seamless_spawn_cmd);

			fprintf(stdout, "No command specified to be spawn in seamless mode.\n");
			return EX_USAGE;
		}
	}

	if (!ui_init())
		return EX_OSERR;

#ifdef WITH_RDPSND
	if (!rdpsnd_init(rdpsnd_optarg))
		warning("Initializing sound-support failed!\n");
#endif

	if (g_lspci_enabled)
		lspci_init();

	rdpdr_init();
	g_reconnect_loop = False;
	while (1)
	{
		rdesktop_reset_state();

		if (g_redirect)
		{
			STRNCPY(domain, g_redirect_domain, sizeof(domain));
			xfree(g_username);
			g_username = (char *) xmalloc(strlen(g_redirect_username) + 1);
			STRNCPY(g_username, g_redirect_username, strlen(g_redirect_username) + 1);
			STRNCPY(server, g_redirect_server, sizeof(server));
			flags |= RDP_INFO_AUTOLOGON;

			fprintf(stderr, "Redirected to %s@%s session %d.\n",
				g_redirect_username, g_redirect_server, g_redirect_session_id);

			/* A redirect on SSL from a 2003 WTS will result in a 'connection reset by peer'
			   and therefor we just clear this error before we connect to redirected server.
			 */
			g_network_error = False;
			g_redirect = False;
		}

		ui_init_connection();
		if (!rdp_connect
		    (server, flags, domain, g_password, shell, directory, g_reconnect_loop))
		{

			g_network_error = False;

			if (g_reconnect_loop == False)
				return EX_PROTOCOL;

			/* check if auto reconnect cookie has timed out */
			if (time(NULL) - g_reconnect_random_ts > RECONNECT_TIMEOUT)
			{
				fprintf(stderr, "Tried to reconnect for %d minutes, giving up.\n",
					RECONNECT_TIMEOUT / 60);
				return EX_PROTOCOL;
			}

			sleep(4);
			continue;
		}

		if (g_redirect)
		{
			rdp_disconnect();
			continue;
		}

		/* By setting encryption to False here, we have an encrypted login 
		   packet but unencrypted transfer of other packets */
		if (!g_packet_encryption)
			g_encryption_initial = g_encryption = False;

		DEBUG(("Connection successful.\n"));

		rd_create_ui();
		tcp_run_ui(True);

		deactivated = False;
		g_reconnect_loop = False;
		rdp_main_loop(&deactivated, &ext_disc_reason);

		tcp_run_ui(False);

		DEBUG(("Disconnecting...\n"));
		rdp_disconnect();

		if (g_redirect)
			continue;

		/* handle network error and start autoreconnect */
		if (g_network_error && !deactivated)
		{
			fprintf(stderr,
				"Disconnected due to network error, retrying to reconnect for %d minutes.\n",
				RECONNECT_TIMEOUT / 60);
			g_network_error = False;
			g_reconnect_loop = True;
			continue;
		}

		ui_seamless_end();
		ui_destroy_window();

		/* Enter a reconnect loop if we have a pending resize request */
		if (g_pending_resize)
		{
			g_pending_resize = False;
			g_reconnect_loop = True;
			continue;
		}
		break;
	}

	cache_save_state();
	ui_deinit();

	if (g_user_quit)
		return EXRD_WINDOW_CLOSED;

	return handle_disconnect_reason(deactivated, ext_disc_reason);

#endif
	if (g_redirect_username)
		xfree(g_redirect_username);

	xfree(g_username);
}
Пример #20
0
static int rhizome_server_parse_http_request(rhizome_http_request *r)
{
  /* Switching to writing, so update the call-back */
  r->alarm.poll.events=POLLOUT;
  watch(&r->alarm);
  // Start building up a response.
  r->request_type = 0;
  // Parse the HTTP "GET" line.
  char *path = NULL;
  size_t pathlen = 0;
  if (str_startswith(r->request, "GET ", &path)) {
    char *p;
    // This loop is guaranteed to terminate before the end of the buffer, because we know that the
    // buffer contains at least "\n\n" and maybe "\r\n\r\n" at the end of the header block.
    for (p = path; !isspace(*p); ++p)
      ;
    pathlen = p - path;
    if ( str_startswith(p, " HTTP/1.", &p)
      && (str_startswith(p, "0", &p) || str_startswith(p, "1", &p))
      && (str_startswith(p, "\r\n", &p) || str_startswith(p, "\n", &p))
    )
      path[pathlen] = '\0';
    else
      path = NULL;
  }
  if (path) {
    char *id = NULL;
    INFOF("RHIZOME HTTP SERVER, GET %s", alloca_toprint(1024, path, pathlen));
    if (strcmp(path, "/favicon.ico") == 0) {
      r->request_type = RHIZOME_HTTP_REQUEST_FAVICON;
      rhizome_server_http_response_header(r, 200, "image/vnd.microsoft.icon", favicon_len);
    } else if (strcmp(path, "/rhizome/groups") == 0) {
      /* Return the list of known groups */
      rhizome_server_sql_query_http_response(r, "id", "groups", "from groups", 32, 1);
    } else if (strcmp(path, "/rhizome/files") == 0) {
      /* Return the list of known files */
      rhizome_server_sql_query_http_response(r, "id", "files", "from files", 32, 1);
    } else if (strcmp(path, "/rhizome/bars") == 0) {
      /* Return the list of known BARs */
      rhizome_server_sql_query_http_response(r, "bar", "manifests", "from manifests", 32, 0);
    } else if (str_startswith(path, "/rhizome/file/", &id)) {
      /* Stream the specified payload */
      if (!rhizome_str_is_file_hash(id)) {
	rhizome_server_simple_http_response(r, 400, "<html><h1>Invalid payload ID</h1></html>\r\n");
      } else {
	// TODO: Check for Range: header and return 206 if returning partial content
	str_toupper_inplace(id);
	long long rowid = -1;
	sqlite_exec_int64(&rowid, "select rowid from files where id='%s';", id);
	if (rowid >= 0 && sqlite3_blob_open(rhizome_db, "main", "files", "data", rowid, 0, &r->blob) != SQLITE_OK)
	  rowid = -1;
	if (rowid == -1) {
	  rhizome_server_simple_http_response(r, 404, "<html><h1>Payload not found</h1></html>\r\n");
	} else {
	  r->source_index = 0;
	  r->blob_end = sqlite3_blob_bytes(r->blob);
	  rhizome_server_http_response_header(r, 200, "application/binary", r->blob_end - r->source_index);
	  r->request_type |= RHIZOME_HTTP_REQUEST_BLOB;
	}
      }
    } else if (str_startswith(path, "/rhizome/manifest/", &id)) {
      // TODO: Stream the specified manifest
      rhizome_server_simple_http_response(r, 500, "<html><h1>Not implemented</h1></html>\r\n");
    } else {
      rhizome_server_simple_http_response(r, 404, "<html><h1>Not found</h1></html>\r\n");
    }
  } else {
    if (debug & DEBUG_RHIZOME_TX)
      DEBUGF("Received malformed HTTP request: %s", alloca_toprint(120, (const char *)r->request, r->request_length));
    rhizome_server_simple_http_response(r, 400, "<html><h1>Malformed request</h1></html>\r\n");
  }
  
  /* Try sending data immediately. */
  rhizome_server_http_send_bytes(r);

  return 0;
}
Пример #21
0
bool
hash_command_output(struct mdfour *hash, const char *command,
                    const char *compiler)
{
#ifdef _WIN32
	SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
	HANDLE pipe_out[2];
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	DWORD exitcode;
	bool cmd = false;
	char *sh = NULL;
	char *win32args;
	char *path;
	BOOL ret;
	bool ok;
	int fd;
#else
	pid_t pid;
	int pipefd[2];
#endif

#ifdef _WIN32
	/* trim leading space */
	while (isspace(*command)) {
		command++;
	}
	/* add "echo" command */
	if (str_startswith(command, "echo")) {
		command = format("cmd.exe /c \"%s\"", command);
		cmd = true;
	} else if (str_startswith(command,
	                          "%compiler%") && str_eq(compiler, "echo")) {
		command = format("cmd.exe /c \"%s%s\"", compiler, command + 10);
		cmd = true;
	} else {
		command = x_strdup(command);
	}
#endif
	struct args *args = args_init_from_string(command);
	int i;
	for (i = 0; i < args->argc; i++) {
		if (str_eq(args->argv[i], "%compiler%")) {
			args_set(args, i, compiler);
		}
	}
	cc_log_argv("Executing compiler check command ", args->argv);

#ifdef _WIN32
	memset(&pi, 0x00, sizeof(pi));
	memset(&si, 0x00, sizeof(si));

	path = find_executable(args->argv[0], NULL);
	if (!path) {
		path = args->argv[0];
	}
	sh = win32getshell(path);
	if (sh) {
		path = sh;
	}

	si.cb = sizeof(STARTUPINFO);
	CreatePipe(&pipe_out[0], &pipe_out[1], &sa, 0);
	SetHandleInformation(pipe_out[0], HANDLE_FLAG_INHERIT, 0);
	si.hStdOutput = pipe_out[1];
	si.hStdError = pipe_out[1];
	si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	si.dwFlags = STARTF_USESTDHANDLES;
	if (!cmd) {
		win32args = win32argvtos(sh, args->argv);
	} else {
		win32args = (char *) command;  /* quoted */
	}
	ret = CreateProcess(path, win32args, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
	CloseHandle(pipe_out[1]);
	args_free(args);
	free(win32args);
	if (cmd) {
		free((char *) command);  /* original argument was replaced above */
	}
	if (ret == 0) {
		stats_update(STATS_COMPCHECK);
		return false;
	}
	fd = _open_osfhandle((intptr_t) pipe_out[0], O_BINARY);
	ok = hash_fd(hash, fd);
	if (!ok) {
		cc_log("Error hashing compiler check command output: %s", strerror(errno));
		stats_update(STATS_COMPCHECK);
	}
	WaitForSingleObject(pi.hProcess, INFINITE);
	GetExitCodeProcess(pi.hProcess, &exitcode);
	CloseHandle(pipe_out[0]);
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
	if (exitcode != 0) {
		cc_log("Compiler check command returned %d", (int) exitcode);
		stats_update(STATS_COMPCHECK);
		return false;
	}
	return ok;
#else
	if (pipe(pipefd) == -1) {
		fatal("pipe failed");
	}
	pid = fork();
	if (pid == -1) {
		fatal("fork failed");
	}

	if (pid == 0) {
		/* Child. */
		close(pipefd[0]);
		close(0);
		dup2(pipefd[1], 1);
		dup2(pipefd[1], 2);
		_exit(execvp(args->argv[0], args->argv));
		return false; /* Never reached. */
	} else {
		/* Parent. */
		int status;
		bool ok;
		args_free(args);
		close(pipefd[1]);
		ok = hash_fd(hash, pipefd[0]);
		if (!ok) {
			cc_log("Error hashing compiler check command output: %s", strerror(errno));
			stats_update(STATS_COMPCHECK);
		}
		close(pipefd[0]);
		if (waitpid(pid, &status, 0) != pid) {
			cc_log("waitpid failed");
			return false;
		}
		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
			cc_log("Compiler check command returned %d", WEXITSTATUS(status));
			stats_update(STATS_COMPCHECK);
			return false;
		}
		return ok;
	}
#endif
}
Пример #22
0
/* Client program */
int
main(int argc, char *argv[])
{
	char server[64];
	char fullhostname[64];
	char domain[16];
	char password[64];
	char shell[256];
	char directory[256];
	RD_BOOL prompt_password, deactivated;
	struct passwd *pw;
	uint32 flags, ext_disc_reason = 0;
	char *p;
	int c;
	char *locale = NULL;
	int username_option = 0;
	RD_BOOL geometry_option = False;
	int run_count = 0;	/* Session Directory support */
	RD_BOOL continue_connect = True;	/* Session Directory support */
#ifdef WITH_RDPSND
	char *rdpsnd_optarg = NULL;
#endif

#ifdef HAVE_LOCALE_H
	/* Set locale according to environment */
	locale = setlocale(LC_ALL, "");
	if (locale)
	{
		locale = xstrdup(locale);
	}

#endif
	flags = RDP_LOGON_NORMAL;
	prompt_password = False;
	domain[0] = password[0] = shell[0] = directory[0] = 0;
	g_embed_wnd = 0;

	g_num_devices = 0;

#ifdef RDP2VNC
#define VNCOPT "V:Q:"
#else
#define VNCOPT
#endif

	while ((c = getopt(argc, argv,
			   VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
	{
		switch (c)
		{
#ifdef RDP2VNC
			case 'V':
				rfb_port = strtol(optarg, NULL, 10);
				if (rfb_port < 100)
					rfb_port += 5900;
				break;

			case 'Q':
				defer_time = strtol(optarg, NULL, 10);
				if (defer_time < 0)
					defer_time = 0;
				break;
#endif

			case 'A':
				g_seamless_rdp = True;
				break;

			case 'u':
				STRNCPY(g_username, optarg, sizeof(g_username));
				username_option = 1;
				break;

			case 'L':
#ifdef HAVE_ICONV
				STRNCPY(g_codepage, optarg, sizeof(g_codepage));
#else
				error("iconv support not available\n");
#endif
				break;

			case 'd':
				STRNCPY(domain, optarg, sizeof(domain));
				break;

			case 's':
				STRNCPY(shell, optarg, sizeof(shell));
				break;

			case 'c':
				STRNCPY(directory, optarg, sizeof(directory));
				break;

			case 'p':
				if ((optarg[0] == '-') && (optarg[1] == 0))
				{
					prompt_password = True;
					break;
				}

				STRNCPY(password, optarg, sizeof(password));
				flags |= RDP_LOGON_AUTO;

				/* try to overwrite argument so it won't appear in ps */
				p = optarg;
				while (*p)
					*(p++) = 'X';
				break;

			case 'n':
				STRNCPY(g_hostname, optarg, sizeof(g_hostname));
				break;

			case 'k':
				STRNCPY(g_keymapname, optarg, sizeof(g_keymapname));
				break;

			case 'g':
				geometry_option = True;
				g_fullscreen = False;
				if (!strcmp(optarg, "workarea"))
				{
					g_width = g_height = 0;
					break;
				}

				g_width = strtol(optarg, &p, 10);
				if (g_width <= 0)
				{
					error("invalid geometry\n");
					return 1;
				}

				if (*p == 'x')
					g_height = strtol(p + 1, &p, 10);

				if (g_height <= 0)
				{
					error("invalid geometry\n");
					return 1;
				}

				if (*p == '%')
				{
					g_width = -g_width;
					p++;
				}

				if (*p == '+' || *p == '-')
				{
					g_pos |= (*p == '-') ? 2 : 1;
					g_xpos = strtol(p, &p, 10);

				}
				if (*p == '+' || *p == '-')
				{
					g_pos |= (*p == '-') ? 4 : 1;
					g_ypos = strtol(p, NULL, 10);
				}

				break;

			case 'f':
				g_fullscreen = True;
				break;

			case 'b':
				g_bitmap_cache = False;
				break;

			case 'B':
				g_ownbackstore = False;
				break;

			case 'e':
				g_encryption = False;
				break;
			case 'E':
				g_packet_encryption = False;
				break;
			case 'm':
				g_sendmotion = False;
				break;

			case 'C':
				g_owncolmap = True;
				break;

			case 'D':
				g_hide_decorations = True;
				break;

			case 'K':
				g_grab_keyboard = False;
				break;

			case 'S':
				if (!strcmp(optarg, "standard"))
				{
					g_win_button_size = 18;
					break;
				}

				g_win_button_size = strtol(optarg, &p, 10);

				if (*p)
				{
					error("invalid button size\n");
					return 1;
				}

				break;

			case 'T':
				STRNCPY(g_title, optarg, sizeof(g_title));
				break;

			case 'N':
				g_numlock_sync = True;
				break;

			case 'X':
				g_embed_wnd = strtol(optarg, NULL, 0);
				break;

			case 'a':
				g_server_depth = strtol(optarg, NULL, 10);
				if (g_server_depth != 8 &&
				    g_server_depth != 16 &&
				    g_server_depth != 15 && g_server_depth != 24
				    && g_server_depth != 32)
				{
					error("Invalid server colour depth.\n");
					return 1;
				}
				break;

			case 'z':
				DEBUG(("rdp compression enabled\n"));
				flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
				break;

			case 'x':
				if (str_startswith(optarg, "m"))	/* modem */
				{
					g_rdp5_performanceflags =
						RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
						RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
				}
				else if (str_startswith(optarg, "b"))	/* broadband */
				{
					g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
				}
				else if (str_startswith(optarg, "l"))	/* lan */
				{
					g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
				}
				else
				{
					g_rdp5_performanceflags = strtol(optarg, NULL, 16);
				}
				break;

			case 'P':
				g_bitmap_cache_persist_enable = True;
				break;

			case 'r':

				if (str_startswith(optarg, "sound"))
				{
					optarg += 5;

					if (*optarg == ':')
					{
						optarg++;
						while ((p = next_arg(optarg, ',')))
						{
							if (str_startswith(optarg, "remote"))
								flags |= RDP_LOGON_LEAVE_AUDIO;

							if (str_startswith(optarg, "local"))
#ifdef WITH_RDPSND
							{
								rdpsnd_optarg =
									next_arg(optarg, ':');
								g_rdpsnd = True;
							}

#else
								warning("Not compiled with sound support\n");
#endif

							if (str_startswith(optarg, "off"))
#ifdef WITH_RDPSND
								g_rdpsnd = False;
#else
								warning("Not compiled with sound support\n");
#endif

							optarg = p;
						}
					}
					else
					{
#ifdef WITH_RDPSND
						g_rdpsnd = True;
#else
						warning("Not compiled with sound support\n");
#endif
					}
				}
				else if (str_startswith(optarg, "disk"))
				{
					/* -r disk:h:=/mnt/floppy */
					disk_enum_devices(&g_num_devices, optarg + 4);
				}
				else if (str_startswith(optarg, "comport"))
				{
					serial_enum_devices(&g_num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "lspci"))
				{
					g_lspci_enabled = True;
				}
				else if (str_startswith(optarg, "lptport"))
				{
					parallel_enum_devices(&g_num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "printer"))
				{
					printer_enum_devices(&g_num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "clientname"))
				{
					g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
					strcpy(g_rdpdr_clientname, optarg + 11);
				}
				else if (str_startswith(optarg, "clipboard"))
				{
					optarg += 9;

					if (*optarg == ':')
					{
						optarg++;

						if (str_startswith(optarg, "off"))
							g_rdpclip = False;
						else
							cliprdr_set_mode(optarg);
					}
					else
						g_rdpclip = True;
				}
				else if (strncmp("scard", optarg, 5) == 0)
				{
#ifdef WITH_SCARD
					scard_enum_devices(&g_num_devices, optarg + 5);
#else
					warning("Not compiled with smartcard support\n");
#endif
				}
				else
				{
					warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n");
				}
				break;

			case '0':
				g_console_session = True;
				break;

			case '4':
				g_use_rdp5 = False;
				break;

			case '5':
				g_use_rdp5 = True;
				break;

			case 'h':
			case '?':
			default:
				usage(argv[0]);
				return 1;
		}
	}

	if (argc - optind != 1)
	{
		usage(argv[0]);
		return 1;
	}

	STRNCPY(server, argv[optind], sizeof(server));
	parse_server_and_port(server);

	if (g_seamless_rdp)
	{
		if (g_win_button_size)
		{
			error("You cannot use -S and -A at the same time\n");
			return 1;
		}
		g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
		if (geometry_option)
		{
			error("You cannot use -g and -A at the same time\n");
			return 1;
		}
		if (g_fullscreen)
		{
			error("You cannot use -f and -A at the same time\n");
			return 1;
		}
		if (g_hide_decorations)
		{
			error("You cannot use -D and -A at the same time\n");
			return 1;
		}
		if (g_embed_wnd)
		{
			error("You cannot use -X and -A at the same time\n");
			return 1;
		}
		if (!g_use_rdp5)
		{
			error("You cannot use -4 and -A at the same time\n");
			return 1;
		}
		g_width = -100;
		g_grab_keyboard = False;
	}

	if (!username_option)
	{
		pw = getpwuid(getuid());
		if ((pw == NULL) || (pw->pw_name == NULL))
		{
			error("could not determine username, use -u\n");
			return 1;
		}

		STRNCPY(g_username, pw->pw_name, sizeof(g_username));
	}

#ifdef HAVE_ICONV
	if (g_codepage[0] == 0)
	{
		if (setlocale(LC_CTYPE, ""))
		{
			STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage));
		}
		else
		{
			STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage));
		}
	}
#endif

	if (g_hostname[0] == 0)
	{
		if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
		{
			error("could not determine local hostname, use -n\n");
			return 1;
		}

		p = strchr(fullhostname, '.');
		if (p != NULL)
			*p = 0;

		STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
	}

	if (g_keymapname[0] == 0)
	{
		if (locale && xkeymap_from_locale(locale))
		{
			fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname);
		}
		else
		{
			STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname));
		}
	}
	if (locale)
		xfree(locale);


	if (prompt_password && read_password(password, sizeof(password)))
		flags |= RDP_LOGON_AUTO;

	if (g_title[0] == 0)
	{
		strcpy(g_title, "rdesktop - ");
		strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
	}

#ifdef RDP2VNC
	rdp2vnc_connect(server, flags, domain, password, shell, directory);
	return 0;
#else

	if (!ui_init())
		return 1;

#ifdef WITH_RDPSND
	if (g_rdpsnd)
	{
		if (!rdpsnd_init(rdpsnd_optarg))
		{
			warning("Initializing sound-support failed!\n");
		}
	}
#endif

	if (g_lspci_enabled)
		lspci_init();

	rdpdr_init();

	while (run_count < 2 && continue_connect)	/* add support for Session Directory; only reconnect once */
	{
		if (run_count == 0)
		{
			if (!rdp_connect(server, flags, domain, password, shell, directory))
				return 1;
		}
		else if (!rdp_reconnect
			 (server, flags, domain, password, shell, directory, g_redirect_cookie))
			return 1;

		/* By setting encryption to False here, we have an encrypted login 
		   packet but unencrypted transfer of other packets */
		if (!g_packet_encryption)
			g_encryption = False;


		DEBUG(("Connection successful.\n"));
		memset(password, 0, sizeof(password));

		if (run_count == 0)
			if (!ui_create_window())
				continue_connect = False;

		if (continue_connect)
			rdp_main_loop(&deactivated, &ext_disc_reason);

		DEBUG(("Disconnecting...\n"));
		rdp_disconnect();

		if ((g_redirect == True) && (run_count == 0))	/* Support for Session Directory */
		{
			/* reset state of major globals */
			rdesktop_reset_state();

			STRNCPY(domain, g_redirect_domain, sizeof(domain));
			STRNCPY(g_username, g_redirect_username, sizeof(g_username));
			STRNCPY(password, g_redirect_password, sizeof(password));
			STRNCPY(server, g_redirect_server, sizeof(server));
			flags |= RDP_LOGON_AUTO;

			g_redirect = False;
		}
		else
		{
			continue_connect = False;
			ui_destroy_window();
			break;
		}

		run_count++;
	}

	cache_save_state();
	ui_deinit();

	if (ext_disc_reason >= 2)
		print_disconnect_reason(ext_disc_reason);

	if (deactivated)
	{
		/* clean disconnect */
		return 0;
	}
	else
	{
		if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
		    || ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
		{
			/* not so clean disconnect, but nothing to worry about */
			return 0;
		}
		else
		{
			/* return error */
			return 2;
		}
	}

#endif

}
Пример #23
0
/*
 * Process the compiler options into options suitable for passing to the
 * preprocessor and the real compiler. The preprocessor options don't include
 * -E; this is added later. Returns true on success, otherwise false.
 */
bool
armcc_process_args(struct args *orig_args, struct args **preprocessor_args,
                struct args **compiler_args)
{
	int i;
	bool found_c_opt = false;
	bool found_S_opt = false;
	bool found_pch = false;
	bool found_fpch_preprocess = false;
	const char *actual_language;          /* Language to actually use. */
	const char *input_charset = NULL;
	struct stat st;
	/* is the dependency makefile name overridden with --depend? */
	bool dependency_filename_specified = false;
	/* is the dependency makefile target name specified ? */
	bool dependency_target_specified = false;
	char *dep_file = NULL, *dep_dir = NULL;
	struct args *stripped_args = NULL, *dep_args = NULL;
	int argc = orig_args->argc;
	char **argv = orig_args->argv;
	bool result = true;
	/* 0: Choose preprocessor type by the file extension.
	 * 1: Use c preprocessor.
	 * 2: Use c++ preprocessor.*/
	unsigned force_preprocessor_type = 0;

	stripped_args = args_init(0, NULL);
	dep_args = args_init(0, NULL);

	args_add(stripped_args, argv[0]);

	for (i = 1; i < argc; i++) {
		/* The user knows best: just swallow the next arg */
		if (str_eq(argv[i], "--ccache-skip")) {
			i++;
			if (i == argc) {
				cc_log("--ccache-skip lacks an argument");
				result = false;
				goto out;
			}
			args_add(stripped_args, argv[i]);
			continue;
		}

		/* Special case for -E. */
		if (str_eq(argv[i], "-E")) {
			stats_update(STATS_PREPROCESSING);
			result = false;
			goto out;
		}

		/* These are always too hard. */
		if (compopt_too_hard(argv[i])
		    || str_startswith(argv[i], "@")
		    || str_startswith(argv[i], "-fdump-")) {
			cc_log("Compiler option %s is unsupported", argv[i]);
			stats_update(STATS_UNSUPPORTED);
			result = false;
			goto out;
		}

		/* These are too hard in direct mode. */
		if (enable_direct) {
			if (compopt_too_hard_for_direct_mode(argv[i])) {
				cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
				enable_direct = false;
			}
		}

		/* we must have -c */
		if (str_eq(argv[i], "-c")) {
			args_add(stripped_args, argv[i]);
			found_c_opt = true;
			continue;
		}

		/* -S changes the default extension */
		if (str_eq(argv[i], "-S")) {
			args_add(stripped_args, argv[i]);
			found_S_opt = true;
			continue;
		}

		/* we need to work out where the output was meant to go */
		if (str_eq(argv[i], "-o")) {
			if (i == argc-1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			output_obj = argv[i+1];
			i++;
			continue;
		}

		/* alternate form of -o, with no space */
		if (str_startswith(argv[i], "-o")) {
			output_obj = &argv[i][2];
			continue;
		}


		/* If multiple source type options are there, the armcc will use the last one. */
		if (str_eq(argv[i], "--cpp")) { 
			force_preprocessor_type = 2;
			continue;
		}
		else if (str_eq(argv[i], "--c90") || str_eq(argv[i], "--c99")) { 
			force_preprocessor_type = 1;
			continue;
		}

		if (str_eq(argv[i], "--md")) { 
			generating_dependencies = true;
			continue;
		}

		/* The rvct started supporting --depend_target from 4.0.
		 * And there is a bug when using -E and --depend together with rvct which version is earlier than 4.0_697.
		 * That is too hard to support "--depend" for the earlier version of rvct.*/
		if (str_startswith(argv[i], "--depend_dir")) {
			/* We just concat the dir and the filename and pass the result 
			 * to --depend. */
			if (i >= argc - 1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			dep_dir= x_strdup(argv[i+1]);
			i++;
			continue;
		}
		else if (str_startswith(argv[i], "--depend_target")) {
			if (i >= argc - 1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			dependency_target_specified = true;
			args_add(dep_args, argv[i]);
			args_add(dep_args, argv[i+1]);
			i++;
			continue;
		}
		else if (str_startswith(argv[i], "--depend")) {
			dependency_filename_specified = true;
			generating_dependencies = true;

			if (i >= argc - 1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			dep_file = x_strdup(argv[i + 1]);
			i++;
			continue;
		}


		/*
		 * Options taking an argument that that we may want to rewrite
		 * to relative paths to get better hit rate. A secondary effect
		 * is that paths in the standard error output produced by the
		 * compiler will be normalized.
		 */
		if (compopt_takes_path(argv[i])) {
			char *relpath;
			char *pchpath;
			if (i == argc-1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}

			args_add(stripped_args, argv[i]);
			relpath = make_relative_path(x_strdup(argv[i+1]));
			args_add(stripped_args, relpath);

			/* Try to be smart about detecting precompiled headers */
			pchpath = format("%s.gch", argv[i+1]);
			if (stat(pchpath, &st) == 0) {
				cc_log("Detected use of precompiled header: %s", pchpath);
				found_pch = true;
			}

			free(pchpath);
			free(relpath);
			i++;
			continue;
		}

		/* Same as above but options with concatenated argument. */
		if (compopt_short(compopt_takes_path, argv[i])) {
			char *relpath;
			char *option;
			relpath = make_relative_path(x_strdup(argv[i] + 2));
			option = format("-%c%s", argv[i][1], relpath);
			args_add(stripped_args, option);
			free(relpath);
			free(option);
			continue;
		}

		/* options that take an argument */
		if (compopt_takes_arg(argv[i])) {
			if (i == argc-1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			args_add(stripped_args, argv[i]);
			args_add(stripped_args, argv[i+1]);
			i++;
			continue;
		}

		/* other options */
		if (argv[i][0] == '-') {
			args_add(stripped_args, argv[i]);
			continue;
		}

		/* if an argument isn't a plain file then assume its
		   an option, not an input file. This allows us to
		   cope better with unusual compiler options */
		if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
			cc_log("%s is not a regular file, not considering as input file",
			       argv[i]);
			args_add(stripped_args, argv[i]);
			continue;
		}

		if (input_file) {
			if (language_for_file(argv[i])) {
				cc_log("Multiple input files: %s and %s", input_file, argv[i]);
				stats_update(STATS_MULTIPLE);
			} else if (!found_c_opt) {
				cc_log("Called for link with %s", argv[i]);
				if (strstr(argv[i], "conftest.")) {
					stats_update(STATS_CONFTEST);
				} else {
					stats_update(STATS_LINK);
				}
			} else {
				cc_log("Unsupported source extension: %s", argv[i]);
				stats_update(STATS_SOURCELANG);
			}
			result = false;
			goto out;
		}

		/* Rewrite to relative to increase hit rate. */
		input_file = make_relative_path(x_strdup(argv[i]));
	}

	if (!input_file) {
		cc_log("No input file found");
		stats_update(STATS_NOINPUT);
		result = false;
		goto out;
	}

	if (found_pch || found_fpch_preprocess) {
		using_precompiled_header = true;
		if (!(sloppiness & SLOPPY_TIME_MACROS)) {
			cc_log("You have to specify \"time_macros\" sloppiness when using"
			       " precompiled headers to get direct hits");
			cc_log("Disabling direct mode");
			stats_update(STATS_CANTUSEPCH);
			result = false;
			goto out;
		}
	}

	if(force_preprocessor_type == 0) { 
		actual_language = language_for_file(input_file);
	} 
	else if(force_preprocessor_type == 2) { 
		actual_language = "c++";
	}
	else {
		actual_language = "c";
	}

	output_is_precompiled_header =
		actual_language && strstr(actual_language, "-header") != NULL;

	if (!found_c_opt && !output_is_precompiled_header) {
		cc_log("No -c option found");
		/* I find that having a separate statistic for autoconf tests is useful,
		   as they are the dominant form of "called for link" in many cases */
		if (strstr(input_file, "conftest.")) {
			stats_update(STATS_CONFTEST);
		} else {
			stats_update(STATS_LINK);
		}
		result = false;
		goto out;
	}

	if (!actual_language) {
		cc_log("Unsupported source extension: %s", input_file);
		stats_update(STATS_SOURCELANG);
		result = false;
		goto out;
	}

	direct_i_file = language_is_preprocessed(actual_language);

	if (output_is_precompiled_header) {
		/* It doesn't work to create the .gch from preprocessed source. */
		cc_log("Creating precompiled header; not compiling preprocessed code");
		compile_preprocessed_source_code = false;
	}

	/* don't try to second guess the compilers heuristics for stdout handling */
	if (output_obj && str_eq(output_obj, "-")) {
		stats_update(STATS_OUTSTDOUT);
		cc_log("Output file is -");
		result = false;
		goto out;
	}

	if (!output_obj) {
		if (output_is_precompiled_header) {
			output_obj = format("%s.gch", input_file);
		} else {
			char *p;
			output_obj = x_strdup(input_file);
			if ((p = strrchr(output_obj, '/'))) {
				output_obj = p+1;
			}
			p = strrchr(output_obj, '.');
			if (!p || !p[1]) {
				cc_log("Badly formed object filename");
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			p[1] = found_S_opt ? 's' : 'o';
			p[2] = 0;
		}
	}

	/* cope with -o /dev/null */
	if (!str_eq(output_obj,"/dev/null")
	    && stat(output_obj, &st) == 0
	    && !S_ISREG(st.st_mode)) {
		cc_log("Not a regular file: %s", output_obj);
		stats_update(STATS_DEVICE);
		result = false;
		goto out;
	}

	/*
	 * Some options shouldn't be passed to the real compiler when it compiles
	 * preprocessed code:
	 *
	 * -finput-charset=XXX (otherwise conversion happens twice)
	 * -x XXX (otherwise the wrong language is selected)
	 */
	*preprocessor_args = args_copy(stripped_args);
	if (input_charset) {
		args_add(*preprocessor_args, input_charset);
	}
	if (found_pch) {
		args_add(*preprocessor_args, "-fpch-preprocess");
	}

	/*
	 * Add flags for dependency generation only to the preprocessor command line.
	 */
	if (generating_dependencies) {
		char *dep_path;

		if(!dependency_filename_specified)
		{ 
			char *base_name;

			base_name = remove_extension(output_obj);
			dep_file = format("%s.d", base_name);
			free(base_name);
		}

		if (!dependency_target_specified) {
			args_add(dep_args, "--depend_target");
			args_add(dep_args, output_obj);
		}

		free(output_dep);
		
		if(dep_dir)
		{ 
#ifdef _WIN32
			dep_path = make_relative_path(format("%s\\%s", dep_dir, dep_file));
#else
			dep_path = make_relative_path(format("%s/%s", dep_dir, dep_file));
#endif
		}
		else
		{ 
			dep_path = x_strdup(dep_file);
		}

		args_add(dep_args, "--depend");
		args_add(dep_args, dep_path);
		/* dep_path will be free in make_relative_path */
		output_dep = make_relative_path(x_strdup(dep_path));
	}

	if (compile_preprocessed_source_code) {
		*compiler_args = args_copy(stripped_args);
	} else {
		*compiler_args = args_copy(*preprocessor_args);
	}

	i_extension = getenv("CCACHE_EXTENSION");
	if (!i_extension) {
		const char *p_language = p_language_for_language(actual_language);
		i_extension = extension_for_language(p_language) + 1;

	}
	/* Patch for preprocessed file extension for armcc 3.1.
	 * armcc 3.1 cannot recognize "i" or "ii" as the preprocessed source file 
	 * without --compile_all_input. */
	args_add(*compiler_args, "--compile_all_input");
	if (str_eq(i_extension, "ii")) { 
		args_add(*compiler_args, "--cpp");
	}

	/*
	 * Only pass dependency arguments to the preprocesor since Intel's C++
	 * compiler doesn't produce a correct .d file when compiling preprocessed
	 * source.
	 */
	args_extend(*preprocessor_args, dep_args);

out:
	free(dep_file);
	free(dep_dir);
	args_free(stripped_args);
	args_free(dep_args);
	return result;
}
Пример #24
0
/*
 * Process the compiler options into options suitable for passing to the
 * preprocessor and the real compiler. The preprocessor options don't include
 * -E; this is added later. Returns true on success, otherwise false.
 */
bool
c166_process_args(struct args *orig_args, struct args **preprocessor_args,
                struct args **compiler_args)
{
	int i;
	bool found_c_opt = false;
	bool found_S_opt = false;
	bool found_H_opt = false;
	/* 0: Choose preprocessor type by the file extension.
	 * 1: Use c preprocessor.
	 * 2: Use c++ preprocessor.*/
	unsigned force_preprocessor_type = 0;
	const char *actual_language;          /* Language to actually use. */
	struct stat st;
	/* is the dependency makefile name overridden with -MF? */
	bool dependency_filename_specified = false;
	/* is the dependency makefile target name specified with -MT or -MQ? */
	bool dependency_target_specified = false;
	struct args *stripped_args = NULL, *dep_args = NULL, *h_args;
	int argc = orig_args->argc;
	char **argv = orig_args->argv;
	bool result = true;

	stripped_args = args_init(0, NULL);
	dep_args = args_init(0, NULL);
	h_args = args_init(0, NULL);

	args_add(stripped_args, argv[0]);

	for (i = 1; i < argc; i++) {
		/* The user knows best: just swallow the next arg */
		if (str_eq(argv[i], "--ccache-skip")) {
			i++;
			if (i == argc) {
				cc_log("--ccache-skip lacks an argument");
				result = false;
				goto out;
			}
			args_add(stripped_args, argv[i]);
			continue;
		}

		/* Special case for -E. */
		if (str_eq(argv[i], "-E")) {
			stats_update(STATS_PREPROCESSING);
			result = false;
			goto out;
		}

		/* These are always too hard. */
		if (compopt_too_hard(argv[i])) {
			cc_log("Compiler option %s is unsupported", argv[i]);
			stats_update(STATS_UNSUPPORTED);
			result = false;
			goto out;
		}

		/* These are too hard in direct mode. */
		if (enable_direct) {
			if (compopt_too_hard_for_direct_mode(argv[i])) {
				cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
				enable_direct = false;
			}
		}

		/* we must have -c */
		if (str_eq(argv[i], "-c")) {
			args_add(stripped_args, argv[i]);
			found_c_opt = true;
			continue;
		}

		/* -S changes the default extension */
		/* TODO: Check this -S out!
		if (str_eq(argv[i], "-S")) {
			args_add(stripped_args, argv[i]);
			found_S_opt = true;
			continue;
		}
		*/

		/* we need to work out where the output was meant to go */
		if (str_eq(argv[i], "-o")) {
			if (i == argc-1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			output_obj = argv[i+1];
			i++;
			continue;
		}

		/* alternate form of -o, with no space */
		if (str_startswith(argv[i], "-o")) {
			output_obj = &argv[i][2];
			continue;
		}

		/* debugging is handled specially, so that we know if we
		   can strip line number info
		*/
		if (str_startswith(argv[i], "-g")) {
			args_add(stripped_args, argv[i]);
			if (enable_unify) {
				cc_log("%s used; disabling unify mode", argv[i]);
				enable_unify = false;
			}
			continue;
		}

		if (str_startswith(argv[i], "-H")) {
			cc_log("Detected -H %s", argv[i]);
			args_add(h_args, argv[i]);
			found_H_opt = true;
			continue;
		}

		/*
		 * Options taking an argument that that we may want to rewrite
		 * to relative paths to get better hit rate. A secondary effect
		 * is that paths in the standard error output produced by the
		 * compiler will be normalized.
		 */
		if (compopt_takes_path(argv[i])) {
			char *relpath;
			if (i == argc-1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}

			args_add(stripped_args, argv[i]);
			relpath = make_relative_path(x_strdup(argv[i+1]));
			args_add(stripped_args, relpath);

			free(relpath);
			i++;
			continue;
		}

		/* Same as above but options with concatenated argument. */
		if (compopt_short(compopt_takes_path, argv[i])) {
			char *relpath;
			char *option;
			relpath = make_relative_path(x_strdup(argv[i] + 2));
			option = format("-%c%s", argv[i][1], relpath);
			args_add(stripped_args, option);
			free(relpath);
			free(option);
			continue;
		}

		/* options that take an argument */
		if (compopt_takes_arg(argv[i])) {
			if (i == argc-1) {
				cc_log("Missing argument to %s", argv[i]);
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			args_add(stripped_args, argv[i]);
			args_add(stripped_args, argv[i+1]);
			i++;
			continue;
		}

		if (str_eq(argv[i], "-c++")) {
			force_preprocessor_type = 2;
			args_add(stripped_args, argv[i]);
			continue;
		}
		if (str_eq(argv[i], "-noc++")) {
			force_preprocessor_type = 1;
			args_add(stripped_args, argv[i]);
			continue;
		}

		/* other options */
		if (argv[i][0] == '-') {
			args_add(stripped_args, argv[i]);
			continue;
		}

		/* if an argument isn't a plain file then assume its
		   an option, not an input file. This allows us to
		   cope better with unusual compiler options */
		if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
			cc_log("%s is not a regular file, not considering as input file",
			       argv[i]);
			args_add(stripped_args, argv[i]);
			continue;
		}

		if (input_file) {
			if (language_for_file(argv[i])) {
				cc_log("Multiple input files: %s and %s", input_file, argv[i]);
				stats_update(STATS_MULTIPLE);
			} else if (!found_c_opt) {
				cc_log("Called for link with %s", argv[i]);
				if (strstr(argv[i], "conftest.")) {
					stats_update(STATS_CONFTEST);
				} else {
					stats_update(STATS_LINK);
				}
			} else {
				cc_log("Unsupported source extension: %s", argv[i]);
				stats_update(STATS_SOURCELANG);
			}
			result = false;
			goto out;
		}

		/* Rewrite to relative to increase hit rate. */
		input_file = make_relative_path(x_strdup(argv[i]));
	}

	if (!input_file) {
		cc_log("No input file found");
		stats_update(STATS_NOINPUT);
		result = false;
		goto out;
	}

	if(force_preprocessor_type == 0) { 
		actual_language = language_for_file(input_file);
	} 
	else if(force_preprocessor_type == 2) { 
		actual_language = "c++";
	}
	else {
		actual_language = "c";
	}
	
	output_is_precompiled_header =
		actual_language && strstr(actual_language, "-header") != NULL;

	if (!found_c_opt && !output_is_precompiled_header) {
		cc_log("No -c option found");
		/* I find that having a separate statistic for autoconf tests is useful,
		   as they are the dominant form of "called for link" in many cases */
		if (strstr(input_file, "conftest.")) {
			stats_update(STATS_CONFTEST);
		} else {
			stats_update(STATS_LINK);
		}
		result = false;
		goto out;
	}

	if (!actual_language) {
		cc_log("Unsupported source extension: %s", input_file);
		stats_update(STATS_SOURCELANG);
		result = false;
		goto out;
	}

	direct_i_file = language_is_preprocessed(actual_language);

	if (output_is_precompiled_header) {
		/* It doesn't work to create the .gch from preprocessed source. */
		cc_log("Creating precompiled header; not compiling preprocessed code");
		compile_preprocessed_source_code = false;
	}

	i_extension = getenv("CCACHE_EXTENSION");
	if (!i_extension) {
		const char *p_language = p_language_for_language(actual_language);
		if(str_eq(p_language, "c++-cpp-output")) { 
			/* Dirty fix for preprocessed file extension for cc166.
			 * The cp166 cannot handle cpp files with extension ii.*/
			i_extension = "ii.cpp";
		}
		else { 
			i_extension = extension_for_language(p_language) + 1;
		}
	}

	/* don't try to second guess the compilers heuristics for stdout handling */
	if (output_obj && str_eq(output_obj, "-")) {
		stats_update(STATS_OUTSTDOUT);
		cc_log("Output file is -");
		result = false;
		goto out;
	}

	if (!output_obj) {
		if (output_is_precompiled_header) {
			output_obj = format("%s.gch", input_file);
		} else {
			char *p;
			output_obj = x_strdup(input_file);
			if ((p = strrchr(output_obj, '/'))) {
				output_obj = p+1;
			}
			p = strrchr(output_obj, '.');
			if (!p || !p[1]) {
				cc_log("Badly formed object filename");
				stats_update(STATS_ARGS);
				result = false;
				goto out;
			}
			*p = 0;
			p = output_obj;
			if(found_S_opt)
			{ 
				output_obj = format("%s.s", p);
			}
			else
			{ /*The default extension of object file is obj for c166.*/
				output_obj = format("%s.obj", p);
			}
			free(p);
		}
	}

	/* cope with -o /dev/null */
	if (!str_eq(output_obj,"/dev/null")
	    && stat(output_obj, &st) == 0
	    && !S_ISREG(st.st_mode)) {
		cc_log("Not a regular file: %s", output_obj);
		stats_update(STATS_DEVICE);
		result = false;
		goto out;
	}

	/*
	 * Some options shouldn't be passed to the real compiler when it compiles
	 * preprocessed code:
	 */
	*preprocessor_args = args_copy(stripped_args);
	/* Args with -H has been already preprocessed.
	 * If it passed to the compiler again, some type redefined error will pop up.*/
	if (found_H_opt) {
		args_extend(*preprocessor_args, h_args);
	}

	/*
	 * Add flags for dependency generation only to the preprocessor command line.
	 */
	if (generating_dependencies) {
		if (!dependency_filename_specified) {
			char *default_depfile_name;
			char *base_name;

			base_name = remove_extension(output_obj);
			default_depfile_name = format("%s.d", base_name);
			free(base_name);
			args_add(dep_args, "-MF");
			args_add(dep_args, default_depfile_name);
			output_dep = make_relative_path(x_strdup(default_depfile_name));
		}

		if (!dependency_target_specified) {
			args_add(dep_args, "-MQ");
			args_add(dep_args, output_obj);
		}
	}

	if (compile_preprocessed_source_code) {
		*compiler_args = args_copy(stripped_args);
	} else {
		*compiler_args = args_copy(*preprocessor_args);
	}
	
	/* Due to bugs or cc166 v8.6r3, the behaviours of c/c++ preprocessor 
	 * are quite different.
	 * When using cpp preprocessor, the output will be directly send to stdout like gcc.
	 * When using c preprocessor, the output will be written to filename.i even without "-o".*/
	if(str_eq(actual_language, "c"))
	{ 
#ifdef _WIN32
#error Never test this in Windows.
#else
		args_add(*preprocessor_args, "-o/dev/stdout");
#endif
	}

	/*
	 * Only pass dependency arguments to the preprocesor since Intel's C++
	 * compiler doesn't produce a correct .d file when compiling preprocessed
	 * source.
	 */
	args_extend(*preprocessor_args, dep_args);

out:
	args_free(stripped_args);
	args_free(dep_args);
	args_free(h_args);

	return result;
}
Пример #25
0
/* returns 0 = done, ok. 1 = not done yet, -1 = error */
static int 
__netio_http_parse_data(netio_http_conn_t* conn, char *data, int datalen)
{
	/* collect data. */
	if (!conn->buf || (conn->buf_len - conn->data_len < datalen)) {
		int ns = conn->buf_len + datalen + 1024;
		char *tmp = 0;
		ASSERT_TRUE(tmp = mallocz(ns+1), err);
		if (conn->buf)
			memcpy(tmp, conn->buf, conn->data_len);
		freez(conn->buf);
		conn->buf = tmp;
		conn->buf_len = ns;
	}
	
	if (datalen > 0) {
		memcpy(conn->buf + conn->data_len, data, datalen);
		conn->data_len += datalen;
	}

	/* check if we have the header, parse url & datalen (if present) */
	if (!conn->header_got && strstr(conn->buf, "\r\n\r\n")) {
		char *line = conn->buf, *le;
		
		conn->header_got = 1;
		conn->header_len = strstr(conn->buf, "\r\n\r\n") - conn->buf + 4;
		do {
			le = strstr(line, "\r\n");
			if (le == line)
				break;

			if (str_startswith(line, "POST") || 
			    str_startswith(line, "GET") ||  
			    str_startswith(line, "OPTIONS") ||  
			    str_startswith(line, "HEAD") ||  
			    str_startswith(line, "PUT") ||  
			    str_startswith(line, "DELETE") ||  
			    str_startswith(line, "TRACE") ||  
			    str_startswith(line, "CONNECT")) {
				/* requests! */
				char *tmple;
				
				/* store method */
				if ((tmple = strchr(line, ' '))) {
					char *t2;
					tmple++;
					
					freez(conn->url); freez(conn->http_version);
					if (le) {
						t2 = le;
						while ((t2 > tmple) && *t2 != ' ')
							t2--;
					} else 
						t2 = strrchr(tmple, ' ');
					if (t2) {
						conn->url = strndup(tmple, t2-tmple);
						conn->http_version = trim(strndup(t2, le-t2));
					} else {
						conn->url = strndup(tmple, le-tmple);
					}
					freez(conn->method);
					conn->method = strndup(line, tmple-line);
					trim(conn->method);
					trim(conn->url);
				}
			} else if (str_startswith(line, "HTTP")) {
				/* for responses! */
				freez(conn->resp_code_line);
				conn->resp_code_line = trim(strndup(line, le-line));
				if (strchr(line, ' '))
					conn->resp_code = atoi(strchr(line, ' ')+1);
			} else {
				/* generic parameter */
				char *tmple = strchr(line, ':');

				if (str_startswith(line, "Content-Length: ")) {
					conn->content_len = atoi(strchr(line, ' ') + 1);
				}

				if (tmple) {
					char *val = strndup(tmple+1, le-tmple+1);
					char *key = strndup(line, tmple-line);
					
					netio_http_set_header(conn, key, val);
					freez(val);
					freez(key);
				}
			}
			if (le)
				line = le+2;
		} while (le);
	}

	/* process data.. */
	if (conn->header_got && 
	    ((conn->content_len == -1 && datalen < 1) || 
	     (conn->content_len != -1 && (conn->content_len <= (conn->data_len - conn->header_len))))) {

		if (conn->content_len == -1) {
			conn->content_len = conn->data_len - conn->header_len;
		}
		
		if (conn->method) {
			LOG_DEBUG("Got total %d bytes, %d bytes data for %s on http\n",
				  conn->data_len, conn->content_len, conn->url);
			
			/* treat multipart & 'normal' posts differently */
			if (!strcmp(conn->method, "POST") && 
			    str_startswith(netio_http_get_header(conn, "Content-Type"), "multipart")) {
				char *bound, *ps, *pe;
				bound = strstr_after(netio_http_get_header(conn, "Content-Type"), "boundary=");

				/* go through parts one-by-one, parsing name & data */
				if (bound) {
					ps = memmem_after(&conn->buf[conn->header_len], conn->data_len - conn->header_len, bound, strlen(bound));
					while (ps) {
						char *tmp, *name, *tmp2 = 0;
						pe = (char*)memmem(ps, conn->data_len - (ps-conn->buf), bound, strlen(bound));
						if (!pe) {
							pe = conn->buf + conn->data_len;
							tmp = 0;
						} else
							tmp = pe + strlen(bound);

						if ((name = strstr(ps, "Content-Disposition: ")))
							tmp2 = strstr(name, "\r\n");
						ps = strstr_after(ps, "\r\n\r\n");
						if (ps && name && tmp2) {
							tmp2[0] = 0;
							if ((name = strstr_after(name, "name=\"")) &&
							    (tmp2 = strchr(name, '"'))) {
								int datalen = pe-ps-4;
								ASSERT_ZERO(netio_http_conn_set_param(conn, name, tmp2-name, ps, datalen), err);
							}
						}
						ps = tmp;
					}
				}
			} else {
				int parsedata = conn->header_len;
				char *ns;

				ns = &(conn->buf[parsedata]);
				
				/* if get, set parsedata to the url's first ?-char */
				if (!strcmp(conn->method, "GET")) {
					char *params = strchr(conn->url, '?');
					if (params) {
						params[0] = 0;
						ns = params+1;
						conn->url_extras = strdup(ns);
					}
				}

				while (ns) {
					char *tmp = 0, *pe = 0;
					char *ps = strchr(ns, '=');
					if (ps) {
						pe = strchr(ps, '&');
						if (!pe) {
							pe = ps + strlen(ps);
							tmp = 0;
						} else
							tmp = pe+1;
					}
					if (ps) {
						char *k = strndup(ns, ps-ns);
						char *v = strndup(ps+1, pe-ps-1);
						if (k && v) {
							ship_urldecode(k);
							ship_urldecode(v);
							ASSERT_ZERO(netio_http_conn_set_param(conn, k, strlen(k), v, strlen(v)), err);
						}
						freez(k); 
						freez(v);
					}
					ns = tmp;
				}
			}
		}
		
		/* ..and we're done! */
		if (conn->url) {
			conn->original_url = conn->url;
			conn->url = strdup(conn->original_url);
			ship_urldecode(conn->url);
		}
		return 0;
	} else if (datalen < 1)
		goto err;
	
	return 1;
 err:
	return -1;
}
Пример #26
0
static void _open_log_file(_log_iterator *it)
{
  assert(it->state == &state_file);
  if (_log_file != NO_FILE) {
    if (_log_file_path == NULL)
      _log_file_path = getenv("SERVALD_LOG_FILE");
    if (_log_file_path == NULL && !cf_limbo) {
      strbuf sbfile = strbuf_local(_log_file_path_buf, sizeof _log_file_path_buf);
      strbuf_path_join(sbfile, serval_instancepath(), log_file_directory_path(), NULL);
      _compute_file_start_time(it);
      if (config.log.file.path[0]) {
	strbuf_path_join(sbfile, config.log.file.path, NULL);
      } else {
	struct tm tm;
	(void)localtime_r(&it->file_start_time, &tm);
	strbuf_append_strftime(sbfile, "/serval-%Y%m%d%H%M%S.log", &tm);
      }
      if (strbuf_overrun(sbfile)) {
	_log_file = NO_FILE;
	_logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot form log file name - buffer overrun");
      } else {
	_log_file_start_time = it->file_start_time;
	_log_file_path = strbuf_str(sbfile);
      }
    }
    if (!_log_file) {
      if (_log_file_path == NULL) {
	if (cf_limbo)
	  return;
	_log_file = NO_FILE;
	_logs_printf_nl(serverMode ? LOG_LEVEL_WARN : LOG_LEVEL_INFO, __NOWHERE__, "No log file configured");
      } else {
	// Create the new log file.
	size_t dirsiz = strlen(_log_file_path) + 1;
	char _dir[dirsiz];
	strcpy(_dir, _log_file_path);
	const char *dir = dirname(_dir); // modifies _dir[]
	if (mkdirs(dir, 0700) != -1 && (_log_file = fopen(_log_file_path, "a"))) {
	  setlinebuf(_log_file);
	  memset(it->state, 0, sizeof *it->state);
	  // The first line in every log file must be the starting time stamp.  (After that, it is up
	  // to _log_update() to insert other mandatory messages in any suitable order.)
	  _log_current_datetime(it, LOG_LEVEL_INFO);
	  _logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Logging to %s (fd %d)", _log_file_path, fileno(_log_file));
	  // Update the log symlink to point to the latest log file.
	  strbuf sbsymlink = strbuf_alloca(400);
	  strbuf_path_join(sbsymlink, serval_instancepath(), "serval.log", NULL);
	  if (strbuf_overrun(sbsymlink))
	    _logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot form log symlink name - buffer overrun");
	  else {
	    const char *f = _log_file_path;
	    const char *s = strbuf_str(sbsymlink);
	    const char *relpath = f;
	    for (; *f && *f == *s; ++f, ++s)
	      if (*f == '/')
		relpath = f;
	    while (*relpath == '/')
	      ++relpath;
	    while (*s == '/')
	      ++s;
	    if (strchr(s, '/'))
	      relpath = _log_file_path;
	    unlink(strbuf_str(sbsymlink));
	    if (symlink(relpath, strbuf_str(sbsymlink)) == -1)
	      _logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot symlink %s to %s - %s [errno=%d]", strbuf_str(sbsymlink), relpath, strerror(errno), errno);
	  }
	  // Expire old log files.
	  size_t pathsiz = strlen(_log_file_path) + 1;
	  char path[pathsiz];
	  while (1) {
	    strcpy(path, _log_file_path);
	    const char *base = basename(path); // modifies path[]
	    DIR *d = opendir(dir);
	    if (!d) {
	      _logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot expire log files: opendir(%s) - %s [errno=%d]", dir, strerror(errno), errno);
	      break;
	    }
	    struct dirent oldest;
	    memset(&oldest, 0, sizeof oldest);
	    unsigned count = 0;
	    while (1) {
	      struct dirent ent;
	      struct dirent *ep;
	      int err = readdir_r(d, &ent, &ep);
	      if (err) {
		_logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot expire log files: r_readdir(%s) - %s [errno=%d]", dir, strerror(err), err);
		break;
	      }
	      if (!ep)
		break;
	      const char *e;
	      if (   str_startswith(ent.d_name, "serval-", &e)
		  && isdigit(e[0]) && isdigit(e[1]) && isdigit(e[2]) && isdigit(e[3]) // YYYY
		  && isdigit(e[4]) && isdigit(e[5]) // MM
		  && isdigit(e[6]) && isdigit(e[7]) // DD
		  && isdigit(e[8]) && isdigit(e[9]) // HH
		  && isdigit(e[10]) && isdigit(e[11]) // MM
		  && isdigit(e[12]) && isdigit(e[13]) // SS
		  && strcmp(&e[14], ".log") == 0
	      ) {
		++count;
		if ( strcmp(ent.d_name, base) != 0
		  && (!oldest.d_name[0] || strcmp(ent.d_name, oldest.d_name) < 0)
		)
		  oldest = ent;
	      }
	    }
	    closedir(d);
	    if (count <= config.log.file.rotate || !oldest.d_name[0])
	      break;
	    strbuf b = strbuf_local(path, pathsiz);
	    strbuf_path_join(b, dir, oldest.d_name, NULL);
	    assert(!strbuf_overrun(b));
	    _logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Unlink %s", path);
	    unlink(path);
	  }
	} else {
	  _log_file = NO_FILE;
	  _logs_printf_nl(LOG_LEVEL_WARN, __HERE__, "Cannot create/append %s - %s [errno=%d]", _log_file_path, strerror(errno), errno);
	}
      }
    }
  }
}
Пример #27
0
/* Handle one line of output from the lspci subprocess */
static BOOL
handle_child_line(const char *line, void *data)
{
	const char *val;
	char buf[1024];

	if (str_startswith(line, "Class:"))
	{
		val = line + sizeof("Class:");
		/* Skip whitespace and second Class: occurance */
		val += strspn(val, " \t") + sizeof("Class");
		current_device.klass = strtol(val, NULL, 16);
	}
	else if (str_startswith(line, "Vendor:"))
	{
		val = line + sizeof("Vendor:");
		current_device.vendor = strtol(val, NULL, 16);
	}
	else if (str_startswith(line, "Device:"))
	{
		val = line + sizeof("Device:");
		/* Sigh, there are *two* lines tagged as Device:. We
		   are not interested in the domain/bus/slot/func */
		if (!strchr(val, ':'))
			current_device.device = strtol(val, NULL, 16);
	}
	else if (str_startswith(line, "SVendor:"))
	{
		val = line + sizeof("SVendor:");
		current_device.subvendor = strtol(val, NULL, 16);
	}
	else if (str_startswith(line, "SDevice:"))
	{
		val = line + sizeof("SDevice:");
		current_device.subdevice = strtol(val, NULL, 16);
	}
	else if (str_startswith(line, "Rev:"))
	{
		val = line + sizeof("Rev:");
		current_device.revision = strtol(val, NULL, 16);
	}
	else if (str_startswith(line, "ProgIf:"))
	{
		val = line + sizeof("ProgIf:");
		current_device.progif = strtol(val, NULL, 16);
	}
	else if (strspn(line, " \t") == strlen(line))
	{
		/* Blank line. Send collected information over channel */
		snprintf(buf, sizeof(buf), "%04x,%04x,%04x,%04x,%04x,%02x,%02x\n",
			 current_device.klass, current_device.vendor,
			 current_device.device, current_device.subvendor,
			 current_device.subdevice, current_device.revision, current_device.progif);
		lspci_send(buf);
		memset(&current_device, 0, sizeof(current_device));
	}
	else
	{
		warning("lspci: Unrecoqnized line '%s'\n", line);
	}
	return True;
}
Пример #28
0
static RD_BOOL
xkeymap_read(char *mapname)
{
	FILE *fp;
	char line[KEYMAP_MAX_LINE_LENGTH];
	unsigned int line_num = 0;
	unsigned int line_length = 0;
	char *keyname, *p;
	char *line_rest;
	uint8 scancode;
	uint16 modifiers;

	fp = xkeymap_open(mapname);
	if (fp == NULL)
	{
		error("Failed to open keymap %s\n", mapname);
		return False;
	}

	/* FIXME: More tolerant on white space */
	while (fgets(line, sizeof(line), fp) != NULL)
	{
		line_num++;

		/* Replace the \n with \0 */
		p = strchr(line, '\n');
		if (p != NULL)
			*p = 0;

		line_length = strlen(line);

		/* Completely empty line */
		if (strspn(line, " \t\n\r\f\v") == line_length)
		{
			continue;
		}

		/* Include */
		if (str_startswith(line, "include "))
		{
			if (!xkeymap_read(line + sizeof("include ") - 1))
				return False;
			continue;
		}

		/* map */
		if (str_startswith(line, "map "))
		{
			g_keylayout = strtoul(line + sizeof("map ") - 1, NULL, 16);
			DEBUG_KBD(("Keylayout 0x%x\n", g_keylayout));
			continue;
		}

		/* compose */
		if (str_startswith(line, "enable_compose"))
		{
			DEBUG_KBD(("Enabling compose handling\n"));
			g_enable_compose = True;
			continue;
		}

		/* sequence */
		if (str_startswith(line, "sequence"))
		{
			add_sequence(line + sizeof("sequence") - 1, mapname);
			continue;
		}

		/* keyboard_type */
		if (str_startswith(line, "keyboard_type "))
		{
			g_keyboard_type = strtol(line + sizeof("keyboard_type ") - 1, NULL, 16);
			DEBUG_KBD(("keyboard_type 0x%x\n", g_keyboard_type));
			continue;
		}

		/* keyboard_subtype */
		if (str_startswith(line, "keyboard_subtype "))
		{
			g_keyboard_subtype =
				strtol(line + sizeof("keyboard_subtype ") - 1, NULL, 16);
			DEBUG_KBD(("keyboard_subtype 0x%x\n", g_keyboard_subtype));
			continue;
		}

		/* keyboard_functionkeys */
		if (str_startswith(line, "keyboard_functionkeys "))
		{
			g_keyboard_functionkeys =
				strtol(line + sizeof("keyboard_functionkeys ") - 1, NULL, 16);
			DEBUG_KBD(("keyboard_functionkeys 0x%x\n", g_keyboard_functionkeys));
			continue;
		}

		/* Comment */
		if (line[0] == '#')
		{
			continue;
		}

		/* Normal line */
		keyname = line;
		p = strchr(line, ' ');
		if (p == NULL)
		{
			error("Bad line %d in keymap %s\n", line_num, mapname);
			continue;
		}
		else
		{
			*p = 0;
		}

		/* scancode */
		p++;
		scancode = strtol(p, &line_rest, 16);

		/* flags */
		/* FIXME: Should allow case-insensitive flag names. 
		   Fix by using lex+yacc... */
		modifiers = 0;
		if (strstr(line_rest, "altgr"))
		{
			MASK_ADD_BITS(modifiers, MapAltGrMask);
		}

		if (strstr(line_rest, "shift"))
		{
			MASK_ADD_BITS(modifiers, MapLeftShiftMask);
		}

		if (strstr(line_rest, "numlock"))
		{
			MASK_ADD_BITS(modifiers, MapNumLockMask);
		}

		if (strstr(line_rest, "localstate"))
		{
			MASK_ADD_BITS(modifiers, MapLocalStateMask);
		}

		if (strstr(line_rest, "inhibit"))
		{
			MASK_ADD_BITS(modifiers, MapInhibitMask);
		}

		add_to_keymap(keyname, scancode, modifiers, mapname);

		if (strstr(line_rest, "addupper"))
		{
			/* Automatically add uppercase key, with same modifiers 
			   plus shift */
			for (p = keyname; *p; p++)
				*p = toupper((int) *p);
			MASK_ADD_BITS(modifiers, MapLeftShiftMask);
			add_to_keymap(keyname, scancode, modifiers, mapname);
		}
	}

	fclose(fp);
	return True;
}
Пример #29
0
int main() {
    printf("=============================================\n");

 /* * * * * * * *       
  * str.h tests
  */
    
    char* s = "test string";
    
    // str_new()
    char* str_new_ = str_new(s);
    ass(str_new_ != s, "defferent ptr");
    ass_eq(str_new_, s);
    
    // str_auto()
    char* str_auto_ = str_auto(str_new_);
    ass(str_auto_ != str_new_, "different ptr");
    ass_eq(str_auto_, str_new_);

    // str_cat_new()
    char* str_cat_new_ = str_cat_new(s, " gnirts tset");
    ass(str_cat_new_ != s, "different ptr");
    ass_eq(str_cat_new_, "test string gnirts tset");

    // str_cat_auto()
    char* str_cat_auto_ = str_cat_auto(str_cat_new_, "!!");
    ass(str_cat_auto_ != str_cat_new_, "dif ptr");
    ass_eq(str_cat_auto_, "test string gnirts tset!!");

    // str_sub_new()
    char* str_sub_new_ = str_sub_new(s, 0, 4);
    ass_eq(str_sub_new_, "test");

    // str_sub_auto()
    char* str_sub_auto_ = str_sub_auto(s, 5, 200); // overalocated?
    ass_eq(str_sub_auto_, "string");
    ass_eq(str_sub_auto(s, 5, 5), "");
    ass_eq(str_sub_auto(s, 9, 1), "");

    // str_slice_new()
    char* str_slice_new_ = str_slice_new(s, 0, 4);
    ass_eq(str_slice_new_, "test");
    ass_eq(str_slice_new(s, 0, 0), "test string");
    ass_eq(str_slice_new(s, 5, 0), "string");
    ass_eq(str_slice_new(s,-6, 0), "string");

    // str_slice_auto()  
    ass_eq(str_slice_auto(s,-6,-3), "str");
    ass_eq(str_slice_auto(s,-1,-2), "");
    ass_eq(str_slice_auto(s, 2, 1), "");
    ass_eq(str_slice_auto(s, 5, 200), "string"); // overallocated?

    // str_input_dest()
    // str_input_new()
    // str_input_auto()

    // str_format_dest()  // sprintf
    // str_format_new()  // asprintf
    // str_format_auto()

    // str_len()  // strlen
    
    // str_is_alnum()
    ass(str_is_alnum("abc123"));
    ass(! str_is_alnum("(@^*^&"));

    // str_is_alpha()
    ass(str_is_alpha("abcdEFG"));
    ass(! str_is_alpha("!@#$@#$"));

    // str_from_file_new()
    char* str_from_file_new_ = str_from_file_new("file.test");
    ass_eq(str_from_file_new_, "file.test:test\n");

    // str_eq()
    ass(str_eq("abc", "abc"));
    ass(str_eq("", ""));

    // str_endswith()
    ass(str_endswith(s, "string"));
    ass(str_endswith(s, "ing"));
    ass(str_endswith(s, "test string"));
    //ass(str_endswith(s, "")); //hm...
    //logs(str_slice_auto(s, -1 * strlen(""), 0));
    ass(!str_endswith(s, "swing"));
    ass(!str_endswith(s, " test string"));

    // str_startswith()
    ass(str_startswith(s, "test"));
    ass(str_startswith(s, "test string"));
    ass(str_startswith(s, ""));

}
Пример #30
0
/**
 * Parse arguments, extract ones we care about, and also work out
 * whether it will be possible to distribute this invocation remotely.
 *
 * This is a little hard because the cc argument rules are pretty complex, but
 * the function still ought to be simpler than it already is.
 *
 * This code is called on both the client and the server, though they use the
 * results differently.
 *
 * This function makes a copy of the arguments, modified to ensure that
 * the arguments include '-o <filename>'.  This is returned in *ret_newargv.
 * The copy is dynamically allocated and the caller is responsible for
 * deallocating it.
 *
 * If @p forced_cpp_ext is non NULL, it is filled it with the extension that
 * is forced by a -x language directive.  The caller should not free this
 * value.
 *
 * @returns 0 if it's ok to distribute this compilation, or an error code.
 **/
int dcc_scan_args(char *argv[], char **input_file, char **output_file,
                  char ***ret_newargv, const char **forced_cpp_ext)
{
    int seen_opt_c = 0, seen_opt_s = 0;
    int i;
    char *a, *optx_lang;
    const char *optx_ext = NULL;
    int ret;

     /* allow for -o foo.o */
    if ((ret = dcc_copy_argv(argv, ret_newargv, 2)) != 0)
        return ret;
    argv = *ret_newargv;

    /* FIXME: new copy of argv is leaked */

    dcc_trace_argv("scanning arguments", argv);

#ifdef XCODE_INTEGRATION
    /* Xcode invokes the distcc client as "distcc --host-info HOST" to gather
     * info about HOST.  When the request is transmitted to the distccd server,
     * it will see only "--host-info" and no other arguments in argv. */
    if (argv[0] && !strcmp(argv[0], "--host-info")) {
        return 0;
    }
#endif /* XCODE_INTEGRATION */

    /* Things like "distcc -c hello.c" with an implied compiler are
     * handled earlier on by inserting a compiler name.  At this
     * point, argv[0] should always be a compiler name. */
    if (argv[0] && argv[0][0] == '-') {
        rs_log_error("unrecognized distcc option: %s", argv[0]);
        exit(EXIT_BAD_ARGUMENTS);
    }

    *input_file = *output_file = NULL;

    for (i = 0; (a = argv[i]); i++) {
        if (a[0] == '-') {
            if (!strcmp(a, "-E")) {
                rs_trace("-E call for cpp must be local");
                return EXIT_DISTCC_FAILED;
            } else if (!strcmp(a, "-MD") || !strcmp(a, "-MMD")) {
                /* These two generate dependencies as a side effect.  They
                 * should work with the way we call cpp. */
            } else if (!strcmp(a, "-MG") || !strcmp(a, "-MP")) {
                /* These just modify the behaviour of other -M* options and do
                 * nothing by themselves. */
            } else if (!strcmp(a, "-MF") || !strcmp(a, "-MT") ||
                       !strcmp(a, "-MQ")) {
                /* As above but with extra argument. */
                i++;
            } else if (!strncmp(a, "-MF", 3) || !strncmp(a, "-MT", 3) ||
                       !strncmp(a, "-MQ", 3)) {
                /* As above, without extra argument. */
            } else if (a[1] == 'M') {
                /* -M(anything else) causes the preprocessor to
                    produce a list of make-style dependencies on
                    header files, either to stdout or to a local file.
                    It implies -E, so only the preprocessor is run,
                    not the compiler.  There would be no point trying
                    to distribute it even if we could. */
                rs_trace("%s implies -E (maybe) and must be local", a);
                return EXIT_DISTCC_FAILED;
            } else if (!strcmp(a, "-march=native")) {
                rs_trace("-march=native generates code for local machine; "
                         "must be local");
                return EXIT_DISTCC_FAILED;
            } else if (!strcmp(a, "-mtune=native")) {
                rs_trace("-mtune=native optimizes for local machine; "
                         "must be local");
                return EXIT_DISTCC_FAILED;
            } else if (str_startswith("-Wa,", a)) {
                /* Look for assembler options that would produce output
                 * files and must be local.
                 *
                 * Writing listings to stdout could be supported but it might
                 * be hard to parse reliably. */
                if (strstr(a, ",-a") || strstr(a, "--MD")) {
                    rs_trace("%s must be local", a);
                    return EXIT_DISTCC_FAILED;
                }
            } else if (str_startswith("-specs=", a)) {
                rs_trace("%s must be local", a);
                return EXIT_DISTCC_FAILED;
            } else if (!strcmp(a, "-S")) {
                seen_opt_s = 1;
            } else if (!strcmp(a, "-fprofile-arcs")
                       || !strcmp(a, "-ftest-coverage")) {
                rs_log_info("compiler will emit profile info; must be local");
                return EXIT_DISTCC_FAILED;
            } else if (!strcmp(a, "-frepo")) {
                rs_log_info("compiler will emit .rpo files; must be local");
                return EXIT_DISTCC_FAILED;
            } else if (!strcmp("-x", a)) {
              optx_lang = argv[++i];
              if (!optx_lang || !strlen(optx_lang)) {
                rs_log_info("-x requires an argument; running locally");
                return EXIT_DISTCC_FAILED;
              }
              if (*input_file) {
                rs_log_info("-x must precede source file; running locally");
                return EXIT_DISTCC_FAILED;
              }
              if (optx_ext) {
                rs_log_info("at most one -x supported; running locally");
                return EXIT_DISTCC_FAILED;
              }
              optx_ext = dcc_optx_ext_lookup(optx_lang);
              if (!optx_ext) {
                rs_log_info("unsupported -x language; running locally");
                return EXIT_DISTCC_FAILED;
              }
            } else if (str_startswith("-x", a)) {
                /* Handling -xlanguage is possible, but it makes some of the
                 * command rewriting (over in remote.c) much harder, so it
                 * isn't supported at this time. */
                rs_log_info("-xlanguage unsupported, use -x language instead; "
                            "running locally");
                return EXIT_DISTCC_FAILED;
            } else if (str_startswith("-dr", a)) {
                rs_log_info("gcc's debug option %s may write extra files; "
                            "running locally", a);
                return EXIT_DISTCC_FAILED;
            } else if (!strcmp(a, "-c")) {
                seen_opt_c = 1;
            } else if (!strcmp(a, "-o")) {
                /* Whatever follows must be the output */
                a = argv[++i];
                goto GOT_OUTPUT;
            } else if (str_startswith("-o", a)) {
                a += 2;         /* skip "-o" */
                goto GOT_OUTPUT;
            }
        } else {
            if (dcc_is_source(a)) {
                rs_trace("found input file \"%s\"", a);
                if (*input_file) {
                    rs_log_info("do we have two inputs?  i give up");
                    return EXIT_DISTCC_FAILED;
                }
                *input_file = a;
            } else if (str_endswith(".o", a)) {
              GOT_OUTPUT:
                rs_trace("found object/output file \"%s\"", a);
                if (*output_file) {
                    rs_log_info("called for link?  i give up");
                    return EXIT_DISTCC_FAILED;
                }
                *output_file = a;
            }
        }
    }

    /* TODO: ccache has the heuristic of ignoring arguments that are not
     * extant files when looking for the input file; that's possibly
     * worthwile.  Of course we can't do that on the server. */

    if (!seen_opt_c && !seen_opt_s) {
        rs_log_info("compiler apparently called not for compile");
        return EXIT_DISTCC_FAILED;
    }

    if (!*input_file) {
        rs_log_info("no visible input file");
        return EXIT_DISTCC_FAILED;
    }

    if (dcc_source_needs_local(*input_file))
        return EXIT_DISTCC_FAILED;

    if (!*output_file) {
        /* This is a commandline like "gcc -c hello.c".  They want
         * hello.o, but they don't say so.  For example, the Ethereal
         * makefile does this.
         *
         * Note: this doesn't handle a.out, the other implied
         * filename, but that doesn't matter because it would already
         * be excluded by not having -c or -S.
         */
        char *ofile;

        /* -S takes precedence over -c, because it means "stop after
         * preprocessing" rather than "stop after compilation." */
        if (seen_opt_s) {
            if (dcc_output_from_source(*input_file, ".s", &ofile))
                return EXIT_DISTCC_FAILED;
        } else if (seen_opt_c) {
            if (dcc_output_from_source(*input_file, ".o", &ofile))
                return EXIT_DISTCC_FAILED;
        } else {
            rs_log_crit("this can't be happening(%d)!", __LINE__);
            return EXIT_DISTCC_FAILED;
        }
        rs_log_info("no visible output file, going to add \"-o %s\" at end",
                      ofile);
        dcc_argv_append(argv, strdup("-o"));
        dcc_argv_append(argv, ofile);
        *output_file = ofile;
    }

    dcc_note_compiled(*input_file, *output_file);

    if (strcmp(*output_file, "-") == 0) {
        /* Different compilers may treat "-o -" as either "write to
         * stdout", or "write to a file called '-'".  We can't know,
         * so we just always run it locally.  Hopefully this is a
         * pretty rare case. */
        rs_log_info("output to stdout?  running locally");
        return EXIT_DISTCC_FAILED;
    }

    if (forced_cpp_ext)
        *forced_cpp_ext = optx_ext;

    return 0;
}