Mercurial > emacs
view src/unexnext.c @ 82975:590114f9753d gnus-5_10-pre-merge-josefsson
2004-08-31 Katsumi Yamaoka <yamaoka@jpl.org>
* gnus-agent.el (gnus-agent-restore-gcc): Use ^ and regexp-quote.
* gnus-sum.el (gnus-newsgroup-variables): Doc fix (tiny change).
From Helmut Waitzmann <Helmut.Waitzmann@web.de>.
* gnus-agent.el (gnus-agent-regenerate-group): Activate the group
when the group's active is not available.
* gnus-art.el (article-hide-headers): Refer to the values for
gnus-ignored-headers and gnus-visible-headers in the summary
buffer since a user may have set them as group parameters.
(gnus-article-next-page): Fix the way to find a real end-of-buffer
(tiny change). From YAGI Tatsuya <ynyaaa@ybb.ne.jp>.
(gnus-article-read-summary-keys): Restore new window-start and
hscroll to summary window.
(gnus-prev-page-map): Remove duplicated one.
* gnus-cite.el (gnus-cite-ignore-quoted-from): New user option.
(gnus-cite-parse): Ignore quoted envelope From_. Suggested by
Karl Chen <quarl@nospam.quarl.org> and Reiner Steib
<Reiner.Steib@gmx.de>.
* gnus-cus.el (gnus-agent-cat-prepare-category-field): Replace
pp-to-string with gnus-pp-to-string.
* gnus-eform.el (gnus-edit-form): Replace pp with gnus-pp.
* gnus-group.el (gnus-group-make-kiboze-group): Replace pp with
gnus-pp.
* gnus-msg.el (gnus-setup-message): Ignore an article copy while
parsing gnus-posting-styles when the message is not for replying.
(gnus-summary-resend-message-edit): Call mime-to-mml. Suggested
by Hiroshi Fujishima <pooh@nature.tsukuba.ac.jp>.
(gnus-debug): Replace pp with gnus-pp.
* gnus-score.el (gnus-score-save): Replace pp with gnus-pp.
* gnus-spec.el (gnus-update-format): Replace pp-to-string with
gnus-pp-to-string.
* gnus-sum.el (gnus-read-header): Don't remove a header for the
parent article of a sparse article in the thread hashtb. From
Stefan Wiens <s.wi@gmx.net>.
* gnus-util.el (gnus-bind-print-variables): New macro.
(gnus-prin1): Use it.
(gnus-prin1-to-string): Use it.
(gnus-pp): New function.
(gnus-pp-to-string): New function.
* gnus.el: Don't make unnecessary *Group* buffer when loading.
* mail-source.el (mail-source-touch-pop): Doc fix.
* message.el (message-mode): Don't modify paragraph-separate there.
(message-setup-fill-variables): Add mml tags to paragraph-start
and paragraph-separate. Suggested by Andrew Korty <ajk@iu.edu>.
(message-smtpmail-send-it): Doc fix.
(message-exchange-point-and-mark): Don't activate region if it was
inactive. Suggested by Hiroshi Fujishima
<pooh@nature.tsukuba.ac.jp> and Jesper Harder <harder@ifa.au.dk>.
* mm-decode.el (mm-save-part): Bind enable-multibyte-characters to
t while entering a file name using the mm-with-multibyte macro.
Suggested by Hiroshi Fujishima <pooh@nature.tsukuba.ac.jp>.
* mm-encode.el (mm-content-transfer-encoding-defaults): Use
qp-or-base64 for the application/* types.
(mm-safer-encoding): Consider 7bit is safe.
* mm-util.el (mm-with-multibyte-buffer): New macro.
(mm-with-multibyte): New macro.
* mm-view.el (mm-inline-render-with-function): Use multibyte
buffer; decode html source by charset.
* nndoc.el (nndoc-type-alist): Improve regexp for article-begin,
add generate-head-function and generate-article-function to the
rfc822-forward entry.
(nndoc-forward-type-p): Recognize envelope From_.
(nndoc-rfc822-forward-generate-article): New function.
(nndoc-rfc822-forward-generate-head): New function.
From David Hedbor <dhedbor@real.com>.
* nnmail.el (nnmail-split-lowercase-expanded): New user option.
(nnmail-expand-newtext): Lowercase expanded entries if
nnmail-split-lowercase-expanded is non-nil.
* score-mode.el (gnus-score-pretty-print): Replace pp with gnus-pp.
* webmail.el (webmail-debug): Replace pp with gnus-pp.
* gnus-art.el (gnus-article-wash-html-with-w3m): Bind
w3m-safe-url-regexp as the value for mm-w3m-safe-url-regexp; use
w3m-minor-mode-map instead of mm-w3m-local-map-property.
(gnus-mime-save-part-and-strip): Use mm-complicated-handles
instead of mm-multiple-handles.
(gnus-mime-delete-part): Ditto.
* mm-decode.el (mm-multiple-handles): Recognize a string as a mime
handle, as well as a list.
(mm-complicated-handles): Former definition of mm-multiple-handles.
* mm-view.el (mm-w3m-mode-map): Remove.
(mm-w3m-local-map-property): Remove.
(mm-w3m-cid-retrieve-1): Call itself recursively. Suggested by
ARISAWA Akihiro <ari@mbf.sphere.ne.jp>.
(mm-w3m-cid-retrieve): Simplify.
(mm-inline-text-html-render-with-w3m): Decode html source by
charset; check META tags only when charsets are not specified in
headers; specify charset to w3m-region; use w3m-minor-mode-map
instead of mm-w3m-local-map-property.
author | Reiner Steib <Reiner.Steib@gmx.de> |
---|---|
date | Tue, 31 Aug 2004 14:47:59 +0000 |
parents | 695cf19ef79e |
children | a8fa7c632ee4 375f2633d815 |
line wrap: on
line source
/* Dump Emacs in macho format. Copyright (C) 1990, 1993 Free Software Foundation, Inc. Written by Bradley Taylor (btaylor@next.com). This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #undef __STRICT_BSD__ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <mach/mach.h> #include <mach-o/loader.h> #include <mach-o/reloc.h> #include <sys/file.h> #include <sys/stat.h> #include <unistd.h> /* Instead of unistd.h, this used to include libc.h. "Nelson H. F. Beebe" <beebe@math.utah.edu> says that doesn't work in system version 3.3. */ int malloc_cookie; /* * Kludge: we don't expect any program data beyond VM_HIGHDATA * What is really needed is a way to find out from malloc() which * pages it vm_allocated and write only those out into the data segment. * * This kludge may break when we stop using fixed virtual address * shared libraries. Actually, emacs will probably continue working, but be * much larger on disk than it needs to be (because non-malloced data will * be in the file). */ static const unsigned VM_HIGHDATA = 0x2000000; typedef struct region_t { vm_address_t address; vm_size_t size; vm_prot_t protection; vm_prot_t max_protection; vm_inherit_t inheritance; boolean_t shared; port_t object_name; vm_offset_t offset; } region_t; static void grow( struct load_command ***the_commands, unsigned *the_commands_len ) { if (*the_commands == NULL) { *the_commands_len = 1; *the_commands = malloc(sizeof(*the_commands)); } else { (*the_commands_len)++; *the_commands = realloc(*the_commands, (*the_commands_len * sizeof(**the_commands))); } } static void save_command( struct load_command *command, struct load_command ***the_commands, unsigned *the_commands_len ) { struct load_command **tmp; grow(the_commands, the_commands_len); tmp = &(*the_commands)[*the_commands_len - 1]; *tmp = malloc(command->cmdsize); bcopy(command, *tmp, command->cmdsize); } static void fatal_unexec(char *format, ...) { va_list ap; va_start(ap, format); fprintf(stderr, "unexec: "); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); va_end(ap); } static int read_macho( int fd, struct mach_header *the_header, struct load_command ***the_commands, unsigned *the_commands_len ) { struct load_command command; struct load_command *buf; int i; int size; if (read(fd, the_header, sizeof(*the_header)) != sizeof(*the_header)) { fatal_unexec("cannot read macho header"); return (0); } for (i = 0; i < the_header->ncmds; i++) { if (read(fd, &command, sizeof(struct load_command)) != sizeof(struct load_command)) { fatal_unexec("cannot read macho load command header"); return (0); } size = command.cmdsize - sizeof(struct load_command); if (size < 0) { fatal_unexec("bogus load command size"); return (0); } buf = malloc(command.cmdsize); buf->cmd = command.cmd; buf->cmdsize = command.cmdsize; if (read(fd, ((char *)buf + sizeof(struct load_command)), size) != size) { fatal_unexec("cannot read load command data"); return (0); } save_command(buf, the_commands, the_commands_len); } return (1); } static int filldatagap( vm_address_t start_address, vm_size_t *size, vm_address_t end_address ) { vm_address_t address; vm_size_t gapsize; address = (start_address + *size); gapsize = end_address - address; *size += gapsize; if (vm_allocate(task_self(), &address, gapsize, FALSE) != KERN_SUCCESS) { fatal_unexec("cannot vm_allocate"); return (0); } return (1); } static int get_data_region( vm_address_t *address, vm_size_t *size ) { region_t region; kern_return_t ret; struct section *sect; sect = (struct section *) getsectbyname(SEG_DATA, SECT_DATA); region.address = 0; *address = 0; for (;;) { ret = vm_region(task_self(), ®ion.address, ®ion.size, ®ion.protection, ®ion.max_protection, ®ion.inheritance, ®ion.shared, ®ion.object_name, ®ion.offset); if (ret != KERN_SUCCESS || region.address >= VM_HIGHDATA) { break; } if (*address != 0) { if (region.address > *address + *size) { if (!filldatagap(*address, size, region.address)) { return (0); } } *size += region.size; } else { if (region.address == sect->addr) { *address = region.address; *size = region.size; } } region.address += region.size; } return (1); } static char * my_malloc( vm_size_t size ) { vm_address_t address; if (vm_allocate(task_self(), &address, size, TRUE) != KERN_SUCCESS) { return (NULL); } return ((char *)address); } static void my_free( char *buf, vm_size_t size ) { vm_deallocate(task_self(), (vm_address_t)buf, size); } static int unexec_doit( int infd, int outfd ) { int i; struct load_command **the_commands = NULL; unsigned the_commands_len; struct mach_header the_header; int fgrowth = 0; int fdatastart; int fdatasize; int size; struct stat st; char *buf; vm_address_t data_address; vm_size_t data_size; vm_size_t vmaddr_growth = 0; vm_size_t dataseg_vmaddr, dataseg_vmend; struct segment_command *segment; #ifdef NS_TARGET unsigned long extreloff = 0; unsigned long nextrel = 0; struct dysymtab_command *dysymtab; struct relocation_info reloc_info; #endif if (!read_macho(infd, &the_header, &the_commands, &the_commands_len)) { return (0); } malloc_cookie = malloc_freezedry (); if (!get_data_region(&data_address, &data_size)) { return (0); } /* * DO NOT USE MALLOC IN THIS SECTION */ { /* * Fix offsets */ for (i = 0; i < the_commands_len; i++) { switch (the_commands[i]->cmd) { case LC_SEGMENT: segment = ((struct segment_command *) the_commands[i]); if (strcmp(segment->segname, SEG_DATA) == 0) { fdatastart = segment->fileoff; fdatasize = segment->filesize; fgrowth = (data_size - segment->filesize); segment->vmsize = data_size; segment->filesize = data_size; dataseg_vmaddr = segment->vmaddr; dataseg_vmend = segment->vmaddr + segment->vmsize; vmaddr_growth = segment->vmaddr + segment->vmsize; } else { ((struct segment_command *)the_commands[i])->fileoff += fgrowth; } if( strcmp( segment->segname, SEG_LINKEDIT ) == 0 ) { segment->vmaddr = vmaddr_growth; } break; case LC_SYMTAB: ((struct symtab_command *) the_commands[i])->symoff += fgrowth; ((struct symtab_command *) the_commands[i])->stroff += fgrowth; break; case LC_SYMSEG: ((struct symseg_command *) the_commands[i])->offset += fgrowth; break; #ifdef NS_TARGET case LC_DYSYMTAB: dysymtab = ((struct dysymtab_command *)the_commands[i]); extreloff = dysymtab->extreloff; nextrel = dysymtab->nextrel; dysymtab->indirectsymoff += fgrowth; dysymtab->extreloff += fgrowth; break; #endif default: break; } } /* * Write header */ if (write(outfd, &the_header, sizeof(the_header)) != sizeof(the_header)) { fatal_unexec("cannot write output file"); return (0); } /* * Write commands */ for (i = 0; i < the_commands_len; i++) { if (write(outfd, the_commands[i], the_commands[i]->cmdsize) != the_commands[i]->cmdsize) { fatal_unexec("cannot write output file"); return (0); } } /* * Write original text */ if (lseek(infd, the_header.sizeofcmds + sizeof(the_header), L_SET) < 0) { fatal_unexec("cannot seek input file"); return (0); } size = fdatastart - (sizeof(the_header) + the_header.sizeofcmds); buf = my_malloc(size); if (read(infd, buf, size) != size) { my_free(buf, size); fatal_unexec("cannot read input file"); } if (write(outfd, buf, size) != size) { my_free(buf, size); fatal_unexec("cannot write output file"); return (0); } my_free(buf, size); /* * Write new data */ if (write(outfd, (char *)data_address, data_size) != data_size) { fatal_unexec("cannot write output file"); return (0); } } /* * OKAY TO USE MALLOC NOW */ /* * Write rest of file */ fstat(infd, &st); if (lseek(infd, fdatasize, L_INCR) < 0) { fatal_unexec("cannot seek input file"); return (0); } size = st.st_size - lseek(infd, 0, L_INCR); buf = malloc(size); if (read(infd, buf, size) != size) { free(buf); fatal_unexec("cannot read input file"); return (0); } if (write(outfd, buf, size) != size) { free(buf); fatal_unexec("cannot write output file"); return (0); } free(buf); #ifdef NS_TARGET /* * Fix up relocation entries in the data segment. */ if (lseek(infd, extreloff, L_SET) < 0) { fatal_unexec("cannot seek input file"); return (0); } for (i = 0; i < nextrel; i++) { long zeroval = 0; if (read(infd, &reloc_info, sizeof (reloc_info)) != sizeof (reloc_info)) { fatal_unexec("cannot read input file"); return (0); } if (reloc_info.r_address >= dataseg_vmaddr && reloc_info.r_address < dataseg_vmend) { if (lseek (outfd, fdatastart + reloc_info.r_address - dataseg_vmaddr, L_SET) < 0 ) { fatal_unexec("cannot seek input file"); return (0); } switch (reloc_info.r_length) { case 0: if (write(outfd, &zeroval, 1) != 1) { fatal_unexec("cannot write output file"); return (0); } break; case 1: if (write(outfd, &zeroval, 2) != 2) { fatal_unexec("cannot write output file"); return (0); } break; case 2: if (write(outfd, &zeroval, 4) != 4) { fatal_unexec("cannot write output file"); return (0); } break; } } } #endif return (1); } void unexec( char *outfile, char *infile ) { int infd; int outfd; char tmpbuf[L_tmpnam]; char *tmpfile; infd = open(infile, O_RDONLY, 0); if (infd < 0) { fatal_unexec("cannot open input file `%s'", infile); exit(1); } tmpnam(tmpbuf); tmpfile = rindex(tmpbuf, '/'); if (tmpfile == NULL) { tmpfile = tmpbuf; } else { tmpfile++; } outfd = open(tmpfile, O_WRONLY|O_TRUNC|O_CREAT, 0755); if (outfd < 0) { close(infd); fatal_unexec("cannot open tmp file `%s'", tmpfile); exit(1); } if (!unexec_doit(infd, outfd)) { close(infd); close(outfd); unlink(tmpfile); exit(1); } close(infd); close(outfd); if (rename(tmpfile, outfile) < 0) { unlink(tmpfile); fatal_unexec("cannot rename `%s' to `%s'", tmpfile, outfile); exit(1); } } /* arch-tag: 9796bdc3-c050-417a-b2f5-4cfd31032634 (do not change this comment) */