Rizin
unix-like reverse engineering framework and cli tools
magic.c File Reference
#include <rz_userconf.h>
#include <rz_magic.h>
#include "file.h"

Go to the source code of this file.

Macros

#define PIPE_BUF   512
 
#define SLOP   (1 + sizeof(union VALUETYPE))
 

Functions

 RZ_LIB_VERSION (rz_magic)
 
static void free_mlist (struct mlist *mlist)
 
static int info_from_stat (RzMagic *ms, unsigned short md)
 
static void close_and_restore (const RzMagic *ms, const char *name, int fd, const struct stat *sb)
 
static const char * file_or_fd (RzMagic *ms, const char *inname, int fd)
 
RZ_API RzMagic * rz_magic_new (int flags)
 
RZ_API void rz_magic_free (RzMagic *ms)
 
RZ_API bool rz_magic_load_buffer (RzMagic *ms, const char *magicdata)
 
RZ_API bool rz_magic_load (RzMagic *ms, const char *magicfile)
 
RZ_API bool rz_magic_compile (RzMagic *ms, const char *magicfile)
 
RZ_API bool rz_magic_check (RzMagic *ms, const char *magicfile)
 
RZ_API const char * rz_magic_descriptor (RzMagic *ms, int fd)
 
RZ_API const char * rz_magic_file (RzMagic *ms, const char *inname)
 
RZ_API const char * rz_magic_buffer (RzMagic *ms, const void *buf, size_t nb)
 
RZ_API const char * rz_magic_error (RzMagic *ms)
 
RZ_API int rz_magic_errno (RzMagic *ms)
 
RZ_API void rz_magic_setflags (RzMagic *ms, int flags)
 

Macro Definition Documentation

◆ PIPE_BUF

#define PIPE_BUF   512

Definition at line 83 of file magic.c.

◆ SLOP

#define SLOP   (1 + sizeof(union VALUETYPE))

Function Documentation

◆ close_and_restore()

static void close_and_restore ( const RzMagic *  ms,
const char *  name,
int  fd,
const struct stat sb 
)
static

Definition at line 125 of file magic.c.

125  {
126  if (fd >= 0) {
127  close(fd);
128  }
129 }
static static fork const void static count close
Definition: sflib.h:33
static const z80_opcode fd[]
Definition: z80_tab.h:997

References close, and fd.

Referenced by file_or_fd().

◆ file_or_fd()

static const char* file_or_fd ( RzMagic *  ms,
const char *  inname,
int  fd 
)
static

Definition at line 131 of file magic.c.

131  {
132  bool ispipe = false;
133  int rv = -1;
134  unsigned char *buf;
135  struct stat sb;
136  int nbytes = 0; /* number of bytes read from a datafile */
137 
138  /*
139  * one extra for terminating '\0', and
140  * some overlapping space for matches near EOF
141  */
142 #define SLOP (1 + sizeof(union VALUETYPE))
143  if (!(buf = malloc(HOWMANY + SLOP))) {
144  return NULL;
145  }
146 
147  if (file_reset(ms) == -1) {
148  goto done;
149  }
150 
151  switch (file_fsmagic(ms, inname, &sb)) {
152  case -1: goto done; /* error */
153  case 0: break; /* nothing found */
154  default: rv = 0; goto done; /* matched it and printed type */
155  }
156 
157  if (!inname) {
158  if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode)) {
159  ispipe = true;
160  }
161  } else {
162  int flags = O_RDONLY | O_BINARY;
163 
164  if (stat(inname, &sb) == 0 && S_ISFIFO(sb.st_mode)) {
165 #if O_NONBLOCK
166  flags |= O_NONBLOCK;
167 #endif
168  ispipe = true;
169  }
170  errno = 0;
171  if ((fd = open(inname, flags)) < 0) {
172  eprintf("couldn't open file\n");
173  if (info_from_stat(ms, sb.st_mode) == -1) {
174  goto done;
175  }
176  rv = 0;
177  goto done;
178  }
179 #ifdef O_NONBLOCK
180  if ((flags = fcntl(fd, F_GETFL)) != -1) {
181  flags &= ~O_NONBLOCK;
182  (void)fcntl(fd, F_SETFL, flags);
183  }
184 #endif
185  }
186 
187  /*
188  * try looking at the first HOWMANY bytes
189  */
190 #ifdef O_NONBLOCK
191  if (ispipe) {
192  ssize_t r = 0;
193 
194  // while ((r = sread(fd, (void *)&buf[nbytes],
195  while ((r = read(fd, (void *)&buf[nbytes],
196  (size_t)(HOWMANY - nbytes))) > 0) {
197  nbytes += r;
198  if (r < PIPE_BUF) {
199  break;
200  }
201  }
202 
203  if (nbytes == 0) {
204  /* We can not read it, but we were able to stat it. */
205  if (info_from_stat(ms, sb.st_mode) == -1) {
206  goto done;
207  }
208  rv = 0;
209  goto done;
210  }
211  } else {
212 #endif
213  if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
214  file_error(ms, errno, "cannot read `%s'", inname);
215  goto done;
216  }
217 #ifdef O_NONBLOCK
218  }
219 #endif
220 
221  (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
222  if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1) {
223  goto done;
224  }
225  rv = 0;
226 done:
227  free(buf);
228  close_and_restore(ms, inname, fd, &sb);
229  return rv == 0 ? file_getbuffer(ms) : NULL;
230 }
static SblHeader sb
Definition: bin_mbn.c:26
#define O_BINARY
Definition: cpipe.c:13
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void nbytes
Definition: sflib.h:113
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset fstat
Definition: sflib.h:107
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags fcntl
Definition: sflib.h:79
struct tab * done
Definition: enough.c:233
int file_reset(struct rz_magic_set *)
const char * file_getbuffer(struct rz_magic_set *)
void file_error(struct rz_magic_set *, int, const char *,...)
int file_buffer(struct rz_magic_set *, int, const char *, const void *, size_t)
int file_fsmagic(struct rz_magic_set *, const char *, struct stat *)
Definition: fsmagic.c:76
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
return memset(p, 0, total)
void * malloc(size_t size)
Definition: malloc.c:123
static stat
Definition: sflib.h:131
static int info_from_stat(RzMagic *ms, unsigned short md)
Definition: magic.c:102
static void close_and_restore(const RzMagic *ms, const char *name, int fd, const struct stat *sb)
Definition: magic.c:125
#define SLOP
#define PIPE_BUF
Definition: magic.c:83
#define eprintf(x, y...)
Definition: rlcc.c:7
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define F_GETFL
Definition: sftypes.h:506
#define O_NONBLOCK
Definition: sftypes.h:494
#define O_RDONLY
Definition: sftypes.h:486
#define F_SETFL
Definition: sftypes.h:507
int ssize_t
Definition: sftypes.h:39
Definition: sftypes.h:80
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115

References close_and_restore(), done, eprintf, F_GETFL, F_SETFL, fcntl, fd, file_buffer(), file_error(), file_fsmagic(), file_getbuffer(), file_reset(), flags, free(), fstat, info_from_stat(), malloc(), memset(), nbytes, NULL, O_BINARY, O_NONBLOCK, O_RDONLY, PIPE_BUF, r, read(), sb, SLOP, and stat.

Referenced by rz_magic_descriptor(), and rz_magic_file().

◆ free_mlist()

static void free_mlist ( struct mlist *  mlist)
static

Definition at line 87 of file magic.c.

87  {
88  struct mlist *ml;
89  if (!mlist) {
90  return;
91  }
92  for (ml = mlist->next; ml != mlist;) {
93  struct mlist *next = ml->next;
94  struct rz_magic *mg = ml->magic;
95  file_delmagic(mg, ml->mapped, ml->nmagic);
96  free(ml);
97  ml = next;
98  }
99  free(ml);
100 }
void file_delmagic(struct rz_magic *p, int type, size_t entries)
Definition: apprentice.c:255

References file_delmagic(), and free().

Referenced by rz_magic_check(), rz_magic_compile(), rz_magic_free(), rz_magic_load(), and rz_magic_load_buffer().

◆ info_from_stat()

static int info_from_stat ( RzMagic *  ms,
unsigned short  md 
)
static

Definition at line 102 of file magic.c.

102  {
103  /* We cannot open it, but we were able to stat it. */
104  if (md & 0222) {
105  if (file_printf(ms, "writable, ") == -1) {
106  return -1;
107  }
108  }
109  if (md & 0111) {
110  if (file_printf(ms, "executable, ") == -1) {
111  return -1;
112  }
113  }
114  if (S_ISREG(md)) {
115  if (file_printf(ms, "regular file, ") == -1) {
116  return -1;
117  }
118  }
119  if (file_printf(ms, "no read permission") == -1) {
120  return -1;
121  }
122  return 0;
123 }
#define S_ISREG(mode)
Definition: compat.h:191
int file_printf(struct rz_magic_set *, const char *,...)

References file_printf(), benchmark::md, and S_ISREG.

Referenced by file_or_fd().

◆ RZ_LIB_VERSION()

RZ_LIB_VERSION ( rz_magic  )

◆ rz_magic_buffer()

RZ_API const char* rz_magic_buffer ( RzMagic *  ms,
const void *  buf,
size_t  nb 
)

Definition at line 308 of file magic.c.

308  {
309  if (file_reset(ms) == -1) {
310  return NULL;
311  }
312  if (file_buffer(ms, -1, NULL, buf, nb) == -1) {
313  return NULL;
314  }
315  return file_getbuffer(ms);
316 }

References file_buffer(), file_getbuffer(), file_reset(), and NULL.

Referenced by get_filetype(), and rz_core_magic_at().

◆ rz_magic_check()

RZ_API bool rz_magic_check ( RzMagic *  ms,
const char *  magicfile 
)

Definition at line 294 of file magic.c.

294  {
295  struct mlist *ml = file_apprentice(ms, magicfile, FILE_CHECK);
296  free_mlist(ml);
297  return ml != NULL;
298 }
struct mlist * file_apprentice(RzMagic *ms, const char *fn, int action)
Definition: apprentice.c:277
static void free_mlist(struct mlist *mlist)
Definition: magic.c:87

References file_apprentice(), free_mlist(), and NULL.

◆ rz_magic_compile()

RZ_API bool rz_magic_compile ( RzMagic *  ms,
const char *  magicfile 
)

Definition at line 288 of file magic.c.

288  {
289  struct mlist *ml = file_apprentice(ms, magicfile, FILE_COMPILE);
290  free_mlist(ml);
291  return ml != NULL;
292 }

References file_apprentice(), free_mlist(), and NULL.

◆ rz_magic_descriptor()

RZ_API const char* rz_magic_descriptor ( RzMagic *  ms,
int  fd 
)

Definition at line 300 of file magic.c.

300  {
301  return file_or_fd(ms, NULL, fd);
302 }
static const char * file_or_fd(RzMagic *ms, const char *inname, int fd)
Definition: magic.c:131

References fd, file_or_fd(), and NULL.

◆ rz_magic_errno()

RZ_API int rz_magic_errno ( RzMagic *  ms)

Definition at line 325 of file magic.c.

325  {
326  if (ms && ms->haderr) {
327  return ms->error;
328  }
329  return 0;
330 }

◆ rz_magic_error()

RZ_API const char* rz_magic_error ( RzMagic *  ms)

Definition at line 318 of file magic.c.

318  {
319  if (ms && ms->haderr) {
320  return ms->o.buf;
321  }
322  return NULL;
323 }

References NULL.

Referenced by rz_core_magic_at().

◆ rz_magic_file()

RZ_API const char* rz_magic_file ( RzMagic *  ms,
const char *  inname 
)

Definition at line 304 of file magic.c.

304  {
305  return file_or_fd(ms, inname, 0); // 0 = stdin
306 }

References file_or_fd().

Referenced by file_fsmagic().

◆ rz_magic_free()

RZ_API void rz_magic_free ( RzMagic *  ms)

Definition at line 254 of file magic.c.

254  {
255  if (ms) {
256  free_mlist(ms->mlist);
257  free(ms->o.pbuf);
258  free(ms->o.buf);
259  free(ms->c.li);
260  free(ms);
261  }
262 }

References free(), and free_mlist().

Referenced by get_filetype(), and rz_core_magic_at().

◆ rz_magic_load()

RZ_API bool rz_magic_load ( RzMagic *  ms,
const char *  magicfile 
)

Definition at line 278 of file magic.c.

278  {
279  struct mlist *ml = file_apprentice(ms, magicfile, FILE_LOAD);
280  if (ml) {
281  free_mlist(ms->mlist);
282  ms->mlist = ml;
283  return true;
284  }
285  return false;
286 }

References file_apprentice(), and free_mlist().

Referenced by get_filetype(), and rz_core_magic_at().

◆ rz_magic_load_buffer()

RZ_API bool rz_magic_load_buffer ( RzMagic *  ms,
const char *  magicdata 
)

Definition at line 264 of file magic.c.

264  {
265  if (*magicdata == '#') {
266  struct mlist *ml = file_apprentice(ms, magicdata, FILE_LOAD);
267  if (ml) {
268  free_mlist(ms->mlist);
269  ms->mlist = ml;
270  return true;
271  }
272  } else {
273  eprintf("Magic buffers should start with #\n");
274  }
275  return false;
276 }

References eprintf, file_apprentice(), and free_mlist().

◆ rz_magic_new()

RZ_API RzMagic* rz_magic_new ( int  flags)

Definition at line 235 of file magic.c.

235  {
236  RzMagic *ms = RZ_NEW0(RzMagic);
237  if (!ms) {
238  return NULL;
239  }
241  ms->o.buf = ms->o.pbuf = NULL;
242  ms->c.li = malloc((ms->c.len = 10) * sizeof(*ms->c.li));
243  if (!ms->c.li) {
244  free(ms);
245  return NULL;
246  }
247  file_reset(ms);
248  ms->mlist = NULL;
249  ms->file = "unknown";
250  ms->line = 0;
251  return ms;
252 }
RZ_API void rz_magic_setflags(RzMagic *ms, int flags)
Definition: magic.c:332
#define RZ_NEW0(x)
Definition: rz_types.h:284

References file_reset(), flags, free(), malloc(), NULL, rz_magic_setflags(), and RZ_NEW0.

Referenced by get_filetype(), and rz_core_magic_at().

◆ rz_magic_setflags()

RZ_API void rz_magic_setflags ( RzMagic *  ms,
int  flags 
)

Definition at line 332 of file magic.c.

332  {
333  if (ms) {
334  ms->flags = flags;
335  }
336 }

References flags.

Referenced by rz_magic_new().