diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1995-06-11 19:33:05 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1995-06-11 19:33:05 +0000 |
commit | 1b1ee5553889e207087539ddafa5dfd4e28bd585 (patch) | |
tree | ba998dfb4fcad03e00a5cbf58e2a0ad648bab6e6 /lib | |
parent | b1a97daa1e06ab0de3071f979965878fd056292b (diff) | |
download | FreeBSD-src-1b1ee5553889e207087539ddafa5dfd4e28bd585.zip FreeBSD-src-1b1ee5553889e207087539ddafa5dfd4e28bd585.tar.gz |
Merge RELENG_2_0_5 into HEAD
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/gen/getpwent.c | 9 | ||||
-rw-r--r-- | lib/libdisk/change.c | 4 | ||||
-rw-r--r-- | lib/libdisk/chunk.c | 30 | ||||
-rw-r--r-- | lib/libdisk/create_chunk.c | 4 | ||||
-rw-r--r-- | lib/libdisk/disk.c | 7 | ||||
-rw-r--r-- | lib/libdisk/libdisk.h | 14 | ||||
-rw-r--r-- | lib/libdisk/rules.c | 89 | ||||
-rw-r--r-- | lib/libdisk/tst01.c | 10 | ||||
-rw-r--r-- | lib/libdisk/write_disk.c | 8 | ||||
-rw-r--r-- | lib/libskey/skey_crypt.c | 2 | ||||
-rw-r--r-- | lib/libskey/skey_getpass.c | 2 | ||||
-rw-r--r-- | lib/libskey/skeyaccess.c | 6 | ||||
-rw-r--r-- | lib/libskey/skeylogin.c | 29 | ||||
-rw-r--r-- | lib/libskey/skeysubr.c | 43 |
14 files changed, 172 insertions, 85 deletions
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index 22b1485..8b17ca2 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -496,6 +496,15 @@ static void _pw_breakout_yp(struct passwd *pw, char *result, int master) { char *s; + static char name[UT_NAMESIZE+2], passwd[_PASSWORD_LEN], class[1024]; + static char gecos[1024], dir[MAXPATHLEN], shell[MAXPATHLEN]; + + strcpy(name, pw->pw_name); pw->pw_name = (char *)&name; + strcpy(passwd, pw->pw_passwd); pw->pw_passwd = (char *)&passwd; + strcpy(class, pw->pw_class); pw->pw_class = (char *)&class; + strcpy(gecos, pw->pw_gecos); pw->pw_gecos = (char *)&gecos; + strcpy(dir, pw->pw_dir); pw->pw_dir = (char *)&dir; + strcpy(shell, pw->pw_shell); pw->pw_shell = (char *)&shell; s = strsep(&result, ":"); /* name */ if(!(pw->pw_fields & _PWF_NAME) || (pw->pw_name[0] == '+')) { diff --git a/lib/libdisk/change.c b/lib/libdisk/change.c index ab5a46c..57ccbfa 100644 --- a/lib/libdisk/change.c +++ b/lib/libdisk/change.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: change.c,v 1.7 1995/05/25 06:14:45 phk Exp $ + * $Id: change.c,v 1.8.2.1 1995/06/05 02:24:20 jkh Exp $ * */ @@ -19,6 +19,7 @@ #include <sys/types.h> #include "libdisk.h" +#if 0 struct disk * Set_Phys_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect) { @@ -33,6 +34,7 @@ Set_Phys_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect) Free_Disk(disk); return d; } +#endif void Set_Bios_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect) diff --git a/lib/libdisk/chunk.c b/lib/libdisk/chunk.c index a7d7c85..906911a 100644 --- a/lib/libdisk/chunk.c +++ b/lib/libdisk/chunk.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: chunk.c,v 1.13 1995/05/25 06:14:47 phk Exp $ + * $Id: chunk.c,v 1.14.2.2 1995/06/05 02:24:25 jkh Exp $ * */ @@ -261,6 +261,22 @@ Add_Chunk(struct disk *d, long offset, u_long size, char *name, chunk_e type, return __LINE__; } +char * +ShowChunkFlags(struct chunk *c) +{ + static char ret[10]; + + int i=0; + if (c->flags & CHUNK_BSD_COMPAT) ret[i++] = 'C'; + if (c->flags & CHUNK_ACTIVE) ret[i++] = 'A'; + if (c->flags & CHUNK_ALIGN) ret[i++] = '='; + if (c->flags & CHUNK_PAST_1024) ret[i++] = '>'; + if (c->flags & CHUNK_IS_ROOT) ret[i++] = 'R'; + if (c->flags & CHUNK_BAD144) ret[i++] = 'B'; + ret[i++] = '\0'; + return ret; +} + void Print_Chunk(struct chunk *c1,int offset) { @@ -270,14 +286,10 @@ Print_Chunk(struct chunk *c1,int offset) for(;i<offset;i++) putchar('-'); putchar('>'); for(;i<10;i++) putchar(' '); - printf("%p %8ld %8lu %8lu %-8s %-8s 0x%02x ", + printf("%p %8ld %8lu %8lu %-8s %-8s 0x%02x %s", c1, c1->offset, c1->size, c1->end, c1->name, - chunk_n[c1->type],c1->subtype); - if (c1->flags & CHUNK_ALIGN) putchar('='); - if (c1->flags & CHUNK_PAST_1024) putchar('>'); - if (c1->flags & CHUNK_IS_ROOT) putchar('R'); - if (c1->flags & CHUNK_BAD144) putchar('B'); - if (c1->flags & CHUNK_BSD_COMPAT) putchar('C'); + chunk_n[c1->type],c1->subtype, + ShowChunkFlags(c1)); putchar('\n'); Print_Chunk(c1->part,offset + 2); Print_Chunk(c1->next,offset); @@ -354,6 +366,7 @@ Delete_Chunk(struct disk *d, struct chunk *c) return 0; } +#if 0 int Collapse_Chunk(struct disk *d, struct chunk *c1) { @@ -417,3 +430,4 @@ Collapse_Chunk(struct disk *d, struct chunk *c1) return 0; } +#endif diff --git a/lib/libdisk/create_chunk.c b/lib/libdisk/create_chunk.c index e019752..ad0c802 100644 --- a/lib/libdisk/create_chunk.c +++ b/lib/libdisk/create_chunk.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: create_chunk.c,v 1.19 1995/05/24 08:59:38 jkh Exp $ + * $Id: create_chunk.c,v 1.20.2.1 1995/05/31 23:53:45 jkh Exp $ * */ @@ -190,7 +190,7 @@ Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e ty warn("Not enough unused space"); return 0; found: - if (c1->flags & CHUNK_BAD144) { + if (parent->flags & CHUNK_BAD144) { edge = c1->end - d->bios_sect - 127; if (offset > edge) return 0; diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c index e3899c7..cfac7b5 100644 --- a/lib/libdisk/disk.c +++ b/lib/libdisk/disk.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: disk.c,v 1.18 1995/05/08 02:08:28 phk Exp $ + * $Id: disk.c,v 1.19.2.2 1995/06/05 02:24:27 jkh Exp $ * */ @@ -199,6 +199,7 @@ Int_Open_Disk(char *name, u_long size) } close(fd); Fixup_Names(d); + Bios_Limit_Chunk(d->chunks,1024*d->bios_hd*d->bios_sect); return d; } @@ -207,7 +208,9 @@ Debug_Disk(struct disk *d) { printf("Debug_Disk(%s)",d->name); printf(" flags=%lx",d->flags); +#if 0 printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect); +#endif printf(" bios_geom=%lu/%lu/%lu\n",d->bios_cyl,d->bios_hd,d->bios_sect); printf(" boot1=%p, boot2=%p, bootmgr=%p\n", d->boot1,d->boot2,d->bootmgr); @@ -250,6 +253,7 @@ Clone_Disk(struct disk *d) return d2; } +#if 0 void Collapse_Disk(struct disk *d) { @@ -257,6 +261,7 @@ Collapse_Disk(struct disk *d) while(Collapse_Chunk(d,d->chunks)) ; } +#endif static char * device_list[] = {"wd","sd",0}; diff --git a/lib/libdisk/libdisk.h b/lib/libdisk/libdisk.h index 6ba7bbb..e7d6bd3 100644 --- a/lib/libdisk/libdisk.h +++ b/lib/libdisk/libdisk.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: libdisk.h,v 1.17 1995/05/25 06:14:49 phk Exp $ + * $Id: libdisk.h,v 1.18.2.2 1995/06/05 02:24:32 jkh Exp $ * */ @@ -29,9 +29,11 @@ struct disk { char *name; u_long flags; # define DISK_ON_TRACK 1 +#if 0 u_long real_cyl; u_long real_hd; u_long real_sect; +#endif u_long bios_cyl; u_long bios_hd; u_long bios_sect; @@ -103,11 +105,13 @@ Debug_Disk(struct disk *disk); /* Print the content of the tree to stdout */ +#if 0 struct disk * Set_Phys_Geom(struct disk *disk, u_long cyl, u_long heads, u_long sects); /* Use a different physical geometry. Makes sense for ST506 disks only. * The tree returned is read from the disk, using this geometry. */ +#endif void Set_Bios_Geom(struct disk *disk, u_long cyl, u_long heads, u_long sects); @@ -211,6 +215,14 @@ void MakeDevDisk(struct disk *d,char *path); /* Make device nodes for all chunks on this disk */ +char * +ShowChunkFlags(struct chunk *c); + /* Return string to show flags. */ + +char * +ChunkCanBeRoot(struct chunk *c); + /* Return NULL if chunk can be /, explanation otherwise */ + /* * Implementation details >>> DO NOT USE <<< */ diff --git a/lib/libdisk/rules.c b/lib/libdisk/rules.c index 73a321c..1ea9ca8 100644 --- a/lib/libdisk/rules.c +++ b/lib/libdisk/rules.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: rules.c,v 1.9 1995/05/08 01:34:31 phk Exp $ + * $Id: rules.c,v 1.10.2.1 1995/06/03 08:40:33 jkh Exp $ * */ @@ -179,22 +179,44 @@ Rule_003(struct disk *d, struct chunk *c, char *msg) /* * Rule#4: * Max seven 'part' as children of 'freebsd' - * Max one FS_SWAP child per 'freebsd' * Max one CHUNK_IS_ROOT child per 'freebsd' + * If Bad144, space for table must exist. + * If Bad144 & root, bad144 table must be inside 1024 */ void Rule_004(struct disk *d, struct chunk *c, char *msg) { - int i=0,j=0,k=0; + int i=0,k=0; struct chunk *c1; + u_long l; if (c->type != freebsd) return; + + if (c->flags & CHUNK_BAD144) { + l = c->end - 127 - d->bios_sect + 1; + for (c1=c->part; c1; c1=c1->next) { + if (c1->end < l || c1->type == unused) + continue; + sprintf(msg+strlen(msg), + "Blocks %lu to %lu are needed for bad144 information, but isn't unused.\n", + l, c->end); + break; + } + if (c->flags & CHUNK_PAST_1024) { + for (c1=c->part; c1; c1=c1->next) { + if (c1->flags & CHUNK_IS_ROOT) { + sprintf(msg+strlen(msg), + "You have assigned root to a slice which uses bad144, and\n extends past the first 1023 cylinders, and thus cannot be booted from.\n"); + break; + } + } + } + } + for (c1=c->part; c1; c1=c1->next) { if (c1->type != part) continue; - if (c1->subtype == FS_SWAP) - j++; if (c1->flags & CHUNK_IS_ROOT) { k++; if (c1->flags & CHUNK_PAST_1024) @@ -205,15 +227,11 @@ Rule_004(struct disk *d, struct chunk *c, char *msg) } if (i > 7) { sprintf(msg+strlen(msg), - "Max seven 'part' per 'freebsd' chunk\n"); - } - if (j > 1) { - sprintf(msg+strlen(msg), - "Max one subtype=FS_SWAP child per 'freebsd' chunk\n"); + "Max seven partitions per freebsd slice\n"); } if (k > 1) { sprintf(msg+strlen(msg), - "Max one CHUNK_IS_ROOT child per 'freebsd' chunk\n"); + "Max one root partition child per freebsd slice\n"); } } @@ -247,3 +265,52 @@ CheckRules(struct disk *d) return strdup(msg); return 0; } + +char * +ChunkCanBeRoot(struct chunk *c) +{ + struct chunk *c1; + struct disk *d = c->disk; + char msg[BUFSIZ]; + + *msg = '\0'; + if (c->flags & CHUNK_PAST_1024) { + strcat(msg, +"The root partition must end before cylinder 1024 seen from\n"); + strcat(msg, +"the BIOS' point of view, or it cannot be booted from.\n"); + return strdup(msg); + } + for (c1=d->chunks->part;;) { + for (; c1; c1=c1->next) + if (c1->offset <= c->offset && c1->end >= c->end) + break; + if (!c1) { + strcat(msg, +"Internal trouble, cannot find this chunk in the chunk-tree\n"); + return strdup(msg); + } + if (c1->type == freebsd) + break; + c1 = c1->part; + } + + if (c1->type != freebsd) { + strcat(msg, +"The root partition must be in a FreeBSD slice, otherwise\n"); + strcat(msg, +"the kernel cannot be booted from it\n"); + return strdup(msg); + } + + if ((c1->flags & CHUNK_BAD144) && (c1->flags & CHUNK_PAST_1024)) { + strcat(msg, +"This partition is unsuitable for root, because the FreeBSD slice\n"); + strcat(msg, +"it is inside has bad144 enabled, but the badblock data lives past\n"); + strcat(msg, +"the 1024th cylinder, and the bootblocks cannot get to it there.\n"); + return strdup(msg); + } + return NULL; +} diff --git a/lib/libdisk/tst01.c b/lib/libdisk/tst01.c index 506e3b9..2793778 100644 --- a/lib/libdisk/tst01.c +++ b/lib/libdisk/tst01.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: tst01.c,v 1.13 1995/05/12 18:50:00 phk Exp $ + * $Id: tst01.c,v 1.14.2.1 1995/06/05 02:24:35 jkh Exp $ * */ @@ -199,6 +199,7 @@ main(int argc, char **argv) strtol(cmds[3],0,0)); continue; } +#if 0 if (!strcasecmp(*cmds,"phys") && ncmd == 4) { d = Set_Phys_Geom(d, strtol(cmds[1],0,0), @@ -206,6 +207,8 @@ main(int argc, char **argv) strtol(cmds[3],0,0)); continue; } +#endif +#if 0 if (!strcasecmp(*cmds,"collapse")) { if (cmds[1]) while (Collapse_Chunk(d, @@ -215,6 +218,7 @@ main(int argc, char **argv) Collapse_Disk(d); continue; } +#endif if (!strcasecmp(*cmds,"list")) { cp = Disk_Names(); printf("Disks:"); @@ -279,13 +283,17 @@ main(int argc, char **argv) printf("\tbios cyl hd sect\n"); printf("\tboot\n"); printf("\tbteasy17\n"); +#if 0 printf("\tcollapse [pointer]\n"); +#endif printf("\tcreate offset size enum subtype flags\n"); printf("\t\tsubtype(part): swap=1, ffs=7\n"); printf("\tdelete pointer\n"); printf("\tlist\n"); printf("\tmbr\n"); +#if 0 printf("\tphys cyl hd sect\n"); +#endif printf("\tquit\n"); printf("\tread [disk]\n"); printf("\tscan\n"); diff --git a/lib/libdisk/write_disk.c b/lib/libdisk/write_disk.c index e2c0674..dc46bee 100644 --- a/lib/libdisk/write_disk.c +++ b/lib/libdisk/write_disk.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: write_disk.c,v 1.12 1995/05/24 08:59:40 jkh Exp $ + * $Id: write_disk.c,v 1.13.2.1 1995/06/05 02:24:37 jkh Exp $ * */ @@ -69,9 +69,15 @@ Write_FreeBSD(int fd, struct disk *new, struct disk *old, struct chunk *c1) dl->d_secsize = 512; dl->d_secperunit = new->chunks->size; +#if 0 dl->d_secpercyl = new->real_cyl ? new->real_cyl : new->bios_cyl; dl->d_ntracks = new->real_hd ? new->real_hd : new->bios_hd; dl->d_nsectors = new->real_sect ? new->real_sect : new->bios_sect; +#else + dl->d_secpercyl = new->bios_cyl; + dl->d_ntracks = new->bios_hd; + dl->d_nsectors = new->bios_sect; +#endif dl->d_secpercyl = dl->d_ntracks * dl->d_nsectors; dl->d_npartitions = MAXPARTITIONS; diff --git a/lib/libskey/skey_crypt.c b/lib/libskey/skey_crypt.c index ca1024f..79e5635 100644 --- a/lib/libskey/skey_crypt.c +++ b/lib/libskey/skey_crypt.c @@ -20,7 +20,7 @@ int pwok; /* Try s/key authentication even when the UNIX password is permitted. */ - if (pwd != 0 && skeylookup(&skey, pwd->pw_name) == 0 + if (pwd != 0 && skeyinfo(&skey, pwd->pw_name, (char *) 0) == 0 && skeyverify(&skey, pp) == 0) { /* s/key authentication succeeded */ return (pwd->pw_passwd); diff --git a/lib/libskey/skey_getpass.c b/lib/libskey/skey_getpass.c index 9fd05d0..e8d50d3 100644 --- a/lib/libskey/skey_getpass.c +++ b/lib/libskey/skey_getpass.c @@ -16,7 +16,7 @@ int pwok; int sflag; /* Attempt an s/key challenge. */ - sflag = skeychallenge(&skey, username, buf); + sflag = skeyinfo(&skey, username, buf); if (!sflag) printf("%s\n", buf); diff --git a/lib/libskey/skeyaccess.c b/lib/libskey/skeyaccess.c index 098d618..3cb707f 100644 --- a/lib/libskey/skeyaccess.c +++ b/lib/libskey/skeyaccess.c @@ -69,6 +69,10 @@ static struct in_addr *lookup_internet_addr(); #define PERMIT 1 #define DENY 0 +#ifndef CONSOLE +#define CONSOLE "console" +#endif + struct login_info { char *host_name; /* host name */ struct in_addr *internet_addr; /* null terminated list */ @@ -163,7 +167,7 @@ struct login_info *login_info; int permission; #ifdef PERMIT_CONSOLE - if (login_info->port != 0 && strcasecmp(login_info->port, "console") == 0) + if (login_info->port != 0 && strcasecmp(login_info->port, CONSOLE) == 0) return (1); #endif diff --git a/lib/libskey/skeylogin.c b/lib/libskey/skeylogin.c index 93a5d1d..229fc61 100644 --- a/lib/libskey/skeylogin.c +++ b/lib/libskey/skeylogin.c @@ -26,29 +26,30 @@ int skeylookup __P((struct skey *mp,char *name)); #define setpriority(x,y,z) /* nothing */ -/* Issue a skey challenge for user 'name'. If successful, - * fill in the caller's skey structure and return 0. If unsuccessful - * (e.g., if name is unknown) return -1. +/* Look up skey info for user 'name'. If successful, fill in the caller's + * skey structure and return 0. If unsuccessful (e.g., if name is unknown) + * return -1. If an optional challenge string buffer is given, update it. * * The file read/write pointer is left at the start of the * record. */ int -getskeyprompt(mp,name,prompt) +skeyinfo(mp,name,ss) struct skey *mp; char *name; -char *prompt; +char *ss; { int rval; - sevenbit(name); rval = skeylookup(mp,name); - strcpy(prompt,"s/key 55 latour1\n"); switch(rval){ case -1: /* File error */ return -1; - case 0: /* Lookup succeeded, return challenge */ - sprintf(prompt,"s/key %d %s\n",mp->n - 1,mp->seed); + case 0: /* Lookup succeeded */ + if (ss != 0) { + sprintf(ss, "s/key %d %s",mp->n - 1,mp->seed); + fclose(mp->keyfile); + } return 0; case 1: /* User not found */ fclose(mp->keyfile); @@ -173,7 +174,6 @@ char *response; { struct timeval startval; struct timeval endval; -long microsec; char key[8]; char fkey[8]; char filekey[8]; @@ -211,9 +211,6 @@ long microsec; */ setpriority(PRIO_PROCESS, 0, -4); -/* - gettimeofday(&startval, (char *)0 ); -*/ /* reread the file record NOW*/ @@ -256,12 +253,6 @@ long microsec; fseek(mp->keyfile,mp->recstart,0); fprintf(mp->keyfile,"%s %04d %-16s %s %-21s\n",mp->logname,mp->n,mp->seed, mp->val, tbuf); -/* -gettimeofday(&endval, (char *)0 ); - microsec = (endval.tv_sec - startval.tv_sec) * 1000000 + (endval.tv_usec - startval.tv_usec); -fprintf(stderr, "window= %d micro seconds \n" , microsec); -*/ - fclose(mp->keyfile); diff --git a/lib/libskey/skeysubr.c b/lib/libskey/skeysubr.c index 3911b32..68564cf 100644 --- a/lib/libskey/skeysubr.c +++ b/lib/libskey/skeysubr.c @@ -1,20 +1,15 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#ifdef __MSDOS__ -#include <dos.h> -#endif -#ifdef unix #include <fcntl.h> #include <termios.h> #include <signal.h> -#endif #include "skey.h" #include "mdx.h" /* Crunch a key: - * concatenate the seed and the password, run through MD4 and + * concatenate the seed and the password, run through MDX and * collapse to 64 bits. This is defined as the user's starting key. */ int @@ -64,7 +59,6 @@ char *x; results[0] ^= results[2]; results[1] ^= results[3]; - /* Only works on byte-addressed little-endian machines!! */ memcpy(x,(char *)results,8); } @@ -73,36 +67,13 @@ void rip(buf) char *buf; { - char *cp; - - if((cp = strchr(buf,'\r')) != NULL) - *cp = '\0'; - - if((cp = strchr(buf,'\n')) != NULL) - *cp = '\0'; -} -/************************/ -#ifdef __MSDOS__ -char * -readpass(buf,n) -char *buf; -int n; -{ - int i; - char *cp; - - for(cp=buf,i = 0; i < n ; i++) - if ((*cp++ = bdos(7,0,0)) == '\r') - break; - *cp = '\0'; - printf("\n"); - rip(buf); - return buf; + buf[strcspn(buf, "\r\n")] = 0; } -#else + static struct termios saved_ttymode; -static void interrupt() +static void interrupt(sig) +int sig; { tcsetattr(0, TCSANOW, &saved_ttymode); exit(1); @@ -147,14 +118,12 @@ int n; return buf; } -#endif - sevenbit(s) char *s; { /* make sure there are only 7 bit code in the line*/ while(*s){ - *s = 0x7f & ( *s); + *s &= 0x7f; s++; } } |