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; }
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; }
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; }
/* 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; }
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"); } }
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; }
// 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; }
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); }
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); }
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); }
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); }
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; }
/** * 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; }