source: neercs/trunk/src/main.c @ 4075

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