k() * , * dst (errno==EEXIST). */ if( link( src, dst ) < 0 ) return FAILED; unlinkd( src, typefrom ); /* */ return OK; } } /* link() - * , . */ int mcopy(char *src, char *dst, unsigned typefrom, unsigned typeto) { if( typefrom == S_IFDIR ) return FAILED; /* , * ( ) . */ return docopy( src, dst, typefrom, typeto ); } /* */ int domove(char *src, char *dst, unsigned typefrom, unsigned typeto) { switch( typefrom ){ default: if( ! mlink( src, dst, typefrom, typeto)){ if( ! mcopy( src, dst, typefrom, typeto)){ printf( "Can't move %s\n", src ); return FAILED; } else unlinkd( src, typefrom ); /* */ } break; case S_IFDIR: /* */ if( ! strcmp( ".", basename(src))){ printf( "impossible to move directory \".\"\n" ); return FAILED; } if( ! mlink( src, dst, typefrom, typeto )){ if( errno == EXDEV ) printf( "No cross device directory links\n" ); return FAILED; } break; case ECANTSTAT: printf( "%s does not exist\n", src ); return FAILED; } return OK; /* okay */ } int docpmv( char *src, /* - */ char *dst, /* - */ struct ftype typeto, /* - */ int cp, /* 0 - , 1 - */ int *confirm /* ? */ ){ struct ftype typefrom; /* */ char namebuf[BUFSIZ]; /* ( ) */ typefrom = filetype(src); if(typefrom.type == ECANTSTAT){ /* */ printf("%s does not exist.\n", src); return FAILED; } if( typefrom.type != S_IFDIR && typeto.type == S_IFDIR ){ /* dst */ sprintf(namebuf, "%s/%s", dst, basename(src)); typeto = filetype(dst = namebuf); } if(typefrom.dev == typeto.dev && typefrom.ino == typeto.ino){ /* */ printf("%s and %s are identical.\n", src, dst); return OK; /* - */ } /* , * */ if(*confirm && typeto.type == S_IFREG){ char answer[40]; printf("%s already exists. Overwrite (y/n/all) ? ", dst); fflush(stdout); switch( *gets(answer)){ case 'n': default: return OK; /* */ case 'y': break; case 'a': *confirm = NO; /* - */ break; } } return cp ? docopy(src, dst, typefrom.type, typeto.type) : domove(src, dst, typefrom.type, typeto.type) ; } void main(int argc, char *argv[]) { char *cmd; int cp, i, err, confirm = YES; struct ftype typeto; /* - */ if( argc < 3 ) { printf( "Usage: %s source... destination\n", argv[0] ); exit(1); /* */ } /* . */ cmd = basename( argv[0] ); if ( !strcmp( cmd, CP )) cp = 1; else if( !strcmp( cmd, MV )) cp = 0; else{ printf( "%s - wrong program name.\n", cmd ); exit(2); } typeto = filetype( argv[argc-1] ); if(cp && typeto.type != S_IFDIR && typeto.type != S_IFBLK && typeto.type != S_IFCHR && argc > 3){ printf("Group of files can be copied " "to the directory or device only.\n"); exit(3); } if(!cp && typeto.type != S_IFDIR && argc > 3){ printf("Group of files can be moved " "to the directory only.\n"); exit(4); } for(err=0, i=1; i < argc-1; i++) err += ! docpmv(argv[i], argv[argc-1], typeto, cp, &confirm); exit(err); /* 0, */ } /* 13 */ /* MS DOS . * ls -R UNIX. * find . -print ( find, match()) */ #define STYLE2 #include <stdio.h> #include <stdlib.h> #include <dir.h> #include <dos.h> #include <alloc.h> /* malloc() */ #include <string.h> /* strchr(), strrchr(), strcpy(), ... */ /* */ char *strend(char *s); char *strdup(const char *s); void action(int, char **); void main(int, char **); int listdir(char *); void printdir(int n); #ifdef STYLE2 void lookdir(char *s, int ac, char **av, register int level); #else void lookdir(char *s, int ac, char **av); #endif char root[256]; /* */ char cwd[256]; /* */ char *strend(register char *s){ while(*s)s++; return s; } char *strdup(const char *s){ /* malloc <stdlib.h> */ char *p = (char *) malloc(strlen(s) + 1); if(p) strcpy(p, s); return p; } stop(){ /* control/break */ chdir( root ); /* , MS DOS ( UNIX) " " . , , . */ printf( "\nInterrupted by ctrl-break\n"); return 0; /* exit */ } void main(int argc, char **argv){ /* */ (void) getcwd(root, sizeof root); ctrlbrk( stop ); /* ctrl/break */ #ifndef STYLE2 lookdir( "." /* */, argc, argv ); #else /* : "\\" "." */ lookdir( "\\", argc, argv, 0 /* */ ); #endif /*STYLE2*/ chdir(root); /* . */ } # ifndef STYLE2 void lookdir(char *s, int ac, char **av){ static int level = 0; /* */ # else void lookdir(char *s, int ac, char **av, register int level){ # endif /*STYLE2*/ struct ffblk dblk, *psd = &dblk; register done; if( chdir(s) < 0 ){ /* */ printf( "Cannot cd %s\n", s ); return; } else if (level == 0){ /* */ (void) getcwd(cwd, sizeof cwd); /* */ } action(ac, av); /* , "*" */ /* ( !) */ done = findfirst("*.", psd, FA_DIREC); while( !done ){ if((psd->ff_attrib & FA_DIREC) && psd->ff_name[0] != '.' ){ /* : ! */ char *tail = strend(cwd); char *addplace; if( tail[-1] == '\\' ){ addplace = tail; }else{ *tail = '\\'; addplace = tail+1; } strcpy(addplace, psd->ff_name); #ifndef STYLE2 level++; lookdir( psd->ff_name, ac, av ); level--; #else lookdir( psd->ff_name, ac, av, level+1 ); #endif *tail = '\0'; } /* . , * , dblk */ done = findnext(psd); } if( level ) chdir( ".." ); /* */ } /* */ void action(int ac, char **av){ extern int busy; busy = 0; if( ac == 1 ) listdir( "*.*" ); else{ av++; while( *av ) listdir( *av++ ); } printdir( busy ); } #define MAXF 400 struct fst{ char *name; long size; short attr; } files[MAXF]; int busy; /* */ /* , . */ int listdir( char *picture ){ int done, n; struct ffblk dentry; for(n=0, done=findfirst(picture, &dentry,0xFF /* */); busy < MAXF && !done ; done = findnext( &dentry )){ files[busy].name = strdup(dentry.ff_name); files[busy].size = dentry.ff_fsize; files[busy].attr = dentry.ff_attrib; n++; busy++; } return n; } /* int cmp(struct fst *a, struct fst *b) */ /* : */ int cmp(const void *a, const void *b){ return strcmp(((struct fst *) a) -> name, ((struct fst *) b) -> name ); } /* */ void printdir(int n){ register i; struct fst *f; qsort( files, n, sizeof files[0], cmp ); printf( "Directory %s\n", cwd ); for( i=0, f = files; i < n; i++, f++ ) printf("\t%-16s\t%10ld\t%c%c%c%c%c%c\n", f->name, f->size, f->attr & FA_DIREC ? 'd':'-', /* directory */ f->attr & FA_RDONLY ? 'r':'-', /* read only */ f->attr & FA_HIDDEN ? 'h':'-', /* hidden */ f->attr & FA_SYSTEM ? 's':'-', /* system */ f->attr & FA_LABEL ? 'l':'-', /* volume label */ f->attr & FA_ARCH ? 'a':'-' /* archive */ ), free(f->name); putchar('\n'); } /* 14 */ /* longjmp/setjmp */ /* . .. */ #include <stdio.h> #include <fcntl.h> #include <signal.h> #include <setjmp.h> /*#define IGN*/ /* */ jmp_buf cs_stack; /* control point */ int in_cs; /* , */ int sig_recd; /* signal received */ /* */ Delay(){ int i; for( i=0; i < 10000; i++ ){ i += 200; i -= 200; } } interrupt( code ){ fprintf( stderr, "\n\n***\n" ); fprintf( stderr, "*** (%s)\n", code == 1 ? "" : "" ); fprintf( stderr, "***\n\n" ); } /* - ( ) */ void mexit( nsig ){ fprintf( stderr, "\n #%d...\n\n", nsig ); exit(0); } void main(){ extern void sig_vec(); int code; int killable = 1; signal( SIGINT, mexit ); signal( SIGQUIT, mexit ); fprintf( stderr, " INTR\n" ); fprintf( stderr, " QUIT\n\n\n" ); fprintf( stderr, " ...\n\n" ); Delay(); Delay(); Delay(); for(;;){ if( code = setjmp( cs_stack )){ /* 0, * longjmp( cs_stack, code ); code != 0 */ interrupt( code ); /* */ } /* else setjmp() 0, * ( * SP, PC cs_stack), * . */ signal( SIGINT, sig_vec ); /* */ if( killable ){ killable = 0; fprintf( stderr, "\7 INTR \n\n\n" ); } body(); /* */ } } body(){ static int n = 0; int i; fprintf( stderr, "\t %d- \n", ++n ); ecs(); for( i=0; i < 10 ; i++ ){ fprintf( stderr, "- %d\n",i); Delay(); } lcs(); for( i=0; i < 10 ; i++ ){ fprintf( stderr, "+ %d\n",i); Delay(); } } /* */ void sig_vec(nsig){ if( in_cs ){ /* we're in critical section */ #ifdef IGN signal( SIGINT, SIG_IGN ); /* */ fprintf( stderr, " \n" ); #else signal( SIGINT, sig_vec ); fprintf( stderr, " \n" ); #endif fprintf( stderr, " \n" ); sig_recd++ ; /* signal received */ /* , */ }else{ signal( SIGINT, sig_vec ); fprintf( stderr, " : \n" ); longjmp( cs_stack, 1); } } ecs(){ /* enter critical section */ fprintf( stderr, " \n" ); sig_recd = 0; in_cs = 1; } lcs(){ /* leave critical section */ fprintf( stderr, " \n" ); in_cs = 0; if( sig_recd ){ fprintf( stderr, " , .. (%d )\n", sig_recd ); sig_recd = 0; signal( SIGINT, sig_vec ); longjmp( cs_stack, 2); } } /* 15 */ /* (baud).*/ /* XENIX: baud /dev/tty1a 9600 */ /* /dev/tty1a - . #1 */ /* man termio */ #include <fcntl.h> #include <termio.h> struct termio old, new; int fd = 2; /* stderr */ struct baudrate{ int speed; char *name;} br[] = { { B0, "HANGUP" }, { B1200, "1200" }, { B9600, "9600" }, { B600, "600" }, { B2400, "2400" }, { EXTA, "19200" }, }; #define RATES (sizeof br/sizeof br[0]) main(ac, av) char *av[]; { register i; char *newbaud; if( ac == 3 ){ if((fd = open(av[1], O_RDWR)) < 0 ){ printf(" %s\n", av[1]); exit(1); } newbaud = av[2]; } else newbaud = av[1]; if( ioctl(fd, TCGETA, &old) < 0 ){ printf(" .\n"); exit(2); } if(newbaud == (char*)0) newbaud = "< >"; new=old; for(i=0; i < RATES; i++) if((old.c_cflag & CBAUD) == br[i].speed) goto ok; printf(" \n"); exit(3); ok: printf(" %s \n", br[i].name); for(i=0; i < RATES; i++) if( !strcmp(newbaud, br[i].name)){ new.c_cflag &= ~CBAUD; /* "" B... */ new.c_cflag |= br[i].speed; if( ioctl(fd, TCSETA, &new) < 0) perror("ioctl"); /* , * ( ). */ exit(0); } printf(" %s\n", newbaud); exit(4); } /* 16 */ /*#!/bin/cc -DUSG wins.c -o wins -lncurses -lx . . */ /* _______________________ wcur.h __________________________ */ #include "curses.h" /* , curses */ /* : */ # define wcols(w) ((w)-> _maxx+1 ) # define wlines(w) ((w)-> _maxy+1 ) /* : */ # define wbegx(w) ((w)-> _begx ) # define wbegy(w) ((w)-> _begy ) /* : */ # define wcurx(w) ((w)-> _curx ) # define wcury(w) ((w)-> _cury ) /* : */ # define wtext(w) ((w)-> _line) /* chtype **_line; */ /* : ((w)-> _y) */ /* : curses IBM PC MS DOS */ #define HOR_LINE '\200' /* 196 */ #define VER_LINE '\201' /* 179 */ #define UPPER_LEFT '\210' /* 218 */ #define LOWER_LEFT '\202' /* 192 */ #define UPPER_RIGHT '\212' /* 191 */ #define LOWER_RIGHT '\204' /* 217 */ #define LEFT_JOIN '\205' /* 195 */ #define RIGHT_JOIN '\207' /* 180 */ #define TOP_JOIN '\211' /* 194 */ #define BOTTOM_JOIN '\203' /* 193 */ #define MIDDLE_CROSS '\206' /* 197 */ #define BOX '\272' /* 219 */ #define BOX_HATCHED '\273' /* 177 */ #define LABEL '\274' /* 3 */ #define RIGHT_TRIANG '\234' /* 16 */ #define LEFT_TRIANG '\235' /* 17 */ #define YES 1 #define NO 0 #define MIN(a,b) (((a) < (b)) ? (a):(b)) #define MAX(a,b) (((a) > (b)) ? (a):(b)) #define A_ITALICS A_ALTCHARSET /* curses- - */ #ifndef ESC # define ESC '\033' /* escape */ #endif #define ctrl(c) (c & 037) /* */ #define RedrawScreen() { vidattr(curscr->_attrs = A_NORMAL); \ wrefresh(curscr); } /* curscr - - * - newscr. * _attrs , * wattrset(), wattron(), wattroff(); */ /* _______________________ wins.c __________________________ */ #include "wcur.h" #include <signal.h> WINDOW *wbase1, *wbase2; /* ( ) */ WINDOW *w1, *w2; /* */ /* */ /* COLS - : */ /* LINES - // - : */ #define W1ysize (LINES/2) /* */ #define W1xsize (COLS/3*2) /* */ #define W1y 5 /* y */ #define W1x 20 /* x */ #define W2ysize (LINES/2) #define W2xsize (COLS/3*2) #define W2y 10 #define W2x 5 FILE *fp1, *fp2; /* */ /* */ void die(sig){ /* - */ /* */ echo(); /* - */ nocbreak(); /* */ mvcur( -1, -1, LINES-1, 0 ); /* . */ endwin(); /* curses- */ putchar('\n'); exit(sig); /* sig. 0 - */ } int run; void stop(nsig){ signal(SIGINT, SIG_IGN); run = 0; beep(); } char label[3][5] = { /* */ { UPPER_LEFT, TOP_JOIN, UPPER_RIGHT, HOR_LINE, '\0' }, { LEFT_JOIN, MIDDLE_CROSS, RIGHT_JOIN, VER_LINE, '\0' }, { LOWER_LEFT, BOTTOM_JOIN, LOWER_RIGHT, BOX, '\0' } }; /* , */ wborder( w, name ) WINDOW *w; char *name; { register i, j; for(i=1; i < wlines(w)-1; i++ ){ /* */ mvwaddch(w, i, 0, VER_LINE ); /* mvwaddch(w,y,x,c) = wmove(w,y,x); waddch(w,c); */ /* wmove(w,y,x) - . (y,x) */ /* waddch(w,c) - , . putchar */ mvwaddch(w, i, wcols(w)-1, VER_LINE ); } for(j=1; j < wcols(w)-1; j++ ){ mvwaddch(w, 0, j, HOR_LINE ); mvwaddch(w, wlines(w)-1, j, HOR_LINE ); } /* */ mvwaddch(w, 0, 0, UPPER_LEFT); mvwaddch(w, wlines(w)-1, 0, LOWER_LEFT); mvwaddch(w, wlines(w)-1, wcols(w)-1, LOWER_RIGHT); mvwaddch(w, 0, wcols(w)-1, UPPER_RIGHT); /* . * . */ if( (j = (wcols(w) - strlen(name))/2 ) > 0 ){ /* - 0 , j */ wmove(w, 0, j); /* */ wattrset( w, A_BOLD | A_BLINK | A_REVERSE ); waddstr( w, name ); /* */ wmove( w, wlines(w)-1, j); wattrset( w, A_ITALICS | A_STANDOUT ); waddstr ( w, name ); wattrset( w, A_NORMAL ); /* */ } } /* */ int mode = 0; /* 0 - , 1 - */ main( ac, av ) char **av; { char buffer[512]; int need1, need2; int c; void (*save)(); WINDOW *w; /* */ if( ac < 3 ){ fprintf( stderr, ": %s file1 file2\n", av[0] ); exit( 1 ); } if((fp1 = fopen( av[1], "r" )) == NULL ){ fprintf( stderr, " %s\n", av[1] ); exit( 2 ); } if((fp2 = fopen( av[2], "r" )) == NULL ){ fprintf( stderr, " %s\n", av[2] ); exit( 2 ); } /* curses */ initscr(); signal( SIGINT, die ); /* ctrl/C - */ signal( SIGQUIT,die ); /* */ /* Y X . */ wbase1 = newwin( W1ysize, W1xsize, W1y, W1x); if( wbase1 == NULL ){ fprintf( stderr, " wbase1\n" ); goto bad; } wbase2 = newwin( W2ysize, W2xsize, W2y, W2x); if( wbase2 == NULL ){ fprintf( stderr, " wbase2\n" ); goto bad; } /* */ /* Y X */ w1 = subwin( wbase1, W1ysize - 2, W1xsize - 2, W1y+1, W1x+1); w2 = subwin( wbase2, W2ysize - 2, W2xsize - 2, W2y+1, W2x+1); scrollok( w1, TRUE ); /* */ scrollok( w2, TRUE ); wattrset( w2, A_REVERSE ); /* */ wattrset( stdscr, A_STANDOUT ); wborder( wbase1, av[1] ); wborder( wbase2, av[2] ); /* */ werase( w1 ); werase( w2 ); /* */ /* */ werase( stdscr ); /* w... stdscr ( ) */ for(c=0; c < 3; c++) mvwaddstr(stdscr, c, COLS-5, &label[c][0]); move( 1, 10 ); addstr( "F1 - " ); mvaddstr( 2, 10, "F5 - /" ); move( 3, 10 ); printw( "F%d - , F%c - ", 7, '8' ); mvwprintw(stdscr, 4,10, "ESC - , CTRL/C - "); /* wprintw(w, fmt, ...) - printf */ /* : * * . */ wattrset( stdscr, A_NORMAL ); wmove( stdscr, LINES-1, COLS-1 ); waddch( stdscr, ' ' ); wnoutrefresh( stdscr ); /* . */ run = need1 = need2 = 1; /* */ /* CTRL/C */ save = signal(SIGINT, stop); while( run && (need1 || need2)){ if( need1 ){ /* */ if( fgets( buffer, sizeof buffer, fp1 ) == NULL ) need1 = 0; /* */ else{ /* */ waddstr( w1, buffer ); } } if( need2 ){ /* */ if( fgets( buffer, sizeof buffer, fp2 ) == NULL ) need2 = 0; /* */ else{ waddstr( w2, buffer ); /* wnoutrefresh( w2 ); */ } } /* w1 w2 */ touchwin( wbase2 ); wnoutrefresh( wbase2 ); touchwin( w2 ); wnoutrefresh( w2 ); touchwin( wbase1 ); wnoutrefresh( wbase1 ); touchwin( w1 ); wnoutrefresh( w1 ); /* touchwin - . * wnoutrefresh - * . */ /* * ( ). * * ( ). */ doupdate(); } fclose(fp1); fclose(fp2); /* */ signal(SIGINT, save); /* */ noecho(); /* . - */ cbreak(); /* * ( \n) */ keypad( w1, TRUE ); /* . */ keypad( w2, TRUE ); scrollok( w1, FALSE ); /* */ w = w1; /* */ for( ;; ){ int y, x; /* */ wrefresh( w ); /* . * wnoutrefresh(w);doupdate(); */ c = wgetch( w ); /* */ /* , noecho() * ! */ getyx( w, y, x ); /* */ /* &y &x, .. , */ switch( c ){ case KEY_LEFT: /* */ waddch( w, '\b' ); break; case KEY_RIGHT: /* */ wmove( w, y, x+1 ); break; case KEY_UP: /* */ wmove( w, y-1, x ); break; case KEY_DOWN: /* */ wmove( w, y+1, x ); break; case KEY_HOME: /* */ case KEY_LL: /* KEY_END */ { int xbeg, xend; wbegend(w, &xbeg, &xend); wmove(w, y, c==KEY_HOME ? xbeg : xend); break; } case '\t': /* */ x += 8 - (x % 8); if( x >= wcols( w )) x = wcols(w)-1; wmove(w, y, x); break; case KEY_BACKTAB: /* */ x -= 8 - (x % 8); if( x < 0 ) x = 0; wmove( w, y, x ); break; case '\b': /* */ case KEY_BACKSPACE: case '\177': if( !x ) break; /* */ wmove( w, y, x-1 ); /* and fall to ... ( ) */ case KEY_DC: /* */ wdelch( w ); break; case KEY_IC: /* */ winsch( w, ' ' ); break; case KEY_IL: case KEY_F(8): /* */ winsertln( w ); break; case KEY_DL: /* */ case KEY_F(7): wdeleteln( w ); break; case ESC: /* ESC - */ goto out; case KEY_F(1): /* */ if( w == w1 ){ touchwin( wbase2 ); wnoutrefresh( wbase2 ); touchwin( w2 ); wnoutrefresh( w2 ); w = w2; } else { touchwin( wbase1 ); wnoutrefresh( wbase1 ); touchwin( w1 ); wnoutrefresh( w1 ); w = w1; } break; case KEY_F(5): /* */ mode = ! mode; break; case ctrl('A'): /* */ RedrawScreen(); break; case '\n': case '\r': waddch( w, '\n' ); break; default: /* */ if( c >= 0400 ){ beep(); /* */ break; /* . - */ } if( mode ){ winsch( w, ' ' ); /* */ } waddch( w, c ); /* */ break; } } out: wrefresh( w ); wsave(w); bad: die(0); /* */ } /* , */ wsave(w) WINDOW *w; { FILE *fp = fopen("win.out", "w"); register int x,y, lastnospace; int xs, ys; getyx(w, ys, xs); for( y=0; y < wlines(w); y++ ){ /* */ for( lastnospace = (-1), x=0; x < wcols(w); x++ ) /* (x,y) */ if((mvwinch(w,y,x) & A_CHARTEXT) != ' ' ) lastnospace = x; /* */ for( x=0 ; x <= lastnospace; x++ ){ wmove(w,y,x); putc( winch(w) & A_CHARTEXT, fp ); } putc( '\n', fp ); } fclose(fp); wmove(w, ys, xs ); /* */ } /* * winch(w) = wtext(w)[ wcury(w) ][ wcurx(w) ]; * , * ( , .. curses * ). */ /* */ int wbegend(w, xbeg, xend) WINDOW *w; int *xbeg, *xend; { /* chtype: 0xFF - ; 0xFF00 - */ chtype ch, *thisline = wtext(w)[ wcury(w) ]; register x, notset = TRUE; *xbeg = *xend = 0; for(x=0; x < wcols(w); x++) /* & A_CHARTEXT */ if(((ch=thisline[x]) & A_CHARTEXT) != ' '){ if((*xend = x+1) >= wcols(w)) *xend = wcols(w) - 1; if(notset){ notset = FALSE; *xbeg=x; } } return (*xend - *xbeg); } /* 17 */ /* Window management: "" * cc -DTEST -DUSG w.c -lncurses -lx * *____ w.h 17, 19, 21, 23 _____ */ #include "wcur.h" /* , 16 */ extern int botw, topw; extern struct WindowList { /* */ WINDOW *w; /* */ int next; /* */ char busy; /* 0: , 1: , -1: */ } wins[]; /* busy: */ #define W_VISIBLE 1 /* */ #define W_FREE 0 /* */ #define W_HIDDEN (-1) /* */ #define EOW (-1) #define WIN(n) wins[n].w /* ... */ #define TOPW (topw != EOW ? WIN(topw) : stdscr) #define BOTW (botw == EOW ? stdscr : WIN(botw)) #define MAXW 15 #define iswindow(n) wins[n].busy int RaiseWin (WINDOW *w); void PopWin (); void DestroyWin(WINDOW *w, int destroy); int HideWin (WINDOW *w); #define KillWin(w) DestroyWin(w, TRUE) #define DropWin(w) DestroyWin(w, FALSE) #define PushWin(w) RaiseWin(w) #define BAR_HOR 01 /* scroll bar */ #define BAR_VER 02 /* scroll bar */ #define DX 2 /* */ #define BARWIDTH 2 /* scroll bar- */ #define BARHEIGHT 1 /* */ /* */ #define WY(title, y) ((y) + (title ? 3 : 1)) #define WX(x) ((x) + 1 + DX) #define XEND(w,scrollok) (wcols(w)-((scrollok & BAR_VER) ? BARWIDTH+2 : 1)) void whorline (WINDOW *w, int y, int x1, int x2); void wverline (WINDOW *w, int x, int y1, int y2); void wbox (WINDOW *w, int x1, int y1, int x2, int y2); void wborder (WINDOW *w); void wboxerase (WINDOW *w, int x1, int y1, int x2, int y2); void WinBorder (WINDOW *w, int bgattrib, int titleattrib, char *title, int scrollok, int clear); void WinScrollBar(WINDOW *w, int whichbar, int n, int among, char *title, int bgattrib); /* / */ typedef struct { int x, y; } Point; #define SetPoint(p, yy, xx) { (p).x = (xx); (p).y = (yy);} #define GetBack(p, w) wmove((w), (p).y, (p).x) /* _______________________ w.c _____________________________ */ /* */ /* ______________________________________________________________ */ #include "w.h" int botw = EOW, topw = EOW; /* */ struct WindowList wins[MAXW]; /* */ /* , ( ) */ int WinGetch (WINDOW *win) { register n, dorefr = YES; if(botw != EOW) for(n=botw; n != EOW; n=wins[n].next) if(wins[n].w == win){ if(wins[n].busy == W_HIDDEN) dorefr = NO; /* */ break; } if( dorefr ) wrefresh (win); /* */ else doupdate (); for(;;){ n = wgetch (win); /* */ if( n == ctrl('A')){ RedrawScreen(); continue; } return n; } } /* */ static void ComputeTopWin(){ register n; if(botw == EOW) topw = EOW; /* */ else{ /* */ for(topw = EOW, n=botw; n != EOW; n=wins[n].next) /* */ if( wins[n].busy == W_VISIBLE) topw = n; /* ; * topw == EOW, botw != EOW. TOPW * stdscr */ } } /* */ static void WinRefresh(){ register nw; /* */ touchwin(stdscr); wnoutrefresh(stdscr); if(botw != EOW) for(nw=botw; nw != EOW; nw=wins[nw].next) if(wins[nw].busy == W_VISIBLE){ touchwin(wins[nw].w); wnoutrefresh(wins[nw].w); } } /* */ static int WinDelList(WINDOW *w){ register nw, prev; if(botw == EOW) return EOW; /* */ for(prev=EOW, nw=botw; nw != EOW; prev=nw, nw=wins[nw].next) if(wins[nw].w == w){ if(prev == EOW) botw = wins[nw].next; /* */ else wins[prev].next = wins[nw].next; return nw; /* */ } return EOW; /* */ } /* , - */ int RaiseWin(WINDOW *w){ int nw, n; if((nw = WinDelList(w)) == EOW){ /* */ for(nw=0; nw < MAXW; nw++) /* */ if( !iswindow(nw)){ wins[nw].w = w; break; } if(nw == MAXW){ beep(); return EOW; } /* */ } /* nw */ if(botw == EOW) botw = nw; else{ for(n = botw; wins[n].next != EOW; n=wins[n].next); wins[n].next = nw; } wins[nw].busy = W_VISIBLE; /* , */ wins[topw = nw].next = EOW; WinRefresh(); return nw; } /* () */ /* */ void DestroyWin(WINDOW *w, int destroy){ int nw; if((nw = WinDelList(w)) != EOW){ /* */ ComputeTopWin(); wins[nw].busy = W_FREE; /* */ wins[nw].w = NULL; } if(destroy) delwin(w); /* curses- */ WinRefresh(); } void PopWin(){ KillWin(TOPW); } /* , . */ int HideWin(WINDOW *w){ register nw, prev; if(botw == EOW) return EOW; /* */ for(prev = EOW, nw = botw; nw != EOW; prev = nw, nw = wins[nw].next ) if(wins[nw].w == w){ wnoutrefresh(w); /* untouchwin(w); */ wins[nw].busy = W_HIDDEN; /* */ if( nw != botw ){ wins[prev].next = wins[nw].next; /* */ wins[nw].next = botw; botw = nw; /* */ } WinRefresh(); ComputeTopWin(); return nw; } return EOW; /* */ } /* _______________ _____________________ */ /* */ void whorline(WINDOW *w, int y, int x1, int x2){ for( ; x1 <= x2; x1++) mvwaddch(w, y, x1, HOR_LINE); } /* */ void wverline(WINDOW *w, int x, int y1, int y2){ for( ; y1 <= y2; y1++) mvwaddch(w, y1, x, VER_LINE); } /* */ void wbox(WINDOW *w, int x1, int y1, int x2, int y2){ whorline(w, y1, x1+1, x2-1); whorline(w, y2, x1+1, x2-1); wverline(w, x1, y1+1, y2-1); wverline(w, x2, y1+1, y2-1); /* */ mvwaddch (w, y1, x1, UPPER_LEFT); mvwaddch (w, y1, x2, UPPER_RIGHT); mvwaddch (w, y2, x1, LOWER_LEFT); /* ! */ if(! (wbegx(w) + x2 == COLS-1 && wbegy(w) + y2 == LINES-1)) mvwaddch (w, y2, x2, LOWER_RIGHT); } /* */ void wborder(WINDOW *w){ wbox(w, 0, 0, wcols(w)-1, wlines(w)-1); } /* */ void wboxerase(WINDOW *w, int x1, int y1, int x2, int y2){ int x, y; register i, j; getyx(w, y, x); for(i=y1; i <= y2; ++i) for(j=x1; j <= x2; j++) mvwaddch(w, i, j, ' '); wmove(w, y, x); } /* */ void WinBorder (WINDOW *w, int bgattrib, int titleattrib, char *title, int scrollok, int clear){ register x, y; wattrset (w, bgattrib); /* */ if(clear) werase(w); /* */ wborder (w); /* */ if (title) { /* ... */ for (x = 1; x < wcols (w) - 1; x++){ wattrset(w, bgattrib); mvwaddch (w, 2, x, HOR_LINE); /* */ wattrset(w, titleattrib); mvwaddch (w, 1, x, ' '); } wattrset(w, bgattrib); mvwaddch (w, 2, 0, LEFT_JOIN); mvwaddch (w, 2, wcols (w) - 1, RIGHT_JOIN); wattrset (w, A_BOLD | titleattrib); mvwaddstr(w, 1, (wcols(w)-strlen(title))/2, title); wattrset (w, bgattrib); } if (scrollok & BAR_VER) { /* scroll bar. */ int ystart = WY(title, 0), xend = XEND(w, scrollok); for (y = ystart; y < wlines (w) - 1; y++) mvwaddch (w, y, xend, VER_LINE); mvwaddch (w, wlines (w)-1, xend, BOTTOM_JOIN); mvwaddch (w, ystart-1, xend, TOP_JOIN); } /* */ if(wcols(w)==COLS && wlines(w)==LINES){ wattrset(w, A_NORMAL); mvwaddch(w, LINES-1, COLS-1, ' '); } wattrset (w, bgattrib); } /* scroll bar ( ) */ /* */ void WinScrollBar(WINDOW *w, int whichbar, int n, int among, char *title, int bgattrib){ register y, i; int starty = WY(title, 0); int endy = wlines (w) - 1; int x = XEND(w, whichbar) + 1; int height = endy - starty ; if(whichbar & BAR_VER){ /* */ wattrset (w, A_NORMAL); for (y = starty; y < endy; y++) for (i = 0; i < BARWIDTH; i++) mvwaddch (w, y, x + i, ' '); y = starty; if(among > 1) y += ((long) (height - BARHEIGHT) * n / (among - 1)); wattron(w, A_BOLD); for (i = 0; i < BARWIDTH; i++) mvwaddch (w, y, x + i, BOX); wattrset(w, bgattrib | A_BOLD ); if( wcols(w) >= 10 ) mvwprintw(w, 0, wcols(w)-9, "%03d/%03d", n+1, among); } wattrset (w, bgattrib); } #ifdef TEST main(){ WINDOW *w[5]; register i, y; initscr(); /* curses */ w[0] = newwin(16, 20, 4, 43); /* 5 */ w[1] = newwin(12, 20, 7, 34); w[2] = newwin(6, 30, 3, 40); w[3] = newwin(7, 35, 12, 38); w[4] = newwin(6, 20, 11, 54); for(i=0; i < 5; i++){ keypad (w[i], TRUE); wattrset(w[i], A_REVERSE); werase(w[i]); wborder (w[i]); mvwprintw(w[i], 1, 2, "Window %d", i); RaiseWin(w[i]); /* */ } noecho(); cbreak(); /* */ for(;botw != EOW;){ int c; /* */ for(i=botw, y=0; y < 5; y++, i=(i==EOW ? EOW : wins[i].next)) mvprintw(8 - y, 5, i==EOW ? "~": "%d%c", i, wins[i].busy == W_HIDDEN ? 'h':' '); mvprintw(9, 5, "topw=%3d botw=%3d", topw, botw); wnoutrefresh(stdscr); /* . */ c = WinGetch(TOPW); /* doupdate(); * */ switch(c){ case KEY_DC: PopWin(); break; case KEY_IC: KillWin(BOTW); break; case '0': case '1': case '2': case '3': case '4': case '5': c -= '0'; if( !iswindow(c)){ beep(); break; } RaiseWin(WIN(c)); break; case 'D': KillWin(w[2]); break; case 'h': HideWin(BOTW); break; case 'H': HideWin(TOPW); break; case ESC: goto out; default: waddch(TOPW, c & 0377); break; } } mvaddstr(LINES-2, 0, " "); refresh(); out: echo(); nocbreak(); endwin(); } #endif /* 18 */ /* _______________________ glob.h ___________________________*/ /* */ /* ______________________________________________________________ */ #define FILF #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> # define DIR_SIZE 14 extern char *malloc(unsigned); char *strdup(const char *str); extern char *getenv(); extern char *strchr(char *, char), *strrchr(char *, char); #define ISDIR(mode) ((mode & S_IFMT) == S_IFDIR) #define ISDEV(mode) ((mode & S_IFMT) & (S_IFCHR|S_IFBLK)) #define ISREG(mode) ((mode & S_IFMT) == S_IFREG) #define ISEXE(mode) ((mode & S_IFMT) == S_IFREG && (mode & 0111)) #define isdir(st) ISDIR(st.st_mode) #define isdev(st) ISDEV(st.st_mode) #define isreg(st) ISREG(st.st_mode) #define isexe(st) ISEXE(st.st_mode) #define YES 1 #define NO 0 #define I_DIR 0x01 /* */ #define I_EXE 0x02 /* */ #define I_NOSEL 0x04 /* */ #define I_SYS (I_DIR | I_EXE | I_NOSEL) /* treemk.c * #include "glob.h" treemk.c */ #define FAILURE (-1) /* */ #define SUCCESS 1 /* */ #define WARNING 0 /* */ typedef struct _info { /* */ char *s; /* */ short fl; /* */ union _any{ int (*act)(); /* */ char *note; /* */ unsigned i; /* - */ struct _info *inf; } any; /* */ #ifdef FILF /* , stat(); */ long size; int uid, gid; unsigned short mode; #endif } Info; typedef union _any Any; extern Info NullInfo; #define MAX_ARGV 256 /* */ typedef struct { /* name */ time_t lastRead; /* */ Info *files; /* */ char *name; /* */ ino_t ino; dev_t dev; /* I- */ char valid; /* */ short readErrors; /* != 0, */ } DirContents; /* */ typedef enum { SORT_ASC, SORT_DESC, SORT_SUFX, SORT_NOSORT, SORT_SIZE } Sort; extern Sort sorttype; extern int in_the_root; int gcmps (const void *p1, const void *p2); Info *blkcpy(Info *v); void blkfree(Info *v); Info *glob(char **patvec, char *dirname); Info *glb(char *pattern, char *dirname); int ReadDir(char *dirname, DirContents *d); struct savech{ char *s, c; }; #define SAVE(sv, str) (sv).s = (str); (sv).c = *(str) #define RESTORE(sv) if((sv).s) *(sv).s =