Пример #1
0
// dead-reckoning support
bool AP_AHRS_NavEKF::get_position(struct Location &loc) const
{
    Vector3f ned_pos;
    switch (active_EKF_type()) {
    case EKF_TYPE1:
        if (EKF1.getLLH(loc) && EKF1.getPosNED(ned_pos)) {
            // fixup altitude using relative position from AHRS home, not
            // EKF origin
            loc.alt = get_home().alt - ned_pos.z*100;
            return true;
        }
        break;
    case EKF_TYPE2:
        if (EKF2.getLLH(loc) && EKF2.getPosNED(ned_pos)) {
            // fixup altitude using relative position from AHRS home, not
            // EKF origin
            loc.alt = get_home().alt - ned_pos.z*100;
            return true;
        }
        break;

    default:
        break;
    }
    return AP_AHRS_DCM::get_position(loc);
}
Пример #2
0
static void stats_print_diff(struct stats_file *file)
{
	struct stats_record *begin, *end;

	begin = get_begin(file);
	begin = get_next(file, begin);
	end = get_end(file);

	printf("\n(begin + 1)\n");
	printf("\t[%04d] ", get_index(file, begin));
	stats_print_record(begin);
	printf("end\n");
	printf("\t[%04d] ", get_index(file, end));
	stats_print_record(end);

	if (file->home_first && get_home(file)) {
		printf("\nhome\n");
		stats_print_rec_diff(file->home_first, get_home(file));
	}

	if (file->roaming_first && get_roaming(file)) {
		printf("\roaming\n");
		stats_print_rec_diff(file->roaming_first, get_roaming(file));
	}
}
Пример #3
0
// return a relative ground position in meters/second, North/East/Down
// order. Must only be called if have_inertial_nav() is true
bool AP_AHRS_NavEKF::get_relative_position_NED(Vector3f &vec) const
{
    switch (active_EKF_type()) {
    case EKF_TYPE_NONE:
        return false;

#if AP_AHRS_WITH_EKF1
    case EKF_TYPE1:
        return EKF1.getPosNED(vec);
#endif

    case EKF_TYPE2:
    default:
        return EKF2.getPosNED(-1,vec);

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
    case EKF_TYPE_SITL: {
        Location loc;
        get_position(loc);
        Vector2f diff2d = location_diff(get_home(), loc);
        const struct SITL::sitl_fdm &fdm = _sitl->state;
        vec = Vector3f(diff2d.x, diff2d.y,
                       -(fdm.altitude - get_home().alt*0.01f));
        return true;
    }
#endif
    }
}
Пример #4
0
// return a relative ground position to the origin in meters
// North/East/Down order.
bool AP_AHRS_NavEKF::get_relative_position_NED_origin(Vector3f &vec) const
{
    switch (active_EKF_type()) {
    case EKF_TYPE_NONE:
        return false;

    case EKF_TYPE2:
    default: {
        Vector2f posNE;
        float posD;
        if (EKF2.getPosNE(-1,posNE) && EKF2.getPosD(-1,posD)) {
            // position is valid
            vec.x = posNE.x;
            vec.y = posNE.y;
            vec.z = posD;
            return true;
        }
        return false;
    }

    case EKF_TYPE3: {
            Vector2f posNE;
            float posD;
            if (EKF3.getPosNE(-1,posNE) && EKF3.getPosD(-1,posD)) {
                // position is valid
                vec.x = posNE.x;
                vec.y = posNE.y;
                vec.z = posD;
                return true;
            }
            return false;
        }

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
    case EKF_TYPE_SITL: {
        if (!_sitl) {
            return false;
        }
        Location loc;
        get_position(loc);
        const Vector2f diff2d = location_diff(get_home(), loc);
        const struct SITL::sitl_fdm &fdm = _sitl->state;
        vec = Vector3f(diff2d.x, diff2d.y,
                       -(fdm.altitude - get_home().alt*0.01f));
        return true;
    }
#endif
    }
}
Пример #5
0
std::string expand_path_home(const std::string &str)
{
  const char *home = get_home();
  if (home && str.size() > 0 && str[0] == '~')
    return home + str.substr(1);
  return str;
}
Пример #6
0
int asill_load_pars(struct asill_s *A)
{
  char fname[MAX_PATH];
  FILE *f;

  snprintf(fname, MAX_PATH, "%s/.ASILL_%d_%d", get_home(), A->model, A->n);
  f = fopen(fname, "r");
  if (f) {
    char b[200];

    while(!feof(f)) {
      if (fgets(b, 200, f)) {
	int p = atoi(b);
	const char *vs = get_p(b);

	if (vs) {
	  int v = atoi(vs);

	  if (p >= 11 && p <= 21) {
	    asill_set_int_par(A, p - 11, v);
	    if (p == 16 || p == 17) sleep(1); /* without this column denoise is killed if row and bias cor are saved off */
	  }
	  else {
	    switch(p) {
	    case 2:
	      A->width = v;
	      break;
	    case 3:
	      A->height = v;
	      break;
	    case 4:
	      A->start_x = v;
	      break;
	    case 5:
	      A->start_y = v;
	      break;
	    case 6:
	      A->bin = v;
	      break;
	    case 7:
	      A->fmt = v;
	      break;
	    case 8:
	      A->pclk = v;
	      break;
	    case 9:
	      A->exposure_us = v;
	      break;
	    }
	  }
	}
      }
    }
    fclose(f);
    setup_frame(A);
  }
  else
    return -1;
  return 0;
}
Пример #7
0
int asill_save_pars(struct asill_s *A)
{
  char fname[MAX_PATH];

  snprintf(fname, MAX_PATH, "%s/.ASILL_%d_%d", get_home(), A->model, A->n);
  return save_hdr(A, fname, time(NULL), 0);
}
Пример #8
0
// get latest height above ground level estimate in metres and a validity flag
bool AP_AHRS_NavEKF::get_hagl(float &height) const
{
    switch (active_EKF_type()) {
    case EKF_TYPE_NONE:
        return false;

    case EKF_TYPE2:
    default:
        return EKF2.getHAGL(height);
        
    case EKF_TYPE3:
        return EKF3.getHAGL(height);

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
    case EKF_TYPE_SITL: {
        if (!_sitl) {
            return false;
        }
        const struct SITL::sitl_fdm &fdm = _sitl->state;
        height = fdm.altitude - get_home().alt*0.01f;
        return true;
    }
#endif
    }
}
Пример #9
0
char *
get_config_file_path (void)
{
  char *upath = NULL, *rpath = NULL;

  /* determine which config file to open, default or custom */
  if (conf.iconfigfile != NULL) {
    rpath = realpath (conf.iconfigfile, NULL);
    if (rpath == NULL)
      FATAL ("Unable to open the specified config file. %s", strerror (errno));
    return rpath;
  }

  /* otherwise, fallback to global config file, or
   * attempt to use the user's config file */
  if (conf.load_global_config) {
    upath = get_global_config ();
    rpath = realpath (upath, NULL);
    if (upath) {
      free (upath);
    }
  }
  if (rpath == NULL) {
    upath = get_home ();
    rpath = realpath (upath, NULL);
    if (upath) {
      free (upath);
    }
  }

  return rpath;
}
Пример #10
0
Файл: xdg.c Проект: Cloudef/chck
char*
xdg_get_path(const char *xdg_env, const char *default_path)
{
   assert(xdg_env && default_path && default_path[0] != '/');

   if (!xdg_env || !default_path || default_path[0] == '/')
      return NULL;

   const char *xdg_dir;
   if ((xdg_dir = getenv(xdg_env)) && xdg_dir[0] == '/')
      return strip_slash(ccopy(xdg_dir));

   char *home;
   if (!(home = get_home()))
      return NULL; /** fatal! */

   const size_t len = snprintf(NULL, 0, "%s/%s", home, default_path) + 1;

   char *path;
   if (!(path = calloc(1, len))) {
      free(home);
      return NULL; /** fatal! */
   }

   snprintf(path, len, "%s/%s", home, default_path);
   free(home);
   return path;
}
Пример #11
0
int main (int argc, char *argv[])
{
  GtkWidget *window;

  /* Init GTK stuffs */
  gtk_set_locale();
  gtk_init(&argc, &argv);

  /* Get command arguments */
  if ( argc > 1 )
    usage();

  /* Add pixmap search path */
  {
    char *home = get_home();
    char path[strlen(home)+10];
    snprintf(path, sizeof(path), "%s/icons", home);
    add_pixmap_directory(path);
  }
  add_pixmap_directory (".");

  /* Start Report Config gui */
  window = report_config_gui(NULL);
  gtk_signal_connect_object(GTK_OBJECT(window), "destroy",
                            GTK_SIGNAL_FUNC(gtk_main_quit), (gpointer) NULL);

  /* Setup control command handling */
  command_id = gdk_input_add(fileno(stdin), GDK_INPUT_READ,
			     (GdkInputFunction) command_handler, window);

  gtk_main();

  return 0;
}
Пример #12
0
// write a relative ground position in meters, Down
// return true if the estimate is valid
bool AP_AHRS_NavEKF::get_relative_position_D(float &posD) const
{
    switch (active_EKF_type()) {
    case EKF_TYPE_NONE:
        return false;

#if AP_AHRS_WITH_EKF1
    case EKF_TYPE1: {
        bool position_is_valid = EKF1.getPosD(posD);
        return position_is_valid;
    }
#endif

    case EKF_TYPE2:
    default: {
        bool position_is_valid = EKF2.getPosD(-1,posD);
        return position_is_valid;
    }

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
    case EKF_TYPE_SITL: {
        const struct SITL::sitl_fdm &fdm = _sitl->state;
        posD = -(fdm.altitude - get_home().alt*0.01f);
        return true;
    }
#endif
    }
}
Пример #13
0
// passes a reference to the location of the inertial navigation origin
// in WGS-84 coordinates
// returns a boolean true when the inertial navigation origin has been set
bool AP_AHRS_NavEKF::get_origin(Location &ret) const
{
    switch (ekf_type()) {
    case EKF_TYPE_NONE:
        return false;

#if AP_AHRS_WITH_EKF1
    case EKF_TYPE1:
        if (!EKF1.getOriginLLH(ret)) {
            return false;
        }
        return true;
#endif

    case EKF_TYPE2:
    default:
        if (!EKF2.getOriginLLH(ret)) {
            return false;
        }
        return true;

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
    case EKF_TYPE_SITL:
        ret = get_home();
        return ret.lat != 0 || ret.lng != 0;
#endif
    }
}
Пример #14
0
// write a relative ground position estimate in meters, North/East order
// return true if estimate is valid
bool AP_AHRS_NavEKF::get_relative_position_NE(Vector2f &posNE) const
{
    switch (active_EKF_type()) {
    case EKF_TYPE_NONE:
        return false;

#if AP_AHRS_WITH_EKF1
    case EKF_TYPE1: {
        bool position_is_valid = EKF1.getPosNE(posNE);
        return position_is_valid;
    }
#endif

    case EKF_TYPE2:
    default: {
        bool position_is_valid = EKF2.getPosNE(-1,posNE);
        return position_is_valid;
    }

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
    case EKF_TYPE_SITL: {
        Location loc;
        get_position(loc);
        posNE = location_diff(get_home(), loc);
        return true;
    }
#endif
    }
}
Пример #15
0
static void stats_hdr_info(struct stats_file *file)
{
	struct stats_file_header *hdr;
	struct stats_record *begin, *end, *home, *roaming;
	unsigned int home_idx, roaming_idx;

	hdr = get_hdr(file);
	begin = get_begin(file);
	end = get_end(file);

	home = get_home(file);
	if (!home)
		home_idx = UINT_MAX;
	else
		home_idx = get_index(file, home);

	roaming = get_roaming(file);
	if (!roaming)
		roaming_idx = UINT_MAX;
	else
		roaming_idx = get_index(file, roaming);

	printf("Data Structure Sizes\n");
	printf("  sizeof header   %zd/0x%02zx\n",
		sizeof(struct stats_file_header),
		sizeof(struct stats_file_header));
	printf("  sizeof entry    %zd/0%02zx\n\n",
		sizeof(struct stats_record),
		sizeof(struct stats_record));

	printf("File\n");
	printf("  addr            %p\n",  file->addr);
	printf("  len             %zd\n", file->len);

	printf("  max nr entries  %d\n", file->max_nr);
	printf("  nr entries      %d\n\n", file->nr);

	printf("Header\n");
	printf("  magic           0x%08x\n", hdr->magic);
	printf("  begin           [%d] 0x%08x\n",
		get_index(file, begin), hdr->begin);
	printf("  end             [%d] 0x%08x\n",
		get_index(file, end), hdr->end);
	printf("  home            [%d] 0x%08x\n",
		home_idx, hdr->home);
	printf("  roaming         [%d] 0x%08x\n\n",
		roaming_idx, hdr->roaming);


	printf("Pointers\n");
	printf("  hdr             %p\n", hdr);
	printf("  begin           %p\n", begin);
	printf("  end             %p\n", end);
	printf("  home            %p\n", home);
	printf("  romaing         %p\n", roaming);
	printf("  first           %p\n", file->first);
	printf("  last            %p\n\n", file->last);
}
Пример #16
0
// dead-reckoning support
bool AP_AHRS_NavEKF::get_position(struct Location &loc) const
{
    Vector3f ned_pos;
    if (using_EKF() && EKF.getLLH(loc) && EKF.getPosNED(ned_pos)) {
        // fixup altitude using relative position from AHRS home, not
        // EKF origin
        loc.alt = get_home().alt - ned_pos.z*100;
        return true;
    }
    return AP_AHRS_DCM::get_position(loc);
}
Пример #17
0
const std::string compact_path_home(const std::string &str)
{
  const char *home = get_home();
  if (home)
  {
    std::string home_str(home);
    if (str == home_str || boost::algorithm::starts_with(str, home_str + "/"))
      return "~" + str.substr(home_str.size());
  }
  return str;
}
Пример #18
0
void readAgents(void) {

FILE *fp;
char fname[BUFSIZ],buf[512];
char *homedir,*ptr;

	if (get_home(&homedir)!=0 || !homedir) {
		fprintf(stderr,"home: Could not get your home directory.\n");
		return;
	}
	sprintf(fname,"%s/.mosaic/spoof-agents",homedir); // SAM
	free(homedir);

	if (!(fp=fopen(fname,"r"))) {
		return;
	}

	while (!feof(fp)) {
		fgets(buf,511,fp);
		if (feof(fp)) {
			break;
		}
		if (*buf && *buf!='#') {
			buf[strlen(buf)-1]='\0';
			for (ptr=buf; *ptr && isspace(*ptr); ptr++);
			if (*ptr=='+') { /* This is to be the default*/
				if (*(ptr+1)) {
					agent[numAgents]=strdup(ptr+1);
					selectedAgent=numAgents;
				}
				else {
					continue;
				}
			}
			else if (*ptr) {
				agent[numAgents]=strdup(ptr);
			}
			else {
				continue;
			}
			numAgents++;
			if (numAgents==MAX_AGENTS) { /* limit reached */
				fprintf(stderr,"WARNING: Hard limit reached for agent spoof file.\n");
				break;
			}
		}
	}

	fclose(fp);

	return;
}
Пример #19
0
// dead-reckoning support
bool AP_AHRS_NavEKF::get_position(struct Location &loc) const
{
    Vector3f ned_pos;
    switch (active_EKF_type()) {
    case EKF_TYPE1:
        if (EKF1.getLLH(loc) && EKF1.getPosNED(ned_pos)) {
            // fixup altitude using relative position from AHRS home, not
            // EKF origin
            loc.alt = get_home().alt - ned_pos.z*100;
            return true;
        }
        break;
    case EKF_TYPE2:
        if (EKF2.getLLH(loc) && EKF2.getPosNED(-1,ned_pos)) {
            // fixup altitude using relative position from AHRS home, not
            // EKF origin
            loc.alt = get_home().alt - ned_pos.z*100;
            return true;
        }
        break;

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
    case EKF_TYPE_SITL: {
        const struct SITL::sitl_fdm &fdm = _sitl->state;
        memset(&loc, 0, sizeof(loc));
        loc.lat = fdm.latitude * 1e7;
        loc.lng = fdm.longitude * 1e7;
        loc.alt = fdm.altitude*100;
        return true;
    }
#endif
        
    default:
        break;
    }
    return AP_AHRS_DCM::get_position(loc);
}
Пример #20
0
void set_window_icon(GtkWindow *window)
{
  char *home = get_home();
  int len = strlen(home);
  char pixmap[len+32];
  GdkPixbuf *pixbuf;

  strcpy(pixmap, home);
  strcpy(pixmap+len, "/icons/testfarm.png");

  pixbuf = gdk_pixbuf_new_from_file(pixmap, NULL);
  if ( pixbuf != NULL ) {
    gtk_window_set_icon(window, pixbuf);
    gdk_pixbuf_unref(pixbuf);
  }
}
Пример #21
0
static char *
get_config_file_path (void)
{
  char *path = NULL;

  /* determine which config file to open, default or custom */
  if (conf.iconfigfile != NULL) {
    path = realpath (conf.iconfigfile, NULL);
    if (path == NULL)
      FATAL ("%s", strerror (errno));
  } else if (conf.load_global_config)
    path = get_global_config ();
  else
    path = get_home ();

  return path;
}
Пример #22
0
/*============================================
 * expand_special_fname_chars -- Replace ~ with home
 *==========================================*/
BOOLEAN
expand_special_fname_chars (STRING buffer, INT buflen, INT utf8)
{
	char * sep=0;
	if (buffer[0]=='~') {
		if (is_dir_sep(buffer[1])) {
			STRING home = get_home();
			if (home && home[0]) {
				STRING tmp;
				if ((INT)strlen(home) + 1 + (INT)strlen(buffer) > buflen) {
					return FALSE;
				}
				tmp = strsave(buffer);
				buffer[0] = 0;
				llstrapps(buffer, buflen, utf8, home);
				llstrapps(buffer, buflen, utf8, tmp+1);
				strfree(&tmp);
				return TRUE;
			}
		}
		/* check for ~name/... and resolve the ~name */
		if ((sep = strchr(buffer,LLCHRDIRSEPARATOR))) {
			STRING username = strsave(buffer+1);
			STRING homedir;
			username[sep-buffer+1] = 0;
			homedir = get_user_homedir(username);
			strfree(&username);
			if (homedir) {
				STRING tmp=0;
				if ((INT)strlen(homedir) + 1 + (INT)strlen(sep+1) > buflen) {
					return FALSE;
				}
				tmp = strsave(sep+1);
				buffer[0] = 0;
				llstrapps(buffer, buflen, utf8, homedir);
				llstrapps(buffer, buflen, utf8, tmp+(sep-buffer+1));
				strfree(&tmp);
				return TRUE;
			}
		}
	}
	return TRUE;
}
Пример #23
0
int	replace_tild(t_cmd *tmp, t_env *env, char *home)
{
	char	*tmp_home;

	if ((tmp_home = get_home(env)))
	{
		if ((tmp_home = ft_strdup(tmp_home)) == NULL)
			return (ft_error("Error: Couldn't strdup\n"));
	}
	else if (home)
		tmp_home = home;
	else
		return (0);
	if (tmp->word[1] == '/')
		tmp->word = tmp->word + 1;
	else
		tmp->word[0] = '/';
	if ((tmp->word = ft_strcat(tmp_home, tmp->word)) == NULL)
		return (ft_error("Error: Couldn't strcat\n"));
	return (0);
}
Пример #24
0
int cli_cd(char *arg)
{
	char line[MAXPATHLEN];
	char key[MAXPATHLEN];
	char value[MAXPATHLEN];
	if (strlen(arg) == 0) 
	{
		get_home(line);
		read_pair(line, key, value);
		chdir(value);
		cli_pwd();
		return 0;
	}
	if (chdir(arg) == -1) 
	{
		debugNetPrintf(ERROR,"%s %s\n",strerror(errno));
		return 1;
	}
	cli_pwd();
	return (0);
}
Пример #25
0
/* Look for [._]gprc: $GPRC, then in $HOME, ., /etc, pari_datadir */
static FILE *
gprc_get(void)
{
  FILE *f = NULL;
  const char *gprc = os_getenv("GPRC");
  if (gprc) f = gprc_chk(gprc);
  if (!f)
  {
    int free_it = 0;
    const char *home = get_home(&free_it);
    char *str, *s, c;
    long l;
    l = strlen(home); c = home[l-1];
    /* + "/gprc.txt" + \0*/
    str = strcpy((char*)pari_malloc(l+10), home);
    if (free_it) pari_free((void*)home);
    s = str + l;
    if (c != '/' && c != '\\') *s++ = '/';
#ifndef _WIN32
    strcpy(s, ".gprc");
#else
    strcpy(s, "gprc.txt");
#endif
    f = gprc_chk(str); /* in $HOME */
    if (!f) f = gprc_chk(s); /* in . */
#ifndef _WIN32
    if (!f) f = gprc_chk("/etc/gprc");
#else
    if (!f)  /* in basedir */
    {
      const char *basedir = win32_basedir();
      char *t = (char *) pari_malloc(strlen(basedir)+strlen(s)+2);
      sprintf(t, "%s/%s", basedir, s);
      f = gprc_chk(t); free(t);
    }
#endif
    pari_free(str);
  }
  return f;
}
Пример #26
0
static int get_cookie(char *buf, int bufsize)
{
    char fname[EI_MAX_HOME_PATH + sizeof(COOKIE_FILE) + 1];
    int fd;
    int len;
    unsigned char next_c;
    
    if (!get_home(fname, EI_MAX_HOME_PATH+1)) {
	fprintf(stderr,"<ERROR> get_cookie: too long path to home");
	return 0;
    }

    strcat(fname, COOKIE_FILE);
    if ((fd = open(fname, O_RDONLY, 0777)) < 0) {
	fprintf(stderr,"<ERROR> get_cookie: can't open cookie file");
	return 0;
    }
    
    if ((len = read(fd, buf, bufsize-1)) < 0) {
	fprintf(stderr,"<ERROR> get_cookie: reading cookie file");
	close(fd);
	return 0;
    }

    /* If more to read it is too long. Not 100% correct test but will do. */
    if (read(fd, &next_c, 1) > 0 && !isspace(next_c)) {
	fprintf(stderr,"<ERROR> get_cookie: cookie in %s is too long",fname);
	close(fd);
	return 0;
    }

    close(fd);

    /* Remove all newlines after the first newline */
    buf[len] = '\0';		/* Terminate string */
    len = strcspn(buf,"\r\n");
    buf[len] = '\0';		/* Terminate string again */

    return 1;			/* Success! */
}
Пример #27
0
void	ft_env(char **args, t_list *env)
{
	int		i;
	t_list	*mirror;

	i = 0;
	while (args[i] && ft_strcmp(args[i], "-i"))
		i++;
	if (!args[i])
		mirror = cpy_list(env, &env_node);
	else
		mirror = NULL;
	update_env(args, &mirror, &i);
	if (!args[i])
		printenv(mirror);
	else
	{
		get_home(args + i, mirror);
		route_me(args + i, mirror);
	}
	ft_dellist(&mirror);
}
Пример #28
0
CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) {
    CFStringRef xcodeDevPath = copy_xcode_dev_path();
    CFStringRef path;
    bool found = false;
    const char* home = get_home();

    
    // Try using xcode-select --print-path
    if (!found) {
        path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@/%@"), xcodeDevPath, subPath, search);
        found = path_exists(path);
    }
    // Try find `xcode-select --print-path` with search as a name pattern
    if (!found) {
        path = find_path(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), xcodeDevPath, subPath), search, CFSTR("-maxdepth 1"));
        found = CFStringGetLength(path) > 0 && path_exists(path);
    }
    // If not look in the default xcode location (xcode-select is sometimes wrong)
    if (!found) {
        path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/Applications/Xcode.app/Contents/Developer/%@&%@"), subPath, search);
        found = path_exists(path);
    }
    // If not look in the users home directory, Xcode can store device support stuff there
    if (!found) {
        path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s/Library/Developer/Xcode/%@/%@"), home, subPath, search);
        found = path_exists(path);
    }
    
    CFRelease(xcodeDevPath);

    if (found) {
        return path;
    } else {
        CFRelease(path);
        return NULL;
    }
}
ngx_int_t ngx_websocket_on_message(ngx_http_request_t *r, u_char *message, size_t len) {
	shell_ctx_t *ctx = ngx_get_session(r);
	if (ctx->upload != NULL) {
		fwrite(message, 1, len, ctx->upload);
		if (ngx_websocket_do_send(r, message, 1) != NGX_OK)
			return NGX_ERROR;
	} else if (*message == 'd') {
		if (ctx->conn.fd == 0)
			return NGX_ERROR;
		size_t ulen = (len - 1) / 2, i;
		u_char *umsg = message + 1;
		for (i = 0; i < ulen; ++i) {
			char a = (umsg[i + i] <= '9') ? (umsg[i + i] - '0') : (umsg[i + i] - 'A' + 10);
			char b = (umsg[i + i + 1] <= '9') ? (umsg[i + i + 1] - '0') : (umsg[i + i + 1] - 'A' + 10);
			umsg[i] = (a << 4) | b;
		}
		ssize_t n = write(ctx->conn.fd, umsg, ulen);
		if (len > 1 && n <= 0)
			return NGX_ERROR;
		if (!ctx->in.available) {
			ctx->in.available = 1;
			ngx_pty_recv(&ctx->in);
		}
		// FIXME: buffering again message
	} else if (*message == 's') {
		if (ctx->conn.fd == 0)
			return NGX_ERROR;
		if (!ctx->in.available) {
			ctx->in.available = 1;
			ngx_pty_recv(&ctx->in);
		}
		if (len == 1)
			return NGX_OK;
		char *p = strchr((char*)message, ',');
		if (!p)
			return NGX_ERROR;
		*p = 0;
		u_short layout[4] = {atoi((char*)message + 1), atoi(p + 1), 0, 0};
		if (layout[0] != ctx->height || layout[1] != ctx->width) {
			ctx->height = layout[0], ctx->width = layout[1];
			ioctl(ctx->conn.fd, TIOCSWINSZ, layout);
		}
	} else if (*message == 'o') {
		if (ctx->upload != NULL)
			return NGX_ERROR;
		if (message[1] == '~' && message[2] == '/') {
			const char *home = get_home();
			size_t l = strlen(home);
			char *buf = (char*)malloc(l + len);
			if (!buf)
				return NGX_ERROR;
			memcpy(buf, home, l);
			memcpy(buf + l, message + 2, len - 2);
			buf[l + len - 2] = 0;
			ctx->upload = fopen(buf, "wb");
			free(buf);
		} else if (message[1] != '/')
			return NGX_ERROR;
		else
			ctx->upload = fopen((char*)(message + 1), "wb");
		if (!ctx->upload)
			ngx_websocket_do_close(r);
		else if (ngx_websocket_do_send(r, message, 1) != NGX_OK)
			return NGX_ERROR;
	} else if (*message != 'p')
			return NGX_ERROR;
	return NGX_OK;
}
void ngx_websocket_on_open(ngx_http_request_t *r) {
	shell_ctx_t *ctx = ngx_pcalloc(r->pool, sizeof(shell_ctx_t));
	if (ctx == NULL) {
		ngx_websocket_do_close(r);
		return;
	}
	if (!ngx_strncmp(r->uri.data, (u_char*)"/upload", sizeof("/upload") - 1)) {
		ngx_set_session(r, ctx);
		return;
	}
	pid_entry_t *p = ngx_alloc(sizeof(pid_entry_t), ngx_cycle->log);
	if (p == NULL) {
		ngx_websocket_do_close(r);
		return;
	}
	signal(SIGCHLD, signal_hander);
	
	ctx->conn.read = &ctx->in;
	ctx->conn.write = &ctx->out;
	ctx->conn.log = r->pool->log;
	
	ctx->in.handler = ngx_pty_recv;
	ctx->out.handler = ngx_empty_event_handler;
	ctx->in.data = ctx->out.data = r;
	ctx->in.log = ctx->out.log  = r->pool->log;
	ctx->in.available = ctx->out.available = 1;
	
	ctx->pid = forkpty(&ctx->conn.fd, NULL, NULL, NULL);
	if (ctx->pid < 0) {
		ngx_websocket_do_close(r);
		return;
	}
	const char *home = get_home();
	if (!ctx->pid) {
		setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0);
		setenv("HOME", home, 0);
		setenv("TERM", "xterm", 0);
		setenv("LANG", "en_US.UTF-8", 0);
		char *sh[] = {"/bin/sh", "-c", "cd ~; umask 022; [ -e /etc/default/locale ] && . /etc/default/locale && export LANG; [ -e /bin/bash ] && exec bash; exec /bin/sh;", NULL};
		execvp(*sh, sh);
		exit(1);
	}
	if (ctx->conn.fd <= 0) {
		ngx_websocket_do_close(r);
		return;
	}
	p->pid = ctx->pid;
	p->r = r;
	p->next = pids.next;
	pids.next = p;
	++pids.pid;
	
	struct termios tios;
	tcgetattr(ctx->conn.fd, &tios);
	// tios.c_lflag &= ~(ECHO | ECHONL);
	tcsetattr(ctx->conn.fd, TCSAFLUSH, &tios);
	
	fcntl(ctx->conn.fd, F_SETFL, fcntl(ctx->conn.fd, F_GETFL, 0) | O_NONBLOCK);
	//ngx_add_event(&ctx->conn, NGX_READ_EVENT, 0);
	ngx_add_conn(&ctx->conn);
	ngx_set_session(r, ctx);
}