"" */ if( ReadDir(tpane1.d.name, &tpane1.d) || NON_VALID(&tpane1.d)) InitTblFromDir(&tpane1, NO, NULL); if( tpane1.t.exposed == NO ) TblDraw(&tpane1.t); if( ReadDir(tpane2.d.name, &tpane2.d) || NON_VALID(&tpane2.d)) InitTblFromDir(&tpane2, NO, NULL); if( tpane2.t.exposed == NO ) TblDraw(&tpane2.t); } /*-----------------------------------------------------------------* * . * *-----------------------------------------------------------------*/ /* */ char e_move = NO; /* <- -> / */ int e_hit[] = { KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, KEY_F(0), KEY_IC, ctrl('G'), ctrl('E'), ctrl('L'), ctrl('F'), ctrl('X'), ctrl('Y'), -1 }; int e_handler (LineEdit *le, int c, HandlerReply *reply){ *reply = HANDLER_CONTINUE; switch(c){ /* */ case KEY_LEFT: if( !SEL_PANE || !e_move){ *reply=HANDLER_SWITCH; return c; } TblPointAt(A_tbl, A_tbl->current - A_tbl->height); break; case KEY_RIGHT: if( !SEL_PANE || !e_move){ *reply=HANDLER_SWITCH; return c; } TblPointAt(A_tbl, A_tbl->current + A_tbl->height); break; case KEY_DOWN: if( !SEL_PANE){ *reply=HANDLER_SWITCH; return c; } TblPointAt(A_tbl, A_tbl->current + 1); break; case KEY_UP: if( !SEL_PANE){ *reply=HANDLER_SWITCH; return c; } TblPointAt(A_tbl, A_tbl->current - 1); break; case KEY_F(0): /* F10 */ e_move = !e_move; break; case KEY_IC: if( !SEL_PANE){ *reply=HANDLER_SWITCH; return c; } TblRetag(A_tbl, A_tbl->current, T_LABEL); TblPointAt(A_tbl, A_tbl->current+1); break; /* */ case ctrl('G'): /* */ LeInsStr(le, getenv("HOME")); LeInsStr(le, " "); break; case ctrl('E'): /* */ if( A_tbl->nitems ) LeInsStr(le, T_ITEMF(A_tbl, A_tbl->current, 0)); LeInsStr(le, " "); break; case ctrl('L'): /* */ LeInsStr(le, T_ITEMF(B_tbl, B_tbl->current, 0)); LeInsStr(le, " "); break; case ctrl('X'): case ctrl('Y'): /* */ { int label = (c == ctrl('X') ? T_LABEL : T_HATCH); register i; for(i=0; i < A_tbl->nitems && le->len < le->maxlen; ++i ) if( T_TST(A_tbl, i, label)){ LeInsStr(le, " "); LeInsStr(le, T_ITEMF(A_tbl, i, 0)); } } break; case ctrl('F'): /* */ LeInsStr(le, CWD); LeInsStr(le, " "); break; } return c; } /* */ void e_pos (LineEdit *le){ le->pos = le->len; } /* , */ void e_hide(LineEdit *le){ le->sel_attrib = le->fr_attrib = le->bg_attrib = A_ITALICS; LeDraw(le); } /* */ char *Edit(WINDOW *w, char *src, RunType dorun){ static char CMD[MAXLEN]; /* */ int c; if(w != TOPW){ beep(); return NULL; }/* */ keypad(w, TRUE); /* */ switch(dorun){ case NORUN: edit.histIn = edit.histOut = NULL; break; case RUNCMD: edit.histIn = edit.histOut = &hedit; break; case FIND: case TAG: edit.histIn = edit.histOut = &hpat; break; case CHDIR: edit.histIn = &hcwd; edit.histOut = NULL; break; } edit.line = CMD; edit.maxlen = sizeof(CMD)-1; edit.top = wlines(w)-2; edit.left = 2; edit.width = wcols (w)-4 - (1+BARWIDTH); edit.insert = YES; edit.nc = YES; edit.win = w; edit.wl_attrib = edit.bg_attrib=A_REVERSE; edit.fr_attrib=A_STANDOUT; edit.sel_attrib = A_NORMAL|A_BLINK; edit.posMe = e_pos; edit.hitkeys = (SEL_PANE ? e_hit : e_hit+5); edit.handler = e_handler; /* edit.hideMe = e_hide; */ /* 0, .. edit - */ for(;;){ strcpy(CMD, src); if(*src){ strcat(CMD, " "); } c = LeEdit( &edit ); if( LE_REFUSED(&edit) || dorun != RUNCMD || !*CMD || c != '\n' ) break; /* */ attrset(A_NORMAL); move(LINES-1, 0); refresh(); resetterm(); /* curses- */ putchar('\n'); /* */ system(CMD); /* */ fprintf(stderr," ENTER --- ");gets(CMD); fixterm(); /* curses- */ RedrawScreen(); /* */ if(w == panewin){ checkBothPanes(); if(A_tbl->nitems) TblPoint(A_tbl, A_tbl->current, NO); } src = ""; /* */ } wattrset(w, A_NORMAL); /* ? */ e_hide ( &edit ); return ( *CMD && !LE_REFUSED(&edit)) ? CMD : NULL; } /* . */ /* (dorun==RUNCMD). */ char *help(char *msg, RunType dorun){ register i; char *s; static char *helptext[] = { "ESC - ", "F1 - ", "INS - ", "ctrl/E - ", "ctrl/L - ", "ctrl/X - ", "ctrl/Y - ", "ctrl/G - ", "ctrl/F - ", "F4 - ", "F7 - /", "F10 - / ", }; #define HELPLINES (sizeof(helptext)/sizeof helptext[0]) Sel save_current_menu = current_menu; /* "" POP-UP window */ WINDOW *w = newwin(2+1+HELPLINES+1, 70, 2, (COLS-70)/2); if( w == NULL ) return NULL; current_menu = SEL_HELP; wattrset(w, A_REVERSE); /* */ werase (w); /* */ wborder(w); RaiseWin(w); /* */ if(*msg){ wattron (w, A_BOLD); mvwaddstr(w, 1+HELPLINES, 2, msg); wattroff(w, A_BOLD); } for(i=0; i < HELPLINES; i++) mvwaddstr(w, 1+i, 2, helptext[i]); s = Edit(w, "", dorun); PopWin(); /* */ current_menu = save_current_menu; return s; } /*-----------------------------------------------------------------* * . * *-----------------------------------------------------------------*/ int f_left(), f_right(), f_pull(), f_help(), f_sort(), f_dir(), f_bye(), f_redraw(),f_cdroot(); /* , , * . 0 */ #ifndef __GNUC__ Info mwrk_info[] = { /* */ { "\\Current directory", 0 , f_left }, /* 0 */ { "\\Root directory", M_HATCH , f_right }, /* 1 */ { "\\Menus", 0 , f_pull }, /* 2 */ { "\1", /* . */ 0 }, /* 3 */ { "\\Help", 0 , f_help }, /* 4 */ { "Un\\implemented", I_NOSEL }, /* 5 */ { "Change \\sorttype", 0 , f_sort }, /* 6 */ { "Look directory \\history", 0 , f_dir }, /* 7 */ { "\1", /* . */ 0 }, /* 8 */ { "\\Quit", M_BOLD , f_bye }, /* 9 */ { "\1", /* . */ 0 }, /* 10 */ { "\\Redraw screen", M_HATCH , f_redraw}, /* 11 */ { "Chdir both panels to /", M_HATCH , f_cdroot}, /* 12 */ { NULL, 0 } }; #else /* GNU C- 1.37 -union- */ static char _gnu_[] = "Compiled with GNU C-compiler"; Info mwrk_info[] = { /* */ { "\\Current directory", 0 }, { "\\Root directory", M_HATCH }, { "\\Menus", 0 }, { "\1", /* . */ 0 }, { "\\Help", 0 }, { "Un\\implemented", I_NOSEL }, { "Change \\sorttype", 0 }, { "Look directory \\history", 0 }, { "\1", /* . */ 0 }, { "\\Quit", M_BOLD }, { "\1", /* . */ 0 }, { "\\Redraw screen", M_HATCH }, { "Chdir both panels to /", M_HATCH }, { NULL, 0 } }; void mwrk_init(){ mwrk_info [0].any.act = f_left; mwrk_info [1].any.act = f_right; mwrk_info [2].any.act = f_pull; mwrk_info [4].any.act = f_help; mwrk_info [6].any.act = f_sort; mwrk_info [7].any.act = f_dir; mwrk_info [9].any.act = f_bye; mwrk_info[11].any.act = f_redraw; mwrk_info[12].any.act = f_cdroot; } #endif char *mwrk_help[] = { " ", " ", " ", "", " ", " ", " ", " ", "", "", "", " ", " ", NULL }; void m_help(Menu *m, int n, int among){ Message(mwrk_help[n]); } /* () */ void SelectWorkingMenu(int sel){ if(sel == NOSELECTED) sel = MnuUsualSelect( & mwrk, NO); if( M_REFUSED(&mwrk)) help(" Quit", NORUN); else if(mwrk.items[sel].any.act) (*mwrk.items[sel].any.act)(); if( !done) MnuHide( & mwrk ); } f_left () { current_menu = SEL_PANE1; return 0; } f_right() { current_menu = SEL_PANE2; return 0; } f_pull () { current_menu = SEL_PULL; return 0; } f_help () { help(" ENTER :", RUNCMD); return 0; } f_sort () { SelectSortType(NOSELECTED); return 0; } f_dir () { Info *idir; if(idir = HistSelect(&hcwd, 20, 3)) cd(idir->s, &tpane2, CWD); current_menu = SEL_PANE2; return 0; } f_bye () { done++; return 0; } f_redraw() { RedrawScreen(); return 0; } f_cdroot() { cd("/", &tpane1, CWD); cd("/", &tpane2, CWD); checkBothPanes(); return 0; } /*-----------------------------------------------------------------* * , . * *-----------------------------------------------------------------*/ void MYwaddstr(WINDOW *w, int y, int x, int maxwidth, char *s){ register pos; for(pos=0; *s && *s != '\n' && pos < maxwidth; ++s){ wmove(w, y, x+pos); if( *s == '\t') pos += 8 - (pos & 7); else if( *s == '\b'){ if(pos) --pos; } else if( *s == '\r') pos = 0; else { ++pos; waddch(w, isprint(*s) ? *s : '?'); } } } /* . */ void fastView( char *name, /* */ unsigned mode, /* */ Table *otbl /* */ ){ FILE *fp; register int x, y; char buf[512]; TblClear(otbl); Message(" ENTER . " " - . " "ESC - ."); if( !ISREG(mode)) goto out; if((fp = fopen(name, "r")) == NULL){ Message(" %s", name); return; } for(y=0; y < otbl->height && fgets(buf, sizeof buf, fp); y++) MYwaddstr(panewin, otbl->top+y, otbl->left+1, otbl->width-2, buf); fclose(fp); out: wrefresh(otbl->win); /* */ } static struct attrNames{ unsigned mode; char name; char acc; int off; } modes[] = { { S_IREAD, 'r', 'u', 0 }, { S_IWRITE, 'w', 'u', 1 }, { S_IEXEC, 'x', 'u', 2 }, { S_IREAD >> 3, 'r', 'g', 3 }, { S_IWRITE >> 3, 'w', 'g', 4 }, { S_IEXEC >> 3, 'x', 'g', 5 }, { S_IREAD >> 6, 'r', 'o', 6 }, { S_IWRITE >> 6, 'w', 'o', 7 }, { S_IEXEC >> 6, 'x', 'o', 8 }, }; #define NMODES (sizeof(modes)/sizeof(modes[0])) /* i- */ #define MODE_X_POS(tbl, i) (tbl->left + DIR_SIZE + 12 + modes[i].off) #define MODE_Y_POS(tbl) (tbl->top + tbl->height + 1) #ifdef FILF /* */ void showMode(Table *tbl, int attr){ Info *inf = & tbl->items[tbl->current]; /* */ register i; unsigned mode = inf->mode; /* */ int uid = inf->uid, gid = inf->gid; /* */ /* - */ static char first = YES; static int myuid, mygid; WINDOW *win = tbl->win; int xleft = tbl->left + 1, y = MODE_Y_POS(tbl); if( first ){ first = NO; myuid = getuid(); mygid = getgid(); } wattron (win, attr); mvwprintw(win, y, xleft, " %*.*s %8ld ", /* */ -DIR_SIZE, DIR_SIZE, inf->s ? (!strcmp(inf->s, "..") ? "<UP-DIR>": inf->s) : "(EMPTY)", inf->size); /* (||) */ wattron (win, A_ITALICS|A_BOLD); waddch (win, ISDIR(mode) ? 'd': ISDEV(mode) ? '@' : '-'); wattroff(win, A_ITALICS|A_BOLD); /* */ for(i=0; i < NMODES; i++){ if((modes[i].acc == 'u' && myuid == uid) || (modes[i].acc == 'g' && mygid == gid) || (modes[i].acc == 'o' && myuid != uid && mygid != gid)) ; else wattron(win, A_ITALICS); mvwaddch(win, y, MODE_X_POS(tbl, i), mode & modes[i].mode ? modes[i].name : '-'); wattroff(win, A_ITALICS); } waddch(win, ' '); wattroff(win, attr); } #define newmode (tbl->items[tbl->current].mode) /* . */ int editAccessModes(FileWidget *wd){ Table *tbl = &wd->t; Table *otbl = &(Other_pane(wd)->t); /* Other_tbl(tbl); */ unsigned prevmode, oldmode; /* */ char *name; /* */ WINDOW *win = tbl->win; int position = 0, c; for(;;){ /* */ name = T_ITEMF(tbl, tbl->current, 0); oldmode = newmode; /* */ fastView(name, newmode, otbl); /* */ for(;;){ /* */ wmove(win, MODE_Y_POS(tbl), MODE_X_POS(tbl, position)); switch(c = WinGetch(win)){ /* */ case KEY_BACKTAB: TblPointAt(tbl, tbl->current - tbl->height); goto mv; case '\t': TblPointAt(tbl, tbl->current + tbl->height); goto mv; case KEY_UP: TblPointAt(tbl, tbl->current - 1); goto mv; case KEY_DOWN: TblPointAt(tbl, tbl->current + 1); goto mv; case KEY_HOME: TblPointAt(tbl, 0); goto mv; case KEY_END: TblPointAt(tbl, tbl->nitems-1); goto mv; /* */ case KEY_LEFT: if(position) --position; break; case KEY_RIGHT: if(position < NMODES-1) position++; break; default: goto out; case ESC: /* */ prevmode = newmode = oldmode; goto change; case ' ': /* */ prevmode = newmode; /* */ newmode ^= modes[position].mode; /* */ change: if( chmod(name, newmode) < 0){ beep(); Message(" %s", name); newmode = prevmode; /* */ } else /* , */ showMode(tbl, A_REVERSE); break; } } /* */ mv: ; } /* */ out: /* fastView(); */ Message(""); TblClear(otbl); return c; } #undef newmode #else void editAccessModes(FileWidget *wd){} #endif long diskFree(){ struct ustat ust; struct stat st; long freespace; if(stat(".", &st) < 0) return 0; ustat(st.st_dev, &ust); freespace = ust.f_tfree * 512L; freespace /= 1024; Message(" %*.*s %ld .", -sizeof(ust.f_fname), sizeof(ust.f_fname), *ust.f_fname ? ust.f_fname : ".", freespace); doupdate(); /* Message() */ return freespace; } /*-----------------------------------------------------------------* * , *-----------------------------------------------------------------*/ /* ( Makefile) */ int tree_err_cant_read(char *name){ Message(" \"%s\"", name); return WARNING; } int tree_name_too_long(){ Message(" "); return WARNING; } char canRun; /* */ /* SIGINT */ void onintr_f(nsig){ canRun = NO; Message("Interrupted"); } /* ==== , ==== */ long tu(int *count){ struct stat st; register i; long sum = 0L; *count = 0; for(i=0; i < A_tbl->nitems ;++i ) if( T_TST(A_tbl, i, T_LABEL)){ stat(T_ITEMF(A_tbl, i, 0), &st); #define KB(s) (((s) + 1024L - 1) / 1024L) sum += KB(st.st_size); (*count)++; } return sum; } void diskUsage(){ long du(), size, sizetagged; int n; char msg[512]; Message(" ..."); doupdate(); size = du("."); diskFree(); sizetagged = tu(&n); sprintf(msg, "%ld %s, %ld %d ", size, CWD, sizetagged, n); help(msg, NORUN); } /* ==== ===================== */ extern char *find_PATTERN; /* imported from treemk.c */ extern Info gargv[]; extern int gargc; /* imported from glob.c */ /* , */ static int findCheck(char *fullname, int level, struct stat *st){ char *basename = strrchr(fullname, '/'); if(basename) basename++; else basename = fullname; if( canRun == NO ) return FAILURE; /* */ if( match(basename, find_PATTERN)){ /* imported from match.c */ gargv[gargc] = NullInfo; /* */ gargv[gargc].s = strdup(fullname); gargv[gargc++].fl= ISDIR(st->st_mode) ? I_DIR : 0; gargv[gargc] = NullInfo; Message("%s", fullname); doupdate(); } /* gargv[] */ if ( gargc < MAX_ARGV - 1 ) return SUCCESS; else { Message(" ."); return FAILURE; } } /* , */ static Info *findAndCollect(char *pattern){ void (*old)() = signal(SIGINT, onintr_f); Sort saveSort; find_PATTERN = pattern; canRun = YES; Message(" %s %s", pattern, CWD); doupdate(); greset(); /* glob.c, gargc=0; */ walktree(CWD, findCheck, NULL, findCheck); signal(SIGINT, old); saveSort = sorttype; sorttype = SORT_ASC; if(gargc) qsort( gargv, gargc, sizeof(Info), gcmps); sorttype = saveSort; return gargc ? blkcpy(gargv) : NULL; } /* */ void findFile(FileWidget *wd){ static Info *found; static Menu mfind; int c; Table *tbl = & wd->t; char *pattern = help(" , *.c, " " ENTER ", FIND); if( LE_REFUSED( &edit)) return; /* */ /* , help() NULL */ if( pattern ){ /* - */ /* */ if( found ) blkfree( found ); MnuDeinit( &mfind ); found = findAndCollect(pattern); /* */ HistAdd( &hpat, pattern, 0); /* */ if( found ){ /* - */ mfind.items = found; mfind.title = pattern ? pattern : " "; mfind.top = 3; mfind.left = COLS/6; mfind.bg_attrib = A_STANDOUT; mfind.sel_attrib = A_REVERSE; MnuInit (&mfind); } } /* else - * . */ if( found == NULL ){ Message(" "); beep(); return; } c = MnuUsualSelect(&mfind, NO); /* , * */ if( !M_REFUSED( &mfind )){ char *s = M_ITEM(&mfind, mfind.current); /* */ M_SET(&mfind, mfind.current, M_LABEL); /* - */ if( M_TST(&mfind, mfind.current, I_DIR)) cd(s, wd, CWD); /* , */ else { char *p; struct savech svch; /* glob.h */ SAVE( svch, strrchr(s, '/')); *svch.s = '\0'; p = strdup(s); RESTORE(svch); if( !strcmp(CWD, p)) /* */ TblPlaceByName(tbl, svch.s+1); /* */ else /* s */ cd(p, wd, s); free(p); } } MnuHide(&mfind); /* , */ } /*-----------------------------------------------------------------* * , . * *-----------------------------------------------------------------*/ /* , WinBorder */ void t_restore_corners(){ mvwaddch(panewin, LINES-3, 0, LEFT_JOIN); mvwaddch(panewin, LINES-3, COLS-2-BARWIDTH, RIGHT_JOIN); mvwaddch(panewin, LINES-5, 0, LEFT_JOIN); mvwaddch(panewin, LINES-5, COLS-2-BARWIDTH, RIGHT_JOIN); mvwaddch(panewin, 2, CENTER, TOP_JOIN); wattron (panewin, A_BOLD); mvwaddch(panewin, LINES-3, CENTER, BOTTOM_JOIN); mvwaddch(panewin, LINES-5, CENTER, MIDDLE_CROSS); wattroff(panewin, A_BOLD); } /* . * : , * */ void t_enter(Table *tbl){ WinBorder(tbl->win, tbl->bg_attrib, tbl->sel_attrib, CWD, BAR_VER|BAR_HOR, NO); t_restore_corners(); } /* */ void t_leave(Table *tbl){ TblDrawItem( tbl, tbl->current, NO, YES ); } /* , */ void t_border_common(){ WinBorder(panewin, A_tbl->bg_attrib, A_tbl->sel_attrib, A_dir->name, BAR_VER|BAR_HOR, NO); wattron (panewin, A_BOLD); whorline(panewin, LINES-3, 1, COLS-1-BARWIDTH-1); whorline(panewin, LINES-5, 1, COLS-1-BARWIDTH-1); wverline(panewin, CENTER, A_tbl->top, A_tbl->top + A_tbl->height+2); wattroff(panewin, A_BOLD); t_restore_corners(); } /* , */ int t_show(Table *tbl){ #ifdef FILF showMode(A_tbl, A_STANDOUT); showMode(B_tbl, A_STANDOUT); #endif return 1; } void t_scrollbar(Table *tbl, int whichbar, int n, int among){ WinScrollBar(tbl->win, BAR_VER|BAR_HOR, n, among, "Yes", tbl->bg_attrib); #ifdef FILF showMode(tbl, A_REVERSE); #endif } /* */ int t_hit[] = { '\t', KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(8), ' ', '+', '-', ctrl('R'), ctrl('L'), ctrl('F'), -1 }; Info t_info[] = { { "TAB ", 0}, { "F1 ", 0}, { "F2 ", 0}, { "F3 ", 0}, { "F4 ", 0}, { "F8 ", 0}, { " ", 0}, { "+ ", 0}, { "- ", 0}, { "ctrl/R ", 0}, { "ctrl/L ",0}, { "ctrl/F ", 0}, { NULL, 0} }; int t_help(){ static Menu mth; int c = 0; if( mth.items == NULL ){ mth.items = t_info; mth.title = " "; mth.top = 3; mth.left = COLS/6; mth.bg_attrib = A_STANDOUT; mth.sel_attrib = A_REVERSE; MnuInit (&mth); mth.hotkeys = t_hit; } c = MnuUsualSelect(&mth, 0); /* , . : * mth.hotkeys = NULL; (.. malloc()-) * MnuDeinit(&mth); */ MnuHide(&mth); if( M_REFUSED(&mth)) return 0; /* */ return t_hit[c]; /* , */ } int t_handler (Table *tbl, int c, HandlerReply *reply){ int i, cnt=0; extern int unlink(), rmdir(); char *answer; FileWidget *wd = TblFW (tbl); switch(c){ case '\t': /* */ ExchangePanes(); *reply = HANDLER_OUT; return LEAVE_KEY; /* */ case KEY_F(1): *reply = HANDLER_NEWCHAR; return t_help(); case KEY_F(2): (void) Edit(tbl->win, T_ITEMF(tbl, tbl->current, 0), RUNCMD); break; case KEY_F(3): cd(".." , wd, CWD); break; case KEY_F(4): if(answer = help(" , ",CHDIR)) cd(answer , wd, CWD); break; case ctrl('R'): break; case KEY_F(8): for(i=0; i < tbl->nitems; i++) if(T_TST(tbl, i, M_LABEL)){ int code; cnt++; if((code = (T_TST(tbl, i, I_DIR) ? rmdir : unlink) (T_ITEMF(tbl, i,0))) < 0) T_SET(tbl, i, M_HATCH); } if(cnt==0) help(" ", NORUN); break; case '+': if(answer = help(" ", TAG)) TblTagAll(tbl, answer, T_LABEL); break; case '-': if(answer = help(" ", TAG)) TblUntagAll(tbl, answer, T_LABEL); break; case ctrl('L'): /* "disk usage" */ diskUsage(); break; case ctrl('F'): /* */ findFile(wd); break; case ' ': /* */ editAccessModes(wd); break; } *reply = HANDLER_OUT; return REPEAT_KEY; /* */ } /* . */ int SelectPane(FileWidget *wd){ Table *tbl = & wd->t; DirContents *d = & wd->d; int sel, retcode = 0; RaiseWin( tbl->win ); /* , CWD */ if(mychdir( d->name ) < 0) checkBothPanes(); /* t_enter( tbl ); /* , */ for(;;){ /* , */ checkBothPanes(); if((sel = TblUsualSelect( tbl )) == TOTAL_NOSEL ){ current_menu = SEL_PULL; goto out; } if( T_REFUSED(tbl)) break; /* ESC */ if( tbl->key == LEAVE_KEY ){ retcode=1; break; } strcpy(SELECTION, T_ITEMF(tbl, sel, 0)); if( tbl->key == REPEAT_KEY ) continue; if(T_TST(tbl, sel, I_DIR)){ /* */ /* */ cd(SELECTION, wd, CWD); } else if(T_TST(tbl, sel, I_EXE)){ /* */ (void) Edit(tbl->win, SELECTION, RUNCMD); } else { editAccessModes(wd); /* * ( * , ). * runCommand( classify(SELECTION)); * - , * - ( ) * ( " "). */ } } /* end for */ t_leave( tbl ); out: if( !retcode ) current_menu = SEL_PULL; /* ESC */ return retcode; } /*-----------------------------------------------------------------* * ( ESC). * *-----------------------------------------------------------------*/ PullInfo pm_items [] = { /* */ {{ " \\Left ", 0 }, NULL, "Left pane" }, /* 0 */ {{ " \\Commands ", 0 }, &mwrk, "Do some commands"}, /* 1 */ {{ " \\Tools ", PM_NOSEL }, NULL, "" }, /* 2 */ {{ " \\Sorttype ", 0 }, &msort, "Change sort type"}, /* 3 */ {{ " \\Right ", 0 }, NULL, "Right pane" }, /* 4 */ {{ NULL, 0 }, NULL, NULL } }; void p_help(PullMenu *p, int n, int among){ Message( PM_NOTE(p, n)); } /* - */ void SelectPullMenu(){ int c, sel; Menu *m; for(;current_menu == SEL_PULL;){ c = PullUsualSelect(&pull); sel = pull.current; if( PM_REFUSED(&pull)){ current_menu = previous_menu; return;} switch(sel){ case 0: current_menu = SEL_PANE1; return; case 1: SelectWorkingMenu(c); return; case 2: return; /* */ case 3: SelectSortType(c); return; case 4: current_menu = SEL_PANE2; return; } } } /*-----------------------------------------------------------------* * . * *-----------------------------------------------------------------*/ void die(int sig){ echo(); nocbreak(); mvcur(-1,-1,LINES-1,0); refresh(); endwin (); putchar('\n'); if(sig) printf("Signal %d\n", sig); if(sig == SIGSEGV) abort(); else exit(sig); } void main (void) { setlocale(LC_ALL, ""); /* */ initscr (); /* curses */ signal(SIGINT, die); /* die(); */ signal(SIGBUS, die); /* */ signal(SIGSEGV,die); refresh(); /* : */ noecho(); cbreak(); /* , */ /* */ HistInit(&hcwd, 20); hcwd. mnu.title = " "; HistInit(&hedit, 20); hedit.mnu.title = " "; HistInit(&hpat, 8); hpat. mnu.title = " "; /* */ msort.items = sort_info; msort.title = " "; msort.top = 1; msort.left = 2; msort.showMe = sort_show; msort.bg_attrib = A_NORMAL; msort.sel_attrib = A_STANDOUT; /* MnuInit (&msort); pull-menu */ /* */ mwrk.items = mwrk_info; mwrk.title = " "; mwrk.top = 1; mwrk.left = COLS/3; mwrk.handler = NULL; mwrk.hitkeys = NULL; mwrk.bg_attrib = A_STANDOUT; mwrk.sel_attrib = A_REVERSE; mwrk.scrollBar = m_help; #ifdef __GNUC__ mwrk_init(); #endif /* MnuInit (&mwrk); pull-menu */ /* */ tpane1.t.width = CENTER - 1; tpane2.t.width = COLS - tpane1.t.width - 2 - (2 + BARWIDTH); tpane1.t.height = tpane2.t.height = (LINES - 8); tpane1.t.win = tpane2.t.win = panewin = stdscr; tpane1.t.left = 1; tpane2.t.left = CENTER+1; tpane1.t.top = tpane2.t.top = 3; tpane1.t.bg_attrib = tpane2.t.bg_attrib = A_NORMAL; tpane1.t.sel_attrib = tpane2.t.sel_attrib = A_STANDOUT; tpane1.t.scrollBar = tpane2.t.scrollBar = t_scrollbar; tpane1.t.hitkeys = tpane2.t.hitkeys = t_hit; tpane1.t.handler = tpane2.t.handler = t_handler; tpane1.t.showMe = tpane2.t.showMe = t_show; tpane1.t.hideMe = tpane2.t.hideMe = NULL; /* */ tpane1.d.name = strdup(" "); tpane2.d.name = strdup(" "); /* ( ) * cd(), .. * , */ t_border_common(); t_restore_corners(); /* */ mychdir("."); /* CWD[] */ /* CWD tpane1.d */ cd( CWD , &tpane1, CWD); tpane1.t.fmt = "directory"; InitTblFromDir(&tpane1, NO, NULL); /* */ tpane2.t.fmt = NULL; /* "/" tpane2.d */ cd( "/", &tpane2, CWD); /* */ /* */ cd( tpane1.d.name, &tpane1, CWD); /* */ TblDraw(A_tbl); TblDraw(B_tbl); /* pulldown */ pull.bg_attrib = A_REVERSE; pull.sel_attrib = A_NORMAL; pull.items = pm_items; pull.scrollBar = p_help; PullInit(&pull); /* */ for(done=NO, current_menu=SEL_PANE1, A_pane= &tpane1, B_pane= &tpane2; done == NO; ){ Message(""); if(SEL_PANE) previous_menu = current_menu; switch(current_menu){ case SEL_WRK : SelectWorkingMenu(NOSELECTED); break; case SEL_PULL: SelectPullMenu(); break; case SEL_PANE1: if( SelectPane(&tpane1) < 0) M_SET(&mwrk, 0, I_NOSEL); break; case SEL_PANE2: if( SelectPane(&tpane2) < 0) M_SET(&mwrk, 0, I_NOSEL); break; } } die(0); /* */ } /* 24 */ /* * (, pipes). * , * : * * stdout stdin * /------------ PIP1 -----------> cmd2 * cmd1 <----------PIP2---------------/ * stdin stdout */ /* LOOP_strt.c */ #include <stdio.h> #define eq(s1,s2) ( strcmp(s1,s2) == 0 ) /* , */ #define SEP "---" /* */ main( c, v ) char **v; { char **p, **q; int pid; int PIP1[2]; /* cmd1-->cmd2 */ int PIP2[2]; /* cmd2-->cmd1 */ if( c==1 ){ printf( "Call: strt cmd1... %s cmd2...\n", SEP ); exit(1); } /* */ v++; /* p - */ p = v; while( *v && !eq( *v, SEP )) v++; *v = NULL; v++; /* q - */ q = v; pipe( PIP1 ); /* */ pipe( PIP2 ); /* PIP[0] - , PIP[1] - */ if( pid = fork()){ /* : */ /* */ fprintf( stderr, "=%s pid=%d\n", p[0], getpid()); /* stdout PIP1 */ dup2( PIP1[1], 1 ); close( PIP1[1] ); /* */ close( PIP1[0] ); /* stdin PIP2 */ dup2( PIP2[0], 0 ); close( PIP2[0] ); /* */ close( PIP2[1] ); /* , * p[0] p (.. cmd1) */ execvp( p[0], p ); /* exec */ }else{ /* - */ fprintf( stderr, "=%s pid=%d\n", q[0], getpid()); /* stdout PIP2 */ dup2( PIP2[1], 1 ); close( PIP2[1] ); close( PIP2[0] ); /* stdin PIP1 */ dup2( PIP1[0], 0 ); close( PIP1[0] ); close( PIP1[1] ); /* cmd2 */ execvp( q[0], q ); } } /* , * . cmd2, * - cmd1. * strt, * strt cmd1 --- cmd2 * strt cmd2 --- cmd1 */ /* LOOP_p.c --------------------------------------------- * - (cmd1) */ #include <stdio.h> int trace = 1; /* */ main(c , v) char **v; { FILE *fp; int pid; char buf[128]; fprintf( stderr, "P: process pid=%d\n", getpid()); fp = fopen( "LOOP_p.c", "r" ); /* */ /* */ while( fgets( buf, sizeof buf, fp ) != NULL ){ if( trace ) fprintf( stderr, "P : %s", buf ); /* : PIP1 */ printf( "%s", buf ); fflush( stdout ); /* PIP2 */ fgets( buf, sizeof buf, stdin ); if( trace ) fprintf( stderr, "P : %s", buf ); } fclose( stdout ); /* PIP1. , * EOF */ while((pid = wait(NULL)) > 0 ) fprintf( stderr, "P: %d \n", pid ); } /* LOOP_q.c ------------------------------------------------ * - (cmd2) */ #include <stdio.h> int trace = 1; main(c , v) char **v; { char buf[128]; int pid; fprintf( stderr, "Q: process pid=%d\n", getpid()); /* PIP1 */ while( fgets( buf, sizeof(buf), stdin ) != NULL ){ /* */ if( trace ) fprintf( stderr, "Q : %s", buf ); if( trace ) fprintf( stderr, "Q : OK=%s", buf ); /* PIP2 */ printf( "OK=%s", buf ); fflush( stdout ); } fclose( stdout ); /* PIP2 */ while((pid = wait(NULL)) > 0 ) fprintf( stderr, "Q: %d \n", pid ); } /* 25 */ /* "" (pipes) FIFO- * * (FIFO - first in, first out : - ). * . .. */ /* P_packet.h --------------------------------------------*/ #include <sys/types.h> #include <sys/stat.h> /* S_IFIFO */ /* - */ struct packet { int pk_pid; /* - */ int pk_blk; /* , */ int pk_code; /* */ }; /* request codes ( ) */ #define RQ_READ 0 /* */ #define CONNECT 1 /* */ #define SENDPID 2 /* */ #define DISCONNECT 3 /* */ #define BYE 4 /* */ /* FIFO- */ #define DNAME "datapipe" #define CNAME "ctrlpipe" /* */ #define PBUFSIZE 512 /* P_client.c --------------------------------------------------------- */ /* * -, . */ #include <stdio.h> #include <signal.h> #include <fcntl.h> #include "P_packet.h" int datapipe, ctrlpipe; int got_sig; int mypid; /* - */ int spid; /* - */ /* waiting for signal */ #define WAITSIG while( !got_sig ) void handler(nsig){ signal( SIGUSR1, handler ); got_sig ++; } void init(){ extern void die(); /* */ while( (datapipe = open( DNAME, O_RDONLY | O_NDELAY )) < 0 ); while( (ctrlpipe = open( CNAME, O_WRONLY | O_NDELAY )) < 0 ); mypid = getpid(); /* my process identifier */ printf( "Client pid=%d started\n", mypid ); signal( SIGINT, die); signal( SIGQUIT, die); signal( SIGTERM, die); handler(0); } int canRun = 1; void die(nsig){ canRun = 0; } /* , pid */ connect(){ struct packet pk; pk.pk_pid = mypid; pk.pk_code = CONNECT; pk.pk_blk = (-1); got_sig = 0; write( ctrlpipe, &pk, sizeof pk ); /* */ /* -"" */ WAITSIG; /* */ read( datapipe, &pk, sizeof pk ); /* - */ kill( pk.pk_pid, SIGUSR1 ); return pk.pk_pid; } void disconnect(){ struct packet pk; pk.pk_pid = mypid; pk.pk_code = DISCONNECT; pk.pk_blk = (-1); got_sig = 0; write( ctrlpipe, &pk, sizeof pk ); /* send request */ /* wait for reply */ WAITSIG; /* receive reply */ read( datapipe, &pk, sizeof pk ); /* confirm */ kill( pk.pk_pid, SIGUSR1 ); printf( "Disconnected.\n" ); } request( ptr, blk, spid ) char *ptr; int blk; int spid; { struct packet pk; pk.pk_pid = mypid; pk.pk_blk = blk; pk.pk_code = RQ_READ; got_sig = 0; write( ctrlpipe, &pk, sizeof pk ); WAITSIG; read( datapipe, ptr, PBUFSIZE ); kill( spid, SIGUSR1 ); } bye(){ struct packet pk; pk.pk_pid = mypid; pk.pk_code = BYE; pk.pk_blk = (-1); got_sig = 0; write( ctrlpipe, &pk, sizeof pk ); /* send request */ exit(0); } /* client [_] */ main(argc, argv) char *argv[]; { int blk; char buffer[ PBUFSIZE ]; setbuf( stdout, NULL ); /* make unbuffered */ blk = (argv[1] ? atoi( argv[1] ) : 0); init(); spid = connect(); printf( "Client pid=%d connected to server pid=%d\n", mypid, spid ); /* -33 " * " */ if( blk == -33 ) bye(); /* blk */ while( canRun ){ request( buffer, blk, spid ); printf( "\nBEG-------------------------------------\n" ); fwrite( buffer, PBUFSIZE, 1, stdout );