~ubuntu-branches/ubuntu/oneiric/oss4/oneiric-proposed

« back to all changes in this revision

Viewing changes to os_cmd/Linux/ossvermagic/ossvermagic.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefano Rivera
  • Date: 2011-06-16 20:37:48 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110616203748-jbrxik6ql33z54co
Tags: 4.2-build2004-1ubuntu1
* Merge from Debian unstable.
  - Supports our current kernel (LP: #746048)
  Remaining changes:
  - debian/oss4-dkms.dkms.in: s/source/build/ in Kernel headers paths.
* ld-as-needed.patch: Re-order CC arguments to enable building with ld
  --as-needed (LP: #770972)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * This file is part of Open Sound System.
 
4
 *
 
5
 * Copyright (C) 4Front Technologies 1996-2008.
 
6
 *
 
7
 * This this source file is released under GPL v2 license (no other versions).
 
8
 * See the COPYING file included in the main directory of this source
 
9
 * distribution for the license terms and conditions.
 
10
 *
 
11
 */
 
12
 
 
13
#include <stdio.h>
 
14
#include <stdlib.h>
 
15
#include <unistd.h>
 
16
#include <fcntl.h>
 
17
#include <string.h>
 
18
#include <sys/types.h>
 
19
#include <sys/wait.h>
 
20
#include <dirent.h>
 
21
#include <sys/utsname.h>
 
22
#include <sys/stat.h>
 
23
#include <elf.h>
 
24
#define CONFIGURE_C
 
25
#include "oss_config.h"
 
26
 
 
27
int elf_verbose = 0;
 
28
 
 
29
#ifdef __x86_64__
 
30
#define ELF64
 
31
#define ELF_LOAD_SYMTAB elf_load_symtab
 
32
#else
 
33
#define ELF32
 
34
#define ELF_LOAD_SYMTAB elf_load_symtab
 
35
#endif
 
36
#include "../../../setup/elflib.inc"
 
37
 
 
38
char *fname;
 
39
int ok;
 
40
int quiet = 0;
 
41
int verbose = 0;
 
42
int once = 0;
 
43
int exit_status = -1;
 
44
int check_compile_vermagic = 0;
 
45
 
 
46
static void
 
47
sym_callback (char *buffer, int blen, Elf_Sym * sym, char *name, int addr)
 
48
{
 
49
 
 
50
  char tmp[256], *vermagic = tmp;
 
51
 
 
52
  ok = 1;
 
53
  exit_status = 0;
 
54
 
 
55
  if (verbose)
 
56
    printf ("Vermagic buffer at %x\n", addr);
 
57
 
 
58
  elf_read_datasym (buffer, blen, sym, addr, tmp, sizeof (tmp));
 
59
 
 
60
  if (strncmp (vermagic, "vermagic=", 9) == 0)
 
61
    vermagic += 9;
 
62
 
 
63
  if (quiet)
 
64
    printf ("%s\n", vermagic);
 
65
  else
 
66
    printf ("%s: '%s'\n", fname, vermagic);
 
67
 
 
68
  if (once)
 
69
    exit (0);
 
70
}
 
71
 
 
72
static void
 
73
find_vermagic (char *fname)
 
74
{
 
75
  ok = 0;
 
76
 
 
77
  if (verbose)
 
78
    printf ("ELF scan %s\n", fname);
 
79
 
 
80
  ok = ELF_LOAD_SYMTAB (fname, "vermagic", sym_callback);
 
81
  if (!ok)
 
82
    ok = ELF_LOAD_SYMTAB (fname, "__mod_vermagic", sym_callback);
 
83
  if (!ok)
 
84
    ELF_LOAD_SYMTAB (fname, "__oss_compile_vermagic", sym_callback);
 
85
}
 
86
 
 
87
static void
 
88
find_link_vermagic (char *fname)
 
89
{
 
90
  if (verbose)
 
91
    printf ("ELF scan %s\n", fname);
 
92
 
 
93
  ELF_LOAD_SYMTAB (fname, "__oss_compile_vermagic", sym_callback);
 
94
}
 
95
 
 
96
static void
 
97
check_gzipped_module (char *fname)
 
98
{
 
99
  char tmp[1024];
 
100
 
 
101
  sprintf (tmp, "gunzip -c %s > /tmp/oss.tmpmodule", fname);
 
102
  unlink ("/tmp/oss.tmpmodule");
 
103
 
 
104
  if (system (tmp) != 0)
 
105
    {
 
106
      unlink ("/tmp/oss.tmpmodule");
 
107
      return;
 
108
    }
 
109
 
 
110
  find_vermagic ("/tmp/oss.tmpmodule");
 
111
  unlink ("/tmp/oss.tmpmodule");
 
112
}
 
113
 
 
114
static void
 
115
check_bzipped_module (char *fname)
 
116
{
 
117
  char tmp[1024];
 
118
 
 
119
  sprintf (tmp, "bunzip2 -c %s > /tmp/oss.tmpmodule", fname);
 
120
  unlink ("/tmp/oss.tmpmodule");
 
121
 
 
122
  if (system (tmp) != 0)
 
123
    {
 
124
      unlink ("/tmp/oss.tmpmodule");
 
125
      return;
 
126
    }
 
127
 
 
128
  find_vermagic ("/tmp/oss.tmpmodule");
 
129
  unlink ("/tmp/oss.tmpmodule");
 
130
}
 
131
 
 
132
static void
 
133
scan_dir (char *dirname)
 
134
{
 
135
  char tmp[1024];
 
136
  DIR *dir;
 
137
  struct dirent *de;
 
138
 
 
139
  if ((dir = opendir (dirname)) == NULL)
 
140
    return;
 
141
 
 
142
  while ((de = readdir (dir)))
 
143
    {
 
144
      struct stat st;
 
145
 
 
146
      if (de->d_name[0] == '.')
 
147
        continue;
 
148
 
 
149
      sprintf (tmp, "%s/%s", dirname, de->d_name);
 
150
 
 
151
      if (stat (tmp, &st) == -1)
 
152
        {
 
153
          perror (tmp);
 
154
          return;
 
155
        }
 
156
 
 
157
      if (S_ISDIR (st.st_mode))
 
158
        scan_dir (tmp);
 
159
      else
 
160
        {
 
161
          char *p;
 
162
 
 
163
          if (verbose)
 
164
            printf ("Checking %s\n", tmp);
 
165
          p = tmp + strlen (tmp) - 3;   // Seek the .gz suffix
 
166
          if (strcmp (p, ".gz") == 0)
 
167
            {
 
168
              fname = tmp;
 
169
              check_gzipped_module (tmp);
 
170
              continue;
 
171
            }
 
172
 
 
173
          p = tmp + strlen (tmp) - 4;   // Seek the .bz2 suffix
 
174
          if (strcmp (p, ".bz2") == 0)
 
175
            {
 
176
              fname = tmp;
 
177
              check_bzipped_module (tmp);
 
178
              continue;
 
179
            }
 
180
 
 
181
          fname = tmp;
 
182
          find_vermagic (tmp);
 
183
        }
 
184
    }
 
185
 
 
186
  closedir (dir);
 
187
}
 
188
 
 
189
static void
 
190
find_system_vermagic (void)
 
191
{
 
192
  struct utsname un;
 
193
  char dirname[1024];
 
194
 
 
195
  struct stat st;
 
196
 
 
197
  if (uname (&un) == -1)
 
198
    {
 
199
      perror ("uname");
 
200
      exit (-1);
 
201
    }
 
202
 
 
203
  sprintf (dirname, "/lib/modules/%s/kernel", un.release);
 
204
 
 
205
  if (stat (dirname, &st) == -1)
 
206
    {
 
207
      perror (dirname);
 
208
      fprintf (stderr, "Kernel modules not available\n");
 
209
      exit (-1);
 
210
    }
 
211
 
 
212
  quiet = 1;
 
213
  once = 1;
 
214
  scan_dir (dirname);
 
215
}
 
216
 
 
217
int
 
218
main (int argc, char *argv[])
 
219
{
 
220
  int i, ok;
 
221
  int do_sys = 0;
 
222
  int valid = 0;
 
223
 
 
224
  if (argc < 2)
 
225
    exit (-1);
 
226
 
 
227
  for (i = 1; i < argc; i++)
 
228
    {
 
229
      if (strcmp (argv[i], "-r") == 0)
 
230
        {
 
231
          /*
 
232
           * Check if the system is 2.6.20 or later which is
 
233
           * always compiled with CONFIG_REGPARM.
 
234
           */
 
235
 
 
236
          struct utsname un;
 
237
          int a, b, c;
 
238
 
 
239
          if (uname (&un) == -1)
 
240
            {
 
241
              perror ("uname");
 
242
              exit (-1);
 
243
            }
 
244
 
 
245
          if (sscanf (un.release, "%d.%d.%d", &a, &b, &c) != 3)
 
246
            {
 
247
              fprintf (stderr, "Unrecognized kernel release '%s'\n",
 
248
                       un.release);
 
249
              exit (0);         /* Assume it's some future kernel */
 
250
            }
 
251
 
 
252
          if (a > 2)
 
253
            exit (0);           /* Always REGPARM */
 
254
          if (b > 6)
 
255
            exit (0);           /* Always REGPARM */
 
256
          if (c >= 20)
 
257
            exit (0);           /* Always REGPARM */
 
258
 
 
259
          exit (1);             /* Don't know */
 
260
        }
 
261
 
 
262
      if (strcmp (argv[i], "-s") == 0)
 
263
        do_sys = 1;
 
264
      if (strcmp (argv[i], "-v") == 0)
 
265
        verbose++;
 
266
      if (strcmp (argv[i], "-z") == 0)
 
267
        valid = 1;
 
268
      if (strcmp (argv[i], "-u") == 0)
 
269
        check_compile_vermagic = 1;
 
270
    }
 
271
 
 
272
  if (!valid)
 
273
    {
 
274
      fprintf (stderr,
 
275
               "%s: This program is reserved for use by Open Sound System\n",
 
276
               argv[0]);
 
277
      exit (-1);
 
278
    }
 
279
 
 
280
  elf_verbose = verbose;
 
281
 
 
282
  if (do_sys)
 
283
    {
 
284
      ok = 0;
 
285
      if (fork () == 0)
 
286
        find_system_vermagic ();
 
287
      else
 
288
        {
 
289
          int status;
 
290
          wait (&status);
 
291
          unlink ("/tmp/oss.tmpmodule");
 
292
          exit (WEXITSTATUS (status));
 
293
        }
 
294
 
 
295
      if (!ok)
 
296
        exit (-1);
 
297
      exit (0);
 
298
    }
 
299
 
 
300
  for (i = 1; i < argc; i++)
 
301
    {
 
302
      if (strcmp (argv[i], "-q") == 0)
 
303
        {
 
304
          quiet = 1;
 
305
          continue;
 
306
        }
 
307
 
 
308
      if (strcmp (argv[i], "-1") == 0)
 
309
        {
 
310
          once = 1;
 
311
          continue;
 
312
        }
 
313
 
 
314
      fname = argv[i];
 
315
      ok = 0;
 
316
 
 
317
      if (*fname != '-')
 
318
        {
 
319
          if (check_compile_vermagic == 0) find_vermagic (fname);
 
320
          else find_link_vermagic (fname);
 
321
        }
 
322
    }
 
323
 
 
324
  exit (exit_status);
 
325
}