bool mod_query_init() { if(!mod_query_register_exports()) goto err; mod_query_input_bindmap=ioncore_alloc_bindmap("WInput", NULL); mod_query_wedln_bindmap=ioncore_alloc_bindmap("WEdln", NULL); if(mod_query_wedln_bindmap==NULL || mod_query_input_bindmap==NULL){ goto err; } /*ioncore_read_config("cfg_query", NULL, TRUE);*/ load_history(); loaded_ok=TRUE; hook_add(ioncore_snapshot_hook, save_history); return TRUE; err: mod_query_deinit(); return FALSE; }
static int cmd_loop(int in_argc, const char *in_argv[]) { int argc; char *input, **argv; int quit = 0; char *history_path; history_path = load_history(); while (!quit) { input = readline("> "); append_history(history_path, input); if ((tokenize_command_line(input, &argc, &argv) == -1) || argc < 1) { free(input); continue; } int cmd = str_to_cmd(argv[0]); if (cmd == CMD_UNKNOWN || CMD_INTERACTIVE) { warnx("'%s': unknown command", argv[0]); free(argv); free(input); continue; } do_cmd(cmd, --argc, (const char **) ++argv); free(--argv); free(input); } return AFC_E_SUCCESS; }
void history_add(history_t *ph, char *string) { if (ph -> history_size > 0) { int loop; int found = -1; load_history(ph); /* bail out if this string is already in the history */ for(loop=0; loop<ph -> history_size; loop++) { if ((ph -> history)[loop] != NULL && strcmp((ph -> history)[loop], string) == 0) return ; } /* find free spot */ found = history_find_null_entry(ph); /* when no free spot was found, free-up an entry */ if (found == -1) { myfree((ph -> history)[ph -> history_size - 1]); memmove(&(ph -> history)[1], &(ph -> history)[0], sizeof(char *) * (ph -> history_size - 1)); found = 0; } (ph -> history)[found] = mystrdup(string); save_history(ph); } }
//------------------------------------------------------------------------------ static int startup_hook() { static int initialised = 0; if (!initialised) { // This is a bit of a hack. Ideally we should take care of this in // the termcap functions. _rl_term_forward_char = "\013"; _rl_term_clreol = "\001"; rl_redisplay_function = display; rl_getc_function = getc_impl; rl_completer_quote_characters = "\""; rl_ignore_some_completions_function = postprocess_matches; rl_basic_word_break_characters = " <>|"; rl_completer_word_break_characters = " <>|"; rl_completion_display_matches_hook = display_matches; rl_attempted_completion_function = alternative_matches; rl_add_funmap_entry("clink-completion-shim", completion_shim); rl_add_funmap_entry("clear-line", clear_line); rl_add_funmap_entry("paste-from-clipboard", paste_from_clipboard); initialise_lua(); load_history(); rl_re_read_init_file(0, 0); rl_visible_stats = 0; // serves no purpose under win32. initialised = 1; } return 0; }
static void load_new(void) { char hgz[256]; sprintf(hgz, "%s.gz.new", history_fn); if (load_history(hgz) >= 0) save(0); unlink(hgz); }
/* Try loading from the backup versions. * We'll try from oldest to newest, then * retry the requested one again last. In case the drive mounts while * we are trying to find a good version. */ static int try_hardway(const char *fname) { char fn[256]; int n, b, found = 0; strcpy(fn, fname); n = strlen(fn); if ((n > 3) && (strcmp(fn + (n - 3), ".gz") == 0)) n -= 3; for (b = HI_BACK; b > 0; --b) { sprintf(fn + n, "_%d.bak", b); found |= load_history(fn); } found |= load_history(fname); return found; }
int main(int argc, char *argv[]) { struct sysinfo si; long z; struct sigaction sa; printf("rstats\nCopyright (C) 2006 Jonathan Zarate\n\n"); if (fork() != 0) return 0; openlog("rstats", LOG_PID, LOG_USER); sa.sa_handler = sig_handler; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sysinfo(&si); z = si.uptime; load(si.uptime); while (1) { while (si.uptime < z) { sleep(z - si.uptime); if (gothup) { if (unlink("/var/tmp/rstats-reload") == 0) { load_history(); } else { save(0); } gothup = 0; } if (gotterm) { save(1); exit(0); } if (gotuser == 1) { save_speedjs(); gotuser = 0; } else if (gotuser == 2) { save_histjs(); gotuser = 0; } sysinfo(&si); } calc(si.uptime); z += INTERVAL; } return 0; }
// line must be freed by caller char *_readline (char prompt[]) { char *line; load_history(); line = readline(prompt); if (!line) return NULL; // EOF add_history(line); // Add input to in-memory history append_to_history(); // Flush new line of history to disk return line; }
char * search_history(history_t *ph, char *search_string) { if (ph -> history_size > 0) { int n_entries, free_entry; load_history(ph); free_entry = history_find_null_entry(ph); n_entries = free_entry == -1 ? ph -> history_size : free_entry; if (n_entries > 0) { int sel_index = selection_box((void **)ph -> history, NULL, n_entries, SEL_HISTORY, HELP_HISTORY, NULL); if (sel_index >= 0) return mystrdup((ph -> history)[sel_index]); } else error_popup("Search history", -1, "The history list is empty."); } return NULL; }
/* Returns: * -1 on read errors or EOF, or on bare Ctrl-D. * 0 on ctrl-C, * >0 length of input string, including terminating '\n' */ int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *st) { int lastWasTab = FALSE; unsigned int ic; unsigned char c; smallint break_out = 0; #if ENABLE_FEATURE_EDITING_VI smallint vi_cmdmode = 0; smalluint prevc; #endif if (maxsize > MAX_LINELEN) maxsize = MAX_LINELEN; /* With null flags, no other fields are ever used */ state = st ? st : (line_input_t*) &const_int_0; #if ENABLE_FEATURE_EDITING_SAVEHISTORY if ((state->flags & SAVE_HISTORY) && state->hist_file) load_history(state->hist_file); #endif /* prepare before init handlers */ cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ command_len = 0; command_ps = command; command[0] = '\0'; getTermSettings(0, (void *) &initial_settings); memcpy(&new_settings, &initial_settings, sizeof(new_settings)); new_settings.c_lflag &= ~ICANON; /* unbuffered input */ /* Turn off echoing and CTRL-C, so we can trap it */ new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); /* Hmm, in linux c_cc[] is not parsed if ICANON is off */ new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VTIME] = 0; /* Turn off CTRL-C, so we can trap it */ #ifndef _POSIX_VDISABLE #define _POSIX_VDISABLE '\0' #endif new_settings.c_cc[VINTR] = _POSIX_VDISABLE; setTermSettings(0, (void *) &new_settings); /* Now initialize things */ previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); win_changed(0); /* do initial resizing */ #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR { struct passwd *entry; entry = getpwuid(geteuid()); if (entry) { /* If we enter read_line_input for the Nth time, * they may be already allocated! Need to free. */ free(user_buf); if (home_pwd_buf != null_str) free(home_pwd_buf); user_buf = xstrdup(entry->pw_name); home_pwd_buf = xstrdup(entry->pw_dir); /* They are not freed on exit (too small to bother) */ } } #endif /* Print out the command prompt */ parse_prompt(prompt); while (1) { fflush(stdout); if (safe_read(0, &c, 1) < 1) { /* if we can't read input then exit */ goto prepare_to_die; } ic = c; #if ENABLE_FEATURE_EDITING_VI newdelflag = 1; if (vi_cmdmode) ic |= vbit; #endif switch (ic) { case '\n': case '\r': vi_case('\n'|vbit:) vi_case('\r'|vbit:) /* Enter */ goto_new_line(); break_out = 1; break; #if ENABLE_FEATURE_EDITING_FANCY_KEYS case CTRL('A'): vi_case('0'|vbit:) /* Control-a -- Beginning of line */ input_backward(cursor); break; case CTRL('B'): vi_case('h'|vbit:) vi_case('\b'|vbit:) vi_case('\x7f'|vbit:) /* DEL */ /* Control-b -- Move back one character */ input_backward(1); break; #endif case CTRL('C'): vi_case(CTRL('C')|vbit:) /* Control-c -- stop gathering input */ goto_new_line(); command_len = 0; break_out = -1; /* "do not append '\n'" */ break; case CTRL('D'): /* Control-d -- Delete one character, or exit * if the len=0 and no chars to delete */ if (command_len == 0) { errno = 0; prepare_to_die: /* to control stopped jobs */ break_out = command_len = -1; break; } input_delete(0); break; #if ENABLE_FEATURE_EDITING_FANCY_KEYS case CTRL('E'): vi_case('$'|vbit:) /* Control-e -- End of line */ input_end(); break; case CTRL('F'): vi_case('l'|vbit:) vi_case(' '|vbit:) /* Control-f -- Move forward one character */ input_forward(); break; #endif case '\b': case '\x7f': /* DEL */ /* Control-h and DEL */ input_backspace(); break; case '\t': input_tab(&lastWasTab); break; #if ENABLE_FEATURE_EDITING_FANCY_KEYS case CTRL('K'): /* Control-k -- clear to end of line */ command[cursor] = 0; command_len = cursor; printf("\033[J"); break; case CTRL('L'): vi_case(CTRL('L')|vbit:) /* Control-l -- clear screen */ printf("\033[H"); redraw(0, command_len - cursor); break; #endif #if MAX_HISTORY > 0 case CTRL('N'): vi_case(CTRL('N')|vbit:) vi_case('j'|vbit:) /* Control-n -- Get next command in history */ if (get_next_history()) goto rewrite_line; break; case CTRL('P'): vi_case(CTRL('P')|vbit:) vi_case('k'|vbit:) /* Control-p -- Get previous command from history */ if ((state->flags & DO_HISTORY) && state->cur_history > 0) { get_previous_history(); goto rewrite_line; } beep(); break; #endif #if ENABLE_FEATURE_EDITING_FANCY_KEYS case CTRL('U'): vi_case(CTRL('U')|vbit:) /* Control-U -- Clear line before cursor */ if (cursor) { strcpy(command, command + cursor); command_len -= cursor; redraw(cmdedit_y, command_len); } break; #endif case CTRL('W'): vi_case(CTRL('W')|vbit:) /* Control-W -- Remove the last word */ while (cursor > 0 && isspace(command[cursor-1])) input_backspace(); while (cursor > 0 && !isspace(command[cursor-1])) input_backspace(); break; #if ENABLE_FEATURE_EDITING_VI case 'i'|vbit: vi_cmdmode = 0; break; case 'I'|vbit: input_backward(cursor); vi_cmdmode = 0; break; case 'a'|vbit: input_forward(); vi_cmdmode = 0; break; case 'A'|vbit: input_end(); vi_cmdmode = 0; break; case 'x'|vbit: input_delete(1); break; case 'X'|vbit: if (cursor > 0) { input_backward(1); input_delete(1); } break; case 'W'|vbit: vi_Word_motion(command, 1); break; case 'w'|vbit: vi_word_motion(command, 1); break; case 'E'|vbit: vi_End_motion(command); break; case 'e'|vbit: vi_end_motion(command); break; case 'B'|vbit: vi_Back_motion(command); break; case 'b'|vbit: vi_back_motion(command); break; case 'C'|vbit: vi_cmdmode = 0; /* fall through */ case 'D'|vbit: goto clear_to_eol; case 'c'|vbit: vi_cmdmode = 0; /* fall through */ case 'd'|vbit: { int nc, sc; sc = cursor; prevc = ic; if (safe_read(0, &c, 1) < 1) goto prepare_to_die; if (c == (prevc & 0xff)) { /* "cc", "dd" */ input_backward(cursor); goto clear_to_eol; break; } switch (c) { case 'w': case 'W': case 'e': case 'E': switch (c) { case 'w': /* "dw", "cw" */ vi_word_motion(command, vi_cmdmode); break; case 'W': /* 'dW', 'cW' */ vi_Word_motion(command, vi_cmdmode); break; case 'e': /* 'de', 'ce' */ vi_end_motion(command); input_forward(); break; case 'E': /* 'dE', 'cE' */ vi_End_motion(command); input_forward(); break; } nc = cursor; input_backward(cursor - sc); while (nc-- > cursor) input_delete(1); break; case 'b': /* "db", "cb" */ case 'B': /* implemented as B */ if (c == 'b') vi_back_motion(command); else vi_Back_motion(command); while (sc-- > cursor) input_delete(1); break; case ' ': /* "d ", "c " */ input_delete(1); break; case '$': /* "d$", "c$" */ clear_to_eol: while (cursor < command_len) input_delete(1); break; } break; } case 'p'|vbit: input_forward(); /* fallthrough */ case 'P'|vbit: put(); break; case 'r'|vbit: if (safe_read(0, &c, 1) < 1) goto prepare_to_die; if (c == 0) beep(); else { *(command + cursor) = c; putchar(c); putchar('\b'); } break; #endif /* FEATURE_COMMAND_EDITING_VI */ case '\x1b': /* ESC */ #if ENABLE_FEATURE_EDITING_VI if (state->flags & VI_MODE) { /* ESC: insert mode --> command mode */ vi_cmdmode = 1; input_backward(1); break; } #endif /* escape sequence follows */ if (safe_read(0, &c, 1) < 1) goto prepare_to_die; /* different vt100 emulations */ if (c == '[' || c == 'O') { vi_case('['|vbit:) vi_case('O'|vbit:) if (safe_read(0, &c, 1) < 1) goto prepare_to_die; } if (c >= '1' && c <= '9') { unsigned char dummy; if (safe_read(0, &dummy, 1) < 1) goto prepare_to_die; if (dummy != '~') c = '\0'; } switch (c) { #if ENABLE_FEATURE_TAB_COMPLETION case '\t': /* Alt-Tab */ input_tab(&lastWasTab); break; #endif #if MAX_HISTORY > 0 case 'A': /* Up Arrow -- Get previous command from history */ if ((state->flags & DO_HISTORY) && state->cur_history > 0) { get_previous_history(); goto rewrite_line; } beep(); break; case 'B': /* Down Arrow -- Get next command in history */ if (!get_next_history()) break; rewrite_line: /* Rewrite the line with the selected history item */ /* change command */ command_len = strlen(strcpy(command, state->history[state->cur_history])); /* redraw and go to eol (bol, in vi */ redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); break; #endif case 'C': /* Right Arrow -- Move forward one character */ input_forward(); break; case 'D': /* Left Arrow -- Move back one character */ input_backward(1); break; case '3': /* Delete */ input_delete(0); break; case '1': // vt100? linux vt? or what? case '7': // vt100? linux vt? or what? case 'H': /* xterm's <Home> */ input_backward(cursor); break; case '4': // vt100? linux vt? or what? case '8': // vt100? linux vt? or what? case 'F': /* xterm's <End> */ input_end(); break; default: c = '\0'; beep(); } break; default: /* If it's regular input, do the normal thing */ #if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT /* Control-V -- Add non-printable symbol */ if (c == CTRL('V')) { if (safe_read(0, &c, 1) < 1) goto prepare_to_die; if (c == 0) { beep(); break; } } else #endif #if ENABLE_FEATURE_EDITING_VI if (vi_cmdmode) /* Don't self-insert */ break; #endif if (!Isprint(c)) /* Skip non-printable characters */ break; if (command_len >= (maxsize - 2)) /* Need to leave space for enter */ break; command_len++; if (cursor == (command_len - 1)) { /* Append if at the end of the line */ command[cursor] = c; command[cursor+1] = '\0'; cmdedit_set_out_char(' '); } else { /* Insert otherwise */ int sc = cursor; memmove(command + sc + 1, command + sc, command_len - sc); command[sc] = c; sc++; /* rewrite from cursor */ input_end(); /* to prev x pos + 1 */ input_backward(cursor - sc); } break; } if (break_out) /* Enter is the command terminator, no more input. */ break; if (c != '\t') lastWasTab = FALSE; }
//------------------------------------------------------------------------------ static char* call_readline_impl(const char* prompt) { static int initialised = 0; int expand_result; char* text; char* expanded; char* prepared_prompt; char cwd_cache[MAX_PATH]; // Initialisation if (!initialised) { initialise_clink_settings(); initialise_lua(); load_history(); rl_catch_signals = 0; rl_startup_hook = initialise_hook; initialised = 1; } // If no prompt was provided assume the line is prompted already and // extract it. If a prompt was provided filter it through Lua. prepared_prompt = NULL; if (prompt == NULL) { prepared_prompt = extract_prompt(1); // Even though we're not going to display filtered result the extracted // prompt is run through Lua. This is a little bit of a hack, but helps // to keep behaviour consistent. if (prepared_prompt != NULL) { char buffer[1024]; str_cpy(buffer, prepared_prompt, sizeof(buffer)); lua_filter_prompt(buffer, sizeof_array(buffer)); } } else { prepared_prompt = filter_prompt(prompt); } GetCurrentDirectory(sizeof_array(cwd_cache), cwd_cache); // Call readline do { rl_already_prompted = (prompt == NULL); text = readline(prepared_prompt ? prepared_prompt : ""); if (!text) { goto call_readline_epilogue; } // Expand history designators in returned buffer. expanded = NULL; expand_result = history_expand(text, &expanded); if (expand_result < 0) { free(expanded); } else { free(text); text = expanded; // If there was some expansion then display the expanded result. if (expand_result > 0) { hooked_fprintf(NULL, "History expansion: %s\n", text); } } add_to_history(text); } while (!text || expand_result == 2); call_readline_epilogue: free_prompt(prepared_prompt); SetCurrentDirectory(cwd_cache); return text; }
int main(int argc, char ** argv) { int option, nerror = 0, background = 0, quiet = 0, have_socket = 0; time_t pauselength = 0; char * proxy; opterr = 0; /* Create directories. */ makercd(); /* Load settings from ~/.shell-fm/shell-fm.rc. */ settings(rcpath("shell-fm.rc"), !0); /* Enable discovery by default if it is set in configuration. */ if(haskey(& rc, "discovery")) enable(DISCOVERY); /* Disable RTP if option "no-rtp" is set to something. */ if(haskey(& rc, "no-rtp")) disable(RTP); /* If "daemon" is set in the configuration, enable daemon mode by default. */ if(haskey(& rc, "daemon")) background = !0; /* If "quiet" is set in the configuration, enable quiet mode by default. */ if(haskey(& rc, "quiet")) quiet = !0; /* Get proxy environment variable. */ if((proxy = getenv("http_proxy")) != NULL) set(& rc, "proxy", proxy); /* Parse through command line options. */ while(-1 != (option = getopt(argc, argv, ":dbhqi:p:D:y:Y:"))) switch(option) { case 'd': /* Daemonize. */ background = !background; break; case 'i': /* IP to bind network interface to. */ set(& rc, "bind", optarg); break; case 'p': /* Port to listen on. */ if(atoi(optarg)) set(& rc, "port", optarg); else { fputs("Invalid port.\n", stderr); ++nerror; } break; case 'b': /* Batch mode */ batch = !0; break; case 'D': /* Path to audio device file. */ set(& rc, "device", optarg); break; case 'y': /* Proxy address. */ set(& rc, "proxy", optarg); break; case 'Y': /* SOCKS proxy address. */ set(& rc, "socks-proxy", optarg); break; case 'q': /* Quiet mode. */ quiet = !quiet; break; case 'h': /* Print help text and exit. */ help(argv[0], 0); break; case ':': fprintf(stderr, "Missing argument for option -%c.\n\n", optopt); ++nerror; break; case '?': default: fprintf(stderr, "Unknown option -%c.\n", optopt); ++nerror; break; } /* The next argument, if present, is the lastfm:// URL we want to play. */ if(optind > 0 && optind < argc && argv[optind]) { const char * station = argv[optind]; set(& rc, "default-radio", station); } if(nerror) help(argv[0], EXIT_FAILURE); #ifdef EXTERN_ONLY /* Abort if EXTERN_ONLY is defined and no extern command is present */ if(!haskey(& rc, "extern")) { fputs("Can't continue without extern command.\n", stderr); exit(EXIT_FAILURE); } #else #ifndef LIBAO if(!haskey(& rc, "device")) set(& rc, "device", "/dev/audio"); #endif #endif if(!background && !quiet) { puts("Shell.FM v" PACKAGE_VERSION ", (C) 2006-2012 by Jonas Kramer"); puts("Published under the terms of the GNU General Public License (GPL)."); #ifndef TUXBOX puts("\nPress ? for help.\n"); #else puts("Compiled for the use with Shell.FM Wrapper.\n"); #endif fflush(stdout); } /* Open a port so Shell.FM can be controlled over network. */ if(haskey(& rc, "bind")) { int port = 54311; if(haskey(& rc, "port")) port = atoi(value(& rc, "port")); if(tcpsock(value(& rc, "bind"), (unsigned short) port)) have_socket = !0; } /* Open a UNIX socket for local "remote" control. */ if(haskey(& rc, "unix") && unixsock(value(& rc, "unix"))) have_socket = !0; /* We can't daemonize if there's no possibility left to control Shell.FM. */ if(background && !have_socket) { fputs("Can't daemonize without control socket.\n", stderr); exit(EXIT_FAILURE); } memset(& data, 0, sizeof(struct hash)); memset(& track, 0, sizeof(struct hash)); memset(& playlist, 0, sizeof(struct playlist)); /* Fork to background. */ if(background) { int null; pid_t pid = fork(); if(pid == -1) { fputs("Failed to daemonize.\n", stderr); exit(EXIT_FAILURE); } else if(pid) { exit(EXIT_SUCCESS); } enable(QUIET); /* Detach from TTY */ setsid(); pid = fork(); if(pid > 0) exit(EXIT_SUCCESS); /* Close stdin out and err */ close(0); close(1); close(2); /* Redirect stdin and out to /dev/null */ null = open("/dev/null", O_RDWR); dup(null); dup(null); } ppid = getpid(); atexit(cleanup); load_queue(); /* Set up signal handlers for communication with the playback process. */ signal(SIGINT, forcequit); /* SIGUSR2 from playfork means it detected an error. */ signal(SIGUSR2, playsig); /* Catch SIGTSTP to set pausetime when user suspends us with ^Z. */ signal(SIGTSTP, stopsig); /* Authenticate to the Last.FM server. */ create_session(); if(!background) { struct input keyboard = { 0, KEYBOARD }; register_handle(keyboard); canon(0); atexit(cleanup_term); } /* Play default radio, if specified. */ if(haskey(& rc, "default-radio")) { if(!strcmp(value(& rc, "default-radio"), "last")) { char ** history = load_history(), * last = NULL, ** p; for(p = history; * p != NULL; ++p) { last = * p; } set(& rc, "default-radio", last); purge(history); } station(value(& rc, "default-radio")); } else if(!background) radioprompt("radio url> "); /* The main loop. */ while(!0) { pid_t child; int status, playnext = 0; /* Check if anything died (submissions fork or playback fork). */ while((child = waitpid(-1, & status, WNOHANG | WUNTRACED | WCONTINUED)) > 0) { if(child == subfork) subdead(WEXITSTATUS(status)); else if(child == playfork) { if(WIFSTOPPED(status)) { /* time(& pausetime); */ } else { if(WIFCONTINUED(status)) { signal(SIGTSTP, stopsig); if(pausetime != 0) { pauselength += time(NULL) - pausetime; } } else { playnext = !0; unlinknp(); if(delayquit) { quit(); } } pausetime = 0; } } } /* Check if the playback process died. If so, submit the data of the last played track. Then check if there are tracks left in the playlist; if not, try to refresh the list and stop the stream if there are no new tracks to fetch. Also handle user stopping the stream here. We need to check for playnext != 0 before handling enabled(STOPPED) anyway, otherwise playfork would still be running. */ if(playnext) { playfork = 0; if(enabled(RTP)) { unsigned duration, played, minimum; duration = atoi(value(& track, "duration")); played = time(NULL) - change_time - pauselength; /* Allow user to specify minimum playback length (min. 50%). */ if(haskey(& rc, "minimum")) { unsigned percent = atoi(value(& rc, "minimum")); if(percent < 50) percent = 50; minimum = duration * percent / 100; } else { minimum = duration / 2; } if(duration >= 30 && (played >= 240 || played > minimum)) { debug("adding track to scrobble queue\n"); enqueue(& track); } else { debug("track too short (duration %d, played %d, minimum %d) - not scrobbling\n", duration, played, minimum); } } submit(); /* Check if the user stopped the stream. */ if(enabled(STOPPED) || error) { freelist(& playlist); empty(& track); if(error) { fputs("Playback stopped with an error.\n", stderr); error = 0; } disable(STOPPED); disable(CHANGED); continue; } shift(& playlist); } if(playnext || enabled(CHANGED)) { if(nextstation != NULL) { playnext = 0; disable(CHANGED); if(!station(nextstation)) enable(STOPPED); free(nextstation); nextstation = NULL; } if(!enabled(STOPPED) && !playlist.left) { expand(& playlist); if(!playlist.left) { puts("No tracks left."); playnext = 0; disable(CHANGED); continue; } } if(!playfork) { /* If there was a track played before, and there is a gap configured, wait that many seconds before playing the next track. */ if(playnext && !enabled(INTERRUPTED) && haskey(& rc, "gap")) { int gap = atoi(value(& rc, "gap")); if(gap > 0) sleep(gap); } disable(INTERRUPTED); if(play(& playlist)) { time(& change_time); pauselength = 0; set(& track, "stationURL", current_station); /* Print what's currently played. (Ondrej Novy) */ if(!background) { if(enabled(CHANGED) && playlist.left > 0) { puts(meta("Receiving %s.", M_COLORED, & track)); disable(CHANGED); } if(haskey(& rc, "title-format")) printf("%s\n", meta(value(& rc, "title-format"), M_COLORED, & track)); else printf("%s\n", meta("Now playing \"%t\" by %a.", M_COLORED, & track)); } if(enabled(RTP)) { notify_now_playing(& track); } /* Write track data into a file. */ if(haskey(& rc, "np-file") && haskey(& rc, "np-file-format")) { signed np; const char * file = value(& rc, "np-file"), * fmt = value(& rc, "np-file-format"); unlink(file); if(-1 != (np = open(file, O_WRONLY | O_CREAT, 0644))) { const char * output = meta(fmt, 0, & track); if(output) write(np, output, strlen(output)); close(np); } } if(haskey(& rc, "screen-format")) { const char * term = getenv("TERM"); if(term != NULL && !strncmp(term, "screen", 6)) { const char * output = meta(value(& rc, "screen-format"), 0, & track); printf("\x1Bk%s\x1B\\", output); } } if(haskey(& rc, "term-format")) { const char * output = meta(value(& rc, "term-format"), 0, & track); printf("\x1B]2;%s\a", output); } /* Run a command with our track data. */ if(haskey(& rc, "np-unescaped-cmd")) run(meta(value(& rc, "np-unescaped-cmd"), 0, & track)); if(haskey(& rc, "np-cmd")) run(meta(value(& rc, "np-cmd"), M_SHELLESC, & track)); } else change_time = 0; } if(banned(value(& track, "creator"))) { puts(meta("%a is banned.", M_COLORED, & track)); rate(RATING_BAN); fflush(stdout); } } playnext = 0; if(playfork && change_time && haskey(& track, "duration") && !pausetime) { unsigned duration; signed remain; char remstr[32]; duration = atoi(value(& track, "duration")); remain = (change_time + duration) - time(NULL) + pauselength; snprintf(remstr, sizeof(remstr), "%d", remain); set(& track, "remain", remstr); if(!background) { printf( "%s%c", meta("%r", M_COLORED, & track), // strdup(meta("%v", M_COLORED, & track)), batch ? '\n' : '\r' ); fflush(stdout); } } handle_input(1000000); } return 0; }
//------------------------------------------------------------------------------ static char* call_readline_impl(const char* prompt) { static int initialised = 0; int expand_result; char* text; char* expanded; char* prepared_prompt; char cwd_cache[MAX_PATH]; // Turn off EOL wrapping as Readline will take care of it. { HANDLE handle_stdout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleMode(handle_stdout, ENABLE_PROCESSED_OUTPUT); } // Initialisation if (!initialised) { initialise_clink_settings(); initialise_lua(); initialise_fwrite(); load_history(); history_inhibit_expansion_function = history_expand_control; rl_catch_signals = 0; rl_startup_hook = initialise_hook; initialised = 1; } // If no prompt was provided assume the line is prompted already and // extract it. If a prompt was provided filter it through Lua. prepared_prompt = NULL; if (prompt == NULL) { prepared_prompt = extract_prompt(1); // Even though we're not going to display filtered result the extracted // prompt is run through Lua. This is a little bit of a hack, but helps // to keep behaviour consistent. if (prepared_prompt != NULL) { char buffer[1024]; str_cpy(buffer, prepared_prompt, sizeof(buffer)); lua_filter_prompt(buffer, sizeof_array(buffer)); } } else { prepared_prompt = filter_prompt(prompt); } GetCurrentDirectory(sizeof_array(cwd_cache), cwd_cache); do { // Call readline rl_already_prompted = (prompt == NULL); text = readline(prepared_prompt ? prepared_prompt : ""); if (!text) { goto call_readline_epilogue; } // Expand history designators in returned buffer. expanded = NULL; expand_result = expand_from_history(text, &expanded); if (expand_result > 0 && expanded != NULL) { free(text); text = expanded; // If there was some expansion then display the expanded result. if (expand_result > 0) { hooked_fprintf(NULL, "History expansion: %s\n", text); } } // Should we read the history from disk. if (get_clink_setting_int("history_io")) { load_history(); add_to_history(text); save_history(); } else add_to_history(text); } while (!text || expand_result == 2); call_readline_epilogue: free_prompt(prepared_prompt); SetCurrentDirectory(cwd_cache); return text; }
static void load(long uptime) { int i; long t; char *bi, *bo; int n; char hgz[256]; unsigned char mac[6]; strlcpy(save_path, nvram_safe_get("rstats_path"), sizeof(save_path) - 32); if (((n = strlen(save_path)) > 0) && (save_path[n - 1] == '/')) { ether_atoe(nvram_safe_get("et0macaddr"), mac); sprintf(save_path + n, "ddwrt_rstats_%02x%02x%02x%02x%02x%02x.gz", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } if (f_read("/var/lib/misc/rstats-stime", &save_utime, sizeof(save_utime)) != sizeof(save_utime)) { save_utime = 0; } t = uptime + get_stime(); if ((save_utime < uptime) || (save_utime > t)) save_utime = t; _dprintf("uptime = %dm, save_utime = %dm\n", uptime / 60, save_utime / 60); speed_count = decomp(speed_fn, speed, sizeof(speed[0]), MAX_SPEED_IF); _dprintf("load speed_count = %d\n", speed_count); if ((load_history()) || (save_path[0] == 0)) return; sprintf(hgz, "%s.gz", history_fn); if (strcmp(save_path, "*nvram") == 0) { if (!wait_action_idle(60)) exit(0); bi = nvram_safe_get("rstats_data"); if ((n = strlen(bi)) > 0) { if ((bo = malloc(base64_decoded_len(n))) != NULL) { n = base64_decode(bi, bo, n); f_write(hgz, bo, n, 0, 0); free(bo); _dprintf("from nvram = %d\n", n); } } } else { for (i = 30; i > 0; --i) { if (!wait_action_idle(60)) exit(0); _dprintf("copy %s to %s\n", save_path, hgz); if (eval("cp", save_path, hgz) == 0) break; // not ready... sleep(3); } if (i == 0) { save_utime = uptime + 60; _dprintf("forcing early save on next\n"); } } load_history(); }