12 Oct, 2008, quixadhal wrote in the 101st comment:
Votes: 0
Hmmm, here's an idea. If we're willing to move the code along to a standard that's newer than it is (C99), it looks like uint16_t and friends are defined in /usr/include/stdint.h for me. Anyone out there NOT have a stdint.h lurking in their header files somewhere?

For example, for me… intmax_t and int64_t both get mapped to "long long int", whereas on a real 64-bit archetecture, they're "long int". int32_t is an int for both of us. size_t and ptrdiff_t both vary, as you'd expect. And there are the usual INT8_MIN/UNINT16_MAX defines.

We should try to avoid using such things in printf's though, since printf tokens won't adapt as readily. "%ld" will always mean "long int", "%llx" will always mean "long long int as hex", even though a "long int" will vary in actual size.
12 Oct, 2008, David Haley wrote in the 102nd comment:
Votes: 0
It's unfortunate that while the types have been fairly standardized, the printf specifiers haven't. Still, most numbers that are being sent to the player are rather standard numbers. I'd be surprised if you regularly were sending 64 or 128 bit numbers to the player. In those rare cases where you are, it should suffice to just use ifdefs or some other mechanism to figure out what specifier to use.

Of course C++ makes the problem go away because you send the value itself to the stream, as opposed to needing a specifier – then the compiler can figure out how to map it most appropriately to the types that the stream can accept.

Ah well, who could ever need more than 16k, anyhow. :wink:
12 Oct, 2008, MacGregor wrote in the 103rd comment:
Votes: 0
As for changing all the shorts and longs to just plain ints, let's go for it. We shouldn't really have to worry about if the numbers are wide enough or not; in any case I can think of in the code, ints are.

It's the printf family stuff that's causing a problem. One solution is to use ifdefs, another is to use casts, I'm not really happy with either. Another (kludgy) solution would be to assign the sizes to temporary variables and use the temp variables in the printfs – eg. int size_kludge = sizeof( struct somestruct ); printf( "Size: %d\n", size_kludge ); .
12 Oct, 2008, David Haley wrote in the 104th comment:
Votes: 0
I'm not sure why using a temporary variable is any better than casting? Seems to me that it's actually worse as it introduces more levels of indirection. But still, perhaps it would be better to find out how many times this is actually a problem, and how many times it really should be a problem – that is, how many of the printf calls that use funny variable sizes actually need to use those variables. (Or rather, how many of those variables actually need to have funny sizes.)
12 Oct, 2008, Guest wrote in the 105th comment:
Votes: 0
Davion said:
db.c: In function char* str_dup(const char*):
db.c:2681: error: cast from const char* to unsigned int loses precision
cc1plus: warnings being treated as errors
db.c: In function void do_dump(CHAR_DATA*, const char*):
db.c:2816: warning: format %8d expects type int, but argument 4 has type long unsigned int
db.c:2816: warning: format %d expects type int, but argument 6 has type long unsigned int
db.c:2824: warning: format %8d expects type int, but argument 4 has type long unsigned int
db.c:2824: warning: format %d expects type int, but argument 6 has type long unsigned int
db.c:2834: warning: format %8d expects type int, but argument 4 has type long unsigned int
db.c:2834: warning: format %d expects type int, but argument 6 has type long unsigned int
db.c:2846: warning: format %8d expects type int, but argument 4 has type long unsigned int
db.c:2861: warning: format %8d expects type int, but argument 4 has type long unsigned int
db.c:2861: warning: format %d expects type int, but argument 6 has type long unsigned int
db.c:2869: warning: format %8d expects type int, but argument 4 has type long unsigned int
db.c:2869: warning: format %d expects type int, but argument 6 has type long unsigned int
db.c:2873: warning: format %8d expects type int, but argument 4 has type long unsigned int
db.c:2877: warning: format %8d expects type int, but argument 4 has type long unsigned int


The issue is with 'sizeof' being in the argument list for a printf statement. If I use %ld it works fine, but I'm unsure of how that looks on a 32 bit system. I'll let you know soon.

Ya, changing it to %ld fails to compile on 32bit systems.


Since this seems to be at the core of the whole 32/64 issue, wouldn't switching such instances to size_t solve the problem? printf() has a %zd tag that tells it the variable is declared as a size_t. This is more or less how I handled situations like then when working out kinks in AFKMud when I upgraded my servers to 64 bits. Declaring size_t works on both 32 and 64 bit platforms and using %zd has so far not raised any errors in either case.
12 Oct, 2008, MacGregor wrote in the 106th comment:
Votes: 0
Ah, that fixes the problem nicely! I didn't know about that z length modifier, but sure enough there it is, right in man 3 printf. Thanks, Samson!
13 Oct, 2008, David Haley wrote in the 107th comment:
Votes: 0
Sorry, I thought I had already mentioned %z but I guess I didn't actually name it. The problem with it is that, from some things I read in various places, it is not completely standard either. Still, for the our purposes here, it appears to be more or less standard.
13 Oct, 2008, quixadhal wrote in the 108th comment:
Votes: 0
crypt() is no more. All hail sha256_crypt(), which shall be addressed by the name CRYPT()!

For the reasoning behind this, see one of hundreds of support questions from forums all over the world where crypt() isn't supported because of US export laws.

Should you still wish to spy on your players and try to get their shell passwords, you can still define NOCRYPT in the Makefile, and it will happily not use encryption.

I also cranked up the optimization level, improved the Makefile a bit, and squashed a few more bugs.
13 Oct, 2008, MacGregor wrote in the 109th comment:
Votes: 0
You mean crypt() is still a dangerous munition? I thought some semblance of sanity was restored on that a few years back. How old are those posts? I did a very quick search and found stuff from the mid late 90's.
14 Oct, 2008, quixadhal wrote in the 110th comment:
Votes: 0
Considering that some OS's still refuse to include crypt(3) in their libraries, and that there are better options available, I figured it was simplest to just avoid the whole issue. If you're starting a new game based on RaM, it won't matter anyways… if you're foolish enough to try and somehow migrate your old game, well, it's not that big a deal to let people know their passwords will be reset.

I briefly considered putting code in to migrate the passwords, but it's a lot of junk code that 90% of our users won't need, and that puts us into having to continue to support crypt() anyways. Seems like a good exercise for the reader, or perhaps a snippet once things settle to the point that snippets make sense.

Wikipedia has some nice pages regarding these things. I especially liked:
Quote
On the earliest Unix machines it took over a full second to compute a password hash. This also made it reasonably resistant to dictionary attacks in that era.


Yeah, that makes me feel secure. You can't crack this because it would take your most powerful 386/40 years to brute force it!

On the notion of resetting passwords and such though, it occured to me that a couple of things to add to the startup files (if they aren't already there) would be entries for the mud name, address, email address of the admin, etc… so that can be shown in the login sequence AND in the messages sent to banned people.

IE: If you can't login, you should be sent a contact address so you can find out why, or get help resetting your password.
14 Oct, 2008, David Haley wrote in the 111th comment:
Votes: 0
quixadhal said:
Yeah, that makes me feel secure. You can't crack this because it would take your most powerful 386/40 years to brute force it!

Well, that's basically why the current passwords are secure… it would take too long to brute force it.

Incidentally, isn't SHA256 covered by the same export laws that crypt is?
14 Oct, 2008, quixadhal wrote in the 112th comment:
Votes: 0
I don't know about your OS, but mine doesn't use crypt() for passwords… or rather, it doesn't use the old crypt() based on DES where the data being encrypted was simply a block of all-zero bits (which is why it was easy to brute-force if you got a copy of /etc/passwd … you knew half the answer already). Mine appears to use MD5. The man page claims support is there for Blowfish, SHA256 and SHA512 as well, but MD5 is the default.

My understanding was that crypt() posed a particular problem because it was based on DES. The only export restrictions I could find related to SHA256 were mention of a restriction on a hardware imp... used by ATM machines.

Quote
The core is available for export to all the countries of the world with the exception of the
following:
Iran
North Korea
Libya
Cuba
Sudan
Syria
Iraq


It does look like this law might have expired in 1999. Of course, that doesn't change the fact that the DES style of crypt() isn't available on many platforms, by default.

Interesting anyways… I miss the old days when Google wasn't so flooded with advertising keywords and what you were actually looking for was almost always in the first 5 results. :)
14 Oct, 2008, Noplex wrote in the 113th comment:
Votes: 0
I thought that those encryption export laws were loosened back in the late nineties? I would imagine with the Internet and the need for secure websites for payment transactions this was necessary. Of course there are probably obscure laws that only the people writing crypto algorithms deal with.

I think SHA256 software encryption is safe to export; doesn't it ship with Linux distributions?
14 Oct, 2008, David Haley wrote in the 114th comment:
Votes: 0
quixadhal said:
I don't know about your OS, but mine doesn't use crypt() for passwords… or rather, it doesn't use the old crypt() based on DES where the data being encrypted was simply a block of all-zero bits (which is why it was easy to brute-force if you got a copy of /etc/passwd … you knew half the answer already). Mine appears to use MD5. The man page claims support is there for Blowfish, SHA256 and SHA512 as well, but MD5 is the default.

Sorry, I didn't mean that the passwords used crypt. I meant that the reasons why the current algorithms etc. are considered secure is basically the same idea, that it would take too long to break it. It's quite possible/likely that with technological advances, people will look back at us in amusement and laugh about how weak our encryption was. :smile:
14 Oct, 2008, quixadhal wrote in the 115th comment:
Votes: 0
Oh, the next patch that will be coming is one to remove all the sh_int declarations (replaced with int) and all the "long" declarations (replaced with either int, or size_t, as apppropriate). I have the first pass done and working, but I then started looking for 32767, 65535 and found some really NASTY things.

get_random_room() was written by Satan. He laughed while he wrote it too….

I'd post what I have now, but I have to wander off to the dentist because I drink soda all day and now have to pay for it again.
14 Oct, 2008, David Haley wrote in the 116th comment:
Votes: 0
Didn't we have a thread here about a month ago about the weirdness of get_random_room?
15 Oct, 2008, quixadhal wrote in the 117th comment:
Votes: 0
I think that was number_door(), which is also evil, but on a small town sherriff level. get_random_room() is a Mayor Daley level.

For those who haven't braved the code….

number_door() looks like
do
pick a random number from 0 to INT_MAX
mask off the lower 8 bits (resulting in a number from 0 to 127)
until that number < 6


For the non-programmers here, that means keep picking numbers from -128 to 127 until one of them is < 6, and then return that regardless of the validity of the exit. If you're generating a maze, that last bit isn't so bad since maybe you want to make an exit
there. If you're trying to flee(), it's kindof bad since, well, you flee into a wall.

In both cases, the thing can cause 100% CPU utilization for a random amount of time… in theory, forever, since it just keeps trying
until it finds something semi-valid.

get_random_room() one-ups the stakes. Pick a random number from 0 to 65535, it is a room? No. Ok, try again.

Now, imagine you've applied the 2 billion vnum patch. If that patch remembered to edit that routine too, you now sit and spin over 2 billion integers to find one of the (probably) 10,000 rooms you really have. If the patch didn't remember to modify this, you can never randomly get to any room over 64K.

*shiver*
15 Oct, 2008, David Haley wrote in the 118th comment:
Votes: 0
:stare:

OK, yeah, that is pretty scary.
19 Oct, 2008, quixadhal wrote in the 119th comment:
Votes: 0
It's been a while since I posted any files outside the SVN repository, so for those who don't have SVN, or just don't want to bother, I'm uploading a snapshot of the current state. Hopefully I'll have some more time this week to chew on this stuff, as there's still a good amount of cleaning that should happen before we get to the Good Stuff (TM). :)
20 Oct, 2008, quixadhal wrote in the 120th comment:
Votes: 0
In the interest of revving up the indent program this afternoon, I wrote a little perl script to answer the question of what line length we should wrap things at. I know a few people still cling to the old 80 column vt220 days (even though I always put the terminal in 132x24 mode – my eyes were better then). Indent (given no options) defaults to column 78.

It should be noted that some lines will become longer when indent is done adding spaces to them, so I'd expect the number of lines over 80 columns will grow a fair amount, but the number over 90 probably won't change much. My own inclination would be to set the wrap point at 94, but that's just because (a) I use a 137x47 terminal (maximized at the font size I'm using), and (b) 96 columns is the old "elite 12pt" font rather than the "courier 10pt" that 80 columns was based on.

Here's the breakdown of the current formatting:

The codebase contains 44851 lines of code.
The overall average line length of the codebase is 24.6746337874295 characters,
and the overall longest line is 104 characters.
Length 104 1
Length 103 1
Length 98 1
Length 95 4
Length 93 2
Length 91 1
Length 90 2
Length 89 4
Length 88 3
Length 87 3
Length 85 2
Length 84 2
Length 83 2
Length 82 6
Length 81 19
Length 80 62
Length 79 91
Length 78 95
Length 77 110
Length 76 522
Length 75 73
Length 74 134
Length 73 148
Length 72 129
Length 71 105
Length 70 165
Length 69 243
Length 68 157
Length 67 198
Length 66 170
Length 65 209
Length 64 195
Length 63 242
Length 62 235
Length 61 297
Length 60 288
Length 59 335
Length 58 388
Length 57 395
Length 56 313
Length 55 379
Length 54 388
Length 53 457
Length 52 461
Length 51 422
Length 50 322
Length 49 346
Length 48 338
Length 47 327
Length 46 363
Length 45 430
Length 44 362
Length 43 382
Length 42 380
Length 41 494
Length 40 448
Length 39 440
Length 38 491
Length 37 537
Length 36 493
Length 35 616
Length 34 566
Length 33 506
Length 32 609
Length 31 556
Length 30 613
Length 29 563
Length 28 592
Length 27 575
Length 26 627
Length 25 632
Length 24 498
Length 23 620
Length 22 660
Length 21 696
Length 20 437
Length 19 645
Length 18 641
Length 17 513
Length 16 452
Length 15 553
Length 14 461
Length 13 536
Length 12 492
Length 11 665
Length 10 225
Length 9 505
Length 8 1029
Length 7 409
Length 6 1186
Length 5 3431
Length 4 228
Length 3 522
Length 2 1867
Length 1 1997
Length 0 5516
100.0/181