/* $Id: FvwmCommand.c,v 1.1.1.1 2006/11/26 10:53:10 matthieu Exp $ * $Source: /home/cvs/xenocara/app/fvwm/extras/FvwmCommand/Attic/FvwmCommand.c,v $ * * Fvwm2 command input interface. * * Copyright 1998, Toshi Isogai. * Use this program at your own risk. * Permission to use this program for any purpose is given, * as long as the copyright is kept intact. * */ #include "FvwmCommand.h" #define MYNAME "FvwmCommand" int Fdr, Fdw; /* file discriptor for fifo */ FILE *Frun; /* File contains pid */ char *Fr_name; int Pfd; char *getline(); fd_set fdset; struct timeval Tv; int Opt_reply; /* wait for replay */ int Opt_monitor; int Opt_info; int Opt_Serv; int Opt_flags; FILE *Fp; int Rc; /* return code */ int Bg; /* FvwmCommand in background */ void err_msg( char *msg ); void err_quit( char *msg ); void sendit( char *cmd ); void receive( void ); void sig_ttin ( int ); void sig_pipe ( int ); void sig_quit ( int ); void usage(void); int read_f (int fd, char *p, int len); void close_fifos (void); void process_message( void ) ; void list( unsigned long *body, char *) ; void list_configure(unsigned long *body); void list_focus_change(unsigned long *body) ; void list_header(unsigned long *body, char *) ; void list_icon_loc(unsigned long *body) ; void list_iconify(unsigned long *body); void list_mini_icon(unsigned long *body) ; void list_new_desk(unsigned long *body) ; void list_new_page(unsigned long *body) ; void list_string (char *str); void spawn_child( void ); /******************************************************* * * send command to and receive message from the server * *******************************************************/ int main ( int argc, char *argv[]) { char cmd[MAX_COMMAND_SIZE]; char *home; char *f_stem, *fc_name, *fm_name; char *sf_stem; int i; int opt; int ncnt; int count; struct timeval tv2; extern char *optarg; extern int optind, opterr, optopt; signal (SIGINT, sig_quit); signal (SIGHUP, sig_quit); signal (SIGQUIT, sig_quit); signal (SIGTERM, sig_quit); signal (SIGTTIN, sig_ttin); signal (SIGTTOU, sig_ttin); Opt_reply = 0; Opt_info = 1; f_stem = NULL; sf_stem = NULL; Opt_monitor = 0; Opt_Serv = 0; Opt_flags = 2; Tv.tv_sec = 0; Tv.tv_usec = 500000; Rc = 0; Bg = 0; while( (opt = getopt( argc, argv, "S:hvF:f:w:i:rm" )) != EOF ) { switch(opt) { case 'h': usage(); exit(0); break; case 'f': f_stem = optarg; break; case 'F': Opt_flags = atoi (optarg); break; case 'S': sf_stem = optarg; Opt_Serv = 1; break; case 'i': Opt_info = atoi( optarg ); break; case 'v': printf("%s %s\n", MYNAME, MYVERSION ); exit(0); case 'w': Tv.tv_usec = atoi( optarg ) % 1000000; Tv.tv_sec = atoi( optarg ) / 1000000; break; case 'm': Opt_monitor = 1; break; case 'r': Opt_reply = 1; break; case '?': exit(3); } } if( f_stem == NULL ) { home = getenv("HOME"); f_stem = safemalloc( strlen(home)+ strlen(F_NAME) + 3); strcpy (f_stem, home); if (f_stem[strlen(f_stem)-1] != '/') { strcat (f_stem, "/"); } strcat (f_stem, F_NAME); } /* create 2 fifos */ fm_name = safemalloc( strlen(f_stem) + 2 ); strcpy(fm_name,f_stem); strcat(fm_name, "M"); fc_name = safemalloc( strlen(f_stem) + 2 ); strcpy(fc_name,f_stem); strcat(fc_name, "C"); Fr_name = safemalloc( strlen(f_stem) + 2 ); strcpy(Fr_name,f_stem); strcat(Fr_name, "R"); if ((Frun = fopen (Fr_name,"r" )) !=NULL) { if (fgets (cmd, 20, Frun) != NULL) { fprintf (stderr, "\nFvwmCommand lock file %sR is detected. " "This may indicate another FvwmCommand is running. " "It appears to be running under process ID:\n%s\n", f_stem, cmd ); fprintf (stderr, "You may either kill the process or run FvwmCommand " "with another FIFO set using option -S and -f. " "If the process doesn't exist, simply remove file:\n%sR\n\n", f_stem); exit(1); } fclose (Frun); unlink (Fr_name); } if( Opt_Serv ) { sprintf (cmd,"%s '%sS %s'", argv[0], MYNAME, sf_stem); system (cmd); } if ((Frun = fopen (Fr_name,"w" )) != NULL) { fprintf (Frun, "%d\n", (int) getpid()); fclose (Frun); }else { err_quit ("writing lock file"); } Fdr = Fdw = -1; count = 0; while ((Fdr=open (fm_name, O_RDONLY)) < 0) { if (count++>5) { err_quit ("opening message fifo"); } sleep(1); } count = 0; while ((Fdw=open (fc_name, O_WRONLY)) < 0) { if (count++>2) { err_quit ("opening command fifo"); } sleep(1); } strcpy (cmd, CMD_CONNECT); sendit (cmd); i = optind; if( Opt_monitor ) { /* test if its stdin is closed for coprocess */ tv2.tv_sec = 0; tv2.tv_usec = 5; FD_ZERO(&fdset); FD_SET(STDIN_FILENO, &fdset); ncnt = select(FD_SETSIZE,SELECT_TYPE_ARG234 &fdset, 0, 0, &tv2); if( ncnt && (fgets( cmd, 1, stdin )==0 || cmd[0] == 0)) { Bg = 1; } /* line buffer stdout for coprocess */ setvbuf( stdout, NULL, _IOLBF, 0); /* send arguments first */ for( ;i < argc; i++ ) { strncpy( cmd, argv[i], MAX_COMMAND_SIZE-2 ); sendit( cmd ); } while(1) { FD_ZERO(&fdset); FD_SET(Fdr, &fdset); if( Bg == 0 ) { FD_SET(STDIN_FILENO, &fdset); } ncnt = select(FD_SETSIZE,SELECT_TYPE_ARG234 &fdset, 0, 0, NULL); /* message from fvwm */ if (FD_ISSET(Fdr, &fdset)){ process_message(); } if( Bg == 0 ) { /* command input */ if( FD_ISSET(STDIN_FILENO, &fdset) ) { if( fgets( cmd, MAX_COMMAND_SIZE-2, stdin ) == 0 ) { if( Bg == 0 ) { /* other than SIGTTIN */ break; }else{ continue; } } sendit( cmd ); } } } }else { for( ;i < argc; i++ ) { strncpy( cmd, argv[i], MAX_COMMAND_SIZE-2 ); sendit( cmd ); receive(); } } close_fifos(); exit( Rc ); } /* * send exit notice and close fifos */ void close_fifos (void) { char cmd[10]; if (Fdw >= 0) { strcpy (cmd, CMD_EXIT); sendit (cmd); } close(Fdr); close(Fdw); unlink (Fr_name); } /****************************************** * signal handlers ******************************************/ void sig_quit (int dummy) { close_fifos(); err_msg("receiving signal\n" ); exit(1); } void sig_ttin( int dummy ) { Bg = 1; signal( SIGTTIN, SIG_IGN ); } /************************************/ /* print error message on stderr */ /************************************/ void err_quit( char *msg ) { fprintf (stderr, "%s ", strerror(errno)); err_msg(msg); close_fifos(); exit(1); } void err_msg( char *msg ) { fprintf( stderr, "%s error in %s\n", MYNAME , msg ); } /*************************************/ /* add cr to the command and send it */ /*************************************/ void sendit( char *cmd ) { int clen; if( cmd[0] != '\0' ) { clen = strlen(cmd); /* add cr */ if( cmd[clen-1] != '\n' ) { strcat(cmd, "\n"); clen++; } if( clen != 1 ) { write( Fdw, cmd, clen ); } } } void receive () { int ncnt; struct timeval tv; if( Opt_reply ) { /* wait indefinitely */ FD_ZERO(&fdset); FD_SET( Fdr, &fdset); ncnt = select(FD_SETSIZE, SELECT_TYPE_ARG234 &fdset, 0, 0, NULL); } while (1){ tv.tv_sec = Tv.tv_sec; tv.tv_usec = Tv.tv_usec; FD_ZERO(&fdset); FD_SET(Fdr, &fdset); ncnt = select(FD_SETSIZE, SELECT_TYPE_ARG234 &fdset, 0, 0, &tv); if( ncnt < 0 ) { err_quit("receive"); break; } if( ncnt == 0 ) { /* timeout */ break; } if (FD_ISSET(Fdr, &fdset)) { process_message(); } } } /******************************* * print usage *******************************/ void usage(void) { fprintf (stderr, "Usage: %s [OPTION] [COMMAND]...\n", MYNAME); fprintf (stderr, "Send commands to fvwm2 via %sS\n\n", MYNAME); fprintf (stderr, " -F 0 - no flag info\n"); fprintf (stderr, " 2 - full flag info (default)\n"); fprintf (stderr, " -S " "invoke another %s server with fifo \n", MYNAME); fprintf (stderr, " -f use fifo to connect to %sS\n", MYNAME); fprintf (stderr, " -i 0 - error only\n" ); fprintf (stderr, " 1 - above and config info (default)\n" ); fprintf (stderr, " 2 - above and static info\n" ); fprintf (stderr, " 3 - above and dynamic info\n" ); fprintf (stderr, " -m monitor fvwm2 message transaction\n"); fprintf (stderr, " -r " "wait for a reply (overrides waiting time)\n"); fprintf (stderr, " -v print version number\n"); fprintf (stderr, " -w waiting time for the reponse from fvwm\n"); fprintf (stderr, "\nDefault fifo names are ~/.%sC and ~/.%sM\n", MYNAME, MYNAME); fprintf (stderr, "Default waiting time is 500,000 us\n"); } /* * read fifo */ int read_f (int fd, char *p, int len) { int i, n; for (i=0; i= 1 ) { switch( type ) { case M_WINDOW_NAME: list( body, "window"); break; case M_ICON_NAME: list(body, "icon"); break; case M_RES_CLASS: list(body, "class" ); break; case M_RES_NAME: list(body, "resource"); break; case M_END_WINDOWLIST: list_string("end windowlist"); break; case M_ICON_FILE: list(body, "icon file"); break; case M_ICON_LOCATION: list_icon_loc(body); break; case M_END_CONFIG_INFO: list_string("end configinfo"); break; case M_DEFAULTICON: list(body, "default icon"); break; case M_MINI_ICON: list_mini_icon( body ); break; case M_CONFIG_INFO: printf( "%s", (char *)&body[3] ); break; default: if( Opt_info >=2 ) { switch(type) { case M_CONFIGURE_WINDOW: list_configure( body); break; case M_STRING: list(body, "string"); break; default: if( Opt_info >= 3 ) { switch( type ) { case M_NEW_PAGE: list_new_page(body); break; case M_NEW_DESK: list_new_desk(body); break; case M_ADD_WINDOW: list_header(body, "add"); list_configure( body); break; case M_RAISE_WINDOW: list_header(body, "raise"); break; case M_LOWER_WINDOW: list_header(body, "lower"); break; case M_FOCUS_CHANGE: list_focus_change( body ); break; case M_DESTROY_WINDOW: list_header(body, "destroy"); break; case M_ICONIFY: list_iconify( body ); break; case M_DEICONIFY: list_header(body, "deiconify"); break; case M_MAP: list_header(body, "map"); break; case M_WINDOWSHADE: list_header(body, "windowshade"); break; case M_DEWINDOWSHADE: list_header(body, "dewindowshade"); break; default: printf("0x%lx type 0x%lx\n", body[0], type ); } } } } } } } /********************************** * * print configuration info * **********************************/ void list_configure(unsigned long *body) { unsigned long i; char *flag; char *grav; char *flagstr[32] = { "StartIconic", "OnTop", "Sticky", "WindowListSkip", "SuppressIcon", "NoiconTitle", "Lenience", "StickyIcon", "CirculateSkipIcon", "CirculateSkip", "ClickToFocus", "SloppyFocus", "SkipMapping", "Handles", "Title", "Mapped", "Iconified", "Transient", "Raised", /* ??? */ "Visible", "IconOurs", "PixmapOurs", "ShapedIcon", "Maximized", "WmTakeFocus", "WmDeleteWindow", "IconMoved", "IconUnmapped", "MapPending", "HintOverride", "MWMButtons", "MWMBorders" }; printf( "0x%08lx %-20s x %ld, y %ld, width %ld, height %ld\n", body[0], "frame", body[3], body[4], body[5], body[6] ); printf( "0x%08lx %-20s %ld\n" ,body[0], "desktop", body[7]); if (Opt_flags == 2) { for( i=0; i<=31; i++ ) { if( body[8] & (1<