Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 

319 rindas
9.5 KiB

  1. /*
  2. * neercs console-based window manager
  3. * Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
  4. * 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
  5. * 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
  6. * All Rights Reserved
  7. *
  8. * This program is free software. It comes without any warranty, to
  9. * the extent permitted by applicable law. You can redistribute it
  10. * and/or modify it under the terms of the Do What The Fuck You Want
  11. * To Public License, Version 2, as published by Sam Hocevar. See
  12. * http://sam.zoy.org/wtfpl/COPYING for more details.
  13. */
  14. #if defined HAVE_CONFIG_H
  15. # include "config.h"
  16. #endif
  17. #if !defined _WIN32
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <unistd.h>
  22. #include <fcntl.h>
  23. #include <signal.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/types.h>
  26. #include <sys/wait.h>
  27. #include <sys/time.h>
  28. #include <time.h>
  29. #if !defined HAVE_GETOPT_LONG
  30. # include "mygetopt.h"
  31. #elif defined HAVE_GETOPT_H
  32. # include <getopt.h>
  33. #endif
  34. #if defined HAVE_GETOPT_LONG
  35. # define mygetopt getopt_long
  36. # define myoptind optind
  37. # define myoptarg optarg
  38. # define myoption option
  39. #endif
  40. #include <errno.h>
  41. #include <caca.h>
  42. #include "neercs.h"
  43. void version(void)
  44. {
  45. printf("%s\n", PACKAGE_STRING);
  46. printf("Copyright (C) 2006, 2008 Sam Hocevar <sam@zoy.org>\n");
  47. printf
  48. (" Jean-Yves Lamoureux <jylam@lnxscene.org>\n\n");
  49. printf
  50. ("This is free software. You may redistribute copies of it under the\n");
  51. printf
  52. ("terms of the Do What The Fuck You Want To Public License, Version 2\n");
  53. printf("<http://sam.zoy.org/wtfpl/>.\n");
  54. printf("There is NO WARRANTY, to the extent permitted by law.\n");
  55. printf("\n");
  56. printf
  57. ("For more informations, visit http://libcaca.zoy.org/wiki/neercs\n");
  58. }
  59. void usage(int argc, char **argv)
  60. {
  61. printf("%s\n", PACKAGE_STRING);
  62. printf("Usage : %s [command1] [command2] ... [commandN]\n", argv[0]);
  63. printf("Example : %s zsh top \n\n", argv[0]);
  64. printf("Options :\n");
  65. printf("\t--config\t-c <file>\t\tuse given config file\n");
  66. printf("\t--pid\t\t-P [pid]\t\tgrab process\n");
  67. printf("\t\t\t-r [session]\t\treattach to a detached neercs\n");
  68. printf
  69. ("\t\t\t-R [session]\t\treattach if possible, otherwise start a new session\n");
  70. printf("\t\t\t-S <name>\t\tname this session <name> instead of <pid>\n");
  71. printf("\t--lock-after\t-l [n]\t\t\tlock screen after n seconds\n");
  72. printf("\t--version\t-v \t\t\tdisplay version and exit\n");
  73. printf("\t--help\t\t-h \t\t\tthis help\n");
  74. }
  75. struct screen_list *init_neercs(int argc, char **argv)
  76. {
  77. struct screen_list *screen_list = NULL;
  78. int args;
  79. int mainret = -1;
  80. screen_list = create_screen_list();
  81. screen_list->sys.default_shell = getenv("SHELL");
  82. args = argc - 1;
  83. if (screen_list->sys.default_shell == NULL && args <= 0)
  84. {
  85. fprintf(stderr,
  86. "Environment variable SHELL not set and no arguments given. kthxbye.\n");
  87. free_screen_list(screen_list);
  88. return NULL;
  89. }
  90. if (handle_command_line(argc, argv, screen_list) < 0)
  91. {
  92. free_screen_list(screen_list);
  93. return NULL;
  94. }
  95. /* Read global configuration first */
  96. read_configuration_file("/etc/neercsrc", screen_list);
  97. /* Then local one */
  98. if (screen_list->sys.user_path)
  99. {
  100. read_configuration_file(screen_list->sys.user_path, screen_list);
  101. free(screen_list->sys.user_path);
  102. }
  103. if (screen_list->sys.attach)
  104. {
  105. if (screen_list->sys.nb_to_grab || screen_list->sys.to_start)
  106. {
  107. fprintf(stderr,
  108. "-R can not be associated with commands or pids!\n");
  109. free_screen_list(screen_list);
  110. return NULL;
  111. }
  112. attach(screen_list);
  113. if (screen_list->sys.forceattach && !screen_list->sys.attach)
  114. {
  115. free_screen_list(screen_list);
  116. return NULL;
  117. }
  118. }
  119. /* Build default session name */
  120. if (!screen_list->comm.session_name)
  121. {
  122. char mypid[32]; /* FIXME Compute the length of PID_MAX ? */
  123. snprintf(mypid, 31, "%d", getpid());
  124. mypid[31] = '\0';
  125. screen_list->comm.session_name = strdup(mypid);
  126. if (!screen_list->comm.session_name)
  127. {
  128. fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
  129. __LINE__);
  130. free_screen_list(screen_list);
  131. return NULL;
  132. }
  133. }
  134. if (!screen_list->comm.socket_path[SOCK_CLIENT])
  135. screen_list->comm.socket_path[SOCK_CLIENT] =
  136. build_socket_path(screen_list->comm.socket_dir,
  137. screen_list->comm.session_name, SOCK_CLIENT);
  138. if (!screen_list->comm.socket_path[SOCK_SERVER])
  139. screen_list->comm.socket_path[SOCK_SERVER] =
  140. build_socket_path(screen_list->comm.socket_dir,
  141. screen_list->comm.session_name, SOCK_SERVER);
  142. /* Fork the server if needed */
  143. if (!screen_list->sys.attach)
  144. {
  145. debug("Spawning a new server");
  146. if (start_server(screen_list))
  147. {
  148. free_screen_list(screen_list);
  149. return NULL;
  150. }
  151. if (start_client(screen_list))
  152. {
  153. free_screen_list(screen_list);
  154. return NULL;
  155. }
  156. }
  157. return screen_list;
  158. }
  159. int handle_command_line(int argc, char *argv[],
  160. struct screen_list *screen_list)
  161. {
  162. int s = 0, i;
  163. for (;;)
  164. {
  165. int option_index = 0;
  166. int pidopt;
  167. static struct myoption long_options[] = {
  168. {"config", 1, NULL, 'c'},
  169. #if defined USE_GRAB
  170. {"pid", 0, NULL, 'P'},
  171. #endif
  172. {"lock-after", 1, NULL, 'l'},
  173. {"help", 0, NULL, 'h'},
  174. {"version", 0, NULL, 'v'},
  175. {NULL, 0, NULL, 0},
  176. };
  177. #if defined USE_GRAB
  178. int c =
  179. mygetopt(argc, argv, "c:S:R::l::r::P::hv", long_options,
  180. &option_index);
  181. #else
  182. int c =
  183. mygetopt(argc, argv, "c:S:R::l::r::hv", long_options,
  184. &option_index);
  185. #endif
  186. if (c == -1)
  187. break;
  188. switch (c)
  189. {
  190. case 'c': /* --config */
  191. if (screen_list->sys.user_path)
  192. free(screen_list->sys.user_path);
  193. screen_list->sys.user_path = strdup(myoptarg);
  194. s += 2;
  195. break;
  196. case 'S':
  197. if (!screen_list->comm.session_name)
  198. screen_list->comm.session_name = strdup(myoptarg);
  199. s += 2;
  200. break;
  201. case 'P': /* --pid */
  202. if (myoptarg)
  203. {
  204. pidopt = atoi(myoptarg);
  205. if (pidopt <= 0)
  206. {
  207. fprintf(stderr, "Invalid pid %d\n", pidopt);
  208. if (screen_list->sys.to_grab)
  209. free(screen_list->sys.to_grab);
  210. return -1;
  211. }
  212. }
  213. else
  214. pidopt = select_process(screen_list);
  215. if (pidopt <= 0)
  216. {
  217. s += 1;
  218. break;
  219. }
  220. if (!screen_list->sys.to_grab)
  221. {
  222. /* At most argc-1-s times -P <pid> + final 0 */
  223. screen_list->sys.to_grab =
  224. (int *)malloc(((argc - 1 - s) / 2 + 1) * sizeof(int));
  225. if (!screen_list->sys.to_grab)
  226. {
  227. fprintf(stderr, "Can't allocate memory at %s:%d\n",
  228. __FUNCTION__, __LINE__);
  229. return -1;
  230. }
  231. }
  232. screen_list->sys.to_grab[screen_list->sys.nb_to_grab++] = pidopt;
  233. screen_list->sys.to_grab[screen_list->sys.nb_to_grab] = 0;
  234. s += 2;
  235. break;
  236. case 'l':
  237. screen_list->lock.autolock_timeout = atoi(myoptarg) * 1000000;
  238. if (screen_list->lock.autolock_timeout == 0)
  239. screen_list->lock.autolock_timeout -= 1;
  240. break;
  241. case 'r':
  242. screen_list->sys.forceattach = 1;
  243. case 'R':
  244. if (screen_list->sys.attach)
  245. {
  246. fprintf(stderr, "Attaching can only be requested once\n");
  247. return -1;
  248. }
  249. if (myoptarg)
  250. {
  251. if (screen_list->comm.session_name)
  252. free(screen_list->comm.session_name);
  253. screen_list->comm.session_name = strdup(myoptarg);
  254. s += 1;
  255. }
  256. screen_list->sys.attach = 1;
  257. s += 1;
  258. break;
  259. case 'h': /* --help */
  260. usage(argc, argv);
  261. return -1;
  262. break;
  263. case 'v': /* --version */
  264. version();
  265. return -1;
  266. break;
  267. case -2:
  268. return -1;
  269. default:
  270. fprintf(stderr, "Unknown argument #%d\n", myoptind);
  271. return -1;
  272. break;
  273. }
  274. }
  275. if (s >= 0 && s < argc - 1)
  276. {
  277. screen_list->sys.to_start = (char **)malloc((argc - s) * sizeof(char *));
  278. if (!screen_list->sys.to_start)
  279. {
  280. fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
  281. __LINE__);
  282. return -1;
  283. }
  284. for (i = 0; i < (argc - 1) - s; i++)
  285. {
  286. screen_list->sys.to_start[i] = strdup(argv[i + s + 1]);
  287. }
  288. screen_list->sys.to_start[argc - 1 - s] = NULL;
  289. }
  290. return s;
  291. }
  292. #endif