source: trunk/tools/neercs/old/main.c @ 1656

Last change on this file since 1656 was 1656, checked in by sam, 8 years ago

neercs: start porting the old code to Windows; this breaks the Visual Studio
build until further fixes are made.

  • Property svn:keywords set to Id
File size: 9.7 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#if defined HAVE_CONFIG_H
16#   include "config.h"
17#endif
18
19#if !defined _WIN32
20
21#include <stdio.h>
22#include <string.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <signal.h>
27#include <sys/ioctl.h>
28#include <sys/types.h>
29#include <sys/wait.h>
30#include <sys/time.h>
31#include <time.h>
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
84#if 0
85int main(int argc, char **argv)
86{
87    struct screen_list *screen_list = init_neercs(argc, argv);
88    if (!screen_list)
89        return -1;
90
91    mainloop(screen_list);
92}
93#endif
94
95struct screen_list *init_neercs(int argc, char **argv)
96{
97    struct screen_list *screen_list = NULL;
98    int args;
99
100    int mainret = -1;
101
102    screen_list = create_screen_list();
103    screen_list->sys.default_shell = getenv("SHELL");
104
105    args = argc - 1;
106    if (screen_list->sys.default_shell == NULL && args <= 0)
107    {
108        fprintf(stderr,
109                "Environment variable SHELL not set and no arguments given. kthxbye.\n");
110        free_screen_list(screen_list);
111        return NULL;
112    }
113
114    if (handle_command_line(argc, argv, screen_list) < 0)
115    {
116        free_screen_list(screen_list);
117        return NULL;
118    }
119
120    /* Read global configuration first */
121    read_configuration_file("/etc/neercsrc", screen_list);
122
123    /* Then local one */
124    if (screen_list->sys.user_path)
125    {
126        read_configuration_file(screen_list->sys.user_path, screen_list);
127        free(screen_list->sys.user_path);
128    }
129
130    if (screen_list->sys.attach)
131    {
132        if (screen_list->sys.nb_to_grab || screen_list->sys.to_start)
133        {
134            fprintf(stderr,
135                    "-R can not be associated with commands or pids!\n");
136            free_screen_list(screen_list);
137            return NULL;
138        }
139
140        attach(screen_list);
141
142        if (screen_list->sys.forceattach && !screen_list->sys.attach)
143        {
144            free_screen_list(screen_list);
145            return NULL;
146        }
147    }
148
149    /* Build default session name */
150    if (!screen_list->comm.session_name)
151    {
152        char mypid[32];         /* FIXME Compute the length of PID_MAX ? */
153        snprintf(mypid, 31, "%d", getpid());
154        mypid[31] = '\0';
155        screen_list->comm.session_name = strdup(mypid);
156        if (!screen_list->comm.session_name)
157        {
158            fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
159                    __LINE__);
160            free_screen_list(screen_list);
161            return NULL;
162        }
163    }
164    if (!screen_list->comm.socket_path[SOCK_CLIENT])
165        screen_list->comm.socket_path[SOCK_CLIENT] =
166            build_socket_path(screen_list->comm.socket_dir,
167                              screen_list->comm.session_name, SOCK_CLIENT);
168
169    if (!screen_list->comm.socket_path[SOCK_SERVER])
170        screen_list->comm.socket_path[SOCK_SERVER] =
171            build_socket_path(screen_list->comm.socket_dir,
172                              screen_list->comm.session_name, SOCK_SERVER);
173
174    /* Fork the server if needed */
175    if (!screen_list->sys.attach)
176    {
177        debug("Spawning a new server");
178        if (start_server(screen_list))
179        {
180            free_screen_list(screen_list);
181            return NULL;
182        }
183        if (start_client(screen_list))
184        {
185            free_screen_list(screen_list);
186            return NULL;
187        }
188    }
189
190    return screen_list;
191}
192
193int handle_command_line(int argc, char *argv[],
194                        struct screen_list *screen_list)
195{
196    int s = 0, i;
197    for (;;)
198    {
199        int option_index = 0;
200        int pidopt;
201        static struct myoption long_options[] = {
202            {"config", 1, NULL, 'c'},
203#if defined USE_GRAB
204            {"pid", 0, NULL, 'P'},
205#endif
206            {"lock-after", 1, NULL, 'l'},
207            {"help", 0, NULL, 'h'},
208            {"version", 0, NULL, 'v'},
209            {NULL, 0, NULL, 0},
210        };
211#if defined USE_GRAB
212        int c =
213            mygetopt(argc, argv, "c:S:R::l::r::P::hv", long_options,
214                     &option_index);
215#else
216        int c =
217            mygetopt(argc, argv, "c:S:R::l::r::hv", long_options,
218                     &option_index);
219#endif
220        if (c == -1)
221            break;
222
223        switch (c)
224        {
225        case 'c':              /* --config */
226            if (screen_list->sys.user_path)
227                free(screen_list->sys.user_path);
228            screen_list->sys.user_path = strdup(myoptarg);
229            s += 2;
230            break;
231        case 'S':
232            if (!screen_list->comm.session_name)
233                screen_list->comm.session_name = strdup(myoptarg);
234            s += 2;
235            break;
236        case 'P':              /* --pid */
237            if (myoptarg)
238            {
239                pidopt = atoi(myoptarg);
240                if (pidopt <= 0)
241                {
242                    fprintf(stderr, "Invalid pid %d\n", pidopt);
243                    if (screen_list->sys.to_grab)
244                        free(screen_list->sys.to_grab);
245                    return -1;
246                }
247            }
248            else
249                pidopt = select_process(screen_list);
250            if (pidopt <= 0)
251            {
252                s += 1;
253                break;
254            }
255            if (!screen_list->sys.to_grab)
256            {
257                /* At most argc-1-s times -P <pid> + final 0 */
258                screen_list->sys.to_grab =
259                    (int *)malloc(((argc - 1 - s) / 2 + 1) * sizeof(int));
260                if (!screen_list->sys.to_grab)
261                {
262                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
263                            __FUNCTION__, __LINE__);
264                    return -1;
265                }
266            }
267            screen_list->sys.to_grab[screen_list->sys.nb_to_grab++] = pidopt;
268            screen_list->sys.to_grab[screen_list->sys.nb_to_grab] = 0;
269            s += 2;
270            break;
271        case 'l':
272            screen_list->lock.autolock_timeout = atoi(myoptarg) * 1000000;
273            if (screen_list->lock.autolock_timeout == 0)
274                screen_list->lock.autolock_timeout -= 1;
275            break;
276        case 'r':
277            screen_list->sys.forceattach = 1;
278        case 'R':
279            if (screen_list->sys.attach)
280            {
281                fprintf(stderr, "Attaching can only be requested once\n");
282                return -1;
283            }
284            if (myoptarg)
285            {
286                if (screen_list->comm.session_name)
287                    free(screen_list->comm.session_name);
288                screen_list->comm.session_name = strdup(myoptarg);
289                s += 1;
290            }
291            screen_list->sys.attach = 1;
292            s += 1;
293            break;
294        case 'h':              /* --help */
295            usage(argc, argv);
296            return -1;
297            break;
298        case 'v':              /* --version */
299            version();
300            return -1;
301            break;
302        case -2:
303            return -1;
304        default:
305            fprintf(stderr, "Unknown argument #%d\n", myoptind);
306            return -1;
307            break;
308        }
309    }
310    if (s >= 0 && s < argc - 1)
311    {
312        screen_list->sys.to_start = (char **)malloc((argc - s) * sizeof(char *));
313        if (!screen_list->sys.to_start)
314        {
315            fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
316                    __LINE__);
317            return -1;
318        }
319        for (i = 0; i < (argc - 1) - s; i++)
320        {
321            screen_list->sys.to_start[i] = strdup(argv[i + s + 1]);
322        }
323        screen_list->sys.to_start[argc - 1 - s] = NULL;
324    }
325    return s;
326}
327
328#endif
329
Note: See TracBrowser for help on using the repository browser.