source: neercs/trunk/src/main.c

Last change on this file was 4366, checked in by Sam Hocevar, 10 years ago

Clean up source code, copyright information, author names, SVN keywords...

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