Git init
[external/insserv.git] / debian / patches / 62_upstart_job.patch
1 Purpose: Add support for upstart jobs.
2 Fixes:   #547235
3 Status:  Work in progress, not submitted upstream yet.
4 ---
5
6 Index: insserv/insserv.8.in
7 ===================================================================
8 --- insserv.orig/insserv.8.in   2009-09-26 22:35:39.000000000 +0200
9 +++ insserv/insserv.8.in        2009-09-26 22:35:42.000000000 +0200
10 @@ -266,6 +266,10 @@
11  .BR \-f ,\  \-\-force
12  Ignore if a required service is missed.
13  .TP
14 +.BR \-u\ <path> ,\  \-\-upstart-job\ <path>
15 +Path to replace existing upstart job path.  (default path is
16 +.IR /lib/init/upstart-job ).
17 +.TP
18  .BR \-h ,\  \-\-help
19  Print out short usage message.
20  .PP
21 @@ -339,6 +343,12 @@
22  name as the boot or init script in the directory
23  .IR /etc/insserv/overrides/ .
24  .\"
25 +.SH UPSTART JOB COMPATIBILITY
26 +To allow upstart jobs to work as init.d scripts, insserv will
27 +recognize a symlink from path/to/init.d/script to
28 +/lib/init/upstart-job as upstart jobs, and instead of reading the
29 +header from the file will run the script with the argument lsb-header
30 +to get the script header.
31  .SH EXIT CODES
32  The exit codes have the following conditions:
33  .RS 7
34 Index: insserv/insserv.c
35 ===================================================================
36 --- insserv.orig/insserv.c      2009-09-26 22:35:39.000000000 +0200
37 +++ insserv/insserv.c   2009-09-26 22:35:43.000000000 +0200
38 @@ -70,6 +70,8 @@
39  # define INSCONF       "/etc/insserv.conf"
40  #endif
41  
42 +const char *upstartjob_path = "/lib/init/upstart-job";
43 +
44  /*
45   * For a description of regular expressions see regex(7).
46   */
47 @@ -1154,6 +1156,43 @@
48      xreset(script_inf.interactive);
49  }
50  
51 +static char *is_upstart_job_recursive(const char *path,
52 +                                     const char *basenamestr)
53 +{
54 +    struct stat statbuf;
55 +    if (-1 == lstat(path, &statbuf)) {
56 +       return 0;
57 +    }
58 +    if (S_ISLNK(statbuf.st_mode)) {
59 +        char buf[2048];
60 +        int len = readlink(path, buf, sizeof(buf)-1);
61 +       if (0 < len) {
62 +           buf[len] = '\0';
63 +           if (0 == strcmp(buf, upstartjob_path)) {
64 +             /* upstart job, return base name of original symlink */
65 +             return strdup(basenamestr);
66 +           } else
67 +             return is_upstart_job_recursive(buf, basenamestr);
68 +       }
69 +    }
70 +    return 0;
71 +}
72 +
73 +/*
74 + * return name of upstart job if the script is a symlink to
75 + * /lib/init/upstart-job, or NULL if path do not point to an
76 + * upstart job.
77 + */
78 +static char* is_upstart_job(const char *path)
79 +{
80 +
81 +    char *basenamestr = basename(path); /* GNU basename */
82 +    char *retval = is_upstart_job_recursive(path, basenamestr);
83 +    if (retval)
84 +        info("script '%s' is upstart job\n", basenamestr);
85 +    return retval;
86 +}
87 +
88  #define FOUND_LSB_HEADER   0x01
89  #define FOUND_LSB_DEFAULT  0x02
90  #define FOUND_LSB_OVERRIDE 0x04
91 @@ -1170,7 +1209,8 @@
92      char *pbuf = buf;
93      FILE *script;
94      uchar ret = 0;
95 -    int fd;
96 +    int fd = -1;
97 +    char *upstart_job = NULL;
98  
99  #define provides       script_inf.provides
100  #define required_start script_inf.required_start
101 @@ -1186,12 +1226,23 @@
102  
103      info("Loading %s\n", path);
104  
105 -    if ((fd = xopen(dfd, path, o_flags)) < 0 || (script = fdopen(fd, "r")) == (FILE*)0)
106 -       error("fopen(%s): %s\n", path, strerror(errno));
107 +    if (NULL != (upstart_job = is_upstart_job(path))) {
108 +        char cmd[2048];
109 +       int len;
110 +       len = snprintf(cmd, sizeof(cmd),
111 +                      "%s %s lsb-header", upstartjob_path, upstart_job);
112 +       if (len < 0 || sizeof(cmd) == len)
113 +           error("snprintf: insufficient buffer for %s\n", path);
114 +       if ((FILE*)0 == (script = popen(cmd, "r")))
115 +           error("popen(%s): %s\n", path, strerror(errno));
116 +    } else {
117 +        if ((fd = xopen(dfd, path, o_flags)) < 0 || (script = fdopen(fd, "r")) == (FILE*)0)
118 +           error("fopen(%s): %s\n", path, strerror(errno));
119  
120  #if defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 600
121 -    (void)posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
122 +       (void)posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
123  #endif
124 +    }
125  
126  #define COMMON_ARGS    buf, SUBNUM, subloc, 0
127  #define COMMON_SHD_ARGS        buf, SUBNUM_SHD, subloc, 0
128 @@ -1303,7 +1354,12 @@
129         (void)posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE);
130  #endif
131  
132 -    fclose(script);
133 +    if (upstart_job) {
134 +        pclose(script);
135 +        free(upstart_job);
136 +        upstart_job = 0;
137 +    } else
138 +        fclose(script);
139  
140      if (begin && end)
141         ret |= FOUND_LSB_HEADER;
142 @@ -2224,6 +2280,7 @@
143      {"force",  0, (int*)0, 'f'},
144      {"path",   1, (int*)0, 'p'},
145      {"override",1, (int*)0, 'o'},
146 +    {"upstart-job",1, (int*)0, 'u'},
147      {"help",   0, (int*)0, 'h'},
148      { 0,       0, (int*)0,  0 },
149  };
150 @@ -2277,7 +2334,7 @@
151      for (c = 0; c < argc; c++)
152         argr[c] = (char*)0;
153  
154 -    while ((c = getopt_long(argc, argv, "c:dfrhvno:p:", long_options, (int *)0)) != -1) {
155 +    while ((c = getopt_long(argc, argv, "c:dfrhvno:p:u:", long_options, (int *)0)) != -1) {
156         size_t l;
157         switch (c) {
158             case 'c':
159 @@ -2317,6 +2374,11 @@
160                 override_path = optarg;
161                 set_override = true;
162                 break;
163 +           case 'u':
164 +               if (optarg == (char*)0 || *optarg == '\0')
165 +                   goto err;
166 +               upstartjob_path = optarg;
167 +               break;
168             case '?':
169             err:
170                 error("For help use: %s -h\n", myname);