Example #1
0
int sockcl_open(dev_file_t *f) {
  char *p;
  int port;
  char server[129];

  // open "SOCL:smallbasic.sf.net:80" as #1 
  // open "SOCL:80" as #2
  f->drv_dw[0] = 1;
  p = strchr(f->name + 5, ':');
  if (!p) {
    port = xstrtol(f->name + 5);
    f->handle = (int) net_listen(port);
  } else {
    *p = '\0';
    strcpy(server, f->name + 5);
    *p = ':';
    port = xstrtol(p + 1);
    f->handle = (int) net_connect(server, port);
  }

  if (f->handle <= 0) {
    f->handle = -1;
    f->drv_dw[0] = 0;
    return 0;
  }

  return 1;
}
Example #2
0
static int vboxgettyrc_parse(unsigned char *tty)
{
	unsigned char tempsectname[VBOX_MAX_RCLINE_SIZE + 1];

	xstrncpy(temppathname, SYSCONFDIR		 , PATH_MAX);
	xstrncat(temppathname, "/vboxgetty.conf", PATH_MAX);

		/* First time, the global ttyI settings will be	*/
		/* parsed.													*/

	xstrncpy(tempsectname, "vboxgetty-tty", VBOX_MAX_RCLINE_SIZE);

	if (rc_read(rc_getty_c, temppathname, tempsectname) == -1) return(-1);

		/* Second, the settings for the used ttyI will be	*/
		/* parsed.														*/

	xstrncpy(tempsectname, "vboxgetty-", VBOX_MAX_RCLINE_SIZE);
	xstrncat(tempsectname, tty			  , VBOX_MAX_RCLINE_SIZE);

	if (rc_read(rc_getty_c, temppathname, tempsectname) == -1) return(-1);

		/* After this, all unset variables will be filled with	*/
		/* the defaults.														*/

	log_line(LOG_D, "Filling unset configuration variables with defaults...\n");

	if (!rc_set_empty(rc_getty_c, "init"				, "ATZ&B512"		 )) return(-1);
	if (!rc_set_empty(rc_getty_c, "badinitsexit"		, "10"				 )) return(-1);
	if (!rc_set_empty(rc_getty_c, "initpause"			, "2500"				 )) return(-1);
	if (!rc_set_empty(rc_getty_c, "commandtimeout"	, "4"					 )) return(-1);
	if (!rc_set_empty(rc_getty_c, "echotimeout"		, "4"					 )) return(-1);
	if (!rc_set_empty(rc_getty_c, "ringtimeout"		, "6"					 )) return(-1);
	if (!rc_set_empty(rc_getty_c, "alivetimeout"		, "1800"				 )) return(-1);
	if (!rc_set_empty(rc_getty_c, "toggledtrtime"	, "400"				 )) return(-1);
	if (!rc_set_empty(rc_getty_c, "spooldir"			, "/var/spool/vbox")) return(-1);

	modemsetup.echotimeout		= xstrtol(rc_get_entry(rc_getty_c, "echotimeout"	), 4		);
	modemsetup.commandtimeout	= xstrtol(rc_get_entry(rc_getty_c, "commandtimeout"), 4		);
	modemsetup.ringtimeout		= xstrtol(rc_get_entry(rc_getty_c, "ringtimeout"	), 6		);
	modemsetup.alivetimeout		= xstrtol(rc_get_entry(rc_getty_c, "alivetimeout"	), 1800	);
	modemsetup.toggle_dtr_time	= xstrtol(rc_get_entry(rc_getty_c, "toggledtrtime"	), 400	);

	if (!rc_get_entry(rc_getty_c, "initnumber"))
	{
		log_line(LOG_E, "Variable \"initnumber\" *must* be set!\n");
		
		return(-1);
	}

	return(0);
}
int flash_lock_unlock_main(int argc UNUSED_PARAM, char **argv)
{
	/* note: fields in these structs are 32-bits.
	 * apparently we can't win anything by using off_t
	 * or long long's for offset and/or sectors vars. */
	struct mtd_info_user info;
	struct erase_info_user lock;
	unsigned long offset;
	long sectors;
	int fd;

#define do_lock (ENABLE_FLASH_LOCK && (!ENABLE_FLASH_UNLOCK || (applet_name[6] == 'l')))

	if (!argv[1])
		bb_show_usage();

	/* parse offset and number of sectors to lock */
	offset = 0;
	sectors = -1;
	if (do_lock) {
		if (!argv[2] || !argv[3])
			bb_show_usage();
		offset = xstrtoul(argv[2], 0);
		sectors = xstrtol(argv[3], 0);
	}

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

	xioctl(fd, MEMGETINFO, &info);

	lock.start = 0;
	lock.length = info.size;
	if (do_lock) {
		unsigned long size = info.size - info.erasesize;
		if (offset > size) {
			bb_error_msg_and_die("%lx is beyond device size %lx\n",
					offset, size);
		}

		if (sectors == -1) {
			sectors = info.size / info.erasesize;
		} else {
// isn't this useless?
			unsigned long num = info.size / info.erasesize;
			if (sectors > num) {
				bb_error_msg_and_die("%ld are too many "
						"sectors, device only has "
						"%ld\n", sectors, num);
			}
		}

		lock.start = offset;
		lock.length = sectors * info.erasesize;
		xioctl(fd, MEMLOCK, &lock);
	} else {
		xioctl(fd, MEMUNLOCK, &lock);
	}

	return EXIT_SUCCESS;
}
Example #4
0
static long
get_block_size (const char *device)
{
    CLEANUP_FREE_STRING_LIST char **params = NULL;
    const char *block_pattern = "Block size";
    size_t i;
    long block_size;

    params = do_tune2fs_l (device);
    if (params == NULL)
        return -1;

    for (i = 0; params[i] != NULL; i += 2) {
        if (STREQ (params[i], block_pattern)) {
            if (xstrtol (params[i + 1], NULL, 10, &block_size, NULL) != LONGINT_OK) {
                reply_with_error ("cannot parse block size");
                return -1;
            }
            return block_size;
        }
    }

    reply_with_error ("missing 'Block size' in tune2fs_l output");
    return -1;
}
Example #5
0
/* Like parse_unsigned_int, but ignore trailing stuff. */
int
guestfs_int_parse_unsigned_int_ignore_trailing (guestfs_h *g, const char *str)
{
  long ret;
  const int r = xstrtol (str, NULL, 10, &ret, NULL);
  if (r != LONGINT_OK) {
    error (g, _("could not parse integer in version number: %s"), str);
    return -1;
  }
  return ret;
}
Example #6
0
void flock_main(void)
{
  int fd = xstrtol(*toys.optargs, NULL, 10), op;

  if (toys.optflags & FLAG_u) op = LOCK_UN;
  else op = (toys.optflags & FLAG_s) ? LOCK_SH : LOCK_EX;

  if (toys.optflags & FLAG_n) op |= LOCK_NB;

  if (flock(fd, op)) {
    if ((op & LOCK_NB) && errno == EAGAIN) toys.exitval = 1;
    else perror_exit("flock");
  }
}
Example #7
0
static int parse_parameter ( ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t paramsource )
{
	int ret = 0;
#ifdef _DEBUG_FORCE
	fprintf ( stderr, "Force-Debug: parse_parameter(): %i: %i = \"%s\"\n", paramsource, param_id, arg );
#endif

	switch ( paramsource ) {
		case PS_CONTROL:
		case PS_ARGUMENT:
			if ( param_id & OPTION_CONFIGONLY ) {
				syntax();
				return 0;
			}

			ctx_p->flags_set[param_id] = 1;
			break;

		case PS_CONFIG:
			if ( ctx_p->flags_set[param_id] )
				return 0;

			ctx_p->flags_set[param_id] = 1;
			break;

		case PS_DEFAULTS:
#ifdef VERYPARANOID
			if ( ctx_p->flags_set[param_id] ) {
				error ( "Parameter #%i is already set. No need in setting the default value.", param_id );
				return 0;
			}

#endif
			break;

		/*		case PS_REHASH:
					arg = ctx_p->flags_values_raw[param_id];
		#ifdef VERYPARANOID
					critical_on (arg == NULL);
		#endif

					debug(9, "Rehash setting %i -> \"%s\"", param_id, arg);
					break;*/
		case PS_CORRECTION:
			critical_on ( arg == NULL );
			debug ( 9, "Correcting setting %i -> \"%s\"", param_id, arg );
			break;

		default:
			error ( "Unknown parameter #%i source (value \"%s\").", param_id, arg != NULL ? arg : "" );
			break;
	}

	if ( ( arg != NULL ) /*&& (paramsource != PS_REHASH)*/ ) {
		if ( param_id != KVM_ARGS )
			arg = parameter_expand ( ctx_p, arg, 0, NULL, NULL, parameter_get, ctx_p );

		if ( ctx_p->flags_values_raw[param_id] != NULL )
			free ( ctx_p->flags_values_raw[param_id] );

		ctx_p->flags_values_raw[param_id] = arg;
	}

	switch ( param_id ) {
		case '?':
		case HELP:
			syntax();
			break;

		case SHOW_VERSION:
			version();
			break;

		case CONFIG_FILE:
			ctx_p->config_path	= *arg ? arg : NULL;
			break;

		case CONFIG_GROUP:
			ctx_p->config_group	= *arg ? arg : NULL;
			break;

		case CONFIG_GROUP_INHERITS:
			break;

		case VMS_MIN:
			ctx_p->vms_min		= ( unsigned int ) xstrtol ( arg, &ret );
			break;

		case VMS_MAX:
			ctx_p->vms_max		= ( unsigned int ) xstrtol ( arg, &ret );
			break;

		case VMS_SPARE_MIN:
			ctx_p->vms_spare_min	= ( unsigned int ) xstrtol ( arg, &ret );
			break;

		case VMS_SPARE_MAX:
			ctx_p->vms_spare_max	= ( unsigned int ) xstrtol ( arg, &ret );
			break;

		case LISTEN:
			strncpy ( ctx_p->listen_addr, arg, sizeof ( ctx_p->listen_addr ) - 1 );
			break;

		default:
			if ( arg == NULL )
				ctx_p->flags[param_id]++;
			else
				ctx_p->flags[param_id] = xstrtol ( arg, &ret );

#ifdef _DEBUG_FORCE
			fprintf ( stderr, "Force-Debug: flag %i is set to %i\n", param_id & 0xff, ctx_p->flags[param_id] );
#endif
			break;
	}

	return ret;
}
Example #8
0
// open a web server connection
int http_open(dev_file_t *f) {
  char host[250];
  char txbuf[1024];
  f->port = 0;

  // check for http://
  if (0 != strncasecmp(f->name, "http://", 7)) {
    rt_raise("HTTP: INVALID URL");
    return 0;
  }

  // check for end of host delimeter
  char *colon = strchr(f->name + 7, ':');
  char *slash = strchr(f->name + 7, '/');
  char *lastSlash;

  // saves the length of the path component in f->drv_dw[1]
  if (colon) {
    // http://host:port/resource or http://host:port
    if (slash) {
      *slash = 0;
      f->port = xstrtol(colon + 1);
      *slash = '/';
      lastSlash = strrchr(slash, '/');
      f->drv_dw[1] = lastSlash ? lastSlash - f->name : slash - f->name;
    } else {
      f->port = xstrtol(colon + 1);
      f->drv_dw[1] = strlen(f->name);
    }
    *colon = 0;
    strcpy(host, f->name + 7);
    *colon = ':';
  } else if (slash) {
    // http://host/resource or http://host/
    *slash = 0;
    strcpy(host, f->name + 7);
    *slash = '/';
    lastSlash = strrchr(slash, '/');
    f->drv_dw[1] = lastSlash ? lastSlash - f->name : slash - f->name;
  } else {
    // http://host
    strcpy(host, f->name + 7);
    f->drv_dw[1] = strlen(f->name);
  }

  f->drv_dw[0] = 1;
  if (f->port == 0) {
    f->port = 80;
  }

  socket_t s = net_connect(host, f->port);
  f->handle = (socket_t) s;

  if (f->handle <= 0) {
    f->handle = -1;
    f->drv_dw[0] = 0;
    f->port = 0;
    return 0;
  }

  sprintf(txbuf, "GET %s HTTP/1.0\r\n"
      "Host: %s\r\n"
      "Accept: */*\r\n"
      "Accept-Language: en-au\r\n"
      "User-Agent: SmallBASIC\r\n", slash ? slash : "/", host);
  if (f->drv_dw[2]) {
    // If-Modified-Since: Sun, 03 Apr 2005 04:45:47 GMT
    strcat(txbuf, "If-Modified-Since: ");
    strftime(txbuf + strlen(txbuf), 60, "%a, %d %b %Y %H:%M:%S %Z\r\n",
             localtime((time_t *) &f->drv_dw[2]));
  }
  strcat(txbuf, "\r\n");
  net_print(s, txbuf);
  return 1;
}
Example #9
0
void main(int argc, char **argv)
{
	char *stop;
	int	opts;
	char *debugstr;
	int	debuglvl;
	int	i;
	int	modemstate;
	int	modeminits;

	breaklist_init();

	progbasename = argv[0];

	if ((stop = rindex(argv[0], '/'))) progbasename = ++stop;

		/* Die Argumente des Programms einlesen und den Debuglevel	*/
		/* setzen.																	*/

	debugstr		= NULL;
	isdnttyname	= NULL;

	while ((opts = getopt_long(argc, argv, "vhx:d:", arguments, (int *)0)) != EOF)
	{
		switch (opts)
		{
			case 'x':
				debugstr = optarg;
				break;

			case 'd':
				isdnttyname = optarg;
				break;

			case 'v':
				show_usage(200, 0);
				break;

			case 'h':
			default:
				show_usage(200, 1);
				break;
		}
	}

	if (debugstr)
	{
		if (strcasecmp(debugstr, "FULL") != 0)
		{
			debuglvl = LOG_E;

			for (i = 0; i < strlen(debugstr); i++)
			{
				switch (debugstr[i])
				{
					case 'W':
					case 'w':
						debuglvl |= LOG_W;
						break;
					
					case 'I':
						debuglvl |= LOG_I;
						break;
					
					case 'A':
						debuglvl |= LOG_A;
						break;
					
					case 'D':
						debuglvl |= LOG_D;
						break;
				}
			}
		}
		else debuglvl = LOG_X;

		log_set_debuglevel(debuglvl);
	}

	umask(xstrtoo(VBOX_ROOT_UMASK, 0));

		/* Pfadangaben vom Devicenamen abschneiden und überprüfen ob	*/
		/* das Device vom Benutzer gelesen und beschrieben werden		*/
		/* kann (eigentlich nicht nötig, da nur unter Rootrechten ge-	*/
		/* startet werden kann.														*/

	if (isdnttyname)
	{
		if ((stop = rindex(isdnttyname, '/'))) isdnttyname = ++stop;

		printstring(savettydname, "%s"     , isdnttyname);
		printstring(temppathname, "/dev/%s", isdnttyname);
		
		if (access(temppathname, F_OK|R_OK|W_OK) != 0)
		{
			fprintf(stderr, "\n%s: error: \"%s\" doesn't exist or is not accessible!\n\n", progbasename, temppathname);

			quit_program(100);
		}
	}
	else
	{
		fprintf(stderr, "\n%s: error: isdn tty name is required!\n", progbasename);

		show_usage(100, 1);
	}

		/* Prüfen ob das Programm unter Rootrechten gestartet wurde. Die	*/
		/* Rechte werden später auf die des jeweiligen Benutzers geän-		*/
		/* dert, zum Start sind aber Rootrechte nötig.							*/

	if (getuid() != 0)
	{
		fprintf(stderr, "\n%s: error: need root privilegs to start!\n\n", progbasename);

		quit_program(100);
	}

		/* Jetzt wird der Log geöffnet. Der Name des aktuellen Devices	*/
		/* wird an das Ende angehängt.											*/

	printstring(temppathname, "%s/vboxgetty-%s.log", LOGDIR, isdnttyname);

	log_open(temppathname);

		/* Tcl-Interpreter starten. Für die momentanen Funktionen wird	*/
		/* Version 8 oder höher benötigt.										*/

	if (scr_create_interpreter() == -1)
	{
		log_line(LOG_E, "Can't create/initialize the tcl interpreter!\n");
		
		quit_program(100);
	}

	log_line(LOG_I, "Running vbox version %s (with tcl version %s).\n", VERSION, scr_tcl_version());

		/* Konfiguration des getty's abarbeiten. Zuerst wird die globale,	*/
		/* dann die des jeweiligen tty's eingelesen.								*/

	if (vboxgettyrc_parse(isdnttyname) == -1)
	{
		log_line(LOG_E, "Unable to read/parse configuration!\n");
	
		quit_program(100);
	}

		/* Modem Device öffnen und die interne Initialisierung	*/
		/* ausführen (nicht der normale Modeminit).					*/

	printstring(temppathname, "/dev/%s", isdnttyname);

	log_line(LOG_D, "Opening modem device \"%s\" (38400, CTS/RTS)...\n", temppathname);

	if (vboxmodem_open(&vboxmodem, temppathname) == -1)
	{
		log_line(LOG_E, "Can't open/setup modem device (%s).\n", vboxmodem_error());

		quit_program(100);
	}

		/* Lock- und PID-Datei für den getty und das entsprechende	*/
		/* Device erzeugen.														*/

	printstring(temppathname, "%s/LCK..%s", LOCKDIR, isdnttyname);
	
	if (lock_create(temppathname) == -1) quit_program(100);

	printstring(temppathname, "%s/vboxgetty-%s.pid", PIDDIR, isdnttyname);

	pid_create(temppathname);

		/* Signalhändler installieren. Alle möglichen Signale werden	*/
		/* auf quit_program() umgelenkt.											*/

	signal(SIGINT , quit_program);
	signal(SIGTERM, quit_program);
	signal(SIGHUP , quit_program);

		/* Hauptloop: Der Loop wird nur verlassen, wenn während der	*/
		/* Abarbeitung ein Fehler aufgetreten ist. Das Programm be-	*/
		/* endet sich danach!													*/
	
	modemstate = VBOXMODEM_STAT_INIT;
	modeminits = 0;
	
	while (modemstate != VBOXMODEM_STAT_EXIT)
	{
		switch (modemstate)
		{
			case VBOXMODEM_STAT_INIT:

				if (run_modem_init() == -1)
				{
					if ((i = (int)xstrtol(rc_get_entry(rc_getty_c, "badinitsexit"), 10)) > 0)
					{
						modeminits++;
						
						if (modeminits >= i)
						{
							modemstate = VBOXMODEM_STAT_EXIT;
							modeminits = 0;
							
							log_line(LOG_E, "Exit program while bad init limit are reached.\n");
						}
						else log_line(LOG_W, "Bad initialization - Program will exist on %d trys!\n", (i - modeminits));
					}
				}
				else
				{
					modemstate = VBOXMODEM_STAT_WAIT;
					modeminits = 0;
				}
				break;

			case VBOXMODEM_STAT_WAIT:
				
				modem_flush(&vboxmodem, 0);

				if (modem_wait(&vboxmodem) == 0)
				{
					modemstate = VBOXMODEM_STAT_RING;
					modeminits = 0;
				}
				else modemstate = VBOXMODEM_STAT_TEST;
				
				break;

			case VBOXMODEM_STAT_TEST:
			
				log_line(LOG_D, "Checking if modem is still alive...\n");
				
				if (modem_command(&vboxmodem, "AT", "OK") > 0)
				{
					modemstate = VBOXMODEM_STAT_WAIT;
					modeminits = 0;
				}
				else modemstate = VBOXMODEM_STAT_INIT;
				
				break;
				
			case VBOXMODEM_STAT_RING:
			
				modem_set_nocarrier(&vboxmodem, 0);
				process_incoming_call();
				modem_hangup(&vboxmodem);

				if (set_process_permissions(0, 0, xstrtoo(VBOX_ROOT_UMASK, 0)) != 0)
					modemstate = VBOXMODEM_STAT_EXIT;
				else
 					modemstate = VBOXMODEM_STAT_INIT;
				
				break;

			default:

				log_line(LOG_E, "Unknown modem status %d!\n", modemstate);
				
				modemstate = VBOXMODEM_STAT_INIT;
				
				break;
		}
	}

	quit_program(0);
}
Example #10
0
static int userrc_parse(struct vboxuser *vboxuser, unsigned char *home)
{
	unsigned char   tempsectname[VBOX_MAX_RCLINE_SIZE + 1];
	struct passwd	*pwdent;
	struct group	*grpent;
	unsigned char  *varusr;
	unsigned char  *vargrp;
	unsigned char  *varspc;
	unsigned char  *varmsk;
	int				 havegroup;

	static struct vboxrc rc_user_c[] =
	{
		{ "user"		, NULL },
		{ "group"	, NULL },
		{ "umask"	, NULL },
		{ "hdspace"	, NULL },
		{ NULL		, NULL }
	};

	xstrncpy(temppathname, SYSCONFDIR		 , PATH_MAX);
	xstrncat(temppathname, "/vboxgetty.conf", PATH_MAX);

	xstrncpy(tempsectname, "vboxgetty-phone-"	 , VBOX_MAX_RCLINE_SIZE);
	xstrncat(tempsectname, vboxuser->localphone, VBOX_MAX_RCLINE_SIZE);

	if (rc_read(rc_user_c, temppathname, tempsectname) < 0) return(-1);

	varusr = rc_get_entry(rc_user_c, "user"	);
	vargrp = rc_get_entry(rc_user_c, "group"	);
	varspc = rc_get_entry(rc_user_c, "hdspace");
	varmsk = rc_get_entry(rc_user_c, "umask"  );

	vboxuser->uid		= 0;
	vboxuser->gid		= 0;
	vboxuser->space	= 0;
	vboxuser->umask	= 0;

	strcpy(vboxuser->home, "");
	strcpy(vboxuser->name, "");

	if ((!varusr) || (!*varusr))
	{
		log_line(LOG_E, "You *must* specify a user name or a user id!\n");

		rc_free(rc_user_c);

		return(-1);
	}

	if (*varusr == '#')
		pwdent = getpwuid((uid_t)xstrtol(&varusr[1], 0));
	else
		pwdent = getpwnam(varusr);

	if (!pwdent)
	{
		log_line(LOG_E, "Unable to locate \"%s\" in systems passwd list.\n", varusr);

		rc_free(rc_user_c);

		return(-1);
	}

	vboxuser->uid = pwdent->pw_uid;
	vboxuser->gid = pwdent->pw_gid;

	if ((strlen(home) + strlen(pwdent->pw_name) + 2) < (PATH_MAX - 100))
	{
		xstrncpy(vboxuser->name, pwdent->pw_name, VBOXUSER_USERNAME);

		printstring(vboxuser->home, "%s/%s", home, pwdent->pw_name);
	}
	else
	{
		log_line(LOG_E, "Oops! Spool directory name and user name too long!\n");

		rc_free(rc_user_c);

		return(-1);
	}

	if ((vargrp) && (*vargrp))
	{
		havegroup = 0;

		setgrent();
					
		while ((grpent = getgrent()))
		{
			if (*vargrp == '#')
			{
				if (grpent->gr_gid == (gid_t)xstrtol(&vargrp[1], 0))
				{
					vboxuser->gid = grpent->gr_gid;
					havegroup	  = 1;
								
					break;
				}
			}
			else
			{
				if (strcmp(grpent->gr_name, vargrp) == 0)
				{
					vboxuser->gid = grpent->gr_gid;
					havegroup	  = 1;
								
					break;
				}
			}
		}
					
		endgrent();

		if (!havegroup)
		{
			log_line(LOG_E, "Unable to locate \"%s\" in systems group list.\n", vargrp);

			rc_free(rc_user_c);

			return(-1);
		}
	}

	if (varspc) vboxuser->space = xstrtol(varspc, 0);
	if (varmsk) vboxuser->umask = xstrtoo(varmsk, 0);

	log_line(LOG_D, "User \"%s\" (%d.%d) [%04o] will be used...\n", vboxuser->name, vboxuser->uid, vboxuser->gid, vboxuser->umask);

	rc_free(rc_user_c);

	return(0);
}
Example #11
0
static int process_incoming_call(void)
{
	struct vboxuser	 vboxuser;
	struct vboxcall	 vboxcall;
	unsigned char		 line[VBOXMODEM_BUFFER_SIZE + 1];
	int					 haverings;
	int					 waitrings;
	int					 usersetup;
	int					 ringsetup;
	int					 inputisok;
	unsigned char		*stop;
	unsigned char		*todo;

	memset(&vboxuser, 0, sizeof(vboxuser));
	memset(&vboxcall, 0, sizeof(vboxcall));

	haverings =  0;
	waitrings = -1;
	usersetup =  0;
	ringsetup =  0;

	while (modem_read(&vboxmodem, line, modemsetup.ringtimeout) == 0)
	{
		inputisok = 0;

			/* Wenn der Benutzer der angerufenen Nummer ermittelt ist und	*/
			/* dessen Konfigurations abgearbeitet wurde, wird überprüft ob	*/
			/* der Anruf angenommen werden soll.									*/

		if ((usersetup) && (ringsetup))
		{
			if (waitrings >= 0)
			{
				todo = savettydname;
				stop = ctrl_exists(vboxuser.home, "answer", todo);

				if (!stop)
				{
					todo = NULL;
					stop = ctrl_exists(vboxuser.home, "answer", todo);
				}

				if (stop)
				{
					log_line(LOG_D, "Control \"vboxctrl-answer\" detected: %s (%s)...\n", stop, ((char *)todo ? (char *)todo : "global"));

					if ((strcasecmp(stop, "no") == 0) || (strcasecmp(stop, "hangup") == 0) || (strcasecmp(stop, "reject") == 0))
					{
						log_line(LOG_D, "Incoming call will be rejected...\n");
						
						return(0);
					}

					if (strcasecmp(stop, "now") != 0)
					{
						vboxuser.space	= 0;
						waitrings		= xstrtol(stop, waitrings);
					}
					else
					{
						vboxuser.space = 0;
						waitrings		= 1;
					}

					log_line(LOG_D, "Call will be answered after %d ring(s).\n", waitrings);
				}
			}

			if (waitrings > 0)
			{
				if (haverings >= waitrings)
				{
					return(voice_init(&vboxuser, &vboxcall));
				}
			}
		}

			/* Ring abarbeiten: Beim ersten Ring wird die angerufene	*/
			/* Nummer gesichert, die durch ATS13.7=1 mit einem Slash	*/
			/* an den Ringstring angehängt ist.								*/

		if (strncmp(line, "RING/", 5) == 0)
		{
			inputisok++;
			haverings++;
			
			if (!ringsetup)
			{
	         xstrncpy(vboxuser.localphone, &line[5], VBOXUSER_NUMBER);

				ringsetup = 1;
			}				          

			log_line(LOG_A, "%s #%03d (%s)...\n", line, haverings, ((char *)usersetup ? (char *)vboxcall.name : "not known"));
		}

			/* CallerID aus dem Modeminput kopieren. Wenn bereits die	*/
			/* angerufene Nummer ermittelt wurde, wird einmalig die		*/
			/* Konfigurationsdatei des Benutzers abgearbeitet.				*/

		if (strncmp(line, "CALLER NUMBER: ", 15) == 0)
		{
			inputisok++;

			if ((ringsetup) && (!usersetup))
			{
				xstrncpy(vboxuser.incomingid, &line[15], VBOXUSER_CALLID);

				if (userrc_parse(&vboxuser, rc_get_entry(rc_getty_c, "spooldir")) == 0)
				{
					if ((vboxuser.uid != 0) && (vboxuser.gid != 0))
					{
							/* Nachdem "vboxgetty.user" abgearbeitet ist und	*/
							/* ein Benutzer gefunden wurde, werden einige der	*/
							/* Kontrolldateien gelöscht.								*/

						ctrl_remove(vboxuser.home, "suspend", savettydname);
						ctrl_remove(vboxuser.home, "suspend", NULL        );

							/* Die "effective Permissions" des Prozesses auf	*/
							/* die des Benutzers setzen und dessen Konfigurat-	*/
							/* ionsdatei abarbeiten.									*/

						if (set_process_permissions(vboxuser.uid, vboxuser.gid, vboxuser.umask) == 0)
						{
							usersetup = 1;
							waitrings = vboxrc_parse(&vboxcall, vboxuser.home, vboxuser.incomingid);

							if (waitrings <= 0)
							{
								if (waitrings < 0)
									log_line(LOG_W, "Incoming call will be ignored!\n");
								else
									log_line(LOG_D, "Incoming call will be ignored (user setup)!\n");
							}
							else log_line(LOG_D, "Call will be answered after %d ring(s).\n", waitrings);
						}
						else return(-1);
					}
					else log_line(LOG_W, "Useing uid/gid 0 is not allowed - call will be ignored!\n", vboxuser.incomingid);
				}
				else log_line(LOG_W, "Number \"%s\" not bound to a local user - call will be ignored!\n", vboxuser.localphone);
			}
		}

		if (!inputisok)
		{
			log_line(LOG_D, "Got junk line \"");
			log_code(LOG_D, line);
			log_text(LOG_D, "\"...\n");

			continue;
		}
	}

	return(-1);
}
Example #12
0
int voice_get_message(char *name, char *timestr, int save)
{
	vaheader_t	header;
	char			line_i[MODEM_BUFFER_LEN + 1];
	char			line_o[MODEM_BUFFER_LEN + 1];
	int			byte_i;
	int			byte_o;
	int			result;
	int			havedle;
	int			savetimeout;
	int			fd;

	savetimeout = xstrtol(timestr, 90);

	if (save)
		log(L_INFO, "Recording \"%s\" (%d secs)...\n", name, savetimeout);
	else
		log(L_INFO, "Waiting %d secs for input...\n", savetimeout);

	if (!voice_set_compression(setup.modem.compression))
	{
		log(L_ERROR, "Can't set voice audio compressen.\n");

		return(VOICE_ACTION_ERROR);
	}

	if (save)
	{
		if ((fd = open(name, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IWGRP|S_IWOTH)) == -1)
	   {
	   	log(L_ERROR, "Can't create \"%s\".\n", name);

			return(VOICE_ACTION_ERROR);
		}

		truncate(name, 0);

		voice_set_header(&header);

		if (!header_put(fd, &header))
		{
	      log(L_ERROR, "Can't write vbox audio header.\n");
      
			voice_close_or_unlink(fd, name);

			return(VOICE_ACTION_ERROR);
		}
	}
	else fd = -1;

	if (modem_get_nocarrier_state())
	{
		if (save) voice_close_or_unlink(fd, name);

		return(VOICE_ACTION_LOCALHANGUP);
	}

	if (modem_command("AT+VRX", "CONNECT") == 0)
	{
		log(L_ERROR, "Can't start record mode.\n");

		if (save) voice_close_or_unlink(fd, name);

		return(VOICE_ACTION_ERROR);
	}

	sequencestatus	= ST_NO_INPUT;
	voicestatus		= VOICE_ACTION_OK;
	havedle			= FALSE;

	modem_set_timeout(savetimeout);

	while (voicestatus == VOICE_ACTION_OK)
	{
		byte_o = 0;
		byte_i = 0;
		result = 0;

		while ((byte_o < MODEM_BUFFER_LEN) && (voicestatus == VOICE_ACTION_OK))
		{
			if ((result = modem_raw_read(line_i, 1)) == 1)
			{
				byte_i++;

				if (havedle)
				{
					switch (*line_i)
					{
						case DLE:
							line_o[byte_o++] = DLE;
							break;

						case ETX:
							log(L_DEBUG, "Found sequence \"<DLE><ETX>\" (remote hangup)...\n");
							voicestatus = VOICE_ACTION_REMOTEHANGUP;
							break;

						default:
							voice_handle_touchtone_dle(*line_i);
							break;
					}

					havedle = FALSE;
				}
				else
				{
					if (*line_i != DLE)
					{
						line_o[byte_o++] = *line_i;
					}
					else havedle = TRUE;
				}
			}
			else break;
		}

		if (byte_o > 0)
		{
			if (save)
			{
				log(L_JUNK, "Record: <DATA %d incoming; %d outgoing>\n", byte_i, byte_o);
                         
				write(fd, line_o, byte_o);
			}
			else log(L_JUNK, "Wait: <DATA %d incoming>\n", byte_i);
		}

		if ((result != 1) || (modem_get_timeout()))
		{
			if (!modem_get_timeout())
			{
				log(L_ERROR, "Can't read incoming data (%s).\n", strerror(errno));
				
				voicestatus = VOICE_ACTION_ERROR;
			}
			else voicestatus = VOICE_ACTION_TIMEOUT;
		}

		if ((result == 1) && (ctrl_ishere(setup.spool, CTRL_NAME_SUSPEND))) {   
			log(L_INFO, "Control file \"%s\" exists - suspending call...\n", CTRL_NAME_SUSPEND);
			if (!ctrl_remove(setup.spool, CTRL_NAME_SUSPEND)) {
				log(L_WARN, "Can't remove control file \"%s\"!\n", CTRL_NAME_SUSPEND);
			}
			log(L_JUNK, "Sending \"<DLE><DC4>\"...\n");
			printstring(line_o, "%c%c", DLE, DC4);
			printstring(line_i, "%c%c", DLE, ETX);
			modem_raw_write(line_o, strlen(line_o));
			modem_wait_sequence(line_i);
			if (modem_command("", "VCON")>0) {
#ifdef VBOX_SUSPEND_VALUE
				printstring(line_o, "AT+S%d", VBOX_SUSPEND_VALUE);
#else
				printstring(line_o, "AT+S");
#endif
				if (modem_command(line_o, "OK") <= 0) {
					log(L_WARN, "Can't suspend call\n");
				} else {
					log(L_INFO, "Call suspended\n");
					voicestatus = VOICE_ACTION_REMOTEHANGUP;
				}
			}
		}

		if ((voicestatus == VOICE_ACTION_OK) || (voicestatus == VOICE_ACTION_TIMEOUT))
		{
			if ((index(touchtones, '#')) && (index(touchtones, '*')))
			{
				log(L_DEBUG, "Touchtone sequence \"%s\" found.\n", touchtones);

				if (breaklist_search(touchtones))
				{
					log(L_INFO, "Sequence \"%s\" found in breaklist...\n", touchtones);

					voicestatus = VOICE_ACTION_TOUCHTONES;
				}
				else
				{
					log(L_DEBUG, "Sequence \"%s\" not in breaklist (ignored)...\n", touchtones);

					*touchtones = '\0';
				}
			}
		}
	}

	modem_set_timeout(0);

	if (save)
	{
		voice_close_or_unlink(fd, NULL);

		permissions_set(name, setup.users.uid, setup.users.gid, S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH, setup.users.umask);
	}

	if ((voicestatus == VOICE_ACTION_REMOTEHANGUP) || (modem_get_nocarrier_state()))
	{
			/*
			 * Remote hangup: Modem should response with the sequence
			 * NO CARRIER.
			 */

		modem_command("", "NO CARRIER");
	}
	else
	{
			/*
			 * Local hangup: send <DLE><DC4> to the modem and read the
			 * response <DLE><ETX> and VCON.
			 */

		printstring(line_o, "%c%c", DLE, DC4);
		printstring(line_i, "%c%c", DLE, ETX);

		log(L_JUNK, "Sending \"<DLE><DC4>\"...\n");

		modem_raw_write(line_o, strlen(line_o));

		modem_get_sequence(line_i);

		modem_command("", "VCON");
	}

	if (modem_get_nocarrier_state()) voicestatus = VOICE_ACTION_REMOTEHANGUP;

	return(voicestatus);
}
Example #13
0
int main(int argc, char **argv)
{
	uint32_t crc, targetendian_crc;
	const char *txt_filename = NULL, *bin_filename = NULL;
	int txt_fd, bin_fd;
	unsigned char *dataptr, *envptr;
	unsigned char *filebuf = NULL;
	unsigned int filesize = 0, envsize = 0, datasize = 0;
	int bigendian = 0;
	int redundant = 0;
	unsigned char padbyte = 0xff;

	int option;
	int ret = EXIT_SUCCESS;

	struct stat txt_file_stat;

	int fp, ep;
	const char *prg;

	prg = basename(argv[0]);

	/* Turn off getopt()'s internal error message */
	opterr = 0;

	/* Parse the cmdline */
	while ((option = getopt(argc, argv, ":s:o:rbp:hV")) != -1) {
		switch (option) {
		case 's':
			datasize = xstrtol(optarg);
			break;
		case 'o':
			bin_filename = strdup(optarg);
			if (!bin_filename) {
				fprintf(stderr, "Can't strdup() the output filename\n");
				return EXIT_FAILURE;
			}
			break;
		case 'r':
			redundant = 1;
			break;
		case 'b':
			bigendian = 1;
			break;
		case 'p':
			padbyte = xstrtol(optarg);
			break;
		case 'h':
			usage(prg);
			return EXIT_SUCCESS;
		case 'V':
			printf("%s version %s\n", prg, PLAIN_VERSION);
			return EXIT_SUCCESS;
		case ':':
			fprintf(stderr, "Missing argument for option -%c\n",
				optopt);
			usage(prg);
			return EXIT_FAILURE;
		default:
			fprintf(stderr, "Wrong option -%c\n", optopt);
			usage(prg);
			return EXIT_FAILURE;
		}
	}

	/* Check datasize and allocate the data */
	if (datasize == 0) {
		fprintf(stderr, "Please specify the size of the environment partition.\n");
		usage(prg);
		return EXIT_FAILURE;
	}

	dataptr = malloc(datasize * sizeof(*dataptr));
	if (!dataptr) {
		fprintf(stderr, "Can't alloc %d bytes for dataptr.\n",
				datasize);
		return EXIT_FAILURE;
	}

	/*
	 * envptr points to the beginning of the actual environment (after the
	 * crc and possible `redundant' byte
	 */
	envsize = datasize - (CRC_SIZE + redundant);
	envptr = dataptr + CRC_SIZE + redundant;

	/* Pad the environment with the padding byte */
	memset(envptr, padbyte, envsize);

	/* Open the input file ... */
	if (optind >= argc || strcmp(argv[optind], "-") == 0) {
		int readbytes = 0;
		int readlen = sizeof(*envptr) * 4096;
		txt_fd = STDIN_FILENO;

		do {
			filebuf = realloc(filebuf, readlen);
			if (!filebuf) {
				fprintf(stderr, "Can't realloc memory for the input file buffer\n");
				return EXIT_FAILURE;
			}
			readbytes = read(txt_fd, filebuf + filesize, readlen);
			if (errno) {
				fprintf(stderr, "Error while reading stdin: %s\n",
						strerror(errno));
				return EXIT_FAILURE;
			}
			filesize += readbytes;
		} while (readbytes == readlen);

	} else {
		txt_filename = argv[optind];
		txt_fd = open(txt_filename, O_RDONLY);
		if (txt_fd == -1) {
			fprintf(stderr, "Can't open \"%s\": %s\n",
					txt_filename, strerror(errno));
			return EXIT_FAILURE;
		}
		/* ... and check it */
		ret = fstat(txt_fd, &txt_file_stat);
		if (ret == -1) {
			fprintf(stderr, "Can't stat() on \"%s\": %s\n",
					txt_filename, strerror(errno));
			return EXIT_FAILURE;
		}

		filesize = txt_file_stat.st_size;

		filebuf = mmap(NULL, sizeof(*envptr) * filesize, PROT_READ,
			       MAP_PRIVATE, txt_fd, 0);
		if (filebuf == MAP_FAILED) {
			fprintf(stderr, "mmap (%zu bytes) failed: %s\n",
					sizeof(*envptr) * filesize,
					strerror(errno));
			fprintf(stderr, "Falling back to read()\n");

			filebuf = malloc(sizeof(*envptr) * filesize);
			ret = read(txt_fd, filebuf, sizeof(*envptr) * filesize);
			if (ret != sizeof(*envptr) * filesize) {
				fprintf(stderr, "Can't read the whole input file (%zu bytes): %s\n",
					sizeof(*envptr) * filesize,
					strerror(errno));

				return EXIT_FAILURE;
			}
		}
		ret = close(txt_fd);
	}
	/* The +1 is for the additionnal ending \0. See below. */
	if (filesize + 1 > envsize) {
		fprintf(stderr, "The input file is larger than the environment partition size\n");
		return EXIT_FAILURE;
	}

	/* Replace newlines separating variables with \0 */
	for (fp = 0, ep = 0 ; fp < filesize ; fp++) {
		if (filebuf[fp] == '\n') {
			if (ep == 0) {
				/*
				 * Newlines at the beginning of the file ?
				 * Ignore them.
				 */
				continue;
			} else if (filebuf[fp-1] == '\\') {
				/*
				 * Embedded newline in a variable.
				 *
				 * The backslash was added to the envptr; rewind
				 * and replace it with a newline
				 */
				ep--;
				envptr[ep++] = '\n';
			} else {
				/* End of a variable */
				envptr[ep++] = '\0';
			}
		} else {
			envptr[ep++] = filebuf[fp];
		}
	}
	/*
	 * Make sure there is a final '\0'
	 * And do it again on the next byte to mark the end of the environment.
	 */
	if (envptr[ep-1] != '\0') {
		envptr[ep++] = '\0';
		/*
		 * The text file doesn't have an ending newline.  We need to
		 * check the env size again to make sure we have room for two \0
		 */
		if (ep >= envsize) {
			fprintf(stderr, "The environment file is too large for the target environment storage\n");
			return EXIT_FAILURE;
		}
		envptr[ep] = '\0';
	} else {
		envptr[ep] = '\0';
	}

	/* Computes the CRC and put it at the beginning of the data */
	crc = crc32(0, envptr, envsize);
	targetendian_crc = bigendian ? cpu_to_be32(crc) : cpu_to_le32(crc);

	memcpy(dataptr, &targetendian_crc, sizeof(targetendian_crc));
	if (redundant)
		dataptr[sizeof(targetendian_crc)] = 1;

	if (!bin_filename || strcmp(bin_filename, "-") == 0) {
		bin_fd = STDOUT_FILENO;
	} else {
		bin_fd = creat(bin_filename, S_IRUSR | S_IWUSR | S_IRGRP |
					     S_IWGRP);
		if (bin_fd == -1) {
			fprintf(stderr, "Can't open output file \"%s\": %s\n",
					bin_filename, strerror(errno));
			return EXIT_FAILURE;
		}
	}

	if (write(bin_fd, dataptr, sizeof(*dataptr) * datasize) !=
			sizeof(*dataptr) * datasize) {
		fprintf(stderr, "write() failed: %s\n", strerror(errno));
		return EXIT_FAILURE;
	}

	ret = close(bin_fd);

	return ret;
}
Example #14
0
/**
 * Returns the number of a string (constant numeric expression)
 *
 * type  <=0 = error
 *         1 = int32_t
 *         2 = double
 *
 * Warning: octals are different from C (QB compatibility: 009 = 9)
 */
char *get_numexpr(char *text, char *dest, int *type, var_int_t *lv, var_num_t *dv) {
  char *p = (char *) text;
  char *d = dest;
  char *epos = NULL;
  byte base = 10;
  byte dpc = 0, stupid_e_fmt = 0, eop = '+';
  int sign = 1;
  var_num_t power = 1.0;
  var_num_t num;

  *type = 0;
  *lv = 0;
  *dv = 0.0;

  if (p == NULL) {
    *dest = '\0';
    return NULL;
  }
  // spaces
  while (is_space(*p)) {
    p++;
  }
  // sign
  if ((*p == '-' || *p == '+') && strchr("0123456789.", *(p + 1)) &&
      *(p + 1) != '\0'){if (*p == '-') {
      sign = -1;
    }
    p++;                        // don't copy it
  }

  //
  // resolve the base (hex, octal and binary)
  //
  if ((*p == '&') || (*p == '0' && (*(p + 1) != '\0' && strchr("HXBO", to_upper(*(p + 1))) != NULL))) {

    p++;
    switch (*p) {
    case 'H':
    case 'h':
    case 'X':
    case 'x':
      base = 16;
      break;
    case 'O':
    case 'o':
      base = 8;
      break;
    case 'B':
    case 'b':
      base = 2;
      break;
    default:
      *type = -1;
      return p;                 // Unknown base
    }

    p++;
  }
  //
  // copy parts of number
  //
  if (base == 16) {
    // copy hex
    while (is_hexdigit(*p)) {
      *d = to_upper(*p);
      d++;
      p++;
    }
  } else if (base != 10) {
    // copy octal | bin
    while (is_digit(*p)) {
      *d++ = *p++;
    }
  } else if (is_digit(*p) || *p == '.') {
    // copy number (first part)
    while (is_digit(*p) || *p == '.') {
      if (*p == '.') {
        dpc++;
        if (dpc > 1) {
          *type = -2;           // DP ERROR
          break;
        }
      }

      *d++ = *p++;
    }

    // check second part
    if ((*p == 'E' || *p == 'e') && (*type == 0)) {
      epos = d;
      *d++ = *p++;              // E

      if (*p == '+' || *p == '-' || is_digit(*p) || *p == '.') {
        dpc = 0;

        // copy second part (power)
        if (*p == '+' || *p == '-') {
          *d++ = *p++;
          if (strchr("+-*/\\^", *p) != 0) { // stupid E format
            // (1E--9 ||
            // 1E++9)
            stupid_e_fmt = 1;
            eop = *p;
            *d++ = *p++;
            if (*p == '+' || *p == '-')
              *d++ = *p++;
          }
        }
        // power
        while (is_digit(*p) || *p == '.') {
          if (*p == '.') {
            dpc++;
            if (dpc > 1) {
              *type = -4;       // DP ERROR (second part)
              break;
            }
          }
          *d++ = *p++;
        }                       // after E

      }                         //
      else {
        *type = -3;             // E+- ERROR
      }
    }
  } else
    *type = -9;                 // NOT A NUMBER

  *d = '\0';

  //
  // finaly, calculate the number
  //
  if (*type == 0) {
    switch (base) {
    case 10:
      if (dpc || (epos != NULL) || (strlen(dest) > 8)) {
        *type = 2;              // double
        if (epos) {
          if (stupid_e_fmt) {
            int r_type = 1;

            *epos = '\0';
            num = sb_strtof(dest) * ((double) sign);
            *epos = 'E';        // restore E

            /*
             * if ( *p == 'E' || *p == 'e' ) { long r_lv; double r_dv;
             *
             * p = get_numexpr(epos_on_text+3, dest, &r_type, &r_lv, &r_dv);
             *
             * switch ( r_type ) { case 1: power = r_lv; break; case 2: power =
             * r_dv; break; default: // error *type = r_type; } } else
             */
            power = sb_strtof(epos + 3);

            if (r_type > 0) {
              switch (eop) {
              case '+':
                *dv = num + power;
                break;
              case '-':
                *dv = num - power;
                break;
              case '*':
                *dv = num * power;
                break;
              case '/':
                if (ABS(power) != 0.0)
                  *dv = num / power;
                else
                  *dv = 0;
                // else if(comp) sc_raise() else rt_raise
                break;
              case '\\':
                if ((long) power != 0) {
                  *type = 1;
                  *lv = num / (long) power;
                } else {
                  *type = 1;
                  *lv = 0;
                }
                // else if(comp) sc_raise() else rt_raise
                break;
              case '^':
                *dv = pow(num, power);
                break;
              }
            }
          } else {
            *epos = '\0';
            power = pow(10, sb_strtof(epos + 1));
            *dv = sb_strtof(dest) * ((double) sign) * power;
            *epos = 'E';
          }
        } else {
          *dv = sb_strtof(dest) * ((double) sign);
        }
      } else {
        // dpc = 0 && epos = 0
        *type = 1;              // int32_t
        *lv = xstrtol(dest) * sign;
      }
      break;
    case 16:
      *type = 1;                // int32_t
      *lv = hextol(dest);
      break;
    case 8:
      *type = 1;                // int32_t
      *lv = octtol(dest);
      break;
    case 2:
      *type = 1;                // int32_t
      *lv = bintol(dest);
      break;
    }
  }
  //
  if (is_alpha(*p)) {
    *type = -9;                 // ITS NOT A NUMBER
  }
  while (is_space(*p)) {
    p++;
  }
  return p;
}