Changeset 2588
- Timestamp:
- Jul 27, 2008, 1:17:04 AM (14 years ago)
- Location:
- neercs/trunk/src
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
neercs/trunk/src/Makefile.am
r2509 r2588 4 4 neercs_SOURCES = neercs.h mygetopt.c recurrent.c main.c screens.c term.c \ 5 5 grab.c effects.c wm.c screensaver.c attach.c configuration.c \ 6 mytrace.c mytrace.h input.c lock.c 6 mytrace.c mytrace.h input.c lock.c server.c 7 7 neercs_CFLAGS = @CACA_CFLAGS@ 8 8 neercs_LDADD = @CACA_LIBS@ @UTIL_LIBS@ @PAM_LIBS@ -
neercs/trunk/src/attach.c
r2488 r2588 12 12 #include <sys/stat.h> 13 13 14 #include <caca.h> 15 14 16 #include "neercs.h" 15 17 16 staticchar * build_socket_path(char *socket_dir, char *session_name)18 char * build_socket_path(char *socket_dir, char *session_name) 17 19 { 18 20 char *path, *dir; … … 46 48 47 49 myaddr.sun_family = AF_UNIX; 48 screen_list->socket_path = build_socket_path(screen_list->socket_path, screen_list->session_name);49 50 strncpy(myaddr.sun_path, screen_list->socket_path, sizeof(myaddr.sun_path) - 1); 50 unlink(myaddr.sun_path);51 51 52 52 if(bind(sock, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_un)) < 0) … … 65 65 66 66 return 0; 67 }68 69 int detach(struct screen_list* screen_list, caca_display_t * dp)70 {71 int fd;72 int pid;73 74 screen_list->attached = 0;75 caca_free_display(dp);76 77 close(0);78 close(1);79 close(2);80 81 fd = open("/dev/null", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);82 dup2(fd, 0);83 if(fd != 0)84 close(fd);85 fd = open("/tmp/log.txt", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);86 dup2(fd, 1);87 dup2(fd, 2);88 if (fd > 2)89 close(fd);90 91 if(!screen_list->socket)92 {93 pid = fork();94 if (pid < 0)95 return 1;96 if (pid > 0)97 exit(0);98 99 create_socket(screen_list);100 setsid();101 }102 103 return 0;104 }105 106 static int handle_command(char * cmd, struct screen_list* screen_list, cucul_canvas_t * cv, caca_display_t ** dp)107 {108 int refresh = 0;109 debug("Received command %s", cmd);110 if(!strncmp("ENV ", cmd, 4))111 {112 putenv(strdup(cmd+4));113 }114 else if(!strncmp("ATTACH ", cmd, 7))115 {116 int fd;117 screen_list->attached = 1;118 close(screen_list->socket);119 screen_list->socket= 0;120 unlink(screen_list->socket_path);121 screen_list->socket_path = NULL;122 close(0);123 fd=open(cmd+7, O_RDWR);124 dup2(fd, 0);125 close(1);126 fd=open(cmd+7, O_RDWR);127 dup2(fd, 1);128 close(2);129 fd=open(cmd+7, O_RDWR);130 dup2(fd, 2);131 *dp = caca_create_display(cv);132 if(*dp)133 {134 caca_set_cursor(*dp, 1);135 refresh = 1;136 }137 }138 else139 {140 fprintf(stderr, "Unknown command received: %s\n", cmd);141 }142 return refresh;143 }144 145 int read_socket(struct screen_list* screen_list, cucul_canvas_t * cv, caca_display_t ** dp) {146 ssize_t n;147 char buf[4097];148 int refresh = 0;149 150 if(!screen_list->socket)151 return 0;152 153 while (screen_list->socket && (n = read(screen_list->socket, buf, sizeof(buf)-1)) > 0)154 {155 buf[n] = 0;156 refresh |= handle_command(buf, screen_list, cv, dp);157 }158 return refresh;159 67 } 160 68 … … 194 102 } 195 103 196 197 /* FIXME Is this really not defined anywhere ? */ 198 extern char **environ; 199 200 int request_attach(char *socket_path) 104 char * connect_server(char *socket_path, struct screen_list* screen_list) 201 105 { 202 106 int sock; 203 char fdstr[PATH_MAX], lnk[PATH_MAX];204 char buf[4096];205 107 struct sockaddr_un addr; 206 108 … … 210 112 if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { 211 113 perror("request_attach:socket"); 212 return 1;114 return NULL; 213 115 } 214 116 … … 219 121 { 220 122 printf("Failed to connect to %s: %s\n", socket_path, strerror(errno)); 221 return 1;123 return NULL; 222 124 } 125 fcntl(sock, F_SETFL, O_NONBLOCK); 223 126 224 debug("Sending environment", 0); 127 screen_list->socket_path = socket_path; 128 screen_list->socket = sock; 225 129 226 /* Send our environment */ 227 #define sendvar(var) if(getenv(var)) {snprintf(buf, 4096, "ENV %s=%s", var, getenv(var)); write(sock, buf, strlen(buf));} 228 sendvar("DISPLAY") 229 sendvar("CACA_DRIVER") 130 return strdup(socket_path); /* FIXME */ 131 } 230 132 231 snprintf(fdstr, sizeof(fdstr), "/proc/%d/fd/0", getpid()); 232 readlink(fdstr, lnk, sizeof(lnk)-1); 233 lnk[PATH_MAX-1] = '\0';133 int request_attach(struct screen_list* screen_list) 134 { 135 debug("Requesting attach"); 234 136 235 close(0);137 write(screen_list->socket, "ATTACH", strlen("ATTACH")); 236 138 237 debug("Requesting attach to %s", lnk); 139 return 0; 140 } 238 141 239 /* Request attaching */ 240 snprintf(buf, 4096, "ATTACH %s", lnk); 241 write(sock, buf, strlen(buf)); 242 close(sock); 142 int send_event(caca_event_t ev, int sock) 143 { 144 enum caca_event_type t; 243 145 244 debug("Exiting", 0); 245 exit(0); 146 t = caca_get_event_type(&ev); 147 148 if(t & CACA_EVENT_KEY_PRESS) 149 { 150 char buf[16]; 151 int bytes; 152 bytes = snprintf(buf, sizeof(buf)-1, "KEY %d", caca_get_event_key_ch(&ev)); 153 buf[bytes] = '\0'; 154 debug("Sending key press to server: %s", buf); 155 return write(sock, buf, strlen(buf)) <= 0; 156 } 157 else if(t & CACA_EVENT_RESIZE) 158 return write(sock, "RESIZE", strlen("RESIZE")) <= 0; 159 else if(t & CACA_EVENT_QUIT) 160 return write(sock, "QUIT", strlen("QUIT")) <= 0; 161 162 return 0; 246 163 } 164 -
neercs/trunk/src/input.c
r2581 r2588 136 136 case 'd': 137 137 case 0x04: //CACA_KEY_CTRL_D: 138 detach(screen_list , screen_list->dp);138 detach(screen_list); 139 139 break; 140 140 } -
neercs/trunk/src/main.c
r2581 r2588 81 81 struct screen_list *screen_list = NULL; 82 82 struct passwd *user_info; 83 char *user_path = NULL, *user_dir = NULL , *session_name = NULL;83 char *user_path = NULL, *user_dir = NULL; 84 84 int i, args, s=0; 85 int eof = 0, refresh = 1, command = 0;85 int refresh = 1; 86 86 long long unsigned int last_key_time = 0; 87 87 int mainret = 0; 88 88 int attach = 0, forceattach = 0; 89 89 int *to_grab = NULL; 90 char **to_start = NULL; 90 91 int nb_to_grab = 0; 91 92 … … 159 160 break; 160 161 case 'S': 161 if(screen_list->session_name) 162 free(screen_list->session_name); 163 screen_list->session_name = strdup(myoptarg); 162 if(!screen_list->session_name) 163 screen_list->session_name = strdup(myoptarg); 164 164 s+=2; 165 165 break; … … 175 175 if(!to_grab) 176 176 { 177 /* At most argc-1-s times -P <pid> */178 to_grab = (int *)malloc(((argc-1-s)/2 )*sizeof(int));177 /* At most argc-1-s times -P <pid> + final 0 */ 178 to_grab = (int *)malloc(((argc-1-s)/2+1)*sizeof(int)); 179 179 if(!to_grab) 180 180 { … … 184 184 } 185 185 to_grab[nb_to_grab++] = pidopt; 186 to_grab[nb_to_grab] = 0; 186 187 s+=2; 187 188 break; … … 196 197 if(myoptarg) 197 198 { 198 session_name = strdup(myoptarg); 199 if(screen_list->session_name) 200 free(screen_list->session_name); 201 screen_list->session_name = strdup(myoptarg); 199 202 s+=1; 200 203 } … … 217 220 } 218 221 222 if(s < argc - 1) 223 { 224 to_start = (char**)malloc((argc-s)*sizeof(char*)); 225 if(!to_start) 226 { 227 fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__); 228 return -1; 229 } 230 for(i=0; i<(argc-1) - s; i++) 231 { 232 to_start[i] = strdup(argv[i+s+1]); 233 } 234 to_start[argc-1-s] = NULL; 235 } 236 219 237 /* Read global configuration first */ 220 238 read_configuration_file("/etc/neercsrc", screen_list); … … 235 253 return -1; 236 254 } 237 sockets = list_sockets(screen_list->socket_dir, session_name); 238 if(!screen_list->session_name) 239 screen_list->session_name = session_name; 240 else 241 free(session_name); 255 sockets = list_sockets(screen_list->socket_dir, screen_list->session_name); 242 256 if(sockets && sockets[0]) 243 257 { 244 request_attach(sockets[0]); 245 fprintf(stderr, "Failed to attach!\n"); 258 char *session; 259 for(i=0; sockets[i]; i++); 260 i--; 261 session = connect_server(sockets[i], screen_list); 262 if(session) 263 { 264 request_attach(screen_list); 265 if(screen_list->session_name) 266 free(screen_list->session_name); 267 screen_list->session_name = session; 268 } 269 else 270 { 271 fprintf(stderr, "Failed to attach!\n"); 272 attach = 0; 273 } 246 274 for(i=0; sockets[i]; i++) 247 275 free(sockets[i]); … … 251 279 { 252 280 fprintf(stderr, "No socket found!\n"); 253 } 254 if(forceattach) 281 attach = 0; 282 } 283 if(forceattach && !attach) 255 284 return -1; 256 285 } … … 268 297 return -1; 269 298 } 299 } 300 301 /* Fork the server if needed */ 302 if(!attach) 303 { 304 pid_t pid; 305 306 screen_list->socket_path = build_socket_path(screen_list->socket_path, screen_list->session_name); 307 308 pid = fork(); 309 if(pid < 0) 310 { 311 fprintf(stderr, "Failed to create child process\n"); 312 return -1; 313 } 314 if(pid == 0) 315 { 316 int fd; 317 close(0); 318 close(1); 319 close(2); 320 fd = open("/dev/null", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); 321 dup2(fd, 0); 322 #ifndef DEBUG 323 dup2(fd, 1); 324 dup2(fd, 2); 325 if (fd > 2) 326 close(fd); 327 #else 328 if(fd != 0) 329 close(fd); 330 fd = open("/tmp/log.txt", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); 331 dup2(fd, 1); 332 dup2(fd, 2); 333 if (fd > 2) 334 close(fd); 335 #endif 336 setsid(); 337 return server_main(to_grab, to_start, screen_list); 338 } 339 340 free(connect_server(screen_list->socket_path, screen_list)); 270 341 } 271 342 … … 276 347 return 1; 277 348 caca_set_cursor(screen_list->dp, 1); 278 279 349 screen_list->width = cucul_get_canvas_width(screen_list->cv); 280 350 screen_list->height = cucul_get_canvas_height(screen_list->cv) - ((screen_list->mini*6) + (screen_list->status)); 281 351 282 if(nb_to_grab == 0 && s == argc -1)283 {284 add_screen(screen_list,285 create_screen(screen_list->width,286 screen_list->height,287 screen_list->default_shell));288 }289 290 /* Attach processes */291 for(i=0; i<nb_to_grab; i++)292 {293 add_screen(screen_list,create_screen_grab(screen_list->width, screen_list->height, to_grab[i]));294 }295 free(to_grab);296 297 /* Launch command line processes */298 for(i=0; i<(argc-1) - s; i++)299 {300 add_screen(screen_list, create_screen(screen_list->width, screen_list->height, argv[i+s+1]));301 }302 303 /* Windows are in a temporary state, resize them to the right dimensions */304 update_windows_props(screen_list);305 306 352 last_key_time = get_us(); 307 353 … … 310 356 caca_event_t ev; 311 357 int ret = 0; 312 313 /* Read program output */ 314 refresh |= update_screens_contents(screen_list); 315 316 /* If screen was attached, read its output */ 317 refresh |= read_socket(screen_list, screen_list->cv, &screen_list->dp); 318 319 /* No more screens, exit */ 320 if(!screen_list->count) break; 321 322 /* Update each screen canvas */ 323 refresh |= update_terms(screen_list); 324 325 /* Get events, if any */ 326 if(screen_list->attached) 327 ret = caca_get_event(screen_list->dp, CACA_EVENT_ANY, &ev, 0); 328 else 329 sleep(1); 330 331 if(ret && (caca_get_event_type(&ev) & CACA_EVENT_KEY_PRESS)) 332 { 333 unsigned int c = caca_get_event_key_ch(&ev); 334 char *str = NULL; 335 int size = 0; 336 /* CTRL-A has been pressed before, handle this as a 337 * command, except that CTRL-A a sends literal CTRL-A */ 338 if(command && (c != 'a')) 339 { 340 command = 0; 341 refresh |= handle_command_input(screen_list, c); 342 } 343 else 344 { 345 /* Not in command mode */ 346 last_key_time = get_us(); 347 caca_set_cursor(screen_list->dp, 1); 348 349 /* Kill screensaver */ 350 if(screen_list->in_screensaver) 351 { 352 screensaver_kill(screen_list); 353 screen_list->in_screensaver = 0; 354 refresh = 1; 355 continue; 356 } 357 /* Handle lock window */ 358 if(screen_list->locked) 359 refresh |= update_lock(c, screen_list); 360 else 361 { 362 switch(c) 363 { 364 case 0x01: //CACA_KEY_CTRL_A: 365 command = 1; break; 366 case CACA_KEY_ESCAPE: 367 if(screen_list->help) 368 { 369 screen_list->help = 0; 370 refresh = 1; 371 break; 372 } 373 default: 374 /* CTRL-A a sends literal CTRL-A */ 375 if (command && (c == 'a')) 376 { 377 c = 0x01; 378 } 379 /* Normal key, convert it if needed */ 380 str = convert_input_ansi(&c, &size); 381 write(screen_list->screen[screen_list->pty]->fd, str, size); 382 break; 383 } 384 } 385 } 386 } 387 /* Window resized */ 388 else if(ret && (caca_get_event_type(&ev) & CACA_EVENT_RESIZE)) 389 { 390 update_windows_props(screen_list); 391 cucul_clear_canvas(screen_list->cv); 392 refresh = 1; 393 } 394 /* Window closed */ 395 else if(ret && (caca_get_event_type(&ev) & CACA_EVENT_QUIT)) 396 { 397 refresh = 1; 398 break; 399 } 400 401 /* Launch reccurents if any */ 402 refresh |= handle_recurrents(screen_list); 403 404 /* Resfresh screen */ 405 if(!screen_list->attached) 406 { 407 /* No need to refresh */ 408 } 409 /* Draw lock window */ 410 else if(screen_list->locked) 411 { 412 draw_lock(screen_list); 413 refresh = 1; 414 } 415 else 416 { 417 if((refresh || screen_list->in_bell) && 418 (get_us() - last_key_time < screen_list->screensaver_timeout)) 419 { 420 refresh_screens(screen_list); 421 if(screen_list->screen[screen_list->pty]->title) 422 caca_set_display_title(screen_list->dp, screen_list->screen[screen_list->pty]->title); 423 else 424 caca_set_display_title(screen_list->dp, PACKAGE_STRING); 425 refresh = 1; 426 427 } 428 if((get_us() - last_key_time > screen_list->screensaver_timeout)) 429 { 430 if(!screen_list->in_screensaver) 431 screensaver_init(screen_list); 432 screen_list->in_screensaver = 1; 433 434 caca_set_cursor(screen_list->dp, 0); 435 draw_screensaver(screen_list); 436 refresh = 1; 437 } 438 439 if((get_us() - last_key_time > screen_list->autolock_timeout)) 440 { 441 screen_list->locked = 1; 442 refresh = 1; 443 } 444 445 } 446 447 /* Refresh screen if needed */ 448 if(refresh) 449 { 450 caca_refresh_display(screen_list->dp); 451 refresh = 0; 452 } 453 454 eof = 1; 455 for(i=0; i < screen_list->count; i++) 456 if(screen_list->screen[i]->fd >= 0) 457 eof = 0; 458 if(eof) 358 ssize_t n; 359 char buf[4097]; 360 361 while (screen_list->socket && (n = read(screen_list->socket, buf, sizeof(buf)-1)) > 0) 362 { 363 buf[n] = 0; 364 debug("Received from server: %s", buf); 365 if(!strncmp("DETACH", buf, 6)) 366 { 367 ret = 1; 368 break; 369 } 370 else if(!strncmp("REFRESH", buf, 7)) 371 { 372 /* FIXME update the canvas first */ 373 caca_refresh_display(screen_list->dp); 374 } 375 else if(!strncmp("CURSOR ", buf, 7)) 376 { 377 caca_set_cursor(screen_list->dp, atoi(buf+7)); 378 } 379 else if(!strncmp("TITLE ", buf, 6)) 380 { 381 caca_set_display_title(screen_list->dp, buf+6); 382 caca_refresh_display(screen_list->dp); 383 } 384 } 385 if(ret) 386 break; 387 388 ret = caca_get_event(screen_list->dp, CACA_EVENT_ANY, &ev, 100000); 389 if(ret) 390 ret = send_event(ev, screen_list->socket); 391 392 if(ret) 459 393 break; 460 394 } … … 472 406 473 407 if(screen_list->socket_path) { 474 unlink(screen_list->socket_path);475 408 free(screen_list->socket_path); 476 409 } … … 510 443 return mainret; 511 444 } 512 513 514 445 515 446 … … 566 497 return screen_list; 567 498 } 568 569 570 571 long long get_us(void)572 {573 struct timeval tv;574 gettimeofday(&tv, NULL);575 return (tv.tv_sec*(1000000) + tv.tv_usec);576 } -
neercs/trunk/src/neercs.h
r2582 r2588 216 216 long long get_us(void); 217 217 218 int detach(struct screen_list* screen_list, caca_display_t * dp); 219 int request_attach(char *socket_path); 218 int detach(struct screen_list* screen_list); 219 int request_attach(struct screen_list* screen_list); 220 char * build_socket_path(char *socket_dir, char *session_name); 220 221 int create_socket(struct screen_list* screen_list); 221 int read_socket(struct screen_list* screen_list, cucul_canvas_t * cv, caca_display_t ** dp);222 char * connect_server(char *socket_path, struct screen_list* screen_list); 222 223 char ** list_sockets(char *socket_dir, char *session_name); 224 int server_main(int *to_grab, char **to_start, struct screen_list *screen_list); 225 int send_event(caca_event_t ev, int sock); 223 226 224 227 /* Screens management */
Note: See TracChangeset
for help on using the changeset viewer.