Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/src/cmd/cwfs/con.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "all.h"
2
 
3
static	Command	command[100];
4
static	Flag	flag[35];
5
static	char	statsdef[20];	/* default stats list */
6
static	int	whoflag;
7
 
8
static	void	consserve1(void *);
9
static	void	installcmds(void);
10
 
11
void
12
consserve(void)
13
{
14
	int i;
15
 
16
	strncpy(cons.chan->whochan, "console", sizeof(cons.chan->whochan));
17
	installcmds();
18
	con_session();
19
	cmd_exec("cfs");
20
	cmd_exec("users");
21
	cmd_exec("version");
22
 
23
	for(i = 0; command[i].arg0; i++)
24
		if(strcmp("cwcmd", command[i].arg0) == 0){
25
			cmd_exec("cwcmd touchsb");
26
			break;
27
		}
28
 
29
	newproc(consserve1, 0, "con");
30
}
31
 
32
/* console commands process */
33
static void
34
consserve1(void *)
35
{
36
	char *conline;
37
 
38
	for (;;) {
39
		/* conslock(); */
40
		do {
41
			print("%s: ", service);
42
			if ((conline = Brdline(&bin, '\n')) == nil)
43
				print("\n");
44
			else {
45
				conline[Blinelen(&bin)-1] = '\0';
46
				cmd_exec(conline);
47
			}
48
		} while (conline != nil);
49
	}
50
}
51
 
52
static int
53
cmdcmp(void *va, void *vb)
54
{
55
	Command *a, *b;
56
 
57
	a = va;
58
	b = vb;
59
	return strcmp(a->arg0, b->arg0);
60
}
61
 
62
void
63
cmd_install(char *arg0, char *help, void (*func)(int, char*[]))
64
{
65
	int i;
66
 
67
	qlock(&cons);
68
	for(i=0; command[i].arg0; i++)
69
		;
70
	if(i >= nelem(command)-2) {
71
		qunlock(&cons);
72
		print("cmd_install: too many commands\n");
73
		return;
74
	}
75
	command[i+1].arg0 = 0;
76
	command[i].help = help;
77
	command[i].func = func;
78
	command[i].arg0 = arg0;
79
	qsort(command, i+1, sizeof(Command), cmdcmp);
80
	qunlock(&cons);
81
}
82
 
83
void
84
cmd_exec(char *arg)
85
{
86
	char line[2*Maxword], *s;
87
	char *argv[10];
88
	int argc, i, c;
89
 
90
	if(strlen(arg) >= nelem(line)-2) {
91
		print("cmd_exec: line too long\n");
92
		return;
93
	}
94
	strcpy(line, arg);
95
 
96
	argc = 0;
97
	s = line;
98
	c = *s++;
99
	for(;;) {
100
		while(isascii(c) && isspace(c))
101
			c = *s++;
102
		if(c == 0)
103
			break;
104
		if(argc >= nelem(argv)-2) {
105
			print("cmd_exec: too many args\n");
106
			return;
107
		}
108
		argv[argc++] = s-1;
109
		while((!isascii(c) || !isspace(c)) && c != '\0')
110
			c = *s++;
111
		s[-1] = 0;
112
	}
113
	if(argc <= 0)
114
		return;
115
	for(i=0; s=command[i].arg0; i++)
116
		if(strcmp(argv[0], s) == 0) {
117
			(*command[i].func)(argc, argv);
118
			prflush();
119
			return;
120
		}
121
	print("cmd_exec: unknown command: %s\n", argv[0]);
122
}
123
 
124
static void
125
cmd_halt(int, char *[])
126
{
127
	wlock(&mainlock);	/* halt */
128
	sync("halt");
129
	exit();
130
}
131
 
132
static void
133
cmd_duallow(int argc, char *argv[])
134
{
135
	int uid;
136
 
137
	if(argc <= 1) {
138
		duallow = 0;
139
		return;
140
	}
141
 
142
	uid = strtouid(argv[1]);
143
	if(uid < 0)
144
		uid = number(argv[1], -2, 10);
145
	if(uid < 0) {
146
		print("bad uid %s\n", argv[1]);
147
		return;
148
	}
149
	duallow = uid;
150
}
151
 
152
static void
153
cmd_stats(int argc, char *argv[])
154
{
155
	int i, c;
156
	char buf[30], *s, *p, *q;
157
 
158
	if(argc <= 1) {
159
		if(statsdef[0] == 0)
160
			strcpy(statsdef, "a");
161
		sprint(buf, "stats s%s", statsdef);
162
		cmd_exec(buf);
163
		return;
164
	}
165
 
166
	strcpy(buf, "stat");
167
	p = strchr(buf, 0);
168
	p[1] = 0;
169
 
170
	q = 0;
171
	for(i = 1; i < argc; i++)
172
		for(s = argv[i]; c = *s; s++) {
173
			if(c == 's')
174
				continue;
175
			if(c == '-') {
176
				q = statsdef;
177
				continue;
178
			}
179
			if(q) {
180
				*q++ = c;
181
				*q = 0;
182
			}
183
			*p = c;
184
			cmd_exec(buf);
185
		}
186
}
187
 
188
static void
189
cmd_stata(int, char *[])
190
{
191
	int i;
192
 
193
	print("cons stats\n");
194
//	print("\twork =%7W%7W%7W rps\n", cons.work+0, cons.work+1, cons.work+2);
195
//	print("\trate =%7W%7W%7W tBps\n", cons.rate+0, cons.rate+1, cons.rate+2);
196
//	print("\thits =%7W%7W%7W iops\n", cons.bhit+0, cons.bhit+1, cons.bhit+2);
197
//	print("\tread =%7W%7W%7W iops\n", cons.bread+0, cons.bread+1, cons.bread+2);
198
//	print("\trah  =%7W%7W%7W iops\n", cons.brahead+0, cons.brahead+1, cons.brahead+2);
199
//	print("\tinit =%7W%7W%7W iops\n", cons.binit+0, cons.binit+1, cons.binit+2);
200
	print("\tbufs =    %3ld sm %3ld lg %ld res\n",
201
		cons.nsmall, cons.nlarge, cons.nreseq);
202
 
203
	for(i=0; i<nelem(mballocs); i++)
204
		if(mballocs[i])
205
			print("\t[%d]=%d\n", i, mballocs[i]);
206
 
207
	print("\tioerr=    %3ld wr %3ld ww %3ld dr %3ld dw\n",
208
		cons.nwormre, cons.nwormwe, cons.nwrenre, cons.nwrenwe);
209
	print("\tcache=     %9ld hit %9ld miss\n",
210
		cons.nwormhit, cons.nwormmiss);
211
}
212
 
213
static int
214
flagcmp(void *va, void *vb)
215
{
216
	Flag *a, *b;
217
 
218
	a = va;
219
	b = vb;
220
	return strcmp(a->arg0, b->arg0);
221
}
222
 
223
ulong
224
flag_install(char *arg, char *help)
225
{
226
	int i;
227
 
228
	qlock(&cons);
229
	for(i=0; flag[i].arg0; i++)
230
		;
231
	if(i >= 32) {
232
		qunlock(&cons);
233
		print("flag_install: too many flags\n");
234
		return 0;
235
	}
236
	flag[i+1].arg0 = 0;
237
	flag[i].arg0 = arg;
238
	flag[i].help = help;
239
	flag[i].flag = 1<<i;
240
	qsort(flag, i+1, sizeof(Flag), flagcmp);
241
	qunlock(&cons);
242
	return 1<<i;
243
}
244
 
245
void
246
cmd_flag(int argc, char *argv[])
247
{
248
	int f, n, i, j;
249
	char *s;
250
	Chan *cp;
251
 
252
	if(argc <= 1) {
253
		for(i=0; flag[i].arg0; i++)
254
			print("%.4lux %s %s\n",
255
				flag[i].flag, flag[i].arg0, flag[i].help);
256
		if(cons.flags)
257
			print("flag[*]   = %.4lux\n", cons.flags);
258
		for(cp = chans; cp; cp = cp->next)
259
			if(cp->flags)
260
				print("flag[%3d] = %.4lux\n", cp->chan, cp->flags);
261
		return;
262
	}
263
 
264
	f = 0;
265
	n = -1;
266
	for(i=1; i<argc; i++) {
267
		for(j=0; s=flag[j].arg0; j++)
268
			if(strcmp(s, argv[i]) == 0)
269
				goto found;
270
		j = number(argv[i], -1, 10);
271
		if(j < 0) {
272
			print("bad flag argument: %s\n", argv[i]);
273
			continue;
274
		}
275
		n = j;
276
		continue;
277
	found:
278
		f |= flag[j].flag;
279
	}
280
 
281
	if(n < 0) {
282
		cons.flags ^= f;
283
		if(f == 0)
284
			cons.flags = 0;
285
		print("flag      = %.8lux\n", cons.flags);
286
		return;
287
	}
288
	for(cp = chans; cp; cp = cp->next)
289
		if(cp->chan == n) {
290
			cp->flags ^= f;
291
			if(f == 0)
292
				cp->flags = 0;
293
			print("flag[%3d] = %.8lux\n", cp->chan, cp->flags);
294
			return;
295
		}
296
	print("no such channel\n");
297
}
298
 
299
static void
300
cmd_who(int argc, char *argv[])
301
{
302
	Chan *cp;
303
	int i, c;
304
 
305
	c = 0;
306
	for(cp = chans; cp; cp = cp->next) {
307
		if(cp->whotime == 0 && !(cons.flags & whoflag)) {
308
			c++;
309
			continue;
310
		}
311
		if(argc > 1) {
312
			for(i=1; i<argc; i++)
313
				if(strcmp(argv[i], cp->whoname) == 0)
314
					break;
315
			if(i >= argc) {
316
				c++;
317
				continue;
318
			}
319
		}
320
		print("%3d: %10s %24s", cp->chan,
321
			cp->whoname? cp->whoname: "<nowhoname>", cp->whochan);
322
		if(cp->whoprint)
323
			cp->whoprint(cp);
324
		print("\n");
325
		prflush();
326
	}
327
	if(c > 0)
328
		print("%d chans not listed\n", c);
329
}
330
 
331
static void
332
cmd_hangup(int argc, char *argv[])
333
{
334
	Chan *cp;
335
	int n;
336
 
337
	if(argc < 2) {
338
		print("usage: hangup chan-number\n");
339
		return;
340
	}
341
	n = number(argv[1], -1, 10);
342
	for(cp = chans; cp; cp = cp->next) {
343
		if(cp->whotime == 0) {
344
			if(cp->chan == n)
345
				print("that chan is hung up\n");
346
			continue;
347
		}
348
		if(cp->chan == n) {
349
			/* need more than just fileinit with tcp */
350
			chanhangup(cp, "console command", 1);
351
			fileinit(cp);
352
		}
353
	}
354
}
355
 
356
static void
357
cmd_sync(int, char *[])
358
{
359
	wlock(&mainlock);	/* sync */
360
	sync("command");
361
	wunlock(&mainlock);
362
	print("\n");
363
}
364
 
365
static void
366
cmd_help(int argc, char *argv[])
367
{
368
	char *arg;
369
	int i, j;
370
 
371
	for(i=0; arg=command[i].arg0; i++) {
372
		if(argc > 1) {
373
			for(j=1; j<argc; j++)
374
				if(strcmp(argv[j], arg) == 0)
375
					goto found;
376
			continue;
377
		}
378
	found:
379
		print("\t%s %s\n", arg, command[i].help);
380
		prflush();
381
	}
382
}
383
 
384
void
385
cmd_fstat(int argc, char *argv[])
386
{
387
	int i;
388
 
389
	for(i=1; i<argc; i++) {
390
		if(walkto(argv[i])) {
391
			print("cant stat %s\n", argv[i]);
392
			continue;
393
		}
394
		con_fstat(FID2);
395
	}
396
}
397
 
398
void
399
cmd_create(int argc, char *argv[])
400
{
401
	int uid, gid;
402
	long perm;
403
	char elem[NAMELEN], *p;
404
 
405
	if(argc < 5) {
406
		print("usage: create path uid gid mode [lad]\n");
407
		return;
408
	}
409
 
410
	p = utfrrune(argv[1], '/');
411
	if(p) {
412
		*p++ = 0;
413
		if(walkto(argv[1])) {
414
			print("create failed in walkto: %s\n", p);
415
			return;
416
		}
417
	} else {
418
		if(walkto("/"))
419
			return;
420
		p = argv[1];
421
	}
422
	if(strlen(p) >= NAMELEN) {
423
		print("name too long %s\n", p);
424
		return;
425
	}
426
 
427
	memset(elem, 0, sizeof(elem));
428
	strcpy(elem, p);
429
 
430
	uid = strtouid(argv[2]);
431
	if(uid < -1)
432
		uid = number(argv[2], -2, 10);
433
	if(uid < -1) {
434
		print("bad uid %s\n", argv[2]);
435
		return;
436
	}
437
 
438
	gid = strtouid(argv[3]);
439
	if(gid < -1)
440
		gid = number(argv[3], -2, 10);
441
	if(gid < -1) {
442
		print("bad gid %s\n", argv[3]);
443
		return;
444
	}
445
 
446
	perm = number(argv[4], 0777, 8) & 0777;
447
 
448
	if(argc > 5) {
449
		if(strchr(argv[5], 'l'))
450
			perm |= PLOCK;
451
		if(strchr(argv[5], 'a'))
452
			perm |= PAPND;
453
		if(strchr(argv[5], 'd'))
454
			perm |= PDIR;
455
	}
456
 
457
	if(con_create(FID2, elem, uid, gid, perm, 0))
458
		print("create failed: %s/%s\n", argv[1], p);
459
}
460
 
461
static void
462
cmd_clri(int argc, char *argv[])
463
{
464
	int i;
465
 
466
	for(i=1; i<argc; i++) {
467
		if(walkto(argv[i])) {
468
			print("cant remove %s\n", argv[i]);
469
			continue;
470
		}
471
		con_clri(FID2);
472
	}
473
}
474
 
475
static void
476
cmd_allow(int, char**)
477
{
478
	wstatallow = writeallow = 1;
479
}
480
 
481
static void
482
cmd_disallow(int, char**)
483
{
484
	wstatallow = writeallow = 0;
485
}
486
 
487
void
488
ckblock(Device *d, Off a, int typ, Off qpath)
489
{
490
	Iobuf *p;
491
 
492
	if(a) {
493
		p = getbuf(d, a, Brd);
494
		if(p) {
495
			checktag(p, typ, qpath);
496
			putbuf(p);
497
		}
498
	}
499
}
500
 
501
void
502
doclean(Iobuf *p, Dentry *d, int n, Off a)
503
{
504
	int i, mod, typ;
505
	Off qpath;
506
 
507
	mod = 0;
508
	qpath = d->qid.path;
509
	typ = Tfile;
510
	if(d->mode & DDIR)
511
		typ = Tdir;
512
	for(i=0; i<NDBLOCK; i++) {
513
		print("dblock[%d] = %lld\n", i, (Wideoff)d->dblock[i]);
514
		ckblock(p->dev, d->dblock[i], typ, qpath);
515
		if(i == n) {
516
			d->dblock[i] = a;
517
			mod = 1;
518
			print("dblock[%d] modified %lld\n", i, (Wideoff)a);
519
		}
520
	}
521
 
522
	/* add NDBLOCK so user can cite block address by index */
523
	for (i = 0; i < NIBLOCK; i++) {
524
		print("iblocks[%d] = %lld\n", NDBLOCK+i, (Wideoff)d->iblocks[i]);
525
		ckblock(p->dev, d->iblocks[i], Tind1+i, qpath);
526
		if(NDBLOCK+i == n) {
527
			d->iblocks[i] = a;
528
			mod = 1;
529
			print("iblocks[%d] modified %lld\n", NDBLOCK+i, (Wideoff)a);
530
		}
531
	}
532
 
533
	if(mod)
534
		p->flags |= Bmod|Bimm;
535
}
536
 
537
static void
538
cmd_clean(int argc, char *argv[])
539
{
540
	int n;
541
	Off a;
542
	Iobuf *p;
543
	Dentry *d;
544
	File *f;
545
 
546
	p = 0;
547
	f = 0;
548
	while(argc > 1) {
549
		n = -1;
550
		if(argc > 2)
551
			n = number(argv[2], -1, 10);
552
		a = 0;
553
		if(argc > 3)
554
			a = number(argv[3], 0, 10);
555
		if(walkto(argv[1])) {
556
			print("cant remove %s\n", argv[1]);
557
			break;
558
		}
559
		f = filep(cons.chan, FID2, 0);
560
		if(!f)
561
			break;
562
		if(n >= 0 && f->fs->dev->type == Devro) {
563
			print("readonly %s\n", argv[1]);
564
			break;
565
		}
566
		p = getbuf(f->fs->dev, f->addr, Brd);
567
		d = getdir(p, f->slot);
568
		if(!d || !(d->mode & DALLOC)) {
569
			print("not alloc %s\n", argv[1]);
570
			break;
571
		}
572
		doclean(p, d, n, a);
573
		break;
574
	}
575
	if(f)
576
		qunlock(f);
577
	if(p)
578
		putbuf(p);
579
}
580
 
581
static void
582
cmd_remove(int argc, char *argv[])
583
{
584
	int i;
585
 
586
	for(i=1; i<argc; i++) {
587
		if(walkto(argv[i])) {
588
			print("cant remove %s\n", argv[i]);
589
			continue;
590
		}
591
		con_remove(FID2);
592
	}
593
}
594
 
595
static void
596
cmd_version(int, char *[])
597
{
598
	print("%d-bit %s as of %T\n", sizeof(Off)*8 - 1, service, fs_mktime);
599
	print("\tlast boot %T\n", boottime);
600
}
601
 
602
static void
603
cmd_cfs(int argc, char *argv[])
604
{
605
	Filsys *fs;
606
	char *name;
607
 
608
	name = "main";
609
	if(argc > 1)
610
		name = argv[1];
611
	fs = fsstr(name);
612
	if(fs == 0) {
613
		print("%s: unknown file system\n", name);
614
		if(cons.curfs)
615
			return;
616
		fs = &filsys[0];
617
	}
618
	if(con_attach(FID1, "adm", fs->name))
619
		panic("FID1 attach to root");
620
	cons.curfs = fs;
621
	print("current fs is \"%s\"\n", cons.curfs->name);
622
}
623
 
624
static void
625
cmd_prof(int argc, char *argv[])
626
{
627
	int n;
628
	long m, o;
629
	char *p;
630
 
631
	if(cons.profbuf == 0) {
632
		print("no buffer\n");
633
		return;
634
	}
635
	n = !cons.profile;
636
	if(argc > 1)
637
		n = number(argv[1], n, 10);
638
	if(n && !cons.profile) {
639
		print("clr and start\n");
640
		memset(cons.profbuf, 0, cons.nprofbuf*sizeof(cons.profbuf[0]));
641
		cons.profile = 1;
642
		return;
643
	}
644
	if(!n && cons.profile) {
645
		cons.profile = 0;
646
		print("stop and write\n");
647
		if(walkto("/adm/kprofdata"))
648
			goto bad;
649
		if(con_open(FID2, OWRITE|OTRUNC)) {
650
		bad:
651
			print("cant open /adm/kprofdata\n");
652
			return;
653
		}
654
		p = (char*)cons.profbuf;
655
		for(m=0; m<cons.nprofbuf; m++) {
656
			n = cons.profbuf[m];
657
			p[0] = n>>24;
658
			p[1] = n>>16;
659
			p[2] = n>>8;
660
			p[3] = n>>0;
661
			p += 4;
662
		}
663
 
664
		m = cons.nprofbuf*sizeof(cons.profbuf[0]);
665
		o = 0;
666
		while(m > 0) {
667
			n = 8192;
668
			if(n > m)
669
				n = m;
670
			con_write(FID2, (char*)cons.profbuf+o, o, n);
671
			m -= n;
672
			o += n;
673
		}
674
		return;
675
	}
676
}
677
 
678
static void
679
cmd_time(int argc, char *argv[])
680
{
681
	int i, len;
682
	char *cmd;
683
	Timet t1, t2;
684
 
685
	t1 = time(nil);
686
	len = 0;
687
	for(i=1; i<argc; i++)
688
		len += 1 + strlen(argv[i]);
689
	cmd = malloc(len + 1);
690
	cmd[0] = 0;
691
	for(i=1; i<argc; i++) {
692
		strcat(cmd, " ");
693
		strcat(cmd, argv[i]);
694
	}
695
	cmd_exec(cmd);
696
	t2 = time(nil);
697
	free(cmd);
698
	print("time = %ld ms\n", TK2MS(t2-t1));
699
}
700
 
701
void
702
cmd_noattach(int, char *[])
703
{
704
	noattach = !noattach;
705
	if(noattach)
706
		print("attaches are DISABLED\n");
707
}
708
 
709
void
710
cmd_files(int, char *[])
711
{
712
	long i, n;
713
	Chan *cp;
714
 
715
	for(cp = chans; cp; cp = cp->next)
716
		cp->nfile = 0;
717
 
718
	lock(&flock);
719
	n = 0;
720
	for(i=0; i<conf.nfile; i++)
721
		if(files[i].cp) {
722
			n++;
723
			files[i].cp->nfile++;
724
		}
725
	print("%ld out of %ld files used\n", n, conf.nfile);
726
	unlock(&flock);
727
 
728
	n = 0;
729
	for(cp = chans; cp; cp = cp->next)
730
		if(cp->nfile) {
731
			print("%3d: %5d\n", cp->chan, cp->nfile);
732
			prflush();
733
			n += cp->nfile;
734
		}
735
	print("%ld out of %ld files used\n", n, conf.nfile);
736
}
737
 
738
static void
739
installcmds(void)
740
{
741
	cmd_install("allow", "-- disable permission checking", cmd_allow);
742
	cmd_install("cfs", "[file] -- set current filesystem", cmd_cfs);
743
	cmd_install("clean", "file [bno [addr]] -- block print/fix", cmd_clean);
744
	cmd_install("check", "[options]", cmd_check);
745
	cmd_install("clri", "[file ...] -- purge files/dirs", cmd_clri);
746
	cmd_install("create", "path uid gid perm [lad] -- make a file/dir", cmd_create);
747
	cmd_install("disallow", "-- enable permission checking", cmd_disallow);
748
	cmd_install("duallow", "uid -- duallow", cmd_duallow);
749
	cmd_install("flag", "-- print set flags", cmd_flag);
750
	cmd_install("fstat", "path -- print info on a file/dir", cmd_fstat);
751
	cmd_install("halt", "-- return to boot rom", cmd_halt);
752
	cmd_install("help", "", cmd_help);
753
	cmd_install("newuser", "username -- add user to /adm/users", cmd_newuser);
754
	cmd_install("profile", "[01] -- fs profile", cmd_prof);
755
	cmd_install("remove", "[file ...] -- remove files/dirs", cmd_remove);
756
	cmd_install("stata", "-- overall stats", cmd_stata);
757
	cmd_install("stats", "[[-]flags ...] -- various stats", cmd_stats);
758
	cmd_install("sync", "", cmd_sync);
759
	cmd_install("time", "command -- time another command", cmd_time);
760
	cmd_install("users", "[file] -- read /adm/users", cmd_users);
761
	cmd_install("version", "-- print time of mk and boot", cmd_version);
762
	cmd_install("who", "[user ...] -- print attaches", cmd_who);
763
	cmd_install("hangup", "chan -- clunk files", cmd_hangup);
764
	cmd_install("printconf", "-- print configuration", cmd_printconf);
765
	cmd_install("noattach", "toggle noattach flag", cmd_noattach);
766
	cmd_install("files", "report on files structure", cmd_files);
767
 
768
	attachflag = flag_install("attach", "-- attach calls");
769
	chatflag = flag_install("chat", "-- verbose");
770
	errorflag = flag_install("error", "-- on errors");
771
	whoflag = flag_install("allchans", "-- on who");
772
	authdebugflag = flag_install("authdebug", "-- report authentications");
773
	authdisableflag = flag_install("authdisable", "-- disable authentication");
774
}
775
 
776
int
777
walkto(char *name)
778
{
779
	char elem[NAMELEN], *p;
780
	int n;
781
 
782
	if(con_clone(FID1, FID2))
783
		return 1;
784
 
785
	for(;;) {
786
		p = utfrune(name, '/');
787
		if(p == nil)
788
			p = strchr(name, '\0');
789
		if(p == name) {
790
			if(*name == '\0')
791
				return 0;
792
			name = p+1;
793
			continue;
794
		}
795
		n = p-name;
796
		if(n > NAMELEN)
797
			return 1;
798
		memset(elem, 0, sizeof(elem));
799
		memmove(elem, name, n);
800
		if(con_walk(FID2, elem))
801
			return 1;
802
		name = p;
803
	}
804
}
805
 
806
/* needs to parse and return vlongs to cope with new larger block numbers */
807
vlong
808
number(char *arg, int def, int base)
809
{
810
	int c, sign, any;
811
	vlong n;
812
 
813
	if(arg == nil)
814
		return def;
815
 
816
	sign = 0;
817
	any = 0;
818
	n = 0;
819
 
820
	for (c = *arg; isascii(c) && isspace(c) && c != '\n'; c = *arg)
821
		arg++;
822
	if(c == '-') {
823
		sign = 1;
824
		arg++;
825
		c = *arg;
826
	}
827
	while (isascii(c) && (isdigit(c) || base == 16 && isxdigit(c))) {
828
		n *= base;
829
		if(c >= 'a' && c <= 'f')
830
			n += c - 'a' + 10;
831
		else if(c >= 'A' && c <= 'F')
832
			n += c - 'A' + 10;
833
		else
834
			n += c - '0';
835
		arg++;
836
		c = *arg;
837
		any = 1;
838
	}
839
	if(!any)
840
		return def;
841
	if(sign)
842
		n = -n;
843
	return n;
844
}