Wednesday, December 07, 2011
Find android branch names
Crossposted from stackoverflow.
mkdir /tmp/zug
pushd /tmp/zug
git clone https://android.googlesource.com/platform/manifest.git
cd manifest
git branch -a | sed -n '/^ r/s,.*/,,p'|sort -u|column
popd
rm -rf /tmp/zug
gives the following output
android-1.6_r1 android-2.2.1_r1 android-2.3.4_r1
android-1.6_r1.1 android-2.2.1_r2 android-2.3.5_r1
android-1.6_r1.2 android-2.2.2_r1 android-2.3.6_r0.9
android-1.6_r1.3 android-2.2.3_r1 android-2.3.6_r1
android-1.6_r1.4 android-2.2.3_r2 android-2.3.7_r1
android-1.6_r1.5 android-2.2_r1 android-2.3_r1
android-1.6_r2 android-2.2_r1.1 android-4.0.1_r1
android-2.0.1_r1 android-2.2_r1.2 android-4.0.1_r1.2
android-2.0_r1 android-2.2_r1.3 froyo
android-2.1_r1 android-2.3.1_r1 gingerbread
android-2.1_r2 android-2.3.2_r1 gingerbread-release
android-2.1_r2.1p android-2.3.3_r1 ics-mr0
android-2.1_r2.1p2 android-2.3.3_r1.1 master
android-2.1_r2.1s android-2.3.4_r0.9 tradefed
Tuesday, December 06, 2011
Modifying udev on Ubuntu so that an unpriveleged user can use Android adb on a physical Android device:
sudo touch /etc/udev/rules.d/51-android.rules
sudo ln -s /lib/udev/rules.d/51-android.rules
# make sure device is NOT plugged in
lsusb | cut -d" " -f 6 | sed 's/:/ /' > ~/.tmp
# plug in the device
lsusb | cut -d" " -f 6 | sed 's/:/ /' > ~/.tmp1
diff ~/.tmp ~/.tmp1 | sed -n '/^>/s/^..\([^ ]*\) \(.*\)/SUBSYSTEM=="usb", ATTR{idVendor}=="\1",ATTR{idProduct}=="\2", GROUP="plugdev"/p' | sudo tee -a /etc/udev/rules.d/51-android.rules > /dev/null
rm -f ~/.tmp ~/.tmp1
#unplug USB device
adb kill-server
sudo service udev restart
adb start-server
# you should be good to go.
adb devices # the new device should appear
If you need to check out all permissions for all USB devices:
find /dev/bus/usb -not -type d | xargs ls -l
For Kindle Fire:
It seems that it works if you edit ~/.android/adb_usb.ini and add 2 lines containing 0x1949 and 0x0006 and restart the adb server using adb kill-server adb start-server Also, the 51-android.rules file contains the Lab126 vendor id. (thanks r1k0)
Sunday, December 04, 2011
Friday, December 02, 2011
Wednesday, September 12, 2007
Here's how to use Clearcase's cleartool with rsync:
First, on the machine where clearcase is (ie, where you're pulling files FROM), create a script like so: (call it /bin/setviewrun)
#!/bin/bash
view=$1
shift
while [[ -n "$1" && "$1" != "rsync" ]]; do
shift
done
/usr/atria/bin/cleartool setview -exec "$*" $view
Now, on the machine where you want to copy the files to use this rsync command:
rsync -navz --rsh "ssh id@box /bin/setviewrun viewname" id@box:/path/to/file.txt .
Take the -n away once it actually works!
Thursday, May 11, 2006
C# Beautified Menu Entries
There are not many examples of how to do things in C# in a beautiful way. Even the O'Reilly examples are sometimes pretty crufty. Here's an example of how to create an entire menu, including submenus without any goofy placeholder variables.
public void CreateMenus() {
MenuStrip menu = new MenuStrip();
menu.Items.AddRange( new ToolStripItem[]{
new ToolStripMenuItem("&File", null,
new ToolStripMenuItem("&Close", null, new EventHandler(CloseMenu_Click)),
new ToolStripMenuItem("E&xit", null, new EventHandler(ExitMenu_Click)))
,
new ToolStripMenuItem("&Edit", null,
new ToolStripMenuItem("&New Thing", null, new EventHandler(EditNewThingMenu_Click)))
,
new ToolStripMenuItem("&Pen", null,
new ToolStripMenuItem("&Pencil", null, new EventHandler(PenMenu_Click)),
new ToolStripMenuItem("Bl&ack Pen", null, new EventHandler(PenMenu_Click)),
new ToolStripMenuItem("Bl&ue Pen", null, new EventHandler(PenMenu_Click)),
new ToolStripMenuItem("Eraser", null, new EventHandler(PenMenu_Click)))
});
foreach( ToolStripItem i in menu.Items)
i.Font = Global.MenuFont;
Global.ExplorerForm.MainMenuStrip = menu;
}
Friday, May 05, 2006
.NET PrintPreviewDialog very slow
I was having a problem with PrintPreviewDialog.ShowDialog() taking 10s of seconds to show any output. I did a single step from the ShowDialog() line and none of my code was in the way -- it took ~10 seconds to get to the first line of my PrintPageEventHandler. After some googling, I tried changing default printers from my network printer to PDFCreator and voila, proplem solved.
So the moral of the story is that if PrintPreviewDialog.ShowDialog() spends an inordinate amount of time just getting to your print routines, it's probably got something to do with the Windows print driver and not your code.
Wednesday, August 31, 2005
Setting Credentials of your Crystal Reports using your ConnectionString
When using Crystal reports with ASP.NET, you'll need to set the credentials for accessing the database because the .rpt file doesn't keep all of the login information (namely the password). You probably already have this info handy in Your Configuration Settings. This is a handy routine (I put mine in Global.asax.cs) to apply the credentials from your "ConnectionString" of your AppSettings to the CrystalDecisions.CrystalReports.Engine.Tables object.
public static void CrystalReportLogin(CrystalDecisions.CrystalReports.Engine.Tables tables) {
CrystalDecisions.Shared.TableLogOnInfo logOnInfo = new CrystalDecisions.Shared.TableLogOnInfo();
foreach( string s in System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"].Split(';')) {
string[] nv = s.Split('=');
switch(nv[0]) {
case "Password": logOnInfo.ConnectionInfo.Password = nv[1]; break;
case "User ID": logOnInfo.ConnectionInfo.UserID = nv[1]; break;
case "Initial Catalog": logOnInfo.ConnectionInfo.DatabaseName = nv[1]; break;
case "Data Source": logOnInfo.ConnectionInfo.ServerName = nv[1]; break;
}
}
foreach( CrystalDecisions.CrystalReports.Engine.Table table in tables)
table.ApplyLogOnInfo(logOnInfo);
}
With this in place, displaying a Crystal Report is as simple as this:
reportDocument1.Load(@"C:\Projects\Reports\CrystalReport1.rpt");
Global.CrystalReportLogin(reportDocument1.Database.Tables);
CrystalReportViewer1.ReportSource = reportDocument1;
Tuesday, July 26, 2005
NUnit - quick and easy
I searched for a quick and easy introduction to NUnit. There are some nice articles, but they all go into more detail than I want. I just want to take a look at something simple to see what all the fuss is about.
So, here's the smallest introduction to NUnit 2.2 you'll find. Hopefully after you've gone through this procedure you'll be able to see where you can use NUnit in your own projects. You'll then be ready to look at the more complex articles referenced at the end of this one.
Assumptions
- You are using Visual Studio.NET. The version of VS.NET shouldn't matter
- You're using C#. The code is so simple that programmers of other .NET languanges should be able to understand it
- You install NUnit in it's default directory.
The Procedure
- Download and install NUnit. This article was based on NUnit-2.2.0.
- Start Visual Studio.NET
- Create a blank solution.
- Within your blank solution, create a new project called "NUnitTesting".
- Within the "NUnitTesting" project, right click "References", then click on "Add Reference" in the context menu.
- Click the Browse button.
- Navigate to C:\Program Files\NUnit 2.2\bin
- Doubleclick nunit.framework.dll
- Click OK. You have just added the NUnit framework to your project.
- Modify the Class1.cs file so that it looks like this:
using System;
using NUnit.Framework;
namespace NUnitTesting{
public class CalcInt{
public int add(int a,int b){
return a+b;
}
}
[TestFixture]
public class CalcIntTestFixture{
CalcInt testCalcInt;
[SetUp] public void Init(){
testCalcInt = new CalcInt();
}
[Test] public void AddSuccess(){
Assert.AreEqual(2,testCalcInt.add(1,1));
}
[Test] public void AddFails(){
Assert.AreEqual(3,testCalcInt.add(1,1)); // FAILS, 1+1 != 3
}
}
} - Press Shift-Control-B to save/compile the dll
- Start->All Programs->NUnit 2.2->NUnit-GUI
- File->Open
- Navigate to the DLL that was created when you compiled 3 steps ago, and open it.
- Click on the Run button.
- One test should succeed, and one should fail -- hopefully the tests are simple enough to not need explanation.
- That's it! There is a lot more to learn about NUnit, but this article should give you some tools to get started.
Resources
- NUnit documentation - http://www.nunit.org/documentation.html
- Test Driven Development using NUnit in C# - http://aspnet.4guysfromrolla.com/articles/011905-1.aspx
Monday, June 27, 2005
Reading your Outlook Inbox from C# using OleDbDataAdapter
private void ListInbox()
{
string Mailbox = "Inbox";
string Provider = "Microsoft.Jet.OLEDB.4.0;Outlook 9.0";
string MAPILEVEL = "Mailbox - Lastname, Firstname";
string PROFILE = "Lastname, Firstname";
string TABLETYPE = "0";
string DATABASE = @"c:\temp";
DataSet ds = new DataSet();
DataTable dt = new DataTable();
string sql = string.Format(@"SELECT * FROM {0}", Mailbox);
string ConnectionString = string.Format(
@"Provider={0};MAPILEVEL={1}|;PROFILE={2};TABLETYPE={3};DATABASE={4}",
Provider, MAPILEVEL, PROFILE, TABLETYPE, DATABASE);
try
{
OleDbDataAdapter da = new OleDbDataAdapter( sql, ConnectionString );
da.Fill(ds,"Outlook");
dt = ds.Tables["Outlook"];
dataGrid1.DataSource = dt;
}
catch (Exception ex)
{
MessageBox.Show("Error: "+ex.Message);
}
}
Saturday, June 11, 2005
Allow the UI to catch up on a windows forms app
for(a very long time)
Application.DoEvents();
Friday, June 03, 2005
How to hide null ASP.NET data fields
Say you have a bit of data called Symptoms that you want to display on your web page, and it contains a label (also called "Symptoms"). It might look something like this in your form:
Symptoms: <%# DataBinder.Eval(Container.DataItem, "Symptoms") %>
Now say, if there is no data in the database, you don't want the field to appear at all. I did some research to find a nice way to do this, but I didn't like any of them (if someone has a nice server side way of doing this (without peppering the html with >1 "DataBinder.Eval...", I'd like to hear).
So, here's my solution. First, decorate your html with a div and a span like this:
<div class="hide" id="SymptomsDiv">
Symptoms:
<span id="SymptomsSpan"><%# DataBinder.Eval(Container.DataItem, "Symptoms") %></span>
</div>
Then add the following css classes:
<style type="text/css">
.hide{display: none;}
.show{display: block;}
</style>
And the following script code:
<script>
function sectionObjects(name){
o = new Object;
o.name = name;
o.div = document.getElementById(name+"Div");
o.span = document.getElementById(name+"Span");
return o;
}
window.onload = function(){
var sections = new Array;
sections.push(sectionObjects("Symptoms"));
// Show those sections that have data
for(var i = 0; i<sections.length; i++)
if (sections[i].span.innerHTML!="")
sections[i].div.className = "show";
}
</script>
All the sections (all one in this case) start out hidden. The onload function runs when the window loads. It finds any sections that are not null using .innerHTML -- this'll work on all modern browsers.
Thursday, June 02, 2005
An app specific bookmarklet that shows known hidden frames
javascript:{x=window.frames['Content'].document.getElementsByTagName('frameset');for(i=0;i<x.length;i++)if(x[i].rows=='0,0,*')x[i].rows='20,20,*';void(0);}
ASP.NET Response.TransmitFile() sometimes fails with networked UNC files
Simply replace this:
Response.TransmitFile(filename);
With this:
Stream s = new FileStream( filename, FileMode.Open, FileAccess.Read );
const int bufLength = 1024;
byte[] buf = new byte[bufLength];
int red;
while( (red=s.Read(buf,0,bufLength))>0 )
if (Response.IsClientConnected)
Response.BinaryWrite(buf);
Response.Flush();
Response.Close();
s.Close();
UNC networked files error failure fail C# TransmitFile WriteFile
Tuesday, May 31, 2005
CacheDependency Limitation
As of ASP.NET 1.1, it looks like you can only get an ASP.NET cache item
to be dependent on about about 40 remote directories or so, then you'll run
into an arbitrary limitation of the ReadDirectoryChangesW win32 api
call. The exception generated will look something like this:
Failed to start monitoring changes to '\\Your\remote\directory'.
I doubt that this will be fixed in ASP.NET 2.0, since it is really a
limitation of the underlying OS.
This issue is especially ugly when you have to monitor a large number
of directories, such as an entire directory tree. It would be
nice if CacheDependency would allow you to monitor a deep directory --
that is, monitor if any changes were made to any file within an entire
tree structure. My guess is that this is just something the OS
does -- it would be a nice addition.
Supporting URLs:
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.aspnet/msg/fda128472edbf215?hl=en
http://www.vsj.co.uk/dotnet/display.asp?id=381
(See the box titled "Under the Hood of the ASP CacheDependency" at the
bottom of the article)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/readdirectorychangesw.asp
(ReadDirectoryChangesW fails with ERROR_INVALID_PARAMETER...)
Tuesday, May 24, 2005
Calling a server side func in JavaScript with document.createElement('script')
CAUTION: THIS DOESN'T SEEM TO WORK ALL THE TIME. I'VE GONE BACK TO THE HIDDEN IFRAME TECHNIQUE
The following bit of JavaScript and C# code work to gether to do
some remote scripting from the browser to the server. Basically
some javascript function running on the client wants to call the
'ServerFunc' C# code, and pass it a single parameter named "user".
See:
- http://www.htmlcodetutorial.com/help/archive.php/o_t__t_1288__ie6-can-t-load-dynamic-and-ltscript-and-gt-element-s-src-url.html
- http://dojo.jot.com/RemoteScriptingRevisited
// Within a javascript function that wants to call the server:
ServerCall("ServerFunc&user="+User);
// The ServerCall function calls a function in the MYPAGE.aspx on the server.
function ServerCall(call){
var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.src = "MYPAGE.aspx?nocache="+new Date().getTime()+"&cmd="+call;
//alert(script.src);
script.type = 'text/javascript';
head.appendChild(script);
}
NOTE: The rest is C# code in the aspx. If you're not into C#, replace this with whatever you like. The ServerCall() bits should still work.
// Within MYPAGE.aspx’s Page_Load(), we find the desired function and call it.
// Long live reflection
private void Page_Load(object sender, System.EventArgs e){
// Find and execute the command
MethodInfo m = GetType().GetMethod("page"+Request["cmd"]);
if (m==null)
m = GetType().GetMethod("pageDefault");
m.Invoke(this,null);
}
// the m.Invoke() in Page_Load() calls this function. Note, we prepend each page
// function with the word 'page' -- this way baddies can't run arbitrary funcs
public void pageServerFunc(){
string user = Request["user"]; // This came from the client
Script.Append("alert('You can do anything in here');");
Script.Append("SomeClientFunc('Then call a client func to wrap up!');");
Response.Write(script.ToString());
Response.Flush();
Response.Close();
}
StringBuilder script = new StringBuilder();
Wednesday, January 14, 2004
How to use ldapsearch...
[root@prm99ws1 root]# ldapsearch -x -D cn=manager,dc=zzz,dc=net -w ##PASS## -H ldaps://ldap3.zzz.com:636 -b "dc=zzz,dc=net" -s sub "(uid=uidofuser)"
version: 2
#
# filter: (uid=uidofuser)
# requesting: ALL
#
bla bla bla...
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Tuesday, April 29, 2003
Converting a file to/from hex using Perl
I needed to store binary images in Pick. Pick, of course, doesn't like to store binary (it can't deal with char(255)), so I deceded to convert to hex. I could have uuencoded but hex is fine for my purposes.
So here's how to convert a file.gif to file.gif.hex:
perl -n0777e 'print unpack "H*",$_' < file.gif > file.gif.hex
To convert it back:
perl -n0777e 'print pack "H*",$_' < file.gif.hex > newfile.gif
Sunday, April 06, 2003
Hacking the D3 Executable
Ok, here's the problem. D3's filesystem osfi is set to create files with 660 permissions (rw ower, rw group, nothing other). This is secure, but if you want to create files that will work for other users, you have to then go in and change the permissions. And if you have a boat load of software that doesn't do this, then it just doesn't work out well. What you'd really like to do is create all files with 777 (rwx for everybody) and let the umask mask out the unwanted bits (umask of 117 will give you the original result).
At first, this seemed easy, Raining Data gives you the source to rp_driverux.c. But alas, they don't give you the rp_driverux.h source, so you can't compile it. And in our special circumstance, we can't build coff files anyway. So I was left with the second alternative -- using a binary editor to change the executable code. The rest of this howto details how I did it.
Within /usr/lib/pick/rp_driverux.c you'll find:
static int
rp_upditm( long fd, rp_hdr *hd, unsigned char *buf, int length )
{
int code = -1;
unsigned char *p, *q;
int localfd;
localfd = RP_FDNUM(fd) - 1; /* Translate FD into table index */
. . .
/* Go open it */
if ((code = rp_retixux(localfd,O_WRONLY | O_TRUNC | O_CREAT,0660)) < 0)
{
hd->rp_rtncd = code;
return code;
}
. . .
}
The code=rp_retixux... line contains the permissions, 0660. This is the trouble spot. To find this in the actual d3 executable is pretty simple. (Note: there is probably a better way, but this worked for me).
First step is to disassemble the d3 executable into a file: dis /usr/bin/d3 > /tmp/d3.dis
This d3.dis file can now be examined. We know that we're looking for a function named rp_upditm, so just vi the file and search for it. For me, it looked something like this:
rp_upditm()
8054ed8: e9 79 03 00 00 jmp 0x379 <8055256>
8054edd: 90 nop
8054ede: c7 45 fc ff ff ff ff movl $0xffffffff,-4(%ebp)
8054ee5: 8b 45 08 movl 8(%ebp),%eax
8054ee8: 25 ff ff 00 00 andl $0xffff,%eax
8054eed: 48 decl %eax
8054eee: 89 45 f0 movl %eax,-16(%ebp)
. . .
Now, search for 1b0 (which is 0660 in hex). Voila, you found the code:
. . .
805504d: ff 48 08 decl 8(%eax)
8055050: 68 b0 01 00 00 pushl $0x1b0
8055055: 68 01 03 00 00 pushl $0x301
...
(NOTE: I showed the line before and after too)
The pushl $0x1b0 is the push of the 0660 onto the stack for the call to rp_retixux(). Now all we need to do is change the 0660 to 0777 (1b0 to 1ff). To do that, we need the offset. I could have probably figured it out using the address (0x8055050), but I decided just to search for it since I had the object code available. To do that, I did "od -x d3 > d3.od" to create a hex dump of the file, then I did a grep for "b068". Here's the output I got:
# grep "b068" d3.od
0025760 0000 b068 12c5 e808 71d4 000c 6859 c1f4
0043260 0812 b068 12cd ff08 6835 12c3 6a08 e800
0044360 b068 12ce 6808 dcec 0814 b9e8 0ba5 8300
0046100 b068 0003 ff00 7c35 12c3 a108 c850 0815
0056420 1de9 0001 9000 b068 0003 6a00 a105 c850
0056560 5900 016a 37e8 0cba 5900 b068 0003 ff00
0056720 b068 0003 a100 c850 0815 000d 0000 5080
0072260 31eb b068 04f4 6a08 e805 a22a 000c c483
0074600 0f6a 11e8 ffff 83ff 0cc4 b068 04f4 6808
0150120 b068 0001 6800 0301 0000 75ff e8f0 101e
0566300 cde8 0995 8300 10c4 c085 0b7d b068 1322
1127720 038b c085 0d74 b068 1552 e808 0a10 0000
1142660 c483 eb10 8325 00c7 b068 1559 0f08 07bf
1227600 ac15 1361 e808 1366 0000 b068 156b 6808
1363440 4875 94a3 1612 eb08 836d 00c7 b068 1579
1477540 c35d 9090 b068 13df e808 d526 ffff c483
1514440 47f8 088b f93b 847e b068 13e8 e808 bb62
3367300 b85f 0001 0000 e58b c35d 9090 b068 1526
Looking through you'll find the one we want is at 0150120. A couple of things to remember: this is a sco machine so the bytes are switched in words (16 bit). Also, you need the context of the object code around it (from the assembly listing) to distinguish the correct line. Also remember, the offset is in octal (0150120 = 0xd050). For awhile I thought it was decimal which threw me off a bit.
Now that you have the offset of the change and the change to make, you just need to make it. You could write a C program to do it, but I just found myself a hex editor and used it. I copied the d3 exec to my laptop and used frhed to modify it. Then I sent it back.
Wednesday, March 19, 2003
How to do a HTTP request with authentication by hand:
- Let's say your user:pass is fred:supersecret
- /bin/echo -n "fred:supersecret" > /tmp/x
- uuencode -m /tmp/x /tmp/y
You'll get:
begin-base64 644 /tmp/y
ZnJlZDpzdXBlcnNlY3JldA==
==== - Copy the ZnJIZ... string (including the == at the end) to your cut buffer. This is your uuencoded user:password.
- telnet ip.or.host 80
- Type in: GET /path/to/file.html HTTP/1.0
- Optionally type in: HOST: www.yourserver.com
- Type in: Authorization: BASIC ZnJlZDpzdXBlcnNlY3JldA==
- Type in: A Blank line
- You should get the output web page now.
Friday, March 14, 2003
How to upgrade Red Hat 8.0's apache RPMs to the latest Apache release
rpm -i /rhs80.2/SRPMS/httpd-2.0.40-8.src.rpm
Install the Apache source RPM. Ignore the warning. You may need to get the src.rpm file from the CD directly.cd /usr/src/redhat
Go to the Red Hat sources directorywget http://apache.oregonstate.edu/httpd/httpd-2.0.44.tar.gz
Get the latest version of Apache. Go to www.apache.org and follow the download link.http://httpd.apache.org/dev/verification.html
Read this tedious set of gpg instructions about how and why you should verify the code. Ho hum.mv httpd-* SOURCES
Move the source you just downloaded into the SOURCES directoryvi SPECS/httpd.spec
Make the following changes:- Version: 2.0.40 -> 2.0.44
- Release: 8 -> jl1
- Comment out the line that says
%patch3 -p0 -b .sslink
- Comment out the line that says
%patch40 -p0 -b .cnfdir
- Comment out the section that has the comment "fix man page paths"
- Change all occurances of "libapr\." to "libapr-0\."
- Change all occurances of "libaprutil\." to "libaprutil-0\."
- Comment out the line that says
%{_mandir}/man8/apachectl*
. - Comment out the line that says
%{_mandir}/man8/httpd*
. - Find the line that reads: "--enable-deflate \". Add a line after it that reads: " --with-ldap --enable-ldap --enable-auth-ldap \". The tab before the "--enable" and the backslash after the end are very important.
- Add a changelog entry
- And here's the diff:
7,8c7,8
< Version: 2.0.40
< Release: 8
---
> Version: 2.0.44
> Release: cli1
90c90
< %patch3 -p0 -b .sslink
---
> #%patch3 -p0 -b .sslink
92c92
< %patch40 -p0 -b .cnfdir
---
> #%patch40 -p0 -b .cnfdir
127a128
> --with-ldap --enable-ldap --enable-auth-ldap 225,232c226,233
< sed -e "s|/usr/local/apache2/conf/httpd.conf|/etc/httpd/conf/httpd.conf|"
< -e "s|/usr/local/apache2/conf/mime.types|/etc/mime.types|"
< -e "s|/usr/local/apache2/conf/magic|/etc/httpd/conf/magic|"
< -e "s|/usr/local/apache2/logs/error_log|/var/log/httpd/error_log|"
< -e "s|/usr/local/apache2/logs/access_log|/var/log/httpd/access_log|"
< -e "s|/usr/local/apache2/logs/httpd.pid|/var/run/httpd.pid|"
< -e "s|/usr/local/apache2|/etc/httpd|" < docs/man/httpd.8
< > $RPM_BUILD_ROOT%{_mandir}/man8/httpd.8
---
> #sed -e "s|/usr/local/apache2/conf/httpd.conf|/etc/httpd/conf/httpd.conf|"
> # -e "s|/usr/local/apache2/conf/mime.types|/etc/mime.types|"
> # -e "s|/usr/local/apache2/conf/magic|/etc/httpd/conf/magic|"
> # -e "s|/usr/local/apache2/logs/error_log|/var/log/httpd/error_log|"
> # -e "s|/usr/local/apache2/logs/access_log|/var/log/httpd/access_log|"
> # -e "s|/usr/local/apache2/logs/httpd.pid|/var/run/httpd.pid|"
> # -e "s|/usr/local/apache2|/etc/httpd|" < docs/man/httpd.8
> # > $RPM_BUILD_ROOT%{_mandir}/man8/httpd.8
308,309c309,310
< %{_libdir}/libapr.so.*
< %{_libdir}/libaprutil.so.*
---
> %{_libdir}/libapr-0.so.*
> %{_libdir}/libaprutil-0.so.*
336,337c337,338
< %{_mandir}/man8/apachectl*
< %{_mandir}/man8/httpd*
---
> #%{_mandir}/man8/apachectl*
> #%{_mandir}/man8/httpd*
359,360c360,361
< %{_libdir}/libapr.so
< %{_libdir}/libaprutil.so
---
> %{_libdir}/libapr-0.so
> %{_libdir}/libaprutil-0.so
369a371,373
> * Fri Mar 14 2003 John Lombardo2.0.44-cli-1
> - Make it work with Apache 2.0.44 (so we get mod_auth_ldap)
>
- Version: 2.0.40 -> 2.0.44
rpmbuild -ba SPECS/httpd.spec
Finally, you can build the bugger. This will take a few minutes, even on a fast machine. Pay attention to the last thing it says. If it worked it should tell you about your new RPMs, if not, the final few (50 or so) lines will probably tell you where it went wrong.- You should now have the following new files:
- SRPMS/httpd-2.0.44-cli1.src.rpm
- RPMS/i386/httpd-2.0.44-cli1.i386.rpm
- RPMS/i386/httpd-devel-2.0.44-cli1.i386.rpm
- RPMS/i386/httpd-manual-2.0.44-cli1.i386.rpm
- RPMS/i386/mod_ssl-2.0.44-cli1.i386.rpm
- SRPMS/httpd-2.0.44-cli1.src.rpm
Install them and you're done. (Don't forget to uninstall the old ones first!)
Tuesday, March 04, 2003
Friday, February 28, 2003
How to send email w/o a mail client
Note: you have to telnet to your email server
[jl@www jl]$ telnet mail.MySmtpServer.net 25
Trying aa.bb.cc.dd...
Connected to mail.MySmtpServer.net.
Escape character is '^]'.
220 mail.MySmtpServer.net ESMTP
helo www.DoesntReallyMatter.com
250 mail.MySmtpServer.net
mail from: john@MyEmailAddress.net
250 ok
rcpt to: arthur@ReceiversEmailAddress.net
250 ok
data
354 go ahead
Subject: This is a hand _made_ message
Hi Arthur,
How are you today?
Regards,
John
.
250 ok 1046474020 qp 32526
quit
221 mail.MySmtpServer.net
Connection closed by foreign host.
#
# My Fabulous private schema
#
# OIDS:
# iso.org.dod.internet.private.enterprise.me.myclient.ldap.attributetype
# 1 3 6 1 4 1 15823 1 1 1
# iso.org.dod.internet.private.enterprise.me.myclient.ldap.objectclass
# 1 3 6 1 4 1 15823 1 1 2
#
# Created by: John Lombardo <JohnLombardo@acm.org>
#
# Attribute Type Definitions
attributetype ( 1.3.6.1.4.1.15823.1.1.1.1 NAME 'SSHPublicKey'
DESC 'Public key for ssh'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.15823.1.1.1.2 NAME 'DBHost'
DESC 'Which DB server does this user use.'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44
SINGLE-VALUE )
# Object Class Definitions
objectclass ( 1.3.6.1.4.1.15823.1.1.2.1 NAME 'CliUser'
DESC 'CliUser' SUP top AUXILIARY
MUST ( uid )
MAY ( SSHPublicKey $ D3Host )
)
This is about a month old, but it bears blogging: The IANA has assigned the following Private Enterprise Number to LinuxWithin.com: 15823
The prefix is: iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
I'm assigning the .1 sub-code for use at my customer.
Thursday, February 27, 2003
The test stuff is here: /var/www/dev/html/test/x
Here's the command to build the pdf:
htmldoc --header ... --footer ... --webpage --bottom 0 --top 0 --left 0 --right 0 -f jl.pdf a1.html 2> /dev/null
Here's what the HTML file should look like (a1.html in the above line):
<html><head></head><body>
<!-<img src="1/fred.img319.001.gif" width="100%" height="130%">-->
<img src="y.gif" width="100%" height="130%">
</body></html>
Here is our first attempt at trying to convert the tiff to a gif. It works, except that it's inversed:
tifftopnm tiff.tif | ppmquant 256 | ppmtogif > GIF.gif
These programs are all part of the netpbm-progs-9.14-2 package.
HTMLDOC is the groovy package that converts html (and through it gif, jpeg, others) to pdf. It can do it both on Windows and on Linux. A command line version is available.
And this is the magic command line that makes it all work...
X=1/fred.img319.011; tiff2rgba $X x.tif; tifftopnm x.tif | ppmtogif > z.gif ; htmldoc --header ... --footer ... --webpage --bottom 0 --top 0 --left 0 --right 0 -f jl.pdf a1.html
It turns out that the Image Magick package works better than the netpbm stuff for what we need.
So here's a script that converts all of the listed files into one big PDF file using HTMLDOC and ImageMagick. Cool.
#!/bin/sh
######################################################################
# mkpdf: make a pdf out of a bunch of graphic files
######################################################################
DIR=/tmp/mkpdf$$
OUT=$1; shift
if [ -e $OUT ]; then
echo $OUT already exists
exit 1
fi
mkdir $DIR
i=0
FILES=""
while [ -n "$1" ]; do
cat <<DONE >$DIR/$i.html
<html><body><img src="$i.png" width="100%" height="130%"></body></html>
DONE
# tiff2rgba $1 $DIR/x.tif
# tifftopnm $DIR/x.tif | ppmtogif > $DIR/$i.gif
convert $1 $DIR/$i.png
FILES="$FILES $DIR/$i.html"
i=$((i+1));shift
done
htmldoc --header ... --footer ... --webpage --bottom 0 --top 0 --left 0 --right 0 -f $OUT $FILES
rm -rf $DIR
Tuesday, February 25, 2003
One more thing about the email server; I wanted to try my email list test again (send an email to a test list of 50 test users). So I changed the loglevel-send back to 127. When I sent to the test list, I had troubles. After I changed the loglevel-send back to nothing (file exists, but is empty), my list went through with no trouble. Hmmm, seems that having a loglevel can muck things up a bit.
One other thing: when I restarted with the message in the queue, I got double entries in my test users email accounts for the same message. Yuck.
Here's the command line for showing what's in the test email boxes:
for i in `awk 'BEGIN{for(i=0;i<=49;i++)print i}'`;do /bin/echo -n "$i ";ls test$i/Maildir/new;done
Well, that (see yesterdays blog) didn't work. I got a call from the admin this morning that email didn't work, and sure enough it was not delivering mail at all. I undid the change to /var/qmail/control/ldaptimeout and restarted. It took about 5 restarts ((vi /etc/inittab; kill -HUP 1)*2), but eventually it got through the whole deliver queue. The problem still remained of why was this happening. One clue was found by setting /var/qmail/control/loglevel-send to 127 and restarting. I would get something like exhibit 1, except the "success" time was a minute and a half later than the "executing..." time.
The other big clue was that "top" on the openldap server box showed slapd pegged at close to 100% of the cpu. This told me that OpenLDAP was too busy.
Upon further examination of exhibit 1, I noticed that the mailAlternateAddress was being searched every time. The "mail" field is indexed by default, but the mailAlternateAddress was not indexed. I changed the /etc/openldap/slapd file on the OpenLDAP server by adding the line index mailAlternateAddress eq
, and that seems to have fixed everything up quite nicely.
Along the way, I developed two useful utilities for looking at the logs; delivery and deliveries. Delivery's output is shown in exhibit 1. It shows all the information about a specific delivery. The source is in exhibit 2. Deliveries simply shows multiple deliveries. It's source is in exhibit 3.
Exhibit 1 |
[root@mail qmail]# ./delivery 42 |
Exhibit 2: delivery |
#!/bin/sh |
Exhibit 3: deliveries |
#!/bin/sh |
Monday, February 24, 2003
/var/qmail/control/ldaptimeout
so that it now takes 120 seconds (2 minutes) for an LDAP connection to timeout. The default is thirty seconds. People who send messages to lists have been getting bounce messages that look like this:
Hi. This is the qmail-send program at mail.client.com.
I'm afraid I wasn't able to deliver your message to the following
addresses.
This is a permanent error; I've given up. Sorry it didn't work out.
:
Sorry, no mailbox here by that name. (#5.1.1)
--- Below this line is a copy of the message.
...
Friday, February 21, 2003
Created three new /var/qmail/control files that contain the loglevels for different services
- loglevel-pop3d 64 for debug
- loglevel-smtpd 64 for debug
- loglevel-send 64 for debug. This one is for local and remote deliverys.
The problem is this. When delivering to a large ldap list (everybody@client.net for example), some of the deliverys fail with this error message:
@400000003e56be0628768734 starting delivery 54492: msg 450906 to local fred@client.net
@400000003e56be65359844ac delivery 54492: failure: Sorry,_no_mailbox_here_by_that_name._(#5.1.1)/
On Monday, I'll create a bunch of test users in cvs2ldif and a list to send to them all. Then I can test this extensively.
In the being careful dept, I should rebuild the qmail binaries before making any changes, then cmp them to the binaries that are in /var/qmail/bin to make sure that I have the right version of stuff.
try{
CHLReferenceNumber = node.Attributes["CHLReferenceNumber"].Value;
} catch( Exception e){
throw new Exception("get error: "+e.Message);
}
But I forgot to put the CHLReferenceNumber in my Response query. It's in there now:
node = xml.DocumentElement.SelectSingleNode("//EQUAL_RESPONSE_QUERY");
try {
node.Attributes["CHLReferenceNumber"].Value = CHLReferenceNumber;
} catch (Exception){
throw new Exception("set error");
}
Thursday, February 20, 2003
- Your programs are so easy to read. No more mucking about with pointers and stuff, you just say want you want and the computer figures out the hard bits. As A die-hard programmer from way back (1983 -- no, not way way back, but way back enough), it's hard for me to admit it -- but I really don't like fooling around with pointers and memory anymore. Sure it's fun to write the loops that move strings from here to there a char at a time, but after you've done it once...
- I really like the #region stuff. Ok, who invented it -- or did it really come from Microsoft?
- More coming...
int tid = System.Threading.Thread.CurrentThread.GetHashCode();
This doesn't seem to be the same as the thread id, but can be used in a similar way.
DateTime t = System.DateTime.Now;
file.WriteLine(
"{0:00}{1:D2}{2:D2} {3:D2}:{4:D2}:{5:D2}+{6:D4} {7}",
t.Year-2000, // Y21K!
t.Month, t.Day, t.Hour, t.Minute,
t.Second, t.Millisecond, s );
"TE3 can take most legacy terminal emulation and display protocols, Remote Desktop Protocol (RDP) for Windows Terminal Server, and any Java-wrapped application, and resolve them to one display protocol for shipment to a Java-enabled Web browser or Tarantella's own proprietary thin client."
-- ZD Net
> Sent: Thursday, February 20, 2003 8:22 AM
>
> did you make up the word snarf? I've never heard of it before! I'm assuming it means stolen/copied/pirated, correct?
I replied:
Snarf has a long and hallowed history...
http://www.webopedia.com/TERM/S/snarf.html
http://info.astrian.net/jargon/terms/s/snarf.html
It's actually a command line utility too...
http://www.xach.com/snarf/
Wednesday, February 19, 2003
I went with Bevan. We sat in really great seats -- a "suite" actually, with a couch and leather seats!
objectClass: sambaAccount
ntPassword: PASSWORD_ENCRYPTED_FOR_NT
Here are the changes that were made:
226a227
> o.outnv( "objectClass","sambaAccount")
254a256,259
> if userPassword!="":
> ntpass = os.popen("mkntpwd -N "+userPassword).read();
> ntpass = string.rstrip(ntpass);
> o.outnv( "ntPassword", ntpass)
Note the use of the new "mkntpwd" program. It's source is in the /usr/src/mkntpwd directory of ldap.client.net. It was snarfed from the internet at this address:
http://www.demog.berkeley.edu/~aperrin/tips/src/