int order_should_stop(){ int current_floor = control_getcurpos(); if(current_floor==BETWEEN_FLOORS){ return 0; } if(current_floor==N_FLOORS-1 || current_floor==0) { return 1; } struct node * head = gethead(); if(get_last_dir()==UP){ if((head->elevinfo.current_orders[current_floor][COMMAND].active==1) || (head->elevinfo.current_orders[current_floor][CALL_UP].active==1)) { return 1; } else if(!order_check_request_above()){ return 1; } } else if(get_last_dir()==DOWN) { if((head->elevinfo.current_orders[current_floor][COMMAND].active==1) || (head->elevinfo.current_orders[current_floor][CALL_DOWN].active==1)) { return 1; } else if(!order_check_request_below()){ return 1; } } return 0; }
/* xlpeek - peek at a character from a file or stream */ int xlpeek(LVAL fptr) { LVAL lptr, cptr=NULL; int ch; /* check for input from nil */ if (fptr == NIL) ch = EOF; /* otherwise, check for input from a stream */ else if (ustreamp(fptr)) { if ((lptr = gethead(fptr)) == NIL) ch = EOF; else { if (!consp(lptr) || (cptr = car(lptr)) == NIL || !charp(cptr)) xlfail("bad stream"); ch = getchcode(cptr); } } /* otherwise, get the next file character and save it */ else { ch = xlgetc(fptr); setsavech(fptr,ch); } /* return the character */ return (ch); }
/* xlgetc - get a character from a file or stream */ int xlgetc P1C(LVAL, fptr) { LVAL lptr,cptr=NULL; FILEP fp; int ch; /* check for input from nil */ if (fptr == NIL) ch = EOF; /* otherwise, check for input from a stream */ else if (ustreamp(fptr)) { if ((lptr = gethead(fptr)) == NIL) ch = EOF; else { if (!consp(lptr) || (cptr = car(lptr)) == NIL || !charp(cptr)) xlfail("bad stream"); sethead(fptr,lptr = cdr(lptr)); if (lptr == NIL) settail(fptr,NIL); ch = getchcode(cptr); } } /* otherwise, check for a buffered character */ else if ((ch = getsavech(fptr)) != 0) setsavech(fptr,'\0'); /* otherwise, check for terminal input or file input */ else { fp = getfile(fptr); if (fp == CLOSED) /* TAA MOD -- give error */ xlfail("can't read closed stream"); else if (fp == CONSOLE) /* TAA MOD -- revamped for redirecting */ ch = ostgetc(); else { if ((fptr->n_sflags & S_FORREADING) == 0) xlerror("can't read write-only file stream", fptr); if ((fptr->n_sflags & S_READING) == 0) { /* possible direction change*/ if (fptr->n_sflags & S_WRITING) { OSSEEKCUR(fp,0L); } fptr->n_sflags |= S_READING; fptr->n_sflags &= ~S_WRITING; } #ifdef OSAGETC ch = (fptr->n_sflags & S_BINARY) ? OSGETC(fp) : OSAGETC(fp); #else ch = OSGETC(fp); #endif } } /* return the character */ return (ch); }
main(sqqueue *head) { int n,i,m,x,y,select,xq; printf("create a empty sequeue\n"); sqinit(head); printf("please input the sequeue length:\n"); scanf("%d",&n); for (i=0;i<n;i++) { printf("please input a sequeue value:\n"); scanf("%d",&m); enqueue(head,m);} printf("head->rear:%d\n",head->rear); printf("head->front:%d\n",head->front); display(head); printf("select 1 **** enqueue() \n"); printf("select 2 **** dequeue() \n"); printf("select 3 **** empty () \n"); printf("select 4 **** gethead() \n"); printf("select 5 **** display() \n"); printf("please select (1--5):"); scanf("%d",&select); switch(select) { case 1: { printf("please input a value :\n "); scanf("%d",&x); enqueue(head,x); display(head); break; } case 2: { dequeue(head); display(head); break; } case 3: { if(empty(head)) printf("the sequeue is empty"); else printf("the sequeue is full"); } case 4: { y=gethead(head); printf("output head value:%d\n",y); break; } case 5: { display(head); break; } } }
/* * Extract a file from the tape. * When an allocated block is found it is passed to the fill function; * when an unallocated block (hole) is found, a zeroed buffer is passed * to the skip function. * * For some block types (TS_BITS, TS_CLRI), the c_addr map is not meaningful * and no blocks should be skipped. */ void getfile(void (*fill)(char *, size_t), void (*skip)(char *, size_t)) { int i; volatile int curblk = 0; volatile off_t size = spcl.c_size; static char clearedbuf[MAXBSIZE]; char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE]; char junk[TP_BSIZE]; volatile int noskip = (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI); if (spcl.c_type == TS_END) panic("ran off end of tape\n"); if (spcl.c_magic != FS_UFS2_MAGIC) panic("not at beginning of a file\n"); if (!gettingfile && setjmp(restart) != 0) return; gettingfile++; loop: for (i = 0; i < spcl.c_count; i++) { if (noskip || spcl.c_addr[i]) { readtape(&buf[curblk++][0]); if (curblk == fssize / TP_BSIZE) { (*fill)((char *)buf, size > TP_BSIZE ? fssize : ((off_t)curblk - 1) * TP_BSIZE + size); curblk = 0; } } else { if (curblk > 0) { (*fill)((char *)buf, size > TP_BSIZE ? (curblk * TP_BSIZE) : ((off_t)curblk - 1) * TP_BSIZE + size); curblk = 0; } (*skip)(clearedbuf, size > TP_BSIZE ? TP_BSIZE : size); } if ((size -= TP_BSIZE) <= 0) { for (i++; i < spcl.c_count; i++) if (noskip || spcl.c_addr[i]) readtape(junk); break; } } if (gethead(&spcl) == GOOD && size > 0) { if (spcl.c_type == TS_ADDR) goto loop; Dprintf(stdout, "Missing address (header) block for %s at %ld blocks\n", curfile.name, blksread); } if (curblk > 0) (*fill)((char *)buf, ((off_t)curblk * TP_BSIZE) + size); findinode(&spcl); gettingfile = 0; }
void clear_order_all_elev(int floor, int panel){ struct node * iter = gethead(); if(panel==COMMAND) iter->elevinfo.current_orders[floor][panel].active = 0; else { while(iter!=0){ iter->elevinfo.current_orders[floor][panel].active = 0; iter = iter->next; } } }
/* xlungetc - unget a character */ VOID xlungetc P2C(LVAL, fptr, int, ch) { LVAL lptr; /* check for ungetc from nil, or ungetc of EOF */ if (fptr == NIL || ch == EOF) ; /* otherwise, check for ungetc to a stream */ else if (ustreamp(fptr)) { lptr = cons(cvchar(ch),gethead(fptr)); if (gethead(fptr) == NIL) settail(fptr,lptr); sethead(fptr,lptr); } /* otherwise, it must be a file */ else setsavech(fptr,ch); }
int order_requests(){ int floor, panel; struct node * head = gethead(); for (panel = CALL_UP; panel<=COMMAND; panel++){ for(floor = 0; floor< N_FLOORS; floor ++){ if(head->elevinfo.current_orders[floor][panel].active){ return 1; } } } return 0; }
/* xlungetc - unget a character */ void xlungetc(LVAL fptr, int ch) { LVAL lptr; /* check for ungetc from nil */ if (fptr == NIL || ch == EOF) ; /* otherwise, check for ungetc to a stream */ else if (ustreamp(fptr)) { if (ch != EOF) { lptr = cons(cvchar(ch),gethead(fptr)); if (gethead(fptr) == NIL) settail(fptr,lptr); sethead(fptr,lptr); } } /* otherwise, it must be a file */ else setsavech(fptr,ch); }
/* xlgetc - get a character from a file or stream */ int xlgetc(LVAL fptr) { LVAL lptr, cptr=NULL; FILE *fp; int ch; /* check for input from nil */ if (fptr == NIL) ch = EOF; /* otherwise, check for input from a stream */ else if (ustreamp(fptr)) { if ((lptr = gethead(fptr)) == NIL) ch = EOF; else { if (!consp(lptr) || (cptr = car(lptr)) == NIL || !charp(cptr)) xlfail("bad stream"); sethead(fptr,lptr = cdr(lptr)); if (lptr == NIL) settail(fptr,NIL); ch = getchcode(cptr); } } /* otherwise, check for a buffered character */ else if ((ch = getsavech(fptr))) setsavech(fptr,'\0'); /* otherwise, check for terminal input or file input */ else { fp = getfile(fptr); if (fp == stdin || fp == STDERR) ch = ostgetc(); else ch = osagetc(fp); #ifdef DEBUG_INPUT if (read_by_xlisp && ch != -1) { putc(ch, read_by_xlisp); } #endif } /* return the character */ return (ch); }
/* xgetlstoutput - get output stream list */ LVAL xgetlstoutput(void) { LVAL stream,val; /* get the stream */ stream = xlgaustream(); xllastarg(); /* get the output character list */ val = gethead(stream); /* empty the character list */ sethead(stream,NIL); settail(stream,NIL); /* return the list */ return (val); }
/* getstroutput - get the output stream string (internal) */ LOCAL LVAL getstroutput(LVAL stream) { unsigned char *str; LVAL next,val; int len,ch; /* compute the length of the stream */ for (len = 0, next = gethead(stream); next != NIL; next = cdr(next)) ++len; /* create a new string */ val = new_string(len + 1); /* copy the characters into the new string */ str = getstring(val); while ((ch = xlgetc(stream)) != EOF) *str++ = ch; *str = '\0'; /* return the string */ return (val); }
int main() { int servse=-1; //服务标识 while(servse!=0) { printf("\n1.创建队列\n"); printf("2.元素进队\n"); printf("3.元素出列\n"); printf("4.打印队列\n"); printf("0.退出\n"); printf("选择:"); scanf("%d",&servse); switch(servse) { case 1:creat();break; case 2:enqueue();break; case 3:gethead();break; case 4:print();break; case 0:return 0;break; } } return 0; }
rdpost(int i) /* Print message (calls misc. support routines) */ { int c,f,posts; char s[100]; gethead(i); put_char(12); print("3Title: 4%s - [3%d/%d4]",hdr.title,i,totalmsgs); nl(); print("3From : 4%s 4[2%s4]",hdr.poster,hdr.posternote); nl(); print("3To : 4%s",hdr.to); nl(); print("3Date : 4%d/%d/%d - %d:%d:%d",hdr.postdate.da_day,hdr.postdate.da_mon,(hdr.postdate.da_year)-1900,hdr.posttime.ti_hour,hdr.posttime.ti_min,hdr.posttime.ti_sec); if(hdr.prevrep) { nl(); print(" 4! This is a reply to message #3%d",hdr.prevrep); } if(hdr.lastrep) { nl(); print(" 4! This message has 3%d4 replie(s)",hdr.numreps); } nl(); pl("1������������������������������������������������������������������������������"); nl(); ansic(4); makemsgpath(0); f=open(msgpath,O_BINARY | O_RDWR); if(f==-1) { nl(); pl("Data file screwed"); return; } close(f); readdata(); nl(); }
int main(int argc, char *argv[]) { char *input; char *output; char *title; char *temp; FILE *fd, *ft; int cf, direction, sz; struct Cell_head cellhd; struct History history; void *rast, *rast_ptr; int row, col; int nrows, ncols; double x; char y[128]; struct GModule *module; struct { struct Option *input, *output, *title, *mult, *nv, *type; } parm; struct { struct Flag *s; } flag; char *null_val_str; DCELL mult; RASTER_MAP_TYPE data_type; double atof(); G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("import")); G_add_keyword(_("conversion")); G_add_keyword("ASCII"); module->description = _("Converts a GRASS ASCII raster file to binary raster map."); parm.input = G_define_standard_option(G_OPT_F_INPUT); parm.input->label = _("Name of input file to be imported"); parm.input->description = _("'-' for standard input"); parm.output = G_define_standard_option(G_OPT_R_OUTPUT); parm.type = G_define_option(); parm.type->key = "type"; parm.type->type = TYPE_STRING; parm.type->required = NO; parm.type->options = "CELL,FCELL,DCELL"; parm.type->label = _("Storage type for resultant raster map"); parm.type->description = _("Default: CELL for integer values, DCELL for floating-point values"); parm.title = G_define_option(); parm.title->key = "title"; parm.title->key_desc = "phrase"; parm.title->type = TYPE_STRING; parm.title->required = NO; parm.title->description = _("Title for resultant raster map"); parm.mult = G_define_option(); parm.mult->key = "multiplier"; parm.mult->type = TYPE_DOUBLE; parm.mult->description = _("Default: read from header"); parm.mult->required = NO; parm.mult->label = _("Multiplier for ASCII data"); parm.nv = G_define_standard_option(G_OPT_M_NULL_VALUE); parm.nv->description = _("Default: read from header"); parm.nv->label = _("String representing NULL value data cell"); parm.nv->guisection = _("NULL data"); flag.s = G_define_flag(); flag.s->key = 's'; flag.s->description = _("SURFER (Golden Software) ASCII file will be imported"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); input = parm.input->answer; output = parm.output->answer; temp = G_tempfile(); ft = fopen(temp, "w+"); if (ft == NULL) G_fatal_error(_("Unable to open temporary file <%s>"), temp); if ((title = parm.title->answer)) G_strip(title); if (!parm.mult->answer) Rast_set_d_null_value(&mult, 1); else if ((sscanf(parm.mult->answer, "%lf", &mult)) != 1) G_fatal_error(_("Wrong entry for multiplier: %s"), parm.mult->answer); null_val_str = parm.nv->answer; data_type = -1; if (parm.type->answer) { switch(parm.type->answer[0]) { case 'C': data_type = CELL_TYPE; break; case 'F': data_type = FCELL_TYPE; break; case 'D': data_type = DCELL_TYPE; break; } } if (strcmp(input, "-") == 0) { Tmp_file = G_tempfile(); if (NULL == (Tmp_fd = fopen(Tmp_file, "w+"))) G_fatal_error(_("Unable to open temporary file <%s>"), Tmp_file); unlink(Tmp_file); if (0 > file_cpy(stdin, Tmp_fd)) G_fatal_error(_("Unable to read input from stdin")); fd = Tmp_fd; } else fd = fopen(input, "r"); if (fd == NULL) { G_fatal_error(_("Unable to read input from <%s>"), input); } direction = 1; sz = 0; if (flag.s->answer) { sz = getgrdhead(fd, &cellhd); /* for Surfer files, the data type is always FCELL_TYPE, the multiplier and the null_val_str are never used */ data_type = FCELL_TYPE; mult = 1.; null_val_str = ""; /* rows in surfer files are ordered from bottom to top, opposite of normal GRASS ordering */ direction = -1; } else sz = gethead(fd, &cellhd, &data_type, &mult, &null_val_str); if (!sz) G_fatal_error(_("Can't get cell header")); nrows = cellhd.rows; ncols = cellhd.cols; Rast_set_window(&cellhd); if (nrows != Rast_window_rows()) G_fatal_error(_("OOPS: rows changed from %d to %d"), nrows, Rast_window_rows()); if (ncols != Rast_window_cols()) G_fatal_error(_("OOPS: cols changed from %d to %d"), ncols, Rast_window_cols()); rast_ptr = Rast_allocate_buf(data_type); rast = rast_ptr; cf = Rast_open_new(output, data_type); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); for (col = 0; col < ncols; col++) { if (fscanf(fd, "%s", y) != 1) { Rast_unopen(cf); G_fatal_error(_("Data conversion failed at row %d, col %d"), row + 1, col + 1); } if (strcmp(y, null_val_str)) { x = atof(y); if ((float)x == GS_BLANK) { Rast_set_null_value(rast_ptr, 1, data_type); } else { Rast_set_d_value(rast_ptr, (DCELL) (x * mult), data_type); } } else { Rast_set_null_value(rast_ptr, 1, data_type); } rast_ptr = G_incr_void_ptr(rast_ptr, Rast_cell_size(data_type)); } fwrite(rast, Rast_cell_size(data_type), ncols, ft); rast_ptr = rast; } G_percent(nrows, nrows, 2); G_debug(1, "Creating support files for %s", output); sz = 0; if (direction < 0) { sz = -ncols * Rast_cell_size(data_type); G_fseek(ft, sz, SEEK_END); sz *= 2; } else { G_fseek(ft, 0L, SEEK_SET); } for (row = 0; row < nrows; row += 1) { fread(rast, Rast_cell_size(data_type), ncols, ft); Rast_put_row(cf, rast, data_type); G_fseek(ft, sz, SEEK_CUR); } fclose(ft); unlink(temp); Rast_close(cf); if (title) Rast_put_cell_title(output, title); Rast_short_history(output, "raster", &history); Rast_command_history(&history); Rast_write_history(output, &history); G_done_msg(" "); exit(EXIT_SUCCESS); }
/* * Prompt user to load a new dump volume. * "Nextvol" is the next suggested volume to use. * This suggested volume is enforced when doing full * or incremental restores, but can be overrridden by * the user when only extracting a subset of the files. */ void getvol(long nextvol) { long newvol = 0, savecnt = 0, wantnext = 0, i; union u_spcl tmpspcl; # define tmpbuf tmpspcl.s_spcl char buf[TP_BSIZE]; const char *errstr; if (nextvol == 1) { tapesread = 0; gettingfile = 0; } if (pipein) { if (nextvol != 1) panic("Changing volumes on pipe input?\n"); if (volno == 1) return; goto gethdr; } savecnt = blksread; again: if (pipein) exit(1); /* pipes do not get a second chance */ if (command == 'R' || command == 'r' || curfile.action != SKIP) { newvol = nextvol; wantnext = 1; } else { newvol = 0; wantnext = 0; } while (newvol <= 0) { if (tapesread == 0) { fprintf(stderr, "%s%s%s%s%s", "You have not read any tapes yet.\n", "Unless you know which volume your", " file(s) are on you should start\n", "with the last volume and work", " towards the first.\n"); } else { fprintf(stderr, "You have read volumes"); strlcpy(buf, ": ", sizeof buf); for (i = 1; i < 32; i++) if (tapesread & (1 << i)) { fprintf(stderr, "%s%ld", buf, i); strlcpy(buf, ", ", sizeof buf); } fprintf(stderr, "\n"); } do { fprintf(stderr, "Specify next volume #: "); (void)fflush(stderr); if (fgets(buf, sizeof buf, terminal) == NULL) exit(1); buf[strcspn(buf, "\n")] = '\0'; newvol = strtonum(buf, 1, INT_MAX, &errstr); if (errstr) fprintf(stderr, "Volume number %s: %s\n", errstr, buf); } while (errstr); } if (newvol == volno) { tapesread |= 1 << volno; return; } closemt(); fprintf(stderr, "Mount tape volume %ld\n", newvol); fprintf(stderr, "Enter ``none'' if there are no more tapes\n"); fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape); (void)fflush(stderr); if (fgets(buf, sizeof buf, terminal) == NULL || feof(terminal)) exit(1); buf[strcspn(buf, "\n")] = '\0'; if (strcmp(buf, "none") == 0) { terminateinput(); return; } if (buf[0] != '\0') (void)strlcpy(magtape, buf, sizeof magtape); #ifdef RRESTORE if (host) mt = rmtopen(magtape, 0); else #endif mt = open(magtape, O_RDONLY); if (mt == -1) { fprintf(stderr, "Cannot open %s\n", magtape); volno = -1; goto again; } gethdr: volno = newvol; setdumpnum(); FLUSHTAPEBUF(); if (gethead(&tmpbuf) == FAIL) { Dprintf(stdout, "header read failed at %ld blocks\n", blksread); fprintf(stderr, "tape is not dump tape\n"); volno = 0; goto again; } if (tmpbuf.c_volume != volno) { fprintf(stderr, "Wrong volume (%d)\n", tmpbuf.c_volume); volno = 0; goto again; } if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) { time_t t = (time_t)tmpbuf.c_date; fprintf(stderr, "Wrong dump date\n\tgot: %s", ctime(&t)); fprintf(stderr, "\twanted: %s", ctime(&dumpdate)); volno = 0; goto again; } tapesread |= 1 << volno; blksread = savecnt; /* * If continuing from the previous volume, skip over any * blocks read already at the end of the previous volume. * * If coming to this volume at random, skip to the beginning * of the next record. */ Dprintf(stdout, "read %ld recs, tape starts with %lld\n", tpblksread, tmpbuf.c_firstrec); if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) { if (!wantnext) { tpblksread = tmpbuf.c_firstrec; for (i = tmpbuf.c_count; i > 0; i--) readtape(buf); } else if (tmpbuf.c_firstrec > 0 && tmpbuf.c_firstrec < tpblksread - 1) { /* * -1 since we've read the volume header */ i = tpblksread - tmpbuf.c_firstrec - 1; Dprintf(stderr, "Skipping %ld duplicate record%s.\n", i, (i == 1) ? "" : "s"); while (--i >= 0) readtape(buf); } } if (curfile.action == USING) { if (volno == 1) panic("active file into volume 1\n"); return; } /* * Skip up to the beginning of the next record */ if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) for (i = tmpbuf.c_count; i > 0; i--) readtape(buf); (void)gethead(&spcl); findinode(&spcl); if (gettingfile) { gettingfile = 0; longjmp(restart, 1); } }
/* * Verify that the tape drive can be accessed and * that it actually is a dump tape. */ void setup(void) { int i, j, *ip; struct stat stbuf; vprintf(stdout, "Verify tape and initialize maps\n"); #ifdef RRESTORE if (host) mt = rmtopen(magtape, 0); else #endif if (pipein) mt = 0; else mt = open(magtape, O_RDONLY, 0); if (mt < 0) { fprintf(stderr, "%s: %s\n", magtape, strerror(errno)); done(1); } volno = 1; setdumpnum(); FLUSHTAPEBUF(); if (!pipein && !bflag) findtapeblksize(); if (gethead(&spcl) == FAIL) { blkcnt--; /* push back this block */ blksread--; cvtflag++; if (gethead(&spcl) == FAIL) { fprintf(stderr, "Tape is not a dump tape\n"); done(1); } fprintf(stderr, "Converting to new file system format.\n"); } if (pipein) { endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : NFS_MAGIC; endoftapemark.s_spcl.c_type = TS_END; ip = (int *)&endoftapemark; j = sizeof(union u_spcl) / sizeof(int); i = 0; do i += *ip++; while (--j); endoftapemark.s_spcl.c_checksum = CHECKSUM - i; } if (vflag || command == 't') printdumpinfo(); dumptime = spcl.c_ddate; dumpdate = spcl.c_date; if (stat(".", &stbuf) < 0) { fprintf(stderr, "cannot stat .: %s\n", strerror(errno)); done(1); } if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE ) fssize = TP_BSIZE; if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE) fssize = stbuf.st_blksize; if (((fssize - 1) & fssize) != 0) { fprintf(stderr, "bad block size %ld\n", fssize); done(1); } if (spcl.c_volume != 1) { fprintf(stderr, "Tape is not volume 1 of the dump\n"); done(1); } if (gethead(&spcl) == FAIL) { dprintf(stdout, "header read failed at %ld blocks\n", blksread); panic("no header after volume mark!\n"); } findinode(&spcl); if (spcl.c_type != TS_CLRI) { fprintf(stderr, "Cannot find file removal list\n"); done(1); } maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1; dprintf(stdout, "maxino = %d\n", maxino); map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); if (map == NULL) panic("no memory for active inode map\n"); usedinomap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip); if (spcl.c_type != TS_BITS) { fprintf(stderr, "Cannot find file dump list\n"); done(1); } map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); if (map == NULL) panic("no memory for file dump list\n"); dumpmap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip); /* * If there may be whiteout entries on the tape, pretend that the * whiteout inode exists, so that the whiteout entries can be * extracted. */ if (oldinofmt == 0) SETINO(WINO, dumpmap); /* 'r' restores don't call getvol() for tape 1, so mark it as read. */ if (command == 'r') tapesread = 1; }
/* * Prompt user to load a new dump volume. * "Nextvol" is the next suggested volume to use. * This suggested volume is enforced when doing full * or incremental restores, but can be overridden by * the user when only extracting a subset of the files. */ void getvol(long nextvol) { int64_t prevtapea; long i, newvol, savecnt; union u_spcl tmpspcl; # define tmpbuf tmpspcl.s_spcl char buf[TP_BSIZE]; if (nextvol == 1) { tapesread = 0; gettingfile = 0; } prevtapea = tapeaddr; savecnt = blksread; if (pipein) { if (nextvol != 1) { panic("Changing volumes on pipe input?\n"); /* Avoid looping if we couldn't ask the user. */ if (yflag || ferror(terminal) || feof(terminal)) done(1); } if (volno == 1) return; goto gethdr; } again: if (pipein) done(1); /* pipes do not get a second chance */ if (command == 'R' || command == 'r' || curfile.action != SKIP) newvol = nextvol; else newvol = 0; while (newvol <= 0) { if (tapesread == 0) { fprintf(stderr, "%s%s%s%s%s%s%s", "You have not read any tapes yet.\n", "If you are extracting just a few files,", " start with the last volume\n", "and work towards the first; restore", " can quickly skip tapes that\n", "have no further files to extract.", " Otherwise, begin with volume 1.\n"); } else { fprintf(stderr, "You have read volumes"); strcpy(buf, ": "); for (i = 0; i < 32; i++) if (tapesread & (1 << i)) { fprintf(stderr, "%s%ld", buf, i + 1); strcpy(buf, ", "); } fprintf(stderr, "\n"); } do { fprintf(stderr, "Specify next volume #: "); (void) fflush(stderr); if (fgets(buf, BUFSIZ, terminal) == NULL) done(1); } while (buf[0] == '\n'); newvol = atoi(buf); if (newvol <= 0) { fprintf(stderr, "Volume numbers are positive numerics\n"); } } if (newvol == volno) { tapesread |= 1 << (volno - 1); return; } closemt(); fprintf(stderr, "Mount tape volume %ld\n", newvol); fprintf(stderr, "Enter ``none'' if there are no more tapes\n"); fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape); (void) fflush(stderr); if (fgets(buf, BUFSIZ, terminal) == NULL) done(1); if (!strcmp(buf, "none\n")) { terminateinput(); return; } if (buf[0] != '\n') { (void) strcpy(magtape, buf); magtape[strlen(magtape) - 1] = '\0'; } if (pipecmdin) { char volno[sizeof("2147483647")]; (void)sprintf(volno, "%ld", newvol); if (setenv("RESTORE_VOLUME", volno, 1) == -1) { fprintf(stderr, "Cannot set $RESTORE_VOLUME: %s\n", strerror(errno)); done(1); } popenfp = popen(magtape, "r"); mt = popenfp ? fileno(popenfp) : -1; } else #ifdef RRESTORE if (host) mt = rmtopen(magtape, 0); else #endif mt = open(magtape, O_RDONLY, 0); if (mt == -1) { fprintf(stderr, "Cannot open %s\n", magtape); volno = -1; goto again; } gethdr: volno = newvol; setdumpnum(); FLUSHTAPEBUF(); if (gethead(&tmpbuf) == FAIL) { dprintf(stdout, "header read failed at %ld blocks\n", blksread); fprintf(stderr, "tape is not dump tape\n"); volno = 0; goto again; } if (tmpbuf.c_volume != volno) { fprintf(stderr, "Wrong volume (%jd)\n", (intmax_t)tmpbuf.c_volume); volno = 0; goto again; } if (_time64_to_time(tmpbuf.c_date) != dumpdate || _time64_to_time(tmpbuf.c_ddate) != dumptime) { time_t t = _time64_to_time(tmpbuf.c_date); fprintf(stderr, "Wrong dump date\n\tgot: %s", ctime(&t)); fprintf(stderr, "\twanted: %s", ctime(&dumpdate)); volno = 0; goto again; } tapesread |= 1 << (volno - 1); blksread = savecnt; /* * If continuing from the previous volume, skip over any * blocks read already at the end of the previous volume. * * If coming to this volume at random, skip to the beginning * of the next record. */ dprintf(stdout, "last rec %jd, tape starts with %jd\n", (intmax_t)prevtapea, (intmax_t)tmpbuf.c_tapea); if (tmpbuf.c_type == TS_TAPE) { if (curfile.action != USING) { /* * XXX Dump incorrectly sets c_count to 1 in the * volume header of the first tape, so ignore * c_count when volno == 1. */ if (volno != 1) for (i = tmpbuf.c_count; i > 0; i--) readtape(buf); } else if (tmpbuf.c_tapea <= prevtapea) { /* * Normally the value of c_tapea in the volume * header is the record number of the header itself. * However in the volume header following an EOT- * terminated tape, it is the record number of the * first continuation data block (dump bug?). * * The next record we want is `prevtapea + 1'. */ i = prevtapea + 1 - tmpbuf.c_tapea; dprintf(stderr, "Skipping %ld duplicate record%s.\n", i, i > 1 ? "s" : ""); while (--i >= 0) readtape(buf); } } if (curfile.action == USING) { if (volno == 1) panic("active file into volume 1\n"); return; } (void) gethead(&spcl); findinode(&spcl); if (gettingfile) { gettingfile = 0; longjmp(restart, 1); } }
/* * Find an inode header. * Complain if had to skip. */ static void findinode(struct s_spcl *header) { static long skipcnt = 0; long i; char buf[TP_BSIZE]; int htype; curfile.name = "<name unknown>"; curfile.action = UNKNOWN; curfile.mode = 0; curfile.ino = 0; do { htype = header->c_type; switch (htype) { case TS_ADDR: /* * Skip up to the beginning of the next record */ for (i = 0; i < header->c_count; i++) if (header->c_addr[i]) readtape(buf); while (gethead(header) == FAIL || _time64_to_time(header->c_date) != dumpdate) { skipcnt++; if (Dflag) { byteslide++; if (byteslide < TP_BSIZE) { blkcnt--; blksread--; } else byteslide = 0; } } break; case TS_INODE: curfile.mode = header->c_mode; curfile.uid = header->c_uid; curfile.gid = header->c_gid; curfile.file_flags = header->c_file_flags; curfile.rdev = header->c_rdev; curfile.atime_sec = header->c_atime; curfile.atime_nsec = header->c_atimensec; curfile.mtime_sec = header->c_mtime; curfile.mtime_nsec = header->c_mtimensec; curfile.birthtime_sec = header->c_birthtime; curfile.birthtime_nsec = header->c_birthtimensec; curfile.extsize = header->c_extsize; curfile.size = header->c_size; curfile.ino = header->c_inumber; break; case TS_END: /* If we missed some tapes, get another volume. */ if (tapesread & (tapesread + 1)) { getvol(0); continue; } curfile.ino = maxino; break; case TS_CLRI: curfile.name = "<file removal list>"; break; case TS_BITS: curfile.name = "<file dump list>"; break; case TS_TAPE: if (Dflag) fprintf(stderr, "unexpected tape header\n"); else panic("unexpected tape header\n"); default: if (Dflag) fprintf(stderr, "unknown tape header type %d\n", spcl.c_type); else panic("unknown tape header type %d\n", spcl.c_type); while (gethead(header) == FAIL || _time64_to_time(header->c_date) != dumpdate) { skipcnt++; if (Dflag) { byteslide++; if (byteslide < TP_BSIZE) { blkcnt--; blksread--; } else byteslide = 0; } } } } while (htype == TS_ADDR); if (skipcnt > 0) fprintf(stderr, "resync restore, skipped %ld %s\n", skipcnt, Dflag ? "bytes" : "blocks"); skipcnt = 0; }
readpost() /* umm.... Read post! */ { int c,curmsg,dir; char s[80], x[10]; gettotalmsgs(); nl(); nl(); if(totalmsgs==0) { pl("4No messages exist"); return; } print("1Start with which post [31-%d1]:2 ",totalmsgs); input(s,50); if(s[0]==0) return; c=atoi(s); if(c > totalmsgs) { nl(); pl("4Not that many posts!"); return; } curmsg=c; rdpost(c); dir=1; do { nl(); if(dir==1) print("1C/R=Forward [3B,E,F,P,Q,R,+,-,?,#1]:2 "); else print("1C/R=Reverse [3B,E,F,P,Q,R,+,-,?,#1]:2 "); input(s,50); strupr(s); switch(s[0]) { case 0: if(dir==1) { if(curmsg >= totalmsgs) put("4Last message!"); else { curmsg++; rdpost(curmsg); } } else { if(curmsg == 1) put("4First message!"); else { curmsg--; rdpost(curmsg); } } break; case 'B': nl(); pl("4Reverse read mode enabled"); dir=-1; break; case 'E': break; case 'F': nl(); pl("4Forward read mode enabled"); dir=1; break; case 'P': post(0,curmsg); break; case 'Q': break; case 'R': post(1,curmsg); break; case '+': gethead(curmsg); if(hdr.lastrep!=0) { for(c=1;c;) { if(hdr.lastrep!=0) { rdpost(hdr.lastrep+1); nl(); put("1Forward Thread Scan - Q to Quit, C/R to continue:2 "); input(x,10); strupr(x); if(x[0]=='Q') c=0; } else { print("4\bNo replies found"); c=0; } } } else print("4\bNo replies found"); nl(); break; case '-': gethead(curmsg); if(hdr.prevrep!=0) { for(c=1;c;) { if(hdr.prevrep!=0) { rdpost(hdr.prevrep); nl(); put("1Reverse Thread Scan - Q to Quit, C/R to continue:2 "); input(x,10); strupr(x); if(x[0]=='Q') c=0; } else { print("4\bNo replies found"); c=0; } } } else print("4\bNo replies found"); nl(); break; case '?': nl(); nl(); ansic(4); pl("��] Message Read Commands [��"); pl(" B - Reverse read"); pl(" E - E-mail poster"); pl(" F - Forward read"); pl(" P - Post a message"); pl(" Q - Quit reading messages"); pl(" R - Reply to poster"); pl(" - - Reverse thread read"); pl(" + - Forward thread read"); pl(" # - Message number"); nl(); break; default: c=atoi(s); if(c > 0 && c <= totalmsgs) { curmsg=c; rdpost(curmsg); } break; } } while(s[0]!='Q'); nl(); nl(); }
post(int rep, int curmsg) { int f,c,t; long i; char s[80]; makemsgpath(1); f=open(msgpath,O_BINARY | O_RDWR); if(f==-1) /* If no other msgs */ { if(!inputheadinfo()) return; if(!editor()) return; makemsgpath(1); f=open(msgpath,O_BINARY | O_RDWR | O_CREAT,S_IWRITE | S_IREAD); c=0; write(f,&c,1); hdr.num=hdr.prevrep=hdr.lastrep=hdr.datapoint=hdr.numreps=0; hdr.nextpoint=1; write(f,&hdr,sizeof(struct headerinfo)); close(f); gettotalmsgs(); return; } t=filelength(f); t-=1; t=t/(sizeof(struct headerinfo)); if(rep) { hdr.prevrep=curmsg; hdr.lastrep=hdr.numreps=0; } else hdr.prevrep=hdr.lastrep=hdr.numreps=0; hdr.num=t; makemsgpath(0); /* Get "datapoint" set */ c=open(msgpath,O_BINARY | O_RDWR); if(c==-1) c=open(msgpath,O_BINARY | O_RDWR | O_CREAT,S_IWRITE | S_IREAD); if(c==-1) { nl(); pl("Error creating data file."); return; } hdr.datapoint=filelength(c); close(c); if(!inputheadinfo()) { close(f); return; } if(!editor()) { close(f); return; } lseek(f,0l,SEEK_END); write(f,&hdr,sizeof(struct headerinfo)); close(f); makemsgpath(1); if(rep) /* get reply pointers set */ { c=open(msgpath,O_BINARY | O_RDWR); i=sizeof(struct headerinfo); i=i * (curmsg-1); lseek(c,i+1,SEEK_SET); read(c,&hdr,sizeof(struct headerinfo)); hdr.lastrep=t; hdr.numreps++; lseek(c,i+1,SEEK_SET); write(c,&hdr,sizeof(struct headerinfo)); strcpy(s,hdr.poster); gethead(t+1); strcpy(hdr.to,s); i=t * (sizeof(struct headerinfo)); lseek(c,i+1,SEEK_SET); write(c,&hdr,sizeof(struct headerinfo)); close(c); } gettotalmsgs(); }
/* * Extract a file from the tape. * When an allocated block is found it is passed to the fill function; * when an unallocated block (hole) is found, a zeroed buffer is passed * to the skip function. */ void getfile(void (*datafill)(char *, size_t), void (*attrfill)(char *, size_t), void (*skip)(char *, size_t)) { int i; volatile off_t size; size_t seekpos; int curblk, attrsize; void (*fillit)(char *, size_t); char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE]; char junk[TP_BSIZE]; curblk = 0; size = spcl.c_size; seekpos = 0; attrsize = spcl.c_extsize; if (spcl.c_type == TS_END) panic("ran off end of tape\n"); if (spcl.c_magic != FS_UFS2_MAGIC) panic("not at beginning of a file\n"); if (!gettingfile && setjmp(restart) != 0) return; gettingfile++; fillit = datafill; if (size == 0 && attrsize > 0) { fillit = attrfill; size = attrsize; attrsize = 0; } loop: for (i = 0; i < spcl.c_count; i++) { if (!readmapflag && i > TP_NINDIR) { if (Dflag) { fprintf(stderr, "spcl.c_count = %jd\n", (intmax_t)spcl.c_count); break; } else panic("spcl.c_count = %jd\n", (intmax_t)spcl.c_count); } if (readmapflag || spcl.c_addr[i]) { readtape(&buf[curblk++][0]); if (curblk == fssize / TP_BSIZE) { skiphole(skip, &seekpos); (*fillit)((char *)buf, (long)(size > TP_BSIZE ? fssize : (curblk - 1) * TP_BSIZE + size)); curblk = 0; } } else { if (curblk > 0) { skiphole(skip, &seekpos); (*fillit)((char *)buf, (long)(size > TP_BSIZE ? curblk * TP_BSIZE : (curblk - 1) * TP_BSIZE + size)); curblk = 0; } /* * We have a block of a hole. Don't skip it * now, because there may be next adjacent * block of the hole in the file. Postpone the * seek until next file write. */ seekpos += (long)MIN(TP_BSIZE, size); } if ((size -= TP_BSIZE) <= 0) { if (size > -TP_BSIZE && curblk > 0) { skiphole(skip, &seekpos); (*fillit)((char *)buf, (long)((curblk * TP_BSIZE) + size)); curblk = 0; } if (attrsize > 0) { fillit = attrfill; size = attrsize; attrsize = 0; continue; } if (spcl.c_count - i > 1) dprintf(stdout, "skipping %d junk block(s)\n", spcl.c_count - i - 1); for (i++; i < spcl.c_count; i++) { if (!readmapflag && i > TP_NINDIR) { if (Dflag) { fprintf(stderr, "spcl.c_count = %jd\n", (intmax_t)spcl.c_count); break; } else panic("spcl.c_count = %jd\n", (intmax_t)spcl.c_count); } if (readmapflag || spcl.c_addr[i]) readtape(junk); } break; } } if (gethead(&spcl) == GOOD && size > 0) { if (spcl.c_type == TS_ADDR) goto loop; dprintf(stdout, "Missing address (header) block for %s at %ld blocks\n", curfile.name, blksread); } if (curblk > 0) panic("getfile: lost data\n"); findinode(&spcl); gettingfile = 0; }
int main(int argc, char *argv[]) { char *input; char *output; char *title; FILE *fd; int cf; struct Cell_head cellhd; CELL *cell; FCELL *fcell; DCELL *dcell; int row, col; int nrows, ncols; static int missingval; int rtype; double mult_fact; double x; struct GModule *module; struct History history; struct { struct Option *input, *output, *type, *title, *mult; } parm; G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("raster, import"); module->description = _("Converts an ESRI ARC/INFO ascii raster file (GRID) " "into a (binary) raster map layer."); parm.input = G_define_option(); parm.input->key = "input"; parm.input->type = TYPE_STRING; parm.input->required = YES; parm.input->description = _("ARC/INFO ASCII raster file (GRID) to be imported"); parm.input->gisprompt = "old_file,file,input"; parm.output = G_define_standard_option(G_OPT_R_OUTPUT); parm.type = G_define_option(); parm.type->key = "type"; parm.type->type = TYPE_STRING; parm.type->required = NO; parm.type->options = "CELL,FCELL,DCELL"; parm.type->answer = "FCELL"; parm.type->description = _("Storage type for resultant raster map"); parm.title = G_define_option(); parm.title->key = "title"; parm.title->key_desc = "\"phrase\""; parm.title->type = TYPE_STRING; parm.title->required = NO; parm.title->description = _("Title for resultant raster map"); parm.mult = G_define_option(); parm.mult->key = "mult"; parm.mult->type = TYPE_DOUBLE; parm.mult->answer = "1.0"; parm.mult->required = NO; parm.mult->description = _("Multiplier for ASCII data"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); input = parm.input->answer; output = parm.output->answer; if (title = parm.title->answer) G_strip(title); sscanf(parm.mult->answer, "%lf", &mult_fact); if (strcmp("CELL", parm.type->answer) == 0) rtype = CELL_TYPE; else if (strcmp("DCELL", parm.type->answer) == 0) rtype = DCELL_TYPE; else rtype = FCELL_TYPE; if (strcmp("-", input) == 0) { Tmp_file = G_tempfile(); if (NULL == (Tmp_fd = fopen(Tmp_file, "w+"))) G_fatal_error(_("Unable to open temporary file <%s>"), Tmp_file); unlink(Tmp_file); if (0 > file_cpy(stdin, Tmp_fd)) exit(EXIT_FAILURE); fd = Tmp_fd; } else fd = fopen(input, "r"); if (fd == NULL) G_fatal_error(_("Unable to open input file <%s>"), input); if (!gethead(fd, &cellhd, &missingval)) G_fatal_error(_("Can't get cell header")); nrows = cellhd.rows; ncols = cellhd.cols; if (G_set_window(&cellhd) < 0) G_fatal_error(_("Can't set window")); if (nrows != G_window_rows()) G_fatal_error(_("OOPS: rows changed from %d to %d"), nrows, G_window_rows()); if (ncols != G_window_cols()) G_fatal_error(_("OOPS: cols changed from %d to %d"), ncols, G_window_cols()); switch (rtype) { case CELL_TYPE: cell = G_allocate_c_raster_buf(); break; case FCELL_TYPE: fcell = G_allocate_f_raster_buf(); break; case DCELL_TYPE: dcell = G_allocate_d_raster_buf(); break; } cf = G_open_raster_new(output, rtype); if (cf < 0) G_fatal_error(_("Unable to create raster map <%s>"), output); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 5); for (col = 0; col < ncols; col++) { if (fscanf(fd, "%lf", &x) != 1) { G_unopen_cell(cf); G_fatal_error(_("Data conversion failed at row %d, col %d"), row + 1, col + 1); } switch (rtype) { case CELL_TYPE: if ((int)x == missingval) G_set_c_null_value(cell + col, 1); else cell[col] = (CELL) x *mult_fact; break; case FCELL_TYPE: if ((int)x == missingval) G_set_f_null_value(fcell + col, 1); else fcell[col] = (FCELL) x *mult_fact; break; case DCELL_TYPE: if ((int)x == missingval) G_set_d_null_value(dcell + col, 1); else dcell[col] = (DCELL) x *mult_fact; break; } } switch (rtype) { case CELL_TYPE: G_put_c_raster_row(cf, cell); break; case FCELL_TYPE: G_put_f_raster_row(cf, fcell); break; case DCELL_TYPE: G_put_d_raster_row(cf, dcell); break; } } /* G_message(_("CREATING SUPPORT FILES FOR %s"), output); */ G_close_cell(cf); if (title) G_put_cell_title(output, title); G_short_history(output, "raster", &history); G_command_history(&history); G_write_history(output, &history); exit(EXIT_SUCCESS); }
/* Simulate how the CPU works. */ void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); cpu.eip += instr_len; #ifdef DEBUG print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } #endif /* TODO: check watchpoints here. */ WP *p; uint32_t index; bool success=true; p=gethead(); int flag=0; while(p!=NULL) { index=expr(p->expr,&success); if(success==false) printf("Meet a wrong expression!"); if(p->ans!=index) { flag=1; printf("watchpoint %d: %s\n",p->NO+1,p->expr); printf("Old value = %d\n",p->ans); printf("New value = %d\n",index); p->ans=index; } p=p->next; } if(flag==1) nemu_state=STOP; if(nemu_state != RUNNING) { return; } if(cpu.INTR & cpu.EFLAGS.IF) { uint32_t intr_no = i8259_query_intr(); i8259_ack_intr(); raise_intr(intr_no); } } if(nemu_state == RUNNING) { nemu_state = STOP; } }
/* * Print mail entries */ void printmail() { static char pn[] = "printmail"; int flg, curlet, showlet, k, print, aret, stret, rc; int nsmbox = 0; /* 1 ==> mailbox is in non-standard place */ int sav_j = -1; char *p, *getarg(); struct stat stbuf; struct stat *stbufp; int ttyf = isatty(1) ? TTY : ORDINARY; char readbuf[LSIZE]; /* holds user's response in interactive mode */ char *resp; gid_t savedegid; stbufp = &stbuf; /* * create working directory mbox name */ if ((hmbox = malloc(strlen(home) + strlen(mbox) + 1)) == NULL) { errmsg(E_MBOX, ""); return; } cat(hmbox, home, mbox); /* * If we are not using an alternate mailfile, then get * the $MAIL value and build the filename for the mailfile. * If $MAIL is set, but is NOT the 'standard' place, then * use it but set flgf to circumvent :saved processing. */ if (!flgf) { if ((p = malloc(strlen(maildir) + strlen(my_name) + 1)) == NULL) { errmsg(E_MEM, ""); return; } cat(p, maildir, my_name); if (((mailfile = getenv("MAIL")) == NULL) || (strlen(mailfile) == 0)) { /* $MAIL not set, use standard path to mailfile */ mailfile = p; } else { if (strcmp(mailfile, p) != 0) { flgf = 1; nsmbox = 1; Dout(pn, 0, "$MAIL ('%s') != standard path\n", mailfile); Dout("", 0, "\tSetting flgf to 1.\n"); } free(p); } } /* * Get ACCESS and MODIFICATION times of mailfile BEFORE we * use it. This allows us to put them back when we are * done. If we didn't, the shell would think NEW mail had * arrived since the file times would have changed. */ stret = CERROR; if (access(mailfile, A_EXIST) == A_OK) { if ((stret = stat(mailfile, stbufp)) != A_OK) { errmsg(E_FILE, "Cannot stat mailfile"); return; } mf_gid = stbufp->st_gid; mf_uid = stbufp->st_uid; utimep->actime = stbufp->st_atime; utimep->modtime = stbufp->st_mtime; file_size = stbufp->st_size; } /* Open the file as the real gid */ savedegid = getegid(); (void) setegid(getgid()); malf = fopen(mailfile, "r"); (void) setegid(savedegid); /* * stat succeeded, but we cannot access the mailfile */ if (stret == CSUCCESS && malf == NULL) { char buf[MAXFILENAME+50]; (void) snprintf(buf, sizeof (buf), "Invalid permissions on %s", mailfile); errmsg(E_PERM, buf); return; } else /* * using an alternate mailfile, but we failed on access */ if (!nsmbox && flgf && (malf == NULL)) { errmsg(E_FILE, "Cannot open mailfile"); return; } /* * we failed to access OR the file is empty */ else if ((malf == NULL) || (stbuf.st_size == 0)) { if (!flge && !flgE) { printf("No mail.\n"); } error = E_FLGE; Dout(pn, 0, "error set to %d\n", error); return; } if (flge) return; if (flgE) { if (utimep->modtime < utimep->actime) { error = E_FLGE_OM; Dout(pn, 0, "error set to %d\n", error); } return; } /* * Secure the mailfile to guarantee integrity */ lock(my_name); /* * copy mail to temp file and mark each letter in the * let array --- mailfile is still locked !!! */ mktmp(); copymt(malf, tmpf); onlet = nlet; fclose(malf); fclose(tmpf); unlock(); /* All done, OK to unlock now */ tmpf = doopen(lettmp, "r+", E_TMP); changed = 0; print = 1; curlet = 0; while (curlet < nlet) { /* * reverse order ? */ showlet = flgr ? curlet : nlet - curlet - 1; if (setjmp(sjbuf) == 0 && print != 0) { /* -h says to print the headers first */ if (flgh) { gethead(showlet, 0); flgh = 0; /* Only once */ /* set letter # to invalid # */ curlet--; showlet = flgr ? curlet : nlet - curlet - 1; } else { if (showlet != sav_j) { /* Looking at new message. */ /* Reset flag to override */ /* non-display of binary */ /* contents */ sav_j = showlet; pflg = 0; Pflg = flgP; } copylet(showlet, stdout, ttyf); } } /* * print only */ if (flgp) { curlet++; continue; } /* * Interactive */ interactive = 1; setjmp(sjbuf); stat(mailfile, stbufp); if (stbufp->st_size != file_size) { /* * New mail has arrived, load it */ k = nlet; lock(my_name); malf = doopen(mailfile, "r", E_FILE); fclose(tmpf); tmpf = doopen(lettmp, "a", E_TMP); fseek(malf, let[nlet].adr, 0); copymt(malf, tmpf); file_size = stbufp->st_size; fclose(malf); fclose(tmpf); unlock(); tmpf = doopen(lettmp, "r+", E_TMP); if (++k < nlet) printf("New mail loaded into letters %d - %d\n", k, nlet); else printf("New mail loaded into letter %d\n", nlet); } /* read the command */ printf("? "); fflush(stdout); fflush(stderr); if (fgets(readbuf, sizeof (readbuf), stdin) == NULL) break; resp = readbuf; while (*resp == ' ' || *resp == '\t') resp++; print = 1; Dout(pn, 0, "resp = '%s'\n", resp); if ((rc = atoi(resp)) != 0) { if (!validmsg(rc)) print = 0; else curlet = flgr ? rc - 1 : nlet - rc; } else switch (resp[0]) { default: printf("Usage:\n"); /* * help */ case '?': print = 0; for (rc = 0; help[rc]; rc++) printf("%s", help[rc]); break; /* * print message number of current message */ case '#': print = 0; if ((showlet == nlet) || (showlet < 0)) { printf("No message selected yet.\n"); } else { printf("Current message number is %d\n", showlet+1); } break; /* * headers */ case 'h': print = 0; if (resp[2] != 'd' && resp[2] != 'a' && (rc = getnumbr(resp+1)) > 0) { showlet = rc - 1; curlet = flgr ? rc - 1 : nlet - rc- 1; } if (rc == -1 && resp[2] != 'a' && resp[2] != 'd') break; if (resp[2] == 'a') rc = 1; else if (resp[2] == 'd') rc = 2; else rc = 0; /* * if (!validmsg(showlet)) break; */ gethead(showlet, rc); break; /* * skip entry */ case '+': case 'n': case '\n': curlet++; break; case 'P': Pflg++; break; case 'p': pflg++; break; case 'x': changed = 0; case 'q': goto donep; /* * Previous entry */ case '^': case '-': if (--curlet < 0) curlet = 0; break; /* * Save in file without header */ case 'y': case 'w': /* * Save mail with header */ case 's': print = 0; if (!validmsg(curlet)) break; if (resp[1] == '\n' || resp[1] == '\0') { cat(resp+1, hmbox, ""); } else if (resp[1] != ' ') { printf("Invalid command\n"); break; } umask(umsave); flg = 0; if (getarg(lfil, resp + 1) == NULL) { cat(resp + 1, hmbox, ""); } malf = (FILE *)NULL; p = resp + 1; while ((p = getarg(lfil, p)) != NULL) { if (flg) { fprintf(stderr, "%s: File '%s' skipped\n", program, lfil); continue; } malf = NULL; if ((aret = legal(lfil))) { malf = fopen(lfil, "a"); } if ((malf == NULL) || (aret == 0)) { fprintf(stderr, "%s: Cannot append to %s\n", program, lfil); flg++; } else if (aret == 2) { chown(lfil, my_euid, my_gid); } if (!flg && copylet(showlet, malf, resp[0] == 's'? ORDINARY: ZAP) == FALSE) { fprintf(stderr, "%s: Cannot save mail to '%s'\n", program, lfil); flg++; } else Dout(pn, 0, "!saved\n"); if (malf != (FILE *)NULL) { fclose(malf); } } umask(7); if (!flg) { setletr(showlet, resp[0]); print = 1; curlet++; } break; /* * Reply to a letter */ case 'r': print = 0; if (!validmsg(curlet)) break; replying = 1; for (k = 1; resp[k] == ' ' || resp[k] == '\t'; ++k); resp[strlen(resp)-1] = '\0'; (void) strlcpy(m_sendto, resp+k, sizeof (m_sendto)); goback(showlet); replying = 0; setletr(showlet, resp[0]); break; /* * Undelete */ case 'u': print = 0; if ((k = getnumbr(resp+1)) <= 0) k = showlet; else k--; if (!validmsg(k)) break; setletr(k, ' '); break; /* * Mail letter to someone else */ case 'm': { reciplist list; print = 0; if (!validmsg(curlet)) break; new_reciplist(&list); flg = 0; k = 0; if (substr(resp, " -") != -1 || substr(resp, "\t-") != -1) { printf("Only users may be specified\n"); break; } p = resp + 1; while ((p = getarg(lfil, p)) != NULL) { char *env; if (lfil[0] == '$') { if (!(env = getenv(&lfil[1]))) { fprintf(stderr, "%s: %s has no value or is not exported.\n", program, lfil); flg++; } else add_recip(&list, env, FALSE); k++; } else if (lfil[0] != '\0') { add_recip(&list, lfil, FALSE); k++; } } (void) strlcpy(Rpath, my_name, sizeof (Rpath)); sending = TRUE; flg += sendlist(&list, showlet, 0); sending = FALSE; if (k) { if (!flg) { setletr(showlet, 'm'); print = 1; curlet++; } } else printf("Invalid command\n"); del_reciplist(&list); break; } /* * Read new letters */ case 'a': if (onlet == nlet) { printf("No new mail\n"); print = 0; break; } curlet = 0; print = 1; break; /* * Escape to shell */ case '!': systm(resp + 1); printf("!\n"); print = 0; break; /* * Delete an entry */ case 'd': print = 0; k = 0; if (strncmp("dq", resp, 2) != SAME && strncmp("dp", resp, 2) != SAME) if ((k = getnumbr(resp+1)) == -1) break; if (k == 0) { k = showlet; if (!validmsg(curlet)) break; print = 1; curlet++; } else k--; setletr(k, 'd'); if (resp[1] == 'p') print = 1; else if (resp[1] == 'q') goto donep; break; } } /* * Copy updated mailfile back */ donep: if (changed) { copyback(); stamp(); } }
/* * Find an inode header. * Complain if had to skip, and complain is set. */ static void findinode(struct s_spcl *header) { static long skipcnt = 0; long i; char buf[TP_BSIZE]; curfile.name = "<name unknown>"; curfile.action = UNKNOWN; curfile.mode = 0; curfile.ino = 0; do { if (header->c_magic != FS_UFS2_MAGIC) { skipcnt++; while (gethead(header) == FAIL || header->c_date != dumpdate) skipcnt++; } switch (header->c_type) { case TS_ADDR: /* * Skip up to the beginning of the next record */ for (i = 0; i < header->c_count; i++) if (header->c_addr[i]) readtape(buf); while (gethead(header) == FAIL || header->c_date != dumpdate) skipcnt++; break; case TS_INODE: curfile.mode = header->c_mode; curfile.uid = header->c_uid; curfile.gid = header->c_gid; curfile.file_flags = header->c_file_flags; curfile.rdev = header->c_rdev; curfile.atime_sec = header->c_atime; curfile.atime_nsec = header->c_atimensec; curfile.mtime_sec = header->c_mtime; curfile.mtime_nsec = header->c_mtimensec; curfile.birthtime_sec = header->c_birthtime; curfile.birthtime_nsec = header->c_birthtimensec; curfile.size = header->c_size; curfile.ino = header->c_inumber; break; case TS_END: curfile.ino = maxino; break; case TS_CLRI: curfile.name = "<file removal list>"; break; case TS_BITS: curfile.name = "<file dump list>"; break; case TS_TAPE: panic("unexpected tape header\n"); /* NOTREACHED */ default: panic("unknown tape header type %d\n", spcl.c_type); /* NOTREACHED */ } } while (header->c_type == TS_ADDR); if (skipcnt > 0) fprintf(stderr, "resync restore, skipped %ld blocks\n", skipcnt); skipcnt = 0; }
/* * Verify that the tape drive can be accessed and * that it actually is a dump tape. */ void setup(void) { int i, j, *ip; struct stat stbuf; vprintf(stdout, "Verify tape and initialize maps\n"); if (pipecmdin) { if (setenv("RESTORE_VOLUME", "1", 1) == -1) { fprintf(stderr, "Cannot set $RESTORE_VOLUME: %s\n", strerror(errno)); done(1); } popenfp = popen(magtape, "r"); mt = popenfp ? fileno(popenfp) : -1; } else #ifdef RRESTORE if (host) mt = rmtopen(magtape, 0); else #endif if (pipein) mt = 0; else mt = open(magtape, O_RDONLY, 0); if (mt < 0) { fprintf(stderr, "%s: %s\n", magtape, strerror(errno)); done(1); } volno = 1; setdumpnum(); FLUSHTAPEBUF(); if (!pipein && !pipecmdin && !bflag) findtapeblksize(); if (gethead(&spcl) == FAIL) { fprintf(stderr, "Tape is not a dump tape\n"); done(1); } if (pipein) { endoftapemark.s_spcl.c_magic = FS_UFS2_MAGIC; endoftapemark.s_spcl.c_type = TS_END; ip = (int *)&endoftapemark; j = sizeof(union u_spcl) / sizeof(int); i = 0; do i += *ip++; while (--j); endoftapemark.s_spcl.c_checksum = CHECKSUM - i; } if (vflag || command == 't') printdumpinfo(); dumptime = _time64_to_time(spcl.c_ddate); dumpdate = _time64_to_time(spcl.c_date); if (stat(".", &stbuf) < 0) { fprintf(stderr, "cannot stat .: %s\n", strerror(errno)); done(1); } if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE ) fssize = TP_BSIZE; if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE) fssize = stbuf.st_blksize; if (((TP_BSIZE - 1) & stbuf.st_blksize) != 0) { fprintf(stderr, "Warning: filesystem with non-multiple-of-%d " "blocksize (%d);\n", TP_BSIZE, stbuf.st_blksize); fssize = roundup(fssize, TP_BSIZE); fprintf(stderr, "\twriting using blocksize %ld\n", fssize); } if (spcl.c_volume != 1) { fprintf(stderr, "Tape is not volume 1 of the dump\n"); done(1); } if (gethead(&spcl) == FAIL) { dprintf(stdout, "header read failed at %ld blocks\n", blksread); panic("no header after volume mark!\n"); } findinode(&spcl); if (spcl.c_type != TS_CLRI) { fprintf(stderr, "Cannot find file removal list\n"); done(1); } maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1; dprintf(stdout, "maxino = %ju\n", (uintmax_t)maxino); map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); if (map == NULL) panic("no memory for active inode map\n"); usedinomap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip, xtrmapskip); if (spcl.c_type != TS_BITS) { fprintf(stderr, "Cannot find file dump list\n"); done(1); } map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); if (map == (char *)NULL) panic("no memory for file dump list\n"); dumpmap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip, xtrmapskip); /* * If there may be whiteout entries on the tape, pretend that the * whiteout inode exists, so that the whiteout entries can be * extracted. */ SETINO(WINO, dumpmap); /* 'r' restores don't call getvol() for tape 1, so mark it as read. */ if (command == 'r') tapesread = 1; }
/* * Verify that the tape drive can be accessed and * that it actually is a dump tape. */ void setup(void) { int i, j, *ip; struct stat stbuf; Vprintf(stdout, "Verify tape and initialize maps\n"); #ifdef RRESTORE if (host) mt = rmtopen(magtape, 0); else #endif if (pipein) mt = 0; else mt = open(magtape, O_RDONLY); if (mt < 0) err(1, "%s", magtape); volno = 1; setdumpnum(); FLUSHTAPEBUF(); if (!pipein && !bflag) findtapeblksize(); if (gethead(&spcl) == FAIL) { blkcnt--; /* push back this block */ blksread--; tpblksread--; cvtflag++; if (gethead(&spcl) == FAIL) errx(1, "Tape is not a dump tape"); (void)fputs("Converting to new file system format.\n", stderr); } if (pipein) { endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : FS_UFS2_MAGIC; endoftapemark.s_spcl.c_type = TS_END; ip = (int *)&endoftapemark; j = sizeof(union u_spcl) / sizeof(int); i = 0; do i += *ip++; while (--j); endoftapemark.s_spcl.c_checksum = CHECKSUM - i; } if (vflag || command == 't') printdumpinfo(); dumptime = (time_t)spcl.c_ddate; dumpdate = (time_t)spcl.c_date; if (stat(".", &stbuf) < 0) err(1, "cannot stat ."); if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE ) fssize = TP_BSIZE; if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE) fssize = stbuf.st_blksize; if (((fssize - 1) & fssize) != 0) errx(1, "bad block size %ld", fssize); if (spcl.c_volume != 1) errx(1, "Tape is not volume 1 of the dump"); if (gethead(&spcl) == FAIL) { Dprintf(stdout, "header read failed at %ld blocks\n", blksread); panic("no header after volume mark!\n"); } findinode(&spcl); if (spcl.c_type != TS_CLRI) errx(1, "Cannot find file removal list"); maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1; Dprintf(stdout, "maxino = %d\n", maxino); map = calloc(1, howmany(maxino, NBBY)); if (map == NULL) panic("no memory for active inode map\n"); usedinomap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip); if (spcl.c_type != TS_BITS) errx(1, "Cannot find file dump list"); map = calloc(1, howmany(maxino, NBBY)); if (map == NULL) panic("no memory for file dump list\n"); dumpmap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip); }
/* * Extract a file from the tape. * When an allocated block is found it is passed to the fill function; * when an unallocated block (hole) is found, a zeroed buffer is passed * to the skip function. */ void getfile(void (*datafill)(char *, long), void (*attrfill)(char *, long), void (*skip)(char *, long)) { int i; off_t size; int curblk, attrsize; void (*fillit)(char *, long); static char clearedbuf[MAXBSIZE]; char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE]; char junk[TP_BSIZE]; curblk = 0; size = spcl.c_size; attrsize = spcl.c_extsize; if (spcl.c_type == TS_END) panic("ran off end of tape\n"); if (spcl.c_magic != FS_UFS2_MAGIC) panic("not at beginning of a file\n"); if (!gettingfile && setjmp(restart) != 0) return; gettingfile++; fillit = datafill; if (size == 0 && attrsize > 0) { fillit = attrfill; size = attrsize; attrsize = 0; } loop: for (i = 0; i < spcl.c_count; i++) { if (!readmapflag && i > TP_NINDIR) { if (Dflag) { fprintf(stderr, "spcl.c_count = %jd\n", (intmax_t)spcl.c_count); break; } else panic("spcl.c_count = %jd\n", (intmax_t)spcl.c_count); } if (readmapflag || spcl.c_addr[i]) { readtape(&buf[curblk++][0]); if (curblk == fssize / TP_BSIZE) { (*fillit)((char *)buf, (long)(size > TP_BSIZE ? fssize : (curblk - 1) * TP_BSIZE + size)); curblk = 0; } } else { if (curblk > 0) { (*fillit)((char *)buf, (long)(size > TP_BSIZE ? curblk * TP_BSIZE : (curblk - 1) * TP_BSIZE + size)); curblk = 0; } (*skip)(clearedbuf, (long)(size > TP_BSIZE ? TP_BSIZE : size)); } if ((size -= TP_BSIZE) <= 0) { if (size > -TP_BSIZE && curblk > 0) { (*fillit)((char *)buf, (long)((curblk * TP_BSIZE) + size)); curblk = 0; } if (attrsize > 0) { fillit = attrfill; size = attrsize; attrsize = 0; continue; } if (spcl.c_count - i > 1) dprintf(stdout, "skipping %d junk block(s)\n", spcl.c_count - i - 1); for (i++; i < spcl.c_count; i++) { if (!readmapflag && i > TP_NINDIR) { if (Dflag) { fprintf(stderr, "spcl.c_count = %jd\n", (intmax_t)spcl.c_count); break; } else panic("spcl.c_count = %jd\n", (intmax_t)spcl.c_count); } if (readmapflag || spcl.c_addr[i]) readtape(junk); } break; } } if (gethead(&spcl) == GOOD && size > 0) { if (spcl.c_type == TS_ADDR) goto loop; dprintf(stdout, "Missing address (header) block for %s at %ld blocks\n", curfile.name, blksread); } if (curblk > 0) panic("getfile: lost data\n"); findinode(&spcl); gettingfile = 0; }
/* * Find an inode header. * Complain if had to skip. */ static void findinode(struct s_spcl *header) { static long skipcnt = 0; long i; char buf[TP_BSIZE]; int htype; curfile.name = "<name unknown>"; curfile.action = UNKNOWN; curfile.dip = NULL; curfile.ino = 0; do { if (header->c_magic != NFS_MAGIC) { skipcnt++; while (gethead(header) == FAIL || header->c_date != dumpdate) skipcnt++; } htype = header->c_type; switch (htype) { case TS_ADDR: /* * Skip up to the beginning of the next record */ for (i = 0; i < header->c_count; i++) if (header->c_addr[i]) readtape(buf); while (gethead(header) == FAIL || header->c_date != dumpdate) skipcnt++; break; case TS_INODE: curfile.dip = &header->c_dinode; curfile.ino = header->c_inumber; break; case TS_END: /* If we missed some tapes, get another volume. */ if (tapesread & (tapesread + 1)) { getvol(0); continue; } curfile.ino = maxino; break; case TS_CLRI: curfile.name = "<file removal list>"; break; case TS_BITS: curfile.name = "<file dump list>"; break; case TS_TAPE: panic("unexpected tape header\n"); /* NOTREACHED */ default: panic("unknown tape header type %d\n", spcl.c_type); /* NOTREACHED */ } } while (htype == TS_ADDR); if (skipcnt > 0) fprintf(stderr, "resync restore, skipped %ld blocks\n", skipcnt); skipcnt = 0; }