You should use the current position index (which I guess, in your case, is (curpos - str)) to calculate where the character at the cursor will end up, that is, how many spaces to insert. Then you copy the stuff following the cursor position up the number of positions you need to move them by and fill the area left "vacant" by spaces.
The following function assumes that the line buffer is large enough. In actual practice, you will want to make sure you don't overrun the end of the buffer. Also, the function memmove, which I'm using here, checks for overlap and copies in the right direction.
If you don't understand the pointer arithmetic going on in the first argument to the call to memmove(), it gets the address of the character in the buffer numspaces to the "right" of the current cursor pointer.
char *tab_insert(char *buf, char *curpos, int tabsize)
int colpos = curpos - buf; /* get the column position */
int numspaces = (curpos + 1 + tabsize) % tabsize; /* how many spaces we insert */
int tail_len = strlen(curpos); /* how many characters follow the cursor? */
/* copy everything following the cursor to the right by numspaces positions */
memmove(&curpos[numspaces], curpos, tail_len + 1); /* make sure you copy the nul */
while (numspaces > 0)
*curpos++ = 0x20; /* put a space in place */
I have not tested this code, but it should be correct, or at least close enough to use as a model. The fuction returns the new cursor position.