Leaked memory.  You should record the return from xstrdup() separately and free() it after you're done with filename (which *might* be a pointer into it, albeit you have no guarantee of that), i.e. after the sprintf() call.