Monday, September 1, 2014

Heartbeat

There is a magical moment when either a program or a project comes to life: It's first heartbeat.

For programs, this could mean the first run when the program starts doing its chores showing a cyclical behavior. For instance performing queries in regular intervals. Judging the output of the LOGs and the way in which they flow you can actually understand it as its heartbeat. It is unimportant how many bugs there are in that incipient piece of code or how many features are missing: the moment something starts iterating over and over again, that is the moment when a program comes to life.

I always thought that would be the only heartbeat one could experience in IT. But I was wrong: it is also true for projects. Think about that first e-mail you send, kicking-off the project. When you get a reply with a question about the project, or a question that becomes an action item, that very moment the project's heartbeat has also begun. Further questions and actions will follow.

I guess in both cases that is the moment when something ceases to be just a mere thought or idea and actually becomes something with its own dynamics. A though model that exists beyond the mind that initially created it, with consequences that may go well beyond that initial idea.

Tuesday, October 26, 2010

Loading a memory address into a register (PowerPC)

Last week I was doing some programming on 64-bit PowerPC assembly (on an IBM 8204-E8A with AIX 5.3.0.0). The PowerPC architecture is a load/store architecture so rather than performing any operations on memory addresses directly, you have to first load your data into registers, operate on it, and then store it back into memory. I had quite a bit of trouble loading a memory address into a register, which is, as you can imagine, quite an obstacle to doing anything useful at all. ;-)
What I wanted to do was to have a static pointer. Therefore, I needed to store it somewhere so that its value would be preserved whenever I called the subroutine. There is not a lot of documentation for the PowerPC architecture on the Web, but from the resources that I found [1, 2], most cited the following method to loading 64-bit addresses into a register:

.csect data[rw]
var: .quad 1 
...

.csect text[pr]

...

lis 7, var@highest
ori   7, 7, var@higher
rldicr 7, 7, 32, 31
oris 7, 7, var@h
The AIX assembler simply didn't like those suffixes (@highest, @higher, @h) at all. It complained about the @-character not having any meaning within that context (error 1252-044.) I didn't want to give up, so I compiled a C program that would reproduce just the portion that I would need to understand how to do this. After reading the generated assembly, researching the IBM manuals and experimenting a bit, I came up with this simple solution using the TOC:
##  DATA section
.csect data[rw]
##  Table of contents
    .toc
T.var:  .tc     var{TC}, static_str

##  BSS section
.lcomm bss_static_str, 8, static_str

##  TEXT section
.csect text[pr]
.align 3

...
ld 11, T.var(2)  # load the addr of var into r11
To learn more about the complex subject of instruction formats and addressing, see [3]. I'll just attempt to explain this particular code segment without going into too much detail.
First of all, the table of contents (TOC) creates code that works regardless of where in memory the program is loaded at runtime ("position-independent code" [3]). With the .toc pseudo-op you define the table of contents for a module [4]. I took the naming convention of prefixing the TOC symbols with a capital T from the C compiler assembly output.
So with the .tc pseudo-op you instruct the assembler to create an entry in the TOC, which will refer to the static_str symbol. The static_str symbol is defined elsewhere, in the BSS section using the .lcomm pseudo-op, which defines an uninitialized block of storage [4]. The BSS segment contains uninitialized data for the program; defining this storage elsewhere (meaning in a another segment with a different psudo-op) will likely result in a segmentation fault when running the program.
Finally, and this is where I wanted to get, to load the address for that memory address into a register, you just need the plain and simple ld (load double word) instruction providing the name of the register to load the address to as the first operand (in PPC assembly the target register is generally the first operand) and the TOC reference to the variable as the second one. Notice that I provided the number 2 enclosed in parenthesis, as shown below:
ld 11, T.var(2)
This is the TOC-register, which is by convention register 2. It contains the address of the TOC from which the offset for the particular entry specified is computed. I generally set a symbol to reference this in a more readable way (as does the C compiler), as follows:
.set RTOC, 2
...
ld 11, T.var(RTOC)

The trick is then to reference a TOC symbol as an offset from the TOC address (register 2.) To achieve this, enter the name of the TOC symbol enclosing the TOC register in parenthesis (as shown before.) Note that this idiom refers to the address of the memory location rather than its contents!
Not that hard at all! ;-)

References:
[1] Assembly language for Power Architecture, Part 1 by Jonathan Bartlett (IBM)
[2] PowerPC assembly, by Hollis Blanchard (IBM)
[3] Assembly language for Power Architecture, Part 2 by Jonathan Bartlett (IBM)
[4] AIX 5L Version 5.3 Assembler Language Reference by IBM

Per-URL authentication in ASP.NET

I needed to configure an ASP.NET Web application that uses Windows-based authentication so that certain URLs would be accesible to anonymous users, whereas the rest of the application would remain secured. There is plenty of information out there about the basics of the ASP.NET authentication schemes and their configurations, but I could not find anywhere how to configure on a per-URL basis. Finally, I found some very valuable information on this [1] and wanted to share my experience in case this helps somebody.
The trick is basically to use a location element in the Web.config file, containing the authorization rules for that particular URL, as shown below:
<location path="mypage.aspx">
  <system.web>
    <authorization>
      <allow verbs="GET" users="*"/>
    </authorization>
  </system.web>
</location>
Another important piece of information is that the location element is defined within the configuration element, so that it is a top-level element (the same level as, say system.web or appSettings.)
After editing the Web.config, you need to change the IIS settings to support both, Windows authentication and anonymous access. This is done in the Web site properties dialog box. Go to the Directory Security tab and click on the Edit button of the Anonymous access and authentication control section, as shown below:
The Authentication Methods dialog is displayed. Make sure that both, the Anonymous access and the Integrated Windows authentication checkboxes are checked, as shown below.

That's it! Please bear in mind that the rest of the application already had Windows authentication configured (which I am not showing for the sake of brevity). Publish the application to the server and test it. The URL that you configured in the previous steps should come up without the browser asking for your password*.


References:
[1] Setting authorization rules for a particular page or folder in web.config by Guru Sarkar.

* Note that if you are using IE, you may not get asked for a password even if one is being sent to the server. This depends on your IE zone settings configuration.

A piece of my mind

"It's only incidental that computers execute programs. (...) The important thing about a program is that it's something you can show to people, and they can read it and they can learn something from it. It carries information. It's a piece of your mind that you can write down and give to someone else, just like a book."

- Steven Levy, Hackers: Heroes of the Computer Revolution

Uploading a file using FTP in C#

Uploading a file to an FTP server from a program written in C# can be a tricky task. Even though there are plenty of examples in the Web about how to achieve this, those examples were not working for me, despite careful verification of both, the code and the FTP server settings.

My problem was that I was getting the following error:
The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
Of course I verified that the remote location was there on the server and that the location was writable by my user. Finally, my code was basically copied from an MSDN example, so not much of a chance that anything could go wrong there. After a while I noticed that the problem only happened when I was trying to write to a location different that root, like:
ftp://myserver.com/location/NewFileName.txt
didn't work. On the other hand:
ftp://myserver.com/NewFileName.txt
would work as expected.

So if I were to remove location from the URL, it would work perfectly. After quite a while of looking for the answer, I found a post which described the following solution: you should prepend an escaped slash character (%2F) to the location portion of the URL to make it work. Much to my surprise did this not only work, but it also works for multi-level directory structures, having to prepend this prefix only once.

Your remote location would then look as follows:
ftp://myserver.com/%2Flocation/NewFileName.txt
Here is a rough scrap (not compilable as is!) of the code that I'm using that is finally working as expected:

// obtains the file name in a fully qualified file path,
// e.g. for path=C:\Public\test.txt
//   file name=test.txt
private string GetFileName(string path) { }
// the base URL for the FTP sever, e.g. ftp://myserver.com/
private string _baseUrl;
//  credentials
private string _userId;
private string _password;

public void UploadFile(string localFilePath,
                       string remoteLocation)
{
  // create a request URL, with the URL pointing
  // to the new file's location
  string requestUrl;
  if (remoteLocation != null && remoteLocation.Length > 0)
      requestUrl = _baseUrl + "%2F" + remoteLocation + "/" + GetFileName(localFilePath);
  else
      requestUrl = _baseUrl + GetFileName(localFilePath);

  //  create a web request using that URL
  FtpWebRequest request = (FtpWebRequest)WebRequest.Create(requestUrl);
  request.Method = WebRequestMethods.Ftp.UploadFile;
  request.Credentials = new NetworkCredential(_userId, _password);

  //  read the local file as a byte array
  StreamReader src = new StreamReader(localFilePath);
  byte[] fileContents = Encoding.UTF8.GetBytes(src.ReadToEnd());
  src.Close();
  request.ContentLength = fileContents.Length;

  //  write those bytes out to the request
  Stream requestStream = request.GetRequestStream();
  requestStream.Write(fileContents, 0, fileContents.Length);
  requestStream.Close();

  //  check the server response
  FtpWebResponse response =
    (FtpWebResponse)request.GetResponse();
  response.Close();
}

I hope this helps somebody! :-)
BTW I'm using the .NET framework version 2, and a Windows FTP server.